Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Pdo Snapshot Store Laravel Package

prooph/pdo-snapshot-store

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require prooph/pdo-snapshot-store
    

    Add the package to your config/app.php providers and aliases if not using auto-discovery.

  2. Basic Configuration Create a PDO connection (e.g., in config/filesystems.php or a custom config file):

    'pdo_snapshot_store' => [
        'connection' => 'mysql',
        'table' => 'event_store_snapshots',
        'schema' => 'public',
        'snapshot_class' => \Prooph\SnapshotStore\PDO\Snapshot::class,
    ],
    
  3. First Use Case: Storing a Snapshot

    use Prooph\SnapshotStore\PDO\SnapshotStore;
    use Prooph\SnapshotStore\PDO\Snapshot;
    
    $snapshotStore = new SnapshotStore(
        $pdoConnection,
        new Snapshot('aggregate_type', 'aggregate_id', $snapshotData)
    );
    
    $snapshotStore->save($snapshot);
    
  4. Retrieving a Snapshot

    $snapshot = $snapshotStore->get('aggregate_type', 'aggregate_id');
    

Implementation Patterns

Integration with Event Sourcing

  • Snapshot Strategy: Use snapshots to optimize event replay for large aggregates:

    $aggregate = $repository->get($aggregateId, $snapshotStore);
    

    The repository will automatically load the latest snapshot and replay only subsequent events.

  • Event Store Integration Pair with prooph/event-store-pdo for a complete event-sourcing stack:

    $eventStore = new EventStore(
        $pdoConnection,
        new EventStoreConfiguration(),
        new SnapshotStore($pdoConnection)
    );
    

Workflows

  1. Aggregate Hydration

    $aggregate = $repository->get($aggregateId);
    // Automatically loads snapshot + events
    
  2. Snapshot Creation Trigger snapshots after critical events (e.g., every 100 events or on domain milestones):

    $aggregate->markForSnapshot(); // Custom logic
    $snapshotStore->save($aggregate->toSnapshot());
    
  3. Cleanup Implement a cron job to purge old snapshots (e.g., older than 1 year):

    $snapshotStore->deleteOlderThan(\DateTime::createFromFormat('Y-m-d', '2023-01-01'));
    

Dependency Injection

Use Laravel’s service container to bind the store:

$this->app->bind(SnapshotStore::class, function ($app) {
    $pdo = $app['db']->connection('mysql')->getPdo();
    return new SnapshotStore($pdo);
});

Gotchas and Tips

Pitfalls

  1. Schema Mismatches Ensure your database table matches the expected schema (columns: aggregate_type, aggregate_id, snapshot_data, created_at). Run migrations:

    Schema::create('event_store_snapshots', function (Blueprint $table) {
        $table->string('aggregate_type');
        $table->string('aggregate_id');
        $table->json('snapshot_data');
        $table->timestamp('created_at')->useCurrent();
        $table->primary(['aggregate_type', 'aggregate_id']);
    });
    
  2. Snapshot Serialization The snapshot_data column expects JSON-serializable data. Customize serialization if needed:

    $snapshot = new Snapshot('type', 'id', json_encode($data));
    
  3. Concurrency Issues Snapshots are not atomic by default. Use transactions for critical operations:

    DB::transaction(function () use ($snapshotStore, $snapshot) {
        $snapshotStore->save($snapshot);
    });
    

Debugging

  • Missing Snapshots: Verify the aggregate_type and aggregate_id match exactly (case-sensitive).
  • Performance: Large snapshots may slow queries. Optimize with indexing:
    Schema::table('event_store_snapshots', function (Blueprint $table) {
        $table->index(['aggregate_type', 'aggregate_id']);
    });
    

Extension Points

  1. Custom Snapshot Classes Extend Prooph\SnapshotStore\PDO\Snapshot for domain-specific logic:

    class UserSnapshot extends Snapshot {
        public function __construct(string $aggregateId, array $data) {
            parent::__construct('user', $aggregateId, $data);
        }
    }
    
  2. Query Builder Override the default query logic for custom retrieval:

    $snapshot = $snapshotStore->get('user', '123', new CustomQueryBuilder());
    
  3. Event Listeners Hook into snapshot events (e.g., SnapshotSaved) via Laravel’s event system:

    event(new SnapshotSaved($snapshot));
    

Tips

  • Testing: Use prooph/test-helper to mock the snapshot store in unit tests:
    $mockSnapshotStore = $this->prooph()->mockSnapshotStore();
    
  • Backup Strategy: Snapshots are critical for event replay. Include them in your backup routine.
  • Versioning: Consider adding a version column to handle schema migrations gracefully.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
babenkoivan/elastic-client
innmind/static-analysis
innmind/coding-standard
datacore/hub-sdk
alengo/sulu-http-cache-bundle
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
imbo/imbo-coding-standard
visualbuilder/filament-lottie
servicioslineaonce/starter-kit
atomcoder/laravel-reorderable
irajul/filament-shadcn-theme
agtp/agtp-php
agtp/mod-php
centraldesktop/protobuf-php