refactor: standardize design
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace KTXM\PeopleProviderLocal\Store\Personal;
|
||||
namespace KTXM\ProviderLocalPeople\Store\Personal;
|
||||
|
||||
use KTXC\Db\DataStore;
|
||||
use KTXF\Resource\Filter\Filter;
|
||||
@@ -17,15 +17,13 @@ use KTXF\Resource\Range\Range;
|
||||
use KTXF\Resource\Range\RangeType;
|
||||
use KTXF\Resource\Sort\Sort;
|
||||
use KTXF\Utile\UUID;
|
||||
use KTXM\PeopleProviderLocal\Providers\Personal\Collection;
|
||||
use KTXM\PeopleProviderLocal\Providers\Personal\Entity;
|
||||
use KTXM\ProviderLocalPeople\Providers\Personal\CollectionResource;
|
||||
use KTXM\ProviderLocalPeople\Providers\Personal\EntityResource;
|
||||
|
||||
class Store {
|
||||
|
||||
protected string $_CollectionTable = 'people_provider_local_collection';
|
||||
protected string $_CollectionClass = 'KTXM\PeopleProviderLocal\Providers\Personal\Collection';
|
||||
protected string $_EntityTable = 'people_provider_local_entity';
|
||||
protected string $_EntityClass = 'KTXM\PeopleProviderLocal\Providers\Personal\Entity';
|
||||
protected string $_ChronicleTable = 'people_provider_local_chronicle';
|
||||
|
||||
protected array $_CollectionFilterAttributeMap = [
|
||||
@@ -145,8 +143,11 @@ class Store {
|
||||
$cursor = $this->_store->selectCollection($this->_CollectionTable)->find($query, $options);
|
||||
$list = [];
|
||||
foreach ($cursor as $entry) {
|
||||
$entry = (new Collection())->fromStore($entry);
|
||||
$list[$entry->id()] = $entry;
|
||||
$entry = $this->collectionFresh()->fromStore($entry);
|
||||
$identifier = $entry->identifier();
|
||||
if ($identifier !== null) {
|
||||
$list[(string) $identifier] = $entry;
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
@@ -177,9 +178,9 @@ class Store {
|
||||
* @param string $userId user identifier
|
||||
* @param string $identifier collection identifier
|
||||
*
|
||||
* @return Collection
|
||||
* @return CollectionResource
|
||||
*/
|
||||
public function collectionFetch(string $tenantId, string $userId, string $identifier): ?Collection {
|
||||
public function collectionFetch(string $tenantId, string $userId, string $identifier): ?CollectionResource {
|
||||
$cursor = $this->_store->selectCollection($this->_CollectionTable)->findOne([
|
||||
'tid' => $tenantId,
|
||||
'uid' => $userId,
|
||||
@@ -188,7 +189,7 @@ class Store {
|
||||
if ($cursor === null) {
|
||||
return null;
|
||||
}
|
||||
$entry = (new Collection())->fromStore($cursor);
|
||||
$entry = $this->collectionFresh()->fromStore($cursor);
|
||||
return $entry;
|
||||
}
|
||||
|
||||
@@ -197,10 +198,10 @@ class Store {
|
||||
*
|
||||
* @since Release 1.0.0
|
||||
*
|
||||
* @return Collection
|
||||
* @return CollectionResource
|
||||
*/
|
||||
public function collectionFresh(): Collection {
|
||||
return new $this->_CollectionClass;
|
||||
public function collectionFresh(): CollectionResource {
|
||||
return new CollectionResource();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -209,24 +210,24 @@ class Store {
|
||||
* @since Release 1.0.0
|
||||
*
|
||||
* @param string $userId user identifier
|
||||
* @param Collection $entity
|
||||
* @param CollectionResource $entity
|
||||
*
|
||||
* @return Collection
|
||||
* @return CollectionResource
|
||||
*/
|
||||
public function collectionCreate(string $tenantId, string $userId, Collection $entity): Collection {
|
||||
public function collectionCreate(string $tenantId, string $userId, CollectionResource $entity): CollectionResource {
|
||||
// convert entity to store format
|
||||
$data = $entity->toStore();
|
||||
// prepare data for creation
|
||||
$data['tid'] = $tenantId;
|
||||
$data['uid'] = $userId;
|
||||
$data['cid'] = UUID::v4();
|
||||
$data['signature'] = isset($data['signature']) && is_numeric($data['signature']) ? (int)$data['signature'] : 0;
|
||||
$data['createdOn'] = date('c');
|
||||
$data['modifiedOn'] = $data['createdOn'];
|
||||
// create entry
|
||||
$result = $this->_store->selectCollection($this->_CollectionTable)->insertOne($data);
|
||||
if ($result->getInsertedCount() === 1) {
|
||||
$entity = new Collection();
|
||||
$entity->fromStore($data);
|
||||
$entity = $this->collectionFresh()->fromStore($data);
|
||||
}
|
||||
return $entity;
|
||||
}
|
||||
@@ -237,15 +238,18 @@ class Store {
|
||||
* @since Release 1.0.0
|
||||
*
|
||||
* @param string $userId user identifier
|
||||
* @param Collection $entity
|
||||
* @param CollectionResource $entity
|
||||
*
|
||||
* @return Collection
|
||||
* @return CollectionResource
|
||||
*/
|
||||
public function collectionModify(string $tenantId, string $userId, Collection $entity): Collection {
|
||||
public function collectionModify(string $tenantId, string $userId, CollectionResource $entity): CollectionResource {
|
||||
// convert entity to store format
|
||||
$data = $entity->toStore();
|
||||
// prepare data for modification
|
||||
$cid = $entity->id();
|
||||
$cid = $entity->identifier();
|
||||
if ($cid === null) {
|
||||
throw new \InvalidArgumentException('Collection identifier is required for modification');
|
||||
}
|
||||
$data['modifiedOn'] = date('c');
|
||||
unset($data['_id'], $data['tid'], $data['uid'], $data['cid']);
|
||||
// modify entry
|
||||
@@ -261,12 +265,16 @@ class Store {
|
||||
*
|
||||
* @since Release 1.0.0
|
||||
*
|
||||
* @param Collection $entity
|
||||
* @param CollectionResource $entity
|
||||
*
|
||||
* @return Collection
|
||||
* @return CollectionResource
|
||||
*/
|
||||
public function collectionDestroy(string $tenantId, string $userId, Collection $entity): Collection {
|
||||
return $this->collectionDestroyById($tenantId, $userId, $entity->id()) ? $entity : $entity;
|
||||
public function collectionDestroy(string $tenantId, string $userId, CollectionResource $entity): CollectionResource {
|
||||
$identifier = $entity->identifier();
|
||||
if ($identifier === null) {
|
||||
return $entity;
|
||||
}
|
||||
return $this->collectionDestroyById($tenantId, $userId, (string) $identifier) ? $entity : $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -319,19 +327,32 @@ class Store {
|
||||
}
|
||||
|
||||
// Apply range/pagination if provided
|
||||
if ($range !== null && $range->type() === RangeType::TALLY) {
|
||||
// For TALLY ranges, use position (skip) and tally (limit)
|
||||
/** @var IRangeTally $rangeTally */
|
||||
$rangeTally = $range;
|
||||
$findOptions['skip'] = $rangeTally->getPosition();
|
||||
$findOptions['limit'] = $rangeTally->getTally();
|
||||
if ($range !== null) {
|
||||
if ($range->type() === RangeType::TALLY) {
|
||||
// For TALLY ranges, use position (skip) and tally (limit)
|
||||
/** @var \KTXF\Resource\Range\IRangeTally $rangeTally */
|
||||
$rangeTally = $range;
|
||||
$findOptions['skip'] = $rangeTally->getPosition();
|
||||
$findOptions['limit'] = $rangeTally->getTally();
|
||||
} elseif ($range->type() === RangeType::DATE) {
|
||||
// For DATE ranges, filter by date fields
|
||||
/** @var \KTXF\Resource\Range\IRangeDate $rangeDate */
|
||||
$rangeDate = $range;
|
||||
$query['data.startsOn'] = [
|
||||
'\$gte' => $rangeDate->getStart()->format('c'),
|
||||
'\$lte' => $rangeDate->getEnd()->format('c')
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$cursor = $this->_store->selectCollection($this->_EntityTable)->find($query, $findOptions);
|
||||
$list = [];
|
||||
foreach ($cursor as $entry) {
|
||||
$entity = (new Entity())->fromStore($entry);
|
||||
$list[$entity->id()] = $entity;
|
||||
$entity = $this->entityFresh()->fromStore($entry);
|
||||
$identifier = $entity->identifier();
|
||||
if ($identifier !== null) {
|
||||
$list[(string) $identifier] = $entity;
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
@@ -381,7 +402,7 @@ class Store {
|
||||
* @param string $collection collection identifier
|
||||
* @param string ...$identifiers entity identifiers (eid UUID strings)
|
||||
*
|
||||
* @return array<Entity>
|
||||
* @return array<EntityResource>
|
||||
*/
|
||||
public function entityFetch(string $tenantId, string $userId, string $collectionId, string ...$identifiers): array {
|
||||
// Query for entities using eid field
|
||||
@@ -394,8 +415,11 @@ class Store {
|
||||
|
||||
$list = [];
|
||||
foreach ($cursor as $entry) {
|
||||
$entity = (new Entity())->fromStore($entry);
|
||||
$list[$entity->id()] = $entity;
|
||||
$entity = $this->entityFresh()->fromStore($entry);
|
||||
$identifier = $entity->identifier();
|
||||
if ($identifier !== null) {
|
||||
$list[(string) $identifier] = $entity;
|
||||
}
|
||||
}
|
||||
|
||||
return $list;
|
||||
@@ -406,21 +430,12 @@ class Store {
|
||||
*
|
||||
* @since Release 1.0.0
|
||||
*
|
||||
* @return Entity
|
||||
* @return EntityResource
|
||||
*/
|
||||
public function entityFresh(): Entity {
|
||||
return new Entity();
|
||||
public function entityFresh(): EntityResource {
|
||||
return new EntityResource();
|
||||
}
|
||||
|
||||
/**
|
||||
* create a entity entry in the data store
|
||||
*
|
||||
* @since Release 1.0.0
|
||||
*
|
||||
* @param Entity $entity entity to create
|
||||
*
|
||||
* @return Entity
|
||||
*/
|
||||
/**
|
||||
* create a entity entry in the data store
|
||||
*
|
||||
@@ -428,11 +443,11 @@ class Store {
|
||||
*
|
||||
* @param string $userId user identifier
|
||||
* @param string $collection collection identifier
|
||||
* @param Entity $entity entity to create
|
||||
* @param EntityResource $entity entity to create
|
||||
*
|
||||
* @return Entity
|
||||
* @return EntityResource
|
||||
*/
|
||||
public function entityCreate(string $tenantId, string $userId, string $collectionId, Entity $entity): Entity {
|
||||
public function entityCreate(string $tenantId, string $userId, string $collectionId, EntityResource $entity): EntityResource {
|
||||
// convert entity to store format
|
||||
$data = $entity->toStore();
|
||||
// assign identifiers and timestamps
|
||||
@@ -449,7 +464,7 @@ class Store {
|
||||
|
||||
if ($result->getInsertedCount() === 1) {
|
||||
$eid = $data['eid'];
|
||||
$entity->fromStore(['eid' => $eid, 'tid' => $tenantId, 'uid' => $userId, 'cid' => $collectionId]);
|
||||
$entity = $this->entityFresh()->fromStore($data);
|
||||
// Chronicle the creation (operation 1)
|
||||
$this->chronicleDocument($tenantId, $collectionId, $eid, 1);
|
||||
}
|
||||
@@ -465,11 +480,11 @@ class Store {
|
||||
* @param string $userId user identifier
|
||||
* @param string $collection collection identifier
|
||||
* @param string $identifier entity identifier
|
||||
* @param Entity $entity entity to modify
|
||||
* @param EntityResource $entity entity to modify
|
||||
*
|
||||
* @return Entity
|
||||
* @return EntityResource
|
||||
*/
|
||||
public function entityModify(string $tenantId, string $userId, string $collectionId, string $identifier, Entity $entity): Entity {
|
||||
public function entityModify(string $tenantId, string $userId, string $collectionId, string $identifier, EntityResource $entity): EntityResource {
|
||||
// convert entity to store format
|
||||
$data = $entity->toStore();
|
||||
$data['modifiedOn'] = date('c');
|
||||
@@ -497,23 +512,26 @@ class Store {
|
||||
*
|
||||
* @param string $userId user identifier
|
||||
* @param string $collection collection identifier
|
||||
* @param Entity $entity entity to delete
|
||||
* @param EntityResource $entity entity to delete
|
||||
*
|
||||
* @return Entity
|
||||
* @return EntityResource
|
||||
*/
|
||||
public function entityDestroy(string $tenantId, string $userId, string $collectionId, Entity $entity): Entity {
|
||||
$identifier = $entity->id();
|
||||
public function entityDestroy(string $tenantId, string $userId, string $collectionId, EntityResource $entity): EntityResource {
|
||||
$identifier = $entity->identifier();
|
||||
if ($identifier === null) {
|
||||
return $entity;
|
||||
}
|
||||
|
||||
$result = $this->_store->selectCollection($this->_EntityTable)->deleteOne([
|
||||
'tid' => $tenantId,
|
||||
'uid' => $userId,
|
||||
'cid' => $collectionId,
|
||||
'eid' => $identifier
|
||||
'eid' => (string) $identifier
|
||||
]);
|
||||
|
||||
if ($result->getDeletedCount() === 1) {
|
||||
// Chronicle the deletion (operation 3)
|
||||
$this->chronicleDocument($tenantId, $collectionId, $identifier, 3);
|
||||
$this->chronicleDocument($tenantId, $collectionId, (string) $identifier, 3);
|
||||
}
|
||||
|
||||
return $entity;
|
||||
@@ -560,12 +578,19 @@ class Store {
|
||||
private function chronicleDocument(string $tid, string $cid, string $eid, int $operation): void {
|
||||
// retrieve current token from collection
|
||||
$collection = $this->_store->selectCollection($this->_CollectionTable)->findOne([
|
||||
'tid' => $tid,
|
||||
'cid' => $cid
|
||||
], [
|
||||
'projection' => ['signature' => 1, '_id' => 0]
|
||||
]);
|
||||
|
||||
$signature = $collection['signature'] ?? 0;
|
||||
|
||||
$signatureRaw = $collection['signature'] ?? 0;
|
||||
if (is_numeric($signatureRaw)) {
|
||||
$signature = (int)$signatureRaw;
|
||||
} else {
|
||||
$decoded = is_string($signatureRaw) ? base64_decode($signatureRaw, true) : false;
|
||||
$signature = (is_string($decoded) && is_numeric($decoded)) ? (int)$decoded : 0;
|
||||
}
|
||||
|
||||
// document operation in chronicle
|
||||
$this->_store->selectCollection($this->_ChronicleTable)->insertOne([
|
||||
@@ -577,10 +602,10 @@ class Store {
|
||||
'mutatedOn' => time(),
|
||||
]);
|
||||
|
||||
// increment token atomically
|
||||
// update signature as normalized numeric value
|
||||
$this->_store->selectCollection($this->_CollectionTable)->updateOne(
|
||||
['cid' => $cid],
|
||||
['$inc' => ['signature' => 1]]
|
||||
['tid' => $tid, 'cid' => $cid],
|
||||
['$set' => ['signature' => $signature + 1]]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user