/**
  * @param array $data
  * @return array
  */
 public function run(array $data)
 {
     switch ($data['adapter']) {
         case 'mysql':
             $connection = DriverManager::getConnection($data['options']);
             $connection->executeQuery('DROP TABLE IF EXISTS user_stream');
             $adapter = new DoctrineEventStoreAdapter($connection, new FQCNMessageFactory(), new NoOpMessageConverter(), new JsonPayloadSerializer());
             break;
         case 'postgres':
             $connection = DriverManager::getConnection($data['options']);
             $connection->executeQuery('DROP TABLE IF EXISTS user_stream');
             $adapter = new DoctrineEventStoreAdapter($connection, new FQCNMessageFactory(), new NoOpMessageConverter(), new JsonPayloadSerializer());
             break;
         case 'mongodb':
             $connection = new \MongoClient($data['options']['server']);
             $connection->selectDB('event_store_adapter_benchmarks')->selectCollection('user_stream')->drop();
             $adapter = new MongoDbEventStoreAdapter(new FQCNMessageFactory(), new NoOpMessageConverter(), $connection, $data['options']['db_name']);
             break;
         default:
             throw new \InvalidArgumentException('invalid adapter given');
             break;
     }
     $eventStore = new EventStore($adapter, new ProophActionEventEmitter());
     $result = [];
     foreach ($data['batchSizes'] as $batchSize) {
         for ($i = 0; $i < $this->repeats; $i++) {
             $events = [];
             $start = microtime(true);
             for ($b = 1; $b <= $batchSize * 2; $b++) {
                 $v1 = $b;
                 $b++;
                 $v2 = $b;
                 $events[] = UserCreated::with(['name' => 'Max Mustermann ' . $i . '-' . $b, 'email' => 'contact' . $i . '-' . $b . '@prooph.de'], $v1);
                 $events[] = UsernameChanged::with(['name' => 'John Doe ' . $i . '-' . $b], $v2);
             }
             $eventStore->beginTransaction();
             $eventStore->create(new Stream(new StreamName('user_stream'), new \ArrayIterator($events)));
             $eventStore->commit();
             $end = microtime(true);
             if ($connection instanceof Connection) {
                 $connection->executeQuery('DROP TABLE IF EXISTS user_stream');
             } else {
                 $connection->selectDB('event_store_adapter_benchmarks')->selectCollection('user_stream')->drop();
             }
             $diff = $end - $start;
             $result[$data['adapter'] . ' with batch size ' . $batchSize] = $diff;
         }
     }
     return $result;
 }
 /**
  * @test
  */
 public function it_publishes_take_snapshot_commands_for_all_known_aggregates()
 {
     $inMemoryAdapter = new InMemoryAdapter();
     $eventEmitter = new ProophActionEventEmitter();
     $eventStore = new EventStore($inMemoryAdapter, $eventEmitter);
     $repository = new AggregateRepository($eventStore, AggregateType::fromAggregateRootClass('ProophTest\\EventStore\\Mock\\User'), new ConfigurableAggregateTranslator());
     $result = [];
     $router = new CommandRouter();
     $router->route(TakeSnapshot::class)->to(function (TakeSnapshot $command) use(&$result) {
         $result[] = ['aggregate_type' => $command->aggregateType(), 'aggregate_id' => $command->aggregateId()];
     });
     $commandBus = new CommandBus();
     $commandBus->utilize($router);
     $plugin = new SnapshotPlugin($commandBus, 2);
     $plugin->setUp($eventStore);
     $eventStore->beginTransaction();
     $eventStore->create(new Stream(new StreamName('event_stream'), new \ArrayIterator()));
     $eventStore->commit();
     $eventStore->beginTransaction();
     $user = User::create('Alex', '*****@*****.**');
     $repository->addAggregateRoot($user);
     $eventStore->commit();
     $eventStore->beginTransaction();
     $user = $repository->getAggregateRoot($user->getId()->toString());
     $user->changeName('John');
     $user->changeName('Jane');
     $user->changeName('Jim');
     $eventStore->commit();
     $eventStore->beginTransaction();
     $eventWithoutMetadata1 = UsernameChanged::with(['new_name' => 'John Doe'], 5);
     $eventWithoutMetadata2 = UsernameChanged::with(['new_name' => 'Jane Doe'], 6);
     $eventStore->appendTo(new StreamName('event_stream'), new \ArrayIterator([$eventWithoutMetadata1, $eventWithoutMetadata2]));
     $eventStore->commit();
     $this->assertCount(2, $result);
     $this->assertArrayHasKey('aggregate_type', $result[0]);
     $this->assertArrayHasKey('aggregate_id', $result[0]);
     $this->assertArrayHasKey('aggregate_type', $result[1]);
     $this->assertArrayHasKey('aggregate_id', $result[1]);
     $this->assertEquals(User::class, $result[0]['aggregate_type']);
     $this->assertEquals(User::class, $result[1]['aggregate_type']);
 }
 */
