簡體   English   中英

Doctrine 事件溯源 - ManyToMany

[英]Doctrine event sourcing - ManyToMany

問題:¿如何獲取具有給定狀態的所有應用程序?

假設

  • 應用程序的狀態是它的最后一個事件。
  • 事件具有增量 ID。

事件:

<?php

namespace DnD\RaHApiBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints\DateTime;

/**
 * Event
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class Event
{

  public function __construct($name = null, $type = null) {
    if (isset($name)) $this->name = $name;
    if (isset($type)) $this->type = $type;
    $this->eventDate = date_create(date("Y-m-d\TH:i:sO"));
  }

  /**
   * @var integer
   *
   * @ORM\Column(name="id", type="integer")
   * @ORM\Id
   * @ORM\GeneratedValue(strategy="AUTO")
   */
  private $id;

  /**
   * @var string
   *
   * @ORM\Column(name="type", type="string", length=255, nullable=true)
   * @Groups({"application_info"})
   */
  private $type;

  /**
   * @var string
   *
   * @ORM\Column(name="name", type="string", length=255)
   * @Groups({"application_info"})
   */
  private $name;


  /**
   * @var date of event.
   *
   * @ORM\Column(name="event_date", type="datetime")
   * @Groups({"application_info"})
   */
  private $eventDate;

  ...
}

應用:

<?php

namespace DnD\RaHApiBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints\DateTime;

/**
 * Solicitud de registro.
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="DnD\RaHApiBundle\Repository\ApplicationRepository")
 */
class Application
{

  public function __construct()
  {
    $pending = new Event("PENDING", "APPLICATION");

    $this->status = new ArrayCollection($pending);
  }

  /**
   * @var integer
   *
   * @ORM\Column(name="id", type="integer")
   * @ORM\Id
   * @ORM\GeneratedValue(strategy="AUTO")
   * @Groups({"application_info"})
   */
  private $id;

  /**
   * @var string
   *
   * @ORM\Column(name="name", type="string", length=255)
   * @Groups({"application_info"})
   */
  private $name;

  /**
   * @var string
   *
   * @ORM\Column(name="dni", type="string", length=255)
   * @Groups({"application_info"})
   */
  private $dni;

  /**
   * @var string
   *
   * @ORM\Column(name="email", type="string", length=255)
   * @Groups({"application_info"})
   */
  private $email;

  /**
   * @var string
   *
   * @ORM\ManyToMany(targetEntity="DnD\RaHApiBundle\Entity\Event", cascade={"persist"})
   * @ORM\JoinTable(
   *      name="applications_events",
   *      joinColumns={@ORM\JoinColumn(name="application_id", referencedColumnName="id")},
   *      inverseJoinColumns={@ORM\JoinColumn(name="event_id", referencedColumnName="id", unique=true)}
   * )
   * @Groups({"application_info"})
   */
  private $status;
}

¿有沒有辦法獲得具有給定“最后狀態”的應用程序?

您可以在Application存儲庫中進行自定義查詢。

使用學說 2 QueryBuilder您的查詢可能如下所示:

public function getApplicationsByStatusId($id)
{
    $applications = $this->createQueryBuilder('a')
        ->innerJoin('a.status', 's')
        ->where('s = :status_id')
        ->setParameter('status_id', $id)
        ->getQuery()
        ->getResult();

    return $applications;
}

由於它是ManyToMany關聯,因此您的結果可以是復數。

對於事件rela589n/doctrine-event-sourcing實現,您可以使用包rela589n/doctrine-event-sourcing


class Message implements AggregateRoot
{
    private Uuid $uuid;

    private MessageContent $content;

    private MessageStatus $status;

    private Carbon $createdAt;

    private Carbon $updatedAt;

    private User $user;

    private Chat $chat;

    /** @var Collection<MessageEvent> */
    private Collection $recordedEvents;

    /** @var MessageEvent[] */
    private array $newlyRecordedEvents = [];

    private function __construct(Uuid $uuid)
    {
        $this->uuid = $uuid;
        $this->status = MessageStatus::NEW();
        $this->recordedEvents = new ArrayCollection();
    }

    public static function write(Uuid $uuid, User $user, Chat $chat, MessageContent $content): self
    {
        $message = new self($uuid);
        $message->recordThat(
            MessageWritten::withData($message, $user, $chat, $content),
        );

        return $message;
    }

    public function edit(MessageContent $newContent): void
    {
        $this->recordThat(
            MessageWasEdited::with($this, $this->content, $newContent),
        );
    }

    private function recordThat(MessageEvent $event): void
    {
        switch (true) {
            case $event instanceof MessageWritten:
                $this->createdAt = \Carbon\Carbon::instance($event->getTimestamp());
                $this->user = $event->getUser();
                $this->chat = $event->getChat();
                $this->content = $event->getContent();
                $this->chat->addMessage($this);
                break;
            case $event instanceof MessageWasEdited:
                $this->content = $event->getNewContent();
                $this->status = $this->status->changingInto(MessageStatus::EDITED());
                break;
            default:
                throw new UnexpectedAggregateChangeEvent($event);
        }

        $this->updatedAt = \Carbon\Carbon::instance($event->getTimestamp());
        $this->newlyRecordedEvents[] = $event;
        $this->recordedEvents->add($event);
    }

    public function releaseEvents(): array
    {
        $events = $this->newlyRecordedEvents;
        $this->newlyRecordedEvents = [];
        return $events;
    }

    public function getPrimary(): Uuid
    {
        return $this->uuid;
    }

    public static function getPrimaryName(): string
    {
        return 'uuid';
    }
}

Message是您的實體, MessageWrittenMessageWasEdited是將保存在消息事件表中的事件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM