diff --git a/src/Bundle/ChillDocStoreBundle/Entity/StoredObject.php b/src/Bundle/ChillDocStoreBundle/Entity/StoredObject.php index c849abacc..956cffbd2 100644 --- a/src/Bundle/ChillDocStoreBundle/Entity/StoredObject.php +++ b/src/Bundle/ChillDocStoreBundle/Entity/StoredObject.php @@ -97,6 +97,12 @@ class StoredObject implements Document, TrackCreationInterface #[ORM\OneToMany(mappedBy: 'storedObject', targetEntity: StoredObjectVersion::class, cascade: ['persist'], orphanRemoval: true)] private Collection&Selectable $versions; + /** + * @var Collection + */ + #[ORM\OneToMany(mappedBy: 'storedObject', targetEntity: StoredObjectLock::class, cascade: ['persist', 'remove', 'refresh', 'merge'])] + private Collection $locks; + /** * @param StoredObject::STATUS_* $status */ @@ -107,6 +113,22 @@ class StoredObject implements Document, TrackCreationInterface $this->uuid = Uuid::uuid4(); $this->versions = new ArrayCollection(); $this->prefix = self::generatePrefix(); + $this->locks = new ArrayCollection(); + } + + /** + * @internal use @see{StoredObjectLock::__construct} + */ + public function addLock(StoredObjectLock $lock): void + { + if (!$this->locks->contains($lock)) { + $this->locks->add($lock); + } + } + + public function removeLock(StoredObjectLock $lock): void + { + $this->locks->removeElement($lock); } public function addGenerationTrial(): self diff --git a/src/Bundle/ChillDocStoreBundle/Entity/StoredObjectLock.php b/src/Bundle/ChillDocStoreBundle/Entity/StoredObjectLock.php new file mode 100644 index 000000000..40fe9b284 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Entity/StoredObjectLock.php @@ -0,0 +1,121 @@ + + */ + #[ORM\ManyToMany(targetEntity: User::class)] + #[ORM\JoinTable(name: 'stored_object_lock_user', schema: 'chill_doc')] + #[ORM\JoinColumn(referencedColumnName: 'uuid', nullable: false)] + private Collection $users; + + /** + * @param list $users + */ + public function __construct( + #[ORM\ManyToOne(targetEntity: StoredObject::class, inversedBy: 'locks')] + private StoredObject $storedObject, + #[ORM\Column(type: 'string', length: 10, nullable: false, enumType: StoredObjectLockMethodEnum::class)] + private StoredObjectLockMethodEnum $method, + #[ORM\Column(type: 'datetimetz_immutable', nullable: false)] + private \DateTimeImmutable $createdAt, + #[ORM\Column(type: 'text', nullable: false, options: ['default' => ''])] + private string $token = '', + #[ORM\Column(type: 'datetimetz_immutable', nullable: true)] + private ?\DateTimeImmutable $expireAt = null, + array $users = [], + ) { + $this->uuid = Uuid::uuid7(); + $this->users = new ArrayCollection(); + $this->storedObject->addLock($this); + + foreach ($users as $user) { + $this->addUser($user); + } + } + + public function addUser(User $user): void + { + if (!$this->users->contains($user)) { + $this->users->add($user); + } + } + + public function removeUser(User $user): void + { + $this->users->removeElement($user); + } + + /** + * @return Collection + */ + public function getUsers(): Collection + { + return $this->users; + } + + public function setToken(string $token): void + { + $this->token = $token; + } + + public function setExpireAt(?\DateTimeImmutable $expireAt): void + { + $this->expireAt = $expireAt; + } + + public function getUuid(): UuidInterface + { + return $this->uuid; + } + + public function getStoredObject(): StoredObject + { + return $this->storedObject; + } + + public function getMethod(): StoredObjectLockMethodEnum + { + return $this->method; + } + + public function getToken(): string + { + return $this->token; + } + + public function getCreatedAt(): \DateTimeImmutable + { + return $this->createdAt; + } + + public function getExpireAt(): ?\DateTimeImmutable + { + return $this->expireAt; + } +} diff --git a/src/Bundle/ChillDocStoreBundle/Entity/StoredObjectLockMethodEnum.php b/src/Bundle/ChillDocStoreBundle/Entity/StoredObjectLockMethodEnum.php new file mode 100644 index 000000000..675c9fa85 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Entity/StoredObjectLockMethodEnum.php @@ -0,0 +1,18 @@ +addSql('CREATE TABLE chill_doc.stored_object_lock ( + uuid UUID NOT NULL, method VARCHAR(10) NOT NULL, + token TEXT DEFAULT \'\' NOT NULL, createdAt TIMESTAMP(0) WITH TIME ZONE NOT NULL, + expireAt TIMESTAMP(0) WITH TIME ZONE DEFAULT NULL, storedObject_id INT DEFAULT NULL, + PRIMARY KEY(uuid))'); + $this->addSql('CREATE INDEX IDX_E66CB6516C99C13A ON chill_doc.stored_object_lock (storedObject_id)'); + $this->addSql('COMMENT ON COLUMN chill_doc.stored_object_lock.uuid IS \'(DC2Type:uuid)\''); + $this->addSql('COMMENT ON COLUMN chill_doc.stored_object_lock.createdAt IS \'(DC2Type:datetimetz_immutable)\''); + $this->addSql('COMMENT ON COLUMN chill_doc.stored_object_lock.expireAt IS \'(DC2Type:datetimetz_immutable)\''); + $this->addSql('ALTER TABLE chill_doc.stored_object_lock ADD CONSTRAINT FK_E66CB6516C99C13A FOREIGN KEY (storedObject_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('CREATE TABLE chill_doc.stored_object_lock_user (storedobjectlock_uuid UUID NOT NULL, user_id INT NOT NULL, PRIMARY KEY(storedobjectlock_uuid, user_id))'); + $this->addSql('CREATE INDEX IDX_A4353741F52905D0 ON chill_doc.stored_object_lock_user (storedobjectlock_uuid)'); + $this->addSql('CREATE INDEX IDX_A4353741A76ED395 ON chill_doc.stored_object_lock_user (user_id)'); + $this->addSql('COMMENT ON COLUMN chill_doc.stored_object_lock_user.storedobjectlock_uuid IS \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE chill_doc.stored_object_lock_user ADD CONSTRAINT FK_A4353741F52905D0 FOREIGN KEY (storedobjectlock_uuid) REFERENCES chill_doc.stored_object_lock (uuid) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE chill_doc.stored_object_lock_user ADD CONSTRAINT FK_A4353741A76ED395 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE chill_doc.stored_object_lock_user DROP CONSTRAINT FK_A4353741F52905D0'); + $this->addSql('ALTER TABLE chill_doc.stored_object_lock_user DROP CONSTRAINT FK_A4353741A76ED395'); + $this->addSql('DROP TABLE chill_doc.stored_object_lock_user'); + $this->addSql('ALTER TABLE chill_doc.stored_object_lock DROP CONSTRAINT FK_E66CB6516C99C13A'); + $this->addSql('DROP TABLE chill_doc.stored_object_lock'); + } +}