From 3092e765cc9c82b66deec4c844f432a5e72d4d76 Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 9 Feb 2025 18:34:41 +0200 Subject: [PATCH 1/9] indexException --- app/controllers/api/databases.php | 18 ++++++++++++ composer.lock | 46 +++++++++++++++---------------- 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index df46c1890b..8b2369ee15 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -377,6 +377,19 @@ function updateAttribute( $dbForProject->purgeCachedDocument('database_' . $db->getInternalId(), $relatedCollection->getId()); } } else { + + $validator = new IndexValidator( + $collection->getAttribute('attributes', []), + $dbForProject->getAdapter()->getMaxIndexLength(), + $dbForProject->getAdapter()->getInternalIndexesKeys(), + ); + + foreach ($collection->getAttribute('indexes', []) as $index){ + if (!$validator->isValid($index)) { + throw new Exception(Exception::INDEX_INVALID, $validator->getDescription()); + } + } + try { $dbForProject->updateAttribute( collection: $collectionId, @@ -393,6 +406,11 @@ function updateAttribute( throw new Exception(Exception::ATTRIBUTE_NOT_FOUND); } catch (LimitException) { throw new Exception(Exception::ATTRIBUTE_LIMIT_EXCEEDED); + } catch (indexException $e) { + /** + * We do not have index indexException thrown from Utopia... + */ + throw new Exception(Exception::INDEX_INVALID, $e->getDescription()); } } diff --git a/composer.lock b/composer.lock index f3075c1801..a65fabb429 100644 --- a/composer.lock +++ b/composer.lock @@ -1237,16 +1237,16 @@ }, { "name": "open-telemetry/api", - "version": "1.2.1", + "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/opentelemetry-php/api.git", - "reference": "74b1a03263be8c5acb578f41da054b4bac3af4a0" + "reference": "8b925df3047628968bc5be722468db1b98b82d51" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/opentelemetry-php/api/zipball/74b1a03263be8c5acb578f41da054b4bac3af4a0", - "reference": "74b1a03263be8c5acb578f41da054b4bac3af4a0", + "url": "https://api.github.com/repos/opentelemetry-php/api/zipball/8b925df3047628968bc5be722468db1b98b82d51", + "reference": "8b925df3047628968bc5be722468db1b98b82d51", "shasum": "" }, "require": { @@ -1303,7 +1303,7 @@ "issues": "https://github.com/open-telemetry/opentelemetry-php/issues", "source": "https://github.com/open-telemetry/opentelemetry-php" }, - "time": "2025-01-20T23:35:16+00:00" + "time": "2025-02-03T21:49:11+00:00" }, { "name": "open-telemetry/context", @@ -1493,16 +1493,16 @@ }, { "name": "open-telemetry/sdk", - "version": "1.2.1", + "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/opentelemetry-php/sdk.git", - "reference": "96aeaee5b7cb8c0bc4af7ff4717b429f2d9f67e1" + "reference": "37eec0fe47ddd627911f318f29b6cd48196be0c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/opentelemetry-php/sdk/zipball/96aeaee5b7cb8c0bc4af7ff4717b429f2d9f67e1", - "reference": "96aeaee5b7cb8c0bc4af7ff4717b429f2d9f67e1", + "url": "https://api.github.com/repos/opentelemetry-php/sdk/zipball/37eec0fe47ddd627911f318f29b6cd48196be0c0", + "reference": "37eec0fe47ddd627911f318f29b6cd48196be0c0", "shasum": "" }, "require": { @@ -1579,24 +1579,24 @@ "issues": "https://github.com/open-telemetry/opentelemetry-php/issues", "source": "https://github.com/open-telemetry/opentelemetry-php" }, - "time": "2025-01-09T23:17:14+00:00" + "time": "2025-01-29T21:40:28+00:00" }, { "name": "open-telemetry/sem-conv", - "version": "1.27.1", + "version": "1.30.0", "source": { "type": "git", "url": "https://github.com/opentelemetry-php/sem-conv.git", - "reference": "1dba705fea74bc0718d04be26090e3697e56f4e6" + "reference": "4178c9f390da8e4dbca9b181a9d1efd50cf7ee0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/opentelemetry-php/sem-conv/zipball/1dba705fea74bc0718d04be26090e3697e56f4e6", - "reference": "1dba705fea74bc0718d04be26090e3697e56f4e6", + "url": "https://api.github.com/repos/opentelemetry-php/sem-conv/zipball/4178c9f390da8e4dbca9b181a9d1efd50cf7ee0a", + "reference": "4178c9f390da8e4dbca9b181a9d1efd50cf7ee0a", "shasum": "" }, "require": { - "php": "^8.1" + "php": "^8.0" }, "type": "library", "extra": { @@ -1636,7 +1636,7 @@ "issues": "https://github.com/open-telemetry/opentelemetry-php/issues", "source": "https://github.com/open-telemetry/opentelemetry-php" }, - "time": "2024-08-28T09:20:31+00:00" + "time": "2025-02-06T00:21:48+00:00" }, { "name": "paragonie/constant_time_encoding", @@ -2453,16 +2453,16 @@ }, { "name": "symfony/http-client", - "version": "v7.2.2", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "339ba21476eb184290361542f732ad12c97591ec" + "reference": "7ce6078c79a4a7afff931c413d2959d3bffbfb8d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/339ba21476eb184290361542f732ad12c97591ec", - "reference": "339ba21476eb184290361542f732ad12c97591ec", + "url": "https://api.github.com/repos/symfony/http-client/zipball/7ce6078c79a4a7afff931c413d2959d3bffbfb8d", + "reference": "7ce6078c79a4a7afff931c413d2959d3bffbfb8d", "shasum": "" }, "require": { @@ -2528,7 +2528,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v7.2.2" + "source": "https://github.com/symfony/http-client/tree/v7.2.3" }, "funding": [ { @@ -2544,7 +2544,7 @@ "type": "tidelift" } ], - "time": "2024-12-30T18:35:15+00:00" + "time": "2025-01-28T15:51:35+00:00" }, { "name": "symfony/http-client-contracts", @@ -8503,7 +8503,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": {}, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { From 5b786e2a688da15bbd840fb80a06621dba42c4a8 Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 10 Feb 2025 09:19:56 +0200 Subject: [PATCH 2/9] Catch index exception --- app/controllers/general.php | 3 +++ composer.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index 7e691d033f..d9d41a16fd 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -837,6 +837,9 @@ App::error() case 'Utopia\Database\Exception\Dependency': $error = new AppwriteException(AppwriteException::INDEX_DEPENDENCY, null, previous: $error); break; + case 'Utopia\Database\Exception\Index': + $error = new AppwriteException(AppwriteException::INDEX_INVALID, $error->getMessage(), previous: $error); + break; } $code = $error->getCode(); diff --git a/composer.json b/composer.json index 8f5bb54f79..d0b457b6bd 100644 --- a/composer.json +++ b/composer.json @@ -51,7 +51,7 @@ "utopia-php/cache": "0.11.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "0.56.4", + "utopia-php/database": "dev-index-exception as 0.56.4", "utopia-php/domains": "0.5.*", "utopia-php/dsn": "0.2.1", "utopia-php/framework": "0.33.*", From 27709e7683d3505ba442fca537352db24be734da Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 10 Feb 2025 10:04:51 +0200 Subject: [PATCH 3/9] IndexException --- app/controllers/api/databases.php | 8 +++----- composer.json | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index 8b2369ee15..c0357ceac1 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -27,6 +27,7 @@ use Utopia\Database\Document; use Utopia\Database\Exception\Authorization as AuthorizationException; use Utopia\Database\Exception\Conflict as ConflictException; use Utopia\Database\Exception\Duplicate as DuplicateException; +use Utopia\Database\Exception\Index as IndexException; use Utopia\Database\Exception\Limit as LimitException; use Utopia\Database\Exception\NotFound as NotFoundException; use Utopia\Database\Exception\Query as QueryException; @@ -384,7 +385,7 @@ function updateAttribute( $dbForProject->getAdapter()->getInternalIndexesKeys(), ); - foreach ($collection->getAttribute('indexes', []) as $index){ + foreach ($collection->getAttribute('indexes', []) as $index) { if (!$validator->isValid($index)) { throw new Exception(Exception::INDEX_INVALID, $validator->getDescription()); } @@ -407,10 +408,7 @@ function updateAttribute( } catch (LimitException) { throw new Exception(Exception::ATTRIBUTE_LIMIT_EXCEEDED); } catch (indexException $e) { - /** - * We do not have index indexException thrown from Utopia... - */ - throw new Exception(Exception::INDEX_INVALID, $e->getDescription()); + throw new Exception(Exception::INDEX_INVALID, $e->getMessage()); } } diff --git a/composer.json b/composer.json index d0b457b6bd..8f5bb54f79 100644 --- a/composer.json +++ b/composer.json @@ -51,7 +51,7 @@ "utopia-php/cache": "0.11.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "dev-index-exception as 0.56.4", + "utopia-php/database": "0.56.4", "utopia-php/domains": "0.5.*", "utopia-php/dsn": "0.2.1", "utopia-php/framework": "0.33.*", From a032540b3c5676e83322ff64d9b93ce6b51b3d36 Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 10 Feb 2025 10:11:52 +0200 Subject: [PATCH 4/9] IndexException --- app/controllers/api/databases.php | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index c0357ceac1..4d62c9c384 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -378,19 +378,6 @@ function updateAttribute( $dbForProject->purgeCachedDocument('database_' . $db->getInternalId(), $relatedCollection->getId()); } } else { - - $validator = new IndexValidator( - $collection->getAttribute('attributes', []), - $dbForProject->getAdapter()->getMaxIndexLength(), - $dbForProject->getAdapter()->getInternalIndexesKeys(), - ); - - foreach ($collection->getAttribute('indexes', []) as $index) { - if (!$validator->isValid($index)) { - throw new Exception(Exception::INDEX_INVALID, $validator->getDescription()); - } - } - try { $dbForProject->updateAttribute( collection: $collectionId, From edbe0fb72ff58f721c32f66f53dbcf931cf01490 Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 10 Feb 2025 10:40:12 +0200 Subject: [PATCH 5/9] Bump Database version 0.58.5 --- composer.json | 2 +- composer.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index fe3400cfe5..b7c3711410 100644 --- a/composer.json +++ b/composer.json @@ -51,7 +51,7 @@ "utopia-php/cache": "0.11.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "0.58.4", + "utopia-php/database": "0.58.5", "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 87ee9979ae..e653783ef5 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": "232691925e05350c7a3831a4e43d79d1", + "content-hash": "4a54d0bd5973ed68082970f317664df3", "packages": [ { "name": "adhocore/jwt", @@ -3717,16 +3717,16 @@ }, { "name": "utopia-php/database", - "version": "0.58.4", + "version": "0.58.5", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "ff3fd22e4fe757cc2a78f17169f6dcc45c96d0fe" + "reference": "55308014c697639c6cb270cb5a33cc88fc1ef839" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/ff3fd22e4fe757cc2a78f17169f6dcc45c96d0fe", - "reference": "ff3fd22e4fe757cc2a78f17169f6dcc45c96d0fe", + "url": "https://api.github.com/repos/utopia-php/database/zipball/55308014c697639c6cb270cb5a33cc88fc1ef839", + "reference": "55308014c697639c6cb270cb5a33cc88fc1ef839", "shasum": "" }, "require": { @@ -3767,9 +3767,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.58.4" + "source": "https://github.com/utopia-php/database/tree/0.58.5" }, - "time": "2025-02-05T02:51:02+00:00" + "time": "2025-02-10T08:26:52+00:00" }, { "name": "utopia-php/domains", From 33f55c73a7148dae168af76c8e1184e9491e5e52 Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 10 Feb 2025 10:42:29 +0200 Subject: [PATCH 6/9] Revert cast Index --- app/controllers/general.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index d9d41a16fd..7e691d033f 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -837,9 +837,6 @@ App::error() case 'Utopia\Database\Exception\Dependency': $error = new AppwriteException(AppwriteException::INDEX_DEPENDENCY, null, previous: $error); break; - case 'Utopia\Database\Exception\Index': - $error = new AppwriteException(AppwriteException::INDEX_INVALID, $error->getMessage(), previous: $error); - break; } $code = $error->getCode(); From 7caab2f9ff5ae9b56b4c583ea235d13c12b4d7aa Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 10 Feb 2025 10:55:37 +0200 Subject: [PATCH 7/9] IndexException --- app/controllers/api/databases.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index 4d62c9c384..1e0fa03d2c 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -394,7 +394,7 @@ function updateAttribute( throw new Exception(Exception::ATTRIBUTE_NOT_FOUND); } catch (LimitException) { throw new Exception(Exception::ATTRIBUTE_LIMIT_EXCEEDED); - } catch (indexException $e) { + } catch (IndexException $e) { throw new Exception(Exception::INDEX_INVALID, $e->getMessage()); } } From 7a8688932c86097de2dc092fea254dae8d976bb1 Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 10 Feb 2025 15:40:21 +0200 Subject: [PATCH 8/9] Add test --- .../e2e/Services/Databases/DatabasesBase.php | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/tests/e2e/Services/Databases/DatabasesBase.php b/tests/e2e/Services/Databases/DatabasesBase.php index d079cb313c..adc31a391d 100644 --- a/tests/e2e/Services/Databases/DatabasesBase.php +++ b/tests/e2e/Services/Databases/DatabasesBase.php @@ -399,6 +399,73 @@ trait DatabasesBase $this->assertEquals(400, $response['headers']['status-code']); } + /** + * @depends testCreateDatabase + */ + public function testPatchAttribute(array $data): void + { + $databaseId = $data['databaseId']; + + $collection = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'patch', + 'documentSecurity' => true, + 'permissions' => [ + Permission::create(Role::user($this->getUser()['$id'])), + ], + ]); + + $this->assertEquals(201, $collection['headers']['status-code']); + $this->assertEquals($collection['body']['name'], 'patch'); + + $attribute = $this->client->call(Client::METHOD_POST, '/databases/'.$databaseId.'/collections/'.$collection['body']['$id'].'/attributes/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'title', + 'required' => true, + 'size' => 100, + ]); + $this->assertEquals(202, $attribute['headers']['status-code']); + $this->assertEquals($attribute['body']['size'], 100); + + sleep(1); + + $index = $this->client->call(Client::METHOD_POST, '/databases/'.$databaseId.'/collections/'.$collection['body']['$id'].'/indexes', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'titleIndex', + 'type' => 'key', + 'attributes' => ['title'], + ]); + $this->assertEquals(202, $index['headers']['status-code']); + + sleep(1); + + /** + * Update attribute size to exceed Index maximux length + */ + $attribute = $this->client->call(Client::METHOD_PATCH, '/databases/'.$databaseId.'/collections/'.$collection['body']['$id'].'/attributes/string/'.$attribute['body']['key'], array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ]), [ + 'size' => 1000, + 'required' => true, + 'default' => null, + ]); + + $this->assertEquals(400, $attribute['headers']['status-code']); + $this->assertEquals('Index length is longer than the maximum: 768', $attribute['body']['message']); + } + public function testUpdateAttributeEnum(): void { $database = $this->client->call(Client::METHOD_POST, '/databases', [ From 8c3a243a5d3365d95653b2ba61cde92fe35e769a Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 10 Feb 2025 15:40:45 +0200 Subject: [PATCH 9/9] Typo --- tests/e2e/Services/Databases/DatabasesBase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/Services/Databases/DatabasesBase.php b/tests/e2e/Services/Databases/DatabasesBase.php index adc31a391d..3321a786a7 100644 --- a/tests/e2e/Services/Databases/DatabasesBase.php +++ b/tests/e2e/Services/Databases/DatabasesBase.php @@ -450,7 +450,7 @@ trait DatabasesBase sleep(1); /** - * Update attribute size to exceed Index maximux length + * Update attribute size to exceed Index maximum length */ $attribute = $this->client->call(Client::METHOD_PATCH, '/databases/'.$databaseId.'/collections/'.$collection['body']['$id'].'/attributes/string/'.$attribute['body']['key'], array_merge([ 'content-type' => 'application/json',