diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Attributes/Boolean/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Attributes/Boolean/Create.php index 1db55ba33d..57cff8a75f 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Attributes/Boolean/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Attributes/Boolean/Create.php @@ -30,7 +30,8 @@ class Create extends Action { $this->setResponseModel(UtopiaResponse::MODEL_ATTRIBUTE_BOOLEAN); - $this->setHttpMethod(self::HTTP_REQUEST_METHOD_POST) + $this + ->setHttpMethod(self::HTTP_REQUEST_METHOD_POST) ->setHttpPath('/v1/databases/:databaseId/collections/:collectionId/attributes/boolean') ->desc('Create boolean attribute') ->groups(['api', 'database', 'schema']) diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Attributes/Boolean/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Attributes/Boolean/Update.php index 41a0c5a621..7a2db8e74f 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Attributes/Boolean/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Attributes/Boolean/Update.php @@ -30,7 +30,8 @@ class Update extends Action { $this->setResponseModel(UtopiaResponse::MODEL_ATTRIBUTE_BOOLEAN); - $this->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH) + $this + ->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH) ->setHttpPath('/v1/databases/:databaseId/collections/:collectionId/attributes/boolean/:key') ->desc('Update boolean attribute') ->groups(['api', 'database', 'schema']) diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Action.php b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Action.php deleted file mode 100644 index a9415fded3..0000000000 --- a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Action.php +++ /dev/null @@ -1,417 +0,0 @@ -getAttribute('key'); - $type = $column->getAttribute('type', ''); - $size = $column->getAttribute('size', 0); - $required = $column->getAttribute('required', true); - $signed = $column->getAttribute('signed', true); // integers are signed by default - $array = $column->getAttribute('array', false); - $format = $column->getAttribute('format', ''); - $formatOptions = $column->getAttribute('formatOptions', []); - $filters = $column->getAttribute('filters', []); // filters are hidden from the endpoint - $default = $column->getAttribute('default'); - $options = $column->getAttribute('options', []); - - $db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); - - if ($db->isEmpty()) { - throw new Exception(Exception::DATABASE_NOT_FOUND); - } - - $table = $dbForProject->getDocument('database_' . $db->getInternalId(), $tableId); - - if ($table->isEmpty()) { - throw new Exception(Exception::TABLE_NOT_FOUND); - } - - if (!empty($format)) { - if (!Structure::hasFormat($format, $type)) { - throw new Exception(Exception::COLUMN_FORMAT_UNSUPPORTED, "Format {$format} not available for {$type} columns."); - } - } - - // Must throw here since dbForProject->createAttribute is performed by db worker - if ($required && isset($default)) { - throw new Exception(Exception::COLUMN_DEFAULT_UNSUPPORTED, 'Cannot set default value for required column'); - } - - if ($array && isset($default)) { - throw new Exception(Exception::COLUMN_DEFAULT_UNSUPPORTED, 'Cannot set default value for array columns'); - } - - if ($type === Database::VAR_RELATIONSHIP) { - $options['side'] = Database::RELATION_SIDE_PARENT; - $relatedTable = $dbForProject->getDocument('database_' . $db->getInternalId(), $options['relatedCollection'] ?? ''); - if ($relatedTable->isEmpty()) { - throw new Exception(Exception::TABLE_NOT_FOUND, 'The related table was not found.'); - } - } - - try { - $column = new Document([ - '$id' => ID::custom($db->getInternalId() . '_' . $table->getInternalId() . '_' . $key), - 'key' => $key, - 'databaseInternalId' => $db->getInternalId(), - 'databaseId' => $db->getId(), - 'collectionInternalId' => $table->getInternalId(), - 'collectionId' => $tableId, - 'type' => $type, - 'status' => 'processing', // processing, available, failed, deleting, stuck - 'size' => $size, - 'required' => $required, - 'signed' => $signed, - 'default' => $default, - 'array' => $array, - 'format' => $format, - 'formatOptions' => $formatOptions, - 'filters' => $filters, - 'options' => $options, - ]); - - $dbForProject->checkAttribute($table, $column); - $column = $dbForProject->createDocument('attributes', $column); - } catch (DuplicateException) { - throw new Exception(Exception::COLUMN_ALREADY_EXISTS); - } catch (LimitException) { - throw new Exception(Exception::COLUMN_LIMIT_EXCEEDED); - } catch (Throwable $e) { - $dbForProject->purgeCachedDocument('database_' . $db->getInternalId(), $tableId); - $dbForProject->purgeCachedCollection('database_' . $db->getInternalId() . '_collection_' . $table->getInternalId()); - throw $e; - } - - $dbForProject->purgeCachedDocument('database_' . $db->getInternalId(), $tableId); - $dbForProject->purgeCachedCollection('database_' . $db->getInternalId() . '_collection_' . $table->getInternalId()); - - if ($type === Database::VAR_RELATIONSHIP && $options['twoWay']) { - $twoWayKey = $options['twoWayKey']; - $options['relatedCollection'] = $table->getId(); - $options['twoWayKey'] = $key; - $options['side'] = Database::RELATION_SIDE_CHILD; - - try { - $twoWayAttribute = new Document([ - '$id' => ID::custom($db->getInternalId() . '_' . $relatedTable->getInternalId() . '_' . $twoWayKey), - 'key' => $twoWayKey, - 'databaseInternalId' => $db->getInternalId(), - 'databaseId' => $db->getId(), - 'collectionInternalId' => $relatedTable->getInternalId(), - 'collectionId' => $relatedTable->getId(), - 'type' => $type, - 'status' => 'processing', // processing, available, failed, deleting, stuck - 'size' => $size, - 'required' => $required, - 'signed' => $signed, - 'default' => $default, - 'array' => $array, - 'format' => $format, - 'formatOptions' => $formatOptions, - 'filters' => $filters, - 'options' => $options, - ]); - - $dbForProject->checkAttribute($relatedTable, $twoWayAttribute); - $dbForProject->createDocument('attributes', $twoWayAttribute); - } catch (DuplicateException) { - $dbForProject->deleteDocument('attributes', $column->getId()); - throw new Exception(Exception::COLUMN_ALREADY_EXISTS); - } catch (LimitException) { - $dbForProject->deleteDocument('attributes', $column->getId()); - throw new Exception(Exception::COLUMN_LIMIT_EXCEEDED); - } catch (Throwable $e) { - $dbForProject->purgeCachedDocument('database_' . $db->getInternalId(), $relatedTable->getId()); - $dbForProject->purgeCachedCollection('database_' . $db->getInternalId() . '_collection_' . $relatedTable->getInternalId()); - throw $e; - } - - $dbForProject->purgeCachedDocument('database_' . $db->getInternalId(), $relatedTable->getId()); - $dbForProject->purgeCachedCollection('database_' . $db->getInternalId() . '_collection_' . $relatedTable->getInternalId()); - } - - $queueForDatabase - ->setType(DATABASE_TYPE_CREATE_ATTRIBUTE) - ->setDatabase($db) - ->setTable($table) - ->setRow($column); - - $queueForEvents - ->setContext('table', $table) - ->setContext('database', $db) - ->setParam('databaseId', $databaseId) - ->setParam('tableId', $table->getId()) - ->setParam('columnId', $column->getId()); - - $response->setStatusCode(SwooleResponse::STATUS_CODE_CREATED); - - return $column; - } - - protected function updateColumn( - string $databaseId, - string $tableId, - string $key, - Database $dbForProject, - Event $queueForEvents, - string $type, - int $size = null, - string $filter = null, - string|bool|int|float $default = null, - bool $required = null, - int|float|null $min = null, - int|float|null $max = null, - array $elements = null, - array $options = [], - string $newKey = null, - ): Document { - $db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); - - if ($db->isEmpty()) { - throw new Exception(Exception::DATABASE_NOT_FOUND); - } - - $table = $dbForProject->getDocument('database_' . $db->getInternalId(), $tableId); - - if ($table->isEmpty()) { - throw new Exception(Exception::TABLE_NOT_FOUND); - } - - $column = $dbForProject->getDocument('attributes', $db->getInternalId() . '_' . $table->getInternalId() . '_' . $key); - - if ($column->isEmpty()) { - throw new Exception(Exception::COLUMN_NOT_FOUND); - } - - if ($column->getAttribute('status') !== 'available') { - throw new Exception(Exception::COLUMN_NOT_AVAILABLE); - } - - if ($column->getAttribute(('type') !== $type)) { - throw new Exception(Exception::COLUMN_TYPE_INVALID); - } - - if ($column->getAttribute('type') === Database::VAR_STRING && $column->getAttribute(('filter') !== $filter)) { - throw new Exception(Exception::COLUMN_TYPE_INVALID); - } - - if ($required && isset($default)) { - throw new Exception(Exception::COLUMN_DEFAULT_UNSUPPORTED, 'Cannot set default value for required column'); - } - - if ($column->getAttribute('array', false) && isset($default)) { - throw new Exception(Exception::COLUMN_DEFAULT_UNSUPPORTED, 'Cannot set default value for array columns'); - } - - $tableId = 'database_' . $db->getInternalId() . '_collection_' . $table->getInternalId(); - - $column - ->setAttribute('default', $default) - ->setAttribute('required', $required); - - if (!empty($size)) { - $column->setAttribute('size', $size); - } - - switch ($column->getAttribute('format')) { - case APP_DATABASE_ATTRIBUTE_INT_RANGE: - case APP_DATABASE_ATTRIBUTE_FLOAT_RANGE: - $min ??= $column->getAttribute('formatOptions')['min']; - $max ??= $column->getAttribute('formatOptions')['max']; - - if ($min > $max) { - throw new Exception(Exception::COLUMN_VALUE_INVALID, 'Minimum value must be lesser than maximum value'); - } - - if ($column->getAttribute('format') === APP_DATABASE_ATTRIBUTE_INT_RANGE) { - $validator = new Range($min, $max, Database::VAR_INTEGER); - } else { - $validator = new Range($min, $max, Database::VAR_FLOAT); - - if (!is_null($default)) { - $default = \floatval($default); - } - } - - if (!is_null($default) && !$validator->isValid($default)) { - throw new Exception(Exception::COLUMN_VALUE_INVALID, $validator->getDescription()); - } - - $options = [ - 'min' => $min, - 'max' => $max - ]; - $column->setAttribute('formatOptions', $options); - - break; - case APP_DATABASE_ATTRIBUTE_ENUM: - if (empty($elements)) { - throw new Exception(Exception::COLUMN_VALUE_INVALID, 'Enum elements must not be empty'); - } - - foreach ($elements as $element) { - if (\strlen($element) === 0) { - throw new Exception(Exception::COLUMN_VALUE_INVALID, 'Each enum element must not be empty'); - } - } - - if (!is_null($default) && !in_array($default, $elements)) { - throw new Exception(Exception::COLUMN_VALUE_INVALID, 'Default value not found in elements'); - } - - $options = [ - 'elements' => $elements - ]; - - $column->setAttribute('formatOptions', $options); - - break; - } - - if ($type === Database::VAR_RELATIONSHIP) { - $primaryRowOptions = \array_merge($column->getAttribute('options', []), $options); - $column->setAttribute('options', $primaryRowOptions); - try { - $dbForProject->updateRelationship( - collection: $tableId, - id: $key, - newKey: $newKey, - onDelete: $primaryRowOptions['onDelete'], - ); - } catch (NotFoundException) { - throw new Exception(Exception::COLUMN_NOT_FOUND); - } - - if ($primaryRowOptions['twoWay']) { - $relatedTable = $dbForProject->getDocument('database_' . $db->getInternalId(), $primaryRowOptions['relatedCollection']); - - $relatedColumn = $dbForProject->getDocument('attributes', $db->getInternalId() . '_' . $relatedTable->getInternalId() . '_' . $primaryRowOptions['twoWayKey']); - - if (!empty($newKey) && $newKey !== $key) { - $options['twoWayKey'] = $newKey; - } - - $relatedOptions = \array_merge($relatedColumn->getAttribute('options'), $options); - $relatedColumn->setAttribute('options', $relatedOptions); - $dbForProject->updateDocument('attributes', $db->getInternalId() . '_' . $relatedTable->getInternalId() . '_' . $primaryRowOptions['twoWayKey'], $relatedColumn); - - $dbForProject->purgeCachedDocument('database_' . $db->getInternalId(), $relatedTable->getId()); - } - } else { - try { - $dbForProject->updateAttribute( - collection: $tableId, - id: $key, - size: $size, - required: $required, - default: $default, - formatOptions: $options, - newKey: $newKey ?? null - ); - } catch (TruncateException) { - throw new Exception(Exception::COLUMN_INVALID_RESIZE); - } catch (NotFoundException) { - throw new Exception(Exception::COLUMN_NOT_FOUND); - } catch (LimitException) { - throw new Exception(Exception::COLUMN_LIMIT_EXCEEDED); - } catch (IndexException $e) { - throw new Exception(Exception::INDEX_INVALID, $e->getMessage()); - } - } - - if (!empty($newKey) && $key !== $newKey) { - $originalUid = $column->getId(); - - $column - ->setAttribute('$id', ID::custom($db->getInternalId() . '_' . $table->getInternalId() . '_' . $newKey)) - ->setAttribute('key', $newKey); - - $dbForProject->updateDocument('attributes', $originalUid, $column); - - /** - * @var Document $index - */ - foreach ($table->getAttribute('indexes') as $index) { - /** - * @var string[] $columns - */ - $columns = $index->getAttribute('attributes', []); - $found = \array_search($key, $columns); - - if ($found !== false) { - $columns[$found] = $newKey; - $index->setAttribute('attributes', $columns); - $dbForProject->updateDocument('indexes', $index->getId(), $index); - } - } - } else { - $column = $dbForProject->updateDocument('attributes', $db->getInternalId() . '_' . $table->getInternalId() . '_' . $key, $column); - } - - $dbForProject->purgeCachedDocument('database_' . $db->getInternalId(), $table->getId()); - - $queueForEvents - ->setContext('table', $table) - ->setContext('database', $db) - ->setParam('databaseId', $databaseId) - ->setParam('tableId', $table->getId()) - ->setParam('columnId', $column->getId()); - - return $column; - } -} diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Boolean/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Boolean/Create.php index 7e1331a637..385c631493 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Boolean/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Boolean/Create.php @@ -4,21 +4,19 @@ namespace Appwrite\Platform\Modules\Databases\Http\Columns\Boolean; use Appwrite\Event\Database as EventDatabase; use Appwrite\Event\Event; -use Appwrite\Platform\Modules\Databases\Http\Columns\Action as ColumnAction; +use Appwrite\Platform\Modules\Databases\Http\Attributes\Boolean\Create as BooleanCreate; use Appwrite\SDK\AuthType; use Appwrite\SDK\Method; use Appwrite\SDK\Response as SDKResponse; use Appwrite\Utopia\Response as UtopiaResponse; use Utopia\Database\Database; -use Utopia\Database\Document; use Utopia\Database\Validator\Key; use Utopia\Database\Validator\UID; -use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Swoole\Response as SwooleResponse; use Utopia\Validator\Boolean; -class Create extends ColumnAction +class Create extends BooleanCreate { use HTTP; @@ -29,9 +27,12 @@ class Create extends ColumnAction public function __construct() { - $this->setHttpMethod(Action::HTTP_REQUEST_METHOD_POST) + $this->setContext(DATABASE_COLUMNS_CONTEXT); + $this->setResponseModel(UtopiaResponse::MODEL_COLUMN_BOOLEAN); + + $this + ->setHttpMethod(self::HTTP_REQUEST_METHOD_POST) ->setHttpPath('/v1/databases/:databaseId/tables/:tableId/columns/boolean') - ->httpAlias('/v1/databases/:databaseId/collections/:tableId/attributes/boolean') ->desc('Create boolean column') ->groups(['api', 'database', 'schema']) ->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create') @@ -41,14 +42,14 @@ class Create extends ColumnAction ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( namespace: 'databases', - group: 'columns', - name: 'createBooleanColumn', + group: $this->getSdkGroup(), + name: self::getName(), description: '/docs/references/databases/create-boolean-attribute.md', auth: [AuthType::KEY], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_ACCEPTED, - model: UtopiaResponse::MODEL_COLUMN_BOOLEAN, + model: $this->getResponseModel(), ) ] )) @@ -62,23 +63,8 @@ class Create extends ColumnAction ->inject('dbForProject') ->inject('queueForDatabase') ->inject('queueForEvents') - ->callback([$this, 'action']); - } - - public function action(string $databaseId, string $tableId, string $key, ?bool $required, ?bool $default, bool $array, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents): void - { - - $column = $this->createColumn($databaseId, $tableId, new Document([ - 'key' => $key, - 'type' => Database::VAR_BOOLEAN, - 'size' => 0, - 'required' => $required, - 'default' => $default, - 'array' => $array, - ]), $response, $dbForProject, $queueForDatabase, $queueForEvents); - - $response - ->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED) - ->dynamic($column, UtopiaResponse::MODEL_COLUMN_BOOLEAN); + ->callback(function (string $databaseId, string $tableId, string $key, ?bool $required, ?bool $default, bool $array, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { + parent::action($databaseId, $tableId, $key, $required, $default, $array, $response, $dbForProject, $queueForDatabase, $queueForEvents); + }); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Boolean/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Boolean/Update.php index 6725e0c817..7b0754ccc7 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Boolean/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Boolean/Update.php @@ -3,7 +3,7 @@ namespace Appwrite\Platform\Modules\Databases\Http\Columns\Boolean; use Appwrite\Event\Event; -use Appwrite\Platform\Modules\Databases\Http\Columns\Action as ColumnAction; +use Appwrite\Platform\Modules\Databases\Http\Attributes\Boolean\Update as BooleanUpdate; use Appwrite\SDK\AuthType; use Appwrite\SDK\ContentType; use Appwrite\SDK\Method; @@ -12,13 +12,12 @@ use Appwrite\Utopia\Response as UtopiaResponse; use Utopia\Database\Database; use Utopia\Database\Validator\Key; use Utopia\Database\Validator\UID; -use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Swoole\Response as SwooleResponse; use Utopia\Validator\Boolean; use Utopia\Validator\Nullable; -class Update extends ColumnAction +class Update extends BooleanUpdate { use HTTP; @@ -29,9 +28,12 @@ class Update extends ColumnAction public function __construct() { - $this->setHttpMethod(Action::HTTP_REQUEST_METHOD_PATCH) + $this->setContext(DATABASE_COLUMNS_CONTEXT); + $this->setResponseModel(UtopiaResponse::MODEL_COLUMN_BOOLEAN); + + $this + ->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH) ->setHttpPath('/v1/databases/:databaseId/tables/:tableId/columns/boolean/:key') - ->httpAlias('/v1/databases/:databaseId/collections/:tableId/attributes/boolean/:key') ->desc('Update boolean column') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') @@ -41,14 +43,14 @@ class Update extends ColumnAction ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( namespace: 'databases', - group: 'columns', - name: 'updateBooleanColumn', + group: $this->getSdkGroup(), + name: self::getName(), description: '/docs/references/databases/update-boolean-attribute.md', auth: [AuthType::KEY], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_OK, - model: UtopiaResponse::MODEL_COLUMN_BOOLEAN, + model: $this->getResponseModel(), ) ], contentType: ContentType::JSON @@ -62,25 +64,8 @@ class Update extends ColumnAction ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') - ->callback([$this, 'action']); - } - - public function action(string $databaseId, string $tableId, string $key, ?bool $required, ?bool $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents): void - { - $column = $this->updateColumn( - databaseId: $databaseId, - tableId: $tableId, - key: $key, - dbForProject: $dbForProject, - queueForEvents: $queueForEvents, - type: Database::VAR_BOOLEAN, - default: $default, - required: $required, - newKey: $newKey - ); - - $response - ->setStatusCode(SwooleResponse::STATUS_CODE_OK) - ->dynamic($column, UtopiaResponse::MODEL_COLUMN_BOOLEAN); + ->callback(function (string $databaseId, string $tableId, string $key, ?bool $required, ?bool $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents) { + parent::action($databaseId, $tableId, $key, $required, $default, $newKey, $response, $dbForProject, $queueForEvents); + }); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Datetime/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Datetime/Create.php index 29ce39789e..80031d61ab 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Datetime/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Datetime/Create.php @@ -4,22 +4,20 @@ namespace Appwrite\Platform\Modules\Databases\Http\Columns\Datetime; use Appwrite\Event\Database as EventDatabase; use Appwrite\Event\Event; -use Appwrite\Platform\Modules\Databases\Http\Columns\Action as ColumnAction; +use Appwrite\Platform\Modules\Databases\Http\Attributes\Datetime\Create as DatetimeCreate; use Appwrite\SDK\AuthType; use Appwrite\SDK\Method; use Appwrite\SDK\Response as SDKResponse; use Appwrite\Utopia\Response as UtopiaResponse; use Utopia\Database\Database; -use Utopia\Database\Document; use Utopia\Database\Validator\Datetime as DatetimeValidator; use Utopia\Database\Validator\Key; use Utopia\Database\Validator\UID; -use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Swoole\Response as SwooleResponse; use Utopia\Validator\Boolean; -class Create extends ColumnAction +class Create extends DatetimeCreate { use HTTP; @@ -30,10 +28,12 @@ class Create extends ColumnAction public function __construct() { + $this->setContext(DATABASE_COLUMNS_CONTEXT); + $this->setResponseModel(UtopiaResponse::MODEL_COLUMN_DATETIME); + $this - ->setHttpMethod(Action::HTTP_REQUEST_METHOD_POST) + ->setHttpMethod(self::HTTP_REQUEST_METHOD_POST) ->setHttpPath('/v1/databases/:databaseId/tables/:tableId/columns/datetime') - ->httpAlias('/v1/databases/:databaseId/collections/:tableId/attributes/datetime') ->desc('Create datetime column') ->groups(['api', 'database']) ->label('scope', 'collections.write') @@ -43,14 +43,14 @@ class Create extends ColumnAction ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( namespace: 'databases', - group: 'columns', - name: 'createDatetimeColumn', + group: $this->getSdkGroup(), + name: self::getName(), description: '/docs/references/databases/create-datetime-attribute.md', auth: [AuthType::KEY], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_ACCEPTED, - model: UtopiaResponse::MODEL_COLUMN_DATETIME, + model: $this->getResponseModel(), ) ] )) @@ -64,43 +64,8 @@ class Create extends ColumnAction ->inject('dbForProject') ->inject('queueForDatabase') ->inject('queueForEvents') - ->callback([$this, 'action']); - } - - public function action( - string $databaseId, - string $tableId, - string $key, - ?bool $required, - ?string $default, - bool $array, - UtopiaResponse $response, - Database $dbForProject, - EventDatabase $queueForDatabase, - Event $queueForEvents - ): void { - $filters = ['datetime']; - - $column = $this->createColumn( - $databaseId, - $tableId, - new Document([ - 'key' => $key, - 'type' => Database::VAR_DATETIME, - 'size' => 0, - 'required' => $required, - 'default' => $default, - 'array' => $array, - 'filters' => $filters, - ]), - $response, - $dbForProject, - $queueForDatabase, - $queueForEvents - ); - - $response - ->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED) - ->dynamic($column, UtopiaResponse::MODEL_COLUMN_DATETIME); + ->callback(function (string $databaseId, string $tableId, string $key, ?bool $required, ?string $default, bool $array, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { + parent::action($databaseId, $tableId, $key, $required, $default, $array, $response, $dbForProject, $queueForDatabase, $queueForEvents); + }); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Datetime/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Datetime/Update.php index 6ff0744859..d7124981d1 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Datetime/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Datetime/Update.php @@ -3,7 +3,7 @@ namespace Appwrite\Platform\Modules\Databases\Http\Columns\Datetime; use Appwrite\Event\Event; -use Appwrite\Platform\Modules\Databases\Http\Columns\Action as ColumnAction; +use Appwrite\Platform\Modules\Databases\Http\Attributes\Datetime\Update as DatetimeUpdate; use Appwrite\SDK\AuthType; use Appwrite\SDK\ContentType; use Appwrite\SDK\Method; @@ -13,13 +13,12 @@ use Utopia\Database\Database; use Utopia\Database\Validator\Datetime as DatetimeValidator; use Utopia\Database\Validator\Key; use Utopia\Database\Validator\UID; -use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Swoole\Response as SwooleResponse; use Utopia\Validator\Boolean; use Utopia\Validator\Nullable; -class Update extends ColumnAction +class Update extends DatetimeUpdate { use HTTP; @@ -30,10 +29,12 @@ class Update extends ColumnAction public function __construct() { + $this->setContext(DATABASE_COLUMNS_CONTEXT); + $this->setResponseModel(UtopiaResponse::MODEL_COLUMN_DATETIME); + $this - ->setHttpMethod(Action::HTTP_REQUEST_METHOD_PATCH) + ->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH) ->setHttpPath('/v1/databases/:databaseId/tables/:tableId/columns/datetime/:key') - ->httpAlias('/v1/databases/:databaseId/collections/:tableId/attributes/datetime/:key') ->desc('Update dateTime column') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') @@ -43,14 +44,14 @@ class Update extends ColumnAction ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( namespace: 'databases', - group: 'columns', - name: 'updateDatetimeColumn', + group: $this->getSdkGroup(), + name: self::getName(), description: '/docs/references/databases/update-datetime-attribute.md', auth: [AuthType::KEY], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_OK, - model: UtopiaResponse::MODEL_COLUMN_DATETIME, + model: $this->getResponseModel(), ) ], contentType: ContentType::JSON @@ -64,34 +65,8 @@ class Update extends ColumnAction ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') - ->callback([$this, 'action']); - } - - public function action( - string $databaseId, - string $tableId, - string $key, - ?bool $required, - ?string $default, - ?string $newKey, - UtopiaResponse $response, - Database $dbForProject, - Event $queueForEvents - ): void { - $column = $this->updateColumn( - databaseId: $databaseId, - tableId: $tableId, - key: $key, - dbForProject: $dbForProject, - queueForEvents: $queueForEvents, - type: Database::VAR_DATETIME, - default: $default, - required: $required, - newKey: $newKey - ); - - $response - ->setStatusCode(SwooleResponse::STATUS_CODE_OK) - ->dynamic($column, UtopiaResponse::MODEL_COLUMN_DATETIME); + ->callback(function (string $databaseId, string $tableId, string $key, ?bool $required, ?bool $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents) { + parent::action($databaseId, $tableId, $key, $required, $default, $newKey, $response, $dbForProject, $queueForEvents); + }); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Delete.php b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Delete.php index 717e8f958c..eb2c6a9ccf 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Delete.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Delete.php @@ -4,22 +4,19 @@ namespace Appwrite\Platform\Modules\Databases\Http\Columns; use Appwrite\Event\Database as EventDatabase; use Appwrite\Event\Event; -use Appwrite\Extend\Exception; +use Appwrite\Platform\Modules\Databases\Http\Attributes\Delete as AttributesDelete; use Appwrite\SDK\AuthType; use Appwrite\SDK\ContentType; use Appwrite\SDK\Method; use Appwrite\SDK\Response as SDKResponse; use Appwrite\Utopia\Response as UtopiaResponse; use Utopia\Database\Database; -use Utopia\Database\Validator\Authorization; -use Utopia\Database\Validator\IndexDependency as IndexDependencyValidator; use Utopia\Database\Validator\Key; use Utopia\Database\Validator\UID; -use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Swoole\Response as SwooleResponse; -class Delete extends Action +class Delete extends AttributesDelete { use HTTP; @@ -30,10 +27,14 @@ class Delete extends Action public function __construct() { + $this->setContext(DATABASE_COLUMNS_CONTEXT); + + // parent action handles multiple model types internally + $this->setResponseModel(UtopiaResponse::MODEL_NONE); + $this ->setHttpMethod(self::HTTP_REQUEST_METHOD_DELETE) ->setHttpPath('/v1/databases/:databaseId/tables/:tableId/columns/:key') - ->httpAlias('/v1/databases/:databaseId/collections/:tableId/attributes/:key') ->desc('Delete column') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') @@ -43,14 +44,14 @@ class Delete extends Action ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( namespace: 'databases', - group: 'columns', - name: 'deleteColumn', + group: $this->getSdkGroup(), + name: self::getName(), description: '/docs/references/databases/delete-attribute.md', auth: [AuthType::KEY], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_NOCONTENT, - model: UtopiaResponse::MODEL_NONE, + model: $this->getResponseModel(), ) ], contentType: ContentType::NONE @@ -62,103 +63,8 @@ class Delete extends Action ->inject('dbForProject') ->inject('queueForDatabase') ->inject('queueForEvents') - ->callback([$this, 'action']); - } - - public function action( - string $databaseId, - string $tableId, - string $key, - UtopiaResponse $response, - Database $dbForProject, - EventDatabase $queueForDatabase, - Event $queueForEvents, - ): void { - $db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); - if ($db->isEmpty()) { - throw new Exception(Exception::DATABASE_NOT_FOUND); - } - - $table = $dbForProject->getDocument('database_' . $db->getInternalId(), $tableId); - if ($table->isEmpty()) { - throw new Exception(Exception::TABLE_NOT_FOUND); - } - - $column = $dbForProject->getDocument('attributes', $db->getInternalId() . '_' . $table->getInternalId() . '_' . $key); - if ($column->isEmpty()) { - throw new Exception(Exception::COLUMN_NOT_FOUND); - } - - $validator = new IndexDependencyValidator( - $table->getAttribute('indexes'), - $dbForProject->getAdapter()->getSupportForCastIndexArray(), - ); - if (!$validator->isValid($column)) { - throw new Exception(Exception::INDEX_DEPENDENCY); - } - - if ($column->getAttribute('status') === 'available') { - $column = $dbForProject->updateDocument('attributes', $column->getId(), $column->setAttribute('status', 'deleting')); - } - - $dbForProject->purgeCachedDocument('database_' . $db->getInternalId(), $tableId); - $dbForProject->purgeCachedCollection('database_' . $db->getInternalId() . '_collection_' . $table->getInternalId()); - - if ($column->getAttribute('type') === Database::VAR_RELATIONSHIP) { - $options = $column->getAttribute('options'); - if ($options['twoWay']) { - $relatedTable = $dbForProject->getDocument('database_' . $db->getInternalId(), $options['relatedCollection']); - if ($relatedTable->isEmpty()) { - throw new Exception(Exception::TABLE_NOT_FOUND); - } - - $relatedColumn = $dbForProject->getDocument('attributes', $db->getInternalId() . '_' . $relatedTable->getInternalId() . '_' . $options['twoWayKey']); - if ($relatedColumn->isEmpty()) { - throw new Exception(Exception::COLUMN_NOT_FOUND); - } - - if ($relatedColumn->getAttribute('status') === 'available') { - $dbForProject->updateDocument('attributes', $relatedColumn->getId(), $relatedColumn->setAttribute('status', 'deleting')); - } - - $dbForProject->purgeCachedDocument('database_' . $db->getInternalId(), $options['relatedCollection']); - $dbForProject->purgeCachedCollection('database_' . $db->getInternalId() . '_collection_' . $relatedTable->getInternalId()); - } - } - - $queueForDatabase - ->setType(DATABASE_TYPE_DELETE_ATTRIBUTE) - ->setTable($table) - ->setDatabase($db) - ->setRow($column); - - $type = $column->getAttribute('type'); - $format = $column->getAttribute('format'); - - $model = match ($type) { - Database::VAR_BOOLEAN => UtopiaResponse::MODEL_COLUMN_BOOLEAN, - Database::VAR_INTEGER => UtopiaResponse::MODEL_COLUMN_INTEGER, - Database::VAR_FLOAT => UtopiaResponse::MODEL_COLUMN_FLOAT, - Database::VAR_DATETIME => UtopiaResponse::MODEL_COLUMN_DATETIME, - Database::VAR_RELATIONSHIP => UtopiaResponse::MODEL_COLUMN_RELATIONSHIP, - Database::VAR_STRING => match ($format) { - APP_DATABASE_ATTRIBUTE_EMAIL => UtopiaResponse::MODEL_COLUMN_EMAIL, - APP_DATABASE_ATTRIBUTE_ENUM => UtopiaResponse::MODEL_COLUMN_ENUM, - APP_DATABASE_ATTRIBUTE_IP => UtopiaResponse::MODEL_COLUMN_IP, - APP_DATABASE_ATTRIBUTE_URL => UtopiaResponse::MODEL_COLUMN_URL, - default => UtopiaResponse::MODEL_COLUMN_STRING, - }, - default => UtopiaResponse::MODEL_COLUMN, - }; - - $queueForEvents - ->setParam('databaseId', $databaseId) - ->setParam('tableId', $table->getId()) - ->setParam('columnId', $column->getId()) - ->setContext('table', $table) - ->setContext('database', $db) - ->setPayload($response->output($column, $model)); - - $response->noContent(); + ->callback(function (string $databaseId, string $tableId, string $key, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { + parent::action($databaseId, $tableId, $key, $response, $dbForProject, $queueForDatabase, $queueForEvents); + }); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Email/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Email/Create.php index 2372d8b032..2fdb994251 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Email/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Email/Create.php @@ -5,21 +5,19 @@ namespace Appwrite\Platform\Modules\Databases\Http\Columns\Email; use Appwrite\Event\Database as EventDatabase; use Appwrite\Event\Event; use Appwrite\Network\Validator\Email; -use Appwrite\Platform\Modules\Databases\Http\Columns\Action as ColumnAction; +use Appwrite\Platform\Modules\Databases\Http\Attributes\Email\Create as EmailCreate; use Appwrite\SDK\AuthType; use Appwrite\SDK\Method; use Appwrite\SDK\Response as SDKResponse; use Appwrite\Utopia\Response as UtopiaResponse; use Utopia\Database\Database; -use Utopia\Database\Document; use Utopia\Database\Validator\Key; use Utopia\Database\Validator\UID; -use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Swoole\Response as SwooleResponse; use Utopia\Validator\Boolean; -class Create extends ColumnAction +class Create extends EmailCreate { use HTTP; @@ -30,10 +28,12 @@ class Create extends ColumnAction public function __construct() { + $this->setContext(DATABASE_COLUMNS_CONTEXT); + $this->setResponseModel(UtopiaResponse::MODEL_COLUMN_EMAIL); + $this - ->setHttpMethod(Action::HTTP_REQUEST_METHOD_POST) + ->setHttpMethod(self::HTTP_REQUEST_METHOD_POST) ->setHttpPath('/v1/databases/:databaseId/tables/:tableId/columns/email') - ->httpAlias('/v1/databases/:databaseId/collections/:tableId/attributes/email') ->desc('Create email column') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') @@ -43,14 +43,14 @@ class Create extends ColumnAction ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( namespace: 'databases', - group: 'columns', - name: 'createEmailColumn', + group: $this->getSdkGroup(), + name: self::getName(), description: '/docs/references/databases/create-email-attribute.md', auth: [AuthType::KEY], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_ACCEPTED, - model: UtopiaResponse::MODEL_COLUMN_EMAIL, + model: $this->getResponseModel(), ) ] )) @@ -64,41 +64,8 @@ class Create extends ColumnAction ->inject('dbForProject') ->inject('queueForDatabase') ->inject('queueForEvents') - ->callback([$this, 'action']); - } - - public function action( - string $databaseId, - string $tableId, - string $key, - ?bool $required, - ?string $default, - bool $array, - \Appwrite\Utopia\Response $response, - Database $dbForProject, - EventDatabase $queueForDatabase, - Event $queueForEvents - ): void { - $column = $this->createColumn( - $databaseId, - $tableId, - new Document([ - 'key' => $key, - 'type' => Database::VAR_STRING, - 'size' => 254, - 'required' => $required, - 'default' => $default, - 'array' => $array, - 'format' => APP_DATABASE_ATTRIBUTE_EMAIL, - ]), - $response, - $dbForProject, - $queueForDatabase, - $queueForEvents - ); - - $response - ->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED) - ->dynamic($column, UtopiaResponse::MODEL_COLUMN_EMAIL); + ->callback(function (string $databaseId, string $tableId, string $key, ?bool $required, ?string $default, bool $array, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { + parent::action($databaseId, $tableId, $key, $required, $default, $array, $response, $dbForProject, $queueForDatabase, $queueForEvents); + }); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Email/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Email/Update.php index 74124eba37..255e636a39 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Email/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Email/Update.php @@ -4,7 +4,7 @@ namespace Appwrite\Platform\Modules\Databases\Http\Columns\Email; use Appwrite\Event\Event; use Appwrite\Network\Validator\Email; -use Appwrite\Platform\Modules\Databases\Http\Columns\Action as ColumnAction; +use Appwrite\Platform\Modules\Databases\Http\Attributes\Email\Update as EmailUpdate; use Appwrite\SDK\AuthType; use Appwrite\SDK\ContentType; use Appwrite\SDK\Method; @@ -13,13 +13,12 @@ use Appwrite\Utopia\Response as UtopiaResponse; use Utopia\Database\Database; use Utopia\Database\Validator\Key; use Utopia\Database\Validator\UID; -use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Swoole\Response as SwooleResponse; use Utopia\Validator\Boolean; use Utopia\Validator\Nullable; -class Update extends ColumnAction +class Update extends EmailUpdate { use HTTP; @@ -30,10 +29,12 @@ class Update extends ColumnAction public function __construct() { + $this->setContext(DATABASE_COLUMNS_CONTEXT); + $this->setResponseModel(UtopiaResponse::MODEL_COLUMN_EMAIL); + $this - ->setHttpMethod(Action::HTTP_REQUEST_METHOD_PATCH) + ->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH) ->setHttpPath('/v1/databases/:databaseId/tables/:tableId/columns/email/:key') - ->httpAlias('/v1/databases/:databaseId/collections/:tableId/attributes/email/:key') ->desc('Update email column') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') @@ -43,14 +44,14 @@ class Update extends ColumnAction ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( namespace: 'databases', - group: 'columns', - name: 'updateEmailColumn', + group: $this->getSdkGroup(), + name: self::getName(), description: '/docs/references/databases/update-email-attribute.md', auth: [AuthType::KEY], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_OK, - model: UtopiaResponse::MODEL_COLUMN_EMAIL, + model: $this->getResponseModel(), ) ], contentType: ContentType::JSON @@ -64,35 +65,8 @@ class Update extends ColumnAction ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') - ->callback([$this, 'action']); - } - - public function action( - string $databaseId, - string $tableId, - string $key, - ?bool $required, - ?string $default, - ?string $newKey, - UtopiaResponse $response, - Database $dbForProject, - Event $queueForEvents - ): void { - $column = $this->updateColumn( - databaseId: $databaseId, - tableId: $tableId, - key: $key, - dbForProject: $dbForProject, - queueForEvents: $queueForEvents, - type: Database::VAR_STRING, - filter: APP_DATABASE_ATTRIBUTE_EMAIL, - default: $default, - required: $required, - newKey: $newKey - ); - - $response - ->setStatusCode(SwooleResponse::STATUS_CODE_OK) - ->dynamic($column, UtopiaResponse::MODEL_COLUMN_EMAIL); + ->callback(function (string $databaseId, string $tableId, string $key, ?bool $required, ?bool $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents) { + parent::action($databaseId, $tableId, $key, $required, $default, $newKey, $response, $dbForProject, $queueForEvents); + }); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Enum/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Enum/Create.php index c57d451743..2408aeeae4 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Enum/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Enum/Create.php @@ -4,24 +4,21 @@ namespace Appwrite\Platform\Modules\Databases\Http\Columns\Enum; use Appwrite\Event\Database as EventDatabase; use Appwrite\Event\Event; -use Appwrite\Extend\Exception; -use Appwrite\Platform\Modules\Databases\Http\Columns\Action as ColumnAction; +use Appwrite\Platform\Modules\Databases\Http\Attributes\Enum\Create as EnumCreate; use Appwrite\SDK\AuthType; use Appwrite\SDK\Method; use Appwrite\SDK\Response as SDKResponse; use Appwrite\Utopia\Response as UtopiaResponse; use Utopia\Database\Database; -use Utopia\Database\Document; use Utopia\Database\Validator\Key; use Utopia\Database\Validator\UID; -use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Swoole\Response as SwooleResponse; use Utopia\Validator\ArrayList; use Utopia\Validator\Boolean; use Utopia\Validator\Text; -class Create extends ColumnAction +class Create extends EnumCreate { use HTTP; @@ -32,10 +29,12 @@ class Create extends ColumnAction public function __construct() { + $this->setContext(DATABASE_COLUMNS_CONTEXT); + $this->setResponseModel(UtopiaResponse::MODEL_COLUMN_ENUM); + $this - ->setHttpMethod(Action::HTTP_REQUEST_METHOD_POST) + ->setHttpMethod(self::HTTP_REQUEST_METHOD_POST) ->setHttpPath('/v1/databases/:databaseId/tables/:tableId/columns/enum') - ->httpAlias('/v1/databases/:databaseId/collections/:tableId/attributes/enum') ->desc('Create enum column') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') @@ -45,14 +44,14 @@ class Create extends ColumnAction ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( namespace: 'databases', - group: 'columns', - name: 'createEnumColumn', + group: $this->getSdkGroup(), + name: self::getName(), description: '/docs/references/databases/create-attribute-enum.md', auth: [AuthType::KEY], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_ACCEPTED, - model: UtopiaResponse::MODEL_COLUMN_ENUM, + model: $this->getResponseModel(), ) ] )) @@ -67,47 +66,8 @@ class Create extends ColumnAction ->inject('dbForProject') ->inject('queueForDatabase') ->inject('queueForEvents') - ->callback([$this, 'action']); - } - - public function action( - string $databaseId, - string $tableId, - string $key, - array $elements, - ?bool $required, - ?string $default, - bool $array, - \Appwrite\Utopia\Response $response, - Database $dbForProject, - EventDatabase $queueForDatabase, - Event $queueForEvents - ): void { - if (!is_null($default) && !in_array($default, $elements, true)) { - throw new Exception(Exception::COLUMN_VALUE_INVALID, 'Default value not found in elements'); - } - - $column = $this->createColumn( - $databaseId, - $tableId, - new Document([ - 'key' => $key, - 'type' => Database::VAR_STRING, - 'size' => Database::LENGTH_KEY, - 'required' => $required, - 'default' => $default, - 'array' => $array, - 'format' => APP_DATABASE_ATTRIBUTE_ENUM, - 'formatOptions' => ['elements' => $elements], - ]), - $response, - $dbForProject, - $queueForDatabase, - $queueForEvents - ); - - $response - ->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED) - ->dynamic($column, UtopiaResponse::MODEL_COLUMN_ENUM); + ->callback(function (string $databaseId, string $tableId, string $key, array $elements, ?bool $required, ?string $default, bool $array, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { + parent::action($databaseId, $tableId, $key, $elements, $required, $default, $array, $response, $dbForProject, $queueForDatabase, $queueForEvents); + }); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Enum/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Enum/Update.php index aa588a9f1b..c47766b4dd 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Enum/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Enum/Update.php @@ -3,7 +3,7 @@ namespace Appwrite\Platform\Modules\Databases\Http\Columns\Enum; use Appwrite\Event\Event; -use Appwrite\Platform\Modules\Databases\Http\Columns\Action as ColumnAction; +use Appwrite\Platform\Modules\Databases\Http\Attributes\Enum\Update as EnumUpdate; use Appwrite\SDK\AuthType; use Appwrite\SDK\ContentType; use Appwrite\SDK\Method; @@ -12,7 +12,6 @@ use Appwrite\Utopia\Response as UtopiaResponse; use Utopia\Database\Database; use Utopia\Database\Validator\Key; use Utopia\Database\Validator\UID; -use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Swoole\Response as SwooleResponse; use Utopia\Validator\ArrayList; @@ -20,7 +19,7 @@ use Utopia\Validator\Boolean; use Utopia\Validator\Nullable; use Utopia\Validator\Text; -class Update extends ColumnAction +class Update extends EnumUpdate { use HTTP; @@ -31,10 +30,12 @@ class Update extends ColumnAction public function __construct() { + $this->setContext(DATABASE_COLUMNS_CONTEXT); + $this->setResponseModel(UtopiaResponse::MODEL_COLUMN_ENUM); + $this - ->setHttpMethod(Action::HTTP_REQUEST_METHOD_PATCH) + ->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH) ->setHttpPath('/v1/databases/:databaseId/tables/:tableId/columns/enum/:key') - ->httpAlias('/v1/databases/:databaseId/collections/:tableId/attributes/enum/:key') ->desc('Update enum column') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') @@ -44,14 +45,14 @@ class Update extends ColumnAction ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( namespace: 'databases', - group: 'columns', - name: 'updateEnumColumn', + group: $this->getSdkGroup(), + name: self::getName(), description: '/docs/references/databases/update-enum-attribute.md', auth: [AuthType::KEY], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_OK, - model: UtopiaResponse::MODEL_COLUMN_ENUM, + model: $this->getResponseModel(), ) ], contentType: ContentType::JSON @@ -66,37 +67,8 @@ class Update extends ColumnAction ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') - ->callback([$this, 'action']); - } - - public function action( - string $databaseId, - string $tableId, - string $key, - ?array $elements, - ?bool $required, - ?string $default, - ?string $newKey, - UtopiaResponse $response, - Database $dbForProject, - Event $queueForEvents - ): void { - $column = $this->updateColumn( - databaseId: $databaseId, - tableId: $tableId, - key: $key, - dbForProject: $dbForProject, - queueForEvents: $queueForEvents, - type: Database::VAR_STRING, - filter: APP_DATABASE_ATTRIBUTE_ENUM, - default: $default, - required: $required, - elements: $elements, - newKey: $newKey - ); - - $response - ->setStatusCode(SwooleResponse::STATUS_CODE_OK) - ->dynamic($column, UtopiaResponse::MODEL_COLUMN_ENUM); + ->callback(function (string $databaseId, string $tableId, string $key, array $elements, ?bool $required, ?string $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents) { + parent::action($databaseId, $tableId, $key, $elements, $required, $default, $newKey, $response, $dbForProject, $queueForEvents); + }); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Float/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Float/Create.php index a0a16fafec..c8b9a7ec7b 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Float/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Float/Create.php @@ -4,24 +4,20 @@ namespace Appwrite\Platform\Modules\Databases\Http\Columns\Float; use Appwrite\Event\Database as EventDatabase; use Appwrite\Event\Event; -use Appwrite\Extend\Exception; -use Appwrite\Platform\Modules\Databases\Http\Columns\Action as ColumnAction; +use Appwrite\Platform\Modules\Databases\Http\Attributes\Float\Create as FloatCreate; use Appwrite\SDK\AuthType; use Appwrite\SDK\Method; use Appwrite\SDK\Response as SDKResponse; use Appwrite\Utopia\Response as UtopiaResponse; use Utopia\Database\Database; -use Utopia\Database\Document; use Utopia\Database\Validator\Key; use Utopia\Database\Validator\UID; -use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Swoole\Response as SwooleResponse; use Utopia\Validator\Boolean; use Utopia\Validator\FloatValidator; -use Utopia\Validator\Range; -class Create extends ColumnAction +class Create extends FloatCreate { use HTTP; @@ -32,10 +28,12 @@ class Create extends ColumnAction public function __construct() { + $this->setContext(DATABASE_COLUMNS_CONTEXT); + $this->setResponseModel(UtopiaResponse::MODEL_COLUMN_FLOAT); + $this - ->setHttpMethod(Action::HTTP_REQUEST_METHOD_POST) + ->setHttpMethod(self::HTTP_REQUEST_METHOD_POST) ->setHttpPath('/v1/databases/:databaseId/tables/:tableId/columns/float') - ->httpAlias('/v1/databases/:databaseId/collections/:tableId/attributes/float') ->desc('Create float column') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') @@ -45,14 +43,14 @@ class Create extends ColumnAction ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( namespace: 'databases', - group: 'columns', - name: 'createFloatColumn', + group: $this->getSdkGroup(), + name: self::getName(), description: '/docs/references/databases/create-float-attribute.md', auth: [AuthType::KEY], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_ACCEPTED, - model: UtopiaResponse::MODEL_COLUMN_FLOAT, + model: $this->getResponseModel(), ) ] )) @@ -68,54 +66,8 @@ class Create extends ColumnAction ->inject('dbForProject') ->inject('queueForDatabase') ->inject('queueForEvents') - ->callback([$this, 'action']); - } - - public function action( - string $databaseId, - string $tableId, - string $key, - ?bool $required, - ?float $min, - ?float $max, - ?float $default, - bool $array, - UtopiaResponse $response, - Database $dbForProject, - EventDatabase $queueForDatabase, - Event $queueForEvents - ): void { - $min ??= -PHP_FLOAT_MAX; - $max ??= PHP_FLOAT_MAX; - - if ($min > $max) { - throw new Exception(Exception::COLUMN_VALUE_INVALID, 'Minimum value must be lesser than maximum value'); - } - - $validator = new Range($min, $max, Database::VAR_FLOAT); - if (!\is_null($default) && !$validator->isValid($default)) { - throw new Exception(Exception::COLUMN_VALUE_INVALID, $validator->getDescription()); - } - - $column = $this->createColumn($databaseId, $tableId, new Document([ - 'key' => $key, - 'type' => Database::VAR_FLOAT, - 'size' => 0, - 'required' => $required, - 'default' => $default, - 'array' => $array, - 'format' => APP_DATABASE_ATTRIBUTE_FLOAT_RANGE, - 'formatOptions' => ['min' => $min, 'max' => $max], - ]), $response, $dbForProject, $queueForDatabase, $queueForEvents); - - $formatOptions = $column->getAttribute('formatOptions', []); - if (!empty($formatOptions)) { - $column->setAttribute('min', \floatval($formatOptions['min'])); - $column->setAttribute('max', \floatval($formatOptions['max'])); - } - - $response - ->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED) - ->dynamic($column, UtopiaResponse::MODEL_COLUMN_FLOAT); + ->callback(function (string $databaseId, string $tableId, string $key, ?bool $required, ?float $min, ?float $max, ?float $default, bool $array, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { + parent::action($databaseId, $tableId, $key, $required, $min, $max, $default, $array, $response, $dbForProject, $queueForDatabase, $queueForEvents); + }); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Float/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Float/Update.php index 8ea7ab474a..1e008de2c0 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Float/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Float/Update.php @@ -3,7 +3,7 @@ namespace Appwrite\Platform\Modules\Databases\Http\Columns\Float; use Appwrite\Event\Event; -use Appwrite\Platform\Modules\Databases\Http\Columns\Action as ColumnAction; +use Appwrite\Platform\Modules\Databases\Http\Attributes\Float\Update as FloatUpdate; use Appwrite\SDK\AuthType; use Appwrite\SDK\ContentType; use Appwrite\SDK\Method; @@ -12,14 +12,13 @@ use Appwrite\Utopia\Response as UtopiaResponse; use Utopia\Database\Database; use Utopia\Database\Validator\Key; use Utopia\Database\Validator\UID; -use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Swoole\Response as SwooleResponse; use Utopia\Validator\Boolean; use Utopia\Validator\FloatValidator; use Utopia\Validator\Nullable; -class Update extends ColumnAction +class Update extends FloatUpdate { use HTTP; @@ -30,10 +29,12 @@ class Update extends ColumnAction public function __construct() { + $this->setContext(DATABASE_COLUMNS_CONTEXT); + $this->setResponseModel(UtopiaResponse::MODEL_COLUMN_FLOAT); + $this - ->setHttpMethod(Action::HTTP_REQUEST_METHOD_PATCH) + ->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH) ->setHttpPath('/v1/databases/:databaseId/tables/:tableId/columns/float/:key') - ->httpAlias('/v1/databases/:databaseId/collections/:tableId/attributes/float/:key') ->desc('Update float column') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') @@ -43,14 +44,14 @@ class Update extends ColumnAction ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( namespace: 'databases', - group: 'columns', - name: 'updateFloatColumn', + group: $this->getSdkGroup(), + name: self::getName(), description: '/docs/references/databases/update-float-attribute.md', auth: [AuthType::KEY], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_OK, - model: UtopiaResponse::MODEL_COLUMN_FLOAT, + model: $this->getResponseModel(), ) ], contentType: ContentType::JSON @@ -66,44 +67,8 @@ class Update extends ColumnAction ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') - ->callback([$this, 'action']); - } - - public function action( - string $databaseId, - string $tableId, - string $key, - ?bool $required, - ?float $min, - ?float $max, - ?float $default, - ?string $newKey, - UtopiaResponse $response, - Database $dbForProject, - Event $queueForEvents - ): void { - $column = $this->updateColumn( - databaseId: $databaseId, - tableId: $tableId, - key: $key, - dbForProject: $dbForProject, - queueForEvents: $queueForEvents, - type: Database::VAR_FLOAT, - default: $default, - required: $required, - min: $min, - max: $max, - newKey: $newKey - ); - - $formatOptions = $column->getAttribute('formatOptions', []); - if (!empty($formatOptions)) { - $column->setAttribute('min', \floatval($formatOptions['min'])); - $column->setAttribute('max', \floatval($formatOptions['max'])); - } - - $response - ->setStatusCode(SwooleResponse::STATUS_CODE_OK) - ->dynamic($column, UtopiaResponse::MODEL_COLUMN_FLOAT); + ->callback(function (string $databaseId, string $tableId, string $key, ?bool $required, ?float $min, ?float $max, ?float $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents) { + parent::action($databaseId, $tableId, $key, $required, $min, $max, $default, $newKey, $response, $dbForProject, $queueForEvents); + }); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Get.php index 4390f0841c..d8847f0122 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Get.php @@ -2,20 +2,18 @@ namespace Appwrite\Platform\Modules\Databases\Http\Columns; -use Appwrite\Extend\Exception; +use Appwrite\Platform\Modules\Databases\Http\Attributes\Get as AttributesGet; use Appwrite\SDK\AuthType; use Appwrite\SDK\Method; use Appwrite\SDK\Response as SDKResponse; use Appwrite\Utopia\Response as UtopiaResponse; use Utopia\Database\Database; -use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\Key; use Utopia\Database\Validator\UID; -use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Swoole\Response as SwooleResponse; -class Get extends Action +class Get extends AttributesGet { use HTTP; @@ -26,35 +24,38 @@ class Get extends Action public function __construct() { + $this->setContext(DATABASE_COLUMNS_CONTEXT); + + $this->setResponseModel([ + UtopiaResponse::MODEL_COLUMN_BOOLEAN, + UtopiaResponse::MODEL_COLUMN_INTEGER, + UtopiaResponse::MODEL_COLUMN_FLOAT, + UtopiaResponse::MODEL_COLUMN_EMAIL, + UtopiaResponse::MODEL_COLUMN_ENUM, + UtopiaResponse::MODEL_COLUMN_URL, + UtopiaResponse::MODEL_COLUMN_IP, + UtopiaResponse::MODEL_COLUMN_DATETIME, + UtopiaResponse::MODEL_COLUMN_RELATIONSHIP, + UtopiaResponse::MODEL_COLUMN_STRING, + ]); + $this ->setHttpMethod(self::HTTP_REQUEST_METHOD_GET) ->setHttpPath('/v1/databases/:databaseId/tables/:tableId/columns/:key') - ->httpAlias('/v1/databases/:databaseId/collections/:tableId/attributes/:key') ->desc('Get column') ->groups(['api', 'database']) ->label('scope', 'collections.read') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( namespace: 'databases', - group: 'columns', - name: 'getColumn', + group: $this->getSdkGroup(), + name: self::getName(), description: '/docs/references/databases/get-attribute.md', auth: [AuthType::KEY], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_OK, - model: [ - UtopiaResponse::MODEL_COLUMN_BOOLEAN, - UtopiaResponse::MODEL_COLUMN_INTEGER, - UtopiaResponse::MODEL_COLUMN_FLOAT, - UtopiaResponse::MODEL_COLUMN_EMAIL, - UtopiaResponse::MODEL_COLUMN_ENUM, - UtopiaResponse::MODEL_COLUMN_URL, - UtopiaResponse::MODEL_COLUMN_IP, - UtopiaResponse::MODEL_COLUMN_DATETIME, - UtopiaResponse::MODEL_COLUMN_RELATIONSHIP, - UtopiaResponse::MODEL_COLUMN_STRING, - ] + model: $this->getResponseModel() ) ] )) @@ -63,50 +64,8 @@ class Get extends Action ->param('key', '', new Key(), 'Column Key.') ->inject('response') ->inject('dbForProject') - ->callback([$this, 'action']); - } - - public function action(string $databaseId, string $tableId, string $key, UtopiaResponse $response, Database $dbForProject): void - { - $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); - if ($database->isEmpty()) { - throw new Exception(Exception::DATABASE_NOT_FOUND); - } - - $table = $dbForProject->getDocument('database_' . $database->getInternalId(), $tableId); - if ($table->isEmpty()) { - throw new Exception(Exception::TABLE_NOT_FOUND); - } - - $column = $dbForProject->getDocument('attributes', $database->getInternalId() . '_' . $table->getInternalId() . '_' . $key); - if ($column->isEmpty()) { - throw new Exception(Exception::COLUMN_NOT_FOUND); - } - - $type = $column->getAttribute('type'); - $format = $column->getAttribute('format'); - $options = $column->getAttribute('options', []); - - foreach ($options as $optKey => $optValue) { - $column->setAttribute($optKey, $optValue); - } - - $model = match ($type) { - Database::VAR_BOOLEAN => UtopiaResponse::MODEL_COLUMN_BOOLEAN, - Database::VAR_INTEGER => UtopiaResponse::MODEL_COLUMN_INTEGER, - Database::VAR_FLOAT => UtopiaResponse::MODEL_COLUMN_FLOAT, - Database::VAR_DATETIME => UtopiaResponse::MODEL_COLUMN_DATETIME, - Database::VAR_RELATIONSHIP => UtopiaResponse::MODEL_COLUMN_RELATIONSHIP, - Database::VAR_STRING => match ($format) { - APP_DATABASE_ATTRIBUTE_EMAIL => UtopiaResponse::MODEL_COLUMN_EMAIL, - APP_DATABASE_ATTRIBUTE_ENUM => UtopiaResponse::MODEL_COLUMN_ENUM, - APP_DATABASE_ATTRIBUTE_IP => UtopiaResponse::MODEL_COLUMN_IP, - APP_DATABASE_ATTRIBUTE_URL => UtopiaResponse::MODEL_COLUMN_URL, - default => UtopiaResponse::MODEL_COLUMN_STRING, - }, - default => UtopiaResponse::MODEL_COLUMN, - }; - - $response->dynamic($column, $model); + ->callback(function (string $databaseId, string $tableId, string $key, UtopiaResponse $response, Database $dbForProject) { + parent::action($databaseId, $tableId, $key, $response, $dbForProject); + }); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Columns/IP/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Columns/IP/Create.php index 73d8c93031..a69cc6ccfe 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Columns/IP/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Columns/IP/Create.php @@ -4,22 +4,20 @@ namespace Appwrite\Platform\Modules\Databases\Http\Columns\IP; use Appwrite\Event\Database as EventDatabase; use Appwrite\Event\Event; -use Appwrite\Platform\Modules\Databases\Http\Columns\Action as ColumnAction; +use Appwrite\Platform\Modules\Databases\Http\Attributes\IP\Create as IPCreate; use Appwrite\SDK\AuthType; use Appwrite\SDK\Method; use Appwrite\SDK\Response as SDKResponse; use Appwrite\Utopia\Response as UtopiaResponse; use Utopia\Database\Database; -use Utopia\Database\Document; use Utopia\Database\Validator\Key; use Utopia\Database\Validator\UID; -use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Swoole\Response as SwooleResponse; use Utopia\Validator\Boolean; use Utopia\Validator\IP; -class Create extends ColumnAction +class Create extends IPCreate { use HTTP; @@ -30,10 +28,12 @@ class Create extends ColumnAction public function __construct() { + $this->setContext(DATABASE_COLUMNS_CONTEXT); + $this->setResponseModel(UtopiaResponse::MODEL_COLUMN_IP); + $this - ->setHttpMethod(Action::HTTP_REQUEST_METHOD_POST) + ->setHttpMethod(self::HTTP_REQUEST_METHOD_POST) ->setHttpPath('/v1/databases/:databaseId/tables/:tableId/columns/ip') - ->httpAlias('/v1/databases/:databaseId/collections/:tableId/attributes/ip') ->desc('Create IP address column') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') @@ -43,14 +43,14 @@ class Create extends ColumnAction ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( namespace: 'databases', - group: 'columns', - name: 'createIpColumn', + group: $this->getSdkGroup(), + name: self::getName(), description: '/docs/references/databases/create-ip-attribute.md', auth: [AuthType::KEY], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_ACCEPTED, - model: UtopiaResponse::MODEL_COLUMN_IP, + model: $this->getResponseModel(), ) ] )) @@ -64,33 +64,8 @@ class Create extends ColumnAction ->inject('dbForProject') ->inject('queueForDatabase') ->inject('queueForEvents') - ->callback([$this, 'action']); - } - - public function action( - string $databaseId, - string $tableId, - string $key, - ?bool $required, - ?string $default, - bool $array, - \Appwrite\Utopia\Response $response, - Database $dbForProject, - EventDatabase $queueForDatabase, - Event $queueForEvents - ): void { - $column = $this->createColumn($databaseId, $tableId, new Document([ - 'key' => $key, - 'type' => Database::VAR_STRING, - 'size' => 39, - 'required' => $required, - 'default' => $default, - 'array' => $array, - 'format' => APP_DATABASE_ATTRIBUTE_IP, - ]), $response, $dbForProject, $queueForDatabase, $queueForEvents); - - $response - ->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED) - ->dynamic($column, UtopiaResponse::MODEL_COLUMN_IP); + ->callback(function (string $databaseId, string $tableId, string $key, ?bool $required, ?string $default, bool $array, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { + parent::action($databaseId, $tableId, $key, $required, $default, $array, $response, $dbForProject, $queueForDatabase, $queueForEvents); + }); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Columns/IP/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Columns/IP/Update.php index 4b9fa8bca8..d4c6db12fe 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Columns/IP/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Columns/IP/Update.php @@ -3,7 +3,7 @@ namespace Appwrite\Platform\Modules\Databases\Http\Columns\IP; use Appwrite\Event\Event; -use Appwrite\Platform\Modules\Databases\Http\Columns\Action as ColumnAction; +use Appwrite\Platform\Modules\Databases\Http\Attributes\IP\Update as IPUpdate; use Appwrite\SDK\AuthType; use Appwrite\SDK\ContentType; use Appwrite\SDK\Method; @@ -12,14 +12,13 @@ use Appwrite\Utopia\Response as UtopiaResponse; use Utopia\Database\Database; use Utopia\Database\Validator\Key; use Utopia\Database\Validator\UID; -use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Swoole\Response as SwooleResponse; use Utopia\Validator\Boolean; use Utopia\Validator\IP; use Utopia\Validator\Nullable; -class Update extends ColumnAction +class Update extends IPUpdate { use HTTP; @@ -30,10 +29,12 @@ class Update extends ColumnAction public function __construct() { + $this->setContext(DATABASE_COLUMNS_CONTEXT); + $this->setResponseModel(UtopiaResponse::MODEL_COLUMN_IP); + $this - ->setHttpMethod(Action::HTTP_REQUEST_METHOD_PATCH) + ->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH) ->setHttpPath('/v1/databases/:databaseId/tables/:tableId/columns/ip/:key') - ->httpAlias('/v1/databases/:databaseId/collections/:tableId/attributes/ip/:key') ->desc('Update IP address column') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') @@ -43,14 +44,14 @@ class Update extends ColumnAction ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( namespace: 'databases', - group: 'columns', - name: 'updateIpColumn', + group: $this->getSdkGroup(), + name: self::getName(), description: '/docs/references/databases/update-ip-attribute.md', auth: [AuthType::KEY], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_OK, - model: UtopiaResponse::MODEL_COLUMN_IP, + model: $this->getResponseModel(), ) ], contentType: ContentType::JSON @@ -64,35 +65,8 @@ class Update extends ColumnAction ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') - ->callback([$this, 'action']); - } - - public function action( - string $databaseId, - string $tableId, - string $key, - ?bool $required, - ?string $default, - ?string $newKey, - UtopiaResponse $response, - Database $dbForProject, - Event $queueForEvents - ): void { - $column = $this->updateColumn( - databaseId: $databaseId, - tableId: $tableId, - key: $key, - dbForProject: $dbForProject, - queueForEvents: $queueForEvents, - type: Database::VAR_STRING, - filter: APP_DATABASE_ATTRIBUTE_IP, - default: $default, - required: $required, - newKey: $newKey - ); - - $response - ->setStatusCode(SwooleResponse::STATUS_CODE_OK) - ->dynamic($column, UtopiaResponse::MODEL_COLUMN_IP); + ->callback(function (string $databaseId, string $tableId, string $key, ?bool $required, ?string $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents) { + parent::action($databaseId, $tableId, $key, $required, $default, $newKey, $response, $dbForProject, $queueForEvents); + }); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Integer/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Integer/Create.php index cf2244bf1f..2c394dd042 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Integer/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Integer/Create.php @@ -4,24 +4,20 @@ namespace Appwrite\Platform\Modules\Databases\Http\Columns\Integer; use Appwrite\Event\Database as EventDatabase; use Appwrite\Event\Event; -use Appwrite\Extend\Exception; -use Appwrite\Platform\Modules\Databases\Http\Columns\Action as ColumnAction; +use Appwrite\Platform\Modules\Databases\Http\Attributes\Integer\Create as IntegerCreate; use Appwrite\SDK\AuthType; use Appwrite\SDK\Method; use Appwrite\SDK\Response as SDKResponse; use Appwrite\Utopia\Response as UtopiaResponse; use Utopia\Database\Database; -use Utopia\Database\Document; use Utopia\Database\Validator\Key; use Utopia\Database\Validator\UID; -use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Swoole\Response as SwooleResponse; use Utopia\Validator\Boolean; use Utopia\Validator\Integer; -use Utopia\Validator\Range; -class Create extends ColumnAction +class Create extends IntegerCreate { use HTTP; @@ -32,10 +28,12 @@ class Create extends ColumnAction public function __construct() { + $this->setContext(DATABASE_COLUMNS_CONTEXT); + $this->setResponseModel(UtopiaResponse::MODEL_COLUMN_INTEGER); + $this - ->setHttpMethod(Action::HTTP_REQUEST_METHOD_POST) + ->setHttpMethod(self::HTTP_REQUEST_METHOD_POST) ->setHttpPath('/v1/databases/:databaseId/tables/:tableId/columns/integer') - ->httpAlias('/v1/databases/:databaseId/collections/:tableId/attributes/integer') ->desc('Create integer column') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') @@ -45,14 +43,14 @@ class Create extends ColumnAction ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( namespace: 'databases', - group: 'columns', - name: 'createIntegerColumn', + group: $this->getSdkGroup(), + name: self::getName(), description: '/docs/references/databases/create-integer-attribute.md', auth: [AuthType::KEY], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_ACCEPTED, - model: UtopiaResponse::MODEL_COLUMN_INTEGER, + model: $this->getResponseModel(), ) ] )) @@ -68,56 +66,8 @@ class Create extends ColumnAction ->inject('dbForProject') ->inject('queueForDatabase') ->inject('queueForEvents') - ->callback([$this, 'action']); - } - - public function action( - string $databaseId, - string $tableId, - string $key, - ?bool $required, - ?int $min, - ?int $max, - ?int $default, - bool $array, - UtopiaResponse $response, - Database $dbForProject, - EventDatabase $queueForDatabase, - Event $queueForEvents - ): void { - $min ??= \PHP_INT_MIN; - $max ??= \PHP_INT_MAX; - - if ($min > $max) { - throw new Exception(Exception::COLUMN_VALUE_INVALID, 'Minimum value must be lesser than maximum value'); - } - - $validator = new Range($min, $max, Database::VAR_INTEGER); - if (!\is_null($default) && !$validator->isValid($default)) { - throw new Exception(Exception::COLUMN_VALUE_INVALID, $validator->getDescription()); - } - - $size = $max > 2147483647 ? 8 : 4; - - $column = $this->createColumn($databaseId, $tableId, new Document([ - 'key' => $key, - 'type' => Database::VAR_INTEGER, - 'size' => $size, - 'required' => $required, - 'default' => $default, - 'array' => $array, - 'format' => APP_DATABASE_ATTRIBUTE_INT_RANGE, - 'formatOptions' => ['min' => $min, 'max' => $max], - ]), $response, $dbForProject, $queueForDatabase, $queueForEvents); - - $formatOptions = $column->getAttribute('formatOptions', []); - if (!empty($formatOptions)) { - $column->setAttribute('min', \intval($formatOptions['min'])); - $column->setAttribute('max', \intval($formatOptions['max'])); - } - - $response - ->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED) - ->dynamic($column, UtopiaResponse::MODEL_COLUMN_INTEGER); + ->callback(function (string $databaseId, string $tableId, string $key, ?bool $required, ?int $min, ?int $max, ?int $default, bool $array, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { + parent::action($databaseId, $tableId, $key, $required, $min, $max, $default, $array, $response, $dbForProject, $queueForDatabase, $queueForEvents); + }); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Integer/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Integer/Update.php index 1806cc91c3..4eacb2b0df 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Integer/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Integer/Update.php @@ -3,7 +3,7 @@ namespace Appwrite\Platform\Modules\Databases\Http\Columns\Integer; use Appwrite\Event\Event; -use Appwrite\Platform\Modules\Databases\Http\Columns\Action as ColumnAction; +use Appwrite\Platform\Modules\Databases\Http\Attributes\Integer\Update as IntegerUpdate; use Appwrite\SDK\AuthType; use Appwrite\SDK\ContentType; use Appwrite\SDK\Method; @@ -12,14 +12,13 @@ use Appwrite\Utopia\Response as UtopiaResponse; use Utopia\Database\Database; use Utopia\Database\Validator\Key; use Utopia\Database\Validator\UID; -use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Swoole\Response as SwooleResponse; use Utopia\Validator\Boolean; use Utopia\Validator\Integer; use Utopia\Validator\Nullable; -class Update extends ColumnAction +class Update extends IntegerUpdate { use HTTP; @@ -30,10 +29,12 @@ class Update extends ColumnAction public function __construct() { + $this->setContext(DATABASE_COLUMNS_CONTEXT); + $this->setResponseModel(UtopiaResponse::MODEL_COLUMN_INTEGER); + $this - ->setHttpMethod(Action::HTTP_REQUEST_METHOD_PATCH) + ->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH) ->setHttpPath('/v1/databases/:databaseId/tables/:tableId/columns/integer/:key') - ->httpAlias('/v1/databases/:databaseId/collections/:tableId/attributes/integer/:key') ->desc('Update integer column') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') @@ -43,14 +44,14 @@ class Update extends ColumnAction ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( namespace: 'databases', - group: 'columns', - name: 'updateIntegerColumn', + group: $this->getSdkGroup(), + name: self::getName(), description: '/docs/references/databases/update-integer-attribute.md', auth: [AuthType::KEY], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_OK, - model: UtopiaResponse::MODEL_COLUMN_INTEGER, + model: $this->getResponseModel(), ) ], contentType: ContentType::JSON @@ -66,44 +67,8 @@ class Update extends ColumnAction ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') - ->callback([$this, 'action']); - } - - public function action( - string $databaseId, - string $tableId, - string $key, - ?bool $required, - ?int $min, - ?int $max, - ?int $default, - ?string $newKey, - UtopiaResponse $response, - Database $dbForProject, - Event $queueForEvents - ): void { - $column = $this->updateColumn( - databaseId: $databaseId, - tableId: $tableId, - key: $key, - dbForProject: $dbForProject, - queueForEvents: $queueForEvents, - type: Database::VAR_INTEGER, - default: $default, - required: $required, - min: $min, - max: $max, - newKey: $newKey - ); - - $formatOptions = $column->getAttribute('formatOptions', []); - if (!empty($formatOptions)) { - $column->setAttribute('min', \intval($formatOptions['min'])); - $column->setAttribute('max', \intval($formatOptions['max'])); - } - - $response - ->setStatusCode(SwooleResponse::STATUS_CODE_OK) - ->dynamic($column, UtopiaResponse::MODEL_COLUMN_INTEGER); + ->callback(function (string $databaseId, string $tableId, string $key, ?bool $required, ?int $min, ?int $max, ?int $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents) { + parent::action($databaseId, $tableId, $key, $required, $min, $max, $default, $newKey, $response, $dbForProject, $queueForEvents); + }); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Relationship/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Relationship/Create.php index 8b3ec616a3..d0b080b237 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Relationship/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Relationship/Create.php @@ -4,24 +4,20 @@ namespace Appwrite\Platform\Modules\Databases\Http\Columns\Relationship; use Appwrite\Event\Database as EventDatabase; use Appwrite\Event\Event; -use Appwrite\Extend\Exception; -use Appwrite\Platform\Modules\Databases\Http\Columns\Action as ColumnAction; +use Appwrite\Platform\Modules\Databases\Http\Attributes\Relationship\Create as RelationshipCreate; use Appwrite\SDK\AuthType; use Appwrite\SDK\Method; use Appwrite\SDK\Response as SDKResponse; use Appwrite\Utopia\Response as UtopiaResponse; use Utopia\Database\Database; -use Utopia\Database\Document; -use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\Key; use Utopia\Database\Validator\UID; -use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Swoole\Response as SwooleResponse; use Utopia\Validator\Boolean; use Utopia\Validator\WhiteList; -class Create extends ColumnAction +class Create extends RelationshipCreate { use HTTP; @@ -32,10 +28,12 @@ class Create extends ColumnAction public function __construct() { + $this->setContext(DATABASE_COLUMNS_CONTEXT); + $this->setResponseModel(UtopiaResponse::MODEL_COLUMN_RELATIONSHIP); + $this - ->setHttpMethod(Action::HTTP_REQUEST_METHOD_POST) + ->setHttpMethod(self::HTTP_REQUEST_METHOD_POST) ->setHttpPath('/v1/databases/:databaseId/tables/:tableId/columns/relationship') - ->httpAlias('/v1/databases/:databaseId/collections/:tableId/attributes/relationship') ->desc('Create relationship column') ->groups(['api', 'database']) ->label('scope', 'collections.write') @@ -45,14 +43,14 @@ class Create extends ColumnAction ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( namespace: 'databases', - group: 'columns', - name: 'createRelationshipColumn', + group: $this->getSdkGroup(), + name: self::getName(), description: '/docs/references/databases/create-relationship-attribute.md', auth: [AuthType::KEY], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_ACCEPTED, - model: UtopiaResponse::MODEL_COLUMN_RELATIONSHIP + model: $this->getResponseModel() ) ] )) @@ -77,92 +75,8 @@ class Create extends ColumnAction ->inject('dbForProject') ->inject('queueForDatabase') ->inject('queueForEvents') - ->callback([$this, 'action']); - } - - public function action( - string $databaseId, - string $tableId, - string $relatedTableId, - string $type, - bool $twoWay, - ?string $key, - ?string $twoWayKey, - string $onDelete, - UtopiaResponse $response, - Database $dbForProject, - EventDatabase $queueForDatabase, - Event $queueForEvents - ): void { - $key ??= $relatedTableId; - $twoWayKey ??= $tableId; - - $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); - if ($database->isEmpty()) { - throw new Exception(Exception::DATABASE_NOT_FOUND); - } - - $table = $dbForProject->getDocument('database_' . $database->getInternalId(), $tableId); - $table = $dbForProject->getCollection('database_' . $database->getInternalId() . '_collection_' . $table->getInternalId()); - if ($table->isEmpty()) { - throw new Exception(Exception::TABLE_NOT_FOUND); - } - - $relatedTableDocument = $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedTableId); - $relatedTable = $dbForProject->getCollection('database_' . $database->getInternalId() . '_collection_' . $relatedTableDocument->getInternalId()); - if ($relatedTable->isEmpty()) { - throw new Exception(Exception::TABLE_NOT_FOUND); - } - - $columns = $table->getAttribute('attributes', []); - foreach ($columns as $column) { - if ($column->getAttribute('type') !== Database::VAR_RELATIONSHIP) { - continue; - } - - if (\strtolower($column->getId()) === \strtolower($key)) { - throw new Exception(Exception::COLUMN_ALREADY_EXISTS); - } - - if ( - \strtolower($column->getAttribute('options')['twoWayKey']) === \strtolower($twoWayKey) && - $column->getAttribute('options')['relatedCollection'] === $relatedTable->getId() - ) { - throw new Exception(Exception::COLUMN_ALREADY_EXISTS, 'Attribute with the requested key already exists. Attribute keys must be unique, try again with a different key.'); - } - - if ( - $type === Database::RELATION_MANY_TO_MANY && - $column->getAttribute('options')['relationType'] === Database::RELATION_MANY_TO_MANY && - $column->getAttribute('options')['relatedCollection'] === $relatedTable->getId() - ) { - throw new Exception(Exception::COLUMN_ALREADY_EXISTS, 'Creating more than one "manyToMany" relationship on the same table is currently not permitted.'); - } - } - - $column = $this->createColumn($databaseId, $tableId, new Document([ - 'key' => $key, - 'type' => Database::VAR_RELATIONSHIP, - 'size' => 0, - 'required' => false, - 'default' => null, - 'array' => false, - 'filters' => [], - 'options' => [ - 'relatedCollection' => $relatedTableId, - 'relationType' => $type, - 'twoWay' => $twoWay, - 'twoWayKey' => $twoWayKey, - 'onDelete' => $onDelete, - ] - ]), $response, $dbForProject, $queueForDatabase, $queueForEvents); - - foreach ($column->getAttribute('options', []) as $k => $option) { - $column->setAttribute($k, $option); - } - - $response - ->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED) - ->dynamic($column, UtopiaResponse::MODEL_COLUMN_RELATIONSHIP); + ->callback(function (string $databaseId, string $tableId, string $relatedTableId, string $type, bool $twoWay, ?string $key, ?string $twoWayKey, string $onDelete, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { + parent::action($databaseId, $tableId, $relatedTableId, $type, $twoWayKey, $key, $twoWayKey, $onDelete, $response, $dbForProject, $queueForDatabase, $queueForEvents); + }); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Relationship/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Relationship/Update.php index 80ca25e9cf..85e4e207a5 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Columns/Relationship/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Columns/Relationship/Update.php @@ -3,7 +3,7 @@ namespace Appwrite\Platform\Modules\Databases\Http\Columns\Relationship; use Appwrite\Event\Event; -use Appwrite\Platform\Modules\Databases\Http\Columns\Action as ColumnAction; +use Appwrite\Platform\Modules\Databases\Http\Attributes\Relationship\Update as RelationshipUpdate; use Appwrite\SDK\AuthType; use Appwrite\SDK\ContentType; use Appwrite\SDK\Method; @@ -12,12 +12,11 @@ use Appwrite\Utopia\Response as UtopiaResponse; use Utopia\Database\Database; use Utopia\Database\Validator\Key; use Utopia\Database\Validator\UID; -use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Swoole\Response as SwooleResponse; use Utopia\Validator\WhiteList; -class Update extends ColumnAction +class Update extends RelationshipUpdate { use HTTP; @@ -28,8 +27,11 @@ class Update extends ColumnAction public function __construct() { + $this->setContext(DATABASE_COLUMNS_CONTEXT); + $this->setResponseModel(UtopiaResponse::MODEL_COLUMN_RELATIONSHIP); + $this - ->setHttpMethod(Action::HTTP_REQUEST_METHOD_PATCH) + ->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH) ->setHttpPath('/v1/databases/:databaseId/tables/:tableId/columns/:key/relationship') ->httpAlias('/v1/databases/:databaseId/collections/:tableId/attributes/:key/relationship') ->desc('Update relationship column') @@ -41,14 +43,14 @@ class Update extends ColumnAction ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( namespace: 'databases', - group: 'columns', - name: 'updateRelationshipColumn', + group: $this->getSdkGroup(), + name: self::getName(), description: '/docs/references/databases/update-relationship-attribute.md', auth: [AuthType::KEY], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_OK, - model: UtopiaResponse::MODEL_COLUMN_RELATIONSHIP + model: $this->getResponseModel() ) ], contentType: ContentType::JSON @@ -65,39 +67,8 @@ class Update extends ColumnAction ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') - ->callback([$this, 'action']); - } - - public function action( - string $databaseId, - string $tableId, - string $key, - ?string $onDelete, - ?string $newKey, - UtopiaResponse $response, - Database $dbForProject, - Event $queueForEvents - ): void { - $column = $this->updateColumn( - $databaseId, - $tableId, - $key, - $dbForProject, - $queueForEvents, - type: Database::VAR_RELATIONSHIP, - required: false, - options: [ - 'onDelete' => $onDelete - ], - newKey: $newKey - ); - - foreach ($column->getAttribute('options', []) as $k => $option) { - $column->setAttribute($k, $option); - } - - $response - ->setStatusCode(SwooleResponse::STATUS_CODE_OK) - ->dynamic($column, UtopiaResponse::MODEL_COLUMN_RELATIONSHIP); + ->callback(function (string $databaseId, string $tableId, string $key, ?string $onDelete, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents) { + parent::action($databaseId, $tableId, $key, $onDelete, $newKey, $response, $dbForProject, $queueForEvents); + }); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Columns/String/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Columns/String/Create.php index e768fda1d6..e00bdf679e 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Columns/String/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Columns/String/Create.php @@ -4,17 +4,14 @@ namespace Appwrite\Platform\Modules\Databases\Http\Columns\String; use Appwrite\Event\Database as EventDatabase; use Appwrite\Event\Event; -use Appwrite\Extend\Exception; -use Appwrite\Platform\Modules\Databases\Http\Columns\Action as ColumnAction; +use Appwrite\Platform\Modules\Databases\Http\Attributes\String\Create as StringCreate; use Appwrite\SDK\AuthType; use Appwrite\SDK\Method; use Appwrite\SDK\Response as SDKResponse; use Appwrite\Utopia\Response as UtopiaResponse; use Utopia\Database\Database; -use Utopia\Database\Document; use Utopia\Database\Validator\Key; use Utopia\Database\Validator\UID; -use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Swoole\Response as SwooleResponse; use Utopia\Validator; @@ -22,7 +19,7 @@ use Utopia\Validator\Boolean; use Utopia\Validator\Range; use Utopia\Validator\Text; -class Create extends ColumnAction +class Create extends StringCreate { use HTTP; @@ -33,10 +30,12 @@ class Create extends ColumnAction public function __construct() { + $this->setContext(DATABASE_COLUMNS_CONTEXT); + $this->setResponseModel(UtopiaResponse::MODEL_COLUMN_STRING); + $this - ->setHttpMethod(Action::HTTP_REQUEST_METHOD_POST) + ->setHttpMethod(self::HTTP_REQUEST_METHOD_POST) ->setHttpPath('/v1/databases/:databaseId/tables/:tableId/columns/string') - ->httpAlias('/v1/databases/:databaseId/collections/:tableId/attributes/string') ->desc('Create string column') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') @@ -46,14 +45,14 @@ class Create extends ColumnAction ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( namespace: 'databases', - group: 'columns', - name: 'createStringColumn', + group: $this->getSdkGroup(), + name: self::getName(), description: '/docs/references/databases/create-string-attribute.md', auth: [AuthType::KEY], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_ACCEPTED, - model: UtopiaResponse::MODEL_COLUMN_STRING + model: $this->getResponseModel() ) ] )) @@ -69,54 +68,8 @@ class Create extends ColumnAction ->inject('dbForProject') ->inject('queueForDatabase') ->inject('queueForEvents') - ->callback([$this, 'action']); - } - - public function action( - string $databaseId, - string $tableId, - string $key, - ?int $size, - ?bool $required, - ?string $default, - bool $array, - bool $encrypt, - UtopiaResponse $response, - Database $dbForProject, - EventDatabase $queueForDatabase, - Event $queueForEvents - ): void { - // Ensure default fits in the given size - $validator = new Text($size, 0); - if (!is_null($default) && !$validator->isValid($default)) { - throw new Exception(Exception::COLUMN_VALUE_INVALID, $validator->getDescription()); - } - - $filters = []; - if ($encrypt) { - $filters[] = 'encrypt'; - } - - $column = $this->createColumn( - $databaseId, - $tableId, - new Document([ - 'key' => $key, - 'type' => Database::VAR_STRING, - 'size' => $size, - 'required' => $required, - 'default' => $default, - 'array' => $array, - 'filters' => $filters, - ]), - $response, - $dbForProject, - $queueForDatabase, - $queueForEvents - ); - - $response - ->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED) - ->dynamic($column, UtopiaResponse::MODEL_COLUMN_STRING); + ->callback(function (string $databaseId, string $tableId, string $key, ?int $size, ?bool $required, ?string $default, bool $array, bool $encrypt, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { + parent::action($databaseId, $tableId, $key, $size, $required, $default, $array, $encrypt, $response, $dbForProject, $queueForDatabase, $queueForEvents); + }); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Columns/String/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Columns/String/Update.php index ca692d9269..9db47fba69 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Columns/String/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Columns/String/Update.php @@ -3,7 +3,7 @@ namespace Appwrite\Platform\Modules\Databases\Http\Columns\String; use Appwrite\Event\Event; -use Appwrite\Platform\Modules\Databases\Http\Columns\Action as ColumnAction; +use Appwrite\Platform\Modules\Databases\Http\Attributes\String\Update as StringUpdate; use Appwrite\SDK\AuthType; use Appwrite\SDK\ContentType; use Appwrite\SDK\Method; @@ -12,7 +12,6 @@ use Appwrite\Utopia\Response as UtopiaResponse; use Utopia\Database\Database; use Utopia\Database\Validator\Key; use Utopia\Database\Validator\UID; -use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Swoole\Response as SwooleResponse; use Utopia\Validator; @@ -21,7 +20,7 @@ use Utopia\Validator\Nullable; use Utopia\Validator\Range; use Utopia\Validator\Text; -class Update extends ColumnAction +class Update extends StringUpdate { use HTTP; @@ -32,9 +31,12 @@ class Update extends ColumnAction public function __construct() { - $this->setHttpMethod(Action::HTTP_REQUEST_METHOD_PATCH) + $this->setContext(DATABASE_COLUMNS_CONTEXT); + $this->setResponseModel(UtopiaResponse::MODEL_COLUMN_STRING); + + $this + ->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH) ->setHttpPath('/v1/databases/:databaseId/tables/:tableId/columns/string/:key') - ->httpAlias('/v1/databases/:databaseId/collections/:tableId/attributes/string/:key') ->desc('Update string column') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') @@ -44,14 +46,14 @@ class Update extends ColumnAction ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( namespace: 'databases', - group: 'columns', - name: 'updateStringColumn', + group: $this->getSdkGroup(), + name: self::getName(), description: '/docs/references/databases/update-string-attribute.md', auth: [AuthType::KEY], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_OK, - model: UtopiaResponse::MODEL_COLUMN_STRING, + model: $this->getResponseModel(), ) ], contentType: ContentType::JSON @@ -66,36 +68,8 @@ class Update extends ColumnAction ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') - ->callback([$this, 'action']); - } - - public function action( - string $databaseId, - string $tableId, - string $key, - ?bool $required, - ?string $default, - ?int $size, - ?string $newKey, - UtopiaResponse $response, - Database $dbForProject, - Event $queueForEvents - ): void { - $column = $this->updateColumn( - databaseId: $databaseId, - tableId: $tableId, - key: $key, - dbForProject: $dbForProject, - queueForEvents: $queueForEvents, - type: Database::VAR_STRING, - size: $size, - default: $default, - required: $required, - newKey: $newKey - ); - - $response - ->setStatusCode(SwooleResponse::STATUS_CODE_OK) - ->dynamic($column, UtopiaResponse::MODEL_COLUMN_STRING); + ->callback(function (string $databaseId, string $tableId, string $key, ?bool $required, ?string $default, ?int $size, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents) { + parent::action($databaseId, $tableId, $key, $required, $default, $size, $newKey, $response, $dbForProject, $queueForEvents); + }); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Columns/URL/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Columns/URL/Create.php index c1483c373a..ee770e9e4d 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Columns/URL/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Columns/URL/Create.php @@ -4,22 +4,20 @@ namespace Appwrite\Platform\Modules\Databases\Http\Columns\URL; use Appwrite\Event\Database as EventDatabase; use Appwrite\Event\Event; -use Appwrite\Platform\Modules\Databases\Http\Columns\Action as ColumnAction; +use Appwrite\Platform\Modules\Databases\Http\Attributes\URL\Create as URLCreate; use Appwrite\SDK\AuthType; use Appwrite\SDK\Method; use Appwrite\SDK\Response as SDKResponse; use Appwrite\Utopia\Response as UtopiaResponse; use Utopia\Database\Database; -use Utopia\Database\Document; use Utopia\Database\Validator\Key; use Utopia\Database\Validator\UID; -use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Swoole\Response as SwooleResponse; use Utopia\Validator\Boolean; use Utopia\Validator\URL; -class Create extends ColumnAction +class Create extends URLCreate { use HTTP; @@ -30,10 +28,12 @@ class Create extends ColumnAction public function __construct() { + $this->setContext(DATABASE_COLUMNS_CONTEXT); + $this->setResponseModel(UtopiaResponse::MODEL_COLUMN_URL); + $this - ->setHttpMethod(Action::HTTP_REQUEST_METHOD_POST) + ->setHttpMethod(self::HTTP_REQUEST_METHOD_POST) ->setHttpPath('/v1/databases/:databaseId/tables/:tableId/columns/url') - ->httpAlias('/v1/databases/:databaseId/collections/:tableId/attributes/url') ->desc('Create URL column') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') @@ -43,14 +43,14 @@ class Create extends ColumnAction ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( namespace: 'databases', - group: 'columns', - name: 'createUrlColumn', + group: $this->getSdkGroup(), + name: self::getName(), description: '/docs/references/databases/create-url-attribute.md', auth: [AuthType::KEY], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_ACCEPTED, - model: UtopiaResponse::MODEL_COLUMN_URL, + model: $this->getResponseModel(), ) ] )) @@ -64,33 +64,8 @@ class Create extends ColumnAction ->inject('dbForProject') ->inject('queueForDatabase') ->inject('queueForEvents') - ->callback([$this, 'action']); - } - - public function action( - string $databaseId, - string $tableId, - string $key, - ?bool $required, - ?string $default, - bool $array, - UtopiaResponse $response, - Database $dbForProject, - EventDatabase $queueForDatabase, - Event $queueForEvents - ): void { - $column = $this->createColumn($databaseId, $tableId, new Document([ - 'key' => $key, - 'type' => Database::VAR_STRING, - 'size' => 2000, - 'required' => $required, - 'default' => $default, - 'array' => $array, - 'format' => APP_DATABASE_ATTRIBUTE_URL, - ]), $response, $dbForProject, $queueForDatabase, $queueForEvents); - - $response - ->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED) - ->dynamic($column, UtopiaResponse::MODEL_COLUMN_URL); + ->callback(function (string $databaseId, string $tableId, string $key, ?bool $required, ?string $default, bool $array, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { + parent::action($databaseId, $tableId, $key, $required, $default, $array, $response, $dbForProject, $queueForDatabase, $queueForEvents); + }); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Columns/URL/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Columns/URL/Update.php index db35cf56c4..360445750b 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Columns/URL/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Columns/URL/Update.php @@ -3,7 +3,7 @@ namespace Appwrite\Platform\Modules\Databases\Http\Columns\URL; use Appwrite\Event\Event; -use Appwrite\Platform\Modules\Databases\Http\Columns\Action as ColumnAction; +use Appwrite\Platform\Modules\Databases\Http\Attributes\URL\Update as URLUpdate; use Appwrite\SDK\AuthType; use Appwrite\SDK\ContentType; use Appwrite\SDK\Method; @@ -12,14 +12,13 @@ use Appwrite\Utopia\Response as UtopiaResponse; use Utopia\Database\Database; use Utopia\Database\Validator\Key; use Utopia\Database\Validator\UID; -use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Swoole\Response as SwooleResponse; use Utopia\Validator\Boolean; use Utopia\Validator\Nullable; use Utopia\Validator\URL; -class Update extends ColumnAction +class Update extends URLUpdate { use HTTP; @@ -30,8 +29,11 @@ class Update extends ColumnAction public function __construct() { + $this->setContext(DATABASE_COLUMNS_CONTEXT); + $this->setResponseModel(UtopiaResponse::MODEL_COLUMN_URL); + $this - ->setHttpMethod(Action::HTTP_REQUEST_METHOD_PATCH) + ->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH) ->setHttpPath('/v1/databases/:databaseId/tables/:tableId/columns/url/:key') ->httpAlias('/v1/databases/:databaseId/collections/:tableId/attributes/url/:key') ->desc('Update URL column') @@ -43,14 +45,14 @@ class Update extends ColumnAction ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( namespace: 'databases', - group: 'columns', - name: 'updateUrlColumn', + group: $this->getSdkGroup(), + name: self::getName(), description: '/docs/references/databases/update-url-attribute.md', auth: [AuthType::KEY], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_OK, - model: UtopiaResponse::MODEL_COLUMN_URL, + model: $this->getResponseModel(), ) ], contentType: ContentType::JSON @@ -64,35 +66,8 @@ class Update extends ColumnAction ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') - ->callback([$this, 'action']); - } - - public function action( - string $databaseId, - string $tableId, - string $key, - ?bool $required, - ?string $default, - ?string $newKey, - UtopiaResponse $response, - Database $dbForProject, - Event $queueForEvents - ): void { - $column = $this->updateColumn( - $databaseId, - $tableId, - $key, - $dbForProject, - $queueForEvents, - type: Database::VAR_STRING, - filter: APP_DATABASE_ATTRIBUTE_URL, - default: $default, - required: $required, - newKey: $newKey - ); - - $response - ->setStatusCode(SwooleResponse::STATUS_CODE_OK) - ->dynamic($column, UtopiaResponse::MODEL_COLUMN_URL); + ->callback(function (string $databaseId, string $tableId, string $key, ?bool $required, ?string $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents) { + parent::action($databaseId, $tableId, $key, $required, $default, $newKey, $response, $dbForProject, $queueForEvents); + }); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Columns/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Columns/XList.php index c480536e6c..06d7a57dcf 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Columns/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Columns/XList.php @@ -2,24 +2,18 @@ namespace Appwrite\Platform\Modules\Databases\Http\Columns; -use Appwrite\Extend\Exception; +use Appwrite\Platform\Modules\Databases\Http\Attributes\XList as AttributesXList; use Appwrite\SDK\AuthType; use Appwrite\SDK\Method; use Appwrite\SDK\Response as SDKResponse; use Appwrite\Utopia\Database\Validator\Queries\Columns; use Appwrite\Utopia\Response as UtopiaResponse; use Utopia\Database\Database; -use Utopia\Database\Document; -use Utopia\Database\Exception\Order as OrderException; -use Utopia\Database\Query; -use Utopia\Database\Validator\Authorization; -use Utopia\Database\Validator\Query\Cursor; use Utopia\Database\Validator\UID; -use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Swoole\Response as SwooleResponse; -class XList extends Action +class XList extends AttributesXList { use HTTP; @@ -30,24 +24,26 @@ class XList extends Action public function __construct() { + $this->setContext(DATABASE_COLUMNS_CONTEXT); + $this->setResponseModel(UtopiaResponse::MODEL_COLUMN_LIST); + $this ->setHttpMethod(self::HTTP_REQUEST_METHOD_GET) ->setHttpPath('/v1/databases/:databaseId/tables/:tableId/columns') - ->httpAlias('/v1/databases/:databaseId/collections/:tableId/attributes') ->desc('List columns') ->groups(['api', 'database']) ->label('scope', 'collections.read') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( namespace: 'databases', - group: 'columns', - name: 'listColumns', + group: $this->getSdkGroup(), + name: self::getName(), description: '/docs/references/databases/list-attributes.md', auth: [AuthType::KEY], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_OK, - model: UtopiaResponse::MODEL_COLUMN_LIST + model: $this->getResponseModel() ) ] )) @@ -56,70 +52,8 @@ class XList extends Action ->param('queries', [], new Columns(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long. You may filter on the following attributes: ' . implode(', ', Columns::ALLOWED_ATTRIBUTES), true) ->inject('response') ->inject('dbForProject') - ->callback([$this, 'action']); - } - - public function action(string $databaseId, string $tableId, array $queries, UtopiaResponse $response, Database $dbForProject): void - { - $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); - if ($database->isEmpty()) { - throw new Exception(Exception::DATABASE_NOT_FOUND); - } - - $table = $dbForProject->getDocument('database_' . $database->getInternalId(), $tableId); - if ($table->isEmpty()) { - throw new Exception(Exception::TABLE_NOT_FOUND); - } - - $queries = Query::parseQueries($queries); - - \array_push( - $queries, - Query::equal('databaseInternalId', [$database->getInternalId()]), - Query::equal('collectionInternalId', [$table->getInternalId()]) - ); - - $cursor = \array_filter( - $queries, - fn ($query) => \in_array($query->getMethod(), [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]) - ); - $cursor = \reset($cursor); - - if ($cursor) { - $validator = new Cursor(); - if (!$validator->isValid($cursor)) { - throw new Exception(Exception::GENERAL_QUERY_INVALID, $validator->getDescription()); - } - - $columnId = $cursor->getValue(); - $cursorDocument = Authorization::skip( - fn () => $dbForProject->find('attributes', [ - Query::equal('databaseInternalId', [$database->getInternalId()]), - Query::equal('collectionInternalId', [$table->getInternalId()]), - Query::equal('key', [$columnId]), - Query::limit(1), - ]) - ); - - if (empty($cursorDocument) || $cursorDocument[0]->isEmpty()) { - throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Column '{$columnId}' for the 'cursor' value not found."); - } - - $cursor->setValue($cursorDocument[0]); - } - - $filters = Query::groupByType($queries)['filters']; - - try { - $columns = $dbForProject->find('attributes', $queries); - $total = $dbForProject->count('attributes', $filters, APP_LIMIT_COUNT); - } catch (OrderException $e) { - throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order column '{$e->getAttribute()}' had a null value. Cursor pagination requires all rows order column values are non-null."); - } - - $response->dynamic(new Document([ - 'columns' => $columns, - 'total' => $total, - ]), UtopiaResponse::MODEL_COLUMN_LIST); + ->callback(function (string $databaseId, string $tableId, array $queries, UtopiaResponse $response, Database $dbForProject) { + parent::action($databaseId, $tableId, $queries, $response, $dbForProject); + }); } }