/**
  * @param Contract    $aggregateRootType
  * @param EventStream $eventStream
  *
  * @throws \Exception
  */
 public function append(Contract $aggregateRootType, EventStream $eventStream)
 {
     $statement = $this->insertQuery->prepare();
     try {
         while ($eventStream->hasNext()) {
             $event = $eventStream->next();
             $statement->bindValue(':aggregate_id', $event->aggregateRootIdentifier()->toString());
             $statement->bindValue(':aggregate_type', $aggregateRootType->toString());
             $statement->bindValue(':aggregate_version', $event->sequenceNumber());
             $statement->bindValue(':event_id', $event->identifier()->toString());
             $statement->bindValue(':event_payload', $this->eventSerializer->serializePayload($event));
             $statement->bindValue(':event_payload_type', $event->payloadType()->toString());
             $statement->bindValue(':event_metadata', $this->eventSerializer->serializeMetadata($event));
             $statement->bindValue(':event_metadata_type', $event->metadataType()->toString());
             $statement->execute();
             $statement->closeCursor();
         }
     } catch (\PDOException $exception) {
         // 23000 being the primary key duplicate entry error code.
         if ($exception->errorInfo[0] === '23000') {
             throw new ConcurrencyException('Concurrent modification detected.');
         }
         throw $exception;
     }
 }
 public function it_can_be_reconstituted_from_an_event_stream_history(EventStream $eventStream, Event $event)
 {
     $created = new Created(new UuidAggregateRootIdentifier());
     $deleted = new Deleted(new UuidAggregateRootIdentifier());
     $eventStream->hasNext()->willReturn(true, true, false);
     $eventStream->next()->willReturn($event);
     $event->sequenceNumber()->willReturn(1, 2);
     $event->payload()->willReturn($created, $deleted);
     $this->beConstructedThrough('loadFromHistory', [$eventStream]);
     $this->lastCommittedEventSequenceNumber()->shouldReturn(2);
     $this->isDeleted()->shouldReturn(true);
 }
 public function it_can_append_events_to_the_store(Contract $aggregateType, EventStream $eventStream, $query, \PDOStatement $statement, Event $event, AggregateRootIdentifier $aggregateRootIdentifier, MessageIdentifier $messageIdentifier)
 {
     $query->prepare()->willReturn($statement);
     $eventStream->hasNext()->willReturn(true, false);
     $eventStream->next()->willReturn($event);
     $event->aggregateRootIdentifier()->willReturn($aggregateRootIdentifier);
     $event->sequenceNumber()->willReturn(Argument::any());
     $event->identifier()->willReturn($messageIdentifier);
     $event->payloadType()->willReturn($aggregateType);
     $event->metadataType()->willReturn($aggregateType);
     $statement->bindValue(Argument::any(), Argument::any())->shouldBeCalled();
     $statement->execute()->shouldBeCalled();
     $statement->closeCursor()->shouldBeCalled();
     $this->append($aggregateType, $eventStream);
 }
 /**
  * @param Contract    $aggregateType
  * @param EventStream $eventStream
  *
  * @throws \Exception
  */
 public function append(Contract $aggregateType, EventStream $eventStream)
 {
     $statement = $this->insertQuery->prepare();
     $commitIdentifier = CommitIdentifier::generate()->toString();
     $committedAt = new \DateTime();
     while ($eventStream->hasNext()) {
         $event = $eventStream->next();
         $statement->bindValue(':aggregate_id', $event->aggregateRootIdentifier()->toString());
         $statement->bindValue(':aggregate_type', $aggregateType->toString());
         $statement->bindValue(':aggregate_version', $event->sequenceNumber());
         $statement->bindValue(':event_id', $event->identifier()->toString());
         $statement->bindValue(':event_payload', $this->eventSerializer->serializePayload($event));
         $statement->bindValue(':event_payload_type', $event->payloadType()->toString());
         $statement->bindValue(':event_metadata', $this->eventSerializer->serializeMetadata($event));
         $statement->bindValue(':event_metadata_type', $event->metadataType()->toString());
         $statement->bindValue(':commit_id', $commitIdentifier);
         $statement->bindValue(':committed_at', $committedAt->format('UTC'));
         $statement->execute();
         $statement->closeCursor();
     }
 }
 /**
  * Roll-out all events to reconstitute the state of the aggregate.
  *
  * @param EventStream $eventStream
  *
  * @return static
  */
 public static final function loadFromHistory(EventStream $eventStream)
 {
     $aggregate = new static();
     while ($eventStream->hasNext()) {
         $aggregate->replayChange($eventStream->next());
     }
     return $aggregate;
 }