diff --git a/app/config/collections2.php b/app/config/collections2.php index 99c043605..c069a2606 100644 --- a/app/config/collections2.php +++ b/app/config/collections2.php @@ -44,7 +44,7 @@ $collections = [ 'filters' => [], ], [ - '$id' => 'documentsPermission', + '$id' => 'permission', 'type' => Database::VAR_STRING, 'size' => 64, 'signed' => true, @@ -53,26 +53,6 @@ $collections = [ 'array' => false, 'filters' => [], ], - [ - '$id' => 'documentsRead', - 'type' => Database::VAR_STRING, - 'size' => 64, - 'signed' => true, - 'required' => false, - 'default' => null, - 'array' => true, - 'filters' => [], - ], - [ - '$id' => 'documentsWrite', - 'type' => Database::VAR_STRING, - 'size' => 64, - 'signed' => true, - 'required' => false, - 'default' => null, - 'array' => true, - 'filters' => [], - ], [ '$id' => 'attributes', 'type' => Database::VAR_STRING, @@ -130,6 +110,17 @@ $collections = [ 'array' => false, 'filters' => [], ], + [ + '$id' => 'key', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], [ '$id' => 'type', 'type' => Database::VAR_STRING, @@ -213,7 +204,7 @@ $collections = [ 'required' => false, 'default' => null, 'array' => false, - 'filters' => ['json'], + 'filters' => [], ], [ '$id' => 'filters', @@ -223,14 +214,14 @@ $collections = [ 'required' => false, 'default' => null, 'array' => true, - 'filters' => [], + 'filters' => ['json'], ], ], 'indexes' => [ - // [ + // [filters // '$id' => '_key_unique', // 'type' => Database::INDEX_UNIQUE, - // 'attributes' => ['_id', 'collectionId'], + // 'attributes' => ['key', 'collectionId'], // 'lengths' => [Database::LENGTH_KEY, Database::LENGTH_KEY], // 'orders' => [Database::ORDER_ASC, Database::ORDER_ASC], // ], diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index 6832c80f2..be9ffe861 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -30,6 +30,7 @@ use DeviceDetector\DeviceDetector; $attributesCallback = function ($collectionId, $attribute, $response, $dbForInternal, $dbForExternal, $database, $audits) { /** @var Utopia\Database\Document $document*/ /** @var Appwrite\Utopia\Response $response */ + /** @var Utopia\Database\Database $dbForInternal*/ /** @var Utopia\Database\Database $dbForExternal*/ /** @var Appwrite\Event\Event $database */ /** @var Appwrite\Event\Event $audits */ @@ -85,19 +86,28 @@ $attributesCallback = function ($collectionId, $attribute, $response, $dbForInte } } - $attribute = $dbForInternal->createDocument('attributes', new Document([ - '$id' => $attributeId, - 'collectionId' => $collectionId, - 'type' => $type, - 'status' => 'processing', // processing, available, failed - 'size' => $size, - 'required' => $required, - 'signed' => $signed, - 'default' => (string)$default, // Convert to proper type on fetch - 'array' => $array, - 'format' => $format, - 'filters' => $filters, - ])); + try { + $attribute = $dbForInternal->createDocument('attributes', new Document([ + '$id' => $collectionId.'_'.$attributeId, + 'key' => $attributeId, + 'collectionId' => $collectionId, + 'type' => $type, + 'status' => 'processing', // processing, available, failed + 'size' => $size, + 'required' => $required, + 'signed' => $signed, + 'default' => (string)$default, // Convert to proper type on fetch + 'array' => $array, + 'format' => $format, + 'filters' => $filters, + ])); + } catch (DuplicateException $th) { + throw new Exception('Attribute already exists', 409); + } + + if (!$dbForInternal->purgeDocument('collections', $collectionId)) { + throw new Exception('Failed to remove collection from the cache', 500); + } $database ->setParam('type', DATABASE_TYPE_CREATE_ATTRIBUTE) @@ -143,18 +153,17 @@ App::post('/v1/database/collections') $collectionId = $collectionId == 'unique()' ? $dbForExternal->getId() : $collectionId; + var_dump($permission); try { $dbForExternal->createCollection($collectionId); $collection = $dbForInternal->createDocument('collections', new Document([ '$id' => $collectionId, - '$read' => [], // Collection permissions themselves - '$write' => [], // Collection permissions themselves + '$read' => $read ?? [], // Collection permissions for collection documents (based on permission model) + '$write' => $write ?? [], // Collection permissions for collection documents (based on permission model) + 'permission' => $permission, // Permissions model type (document vs collection) 'dateCreated' => time(), 'dateUpdated' => time(), - 'documentsPermission' => $permission, // Permissions model type (document vs collection) - 'documentsRead' => $read ?? [], // Collection permissions for collection documents (based on permission model) - 'documentsWrite' => $write ?? [], // Collection permissions for collection documents (based on permission model) 'name' => $name, 'search' => implode(' ', [$collectionId, $name]), ])); @@ -373,11 +382,11 @@ App::put('/v1/database/collections/:collectionId') try { $collection = $dbForInternal->updateDocument('collections', $collection->getId(), $collection + ->setAttribute('$write', $write) + ->setAttribute('$read', $read) ->setAttribute('name', $name) + ->setAttribute('permission', $permission) ->setAttribute('dateUpdated', time()) - ->setAttribute('documentsPermission', $permission) - ->setAttribute('documentsRead', $read) - ->setAttribute('documentsWrite', $write) ->setAttribute('search', implode(' ', [$collectionId, $name])) ); } @@ -849,13 +858,13 @@ App::delete('/v1/database/collections/:collectionId/attributes/:attributeId') throw new Exception('Collection not found', 404); } - $attribute = $dbForInternal->getDocument('attributes', $attributeId); + $attribute = $dbForInternal->getDocument('attributes', $collectionId.'_'.$attributeId); if (empty($attribute->getId())) { throw new Exception('Attribute not found', 404); } - if (!$dbForInternal->deleteDocument('attributes', $attributeId)) { + if (!$dbForInternal->deleteDocument('attributes', $attribute->getId())) { throw new Exception('Failed to remove attribute from DB', 500); } @@ -865,6 +874,7 @@ App::delete('/v1/database/collections/:collectionId/attributes/:attributeId') $database ->setParam('type', DATABASE_TYPE_DELETE_ATTRIBUTE) + ->setParam('collection', $collection) ->setParam('document', $attribute) ; diff --git a/app/workers/database.php b/app/workers/database.php index c2757ed13..c4f6a61f6 100644 --- a/app/workers/database.php +++ b/app/workers/database.php @@ -24,9 +24,9 @@ class DatabaseV1 extends Worker $projectId = $this->args['projectId'] ?? ''; $type = $this->args['type'] ?? ''; - $collection = $this->args['collection'] ?? ''; + $collection = $this->args['collection'] ?? []; $collection = new Document($collection); - $document = $this->args['document'] ?? ''; + $document = $this->args['document'] ?? []; $document = new Document($document); switch (strval($type)) { @@ -62,10 +62,12 @@ class DatabaseV1 extends Worker */ protected function createAttribute(Document $collection, Document $attribute, string $projectId): void { + $dbForInternal = $this->getInternalDB($projectId); $dbForExternal = $this->getExternalDB($projectId); $collectionId = $collection->getId(); $id = $attribute->getAttribute('$id', ''); + $key = $attribute->getAttribute('key', ''); $type = $attribute->getAttribute('type', ''); $size = $attribute->getAttribute('size', 0); $required = $attribute->getAttribute('required', false); @@ -75,9 +77,17 @@ class DatabaseV1 extends Worker $format = $attribute->getAttribute('format', null); $filters = $attribute->getAttribute('filters', []); - $success = $dbForExternal->createAttribute($collectionId, $id, $type, $size, $required, $default, $signed, $array, $format, $filters); - if ($success) { - $removed = $dbForExternal->removeAttributeInQueue($collectionId, $id); + try { + $success = $dbForExternal->createAttribute($collectionId, $key, $type, $size, $required, $default, $signed, $array, $format, $filters); + + $dbForInternal->updateDocument('attributes', $id, $attribute->setAttribute('status', ($success) ? 'available' : 'failed')); + } catch (\Throwable $th) { + Console::error($th->getMessage()); + $dbForInternal->updateDocument('attributes', $id, $attribute->setAttribute('status', 'failed')); + } + + if (!$dbForInternal->purgeDocument('collections', $collectionId)) { + throw new Exception('Failed to remove collection from the cache', 500); } } diff --git a/docker-compose.yml b/docker-compose.yml index 9e2da7436..b7a872c84 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -214,6 +214,7 @@ services: volumes: - ./app:/usr/src/code/app - ./src:/usr/src/code/src + - ./vendor/utopia-php/database:/usr/src/code/vendor/utopia-php/database depends_on: - redis - mariadb diff --git a/src/Appwrite/Utopia/Response/Model/Attribute.php b/src/Appwrite/Utopia/Response/Model/Attribute.php index d80251eeb..7a0dd733f 100644 --- a/src/Appwrite/Utopia/Response/Model/Attribute.php +++ b/src/Appwrite/Utopia/Response/Model/Attribute.php @@ -10,17 +10,11 @@ class Attribute extends Model public function __construct() { $this - ->addRule('$collection', [ + ->addRule('key', [ 'type' => self::TYPE_STRING, - 'description' => 'Collection ID.', + 'description' => 'Attribute Key.', 'default' => '', - 'example' => '5e5ea5c16d55', - ]) - ->addRule('$id', [ - 'type' => self::TYPE_STRING, - 'description' => 'Attribute ID.', - 'default' => '', - 'example' => '60ccf71b98a2d', + 'example' => 'fullName', ]) ->addRule('type', [ 'type' => self::TYPE_STRING, @@ -28,6 +22,12 @@ class Attribute extends Model 'default' => '', 'example' => 'string', ]) + ->addRule('status', [ + 'type' => self::TYPE_STRING, + 'description' => 'Attribute status. Possible values: `available`, `processing`, or `failed`', + 'default' => '', + 'example' => 'string', + ]) ->addRule('size', [ 'type' => self::TYPE_STRING, 'description' => 'Attribute size.', diff --git a/src/Appwrite/Utopia/Response/Model/Collection.php b/src/Appwrite/Utopia/Response/Model/Collection.php index 4c1db0f53..398bcf770 100644 --- a/src/Appwrite/Utopia/Response/Model/Collection.php +++ b/src/Appwrite/Utopia/Response/Model/Collection.php @@ -35,7 +35,13 @@ class Collection extends Model 'type' => self::TYPE_STRING, 'description' => 'Collection name.', 'default' => '', - 'example' => '', + 'example' => 'My Collection', + ]) + ->addRule('permission', [ + 'type' => self::TYPE_STRING, + 'description' => 'Collection permission model. Possible values: `document` or `collection`', + 'default' => '', + 'example' => 'document', ]) ->addRule('attributes', [ 'type' => Response::MODEL_ATTRIBUTE, @@ -51,20 +57,6 @@ class Collection extends Model 'example' => new stdClass, 'array' => true ]) - ->addRule('attributesInQueue', [ - 'type' => Response::MODEL_ATTRIBUTE, - 'description' => 'Collection attributes in creation queue.', - 'default' => [], - 'example' => new stdClass, - 'array' => true - ]) - ->addRule('indexesInQueue', [ - 'type' => Response::MODEL_INDEX, - 'description' => 'Collection indexes in creation queue.', - 'default' => [], - 'example' => new stdClass, - 'array' => true - ]) ; } diff --git a/src/Appwrite/Utopia/Response/Model/Func.php b/src/Appwrite/Utopia/Response/Model/Func.php index 6c1ba151f..72e6c8927 100644 --- a/src/Appwrite/Utopia/Response/Model/Func.php +++ b/src/Appwrite/Utopia/Response/Model/Func.php @@ -43,7 +43,7 @@ class Func extends Model ]) ->addRule('status', [ 'type' => self::TYPE_STRING, - 'description' => 'Function status. Possible values: disabled, enabled', + 'description' => 'Function status. Possible values: `disabled`, `enabled`', 'default' => '', 'example' => 'enabled', ])