Merge pull request #10668 from appwrite/feat-disable-count

Feat disable count
This commit is contained in:
Jake Barnby 2025-10-29 23:47:33 +13:00 committed by GitHub
commit 7b55a9810f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
39 changed files with 399 additions and 111 deletions

View file

@ -2814,12 +2814,13 @@ App::get('/v1/account/logs')
contentType: ContentType::JSON,
))
->param('queries', [], new Queries([new Limit(), new Offset()]), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('user')
->inject('locale')
->inject('geodb')
->inject('dbForProject')
->action(function (array $queries, Response $response, Document $user, Locale $locale, Reader $geodb, Database $dbForProject) {
->action(function (array $queries, bool $includeTotal, Response $response, Document $user, Locale $locale, Reader $geodb, Database $dbForProject) {
try {
$queries = Query::parseQueries($queries);
@ -2864,7 +2865,7 @@ App::get('/v1/account/logs')
}
$response->dynamic(new Document([
'total' => $audit->countLogsByUser($user->getSequence(), $queries),
'total' => $includeTotal ? $audit->countLogsByUser($user->getSequence(), $queries) : 0,
'logs' => $output,
]), Response::MODEL_LOG_LIST);
});
@ -5211,10 +5212,11 @@ App::get('/v1/account/identities')
contentType: ContentType::JSON
))
->param('queries', [], new Identities(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Identities::ALLOWED_ATTRIBUTES), true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('user')
->inject('dbForProject')
->action(function (array $queries, Response $response, Document $user, Database $dbForProject) {
->action(function (array $queries, bool $includeTotal, Response $response, Document $user, Database $dbForProject) {
try {
$queries = Query::parseQueries($queries);
@ -5255,7 +5257,7 @@ App::get('/v1/account/identities')
} catch (OrderException $e) {
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
}
$total = $dbForProject->count('identities', $filterQueries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForProject->count('identities', $filterQueries, APP_LIMIT_COUNT) : 0;
$response->dynamic(new Document([
'identities' => $results,

View file

@ -1067,9 +1067,10 @@ App::get('/v1/messaging/providers')
))
->param('queries', [], new Providers(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Providers::ALLOWED_ATTRIBUTES), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('dbForProject')
->inject('response')
->action(function (array $queries, string $search, Database $dbForProject, Response $response) {
->action(function (array $queries, string $search, bool $includeTotal, Database $dbForProject, Response $response) {
try {
$queries = Query::parseQueries($queries);
} catch (QueryException $e) {
@ -1105,7 +1106,7 @@ App::get('/v1/messaging/providers')
}
try {
$providers = $dbForProject->find('providers', $queries);
$total = $dbForProject->count('providers', $queries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForProject->count('providers', $queries, APP_LIMIT_COUNT) : 0;
} catch (OrderException $e) {
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
}
@ -1135,11 +1136,12 @@ App::get('/v1/messaging/providers/:providerId/logs')
))
->param('providerId', '', new UID(), 'Provider ID.')
->param('queries', [], new Queries([new Limit(), new Offset()]), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->inject('locale')
->inject('geodb')
->action(function (string $providerId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) {
->action(function (string $providerId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) {
$provider = $dbForProject->getDocument('providers', $providerId);
if ($provider->isEmpty()) {
@ -1207,7 +1209,7 @@ App::get('/v1/messaging/providers/:providerId/logs')
}
$response->dynamic(new Document([
'total' => $audit->countLogsByResource($resource, $queries),
'total' => $includeTotal ? $audit->countLogsByResource($resource, $queries) : 0,
'logs' => $output,
]), Response::MODEL_LOG_LIST);
});
@ -2472,9 +2474,10 @@ App::get('/v1/messaging/topics')
))
->param('queries', [], new Topics(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Topics::ALLOWED_ATTRIBUTES), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('dbForProject')
->inject('response')
->action(function (array $queries, string $search, Database $dbForProject, Response $response) {
->action(function (array $queries, string $search, bool $includeTotal, Database $dbForProject, Response $response) {
try {
$queries = Query::parseQueries($queries);
} catch (QueryException $e) {
@ -2510,7 +2513,7 @@ App::get('/v1/messaging/topics')
}
try {
$topics = $dbForProject->find('topics', $queries);
$total = $dbForProject->count('topics', $queries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForProject->count('topics', $queries, APP_LIMIT_COUNT) : 0;
} catch (OrderException $e) {
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
}
@ -2540,11 +2543,12 @@ App::get('/v1/messaging/topics/:topicId/logs')
))
->param('topicId', '', new UID(), 'Topic ID.')
->param('queries', [], new Queries([new Limit(), new Offset()]), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->inject('locale')
->inject('geodb')
->action(function (string $topicId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) {
->action(function (string $topicId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) {
$topic = $dbForProject->getDocument('topics', $topicId);
if ($topic->isEmpty()) {
@ -2613,7 +2617,7 @@ App::get('/v1/messaging/topics/:topicId/logs')
}
$response->dynamic(new Document([
'total' => $audit->countLogsByResource($resource, $queries),
'total' => $includeTotal ? $audit->countLogsByResource($resource, $queries) : 0,
'logs' => $output,
]), Response::MODEL_LOG_LIST);
});
@ -2873,9 +2877,10 @@ App::get('/v1/messaging/topics/:topicId/subscribers')
->param('topicId', '', new UID(), 'Topic ID. The topic ID subscribed to.')
->param('queries', [], new Subscribers(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Providers::ALLOWED_ATTRIBUTES), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('dbForProject')
->inject('response')
->action(function (string $topicId, array $queries, string $search, Database $dbForProject, Response $response) {
->action(function (string $topicId, array $queries, string $search, bool $includeTotal, Database $dbForProject, Response $response) {
try {
$queries = Query::parseQueries($queries);
} catch (QueryException $e) {
@ -2937,7 +2942,7 @@ App::get('/v1/messaging/topics/:topicId/subscribers')
$response
->dynamic(new Document([
'subscribers' => $subscribers,
'total' => $dbForProject->count('subscribers', $queries, APP_LIMIT_COUNT),
'total' => $includeTotal ? $dbForProject->count('subscribers', $queries, APP_LIMIT_COUNT) : 0,
]), Response::MODEL_SUBSCRIBER_LIST);
});
@ -2961,11 +2966,12 @@ App::get('/v1/messaging/subscribers/:subscriberId/logs')
))
->param('subscriberId', '', new UID(), 'Subscriber ID.')
->param('queries', [], new Queries([new Limit(), new Offset()]), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->inject('locale')
->inject('geodb')
->action(function (string $subscriberId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) {
->action(function (string $subscriberId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) {
$subscriber = $dbForProject->getDocument('subscribers', $subscriberId);
if ($subscriber->isEmpty()) {
@ -3034,7 +3040,7 @@ App::get('/v1/messaging/subscribers/:subscriberId/logs')
}
$response->dynamic(new Document([
'total' => $audit->countLogsByResource($resource, $queries),
'total' => $includeTotal ? $audit->countLogsByResource($resource, $queries) : 0,
'logs' => $output,
]), Response::MODEL_LOG_LIST);
});
@ -3691,9 +3697,10 @@ App::get('/v1/messaging/messages')
))
->param('queries', [], new Messages(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Messages::ALLOWED_ATTRIBUTES), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('dbForProject')
->inject('response')
->action(function (array $queries, string $search, Database $dbForProject, Response $response) {
->action(function (array $queries, string $search, bool $includeTotal, Database $dbForProject, Response $response) {
try {
$queries = Query::parseQueries($queries);
} catch (QueryException $e) {
@ -3729,7 +3736,7 @@ App::get('/v1/messaging/messages')
}
try {
$messages = $dbForProject->find('messages', $queries);
$total = $dbForProject->count('messages', $queries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForProject->count('messages', $queries, APP_LIMIT_COUNT) : 0;
} catch (OrderException $e) {
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
}
@ -3759,11 +3766,12 @@ App::get('/v1/messaging/messages/:messageId/logs')
))
->param('messageId', '', new UID(), 'Message ID.')
->param('queries', [], new Queries([new Limit(), new Offset()]), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->inject('locale')
->inject('geodb')
->action(function (string $messageId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) {
->action(function (string $messageId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) {
$message = $dbForProject->getDocument('messages', $messageId);
if ($message->isEmpty()) {
@ -3832,7 +3840,7 @@ App::get('/v1/messaging/messages/:messageId/logs')
}
$response->dynamic(new Document([
'total' => $audit->countLogsByResource($resource, $queries),
'total' => $includeTotal ? $audit->countLogsByResource($resource, $queries) : 0,
'logs' => $output,
]), Response::MODEL_LOG_LIST);
});
@ -3857,9 +3865,10 @@ App::get('/v1/messaging/messages/:messageId/targets')
))
->param('messageId', '', new UID(), 'Message ID.')
->param('queries', [], new Targets(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Targets::ALLOWED_ATTRIBUTES), true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->action(function (string $messageId, array $queries, Response $response, Database $dbForProject) {
->action(function (string $messageId, array $queries, bool $includeTotal, Response $response, Database $dbForProject) {
$message = $dbForProject->getDocument('messages', $messageId);
if ($message->isEmpty()) {
@ -3909,7 +3918,7 @@ App::get('/v1/messaging/messages/:messageId/targets')
}
try {
$targets = $dbForProject->find('targets', $queries);
$total = $dbForProject->count('targets', $queries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForProject->count('targets', $queries, APP_LIMIT_COUNT) : 0;
} catch (OrderException $e) {
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
}

View file

@ -597,9 +597,10 @@ App::get('/v1/migrations')
))
->param('queries', [], new Migrations(), '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(', ', Migrations::ALLOWED_ATTRIBUTES), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->action(function (array $queries, string $search, Response $response, Database $dbForProject) {
->action(function (array $queries, string $search, bool $includeTotal, Response $response, Database $dbForProject) {
try {
$queries = Query::parseQueries($queries);
} catch (QueryException $e) {
@ -638,7 +639,7 @@ App::get('/v1/migrations')
$filterQueries = Query::groupByType($queries)['filters'];
try {
$migrations = $dbForProject->find('migrations', $queries);
$total = $dbForProject->count('migrations', $filterQueries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForProject->count('migrations', $filterQueries, APP_LIMIT_COUNT) : 0;
} catch (OrderException $e) {
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
}

View file

@ -1234,9 +1234,10 @@ App::get('/v1/projects/:projectId/webhooks')
]
))
->param('projectId', '', new UID(), 'Project unique ID.')
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForPlatform')
->action(function (string $projectId, Response $response, Database $dbForPlatform) {
->action(function (string $projectId, bool $includeTotal, Response $response, Database $dbForPlatform) {
$project = $dbForPlatform->getDocument('projects', $projectId);
@ -1251,7 +1252,7 @@ App::get('/v1/projects/:projectId/webhooks')
$response->dynamic(new Document([
'webhooks' => $webhooks,
'total' => count($webhooks),
'total' => $includeTotal ? count($webhooks) : 0,
]), Response::MODEL_WEBHOOK_LIST);
});
@ -1531,9 +1532,10 @@ App::get('/v1/projects/:projectId/keys')
]
))
->param('projectId', '', new UID(), 'Project unique ID.')
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForPlatform')
->action(function (string $projectId, Response $response, Database $dbForPlatform) {
->action(function (string $projectId, bool $includeTotal, Response $response, Database $dbForPlatform) {
$project = $dbForPlatform->getDocument('projects', $projectId);
@ -1548,7 +1550,7 @@ App::get('/v1/projects/:projectId/keys')
$response->dynamic(new Document([
'keys' => $keys,
'total' => count($keys),
'total' => $includeTotal ? count($keys) : 0,
]), Response::MODEL_KEY_LIST);
});
@ -1834,9 +1836,10 @@ App::get('/v1/projects/:projectId/platforms')
]
))
->param('projectId', '', new UID(), 'Project unique ID.')
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForPlatform')
->action(function (string $projectId, Response $response, Database $dbForPlatform) {
->action(function (string $projectId, bool $includeTotal, Response $response, Database $dbForPlatform) {
$project = $dbForPlatform->getDocument('projects', $projectId);
@ -1851,7 +1854,7 @@ App::get('/v1/projects/:projectId/platforms')
$response->dynamic(new Document([
'platforms' => $platforms,
'total' => count($platforms),
'total' => $includeTotal ? count($platforms) : 0,
]), Response::MODEL_PLATFORM_LIST);
});

View file

@ -180,9 +180,10 @@ App::get('/v1/storage/buckets')
))
->param('queries', [], new Buckets(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Buckets::ALLOWED_ATTRIBUTES), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->action(function (array $queries, string $search, Response $response, Database $dbForProject) {
->action(function (array $queries, string $search, bool $includeTotal, Response $response, Database $dbForProject) {
try {
$queries = Query::parseQueries($queries);
@ -222,7 +223,7 @@ App::get('/v1/storage/buckets')
$filterQueries = Query::groupByType($queries)['filters'];
try {
$buckets = $dbForProject->find('buckets', $queries);
$total = $dbForProject->count('buckets', $filterQueries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForProject->count('buckets', $filterQueries, APP_LIMIT_COUNT) : 0;
} catch (OrderException $e) {
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
} catch (QueryException $e) {
@ -785,10 +786,11 @@ App::get('/v1/storage/buckets/:bucketId/files')
->param('bucketId', '', new UID(), 'Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket).')
->param('queries', [], new Files(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Files::ALLOWED_ATTRIBUTES), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->inject('mode')
->action(function (string $bucketId, array $queries, string $search, Response $response, Database $dbForProject, string $mode) {
->action(function (string $bucketId, array $queries, string $search, bool $includeTotal, Response $response, Database $dbForProject, string $mode) {
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
@ -846,10 +848,10 @@ App::get('/v1/storage/buckets/:bucketId/files')
try {
if ($fileSecurity && !$valid) {
$files = $dbForProject->find('bucket_' . $bucket->getSequence(), $queries);
$total = $dbForProject->count('bucket_' . $bucket->getSequence(), $filterQueries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForProject->count('bucket_' . $bucket->getSequence(), $filterQueries, APP_LIMIT_COUNT) : 0;
} else {
$files = Authorization::skip(fn () => $dbForProject->find('bucket_' . $bucket->getSequence(), $queries));
$total = Authorization::skip(fn () => $dbForProject->count('bucket_' . $bucket->getSequence(), $filterQueries, APP_LIMIT_COUNT));
$total = $includeTotal ? Authorization::skip(fn () => $dbForProject->count('bucket_' . $bucket->getSequence(), $filterQueries, APP_LIMIT_COUNT)) : 0;
}
} catch (NotFoundException) {
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);

View file

@ -52,6 +52,7 @@ use Utopia\Locale\Locale;
use Utopia\System\System;
use Utopia\Validator\ArrayList;
use Utopia\Validator\Assoc;
use Utopia\Validator\Boolean;
use Utopia\Validator\Text;
use Utopia\Validator\URL;
use Utopia\Validator\WhiteList;
@ -169,9 +170,10 @@ App::get('/v1/teams')
))
->param('queries', [], new Teams(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Teams::ALLOWED_ATTRIBUTES), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->action(function (array $queries, string $search, Response $response, Database $dbForProject) {
->action(function (array $queries, string $search, bool $includeTotal, Response $response, Database $dbForProject) {
try {
$queries = Query::parseQueries($queries);
@ -211,7 +213,7 @@ App::get('/v1/teams')
$filterQueries = Query::groupByType($queries)['filters'];
try {
$results = $dbForProject->find('teams', $queries);
$total = $dbForProject->count('teams', $filterQueries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForProject->count('teams', $filterQueries, APP_LIMIT_COUNT) : 0;
} catch (OrderException $e) {
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
}
@ -838,10 +840,11 @@ App::get('/v1/teams/:teamId/memberships')
->param('teamId', '', new UID(), 'Team ID.')
->param('queries', [], new Memberships(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Memberships::ALLOWED_ATTRIBUTES), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('project')
->inject('dbForProject')
->action(function (string $teamId, array $queries, string $search, Response $response, Document $project, Database $dbForProject) {
->action(function (string $teamId, array $queries, string $search, bool $includeTotal, Response $response, Document $project, Database $dbForProject) {
$team = $dbForProject->getDocument('teams', $teamId);
if ($team->isEmpty()) {
@ -893,11 +896,11 @@ App::get('/v1/teams/:teamId/memberships')
collection: 'memberships',
queries: $queries,
);
$total = $dbForProject->count(
$total = $includeTotal ? $dbForProject->count(
collection: 'memberships',
queries: $filterQueries,
max: APP_LIMIT_COUNT
);
) : 0;
} catch (OrderException $e) {
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
}
@ -1430,11 +1433,12 @@ App::get('/v1/teams/:teamId/logs')
))
->param('teamId', '', new UID(), 'Team ID.')
->param('queries', [], new Queries([new Limit(), new Offset()]), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->inject('locale')
->inject('geodb')
->action(function (string $teamId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) {
->action(function (string $teamId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) {
$team = $dbForProject->getDocument('teams', $teamId);
@ -1503,7 +1507,7 @@ App::get('/v1/teams/:teamId/logs')
}
}
$response->dynamic(new Document([
'total' => $audit->countLogsByResource($resource, $queries),
'total' => $includeTotal ? $audit->countLogsByResource($resource, $queries) : 0,
'logs' => $output,
]), Response::MODEL_LOG_LIST);
});

View file

@ -605,9 +605,10 @@ App::get('/v1/users')
))
->param('queries', [], new Users(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Users::ALLOWED_ATTRIBUTES), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->action(function (array $queries, string $search, Response $response, Database $dbForProject) {
->action(function (array $queries, string $search, bool $includeTotal, Response $response, Database $dbForProject) {
try {
$queries = Query::parseQueries($queries);
@ -647,10 +648,10 @@ App::get('/v1/users')
$users = [];
$total = 0;
$dbForProject->skipFilters(function () use ($dbForProject, $queries, &$users, &$total) {
$dbForProject->skipFilters(function () use ($dbForProject, $queries, $includeTotal, &$users, &$total) {
try {
$users = $dbForProject->find('users', $queries);
$total = $dbForProject->count('users', $queries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForProject->count('users', $queries, APP_LIMIT_COUNT) : 0;
} catch (OrderException $e) {
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
} catch (QueryException $e) {
@ -784,10 +785,11 @@ App::get('/v1/users/:userId/sessions')
]
))
->param('userId', '', new UID(), 'User ID.')
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->inject('locale')
->action(function (string $userId, Response $response, Database $dbForProject, Locale $locale) {
->action(function (string $userId, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale) {
$user = $dbForProject->getDocument('users', $userId);
@ -809,7 +811,7 @@ App::get('/v1/users/:userId/sessions')
$response->dynamic(new Document([
'sessions' => $sessions,
'total' => count($sessions),
'total' => $includeTotal ? count($sessions) : 0,
]), Response::MODEL_SESSION_LIST);
});
@ -833,9 +835,10 @@ App::get('/v1/users/:userId/memberships')
->param('userId', '', new UID(), 'User ID.')
->param('queries', [], new Memberships(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Memberships::ALLOWED_ATTRIBUTES), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->action(function (string $userId, array $queries, string $search, Response $response, Database $dbForProject) {
->action(function (string $userId, array $queries, string $search, bool $includeTotal, Response $response, Database $dbForProject) {
$user = $dbForProject->getDocument('users', $userId);
@ -869,7 +872,7 @@ App::get('/v1/users/:userId/memberships')
$response->dynamic(new Document([
'memberships' => $memberships,
'total' => count($memberships),
'total' => $includeTotal ? count($memberships) : 0,
]), Response::MODEL_MEMBERSHIP_LIST);
});
@ -892,11 +895,12 @@ App::get('/v1/users/:userId/logs')
))
->param('userId', '', new UID(), 'User ID.')
->param('queries', [], new Queries([new Limit(), new Offset()]), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->inject('locale')
->inject('geodb')
->action(function (string $userId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) {
->action(function (string $userId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) {
$user = $dbForProject->getDocument('users', $userId);
@ -965,7 +969,7 @@ App::get('/v1/users/:userId/logs')
}
$response->dynamic(new Document([
'total' => $audit->countLogsByUser($user->getSequence(), $queries),
'total' => $includeTotal ? $audit->countLogsByUser($user->getSequence(), $queries) : 0,
'logs' => $output,
]), Response::MODEL_LOG_LIST);
});
@ -989,9 +993,10 @@ App::get('/v1/users/:userId/targets')
))
->param('userId', '', new UID(), 'User ID.')
->param('queries', [], new Targets(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Targets::ALLOWED_ATTRIBUTES), true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->action(function (string $userId, array $queries, Response $response, Database $dbForProject) {
->action(function (string $userId, array $queries, bool $includeTotal, Response $response, Database $dbForProject) {
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty()) {
@ -1031,7 +1036,7 @@ App::get('/v1/users/:userId/targets')
}
try {
$targets = $dbForProject->find('targets', $queries);
$total = $dbForProject->count('targets', $queries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForProject->count('targets', $queries, APP_LIMIT_COUNT) : 0;
} catch (OrderException $e) {
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
}
@ -1060,9 +1065,10 @@ App::get('/v1/users/identities')
))
->param('queries', [], new Identities(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Identities::ALLOWED_ATTRIBUTES), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->action(function (array $queries, string $search, Response $response, Database $dbForProject) {
->action(function (array $queries, string $search, bool $includeTotal, Response $response, Database $dbForProject) {
try {
$queries = Query::parseQueries($queries);
@ -1099,10 +1105,9 @@ App::get('/v1/users/identities')
$cursor->setValue($cursorDocument);
}
$filterQueries = Query::groupByType($queries)['filters'];
try {
$identities = $dbForProject->find('identities', $queries);
$total = $dbForProject->count('identities', $filterQueries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForProject->count('identities', $queries, APP_LIMIT_COUNT) : 0;
} catch (OrderException $e) {
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
}

View file

@ -1535,11 +1535,12 @@ App::get('/v1/vcs/installations')
))
->param('queries', [], new Installations(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Installations::ALLOWED_ATTRIBUTES), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('project')
->inject('dbForProject')
->inject('dbForPlatform')
->action(function (array $queries, string $search, Response $response, Document $project, Database $dbForProject, Database $dbForPlatform) {
->action(function (array $queries, string $search, bool $includeTotal, Response $response, Document $project, Database $dbForProject, Database $dbForPlatform) {
try {
$queries = Query::parseQueries($queries);
} catch (QueryException $e) {
@ -1580,7 +1581,7 @@ App::get('/v1/vcs/installations')
$filterQueries = Query::groupByType($queries)['filters'];
try {
$results = $dbForPlatform->find('installations', $queries);
$total = $dbForPlatform->count('installations', $filterQueries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForPlatform->count('installations', $filterQueries, APP_LIMIT_COUNT) : 0;
} catch (OrderException $e) {
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
}

52
composer.lock generated
View file

@ -4108,16 +4108,16 @@
},
{
"name": "utopia-php/emails",
"version": "0.6.1",
"version": "0.6.2",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/emails.git",
"reference": "0de8896f369b6aa1f14df338645048f95a8439e3"
"reference": "9c4c40cf7c03c2e9e21364566f9b192d03ea93c9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/emails/zipball/0de8896f369b6aa1f14df338645048f95a8439e3",
"reference": "0de8896f369b6aa1f14df338645048f95a8439e3",
"url": "https://api.github.com/repos/utopia-php/emails/zipball/9c4c40cf7c03c2e9e21364566f9b192d03ea93c9",
"reference": "9c4c40cf7c03c2e9e21364566f9b192d03ea93c9",
"shasum": ""
},
"require": {
@ -4125,7 +4125,7 @@
"utopia-php/cli": "^0.15",
"utopia-php/domains": "^0.9",
"utopia-php/fetch": "^0.4",
"utopia-php/validators": "^0.0.1"
"utopia-php/validators": "^0.0.2"
},
"require-dev": {
"laravel/pint": "1.25.*",
@ -4162,9 +4162,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/emails/issues",
"source": "https://github.com/utopia-php/emails/tree/0.6.1"
"source": "https://github.com/utopia-php/emails/tree/0.6.2"
},
"time": "2025-10-28T07:29:58+00:00"
"time": "2025-10-28T16:08:17+00:00"
},
{
"name": "utopia-php/fetch",
@ -5109,16 +5109,16 @@
},
{
"name": "utopia-php/validators",
"version": "0.0.1",
"version": "0.0.2",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/validators.git",
"reference": "69d1afa5df2f052535764520609e91b491708db2"
"reference": "894210695c5d35fa248fb65f7fe7237b6ff4fb0b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/validators/zipball/69d1afa5df2f052535764520609e91b491708db2",
"reference": "69d1afa5df2f052535764520609e91b491708db2",
"url": "https://api.github.com/repos/utopia-php/validators/zipball/894210695c5d35fa248fb65f7fe7237b6ff4fb0b",
"reference": "894210695c5d35fa248fb65f7fe7237b6ff4fb0b",
"shasum": ""
},
"require": {
@ -5149,9 +5149,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/validators/issues",
"source": "https://github.com/utopia-php/validators/tree/0.0.1"
"source": "https://github.com/utopia-php/validators/tree/0.0.2"
},
"time": "2025-10-20T15:08:50+00:00"
"time": "2025-10-20T21:52:28+00:00"
},
{
"name": "utopia-php/vcs",
@ -7872,16 +7872,16 @@
},
{
"name": "symfony/console",
"version": "v7.3.4",
"version": "v7.3.5",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "2b9c5fafbac0399a20a2e82429e2bd735dcfb7db"
"reference": "cdb80fa5869653c83cfe1a9084a673b6daf57ea7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/2b9c5fafbac0399a20a2e82429e2bd735dcfb7db",
"reference": "2b9c5fafbac0399a20a2e82429e2bd735dcfb7db",
"url": "https://api.github.com/repos/symfony/console/zipball/cdb80fa5869653c83cfe1a9084a673b6daf57ea7",
"reference": "cdb80fa5869653c83cfe1a9084a673b6daf57ea7",
"shasum": ""
},
"require": {
@ -7946,7 +7946,7 @@
"terminal"
],
"support": {
"source": "https://github.com/symfony/console/tree/v7.3.4"
"source": "https://github.com/symfony/console/tree/v7.3.5"
},
"funding": [
{
@ -7966,7 +7966,7 @@
"type": "tidelift"
}
],
"time": "2025-09-22T15:31:00+00:00"
"time": "2025-10-14T15:46:26+00:00"
},
{
"name": "symfony/filesystem",
@ -8040,16 +8040,16 @@
},
{
"name": "symfony/finder",
"version": "v7.3.2",
"version": "v7.3.5",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "2a6614966ba1074fa93dae0bc804227422df4dfe"
"reference": "9f696d2f1e340484b4683f7853b273abff94421f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/2a6614966ba1074fa93dae0bc804227422df4dfe",
"reference": "2a6614966ba1074fa93dae0bc804227422df4dfe",
"url": "https://api.github.com/repos/symfony/finder/zipball/9f696d2f1e340484b4683f7853b273abff94421f",
"reference": "9f696d2f1e340484b4683f7853b273abff94421f",
"shasum": ""
},
"require": {
@ -8084,7 +8084,7 @@
"description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/finder/tree/v7.3.2"
"source": "https://github.com/symfony/finder/tree/v7.3.5"
},
"funding": [
{
@ -8104,7 +8104,7 @@
"type": "tidelift"
}
],
"time": "2025-07-15T13:41:35+00:00"
"time": "2025-10-15T18:45:57+00:00"
},
{
"name": "symfony/options-resolver",
@ -8916,5 +8916,5 @@
"platform-overrides": {
"php": "8.3"
},
"plugin-api-version": "2.6.0"
"plugin-api-version": "2.2.0"
}

View file

@ -18,6 +18,7 @@ use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Query\Cursor;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator\Boolean;
class XList extends Action
{
@ -60,12 +61,13 @@ class XList extends Action
->param('databaseId', '', new UID(), 'Database ID.')
->param('collectionId', '', new UID(), 'Collection ID.')
->param('queries', [], new Attributes(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Attributes::ALLOWED_ATTRIBUTES), true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, array $queries, UtopiaResponse $response, Database $dbForProject): void
public function action(string $databaseId, string $collectionId, array $queries, bool $includeTotal, UtopiaResponse $response, Database $dbForProject): void
{
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
@ -122,7 +124,7 @@ class XList extends Action
try {
$attributes = $dbForProject->find('attributes', $queries);
$total = $dbForProject->count('attributes', $queries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForProject->count('attributes', $queries, APP_LIMIT_COUNT) : 0;
} catch (OrderException $e) {
$documents = $this->isCollectionsAPI() ? 'documents' : 'rows';
$attribute = $this->isCollectionsAPI() ? 'attribute' : 'column';

View file

@ -22,6 +22,7 @@ use Utopia\Database\Validator\Query\Cursor;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator\ArrayList;
use Utopia\Validator\Boolean;
use Utopia\Validator\Text;
class XList extends Action
@ -67,6 +68,7 @@ class XList extends Action
->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('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/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.', true)
->param('transactionId', null, new UID(), 'Transaction ID to read uncommitted changes within the transaction.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->inject('queueForStatsUsage')
@ -74,7 +76,7 @@ class XList extends Action
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, array $queries, ?string $transactionId, UtopiaResponse $response, Database $dbForProject, StatsUsage $queueForStatsUsage, TransactionState $transactionState): void
public function action(string $databaseId, string $collectionId, array $queries, ?string $transactionId, bool $includeTotal, UtopiaResponse $response, Database $dbForProject, StatsUsage $queueForStatsUsage, TransactionState $transactionState): void
{
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
@ -129,16 +131,16 @@ class XList extends Action
// Use transaction-aware document retrieval if transactionId is provided
if ($transactionId !== null) {
$documents = $transactionState->listDocuments($collectionTableId, $transactionId, $queries);
$total = $transactionState->countDocuments($collectionTableId, $transactionId, $queries);
$total = $includeTotal ? $transactionState->countDocuments($collectionTableId, $transactionId, $queries) : 0;
} elseif (! empty($selectQueries)) {
// has selects, allow relationship on documents
$documents = $dbForProject->find($collectionTableId, $queries);
$total = $dbForProject->count($collectionTableId, $queries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForProject->count($collectionTableId, $queries, APP_LIMIT_COUNT) : 0;
} else {
// has no selects, disable relationship loading on documents
/* @type Document[] $documents */
$documents = $dbForProject->skipRelationships(fn () => $dbForProject->find($collectionTableId, $queries));
$total = $dbForProject->count($collectionTableId, $queries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForProject->count($collectionTableId, $queries, APP_LIMIT_COUNT) : 0;
}
} catch (OrderException $e) {
$documents = $this->isCollectionsAPI() ? 'documents' : 'rows';

View file

@ -19,6 +19,7 @@ use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Query\Cursor;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator\Boolean;
class XList extends Action
{
@ -62,12 +63,13 @@ class XList extends Action
->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('queries', [], new Indexes(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Indexes::ALLOWED_ATTRIBUTES), true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, array $queries, UtopiaResponse $response, Database $dbForProject): void
public function action(string $databaseId, string $collectionId, array $queries, bool $includeTotal, UtopiaResponse $response, Database $dbForProject): void
{
/** @var Document $database */
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
@ -125,7 +127,7 @@ class XList extends Action
}
try {
$total = $dbForProject->count('indexes', $queries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForProject->count('indexes', $queries, APP_LIMIT_COUNT) : 0;
$indexes = $dbForProject->find('indexes', $queries);
} catch (OrderException $e) {
$documents = $this->isCollectionsAPI() ? 'documents' : 'rows';

View file

@ -19,6 +19,7 @@ use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Query\Cursor;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator\Boolean;
use Utopia\Validator\Text;
class XList extends Action
@ -63,12 +64,13 @@ class XList extends Action
->param('databaseId', '', new UID(), 'Database ID.')
->param('queries', [], new Collections(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Collections::ALLOWED_ATTRIBUTES), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->callback($this->action(...));
}
public function action(string $databaseId, array $queries, string $search, UtopiaResponse $response, Database $dbForProject): void
public function action(string $databaseId, array $queries, string $search, bool $includeTotal, UtopiaResponse $response, Database $dbForProject): void
{
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
@ -112,7 +114,7 @@ class XList extends Action
try {
$collections = $dbForProject->find('database_' . $database->getSequence(), $queries);
$total = $dbForProject->count('database_' . $database->getSequence(), $queries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForProject->count('database_' . $database->getSequence(), $queries, APP_LIMIT_COUNT) : 0;
} catch (OrderException) {
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL);
} catch (QueryException) {

View file

@ -18,6 +18,7 @@ use Utopia\Database\Query;
use Utopia\Database\Validator\Query\Cursor;
use Utopia\Platform\Action;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator\Boolean;
use Utopia\Validator\Text;
class XList extends Action
@ -58,12 +59,13 @@ class XList extends Action
])
->param('queries', [], new Databases(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Databases::ALLOWED_ATTRIBUTES), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->callback($this->action(...));
}
public function action(array $queries, string $search, UtopiaResponse $response, Database $dbForProject): void
public function action(array $queries, string $search, bool $includeTotal, UtopiaResponse $response, Database $dbForProject): void
{
$queries = Query::parseQueries($queries);
@ -98,7 +100,7 @@ class XList extends Action
try {
$databases = $dbForProject->find('databases', $queries);
$total = $dbForProject->count('databases', $queries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForProject->count('databases', $queries, APP_LIMIT_COUNT) : 0;
} catch (OrderException $e) {
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order column '{$e->getAttribute()}' had a null value. Cursor pagination requires all rows order column values are non-null.");
} catch (QueryException) {

View file

@ -10,6 +10,7 @@ use Appwrite\Utopia\Database\Validator\Queries\Columns;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator\Boolean;
class XList extends AttributesXList
{
@ -48,6 +49,7 @@ class XList extends AttributesXList
->param('databaseId', '', new UID(), 'Database ID.')
->param('tableId', '', new UID(), 'Table ID.')
->param('queries', [], new Columns(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long. You may filter on the following columns: ' . implode(', ', Columns::ALLOWED_COLUMNS), true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->callback($this->action(...));

View file

@ -11,6 +11,7 @@ use Appwrite\Utopia\Database\Validator\Queries\Indexes;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator\Boolean;
class XList extends IndexXList
{
@ -50,6 +51,7 @@ class XList extends IndexXList
->param('databaseId', '', new UID(), 'Database ID.')
->param('tableId', '', new UID(), 'Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable).')
->param('queries', [], new Indexes(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long. You may filter on the following columns: ' . implode(', ', Indexes::ALLOWED_ATTRIBUTES), true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->callback($this->action(...));

View file

@ -11,6 +11,7 @@ use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator\ArrayList;
use Utopia\Validator\Boolean;
use Utopia\Validator\Text;
class XList extends DocumentXList
@ -52,6 +53,7 @@ class XList extends DocumentXList
->param('tableId', '', new UID(), 'Table ID. You can create a new table using the TablesDB service [server integration](https://appwrite.io/docs/products/databases/tables#create-table).')
->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/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.', true)
->param('transactionId', null, new UID(), 'Transaction ID to read uncommitted changes within the transaction.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->inject('queueForStatsUsage')

View file

@ -11,6 +11,7 @@ use Appwrite\Utopia\Database\Validator\Queries\Tables;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator\Boolean;
use Utopia\Validator\Text;
class XList extends CollectionXList
@ -51,6 +52,7 @@ class XList extends CollectionXList
->param('databaseId', '', new UID(), 'Database ID.')
->param('queries', [], new Tables(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long. You may filter on the following columns: ' . implode(', ', Tables::ALLOWED_COLUMNS), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->callback($this->action(...));

View file

@ -10,6 +10,7 @@ use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Database\Validator\Queries\Databases;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator\Boolean;
use Utopia\Validator\Text;
class XList extends DatabaseXList
@ -44,6 +45,7 @@ class XList extends DatabaseXList
))
->param('queries', [], new Databases(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long. You may filter on the following columns: ' . implode(', ', Databases::ALLOWED_ATTRIBUTES), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->callback($this->action(...));

View file

@ -19,6 +19,7 @@ use Utopia\Database\Validator\Query\Cursor;
use Utopia\Database\Validator\UID;
use Utopia\Platform\Action;
use Utopia\Platform\Scope\HTTP;
use Utopia\Validator\Boolean;
use Utopia\Validator\Text;
class XList extends Base
@ -57,6 +58,7 @@ class XList extends Base
->param('functionId', '', new UID(), 'Function ID.')
->param('queries', [], new Deployments(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Deployments::ALLOWED_ATTRIBUTES), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('request')
->inject('response')
->inject('dbForProject')
@ -67,6 +69,7 @@ class XList extends Base
string $functionId,
array $queries,
string $search,
bool $includeTotal,
Request $request,
Response $response,
Database $dbForProject
@ -120,7 +123,7 @@ class XList extends Base
try {
$results = $dbForProject->find('deployments', $queries);
$total = $dbForProject->count('deployments', $filterQueries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForProject->count('deployments', $filterQueries, APP_LIMIT_COUNT) : 0;
} catch (OrderException $e) {
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
}

View file

@ -20,6 +20,7 @@ use Utopia\Database\Validator\Query\Cursor;
use Utopia\Database\Validator\UID;
use Utopia\Platform\Action;
use Utopia\Platform\Scope\HTTP;
use Utopia\Validator\Boolean;
class XList extends Base
{
@ -56,6 +57,7 @@ class XList extends Base
))
->param('functionId', '', new UID(), 'Function ID.')
->param('queries', [], new Executions(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Executions::ALLOWED_ATTRIBUTES), true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->callback($this->action(...));
@ -64,6 +66,7 @@ class XList extends Base
public function action(
string $functionId,
array $queries,
bool $includeTotal,
Response $response,
Database $dbForProject
) {
@ -115,7 +118,7 @@ class XList extends Base
try {
$results = $dbForProject->find('executions', $queries);
$total = $dbForProject->count('executions', $filterQueries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForProject->count('executions', $filterQueries, APP_LIMIT_COUNT) : 0;
} catch (OrderException $e) {
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
}

View file

@ -17,6 +17,7 @@ use Utopia\Database\Query;
use Utopia\Database\Validator\Query\Cursor;
use Utopia\Platform\Action;
use Utopia\Platform\Scope\HTTP;
use Utopia\Validator\Boolean;
use Utopia\Validator\Text;
class XList extends Base
@ -54,6 +55,7 @@ class XList extends Base
))
->param('queries', [], new Functions(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Functions::ALLOWED_ATTRIBUTES), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->callback($this->action(...));
@ -62,6 +64,7 @@ class XList extends Base
public function action(
array $queries,
string $search,
bool $includeTotal,
Response $response,
Database $dbForProject
) {
@ -104,7 +107,7 @@ class XList extends Base
try {
$functions = $dbForProject->find('functions', $queries);
$total = $dbForProject->count('functions', $filterQueries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForProject->count('functions', $filterQueries, APP_LIMIT_COUNT) : 0;
} catch (OrderException $e) {
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
}

View file

@ -12,6 +12,7 @@ use Utopia\Database\Document;
use Utopia\Platform\Action;
use Utopia\Platform\Scope\HTTP;
use Utopia\Validator\ArrayList;
use Utopia\Validator\Boolean;
use Utopia\Validator\Range;
use Utopia\Validator\WhiteList;
@ -52,11 +53,12 @@ class XList extends Base
->param('useCases', [], new ArrayList(new WhiteList(['dev-tools','starter','databases','ai','messaging','utilities']), APP_LIMIT_ARRAY_PARAMS_SIZE), 'List of use cases allowed for filtering function templates. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' use cases are allowed.', true)
->param('limit', 25, new Range(1, 5000), 'Limit the number of templates returned in the response. Default limit is 25, and maximum limit is 5000.', true)
->param('offset', 0, new Range(0, 5000), 'Offset the list of returned templates. Maximum offset is 5000.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->callback($this->action(...));
}
public function action(array $runtimes, array $usecases, int $limit, int $offset, Response $response)
public function action(array $runtimes, array $usecases, int $limit, int $offset, bool $includeTotal, Response $response)
{
$templates = Config::getParam('templates-function', []);
@ -76,7 +78,7 @@ class XList extends Base
return $b['score'] <=> $a['score'];
});
$total = \count($templates);
$total = $includeTotal ? \count($templates) : 0;
$templates = \array_slice($templates, $offset, $limit);
$response->dynamic(new Document([
'templates' => $templates,

View file

@ -18,6 +18,7 @@ use Utopia\Database\Validator\Query\Cursor;
use Utopia\Platform\Action;
use Utopia\Platform\Scope\HTTP;
use Utopia\Validator;
use Utopia\Validator\Boolean;
use Utopia\Validator\Text;
class XList extends Action
@ -59,12 +60,13 @@ class XList extends Action
))
->param('queries', [], $this->getQueriesValidator(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Projects::ALLOWED_ATTRIBUTES), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForPlatform')
->callback($this->action(...));
}
public function action(array $queries, string $search, Response $response, Database $dbForPlatform)
public function action(array $queries, string $search, bool $includeTotal, Response $response, Database $dbForPlatform)
{
try {
$queries = Query::parseQueries($queries);
@ -104,7 +106,7 @@ class XList extends Action
$filterQueries = Query::groupByType($queries)['filters'];
try {
$projects = $dbForPlatform->find('projects', $queries);
$total = $dbForPlatform->count('projects', $filterQueries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForPlatform->count('projects', $filterQueries, APP_LIMIT_COUNT) : 0;
} catch (Order $e) {
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
}

View file

@ -15,6 +15,7 @@ use Utopia\Database\Query;
use Utopia\Database\Validator\Query\Cursor;
use Utopia\Platform\Action;
use Utopia\Platform\Scope\HTTP;
use Utopia\Validator\Boolean;
use Utopia\Validator\Text;
class XList extends Action
@ -51,6 +52,7 @@ class XList extends Action
))
->param('queries', [], new Rules(), '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(', ', Rules::ALLOWED_ATTRIBUTES), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('project')
->inject('dbForPlatform')
@ -60,6 +62,7 @@ class XList extends Action
public function action(
array $queries,
string $search,
bool $includeTotal,
Response $response,
Document $project,
Database $dbForPlatform
@ -112,7 +115,7 @@ class XList extends Action
$response->dynamic(new Document([
'rules' => $rules,
'total' => $dbForPlatform->count('rules', $filterQueries, APP_LIMIT_COUNT),
'total' => $includeTotal ? $dbForPlatform->count('rules', $filterQueries, APP_LIMIT_COUNT) : 0,
]), Response::MODEL_PROXY_RULE_LIST);
}
}

View file

@ -19,6 +19,7 @@ use Utopia\Database\Validator\Query\Cursor;
use Utopia\Database\Validator\UID;
use Utopia\Platform\Action;
use Utopia\Platform\Scope\HTTP;
use Utopia\Validator\Boolean;
use Utopia\Validator\Text;
class XList extends Base
@ -57,6 +58,7 @@ class XList extends Base
->param('siteId', '', new UID(), 'Site ID.')
->param('queries', [], new Deployments(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Deployments::ALLOWED_ATTRIBUTES), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('request')
->inject('response')
->inject('dbForProject')
@ -67,6 +69,7 @@ class XList extends Base
string $siteId,
array $queries,
string $search,
bool $includeTotal,
Request $request,
Response $response,
Database $dbForProject
@ -120,7 +123,7 @@ class XList extends Base
try {
$results = $dbForProject->find('deployments', $queries);
$total = $dbForProject->count('deployments', $filterQueries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForProject->count('deployments', $filterQueries, APP_LIMIT_COUNT) : 0;
} catch (OrderException $e) {
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
}

View file

@ -19,6 +19,7 @@ use Utopia\Database\Validator\Query\Cursor;
use Utopia\Database\Validator\UID;
use Utopia\Platform\Action;
use Utopia\Platform\Scope\HTTP;
use Utopia\Validator\Boolean;
class XList extends Base
{
@ -55,12 +56,13 @@ class XList extends Base
))
->param('siteId', '', new UID(), 'Site ID.')
->param('queries', [], new Logs(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Executions::ALLOWED_ATTRIBUTES), true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->callback($this->action(...));
}
public function action(string $siteId, array $queries, Response $response, Database $dbForProject)
public function action(string $siteId, array $queries, bool $includeTotal, Response $response, Database $dbForProject)
{
$site = $dbForProject->getDocument('sites', $siteId);
@ -107,7 +109,7 @@ class XList extends Base
try {
$results = $dbForProject->find('executions', $queries);
$total = $dbForProject->count('executions', $filterQueries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForProject->count('executions', $filterQueries, APP_LIMIT_COUNT) : 0;
} catch (OrderException $e) {
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
}

View file

@ -17,6 +17,7 @@ use Utopia\Database\Query;
use Utopia\Database\Validator\Query\Cursor;
use Utopia\Platform\Action;
use Utopia\Platform\Scope\HTTP;
use Utopia\Validator\Boolean;
use Utopia\Validator\Text;
class XList extends Base
@ -54,12 +55,13 @@ class XList extends Base
))
->param('queries', [], new Sites(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Sites::ALLOWED_ATTRIBUTES), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->callback($this->action(...));
}
public function action(array $queries, string $search, Response $response, Database $dbForProject)
public function action(array $queries, string $search, bool $includeTotal, Response $response, Database $dbForProject)
{
try {
$queries = Query::parseQueries($queries);
@ -100,7 +102,7 @@ class XList extends Base
try {
$sites = $dbForProject->find('sites', $queries);
$total = $dbForProject->count('sites', $filterQueries, APP_LIMIT_COUNT);
$total = $includeTotal ? $dbForProject->count('sites', $filterQueries, APP_LIMIT_COUNT) : 0;
} catch (OrderException $e) {
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
}

View file

@ -15,6 +15,7 @@ use Utopia\Database\Document;
use Utopia\Database\Query;
use Utopia\Database\Validator\UID;
use Utopia\Platform\Scope\HTTP;
use Utopia\Validator\Boolean;
class XList extends Action
{
@ -53,12 +54,13 @@ class XList extends Action
->param('bucketId', '', new UID(), 'Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket).')
->param('fileId', '', new UID(), 'File unique ID.')
->param('queries', [], new FileTokens(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', FileTokens::ALLOWED_ATTRIBUTES), true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->callback($this->action(...));
}
public function action(string $bucketId, string $fileId, array $queries, Response $response, Database $dbForProject)
public function action(string $bucketId, string $fileId, array $queries, bool $includeTotal, Response $response, Database $dbForProject)
{
['bucket' => $bucket, 'file' => $file] = $this->getFileAndBucket($dbForProject, $bucketId, $fileId);
@ -86,7 +88,7 @@ class XList extends Action
$response->dynamic(new Document([
'tokens' => $dbForProject->find('resourceTokens', $queries),
'total' => $dbForProject->count('resourceTokens', $filterQueries, APP_LIMIT_COUNT),
'total' => $includeTotal ? $dbForProject->count('resourceTokens', $filterQueries, APP_LIMIT_COUNT) : 0,
]), Response::MODEL_RESOURCE_TOKEN_LIST);
}
}

View file

@ -389,6 +389,26 @@ class AccountCustomClientTest extends Scope
$this->assertIsNumeric($responseLimitOffset['body']['total']);
$this->assertEquals($response['body']['logs'][1], $responseLimitOffset['body']['logs'][0]);
/**
* Test for total=false
*/
$logsWithIncludeTotalFalse = $this->client->call(Client::METHOD_GET, '/account/logs', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session,
]), [
'total' => false
]);
$this->assertEquals(200, $logsWithIncludeTotalFalse['headers']['status-code']);
$this->assertIsArray($logsWithIncludeTotalFalse['body']);
$this->assertIsArray($logsWithIncludeTotalFalse['body']['logs']);
$this->assertIsInt($logsWithIncludeTotalFalse['body']['total']);
$this->assertEquals(0, $logsWithIncludeTotalFalse['body']['total']);
$this->assertGreaterThan(0, count($logsWithIncludeTotalFalse['body']['logs']));
/**
* Test for FAILURE
*/

View file

@ -961,6 +961,24 @@ trait DatabasesBase
$this->assertEquals(200, $attributes['headers']['status-code']);
$this->assertEquals(12, $attributes['body']['total']);
/**
* Test for SUCCESS with total=false
*/
$attributesWithIncludeTotalFalse = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'total' => false
]);
$this->assertEquals(200, $attributesWithIncludeTotalFalse['headers']['status-code']);
$this->assertIsArray($attributesWithIncludeTotalFalse['body']);
$this->assertIsArray($attributesWithIncludeTotalFalse['body']['attributes']);
$this->assertIsInt($attributesWithIncludeTotalFalse['body']['total']);
$this->assertEquals(0, $attributesWithIncludeTotalFalse['body']['total']);
$this->assertGreaterThan(0, count($attributesWithIncludeTotalFalse['body']['attributes']));
$attributes = $attributes['body']['attributes'];
$this->assertIsArray($attributes);
$this->assertCount(12, $attributes);

View file

@ -55,6 +55,23 @@ class DatabasesCustomServerTest extends Scope
$this->assertEquals($test1['body']['$id'], $databases['body']['databases'][0]['$id']);
$this->assertEquals($test2['body']['$id'], $databases['body']['databases'][1]['$id']);
/**
* Test for SUCCESS with total=false
*/
$databasesWithIncludeTotalFalse = $this->client->call(Client::METHOD_GET, '/databases', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'total' => false
]);
$this->assertEquals(200, $databasesWithIncludeTotalFalse['headers']['status-code']);
$this->assertIsArray($databasesWithIncludeTotalFalse['body']);
$this->assertIsArray($databasesWithIncludeTotalFalse['body']['databases']);
$this->assertIsInt($databasesWithIncludeTotalFalse['body']['total']);
$this->assertEquals(0, $databasesWithIncludeTotalFalse['body']['total']);
$this->assertGreaterThan(0, count($databasesWithIncludeTotalFalse['body']['databases']));
$base = array_reverse($databases['body']['databases']);
$databases = $this->client->call(Client::METHOD_GET, '/databases', array_merge([
@ -395,6 +412,23 @@ class DatabasesCustomServerTest extends Scope
$this->assertEquals($test2['body']['$id'], $collections['body']['collections'][1]['$id']);
$this->assertEquals($test1['body']['enabled'], $collections['body']['collections'][0]['enabled']);
/**
* Test for SUCCESS with total=false
*/
$collectionsWithIncludeTotalFalse = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'total' => false
]);
$this->assertEquals(200, $collectionsWithIncludeTotalFalse['headers']['status-code']);
$this->assertIsArray($collectionsWithIncludeTotalFalse['body']);
$this->assertIsArray($collectionsWithIncludeTotalFalse['body']['collections']);
$this->assertIsInt($collectionsWithIncludeTotalFalse['body']['total']);
$this->assertEquals(0, $collectionsWithIncludeTotalFalse['body']['total']);
$this->assertGreaterThan(0, count($collectionsWithIncludeTotalFalse['body']['collections']));
$base = array_reverse($collections['body']['collections']);
$collections = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections', array_merge([
@ -4548,6 +4582,23 @@ class DatabasesCustomServerTest extends Scope
$this->assertEquals(200, $documents['headers']['status-code']);
$this->assertEquals(10, $documents['body']['total']);
/**
* Test for SUCCESS with total=false
*/
$documentsWithIncludeTotalFalse = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $data['$id'] . '/documents', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'total' => false
]);
$this->assertEquals(200, $documentsWithIncludeTotalFalse['headers']['status-code']);
$this->assertIsArray($documentsWithIncludeTotalFalse['body']);
$this->assertIsArray($documentsWithIncludeTotalFalse['body']['documents']);
$this->assertIsInt($documentsWithIncludeTotalFalse['body']['total']);
$this->assertEquals(0, $documentsWithIncludeTotalFalse['body']['total']);
$this->assertGreaterThan(0, count($documentsWithIncludeTotalFalse['body']['documents']));
$returnedDocuments = $response['body']['documents'];
$refetchedDocuments = $documents['body']['documents'];

View file

@ -55,6 +55,23 @@ class DatabasesCustomServerTest extends Scope
$this->assertEquals($test1['body']['$id'], $databases['body']['databases'][0]['$id']);
$this->assertEquals($test2['body']['$id'], $databases['body']['databases'][1]['$id']);
/**
* Test for SUCCESS with total=false
*/
$databasesWithIncludeTotalFalse = $this->client->call(Client::METHOD_GET, '/tablesdb', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'total' => false
]);
$this->assertEquals(200, $databasesWithIncludeTotalFalse['headers']['status-code']);
$this->assertIsArray($databasesWithIncludeTotalFalse['body']);
$this->assertIsArray($databasesWithIncludeTotalFalse['body']['databases']);
$this->assertIsInt($databasesWithIncludeTotalFalse['body']['total']);
$this->assertEquals(0, $databasesWithIncludeTotalFalse['body']['total']);
$this->assertGreaterThan(0, count($databasesWithIncludeTotalFalse['body']['databases']));
$base = array_reverse($databases['body']['databases']);
$databases = $this->client->call(Client::METHOD_GET, '/tablesdb', array_merge([

View file

@ -376,6 +376,23 @@ class FunctionsCustomClientTest extends Scope
$this->assertGreaterThan(0, $templates['body']['total']);
$this->assertIsArray($templates['body']['templates']);
/**
* Test for SUCCESS with total=false
*/
$templatesWithIncludeTotalFalse = $this->client->call(Client::METHOD_GET, '/functions/templates', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'total' => false
]);
$this->assertEquals(200, $templatesWithIncludeTotalFalse['headers']['status-code']);
$this->assertIsArray($templatesWithIncludeTotalFalse['body']);
$this->assertIsArray($templatesWithIncludeTotalFalse['body']['templates']);
$this->assertIsInt($templatesWithIncludeTotalFalse['body']['total']);
$this->assertEquals(0, $templatesWithIncludeTotalFalse['body']['total']);
$this->assertGreaterThan(0, count($templatesWithIncludeTotalFalse['body']['templates']));
foreach ($templates['body']['templates'] as $template) {
$this->assertArrayHasKey('name', $template);
$this->assertArrayHasKey('id', $template);

View file

@ -418,6 +418,18 @@ class FunctionsCustomServerTest extends Scope
$this->assertEquals(200, $deployments['headers']['status-code']);
$this->assertEquals(1, $deployments['body']['total']);
/**
* Test for SUCCESS with total=false
*/
$deploymentsWithIncludeTotalFalse = $this->listDeployments($functionId, ['total' => false]);
$this->assertEquals(200, $deploymentsWithIncludeTotalFalse['headers']['status-code']);
$this->assertIsArray($deploymentsWithIncludeTotalFalse['body']);
$this->assertIsArray($deploymentsWithIncludeTotalFalse['body']['deployments']);
$this->assertIsInt($deploymentsWithIncludeTotalFalse['body']['total']);
$this->assertEquals(0, $deploymentsWithIncludeTotalFalse['body']['total']);
$this->assertGreaterThan(0, count($deploymentsWithIncludeTotalFalse['body']['deployments']));
$lastDeployment = $deployments['body']['deployments'][0];
$this->assertNotEmpty($lastDeployment['$id']);
@ -1004,6 +1016,18 @@ class FunctionsCustomServerTest extends Scope
$this->assertCount(1, $executions['body']['executions']);
$this->assertEquals($data['deploymentId'], $executions['body']['executions'][0]['deploymentId']);
/**
* Test for SUCCESS with total=false
*/
$executionsWithIncludeTotalFalse = $this->listExecutions($data['functionId'], ['total' => false]);
$this->assertEquals(200, $executionsWithIncludeTotalFalse['headers']['status-code']);
$this->assertIsArray($executionsWithIncludeTotalFalse['body']);
$this->assertIsArray($executionsWithIncludeTotalFalse['body']['executions']);
$this->assertIsInt($executionsWithIncludeTotalFalse['body']['total']);
$this->assertEquals(0, $executionsWithIncludeTotalFalse['body']['total']);
$this->assertGreaterThan(0, count($executionsWithIncludeTotalFalse['body']['executions']));
$executions = $this->listExecutions($data['functionId'], [
'queries' => [
Query::equal('deploymentId', [$data['deploymentId']])->toString(),

View file

@ -644,6 +644,24 @@ trait MessagingBase
$this->assertEquals(1, $response['body']['total']);
}
/**
* Test for SUCCESS with total=false
*/
$subscribersWithIncludeTotalFalse = $this->client->call(Client::METHOD_GET, '/messaging/topics/' . $data['topicId'] . '/subscribers', \array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey'],
]), [
'total' => false
]);
$this->assertEquals(200, $subscribersWithIncludeTotalFalse['headers']['status-code']);
$this->assertIsArray($subscribersWithIncludeTotalFalse['body']);
$this->assertIsArray($subscribersWithIncludeTotalFalse['body']['subscribers']);
$this->assertIsInt($subscribersWithIncludeTotalFalse['body']['total']);
$this->assertEquals(0, $subscribersWithIncludeTotalFalse['body']['total']);
$this->assertGreaterThan(0, count($subscribersWithIncludeTotalFalse['body']['subscribers']));
return $data;
}

View file

@ -379,6 +379,23 @@ trait StorageBase
$this->assertGreaterThan(0, $files['body']['total']);
$this->assertGreaterThan(0, count($files['body']['files']));
/**
* Test for SUCCESS with total=false
*/
$filesWithIncludeTotalFalse = $this->client->call(Client::METHOD_GET, '/storage/buckets/' . $data['bucketId'] . '/files', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'total' => false
]);
$this->assertEquals(200, $filesWithIncludeTotalFalse['headers']['status-code']);
$this->assertIsArray($filesWithIncludeTotalFalse['body']);
$this->assertIsArray($filesWithIncludeTotalFalse['body']['files']);
$this->assertIsInt($filesWithIncludeTotalFalse['body']['total']);
$this->assertEquals(0, $filesWithIncludeTotalFalse['body']['total']);
$this->assertGreaterThan(0, count($filesWithIncludeTotalFalse['body']['files']));
$files = $this->client->call(Client::METHOD_GET, '/storage/buckets/' . $data['bucketId'] . '/files', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],

View file

@ -322,6 +322,23 @@ trait TeamsBase
$this->assertEquals(400, $response['headers']['status-code']);
/**
* Test for SUCCESS with total=false
*/
$teamsWithIncludeTotalFalse = $this->client->call(Client::METHOD_GET, '/teams', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'total' => false
]);
$this->assertEquals(200, $teamsWithIncludeTotalFalse['headers']['status-code']);
$this->assertIsArray($teamsWithIncludeTotalFalse['body']);
$this->assertIsArray($teamsWithIncludeTotalFalse['body']['teams']);
$this->assertIsInt($teamsWithIncludeTotalFalse['body']['total']);
$this->assertEquals(0, $teamsWithIncludeTotalFalse['body']['total']);
$this->assertGreaterThan(0, count($teamsWithIncludeTotalFalse['body']['teams']));
return [];
}

View file

@ -798,6 +798,23 @@ trait UsersBase
$this->assertIsInt($users['body']['total']);
$this->assertGreaterThan(0, $users['body']['total']);
/**
* Test for SUCCESS with total=false
*/
$usersWithIncludeTotalFalse = $this->client->call(Client::METHOD_GET, '/users', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'total' => false
]);
$this->assertEquals(200, $usersWithIncludeTotalFalse['headers']['status-code']);
$this->assertIsArray($usersWithIncludeTotalFalse['body']);
$this->assertIsArray($usersWithIncludeTotalFalse['body']['users']);
$this->assertIsInt($usersWithIncludeTotalFalse['body']['total']);
$this->assertEquals(0, $usersWithIncludeTotalFalse['body']['total']);
$this->assertGreaterThan(0, count($usersWithIncludeTotalFalse['body']['users']));
/**
* Test for FAILURE
*/