From 40b1c28db08690997b578d2d78af2c08694acb30 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Fri, 30 Aug 2024 18:22:17 +0900 Subject: [PATCH] Implement String Attribute Resizing --- app/config/errors.php | 5 +++ app/controllers/api/databases.php | 66 ++++++++++++++++++++----------- composer.json | 6 +-- composer.lock | 54 ++++++++++++------------- src/Appwrite/Extend/Exception.php | 1 + 5 files changed, 80 insertions(+), 52 deletions(-) diff --git a/app/config/errors.php b/app/config/errors.php index dc6dcd5daf..fc79599b12 100644 --- a/app/config/errors.php +++ b/app/config/errors.php @@ -699,6 +699,11 @@ return [ 'description' => 'The relationship value is invalid.', 'code' => 400, ], + Exception::ATTRIBUTE_INVALID_RESIZE => [ + 'name' => Exception::ATTRIBUTE_INVALID_RESIZE, + 'description' => "Existing data is too large for new size, truncate your existing data then try again.", + 'code' => 400, + ], /** Indexes */ Exception::INDEX_NOT_FOUND => [ diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index 54fc1cb08f..d83a542c5a 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -20,6 +20,7 @@ use Utopia\Audit\Audit; use Utopia\Config\Config; use Utopia\Database\Database; use Utopia\Database\Document; +use Utopia\Database\Exception as DatabaseException; use Utopia\Database\Exception\Authorization as AuthorizationException; use Utopia\Database\Exception\Conflict as ConflictException; use Utopia\Database\Exception\Duplicate as DuplicateException; @@ -234,7 +235,8 @@ function updateAttribute( int|float $min = null, int|float $max = null, array $elements = null, - array $options = [] + array $options = [], + int $size = null ): Document { $db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); @@ -280,6 +282,10 @@ function updateAttribute( ->setAttribute('default', $default) ->setAttribute('required', $required); + if (!empty($size)) { + $attribute->setAttribute('size', $size); + } + $formatOptions = $attribute->getAttribute('formatOptions'); switch ($attribute->getAttribute('format')) { @@ -363,7 +369,8 @@ function updateAttribute( id: $key, required: $required, default: $default, - formatOptions: $options ?? null + formatOptions: $options ?? null, + size: $size ?? null, ); } @@ -1142,15 +1149,20 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/string $filters[] = 'encrypt'; } - $attribute = createAttribute($databaseId, $collectionId, new Document([ - 'key' => $key, - 'type' => Database::VAR_STRING, - 'size' => $size, - 'required' => $required, - 'default' => $default, - 'array' => $array, - 'filters' => $filters, - ]), $response, $dbForProject, $queueForDatabase, $queueForEvents); + try { + $attribute = createAttribute($databaseId, $collectionId, new Document([ + 'key' => $key, + 'type' => Database::VAR_STRING, + 'size' => $size, + 'required' => $required, + 'default' => $default, + 'array' => $array, + 'filters' => $filters, + ]), $response, $dbForProject, $queueForDatabase, $queueForEvents); + } catch (DatabaseException $e) { + var_dump($e); + } + $response ->setStatusCode(Response::STATUS_CODE_ACCEPTED) @@ -1859,21 +1871,31 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/strin ->param('key', '', new Key(), 'Attribute Key.') ->param('required', null, new Boolean(), 'Is attribute required?') ->param('default', null, new Nullable(new Text(0, 0)), 'Default value for attribute when not provided. Cannot be set when attribute is required.') + ->param('size', null, new Integer(), 'Maximum size of the string attribute.', true) ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') - ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, Response $response, Database $dbForProject, Event $queueForEvents) { + ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, ?int $size, Response $response, Database $dbForProject, Event $queueForEvents) { - $attribute = updateAttribute( - databaseId: $databaseId, - collectionId: $collectionId, - key: $key, - dbForProject: $dbForProject, - queueForEvents: $queueForEvents, - type: Database::VAR_STRING, - default: $default, - required: $required - ); + try { + $attribute = updateAttribute( + databaseId: $databaseId, + collectionId: $collectionId, + key: $key, + dbForProject: $dbForProject, + queueForEvents: $queueForEvents, + type: Database::VAR_STRING, + default: $default, + required: $required, + size: $size + ); + } catch (DatabaseException $e) { + if ($e->getMessage() === "Resize would result in data truncation") { + throw new Exception(Exception::ATTRIBUTE_INVALID_RESIZE); + } else { + throw $e; + } + } $response ->setStatusCode(Response::STATUS_CODE_OK) diff --git a/composer.json b/composer.json index d572d502a7..91ff1eeb92 100644 --- a/composer.json +++ b/composer.json @@ -45,13 +45,13 @@ "ext-sockets": "*", "appwrite/php-runtimes": "0.15.*", "appwrite/php-clamav": "2.0.*", - "utopia-php/abuse": "0.42.0", + "utopia-php/abuse": "0.43.0", "utopia-php/analytics": "0.10.*", - "utopia-php/audit": "0.42.0", + "utopia-php/audit": "0.43.0", "utopia-php/cache": "0.10.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "0.52.*", + "utopia-php/database": "0.53.*", "utopia-php/domains": "0.5.*", "utopia-php/dsn": "0.2.1", "utopia-php/framework": "0.33.*", diff --git a/composer.lock b/composer.lock index e9399132c4..66076e71c9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "eba741eab8bb748ed684c32711d472df", + "content-hash": "b6820da26239716cf14a445697902a03", "packages": [ { "name": "adhocore/jwt", @@ -1429,16 +1429,16 @@ }, { "name": "utopia-php/abuse", - "version": "0.42.0", + "version": "0.43.0", "source": { "type": "git", "url": "https://github.com/utopia-php/abuse.git", - "reference": "08cf17e7f4fd213966c8d8702e406f2269244f0f" + "reference": "6346a3b4c5177a43160035a7289e30fdfb0790d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/abuse/zipball/08cf17e7f4fd213966c8d8702e406f2269244f0f", - "reference": "08cf17e7f4fd213966c8d8702e406f2269244f0f", + "url": "https://api.github.com/repos/utopia-php/abuse/zipball/6346a3b4c5177a43160035a7289e30fdfb0790d6", + "reference": "6346a3b4c5177a43160035a7289e30fdfb0790d6", "shasum": "" }, "require": { @@ -1446,7 +1446,7 @@ "ext-pdo": "*", "ext-redis": "*", "php": ">=8.0", - "utopia-php/database": "0.52.*" + "utopia-php/database": "0.53.*" }, "require-dev": { "laravel/pint": "1.5.*", @@ -1474,9 +1474,9 @@ ], "support": { "issues": "https://github.com/utopia-php/abuse/issues", - "source": "https://github.com/utopia-php/abuse/tree/0.42.0" + "source": "https://github.com/utopia-php/abuse/tree/0.43.0" }, - "time": "2024-08-21T08:24:01+00:00" + "time": "2024-08-30T05:17:23+00:00" }, { "name": "utopia-php/analytics", @@ -1526,21 +1526,21 @@ }, { "name": "utopia-php/audit", - "version": "0.42.0", + "version": "0.43.0", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "9dc168470625bcf11ff8cd9ab5660db09129f618" + "reference": "cef22b5dc6a6d28fcd522f41c7bf7ded4a4dfd3e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/9dc168470625bcf11ff8cd9ab5660db09129f618", - "reference": "9dc168470625bcf11ff8cd9ab5660db09129f618", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/cef22b5dc6a6d28fcd522f41c7bf7ded4a4dfd3e", + "reference": "cef22b5dc6a6d28fcd522f41c7bf7ded4a4dfd3e", "shasum": "" }, "require": { "php": ">=8.0", - "utopia-php/database": "0.52.*" + "utopia-php/database": "0.53.*" }, "require-dev": { "laravel/pint": "1.5.*", @@ -1567,9 +1567,9 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/0.42.0" + "source": "https://github.com/utopia-php/audit/tree/0.43.0" }, - "time": "2024-08-21T08:24:08+00:00" + "time": "2024-08-30T05:17:36+00:00" }, { "name": "utopia-php/cache", @@ -1723,16 +1723,16 @@ }, { "name": "utopia-php/database", - "version": "0.52.1", + "version": "0.53.1", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "d22a316a010699c5ebb4768c1020167c192b9c6b" + "reference": "3f17072a33649a3451122bfeb630d57330c0a6df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/d22a316a010699c5ebb4768c1020167c192b9c6b", - "reference": "d22a316a010699c5ebb4768c1020167c192b9c6b", + "url": "https://api.github.com/repos/utopia-php/database/zipball/3f17072a33649a3451122bfeb630d57330c0a6df", + "reference": "3f17072a33649a3451122bfeb630d57330c0a6df", "shasum": "" }, "require": { @@ -1773,9 +1773,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.52.1" + "source": "https://github.com/utopia-php/database/tree/0.53.1" }, - "time": "2024-08-23T02:43:43+00:00" + "time": "2024-08-30T09:02:45+00:00" }, { "name": "utopia-php/domains", @@ -4185,16 +4185,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.29.1", + "version": "1.30.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4" + "reference": "5ceb0e384997db59f38774bf79c2a6134252c08f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fcaefacf2d5c417e928405b71b400d4ce10daaf4", - "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/5ceb0e384997db59f38774bf79c2a6134252c08f", + "reference": "5ceb0e384997db59f38774bf79c2a6134252c08f", "shasum": "" }, "require": { @@ -4226,9 +4226,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.1" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.30.0" }, - "time": "2024-05-31T08:52:43+00:00" + "time": "2024-08-29T09:54:52+00:00" }, { "name": "phpunit/php-code-coverage", diff --git a/src/Appwrite/Extend/Exception.php b/src/Appwrite/Extend/Exception.php index 884296ff67..e57936be73 100644 --- a/src/Appwrite/Extend/Exception.php +++ b/src/Appwrite/Extend/Exception.php @@ -200,6 +200,7 @@ class Exception extends \Exception public const ATTRIBUTE_LIMIT_EXCEEDED = 'attribute_limit_exceeded'; public const ATTRIBUTE_VALUE_INVALID = 'attribute_value_invalid'; public const ATTRIBUTE_TYPE_INVALID = 'attribute_type_invalid'; + public const ATTRIBUTE_INVALID_RESIZE = 'attribute_invalid_resize'; /** Relationship */ public const RELATIONSHIP_VALUE_INVALID = 'relationship_value_invalid';