From 60c54e2d10a84022faf374443a1620d944fe866b Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 22 Mar 2023 23:10:47 +0200 Subject: [PATCH] Select Validator --- app/controllers/api/databases.php | 11 +++- .../Utopia/Database/Validator/Queries.php | 5 +- .../Database/Validator/Queries/Base.php | 2 + .../Database/Validator/Queries/Documents.php | 2 + .../Utopia/Database/Validator/Query/Base.php | 1 + .../Database/Validator/Query/Select.php | 56 +++++++++++++++++++ .../e2e/Services/Databases/DatabasesBase.php | 31 ++++++++++ .../Database/Validator/Query/SelectTest.php | 34 +++++++++++ 8 files changed, 138 insertions(+), 4 deletions(-) create mode 100644 src/Appwrite/Utopia/Database/Validator/Query/Select.php create mode 100644 tests/unit/Utopia/Database/Validator/Query/SelectTest.php diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index 60b99767ce..391d21f1b9 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -1,5 +1,7 @@ param('databaseId', '', new UID(), 'Database ID.') ->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).') ->param('documentId', '', new UID(), 'Document ID.') + ->param('queries', [], new Queries(new Select()), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/databases#querying-documents). Only supported methods are limit and offset', true) ->inject('response') ->inject('dbForProject') ->inject('mode') - ->action(function (string $databaseId, string $collectionId, string $documentId, Response $response, Database $dbForProject, string $mode) { + ->action(function (string $databaseId, string $collectionId, string $documentId, array $queries, Response $response, Database $dbForProject, string $mode) { + + var_dump($queries); $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); @@ -2927,9 +2932,9 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen } if ($documentSecurity && !$valid) { - $document = $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId); + $document = $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId, $queries); } else { - $document = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId)); + $document = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId, $queries)); } if ($document->isEmpty()) { diff --git a/src/Appwrite/Utopia/Database/Validator/Queries.php b/src/Appwrite/Utopia/Database/Validator/Queries.php index 2629c08ce5..d6b997d966 100644 --- a/src/Appwrite/Utopia/Database/Validator/Queries.php +++ b/src/Appwrite/Utopia/Database/Validator/Queries.php @@ -57,7 +57,7 @@ class Queries extends Validator if (!$query instanceof Query) { try { $query = Query::parse($query); - if (\str_contains($query->getAttribute(), '.')) { + if (\str_contains($query->getAttribute(), '.')) { // todo: double check! return true; } } catch (\Throwable $th) { @@ -69,6 +69,9 @@ class Queries extends Validator $method = $query->getMethod(); $methodType = ''; switch ($method) { + case Query::TYPE_SELECT: + $methodType = Base::METHOD_TYPE_SELECT; + break; case Query::TYPE_LIMIT: $methodType = Base::METHOD_TYPE_LIMIT; break; diff --git a/src/Appwrite/Utopia/Database/Validator/Queries/Base.php b/src/Appwrite/Utopia/Database/Validator/Queries/Base.php index 89c82c8e82..9d7b2d49d6 100644 --- a/src/Appwrite/Utopia/Database/Validator/Queries/Base.php +++ b/src/Appwrite/Utopia/Database/Validator/Queries/Base.php @@ -8,6 +8,7 @@ use Appwrite\Utopia\Database\Validator\Query\Offset; use Appwrite\Utopia\Database\Validator\Query\Cursor; use Appwrite\Utopia\Database\Validator\Query\Filter; use Appwrite\Utopia\Database\Validator\Query\Order; +use Appwrite\Utopia\Database\Validator\Query\Select; use Utopia\Config\Config; use Utopia\Database\Database; use Utopia\Database\Document; @@ -60,6 +61,7 @@ class Base extends Queries ]); $validators = [ + new Select(), new Limit(), new Offset(), new Cursor(), diff --git a/src/Appwrite/Utopia/Database/Validator/Queries/Documents.php b/src/Appwrite/Utopia/Database/Validator/Queries/Documents.php index 27a09ea99b..cf07f0c37b 100644 --- a/src/Appwrite/Utopia/Database/Validator/Queries/Documents.php +++ b/src/Appwrite/Utopia/Database/Validator/Queries/Documents.php @@ -8,6 +8,7 @@ use Appwrite\Utopia\Database\Validator\Query\Filter; use Appwrite\Utopia\Database\Validator\Query\Limit; use Appwrite\Utopia\Database\Validator\Query\Offset; use Appwrite\Utopia\Database\Validator\Query\Order; +use Appwrite\Utopia\Database\Validator\Query\Select; use Utopia\Database\Database; use Utopia\Database\Document; @@ -38,6 +39,7 @@ class Documents extends Queries ]); $validators = [ + new Select(), new Limit(), new Offset(), new Cursor(), diff --git a/src/Appwrite/Utopia/Database/Validator/Query/Base.php b/src/Appwrite/Utopia/Database/Validator/Query/Base.php index 71a1497d29..d6f6df33f3 100644 --- a/src/Appwrite/Utopia/Database/Validator/Query/Base.php +++ b/src/Appwrite/Utopia/Database/Validator/Query/Base.php @@ -12,6 +12,7 @@ abstract class Base extends Validator public const METHOD_TYPE_CURSOR = 'cursor'; public const METHOD_TYPE_ORDER = 'order'; public const METHOD_TYPE_FILTER = 'filter'; + public const METHOD_TYPE_SELECT = 'select'; /** * @var string diff --git a/src/Appwrite/Utopia/Database/Validator/Query/Select.php b/src/Appwrite/Utopia/Database/Validator/Query/Select.php new file mode 100644 index 0000000000..55e625e07f --- /dev/null +++ b/src/Appwrite/Utopia/Database/Validator/Query/Select.php @@ -0,0 +1,56 @@ +schema[$attribute->getAttribute('key')] = $attribute->getArrayCopy(); + } + } + + /** + * Is valid. + * + * Returns true if method is TYPE_SELECT selections are valid + * + * Otherwise, returns false + * + * @param $query + * @return bool + */ + public function isValid($query): bool + { + /* @var $query Query */ + + if ($query->getMethod() === Query::TYPE_SELECT) { + foreach ($query->getValues() as $attr) { + var_dump($attr); + // todo: Do some validations + return true; + } + } + + return false; + } + + public function getMethodType(): string + { + return self::METHOD_TYPE_SELECT; + } +} diff --git a/tests/e2e/Services/Databases/DatabasesBase.php b/tests/e2e/Services/Databases/DatabasesBase.php index 68437b92fd..e2cb18ea13 100644 --- a/tests/e2e/Services/Databases/DatabasesBase.php +++ b/tests/e2e/Services/Databases/DatabasesBase.php @@ -1381,6 +1381,37 @@ trait DatabasesBase } } + /** + * @depends testListDocuments + */ + public function testGetDocumentWithQueries(array $data): void + { + $databaseId = $data['databaseId']; + foreach ($data['documents'] as $document) { + $response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $document['$collectionId'] . '/documents/' . $document['$id'], array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'queries' => ['select("title","releaseYear")'], + ]); + + var_dump($response); + //Query::select(['string', 'integer']), + die; + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals($response['body']['$id'], $document['$id']); + $this->assertEquals($document['$collectionId'], $response['body']['$collectionId']); + $this->assertArrayNotHasKey('$collection', $response['body']); + $this->assertEquals($document['$databaseId'], $response['body']['$databaseId']); + $this->assertEquals($response['body']['title'], $document['title']); + $this->assertEquals($response['body']['releaseYear'], $document['releaseYear']); + $this->assertEquals($response['body']['$permissions'], $document['$permissions']); + $this->assertEquals($response['body']['birthDay'], $document['birthDay']); + $this->assertFalse(array_key_exists('$internalId', $response['body'])); + } + } + /** * @depends testCreateDocument */ diff --git a/tests/unit/Utopia/Database/Validator/Query/SelectTest.php b/tests/unit/Utopia/Database/Validator/Query/SelectTest.php new file mode 100644 index 0000000000..c677141b99 --- /dev/null +++ b/tests/unit/Utopia/Database/Validator/Query/SelectTest.php @@ -0,0 +1,34 @@ +validator = new Select(); + } + + public function tearDown(): void + { + } + + public function testValue(): void + { + // Test for Success + $this->assertEquals($this->validator->isValid(Query::select(['*', 'attr1', 'attr2', 'collection.id'])), true, $this->validator->getDescription()); + + // Test for Failure + $this->assertEquals($this->validator->isValid(Query::limit(1)), false, $this->validator->getDescription()); + } +}