From dca0b211f636d73cfc355eeae785e5239ddf92fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Fri, 26 Aug 2022 13:38:39 +0000 Subject: [PATCH] Implement queries into list variables --- app/config/collections.php | 20 ++++++++- app/controllers/api/functions.php | 43 ++++++++++++++++--- composer.lock | 8 ++-- .../Database/Validator/Queries/Variables.php | 21 +++++++++ .../Functions/FunctionsConsoleClientTest.php | 43 +++++++++++++++++++ 5 files changed, 123 insertions(+), 12 deletions(-) create mode 100644 src/Appwrite/Utopia/Database/Validator/Queries/Variables.php diff --git a/app/config/collections.php b/app/config/collections.php index 98122df101..021c4ff4c6 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -3430,7 +3430,18 @@ $collections = [ 'default' => null, 'array' => false, 'filters' => [ 'encrypt' ] - ] + ], + [ + '$id' => ID::custom('search'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], ], 'indexes' => [ [ @@ -3454,6 +3465,13 @@ $collections = [ 'lengths' => [Database::LENGTH_KEY], 'orders' => [Database::ORDER_ASC], ], + [ + '$id' => ID::custom('_fulltext_search'), + 'type' => Database::INDEX_FULLTEXT, + 'attributes' => ['search'], + 'lengths' => [], + 'orders' => [], + ], ], ], ]; diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index 2ef3bf8a1a..4db73b9acf 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -25,6 +25,7 @@ use Appwrite\Task\Validator\Cron; use Appwrite\Utopia\Database\Validator\Queries\Deployments; use Appwrite\Utopia\Database\Validator\Queries\Executions; use Appwrite\Utopia\Database\Validator\Queries\Functions; +use Appwrite\Utopia\Database\Validator\Queries\Variables; use Utopia\App; use Utopia\Database\Database; use Utopia\Database\Document; @@ -1321,8 +1322,10 @@ App::post('/v1/functions/:functionId/variables') throw new Exception(Exception::FUNCTION_NOT_FOUND, 'Function not found'); } + $variableId = ID::unique(); + $variable = new Document([ - '$id' => ID::unique(), + '$id' => $variableId, '$permissions' => [ Permission::read(Role::any()), Permission::update(Role::any()), @@ -1331,7 +1334,8 @@ App::post('/v1/functions/:functionId/variables') 'functionInternalId' => $function->getInternalId(), 'functionId' => $function->getId(), 'key' => $key, - 'value' => $value + 'value' => $value, + 'search' => implode(' ', [$variableId, $function->getId(), $key]), ]); try { @@ -1358,21 +1362,45 @@ App::get('/v1/functions/:functionId/variables') ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) ->label('sdk.response.model', Response::MODEL_VARIABLE_LIST) ->param('functionId', null, new UID(), 'Function unique ID.', false) - // TODO: Pagination + ->param('queries', [], new Variables(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/databases#querying-documents). 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(', ', Variables::ALLOWED_ATTRIBUTES), true) + ->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true) ->inject('response') ->inject('dbForProject') - ->action(function (string $functionId, Response $response, Database $dbForProject) { + ->action(function (string $functionId, array $queries, string $search, Response $response, Database $dbForProject) { $function = $dbForProject->getDocument('functions', $functionId); if ($function->isEmpty()) { throw new Exception(Exception::FUNCTION_NOT_FOUND, 'Function not found'); } - $variables = $function['vars']; + $queries = Query::parseQueries($queries); + + if (!empty($search)) { + $queries[] = Query::search('search', $search); + } + + // Set default limit + $queries[] = Query::limit(25); + + // Get cursor document if there was a cursor query + $cursor = Query::getByType($queries, Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE)[0] ?? null; + if ($cursor !== null) { + /** @var Query $cursor */ + $variableId = $cursor->getValue(); + $cursorDocument = $dbForProject->getDocument('variables', $variableId); + + if ($cursorDocument->isEmpty()) { + throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Variable '{$variableId}' for the 'cursor' value not found."); + } + + $cursor->setValue($cursorDocument); + } + + $filterQueries = Query::groupByType($queries)['filters']; $response->dynamic(new Document([ - 'variables' => $variables, - 'total' => count($variables), + 'variables' => $dbForProject->find('variables', $queries), + 'total' => $dbForProject->count('variables', $filterQueries, APP_LIMIT_COUNT), ]), Response::MODEL_VARIABLE_LIST); }); @@ -1450,6 +1478,7 @@ App::put('/v1/functions/:functionId/variables/:variableId') $variable ->setAttribute('key', $key ?? $variable->getAttribute('key')) ->setAttribute('value', $value ?? $variable->getAttribute('value')) + ->setAttribute('search', implode(' ', [$variableId, $function->getId(), $key])) ; try { diff --git a/composer.lock b/composer.lock index 39ac8e206c..149ed168ed 100644 --- a/composer.lock +++ b/composer.lock @@ -2056,12 +2056,12 @@ "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "336df0d08d8bd875acd6b2b87d7b24133aa016f5" + "reference": "a3b291456b0d73ea6b0de1a1bb8fc6713472575e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/336df0d08d8bd875acd6b2b87d7b24133aa016f5", - "reference": "336df0d08d8bd875acd6b2b87d7b24133aa016f5", + "url": "https://api.github.com/repos/utopia-php/database/zipball/a3b291456b0d73ea6b0de1a1bb8fc6713472575e", + "reference": "a3b291456b0d73ea6b0de1a1bb8fc6713472575e", "shasum": "" }, "require": { @@ -2112,7 +2112,7 @@ "issues": "https://github.com/utopia-php/database/issues", "source": "https://github.com/utopia-php/database/tree/refactor-permissions" }, - "time": "2022-08-25T08:19:47+00:00" + "time": "2022-08-26T09:03:29+00:00" }, { "name": "utopia-php/domains", diff --git a/src/Appwrite/Utopia/Database/Validator/Queries/Variables.php b/src/Appwrite/Utopia/Database/Validator/Queries/Variables.php new file mode 100644 index 0000000000..eff7007c58 --- /dev/null +++ b/src/Appwrite/Utopia/Database/Validator/Queries/Variables.php @@ -0,0 +1,21 @@ +assertEquals("APP_TEST", $response['body']['variables'][0]['key']); $this->assertEquals("TESTINGVALUE", $response['body']['variables'][0]['value']); + $variableId = $response['body']['variables'][0]['$id']; + + $response = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/variables', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'queries' => [ 'limit(0)' ] + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertCount(0, $response['body']['variables']); + + $response = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/variables', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'queries' => [ 'offset(1)' ] + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertCount(0, $response['body']['variables']); + + $response = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/variables', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'queries' => [ 'equal("key", "APP_TEST")' ] + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertCount(1, $response['body']['variables']); + + $response = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/variables', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'search' => $variableId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertCount(1, $response['body']['variables']); + return $data; }