diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index 1c46c3b2c3..f5bd131ca0 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -3862,18 +3862,17 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/usage') }); App::get('/v1/databases/:databaseId/slow-queries') - ->desc('List Slow Queries Documents') + ->desc('List slow queries') ->groups(['api', 'database']) ->label('docs', false) ->label('scope', 'documents.read') - ->label('usage.metric', 'documents.{scope}.requests.read') ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN]) ->label('sdk.namespace', 'databases') ->label('sdk.method', 'listSlowQueries') ->label('sdk.description', '/docs/references/databases/list-slow-queries.md') ->label('sdk.response.code', Response::STATUS_CODE_OK) ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) - ->label('sdk.response.model', Response::MODEL_DOCUMENT_LIST) + ->label('sdk.response.model', Response::MODEL_SLOW_QUERY_LIST) ->param('databaseId', '', new UID(), 'Database ID.') ->param('queries', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), '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.', true) ->inject('response') @@ -3899,8 +3898,8 @@ App::get('/v1/databases/:databaseId/slow-queries') ]), Response::MODEL_DOCUMENT_LIST); }); -App::get('/v1/databases/:databaseId/slow-queries/:documentId') - ->desc('Get Slow Query Document') +App::get('/v1/databases/:databaseId/slow-queries/:slowQueryId') + ->desc('Get slow query') ->groups(['api', 'database']) ->label('docs', false) ->label('scope', 'documents.read') @@ -3911,22 +3910,23 @@ App::get('/v1/databases/:databaseId/slow-queries/:documentId') ->label('sdk.description', '/docs/references/databases/get-slow-query.md') ->label('sdk.response.code', Response::STATUS_CODE_OK) ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) - ->label('sdk.response.model', Response::MODEL_DOCUMENT) + ->label('sdk.response.model', Response::MODEL_SLOW_QUERY) ->param('databaseId', '', new UID(), 'Database ID.') - ->param('documentId', '', new UID(), 'Document ID.') + ->param('slowQueryId', '', new UID(), 'Document ID.') ->inject('response') ->inject('dbForProject') - ->action(function (string $databaseId, string $documentId, Response $response, Database $dbForProject) { - $document = $dbForProject->getDocument('slowQueries', $documentId); + ->action(function (string $databaseId, string $slowQueryId, Response $response, Database $dbForProject) { + $document = $dbForProject->getDocument('slowQueries', $slowQueryId); + if ($document->isEmpty() || $document->getAttribute('databaseId') !== $databaseId) { throw new Exception(Exception::DOCUMENT_NOT_FOUND); } - $response->dynamic($document, Response::MODEL_DOCUMENT); + $response->dynamic($document, Response::MODEL_SLOW_QUERY); }); -App::delete('/v1/databases/:databaseId/slow-queries/:documentId') - ->desc('Delete Slow query Document') +App::delete('/v1/databases/:databaseId/slow-queries/:slowQueryId') + ->desc('Delete slow query') ->desc('List Documents') ->groups(['api', 'database']) ->label('docs', false) @@ -3939,15 +3939,15 @@ App::delete('/v1/databases/:databaseId/slow-queries/:documentId') ->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT) ->label('sdk.response.model', Response::MODEL_NONE) ->param('databaseId', '', new UID(), 'Database ID.') - ->param('documentId', '', new UID(), 'Document ID.') + ->param('slowQueryId', '', new UID(), 'Document ID.') ->inject('response') ->inject('dbForProject') - ->action(function (string $databaseId, string $documentId, Response $response, Database $dbForProject) { - $document = $dbForProject->getDocument('slowQueries', $documentId); + ->action(function (string $databaseId, string $slowQueryId, Response $response, Database $dbForProject) { + $document = $dbForProject->getDocument('slowQueries', $slowQueryId); if ($document->isEmpty() || $document->getAttribute('databaseId') !== $databaseId) { throw new Exception(Exception::DOCUMENT_NOT_FOUND); } - $dbForProject->deleteDocument('slowQueries', $documentId); + $dbForProject->deleteDocument('slowQueries', $slowQueryId); $response->noContent(); }); diff --git a/src/Appwrite/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index 63e9170008..566b5718eb 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -2,8 +2,8 @@ namespace Appwrite\Utopia; +use Appwrite\Utopia\Response\Model\SlowQuery; use Exception; -use Swoole\Http\Request as SwooleRequest; use Utopia\Swoole\Response as SwooleResponse; use Swoole\Http\Response as SwooleHTTPResponse; use Utopia\Database\Document; @@ -58,11 +58,9 @@ use Appwrite\Utopia\Response\Model\Locale; use Appwrite\Utopia\Response\Model\Log; use Appwrite\Utopia\Response\Model\Membership; use Appwrite\Utopia\Response\Model\Metric; -use Appwrite\Utopia\Response\Model\Permissions; use Appwrite\Utopia\Response\Model\Phone; use Appwrite\Utopia\Response\Model\Platform; use Appwrite\Utopia\Response\Model\Project; -use Appwrite\Utopia\Response\Model\Rule; use Appwrite\Utopia\Response\Model\Deployment; use Appwrite\Utopia\Response\Model\TemplateEmail; use Appwrite\Utopia\Response\Model\Token; @@ -125,6 +123,10 @@ class Response extends SwooleResponse public const MODEL_DOCUMENT = 'document'; public const MODEL_DOCUMENT_LIST = 'documentList'; + public const MODEL_SLOW_QUERY = 'slowQuery'; + + public const MODEL_SLOW_QUERY_LIST = 'slowQueryList'; + // Database Attributes public const MODEL_ATTRIBUTE = 'attribute'; public const MODEL_ATTRIBUTE_LIST = 'attributeList'; @@ -290,6 +292,7 @@ class Response extends SwooleResponse ->setModel(new BaseList('Variables List', self::MODEL_VARIABLE_LIST, 'variables', self::MODEL_VARIABLE)) ->setModel(new BaseList('Status List', self::MODEL_HEALTH_STATUS_LIST, 'statuses', self::MODEL_HEALTH_STATUS)) ->setModel(new BaseList('Locale codes list', self::MODEL_LOCALE_CODE_LIST, 'localeCodes', self::MODEL_LOCALE_CODE)) + ->setModel(new BaseList('Slow Query List', self::MODEL_SLOW_QUERY_LIST, 'slowQueries', self::MODEL_SLOW_QUERY)) // Entities ->setModel(new Database()) ->setModel(new Collection()) @@ -362,6 +365,7 @@ class Response extends SwooleResponse ->setModel(new TemplateSMS()) ->setModel(new TemplateEmail()) ->setModel(new ConsoleVariables()) + ->setMode(new SlowQuery()) // Verification // Recovery // Tests (keep last) diff --git a/src/Appwrite/Utopia/Response/Model/SlowQuery.php b/src/Appwrite/Utopia/Response/Model/SlowQuery.php new file mode 100644 index 0000000000..6cfbfe45de --- /dev/null +++ b/src/Appwrite/Utopia/Response/Model/SlowQuery.php @@ -0,0 +1,75 @@ +addRule('$id', [ + 'type' => self::TYPE_STRING, + 'description' => 'Slow Query ID.', + 'default' => '', + 'example' => '5e5ea5c16897e', + ]) + ->addRule('$createdAt', [ + 'type' => self::TYPE_DATETIME, + 'description' => 'Slow query creation date in ISO 8601 format.', + 'default' => '', + 'example' => self::TYPE_DATETIME_EXAMPLE, + ]) + ->addRule('$updatedAt', [ + 'type' => self::TYPE_DATETIME, + 'description' => 'Slow query update date in ISO 8601 format.', + 'default' => '', + 'example' => self::TYPE_DATETIME_EXAMPLE, + ]) + ->addRule('blocked', [ + 'type' => self::TYPE_BOOLEAN, + 'description' => 'Is this slow query blocked from execution?', + 'default' => false, + 'example' => true, + ]) + ->addRule('count', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'The number of times this slow query has executed.', + 'default' => 0, + 'example' => 5, + ]) + ->addRule('queries', [ + 'type' => self::TYPE_STRING, + 'description' => 'The slow query itself.', + 'default' => '', + 'example' => '["limit(10000)"]', + ]) + ->addRule('path', [ + 'type' => self::TYPE_STRING, + 'description' => 'The path of the endpoint that executed this slow query.', + 'default' => '', + 'example' => '/v1/databases/123/collections', + ]); + } + + /** + * Get Name + * + * @return string + */ + public function getName(): string + { + return 'Session'; + } + + /** + * Get Type + * + * @return string + */ + public function getType(): string + { + return Response::MODEL_SESSION; + } +}