require __DIR__ . '/../vendor/autoload.php';
use Prooph\Common\Event\ProophActionEventEmitter;
use Prooph\Common\Messaging\FQCNMessageFactory;
use Prooph\Common\Messaging\NoOpMessageConverter;
use Prooph\EventStore\Adapter\Flywheel\FlywheelEventStoreAdapter;
use Prooph\EventStore\EventStore;
use Prooph\EventStore\Stream\Stream;
use Prooph\EventStore\Stream\StreamName;
use ProophTest\EventStore\Mock\UserCreated;
use ProophTest\EventStore\Mock\UsernameChanged;
$rootDir = __DIR__ . '/event_store';
$adapter = new FlywheelEventStoreAdapter($rootDir, new FQCNMessageFactory(), new NoOpMessageConverter());
$actionEmitter = new ProophActionEventEmitter();
$eventStore = new EventStore($adapter, $actionEmitter);
$streamName = new StreamName('event_stream');
$stream = new Stream($streamName, new \ArrayIterator([]));
//
// Persist some events in the event store
//
$eventStore->beginTransaction();
$eventStore->create($stream);
$eventStore->appendTo($streamName, new \ArrayIterator([UserCreated::with(['name' => 'Max Mustermann'], 1)->withAddedMetadata('tag', 'person'), UsernameChanged::with(['name' => 'John Doe'], 2)->withAddedMetadata('tag', 'person')]));
$eventStore->commit();
//
// Load all the stored events
//
$persistedEventStream = $eventStore->load($streamName);
foreach ($persistedEventStream->streamEvents() as $event) {
    echo $event->payload()['name'] . PHP_EOL;
}
 /**
  * @test
  */
 public function it_publishes_take_snapshot_commands_by_event_name()
 {
     $this->eventStore->beginTransaction();
     $user = User::create('Alex', '*****@*****.**');
     $this->repository->addAggregateRoot($user);
     $this->eventStore->commit();
     $this->eventStore->beginTransaction();
     $user = $this->repository->getAggregateRoot($user->getId()->toString());
     $user->changeName('Jim');
     $this->eventStore->commit();
     $this->eventStore->beginTransaction();
     $eventWithoutMetadata1 = UsernameChanged::with(['new_name' => 'John Doe'], 5);
     $this->eventStore->appendTo(new StreamName('event_stream'), new \ArrayIterator([$eventWithoutMetadata1]));
     $this->eventStore->commit();
     $this->assertCount(1, $this->result);
     $this->assertArrayHasKey('aggregate_type', $this->result[0]);
     $this->assertArrayHasKey('aggregate_id', $this->result[0]);
     $this->assertEquals(User::class, $this->result[0]['aggregate_type']);
 }
 /**
  * @test
  */
 public function it_replays_in_correct_order_with_same_date_time()
 {
     $sameDate = new \DateTimeImmutable('now', new \DateTimeZone('UTC'));
     $streamEvent1 = UserCreated::withPayloadAndSpecifiedCreatedAt(['name' => 'Alex', 'email' => '*****@*****.**'], 1, $sameDate);
     $streamEvent2 = UsernameChanged::withPayloadAndSpecifiedCreatedAt(['new_name' => 'John Doe'], 2, $sameDate);
     $streamEvent3 = PostCreated::withPayloadAndSpecifiedCreatedAt(['text' => 'some text'], 1, $sameDate);
     $stream1 = new Stream(new StreamName('user'), new ArrayIterator([$streamEvent1]));
     $stream2 = new Stream(new StreamName('post'), new ArrayIterator([$streamEvent3]));
     $this->eventStore->beginTransaction();
     $this->eventStore->create($stream1);
     $this->eventStore->commit();
     $this->eventStore->beginTransaction();
     $this->eventStore->create($stream2);
     $this->eventStore->commit();
     $this->eventStore->beginTransaction();
     $this->eventStore->appendTo(new StreamName('user'), new ArrayIterator([$streamEvent2]));
     $this->eventStore->commit();
     $iterator = $this->eventStore->replay([new StreamName('user'), new StreamName('post')]);
     $count = 0;
     foreach ($iterator as $key => $event) {
         $count += 1;
         if (1 === $count) {
             $this->assertInstanceOf(UserCreated::class, $event);
         }
         if (2 === $count) {
             $this->assertInstanceOf(UsernameChanged::class, $event);
         }
         if (3 === $count) {
             $this->assertInstanceOf(PostCreated::class, $event);
         }
     }
     $this->assertEquals(3, $count);
 }
 /**
  * @test
  */
 public function it_replays_events_of_two_aggregates_in_a_single_stream_in_correct_order()
 {
     // Create stream
     $stream = $this->createStream();
     $this->adapter->create($stream);
     // Append new event
     $newEvent1 = UsernameChanged::with(['name' => 'John Doe'], 2)->withAddedMetadata('tag', 'person');
     $this->adapter->appendTo(new StreamName('user_stream'), new \ArrayIterator([$newEvent1]));
     // Append new event for different aggragate
     $newEvent2 = UserCreated::with(['name' => 'Jane Doe', 'email' => '*****@*****.**'], 1)->withAddedMetadata('tag', 'person');
     $this->adapter->appendTo(new StreamName('user_stream'), new \ArrayIterator([$newEvent2]));
     // Load events with replay
     $streamEvents = $this->adapter->replay(new StreamName('user_stream'), null, ['tag' => 'person']);
     $replayedPayloads = [];
     foreach ($streamEvents as $event) {
         $replayedPayloads[] = $event->payload();
     }
     $expectedPayloads = [['name' => 'Max Mustermann', 'email' => '*****@*****.**'], ['name' => 'John Doe'], ['name' => 'Jane Doe', 'email' => '*****@*****.**']];
     $this->assertEquals($expectedPayloads, $replayedPayloads);
 }
 /**
  * @test
  * @expectedException \Prooph\EventStore\Exception\ConcurrencyException
  */
 public function it_fails_to_write_with_duplicate_aggregate_id_and_version()
 {
     $streamEvent = UserCreated::with(['name' => 'Max Mustermann', 'email' => '*****@*****.**'], 1);
     $streamEvent = $streamEvent->withAddedMetadata('aggregate_id', 'one');
     $streamEvent = $streamEvent->withAddedMetadata('aggregate_type', 'user');
     $this->adapter->create(new Stream(new StreamName('Prooph\\Model\\User'), new \ArrayIterator([$streamEvent])));
     $streamEvent = UsernameChanged::with(['name' => 'John Doe'], 1);
     $streamEvent = $streamEvent->withAddedMetadata('aggregate_id', 'one');
     $streamEvent = $streamEvent->withAddedMetadata('aggregate_type', 'user');
     $this->adapter->appendTo(new StreamName('Prooph\\Model\\User'), new \ArrayIterator([$streamEvent]));
 }