Update database query syntax
This commit is contained in:
parent
4d9c37f2db
commit
610ec1a6a4
|
@ -6,8 +6,11 @@ use Appwrite\Auth\Phone;
|
|||
use Appwrite\Auth\Validator\Password;
|
||||
use Appwrite\Auth\Validator\Phone as ValidatorPhone;
|
||||
use Appwrite\Detector\Detector;
|
||||
use Appwrite\Event\Audit;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Mail;
|
||||
use Appwrite\Event\Phone as EventPhone;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Network\Validator\Email;
|
||||
use Appwrite\Network\Validator\Host;
|
||||
use Appwrite\Network\Validator\URL;
|
||||
|
@ -15,13 +18,11 @@ use Appwrite\OpenSSL\OpenSSL;
|
|||
use Appwrite\Stats\Stats;
|
||||
use Appwrite\Template\Template;
|
||||
use Appwrite\URL\URL as URLParser;
|
||||
use Appwrite\Utopia\Database\Validator\CustomId;
|
||||
use Appwrite\Utopia\Request;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Appwrite\Utopia\Database\Validator\CustomId;
|
||||
use MaxMind\Db\Reader;
|
||||
use Utopia\App;
|
||||
use Appwrite\Event\Audit;
|
||||
use Appwrite\Event\Phone as EventPhone;
|
||||
use Utopia\Audit\Audit as EventAudit;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
|
@ -32,7 +33,6 @@ use Utopia\Database\Query;
|
|||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Locale\Locale;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Utopia\Validator\ArrayList;
|
||||
use Utopia\Validator\Assoc;
|
||||
use Utopia\Validator\Range;
|
||||
|
@ -165,7 +165,8 @@ App::post('/v1/account/sessions/email')
|
|||
$protocol = $request->getProtocol();
|
||||
|
||||
$profile = $dbForProject->findOne('users', [
|
||||
new Query('email', Query::TYPE_EQUAL, [$email])]);
|
||||
Query::equal('email', [$email]),
|
||||
]);
|
||||
|
||||
if (!$profile || !Auth::passwordVerify($password, $profile->getAttribute('password'))) {
|
||||
throw new Exception('Invalid credentials', 401, Exception::USER_INVALID_CREDENTIALS); // Wrong password or username
|
||||
|
@ -448,8 +449,8 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
}
|
||||
|
||||
$user = ($user->isEmpty()) ? $dbForProject->findOne('sessions', [ // Get user by provider id
|
||||
new Query('provider', QUERY::TYPE_EQUAL, [$provider]),
|
||||
new Query('providerUid', QUERY::TYPE_EQUAL, [$oauth2ID]),
|
||||
Query::equal('provider', [$provider]),
|
||||
Query::equal('providerUid', [$oauth2ID]),
|
||||
]) : $user;
|
||||
|
||||
if ($user === false || $user->isEmpty()) { // No user logged in or with OAuth2 provider ID, create new one or connect with account with same email
|
||||
|
@ -462,7 +463,8 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
$isVerified = $oauth2->isEmailVerified($accessToken);
|
||||
|
||||
$user = $dbForProject->findOne('users', [
|
||||
new Query('email', Query::TYPE_EQUAL, [$email])]);
|
||||
Query::equal('email', [$email]),
|
||||
]);
|
||||
|
||||
if ($user === false || $user->isEmpty()) { // Last option -> create the user, generate random password
|
||||
$limit = $project->getAttribute('auths', [])['limit'] ?? 0;
|
||||
|
@ -628,7 +630,7 @@ App::post('/v1/account/sessions/magic-url')
|
|||
$isPrivilegedUser = Auth::isPrivilegedUser($roles);
|
||||
$isAppUser = Auth::isAppUser($roles);
|
||||
|
||||
$user = $dbForProject->findOne('users', [new Query('email', Query::TYPE_EQUAL, [$email])]);
|
||||
$user = $dbForProject->findOne('users', [Query::equal('email', [$email])]);
|
||||
|
||||
if (!$user) {
|
||||
$limit = $project->getAttribute('auths', [])['limit'] ?? 0;
|
||||
|
@ -869,7 +871,7 @@ App::post('/v1/account/sessions/phone')
|
|||
$isPrivilegedUser = Auth::isPrivilegedUser($roles);
|
||||
$isAppUser = Auth::isAppUser($roles);
|
||||
|
||||
$user = $dbForProject->findOne('users', [new Query('phone', Query::TYPE_EQUAL, [$number])]);
|
||||
$user = $dbForProject->findOne('users', [Query::equal('phone', [$number])]);
|
||||
|
||||
if (!$user) {
|
||||
$limit = $project->getAttribute('auths', [])['limit'] ?? 0;
|
||||
|
@ -1954,7 +1956,7 @@ App::post('/v1/account/recovery')
|
|||
$email = \strtolower($email);
|
||||
|
||||
$profile = $dbForProject->findOne('users', [
|
||||
new Query('email', Query::TYPE_EQUAL, [$email])
|
||||
Query::equal('email', [$email]),
|
||||
]);
|
||||
|
||||
if (!$profile) {
|
||||
|
|
|
@ -21,7 +21,7 @@ use Utopia\Database\Adapter\MariaDB;
|
|||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Database\Validator\Key;
|
||||
use Utopia\Database\Validator\Permissions;
|
||||
use Utopia\Database\Validator\QueryValidator;
|
||||
use Utopia\Database\Validator\Query as QueryValidator;
|
||||
use Utopia\Database\Validator\Structure;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Database\Exception\Authorization as AuthorizationException;
|
||||
|
@ -248,31 +248,37 @@ App::get('/v1/databases')
|
|||
->param('offset', 0, new Range(0, APP_LIMIT_COUNT), 'Offset value. The default value is 0. Use this param to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
|
||||
->param('cursor', '', new UID(), 'ID of the collection used as the starting point for the query, excluding the collection itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor, can be either \'before\' or \'after\'.', true)
|
||||
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
|
||||
->param('orderType', Database::ORDER_ASC, new WhiteList([Database::ORDER_ASC, Database::ORDER_DESC], true), 'Order result by ' . Database::ORDER_ASC . ' or ' . Database::ORDER_DESC . ' order.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('usage')
|
||||
->action(function (string $search, int $limit, int $offset, string $cursor, string $cursorDirection, string $orderType, Response $response, Database $dbForProject, Stats $usage) {
|
||||
|
||||
$filterQueries = [];
|
||||
|
||||
if (!empty($search)) {
|
||||
$filterQueries[] = Query::search('search', $search);
|
||||
}
|
||||
|
||||
$queries = [];
|
||||
$queries[] = Query::limit($limit);
|
||||
$queries[] = Query::offset($offset);
|
||||
$queries[] = $orderType === 'ASC' ? Query::orderAsc('') : Query::orderDesc('');
|
||||
if (!empty($cursor)) {
|
||||
$cursorDocument = $dbForProject->getDocument('databases', $cursor);
|
||||
|
||||
if ($cursorDocument->isEmpty()) {
|
||||
throw new Exception("Collection '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
$queries = [];
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);
|
||||
$queries[] = $cursorDirection === Database::CURSOR_AFTER ? Query::cursorAfter($cursorDocument) : Query::cursorBefore($cursorDocument);
|
||||
}
|
||||
|
||||
$usage->setParam('databases.read', 1);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'databases' => $dbForProject->find('databases', $queries, $limit, $offset, [], [$orderType], $cursorDocument ?? null, $cursorDirection),
|
||||
'total' => $dbForProject->count('databases', $queries, APP_LIMIT_COUNT),
|
||||
'databases' => $dbForProject->find('databases', \array_merge($filterQueries, $queries)),
|
||||
'total' => $dbForProject->count('databases', $filterQueries, APP_LIMIT_COUNT),
|
||||
]), Response::MODEL_DATABASE_LIST);
|
||||
});
|
||||
|
||||
|
@ -574,7 +580,7 @@ App::get('/v1/databases/:databaseId/collections')
|
|||
->param('offset', 0, new Range(0, APP_LIMIT_COUNT), 'Offset value. The default value is 0. Use this param to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
|
||||
->param('cursor', '', new UID(), 'ID of the collection used as the starting point for the query, excluding the collection itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor, can be either \'before\' or \'after\'.', true)
|
||||
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
|
||||
->param('orderType', Database::ORDER_ASC, new WhiteList([Database::ORDER_ASC, Database::ORDER_DESC], true), 'Order result by ' . Database::ORDER_ASC . ' or ' . Database::ORDER_DESC . ' order.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('usage')
|
||||
|
@ -586,18 +592,24 @@ App::get('/v1/databases/:databaseId/collections')
|
|||
throw new Exception('Database not found', 404, Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (!empty($cursor)) {
|
||||
$cursorCollection = $dbForProject->getDocument('database_' . $database->getInternalId(), $cursor);
|
||||
$filterQueries = [];
|
||||
|
||||
if ($cursorCollection->isEmpty()) {
|
||||
throw new Exception("Collection '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
|
||||
}
|
||||
if (!empty($search)) {
|
||||
$filterQueries[] = Query::search('search', $search);
|
||||
}
|
||||
|
||||
$queries = [];
|
||||
$queries[] = Query::limit($limit);
|
||||
$queries[] = Query::offset($offset);
|
||||
$queries[] = $orderType === 'ASC' ? Query::orderAsc('') : Query::orderDesc('');
|
||||
if (!empty($cursor)) {
|
||||
$cursorDocument = $dbForProject->getDocument('database_' . $database->getInternalId(), $cursor);
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);
|
||||
if ($cursorDocument->isEmpty()) {
|
||||
throw new Exception("Collection '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
|
||||
}
|
||||
|
||||
$queries[] = $cursorDirection === Database::CURSOR_AFTER ? Query::cursorAfter($cursorDocument) : Query::cursorBefore($cursorDocument);
|
||||
}
|
||||
|
||||
$usage
|
||||
|
@ -605,8 +617,8 @@ App::get('/v1/databases/:databaseId/collections')
|
|||
->setParam('databases.collections.read', 1);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'collections' => $dbForProject->find('database_' . $database->getInternalId(), $queries, $limit, $offset, [], [$orderType], $cursorCollection ?? null, $cursorDirection),
|
||||
'total' => $dbForProject->count('database_' . $database->getInternalId(), $queries, APP_LIMIT_COUNT),
|
||||
'collections' => $dbForProject->find('database_' . $database->getInternalId(), \array_merge($filterQueries, $queries)),
|
||||
'total' => $dbForProject->count('database_' . $database->getInternalId(), $filterQueries, APP_LIMIT_COUNT),
|
||||
]), Response::MODEL_COLLECTION_LIST);
|
||||
});
|
||||
|
||||
|
@ -1295,7 +1307,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/dateti
|
|||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.method', 'createDatetimeAttribute')
|
||||
->label('sdk.description', '/docs/references/databases/create-datetime-attribute.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
|
||||
->label('sdk.response.code', Response::STATUS_CODE_ACCEPTED)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_DATETIME)
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
|
@ -1322,6 +1334,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/dateti
|
|||
'filters' => ['datetime']
|
||||
]), $response, $dbForProject, $database, $audits, $events, $usage);
|
||||
|
||||
$response->setStatusCode(Response::STATUS_CODE_ACCEPTED);
|
||||
$response->dynamic($attribute, Response::MODEL_ATTRIBUTE_DATETIME);
|
||||
});
|
||||
|
||||
|
@ -1575,8 +1588,8 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/indexes')
|
|||
}
|
||||
|
||||
$count = $dbForProject->count('indexes', [
|
||||
new Query('collectionInternalId', Query::TYPE_EQUAL, [$collection->getInternalId()]),
|
||||
new Query('databaseInternalId', Query::TYPE_EQUAL, [$db->getInternalId()])
|
||||
Query::equal('collectionInternalId', [$collection->getInternalId()]),
|
||||
Query::equal('databaseInternalId', [$db->getInternalId()])
|
||||
], 61);
|
||||
|
||||
$limit = 64 - MariaDB::getNumberOfDefaultIndexes();
|
||||
|
@ -1847,8 +1860,8 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/indexes/:key')
|
|||
->setParam('databaseId', $databaseId)
|
||||
->setParam('collectionId', $collection->getId())
|
||||
->setParam('indexId', $index->getId())
|
||||
->setContext('collection', $collection)
|
||||
->setContext('database', $db)
|
||||
->setContext('collection', $collection)
|
||||
->setContext('database', $db)
|
||||
->setPayload($response->output($index, Response::MODEL_INDEX))
|
||||
;
|
||||
|
||||
|
@ -2003,7 +2016,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
|
|||
->param('cursor', '', new UID(), 'ID of the document used as the starting point for the query, excluding the document itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor, can be either \'before\' or \'after\'.', true)
|
||||
->param('orderAttributes', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of attributes used to sort results. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' order attributes are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.', true)
|
||||
->param('orderTypes', [], new ArrayList(new WhiteList(['DESC', 'ASC'], true), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of order directions for sorting attribtues. Possible values are DESC for descending order, or ASC for ascending order. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' order types are allowed.', true)
|
||||
->param('orderTypes', [], new ArrayList(new WhiteList([Database::ORDER_DESC, Database::ORDER_ASC], true), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of order directions for sorting attribtues. Possible values are DESC for descending order, or ASC for ascending order. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' order types are allowed.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('usage')
|
||||
|
@ -2036,31 +2049,17 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
|
|||
}
|
||||
}
|
||||
|
||||
$queries = \array_map(function ($query) {
|
||||
$query = Query::parse($query);
|
||||
|
||||
if (\count($query->getValues()) > 100) {
|
||||
throw new Exception("You cannot use more than 100 query values on attribute '{$query->getAttribute()}'", 400, Exception::GENERAL_QUERY_LIMIT_EXCEEDED);
|
||||
}
|
||||
|
||||
return $query;
|
||||
$filterQueries = \array_map(function ($query) {
|
||||
return Query::parse($query);
|
||||
}, $queries);
|
||||
|
||||
if (!empty($orderAttributes)) {
|
||||
$validator = new OrderAttributes($collection->getAttribute('attributes', []), $collection->getAttribute('indexes', []), true);
|
||||
if (!$validator->isValid($orderAttributes)) {
|
||||
throw new Exception($validator->getDescription(), 400, Exception::GENERAL_QUERY_INVALID);
|
||||
}
|
||||
$otherQueries = [];
|
||||
$otherQueries[] = Query::limit($limit);
|
||||
$otherQueries[] = Query::offset($offset);
|
||||
foreach ($orderTypes as $i => $orderType) {
|
||||
$otherQueries[] = $orderType === Database::ORDER_DESC ? Query::orderDesc($orderAttributes[$i] ?? '') : Query::orderAsc($orderAttributes[$i] ?? '');
|
||||
}
|
||||
|
||||
if (!empty($queries)) {
|
||||
$validator = new QueriesValidator(new QueryValidator($collection->getAttribute('attributes', [])), $collection->getAttribute('indexes', []), true);
|
||||
if (!$validator->isValid($queries)) {
|
||||
throw new Exception($validator->getDescription(), 400, Exception::GENERAL_QUERY_INVALID);
|
||||
}
|
||||
}
|
||||
|
||||
$cursorDocument = null;
|
||||
if (!empty($cursor)) {
|
||||
$cursorDocument = $collection->getAttribute('permission') === 'collection'
|
||||
? Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $cursor))
|
||||
|
@ -2069,15 +2068,27 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
|
|||
if ($cursorDocument->isEmpty()) {
|
||||
throw new Exception("Document '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
|
||||
}
|
||||
|
||||
$otherQueries[] = $cursorDirection === Database::CURSOR_AFTER ? Query::cursorAfter($cursorDocument) : Query::cursorBefore($cursorDocument);
|
||||
}
|
||||
|
||||
$allQueries = \array_merge($filterQueries, $otherQueries);
|
||||
|
||||
if (!empty($allQueries)) {
|
||||
$attributes = $collection->getAttribute('attributes', []);
|
||||
$validator = new QueriesValidator(new QueryValidator($attributes), $attributes, $collection->getAttribute('indexes', []), true);
|
||||
if (!$validator->isValid($allQueries)) {
|
||||
throw new Exception($validator->getDescription(), 400, Exception::GENERAL_QUERY_INVALID);
|
||||
}
|
||||
}
|
||||
|
||||
if ($collection->getAttribute('permission') === 'collection') {
|
||||
/** @var Document[] $documents */
|
||||
$documents = Authorization::skip(fn() => $dbForProject->find('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $queries, $limit, $offset, $orderAttributes, $orderTypes, $cursorDocument ?? null, $cursorDirection));
|
||||
$total = Authorization::skip(fn() => $dbForProject->count('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $queries, APP_LIMIT_COUNT));
|
||||
$documents = Authorization::skip(fn () => $dbForProject->find('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $allQueries));
|
||||
$total = Authorization::skip(fn () => $dbForProject->count('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $filterQueries, APP_LIMIT_COUNT));
|
||||
} else {
|
||||
$documents = $dbForProject->find('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $queries, $limit, $offset, $orderAttributes, $orderTypes, $cursorDocument ?? null, $cursorDirection);
|
||||
$total = $dbForProject->count('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $queries, APP_LIMIT_COUNT);
|
||||
$documents = $dbForProject->find('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $allQueries);
|
||||
$total = $dbForProject->count('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $filterQueries, APP_LIMIT_COUNT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2562,9 +2573,11 @@ App::get('/v1/databases/usage')
|
|||
$period = $periods[$range]['period'];
|
||||
|
||||
$requestDocs = $dbForProject->find('stats', [
|
||||
new Query('period', Query::TYPE_EQUAL, [$period]),
|
||||
new Query('metric', Query::TYPE_EQUAL, [$metric]),
|
||||
], $limit, 0, ['time'], [Database::ORDER_DESC]);
|
||||
Query::equal('period', [$period]),
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::limit($limit),
|
||||
Query::orderDesc('time'),
|
||||
]);
|
||||
|
||||
$stats[$metric] = [];
|
||||
foreach ($requestDocs as $requestDoc) {
|
||||
|
@ -2674,9 +2687,11 @@ App::get('/v1/databases/:databaseId/usage')
|
|||
$period = $periods[$range]['period'];
|
||||
|
||||
$requestDocs = $dbForProject->find('stats', [
|
||||
new Query('period', Query::TYPE_EQUAL, [$period]),
|
||||
new Query('metric', Query::TYPE_EQUAL, [$metric]),
|
||||
], $limit, 0, ['time'], [Database::ORDER_DESC]);
|
||||
Query::equal('period', [$period]),
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::limit($limit),
|
||||
Query::orderDesc('time'),
|
||||
]);
|
||||
|
||||
$stats[$metric] = [];
|
||||
foreach ($requestDocs as $requestDoc) {
|
||||
|
@ -2787,9 +2802,11 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/usage')
|
|||
$period = $periods[$range]['period'];
|
||||
|
||||
$requestDocs = $dbForProject->find('stats', [
|
||||
new Query('period', Query::TYPE_EQUAL, [$period]),
|
||||
new Query('metric', Query::TYPE_EQUAL, [$metric]),
|
||||
], $limit, 0, ['time'], [Database::ORDER_DESC]);
|
||||
Query::equal('period', [$period]),
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::limit($limit),
|
||||
Query::orderDesc('time'),
|
||||
]);
|
||||
|
||||
$stats[$metric] = [];
|
||||
foreach ($requestDocs as $requestDoc) {
|
||||
|
|
|
@ -103,28 +103,34 @@ App::get('/v1/functions')
|
|||
->param('offset', 0, new Range(0, APP_LIMIT_COUNT), 'Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
|
||||
->param('cursor', '', new UID(), 'ID of the function used as the starting point for the query, excluding the function itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor, can be either \'before\' or \'after\'.', true)
|
||||
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
|
||||
->param('orderType', Database::ORDER_ASC, new WhiteList([Database::ORDER_ASC, Database::ORDER_DESC], true), 'Order result by ' . Database::ORDER_ASC . ' or ' . Database::ORDER_DESC . ' order.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->action(function (string $search, int $limit, int $offset, string $cursor, string $cursorDirection, string $orderType, Response $response, Database $dbForProject) {
|
||||
|
||||
if (!empty($cursor)) {
|
||||
$cursorFunction = $dbForProject->getDocument('functions', $cursor);
|
||||
$filterQueries = [];
|
||||
|
||||
if ($cursorFunction->isEmpty()) {
|
||||
throw new Exception("Function '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
|
||||
}
|
||||
if (!empty($search)) {
|
||||
$filterQueries[] = Query::search('search', $search);
|
||||
}
|
||||
|
||||
$queries = [];
|
||||
$queries[] = Query::limit($limit);
|
||||
$queries[] = Query::offset($offset);
|
||||
$queries[] = $orderType === Database::ORDER_ASC ? Query::orderAsc('') : Query::orderDesc('');
|
||||
if (!empty($cursor)) {
|
||||
$cursorDocument = $dbForProject->getDocument('functions', $cursor);
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);
|
||||
if ($cursorDocument->isEmpty()) {
|
||||
throw new Exception("Function '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
|
||||
}
|
||||
|
||||
$queries[] = $cursorDirection === Database::CURSOR_AFTER ? Query::cursorAfter($cursorDocument) : Query::cursorBefore($cursorDocument);
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'functions' => $dbForProject->find('functions', $queries, $limit, $offset, [], [$orderType], $cursorFunction ?? null, $cursorDirection),
|
||||
'total' => $dbForProject->count('functions', $queries, APP_LIMIT_COUNT),
|
||||
'functions' => $dbForProject->find('functions', \array_merge($filterQueries, $queries)),
|
||||
'total' => $dbForProject->count('functions', $filterQueries, APP_LIMIT_COUNT),
|
||||
]), Response::MODEL_FUNCTION_LIST);
|
||||
});
|
||||
|
||||
|
@ -236,9 +242,11 @@ App::get('/v1/functions/:functionId/usage')
|
|||
$period = $periods[$range]['period'];
|
||||
|
||||
$requestDocs = $dbForProject->find('stats', [
|
||||
new Query('period', Query::TYPE_EQUAL, [$period]),
|
||||
new Query('metric', Query::TYPE_EQUAL, [$metric]),
|
||||
], $limit, 0, ['time'], [Database::ORDER_DESC]);
|
||||
Query::equal('period', [$period]),
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::limit($limit),
|
||||
Query::orderDesc('time'),
|
||||
]);
|
||||
|
||||
$stats[$metric] = [];
|
||||
foreach ($requestDocs as $requestDoc) {
|
||||
|
@ -553,9 +561,9 @@ App::post('/v1/functions/:functionId/deployments')
|
|||
if ($activate) {
|
||||
// Remove deploy for all other deployments.
|
||||
$activeDeployments = $dbForProject->find('deployments', [
|
||||
new Query('activate', Query::TYPE_EQUAL, [true]),
|
||||
new Query('resourceId', Query::TYPE_EQUAL, [$functionId]),
|
||||
new Query('resourceType', Query::TYPE_EQUAL, ['functions'])
|
||||
Query::equal('activate', [true]),
|
||||
Query::equal('resourceId', [$functionId]),
|
||||
Query::equal('resourceType', ['functions'])
|
||||
]);
|
||||
|
||||
foreach ($activeDeployments as $activeDeployment) {
|
||||
|
@ -643,7 +651,7 @@ App::get('/v1/functions/:functionId/deployments')
|
|||
->param('offset', 0, new Range(0, APP_LIMIT_COUNT), 'Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
|
||||
->param('cursor', '', new UID(), 'ID of the deployment used as the starting point for the query, excluding the deployment itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor, can be either \'before\' or \'after\'.', true)
|
||||
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
|
||||
->param('orderType', Database::ORDER_ASC, new WhiteList([Database::ORDER_ASC, Database::ORDER_DESC], true), 'Order result by ' . Database::ORDER_ASC . ' or ' . Database::ORDER_DESC . ' order.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->action(function (string $functionId, string $search, int $limit, int $offset, string $cursor, string $cursorDirection, string $orderType, Response $response, Database $dbForProject) {
|
||||
|
@ -654,25 +662,31 @@ App::get('/v1/functions/:functionId/deployments')
|
|||
throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (!empty($cursor)) {
|
||||
$cursorDeployment = $dbForProject->getDocument('deployments', $cursor);
|
||||
|
||||
if ($cursorDeployment->isEmpty()) {
|
||||
throw new Exception("Tag '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
$queries = [];
|
||||
$filterQueries = [];
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);
|
||||
$filterQueries[] = Query::search('search', $search);
|
||||
}
|
||||
|
||||
$queries[] = new Query('resourceId', Query::TYPE_EQUAL, [$function->getId()]);
|
||||
$queries[] = new Query('resourceType', Query::TYPE_EQUAL, ['functions']);
|
||||
$filterQueries[] = Query::equal('resourceId', [$function->getId()]);
|
||||
$filterQueries[] = Query::equal('resourceType', ['functions']);
|
||||
|
||||
$results = $dbForProject->find('deployments', $queries, $limit, $offset, [], [$orderType], $cursorDeployment ?? null, $cursorDirection);
|
||||
$total = $dbForProject->count('deployments', $queries, APP_LIMIT_COUNT);
|
||||
$queries = [];
|
||||
$queries[] = Query::limit($limit);
|
||||
$queries[] = Query::offset($offset);
|
||||
$queries[] = $orderType === Database::ORDER_ASC ? Query::orderAsc('') : Query::orderDesc('');
|
||||
if (!empty($cursor)) {
|
||||
$cursorDocument = $dbForProject->getDocument('deployments', $cursor);
|
||||
|
||||
if ($cursorDocument->isEmpty()) {
|
||||
throw new Exception("Tag '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
|
||||
}
|
||||
|
||||
$queries[] = $cursorDirection === Database::CURSOR_AFTER ? Query::cursorAfter($cursorDocument) : Query::cursorBefore($cursorDocument);
|
||||
}
|
||||
|
||||
$results = $dbForProject->find('deployments', \array_merge($filterQueries, $queries));
|
||||
$total = $dbForProject->count('deployments', $filterQueries, APP_LIMIT_COUNT);
|
||||
|
||||
foreach ($results as $result) {
|
||||
$build = $dbForProject->getDocument('builds', $result->getAttribute('buildId', ''));
|
||||
|
@ -996,24 +1010,30 @@ App::get('/v1/functions/:functionId/executions')
|
|||
throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (!empty($cursor)) {
|
||||
$cursorExecution = $dbForProject->getDocument('executions', $cursor);
|
||||
|
||||
if ($cursorExecution->isEmpty()) {
|
||||
throw new Exception("Execution '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
$queries = [
|
||||
new Query('functionId', Query::TYPE_EQUAL, [$function->getId()])
|
||||
$filterQueries = [
|
||||
Query::equal('functionId', [$function->getId()])
|
||||
];
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);
|
||||
$filterQueries[] = Query::search('search', $search);
|
||||
}
|
||||
|
||||
$results = $dbForProject->find('executions', $queries, $limit, $offset, [], [Database::ORDER_DESC], $cursorExecution ?? null, $cursorDirection);
|
||||
$total = $dbForProject->count('executions', $queries, APP_LIMIT_COUNT);
|
||||
$queries = [];
|
||||
$queries[] = Query::limit($limit);
|
||||
$queries[] = Query::offset($offset);
|
||||
$queries[] = Query::orderDesc('');
|
||||
if (!empty($cursor)) {
|
||||
$cursorDocument = $dbForProject->getDocument('executions', $cursor);
|
||||
|
||||
if ($cursorDocument->isEmpty()) {
|
||||
throw new Exception("Execution '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
|
||||
}
|
||||
|
||||
$queries[] = $cursorDirection === Database::CURSOR_AFTER ? Query::cursorAfter($cursorDocument) : Query::cursorBefore($cursorDocument);
|
||||
}
|
||||
|
||||
$results = $dbForProject->find('executions', \array_merge($filterQueries, $queries));
|
||||
$total = $dbForProject->count('executions', $filterQueries, APP_LIMIT_COUNT);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'executions' => $results,
|
||||
|
|
|
@ -177,27 +177,33 @@ App::get('/v1/projects')
|
|||
->param('offset', 0, new Range(0, APP_LIMIT_COUNT), 'Results offset. The default value is 0. Use this param to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
|
||||
->param('cursor', '', new UID(), 'ID of the project used as the starting point for the query, excluding the project itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor, can be either \'before\' or \'after\'.', true)
|
||||
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
|
||||
->param('orderType', Database::ORDER_ASC, new WhiteList([Database::ORDER_ASC, Database::ORDER_DESC], true), 'Order result by ' . Database::ORDER_ASC . ' or ' . Database::ORDER_DESC . ' order.', true)
|
||||
->inject('response')
|
||||
->inject('dbForConsole')
|
||||
->action(function (string $search, int $limit, int $offset, string $cursor, string $cursorDirection, string $orderType, Response $response, Database $dbForConsole) {
|
||||
|
||||
if (!empty($cursor)) {
|
||||
$cursorProject = $dbForConsole->getDocument('projects', $cursor);
|
||||
$filterQueries = [];
|
||||
|
||||
if ($cursorProject->isEmpty()) {
|
||||
throw new Exception("Project '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
|
||||
}
|
||||
if (!empty($search)) {
|
||||
$filterQueries[] = Query::search('search', $search);
|
||||
}
|
||||
|
||||
$queries = [];
|
||||
$queries[] = Query::limit($limit);
|
||||
$queries[] = Query::offset($offset);
|
||||
$queries[] = $orderType === Database::ORDER_ASC ? Query::orderAsc('') : Query::orderDesc('');
|
||||
if (!empty($cursor)) {
|
||||
$cursorDocument = $dbForConsole->getDocument('projects', $cursor);
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);
|
||||
if ($cursorDocument->isEmpty()) {
|
||||
throw new Exception("Project '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
|
||||
}
|
||||
|
||||
$queries[] = $cursorDirection === Database::CURSOR_AFTER ? Query::cursorAfter($cursorDocument) : Query::cursorBefore($cursorDocument);
|
||||
}
|
||||
|
||||
$results = $dbForConsole->find('projects', $queries, $limit, $offset, [], [$orderType], $cursorProject ?? null, $cursorDirection);
|
||||
$total = $dbForConsole->count('projects', $queries, APP_LIMIT_COUNT);
|
||||
$results = $dbForConsole->find('projects', \array_merge($filterQueries, $queries));
|
||||
$total = $dbForConsole->count('projects', $filterQueries, APP_LIMIT_COUNT);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'projects' => $results,
|
||||
|
@ -294,9 +300,11 @@ App::get('/v1/projects/:projectId/usage')
|
|||
$period = $periods[$range]['period'];
|
||||
|
||||
$requestDocs = $dbForProject->find('stats', [
|
||||
new Query('period', Query::TYPE_EQUAL, [$period]),
|
||||
new Query('metric', Query::TYPE_EQUAL, [$metric]),
|
||||
], $limit, 0, ['time'], [Database::ORDER_DESC]);
|
||||
Query::equal('period', [$period]),
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::limit($limit),
|
||||
Query::orderDesc('time'),
|
||||
]);
|
||||
|
||||
$stats[$metric] = [];
|
||||
foreach ($requestDocs as $requestDoc) {
|
||||
|
@ -634,8 +642,9 @@ App::get('/v1/projects/:projectId/webhooks')
|
|||
}
|
||||
|
||||
$webhooks = $dbForConsole->find('webhooks', [
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
], 5000);
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
Query::limit(5000),
|
||||
]);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'webhooks' => $webhooks,
|
||||
|
@ -666,8 +675,8 @@ App::get('/v1/projects/:projectId/webhooks/:webhookId')
|
|||
}
|
||||
|
||||
$webhook = $dbForConsole->findOne('webhooks', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$webhookId]),
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
Query::equal('_uid', [$webhookId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($webhook === false || $webhook->isEmpty()) {
|
||||
|
@ -708,8 +717,8 @@ App::put('/v1/projects/:projectId/webhooks/:webhookId')
|
|||
$security = ($security === '1' || $security === 'true' || $security === 1 || $security === true);
|
||||
|
||||
$webhook = $dbForConsole->findOne('webhooks', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$webhookId]),
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
Query::equal('_uid', [$webhookId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($webhook === false || $webhook->isEmpty()) {
|
||||
|
@ -754,8 +763,8 @@ App::patch('/v1/projects/:projectId/webhooks/:webhookId/signature')
|
|||
}
|
||||
|
||||
$webhook = $dbForConsole->findOne('webhooks', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$webhookId]),
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
Query::equal('_uid', [$webhookId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($webhook === false || $webhook->isEmpty()) {
|
||||
|
@ -792,8 +801,8 @@ App::delete('/v1/projects/:projectId/webhooks/:webhookId')
|
|||
}
|
||||
|
||||
$webhook = $dbForConsole->findOne('webhooks', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$webhookId]),
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
Query::equal('_uid', [$webhookId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($webhook === false || $webhook->isEmpty()) {
|
||||
|
@ -875,8 +884,9 @@ App::get('/v1/projects/:projectId/keys')
|
|||
}
|
||||
|
||||
$keys = $dbForConsole->find('keys', [
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()]),
|
||||
], 5000);
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
Query::limit(5000),
|
||||
]);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'keys' => $keys,
|
||||
|
@ -907,8 +917,8 @@ App::get('/v1/projects/:projectId/keys/:keyId')
|
|||
}
|
||||
|
||||
$key = $dbForConsole->findOne('keys', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$keyId]),
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
Query::equal('_uid', [$keyId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($key === false || $key->isEmpty()) {
|
||||
|
@ -944,8 +954,8 @@ App::put('/v1/projects/:projectId/keys/:keyId')
|
|||
}
|
||||
|
||||
$key = $dbForConsole->findOne('keys', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$keyId]),
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
Query::equal('_uid', [$keyId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($key === false || $key->isEmpty()) {
|
||||
|
@ -987,8 +997,8 @@ App::delete('/v1/projects/:projectId/keys/:keyId')
|
|||
}
|
||||
|
||||
$key = $dbForConsole->findOne('keys', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$keyId]),
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
Query::equal('_uid', [$keyId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($key === false || $key->isEmpty()) {
|
||||
|
@ -1072,8 +1082,9 @@ App::get('/v1/projects/:projectId/platforms')
|
|||
}
|
||||
|
||||
$platforms = $dbForConsole->find('platforms', [
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
], 5000);
|
||||
Query::equal('projectId', [$project->getId()]),
|
||||
Query::limit(5000),
|
||||
]);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'platforms' => $platforms,
|
||||
|
@ -1104,8 +1115,8 @@ App::get('/v1/projects/:projectId/platforms/:platformId')
|
|||
}
|
||||
|
||||
$platform = $dbForConsole->findOne('platforms', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$platformId]),
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
Query::equal('_uid', [$platformId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($platform === false || $platform->isEmpty()) {
|
||||
|
@ -1141,8 +1152,8 @@ App::put('/v1/projects/:projectId/platforms/:platformId')
|
|||
}
|
||||
|
||||
$platform = $dbForConsole->findOne('platforms', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$platformId]),
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
Query::equal('_uid', [$platformId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($platform === false || $platform->isEmpty()) {
|
||||
|
@ -1185,8 +1196,8 @@ App::delete('/v1/projects/:projectId/platforms/:platformId')
|
|||
}
|
||||
|
||||
$platform = $dbForConsole->findOne('platforms', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$platformId]),
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
Query::equal('_uid', [$platformId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($platform === false || $platform->isEmpty()) {
|
||||
|
@ -1225,8 +1236,8 @@ App::post('/v1/projects/:projectId/domains')
|
|||
}
|
||||
|
||||
$document = $dbForConsole->findOne('domains', [
|
||||
new Query('domain', Query::TYPE_EQUAL, [$domain]),
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()]),
|
||||
Query::equal('domain', [$domain]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($document && !$document->isEmpty()) {
|
||||
|
@ -1285,8 +1296,9 @@ App::get('/v1/projects/:projectId/domains')
|
|||
}
|
||||
|
||||
$domains = $dbForConsole->find('domains', [
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
], 5000);
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
Query::limit(5000),
|
||||
]);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'domains' => $domains,
|
||||
|
@ -1317,8 +1329,8 @@ App::get('/v1/projects/:projectId/domains/:domainId')
|
|||
}
|
||||
|
||||
$domain = $dbForConsole->findOne('domains', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$domainId]),
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
Query::equal('_uid', [$domainId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($domain === false || $domain->isEmpty()) {
|
||||
|
@ -1351,8 +1363,8 @@ App::patch('/v1/projects/:projectId/domains/:domainId/verification')
|
|||
}
|
||||
|
||||
$domain = $dbForConsole->findOne('domains', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$domainId]),
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
Query::equal('_uid', [$domainId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($domain === false || $domain->isEmpty()) {
|
||||
|
@ -1411,8 +1423,8 @@ App::delete('/v1/projects/:projectId/domains/:domainId')
|
|||
}
|
||||
|
||||
$domain = $dbForConsole->findOne('domains', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$domainId]),
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
Query::equal('_uid', [$domainId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($domain === false || $domain->isEmpty()) {
|
||||
|
|
|
@ -158,27 +158,37 @@ App::get('/v1/storage/buckets')
|
|||
->param('offset', 0, new Range(0, APP_LIMIT_COUNT), 'Results offset. The default value is 0. Use this param to manage pagination.', true)
|
||||
->param('cursor', '', new UID(), 'ID of the bucket used as the starting point for the query, excluding the bucket itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor, can be either \'before\' or \'after\'.', true)
|
||||
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
|
||||
->param('orderType', Database::ORDER_ASC, new WhiteList([Database::ORDER_ASC, Database::ORDER_DESC], true), 'Order result by ' . Database::ORDER_ASC . ' or ' . Database::ORDER_DESC . ' order.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('usage')
|
||||
->action(function (string $search, int $limit, int $offset, string $cursor, string $cursorDirection, string $orderType, Response $response, Database $dbForProject, Stats $usage) {
|
||||
|
||||
$queries = ($search) ? [new Query('name', Query::TYPE_SEARCH, [$search])] : [];
|
||||
$filterQueries = [];
|
||||
|
||||
if (!empty($search)) {
|
||||
$filterQueries[] = Query::search('name', $search);
|
||||
}
|
||||
|
||||
$queries = [];
|
||||
$queries[] = Query::limit($limit);
|
||||
$queries[] = Query::offset($offset);
|
||||
$queries[] = $orderType === Database::ORDER_ASC ? Query::orderAsc('') : Query::orderDesc('');
|
||||
if (!empty($cursor)) {
|
||||
$cursorBucket = $dbForProject->getDocument('buckets', $cursor);
|
||||
$cursorDocument = $dbForProject->getDocument('buckets', $cursor);
|
||||
|
||||
if ($cursorBucket->isEmpty()) {
|
||||
if ($cursorDocument->isEmpty()) {
|
||||
throw new Exception("Bucket '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
|
||||
}
|
||||
|
||||
$queries[] = $cursorDirection === Database::CURSOR_AFTER ? Query::cursorAfter($cursorDocument) : Query::cursorBefore($cursorDocument);
|
||||
}
|
||||
|
||||
$usage->setParam('storage.buckets.read', 1);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'buckets' => $dbForProject->find('buckets', $queries, $limit, $offset, [], [$orderType], $cursorBucket ?? null, $cursorDirection),
|
||||
'total' => $dbForProject->count('buckets', $queries, APP_LIMIT_COUNT),
|
||||
'buckets' => $dbForProject->find('buckets', \array_merge($filterQueries, $queries)),
|
||||
'total' => $dbForProject->count('buckets', $filterQueries, APP_LIMIT_COUNT),
|
||||
]), Response::MODEL_BUCKET_LIST);
|
||||
});
|
||||
|
||||
|
@ -678,7 +688,7 @@ App::get('/v1/storage/buckets/:bucketId/files')
|
|||
->param('offset', 0, new Range(0, APP_LIMIT_COUNT), 'Offset value. The default value is 0. Use this param to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
|
||||
->param('cursor', '', new UID(), 'ID of the file used as the starting point for the query, excluding the file itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor, can be either \'before\' or \'after\'.', true)
|
||||
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
|
||||
->param('orderType', Database::ORDER_ASC, new WhiteList([Database::ORDER_ASC, Database::ORDER_DESC], true), 'Order result by ' . Database::ORDER_ASC . ' or ' . Database::ORDER_DESC . ' order.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('usage')
|
||||
|
@ -702,34 +712,36 @@ App::get('/v1/storage/buckets/:bucketId/files')
|
|||
}
|
||||
}
|
||||
|
||||
$queries = [new Query('bucketId', Query::TYPE_EQUAL, [$bucketId])];
|
||||
$filterQueries = [];
|
||||
|
||||
if ($search) {
|
||||
$queries[] = [new Query('name', Query::TYPE_SEARCH, [$search])];
|
||||
}
|
||||
|
||||
if (!empty($cursor)) {
|
||||
if ($bucket->getAttribute('permission') === 'bucket') {
|
||||
$cursorFile = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $cursor));
|
||||
} else {
|
||||
$cursorFile = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $cursor);
|
||||
}
|
||||
|
||||
if ($cursorFile->isEmpty()) {
|
||||
throw new Exception("File '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
|
||||
}
|
||||
if (!empty($search)) {
|
||||
$filterQueries[] = Query::search('name', $search);
|
||||
}
|
||||
|
||||
$queries = [];
|
||||
$queries[] = Query::limit($limit);
|
||||
$queries[] = Query::offset($offset);
|
||||
$queries[] = $orderType === Database::ORDER_ASC ? Query::orderAsc('') : Query::orderDesc('');
|
||||
if (!empty($cursor)) {
|
||||
if ($bucket->getAttribute('permission') === 'bucket') {
|
||||
$cursorDocument = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $cursor));
|
||||
} else {
|
||||
$cursorDocument = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $cursor);
|
||||
}
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);
|
||||
if ($cursorDocument->isEmpty()) {
|
||||
throw new Exception("File '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
|
||||
}
|
||||
|
||||
$queries[] = $cursorDirection === Database::CURSOR_AFTER ? Query::cursorAfter($cursorDocument) : Query::cursorBefore($cursorDocument);
|
||||
}
|
||||
|
||||
if ($bucket->getAttribute('permission') === 'bucket') {
|
||||
$files = Authorization::skip(fn () => $dbForProject->find('bucket_' . $bucket->getInternalId(), $queries, $limit, $offset, [], [$orderType], $cursorFile ?? null, $cursorDirection));
|
||||
$files = Authorization::skip(fn () => $dbForProject->find('bucket_' . $bucket->getInternalId(), \array_merge($filterQueries, $queries)));
|
||||
$total = Authorization::skip(fn () => $dbForProject->count('bucket_' . $bucket->getInternalId(), $filterQueries, APP_LIMIT_COUNT));
|
||||
} else {
|
||||
$files = $dbForProject->find('bucket_' . $bucket->getInternalId(), $queries, $limit, $offset, [], [$orderType], $cursorFile ?? null, $cursorDirection);
|
||||
$files = $dbForProject->find('bucket_' . $bucket->getInternalId(), \array_merge($filterQueries, $queries));
|
||||
$total = $dbForProject->count('bucket_' . $bucket->getInternalId(), $filterQueries, APP_LIMIT_COUNT);
|
||||
}
|
||||
|
||||
$usage
|
||||
|
@ -739,7 +751,7 @@ App::get('/v1/storage/buckets/:bucketId/files')
|
|||
|
||||
$response->dynamic(new Document([
|
||||
'files' => $files,
|
||||
'total' => $dbForProject->count('bucket_' . $bucket->getInternalId(), $queries, APP_LIMIT_COUNT),
|
||||
'total' => $total,
|
||||
]), Response::MODEL_FILE_LIST);
|
||||
});
|
||||
|
||||
|
@ -1526,9 +1538,11 @@ App::get('/v1/storage/usage')
|
|||
$period = $periods[$range]['period'];
|
||||
|
||||
$requestDocs = $dbForProject->find('stats', [
|
||||
new Query('period', Query::TYPE_EQUAL, [$period]),
|
||||
new Query('metric', Query::TYPE_EQUAL, [$metric]),
|
||||
], $limit, 0, ['time'], [Database::ORDER_DESC]);
|
||||
Query::equal('period', [$period]),
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::limit($limit),
|
||||
Query::orderDesc('time'),
|
||||
]);
|
||||
|
||||
$stats[$metric] = [];
|
||||
foreach ($requestDocs as $requestDoc) {
|
||||
|
@ -1635,9 +1649,11 @@ App::get('/v1/storage/:bucketId/usage')
|
|||
$limit = $periods[$range]['limit'];
|
||||
$period = $periods[$range]['period'];
|
||||
$requestDocs = $dbForProject->find('stats', [
|
||||
new Query('period', Query::TYPE_EQUAL, [$period]),
|
||||
new Query('metric', Query::TYPE_EQUAL, [$metric]),
|
||||
], $limit, 0, ['time'], [Database::ORDER_DESC]);
|
||||
Query::equal('period', [$period]),
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::limit($limit),
|
||||
Query::orderDesc('time'),
|
||||
]);
|
||||
|
||||
$stats[$metric] = [];
|
||||
foreach ($requestDocs as $requestDoc) {
|
||||
|
|
|
@ -127,22 +127,28 @@ App::get('/v1/teams')
|
|||
->inject('dbForProject')
|
||||
->action(function (string $search, int $limit, int $offset, string $cursor, string $cursorDirection, string $orderType, Response $response, Database $dbForProject) {
|
||||
|
||||
if (!empty($cursor)) {
|
||||
$cursorTeam = $dbForProject->getDocument('teams', $cursor);
|
||||
$filterQueries = [];
|
||||
|
||||
if ($cursorTeam->isEmpty()) {
|
||||
throw new Exception("Team '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
|
||||
}
|
||||
if (!empty($search)) {
|
||||
$filterQueries[] = Query::search('search', $search);
|
||||
}
|
||||
|
||||
$queries = [];
|
||||
$queries[] = Query::limit($limit);
|
||||
$queries[] = Query::offset($offset);
|
||||
$queries[] = $orderType === Database::ORDER_ASC ? Query::orderAsc('') : Query::orderDesc('');
|
||||
if (!empty($cursor)) {
|
||||
$cursorDocument = $dbForProject->getDocument('teams', $cursor);
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);
|
||||
if ($cursorDocument->isEmpty()) {
|
||||
throw new Exception("Team '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
|
||||
}
|
||||
|
||||
$queries[] = $cursorDirection === Database::CURSOR_AFTER ? Query::cursorAfter($cursorDocument) : Query::cursorBefore($cursorDocument);
|
||||
}
|
||||
|
||||
$results = $dbForProject->find('teams', $queries, $limit, $offset, [], [$orderType], $cursorTeam ?? null, $cursorDirection);
|
||||
$total = $dbForProject->count('teams', $queries, APP_LIMIT_COUNT);
|
||||
$results = $dbForProject->find('teams', \array_merge($filterQueries, $queries));
|
||||
$total = $dbForProject->count('teams', $filterQueries, APP_LIMIT_COUNT);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'teams' => $results,
|
||||
|
@ -237,8 +243,9 @@ App::delete('/v1/teams/:teamId')
|
|||
}
|
||||
|
||||
$memberships = $dbForProject->find('memberships', [
|
||||
new Query('teamId', Query::TYPE_EQUAL, [$teamId]),
|
||||
], 2000, 0); // TODO fix members limit
|
||||
Query::equal('teamId', [$teamId]),
|
||||
Query::limit(2000), // TODO fix members limit
|
||||
]);
|
||||
|
||||
// TODO delete all members individually from the user object
|
||||
foreach ($memberships as $membership) {
|
||||
|
@ -313,7 +320,7 @@ App::post('/v1/teams/:teamId/memberships')
|
|||
throw new Exception('Team not found', 404, Exception::TEAM_NOT_FOUND);
|
||||
}
|
||||
|
||||
$invitee = $dbForProject->findOne('users', [new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address
|
||||
$invitee = $dbForProject->findOne('users', [Query::equal('email', [$email])]); // Get user by email address
|
||||
|
||||
if (empty($invitee)) { // Create new user if no user with same email found
|
||||
$limit = $project->getAttribute('auths', [])['limit'] ?? 0;
|
||||
|
@ -452,7 +459,7 @@ App::get('/v1/teams/:teamId/memberships')
|
|||
->param('offset', 0, new Range(0, APP_LIMIT_COUNT), 'Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
|
||||
->param('cursor', '', new UID(), 'ID of the membership used as the starting point for the query, excluding the membership itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor, can be either \'before\' or \'after\'.', true)
|
||||
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
|
||||
->param('orderType', Database::ORDER_ASC, new WhiteList([Database::ORDER_ASC, Database::ORDER_DESC], true), 'Order result by ' . Database::ORDER_ASC . ' or ' . Database::ORDER_DESC . ' order.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->action(function (string $teamId, string $search, int $limit, int $offset, string $cursor, string $cursorDirection, string $orderType, Response $response, Database $dbForProject) {
|
||||
|
@ -463,33 +470,34 @@ App::get('/v1/teams/:teamId/memberships')
|
|||
throw new Exception('Team not found', 404, Exception::TEAM_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (!empty($cursor)) {
|
||||
$cursorMembership = $dbForProject->getDocument('memberships', $cursor);
|
||||
|
||||
if ($cursorMembership->isEmpty()) {
|
||||
throw new Exception("Membership '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
$queries = [new Query('teamId', Query::TYPE_EQUAL, [$teamId])];
|
||||
$filterQueries = [Query::equal('teamId', [$teamId])];
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);
|
||||
$filterQueries[] = Query::search('search', $search);
|
||||
}
|
||||
|
||||
$otherQueries = [];
|
||||
$otherQueries[] = Query::limit($limit);
|
||||
$otherQueries[] = Query::offset($offset);
|
||||
$otherQueries[] = $orderType === Database::ORDER_ASC ? Query::orderAsc('') : Query::orderDesc('');
|
||||
if (!empty($cursor)) {
|
||||
$cursorDocument = $dbForProject->getDocument('memberships', $cursor);
|
||||
|
||||
if ($cursorDocument->isEmpty()) {
|
||||
throw new Exception("Membership '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
|
||||
}
|
||||
|
||||
$otherQueries[] = $cursorDirection === Database::CURSOR_AFTER ? Query::cursorAfter($cursorDocument) : Query::cursorBefore($cursorDocument);
|
||||
}
|
||||
|
||||
$memberships = $dbForProject->find(
|
||||
collection: 'memberships',
|
||||
queries: $queries,
|
||||
limit: $limit,
|
||||
offset: $offset,
|
||||
orderTypes: [$orderType],
|
||||
cursor: $cursorMembership ?? null,
|
||||
cursorDirection: $cursorDirection
|
||||
queries: \array_merge($filterQueries, $otherQueries),
|
||||
);
|
||||
|
||||
$total = $dbForProject->count(
|
||||
collection:'memberships',
|
||||
queries: $queries,
|
||||
collection: 'memberships',
|
||||
queries: $filterQueries,
|
||||
max: APP_LIMIT_COUNT
|
||||
);
|
||||
|
||||
|
|
|
@ -106,24 +106,30 @@ App::get('/v1/users')
|
|||
->param('offset', 0, new Range(0, APP_LIMIT_COUNT), 'Offset value. The default value is 0. Use this param to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
|
||||
->param('cursor', '', new UID(), 'ID of the user used as the starting point for the query, excluding the user itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor, can be either \'before\' or \'after\'.', true)
|
||||
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
|
||||
->param('orderType', Database::ORDER_ASC, new WhiteList([Database::ORDER_ASC, Database::ORDER_DESC], true), 'Order result by ASC or DESC order.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('usage')
|
||||
->action(function (string $search, int $limit, int $offset, string $cursor, string $cursorDirection, string $orderType, Response $response, Database $dbForProject, Stats $usage) {
|
||||
|
||||
if (!empty($cursor)) {
|
||||
$cursorUser = $dbForProject->getDocument('users', $cursor);
|
||||
$filterQueries = [];
|
||||
|
||||
if ($cursorUser->isEmpty()) {
|
||||
throw new Exception("User '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
|
||||
}
|
||||
if (!empty($search)) {
|
||||
$filterQueries[] = Query::search('search', $search);
|
||||
}
|
||||
|
||||
$queries = [];
|
||||
$queries[] = Query::limit($limit);
|
||||
$queries[] = Query::offset($offset);
|
||||
$queries[] = $orderType === Database::ORDER_ASC ? Query::orderAsc('') : Query::orderDesc('');
|
||||
if (!empty($cursor)) {
|
||||
$cursorDocument = $dbForProject->getDocument('users', $cursor);
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);
|
||||
if ($cursorDocument->isEmpty()) {
|
||||
throw new Exception("User '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
|
||||
}
|
||||
|
||||
$queries[] = $cursorDirection === Database::CURSOR_AFTER ? Query::cursorAfter($cursorDocument) : Query::cursorBefore($cursorDocument);
|
||||
}
|
||||
|
||||
$usage
|
||||
|
@ -131,8 +137,8 @@ App::get('/v1/users')
|
|||
;
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'users' => $dbForProject->find('users', $queries, $limit, $offset, [], [$orderType], $cursorUser ?? null, $cursorDirection),
|
||||
'total' => $dbForProject->count('users', $queries, APP_LIMIT_COUNT),
|
||||
'users' => $dbForProject->find('users', \array_merge($filterQueries, $queries)),
|
||||
'total' => $dbForProject->count('users', $filterQueries, APP_LIMIT_COUNT),
|
||||
]), Response::MODEL_USER_LIST);
|
||||
});
|
||||
|
||||
|
@ -905,9 +911,11 @@ App::get('/v1/users/usage')
|
|||
$period = $periods[$range]['period'];
|
||||
|
||||
$requestDocs = $dbForProject->find('stats', [
|
||||
new Query('period', Query::TYPE_EQUAL, [$period]),
|
||||
new Query('metric', Query::TYPE_EQUAL, [$metric]),
|
||||
], $limit, 0, ['time'], [Database::ORDER_DESC]);
|
||||
Query::equal('period', [$period]),
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::limit($limit),
|
||||
Query::orderDesc('time'),
|
||||
]);
|
||||
|
||||
$stats[$metric] = [];
|
||||
foreach ($requestDocs as $requestDoc) {
|
||||
|
|
|
@ -22,8 +22,8 @@ use Appwrite\Utopia\Response\Filters\V13 as ResponseV13;
|
|||
use Appwrite\Utopia\Response\Filters\V14 as ResponseV14;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\DateTime;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Validator\Hostname;
|
||||
|
@ -90,7 +90,7 @@ App::init()
|
|||
if (!empty($envDomain) && $envDomain !== 'localhost') {
|
||||
$mainDomain = $envDomain;
|
||||
} else {
|
||||
$domainDocument = $dbForConsole->findOne('domains', [], 0, ['_id'], ['ASC']);
|
||||
$domainDocument = $dbForConsole->findOne('domains', [Query::orderAsc('_id')]);
|
||||
$mainDomain = $domainDocument ? $domainDocument->getAttribute('domain') : $domain->get();
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ App::init()
|
|||
Console::warning($domain->get() . ' is not a main domain. Skipping SSL certificate generation.');
|
||||
} else {
|
||||
$domainDocument = $dbForConsole->findOne('domains', [
|
||||
new Query('domain', QUERY::TYPE_EQUAL, [$domain->get()])
|
||||
Query::equal('domain', [$domain->get()])
|
||||
]);
|
||||
|
||||
if (!$domainDocument) {
|
||||
|
@ -173,42 +173,42 @@ App::init()
|
|||
? null
|
||||
: '.' . $request->getHostname());
|
||||
|
||||
/*
|
||||
* Response format
|
||||
*/
|
||||
$responseFormat = $request->getHeader('x-appwrite-response-format', App::getEnv('_APP_SYSTEM_RESPONSE_FORMAT', ''));
|
||||
if ($responseFormat) {
|
||||
switch ($responseFormat) {
|
||||
case version_compare($responseFormat, '0.11.2', '<='):
|
||||
Response::setFilter(new ResponseV11());
|
||||
break;
|
||||
case version_compare($responseFormat, '0.12.4', '<='):
|
||||
Response::setFilter(new ResponseV12());
|
||||
break;
|
||||
case version_compare($responseFormat, '0.13.4', '<='):
|
||||
Response::setFilter(new ResponseV13());
|
||||
break;
|
||||
case version_compare($responseFormat, '0.14.0', '<='):
|
||||
Response::setFilter(new ResponseV14());
|
||||
break;
|
||||
default:
|
||||
Response::setFilter(null);
|
||||
}
|
||||
} else {
|
||||
Response::setFilter(null);
|
||||
}
|
||||
|
||||
/*
|
||||
* Security Headers
|
||||
*
|
||||
* As recommended at:
|
||||
* @see https://www.owasp.org/index.php/List_of_useful_HTTP_headers
|
||||
*/
|
||||
if (App::getEnv('_APP_OPTIONS_FORCE_HTTPS', 'disabled') === 'enabled') { // Force HTTPS
|
||||
if ($request->getProtocol() !== 'https') {
|
||||
if ($request->getMethod() !== Request::METHOD_GET) {
|
||||
throw new AppwriteException('Method unsupported over HTTP.', 500, AppwriteException::GENERAL_PROTOCOL_UNSUPPORTED);
|
||||
/*
|
||||
* Response format
|
||||
*/
|
||||
$responseFormat = $request->getHeader('x-appwrite-response-format', App::getEnv('_APP_SYSTEM_RESPONSE_FORMAT', ''));
|
||||
if ($responseFormat) {
|
||||
switch ($responseFormat) {
|
||||
case version_compare($responseFormat, '0.11.2', '<='):
|
||||
Response::setFilter(new ResponseV11());
|
||||
break;
|
||||
case version_compare($responseFormat, '0.12.4', '<='):
|
||||
Response::setFilter(new ResponseV12());
|
||||
break;
|
||||
case version_compare($responseFormat, '0.13.4', '<='):
|
||||
Response::setFilter(new ResponseV13());
|
||||
break;
|
||||
case version_compare($responseFormat, '0.14.0', '<='):
|
||||
Response::setFilter(new ResponseV14());
|
||||
break;
|
||||
default:
|
||||
Response::setFilter(null);
|
||||
}
|
||||
} else {
|
||||
Response::setFilter(null);
|
||||
}
|
||||
|
||||
/*
|
||||
* Security Headers
|
||||
*
|
||||
* As recommended at:
|
||||
* @see https://www.owasp.org/index.php/List_of_useful_HTTP_headers
|
||||
*/
|
||||
if (App::getEnv('_APP_OPTIONS_FORCE_HTTPS', 'disabled') === 'enabled') { // Force HTTPS
|
||||
if ($request->getProtocol() !== 'https') {
|
||||
if ($request->getMethod() !== Request::METHOD_GET) {
|
||||
throw new AppwriteException('Method unsupported over HTTP.', 500, AppwriteException::GENERAL_PROTOCOL_UNSUPPORTED);
|
||||
}
|
||||
|
||||
return $response->redirect('https://' . $request->getHostname() . $request->getURI());
|
||||
}
|
||||
|
|
|
@ -45,20 +45,20 @@ App::init()
|
|||
/*
|
||||
* Abuse Check
|
||||
*/
|
||||
$abuseKeyLabel = $route->getLabel('abuse-key', 'url:{url},ip:{ip}');
|
||||
$timeLimitArray = [];
|
||||
$abuseKeyLabel = $route->getLabel('abuse-key', 'url:{url},ip:{ip}');
|
||||
$timeLimitArray = [];
|
||||
|
||||
$abuseKeyLabel = (!is_array($abuseKeyLabel)) ? [$abuseKeyLabel] : $abuseKeyLabel;
|
||||
|
||||
foreach ($abuseKeyLabel as $abuseKey) {
|
||||
$timeLimit = new TimeLimit($abuseKey, $route->getLabel('abuse-limit', 0), $route->getLabel('abuse-time', 3600), $dbForProject);
|
||||
$timeLimit
|
||||
foreach ($abuseKeyLabel as $abuseKey) {
|
||||
$timeLimit = new TimeLimit($abuseKey, $route->getLabel('abuse-limit', 0), $route->getLabel('abuse-time', 3600), $dbForProject);
|
||||
$timeLimit
|
||||
->setParam('{userId}', $user->getId())
|
||||
->setParam('{userAgent}', $request->getUserAgent(''))
|
||||
->setParam('{ip}', $request->getIP())
|
||||
->setParam('{url}', $request->getHostname() . $route->getPath());
|
||||
$timeLimitArray[] = $timeLimit;
|
||||
}
|
||||
$timeLimitArray[] = $timeLimit;
|
||||
}
|
||||
|
||||
$closestLimit = null;
|
||||
|
||||
|
@ -99,11 +99,11 @@ App::init()
|
|||
/*
|
||||
* Background Jobs
|
||||
*/
|
||||
$events
|
||||
$events
|
||||
->setEvent($route->getLabel('event', ''))
|
||||
->setProject($project)
|
||||
->setUser($user)
|
||||
;
|
||||
;
|
||||
|
||||
$mails
|
||||
->setProject($project)
|
||||
|
@ -184,7 +184,7 @@ App::init()
|
|||
|
||||
default:
|
||||
throw new Exception('Unsupported authentication route', 501, Exception::USER_AUTH_METHOD_UNSUPPORTED);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
App::shutdown()
|
||||
|
|
49
app/init.php
49
app/init.php
|
@ -268,9 +268,10 @@ Database::addFilter(
|
|||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('attributes', [
|
||||
new Query('collectionInternalId', Query::TYPE_EQUAL, [$document->getInternalId()]),
|
||||
new Query('databaseInternalId', Query::TYPE_EQUAL, [$document->getAttribute('databaseInternalId')])
|
||||
], $database->getAttributeLimit(), 0, []);
|
||||
Query::equal('collectionInternalId', [$document->getInternalId()]),
|
||||
Query::equal('databaseInternalId', [$document->getAttribute('databaseInternalId')]),
|
||||
Query::limit($database->getAttributeLimit()),
|
||||
]);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -282,9 +283,10 @@ Database::addFilter(
|
|||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('indexes', [
|
||||
new Query('collectionInternalId', Query::TYPE_EQUAL, [$document->getInternalId()]),
|
||||
new Query('databaseInternalId', Query::TYPE_EQUAL, [$document->getAttribute('databaseInternalId')])
|
||||
], 64);
|
||||
Query::equal('collectionInternalId', [$document->getInternalId()]),
|
||||
Query::equal('databaseInternalId', [$document->getAttribute('databaseInternalId')]),
|
||||
Query::limit(64),
|
||||
]);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -296,8 +298,9 @@ Database::addFilter(
|
|||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('platforms', [
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$document->getInternalId()])
|
||||
], APP_LIMIT_SUBQUERY);
|
||||
Query::equal('projectInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -309,8 +312,9 @@ Database::addFilter(
|
|||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('domains', [
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$document->getInternalId()])
|
||||
], APP_LIMIT_SUBQUERY);
|
||||
Query::equal('projectInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -322,8 +326,9 @@ Database::addFilter(
|
|||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('keys', [
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$document->getInternalId()])
|
||||
], APP_LIMIT_SUBQUERY);
|
||||
Query::equal('projectInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -335,8 +340,9 @@ Database::addFilter(
|
|||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('webhooks', [
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$document->getInternalId()])
|
||||
], APP_LIMIT_SUBQUERY);
|
||||
Query::equal('projectInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -347,8 +353,9 @@ Database::addFilter(
|
|||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return Authorization::skip(fn () => $database->find('sessions', [
|
||||
new Query('userInternalId', Query::TYPE_EQUAL, [$document->getInternalId()])
|
||||
], APP_LIMIT_SUBQUERY));
|
||||
Query::equal('userInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]));
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -360,8 +367,9 @@ Database::addFilter(
|
|||
function (mixed $value, Document $document, Database $database) {
|
||||
return Authorization::skip(fn() => $database
|
||||
->find('tokens', [
|
||||
new Query('userInternalId', Query::TYPE_EQUAL, [$document->getInternalId()])
|
||||
], APP_LIMIT_SUBQUERY));
|
||||
Query::equal('userInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]));
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -373,8 +381,9 @@ Database::addFilter(
|
|||
function (mixed $value, Document $document, Database $database) {
|
||||
return Authorization::skip(fn() => $database
|
||||
->find('memberships', [
|
||||
new Query('userInternalId', Query::TYPE_EQUAL, [$document->getInternalId()])
|
||||
], APP_LIMIT_SUBQUERY));
|
||||
Query::equal('userInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]));
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -209,7 +209,7 @@ $server->onWorkerStart(function (int $workerId) use ($server, $register, $stats,
|
|||
$payload = [];
|
||||
|
||||
$list = Authorization::skip(fn () => $database->find('realtime', [
|
||||
new Query('timestamp', Query::TYPE_GREATER, [DateTime::addSeconds(new \DateTime(), -15)])
|
||||
Query::greaterThan('timestamp', DateTime::addSeconds(new \DateTime(), -15)),
|
||||
]));
|
||||
|
||||
/**
|
||||
|
|
|
@ -108,8 +108,8 @@ $cli
|
|||
$time = DateTime::now();
|
||||
|
||||
$certificates = $dbForConsole->find('certificates', [
|
||||
new Query('attempts', Query::TYPE_LESSEREQUAL, [5]), // Maximum 5 attempts
|
||||
new Query('renewDate', Query::TYPE_LESSEREQUAL, [$time]) // includes 60 days cooldown (we have 30 days to renew)
|
||||
Query::lessThanEqual('attempts', 5), // Maximum 5 attempts
|
||||
Query::lessThanEqual('renewDate', $time) // includes 60 days cooldown (we have 30 days to renew)
|
||||
], 200); // Limit 200 comes from LetsEncrypt (300 orders per 3 hours, keeping some for new domains)
|
||||
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ use Utopia\Cache\Cache;
|
|||
use Utopia\Cache\Adapter\Redis as RedisCache;
|
||||
use Utopia\Database\Adapter\MariaDB;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Validator\Text;
|
||||
|
||||
|
@ -70,7 +71,7 @@ $cli
|
|||
}
|
||||
|
||||
$sum = \count($projects);
|
||||
$projects = $consoleDB->find('projects', limit: $limit, offset: $offset);
|
||||
$projects = $consoleDB->find('projects', [Query::limit($limit), Query::offset($offset)]);
|
||||
|
||||
$offset = $offset + $limit;
|
||||
$count = $count + $sum;
|
||||
|
|
|
@ -73,7 +73,7 @@ class CertificatesV1 extends Worker
|
|||
$domain = new Domain($document->getAttribute('domain', ''));
|
||||
|
||||
// Get current certificate
|
||||
$certificate = $this->dbForConsole->findOne('certificates', [new Query('domain', Query::TYPE_EQUAL, [$domain->get()])]);
|
||||
$certificate = $this->dbForConsole->findOne('certificates', [Query::equal('domain', [$domain->get()])]);
|
||||
|
||||
// If we don't have certificate for domain yet, let's create new document. At the end we save it
|
||||
if (!$certificate) {
|
||||
|
@ -151,7 +151,7 @@ class CertificatesV1 extends Worker
|
|||
private function saveCertificateDocument(string $domain, Document $certificate): void
|
||||
{
|
||||
// Check if update or insert required
|
||||
$certificateDocument = $this->dbForConsole->findOne('certificates', [new Query('domain', Query::TYPE_EQUAL, [$domain])]);
|
||||
$certificateDocument = $this->dbForConsole->findOne('certificates', [Query::equal('domain', [$domain])]);
|
||||
if (!empty($certificateDocument) && !$certificateDocument->isEmpty()) {
|
||||
// Merge new data with current data
|
||||
$certificate = new Document(\array_merge($certificateDocument->getArrayCopy(), $certificate->getArrayCopy()));
|
||||
|
@ -176,7 +176,7 @@ class CertificatesV1 extends Worker
|
|||
if (!empty($envDomain) && $envDomain !== 'localhost') {
|
||||
return $envDomain;
|
||||
} else {
|
||||
$domainDocument = $this->dbForConsole->findOne('domains', [], 0, ['_id'], ['ASC']);
|
||||
$domainDocument = $this->dbForConsole->findOne('domains', [Query::orderAsc('_id')]);
|
||||
if ($domainDocument) {
|
||||
return $domainDocument->getAttribute('domain');
|
||||
}
|
||||
|
@ -394,8 +394,9 @@ class CertificatesV1 extends Worker
|
|||
private function updateDomainDocuments(string $certificateId, string $domain): void
|
||||
{
|
||||
$domains = $this->dbForConsole->find('domains', [
|
||||
new Query('domain', Query::TYPE_EQUAL, [$domain])
|
||||
], 1000);
|
||||
Query::equal('domain', [$domain]),
|
||||
Query::limit(1000),
|
||||
]);
|
||||
|
||||
foreach ($domains as $domainDocument) {
|
||||
$domainDocument->setAttribute('updated', DateTime::now());
|
||||
|
|
|
@ -149,11 +149,11 @@ class DeletesV1 extends Worker
|
|||
$dbForProject->deleteCollection('database_' . $databaseId . '_collection_' . $document->getInternalId());
|
||||
|
||||
$this->deleteByGroup('attributes', [
|
||||
new Query('collectionId', Query::TYPE_EQUAL, [$collectionId])
|
||||
Query::equal('collectionId', [$collectionId])
|
||||
], $dbForProject);
|
||||
|
||||
$this->deleteByGroup('indexes', [
|
||||
new Query('collectionId', Query::TYPE_EQUAL, [$collectionId])
|
||||
Query::equal('collectionId', [$collectionId])
|
||||
], $dbForProject);
|
||||
|
||||
$this->deleteAuditLogsByResource('collection/' . $collectionId, $projectId);
|
||||
|
@ -169,13 +169,13 @@ class DeletesV1 extends Worker
|
|||
$dbForProject = $this->getProjectDB($projectId);
|
||||
// Delete Usage stats
|
||||
$this->deleteByGroup('stats', [
|
||||
new Query('time', Query::TYPE_LESSER, [$datetime1d]),
|
||||
new Query('period', Query::TYPE_EQUAL, ['1d']),
|
||||
Query::lessThan('time', $datetime1d),
|
||||
Query::equal('period', ['1d']),
|
||||
], $dbForProject);
|
||||
|
||||
$this->deleteByGroup('stats', [
|
||||
new Query('time', Query::TYPE_LESSER, [$datetime30m]),
|
||||
new Query('period', Query::TYPE_EQUAL, ['30m']),
|
||||
Query::lessThan('time', [$datetime30m]),
|
||||
Query::equal('period', ['30m']),
|
||||
], $dbForProject);
|
||||
});
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ class DeletesV1 extends Worker
|
|||
|
||||
// Delete Memberships
|
||||
$this->deleteByGroup('memberships', [
|
||||
new Query('teamId', Query::TYPE_EQUAL, [$teamId])
|
||||
Query::equal('teamId', [$teamId])
|
||||
], $this->getProjectDB($projectId));
|
||||
}
|
||||
|
||||
|
@ -222,14 +222,14 @@ class DeletesV1 extends Worker
|
|||
|
||||
// Delete all sessions of this user from the sessions table and update the sessions field of the user record
|
||||
$this->deleteByGroup('sessions', [
|
||||
new Query('userId', Query::TYPE_EQUAL, [$userId])
|
||||
Query::equal('userId', [$userId])
|
||||
], $this->getProjectDB($projectId));
|
||||
|
||||
$this->getProjectDB($projectId)->deleteCachedDocument('users', $userId);
|
||||
|
||||
// Delete Memberships and decrement team membership counts
|
||||
$this->deleteByGroup('memberships', [
|
||||
new Query('userId', Query::TYPE_EQUAL, [$userId])
|
||||
Query::equal('userId', [$userId])
|
||||
], $this->getProjectDB($projectId), function (Document $document) use ($projectId) {
|
||||
|
||||
if ($document->getAttribute('confirm')) { // Count only confirmed members
|
||||
|
@ -250,7 +250,7 @@ class DeletesV1 extends Worker
|
|||
|
||||
// Delete tokens
|
||||
$this->deleteByGroup('tokens', [
|
||||
new Query('userId', Query::TYPE_EQUAL, [$userId])
|
||||
Query::equal('userId', [$userId])
|
||||
], $this->getProjectDB($projectId));
|
||||
}
|
||||
|
||||
|
@ -263,7 +263,7 @@ class DeletesV1 extends Worker
|
|||
$dbForProject = $this->getProjectDB($projectId);
|
||||
// Delete Executions
|
||||
$this->deleteByGroup('executions', [
|
||||
new Query('$createdAt', Query::TYPE_LESSER, [$datetime])
|
||||
Query::lessThan('$createdAt', $datetime)
|
||||
], $dbForProject);
|
||||
});
|
||||
}
|
||||
|
@ -277,7 +277,7 @@ class DeletesV1 extends Worker
|
|||
$dbForProject = $this->getProjectDB($projectId);
|
||||
// Delete Sessions
|
||||
$this->deleteByGroup('sessions', [
|
||||
new Query('expire', Query::TYPE_LESSER, [$datetime])
|
||||
Query::lessThan('expire', $datetime)
|
||||
], $dbForProject);
|
||||
});
|
||||
}
|
||||
|
@ -291,7 +291,7 @@ class DeletesV1 extends Worker
|
|||
$dbForProject = $this->getProjectDB($projectId);
|
||||
// Delete Dead Realtime Logs
|
||||
$this->deleteByGroup('realtime', [
|
||||
new Query('timestamp', Query::TYPE_LESSER, [$datetime])
|
||||
Query::lessThan('timestamp', $datetime)
|
||||
], $dbForProject);
|
||||
});
|
||||
}
|
||||
|
@ -346,7 +346,7 @@ class DeletesV1 extends Worker
|
|||
$dbForProject = $this->getProjectDB($projectId);
|
||||
|
||||
$this->deleteByGroup(Audit::COLLECTION, [
|
||||
new Query('resource', Query::TYPE_EQUAL, [$resource])
|
||||
Query::equal('resource', [$resource])
|
||||
], $dbForProject);
|
||||
}
|
||||
|
||||
|
@ -366,7 +366,7 @@ class DeletesV1 extends Worker
|
|||
$storageFunctions = new Local(APP_STORAGE_FUNCTIONS . '/app-' . $projectId);
|
||||
$deploymentIds = [];
|
||||
$this->deleteByGroup('deployments', [
|
||||
new Query('resourceId', Query::TYPE_EQUAL, [$functionId])
|
||||
Query::equal('resourceId', [$functionId])
|
||||
], $dbForProject, function (Document $document) use ($storageFunctions, &$deploymentIds) {
|
||||
$deploymentIds[] = $document->getId();
|
||||
if ($storageFunctions->delete($document->getAttribute('path', ''), true)) {
|
||||
|
@ -383,7 +383,7 @@ class DeletesV1 extends Worker
|
|||
$storageBuilds = new Local(APP_STORAGE_BUILDS . '/app-' . $projectId);
|
||||
foreach ($deploymentIds as $deploymentId) {
|
||||
$this->deleteByGroup('builds', [
|
||||
new Query('deploymentId', Query::TYPE_EQUAL, [$deploymentId])
|
||||
Query::equal('deploymentId', [$deploymentId])
|
||||
], $dbForProject, function (Document $document) use ($storageBuilds, $deploymentId) {
|
||||
if ($storageBuilds->delete($document->getAttribute('outputPath', ''), true)) {
|
||||
Console::success('Deleted build files: ' . $document->getAttribute('outputPath', ''));
|
||||
|
@ -398,7 +398,7 @@ class DeletesV1 extends Worker
|
|||
*/
|
||||
Console::info("Deleting executions for function " . $functionId);
|
||||
$this->deleteByGroup('executions', [
|
||||
new Query('functionId', Query::TYPE_EQUAL, [$functionId])
|
||||
Query::equal('functionId', [$functionId])
|
||||
], $dbForProject);
|
||||
|
||||
/**
|
||||
|
@ -442,7 +442,7 @@ class DeletesV1 extends Worker
|
|||
Console::info("Deleting builds for deployment " . $deploymentId);
|
||||
$storageBuilds = new Local(APP_STORAGE_BUILDS . '/app-' . $projectId);
|
||||
$this->deleteByGroup('builds', [
|
||||
new Query('deploymentId', Query::TYPE_EQUAL, [$deploymentId])
|
||||
Query::equal('deploymentId', [$deploymentId])
|
||||
], $dbForProject, function (Document $document) use ($storageBuilds) {
|
||||
if ($storageBuilds->delete($document->getAttribute('outputPath', ''), true)) {
|
||||
Console::success('Deleted build files: ' . $document->getAttribute('outputPath', ''));
|
||||
|
@ -501,7 +501,7 @@ class DeletesV1 extends Worker
|
|||
$executionStart = \microtime(true);
|
||||
|
||||
while ($sum === $limit) {
|
||||
$projects = $this->getConsoleDB()->find('projects', [], $limit, ($chunk * $limit));
|
||||
$projects = $this->getConsoleDB()->find('projects', [Query::limit($limit), Query::offset($chunk * $limit)]);
|
||||
|
||||
$chunk++;
|
||||
|
||||
|
@ -540,7 +540,7 @@ class DeletesV1 extends Worker
|
|||
while ($sum === $limit) {
|
||||
$chunk++;
|
||||
|
||||
$results = $database->find($collection, $queries, $limit, 0);
|
||||
$results = $database->find($collection, \array_merge([Query::limit($limit)], $queries));
|
||||
|
||||
$sum = count($results);
|
||||
|
||||
|
@ -567,7 +567,7 @@ class DeletesV1 extends Worker
|
|||
// If domain has certificate generated
|
||||
if (isset($document['certificateId'])) {
|
||||
$domainUsingCertificate = $consoleDB->findOne('domains', [
|
||||
new Query('certificateId', Query::TYPE_EQUAL, [$document['certificateId']])
|
||||
Query::equal('certificateId', [$document['certificateId']])
|
||||
]);
|
||||
|
||||
if (!$domainUsingCertificate) {
|
||||
|
|
|
@ -14,6 +14,7 @@ use Utopia\Config\Config;
|
|||
use Utopia\Database\Database;
|
||||
use Utopia\Database\DateTime;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Query;
|
||||
|
||||
require_once __DIR__ . '/../init.php';
|
||||
|
||||
|
@ -61,7 +62,11 @@ class FunctionsV1 extends Worker
|
|||
/** @var Document[] $functions */
|
||||
|
||||
while ($sum >= $limit) {
|
||||
$functions = $database->find('functions', [], $limit, $offset, ['name'], [Database::ORDER_ASC]);
|
||||
$functions = $database->find('functions', [
|
||||
Query::limit($limit),
|
||||
Query::offset($offset),
|
||||
Query::orderAsc('name'),
|
||||
]);
|
||||
$sum = \count($functions);
|
||||
$offset = $offset + $limit;
|
||||
|
||||
|
|
|
@ -44,13 +44,13 @@
|
|||
"appwrite/php-runtimes": "0.10.*",
|
||||
"utopia-php/framework": "0.20.*",
|
||||
"utopia-php/logger": "0.3.*",
|
||||
"utopia-php/abuse": "dev-origin/timestamp-to-datetime as 0.7.2",
|
||||
"utopia-php/abuse": "dev-feat-update-database-queries",
|
||||
"utopia-php/analytics": "0.2.*",
|
||||
"utopia-php/audit": "dev-origin/unix-to-datetime as 0.8.2",
|
||||
"utopia-php/audit": "dev-feat-update-database-queries",
|
||||
"utopia-php/cache": "0.6.*",
|
||||
"utopia-php/cli": "0.13.*",
|
||||
"utopia-php/config": "0.2.*",
|
||||
"utopia-php/database": "0.19.*",
|
||||
"utopia-php/database": "dev-feat-query-gen-2.3",
|
||||
"utopia-php/locale": "0.4.*",
|
||||
"utopia-php/registry": "0.5.*",
|
||||
"utopia-php/preloader": "0.2.*",
|
||||
|
@ -73,6 +73,18 @@
|
|||
{
|
||||
"url": "https://github.com/appwrite/runtimes.git",
|
||||
"type": "git"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/utopia-php/database.git",
|
||||
"type": "git"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/utopia-php/abuse.git",
|
||||
"type": "git"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/utopia-php/audit.git",
|
||||
"type": "git"
|
||||
}
|
||||
],
|
||||
"require-dev": {
|
||||
|
@ -90,4 +102,4 @@
|
|||
"php": "8.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
72
composer.lock
generated
72
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "993486075710ab0cdbba6c33f0b09218",
|
||||
"content-hash": "31918539abb7d1e82ca84ed8fc21969e",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
|
@ -1733,22 +1733,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/abuse",
|
||||
"version": "0.7.0",
|
||||
"version": "dev-feat-update-database-queries",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/abuse.git",
|
||||
"reference": "52fb20e39e2e9619948bc0a73b52e10caa71350d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/52fb20e39e2e9619948bc0a73b52e10caa71350d",
|
||||
"reference": "52fb20e39e2e9619948bc0a73b52e10caa71350d",
|
||||
"shasum": ""
|
||||
"reference": "5c200defd69155c956fc127e8e1771ef820f9dad"
|
||||
},
|
||||
"require": {
|
||||
"ext-pdo": "*",
|
||||
"php": ">=8.0",
|
||||
"utopia-php/database": ">=0.11 <1.0"
|
||||
"utopia-php/database": "dev-feat-query-gen-2.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.4",
|
||||
|
@ -1760,7 +1754,6 @@
|
|||
"Utopia\\Abuse\\": "src/Abuse"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
|
@ -1772,17 +1765,13 @@
|
|||
],
|
||||
"description": "A simple abuse library to manage application usage limits",
|
||||
"keywords": [
|
||||
"Abuse",
|
||||
"abuse",
|
||||
"framework",
|
||||
"php",
|
||||
"upf",
|
||||
"utopia"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/abuse/issues",
|
||||
"source": "https://github.com/utopia-php/abuse/tree/0.7.0"
|
||||
},
|
||||
"time": "2021-12-27T13:06:45+00:00"
|
||||
"time": "2022-08-10T19:51:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/analytics",
|
||||
|
@ -1841,22 +1830,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/audit",
|
||||
"version": "0.8.0",
|
||||
"version": "dev-feat-update-database-queries",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/audit.git",
|
||||
"reference": "b46dc42614a69437c45eb229249b6a6d000122c1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/audit/zipball/b46dc42614a69437c45eb229249b6a6d000122c1",
|
||||
"reference": "b46dc42614a69437c45eb229249b6a6d000122c1",
|
||||
"shasum": ""
|
||||
"reference": "165d4f74fedf31c98c038eb92a0516472885a78a"
|
||||
},
|
||||
"require": {
|
||||
"ext-pdo": "*",
|
||||
"php": ">=8.0",
|
||||
"utopia-php/database": ">=0.11 <1.0"
|
||||
"utopia-php/database": "dev-feat-query-gen-2.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.3",
|
||||
|
@ -1868,7 +1851,6 @@
|
|||
"Utopia\\Audit\\": "src/Audit"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
|
@ -1880,17 +1862,13 @@
|
|||
],
|
||||
"description": "A simple audit library to manage application users logs",
|
||||
"keywords": [
|
||||
"Audit",
|
||||
"audit",
|
||||
"framework",
|
||||
"php",
|
||||
"upf",
|
||||
"utopia"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/audit/issues",
|
||||
"source": "https://github.com/utopia-php/audit/tree/0.8.0"
|
||||
},
|
||||
"time": "2021-12-27T13:05:56+00:00"
|
||||
"time": "2022-08-10T20:15:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/cache",
|
||||
|
@ -2051,17 +2029,11 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/database",
|
||||
"version": "0.18.9",
|
||||
"version": "dev-feat-query-gen-2.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/database.git",
|
||||
"reference": "227b3ca919149b7b0d6556c8effe9ee46ed081e6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/227b3ca919149b7b0d6556c8effe9ee46ed081e6",
|
||||
"reference": "227b3ca919149b7b0d6556c8effe9ee46ed081e6",
|
||||
"shasum": ""
|
||||
"reference": "d6ba28d373e2cad2fc5d916564fd245e17bea38f"
|
||||
},
|
||||
"require": {
|
||||
"ext-mongodb": "*",
|
||||
|
@ -2085,7 +2057,11 @@
|
|||
"Utopia\\Database\\": "src/Database"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Utopia\\Tests\\": "tests/Database"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
|
@ -2107,11 +2083,7 @@
|
|||
"upf",
|
||||
"utopia"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/database/issues",
|
||||
"source": "https://github.com/utopia-php/database/tree/0.18.9"
|
||||
},
|
||||
"time": "2022-07-19T09:42:53+00:00"
|
||||
"time": "2022-08-11T19:26:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/domains",
|
||||
|
@ -5348,7 +5320,11 @@
|
|||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"stability-flags": {
|
||||
"utopia-php/abuse": 20,
|
||||
"utopia-php/audit": 20,
|
||||
"utopia-php/database": 20
|
||||
},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace Appwrite\Migration;
|
|||
use Swoole\Runtime;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Config\Config;
|
||||
use Exception;
|
||||
|
@ -116,7 +117,11 @@ abstract class Migration
|
|||
Console::log('Migrating Collection ' . $collection['$id'] . ':');
|
||||
|
||||
do {
|
||||
$documents = $this->projectDB->find($collection['$id'], limit: $this->limit, cursor: $nextDocument);
|
||||
$queries = [Query::limit($this->limit)];
|
||||
if ($nextDocument !== null) {
|
||||
$queries[] = Query::cursorAfter($nextDocument);
|
||||
}
|
||||
$documents = $this->projectDB->find($collection['$id'], $queries);
|
||||
$count = count($documents);
|
||||
$sum += $count;
|
||||
|
||||
|
|
|
@ -156,7 +156,7 @@ class V12 extends Migration
|
|||
*/
|
||||
$this->createCollection('buckets');
|
||||
|
||||
if (!$this->projectDB->findOne('buckets', [new Query('$id', Query::TYPE_EQUAL, ['default'])])) {
|
||||
if (!$this->projectDB->findOne('buckets', [Query::equal('$id', ['default'])])) {
|
||||
$this->projectDB->createDocument('buckets', new Document([
|
||||
'$id' => 'default',
|
||||
'$collection' => 'buckets',
|
||||
|
@ -180,7 +180,11 @@ class V12 extends Migration
|
|||
*/
|
||||
$nextDocument = null;
|
||||
do {
|
||||
$documents = $this->projectDB->find('files', limit: $this->limit, cursor: $nextDocument);
|
||||
$queries = [Query::limit($this->limit)];
|
||||
if ($nextDocument !== null) {
|
||||
$queries[] = Query::cursorAfter($nextDocument);
|
||||
}
|
||||
$documents = $this->projectDB->find('files', $queries);
|
||||
$count = count($documents);
|
||||
\Co\run(function (array $documents) {
|
||||
foreach ($documents as $document) {
|
||||
|
@ -344,7 +348,11 @@ class V12 extends Migration
|
|||
$nextCollection = null;
|
||||
|
||||
do {
|
||||
$documents = $this->projectDB->find('collections', limit: $this->limit, cursor: $nextCollection);
|
||||
$queries = [Query::limit($this->limit)];
|
||||
if ($nextCollection !== null) {
|
||||
$queries[] = Query::cursorAfter($nextCollection);
|
||||
}
|
||||
$documents = $this->projectDB->find('collections', $queries);
|
||||
$count = count($documents);
|
||||
|
||||
\Co\run(function (array $documents) {
|
||||
|
@ -387,7 +395,11 @@ class V12 extends Migration
|
|||
$nextDocument = null;
|
||||
|
||||
do {
|
||||
$documents = $this->projectDB->find('collection_' . $internalId, limit: $this->limit, cursor: $nextDocument);
|
||||
$queries = [Query::limit($this->limit)];
|
||||
if ($nextDocument !== null) {
|
||||
$queries[] = Query::cursorAfter($nextDocument);
|
||||
}
|
||||
$documents = $this->projectDB->find('collection_' . $internalId, $queries);
|
||||
$count = count($documents);
|
||||
|
||||
foreach ($documents as $document) {
|
||||
|
@ -462,7 +474,11 @@ class V12 extends Migration
|
|||
$nextDocument = null;
|
||||
|
||||
do {
|
||||
$documents = $this->projectDB->find($id, limit: $this->limit, cursor: $nextDocument);
|
||||
$queries = [Query::limit($this->limit)];
|
||||
if ($nextDocument !== null) {
|
||||
$queries[] = Query::cursorAfter($nextDocument);
|
||||
}
|
||||
$documents = $this->projectDB->find($id, $queries);
|
||||
$count = count($documents);
|
||||
|
||||
\Co\run(function (array $documents) {
|
||||
|
|
|
@ -87,7 +87,11 @@ class V14 extends Migration
|
|||
{
|
||||
$nextFile = null;
|
||||
do {
|
||||
$documents = $this->projectDB->find("bucket_{$bucket->getInternalId()}", limit: $this->limit, cursor: $nextFile);
|
||||
$queries = [Query::limit($this->limit)];
|
||||
if ($nextFile !== null) {
|
||||
$queries[] = Query::cursorAfter($nextFile);
|
||||
}
|
||||
$documents = $this->projectDB->find("bucket_{$bucket->getInternalId()}", $queries);
|
||||
$count = count($documents);
|
||||
|
||||
foreach ($documents as $document) {
|
||||
|
@ -164,7 +168,11 @@ class V14 extends Migration
|
|||
$nextCollection = null;
|
||||
|
||||
do {
|
||||
$documents = $this->projectDB->find('database_1', limit: $this->limit, cursor: $nextCollection);
|
||||
$queries = [Query::limit($this->limit)];
|
||||
if ($nextCollection !== null) {
|
||||
$queries[] = Query::cursorAfter($nextCollection);
|
||||
}
|
||||
$documents = $this->projectDB->find('database_1', $queries);
|
||||
$count = count($documents);
|
||||
|
||||
\Co\run(function (array $documents) {
|
||||
|
@ -235,10 +243,15 @@ class V14 extends Migration
|
|||
* Offset pagination instead of cursor, since documents are re-created!
|
||||
*/
|
||||
$offset = 0;
|
||||
$attributesCount = $this->projectDB->count($type, queries: [new Query('collectionId', Query::TYPE_EQUAL, [$collection->getId()])]);
|
||||
$attributesCount = $this->projectDB->count($type, queries: [Query::equal('collectionId', [$collection->getId()])]);
|
||||
|
||||
do {
|
||||
$documents = $this->projectDB->find($type, limit: $this->limit, offset: $offset, queries: [new Query('collectionId', Query::TYPE_EQUAL, [$collection->getId()])]);
|
||||
$queries = [
|
||||
Query::limit($this->limit),
|
||||
Query::offset($offset),
|
||||
Query::equal('collectionId', [$collection->getId()]),
|
||||
];
|
||||
$documents = $this->projectDB->find($type, $queries);
|
||||
$offset += $this->limit;
|
||||
|
||||
foreach ($documents as $document) {
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace Appwrite\Stats;
|
|||
use Exception;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Query;
|
||||
|
||||
class UsageDB extends Usage
|
||||
{
|
||||
|
@ -60,7 +61,7 @@ class UsageDB extends Usage
|
|||
$document->setAttribute('value', $value)
|
||||
);
|
||||
}
|
||||
} catch (Exception$e) { // if projects are deleted this might fail
|
||||
} catch (\Exception $e) { // if projects are deleted this might fail
|
||||
if (is_callable($this->errorHandler)) {
|
||||
call_user_func($this->errorHandler, $e, "sync_project_{$projectId}_metric_{$metric}");
|
||||
} else {
|
||||
|
@ -91,8 +92,12 @@ class UsageDB extends Usage
|
|||
|
||||
while ($sum === $limit) {
|
||||
try {
|
||||
$results = $this->database->find($collection, $queries, $limit, cursor:$latestDocument);
|
||||
} catch (Exception $e) {
|
||||
$paginationQueries = [Query::limit($limit)];
|
||||
if ($latestDocument !== null) {
|
||||
$paginationQueries[] = Query::cursorAfter($latestDocument);
|
||||
}
|
||||
$results = $this->database->find($collection, \array_merge($paginationQueries, $queries));
|
||||
} catch (\Exception $e) {
|
||||
if (is_callable($this->errorHandler)) {
|
||||
call_user_func($this->errorHandler, $e, "fetch_documents_project_{$projectId}_collection_{$collection}");
|
||||
return;
|
||||
|
|
|
@ -9,18 +9,21 @@ class Queries extends ValidatorQueries
|
|||
{
|
||||
/**
|
||||
* Expression constructor
|
||||
*
|
||||
* This Queries Validator that filters indexes for only available indexes
|
||||
*
|
||||
* @param QueryValidator $validator
|
||||
* @param Document[] $attributes
|
||||
* @param Document[] $indexes
|
||||
* @param bool $strict
|
||||
*/
|
||||
public function __construct($attributes, $indexes, $strict)
|
||||
public function __construct($validator, $attributes = [], $indexes = [], $strict = true)
|
||||
{
|
||||
// Remove failed/stuck/processing indexes
|
||||
$indexes = \array_filter($indexes, function ($index) {
|
||||
$availableIndexes = \array_filter($indexes, function ($index) {
|
||||
return $index->getAttribute('status') === 'available';
|
||||
});
|
||||
|
||||
parent::__construct($attributes, $indexes, $strict);
|
||||
parent::__construct($validator, $attributes, $availableIndexes, $strict);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -197,7 +197,7 @@ trait DatabasesBase
|
|||
$this->assertEquals($actors['body']['required'], false);
|
||||
$this->assertEquals($actors['body']['array'], true);
|
||||
|
||||
$this->assertEquals($datetime['headers']['status-code'], 201);
|
||||
$this->assertEquals($datetime['headers']['status-code'], 202);
|
||||
$this->assertEquals($datetime['body']['key'], 'birthDay');
|
||||
$this->assertEquals($datetime['body']['type'], 'datetime');
|
||||
$this->assertEquals($datetime['body']['required'], false);
|
||||
|
@ -410,7 +410,7 @@ trait DatabasesBase
|
|||
$this->assertEquals(false, $boolean['body']['array']);
|
||||
$this->assertEquals(true, $boolean['body']['default']);
|
||||
|
||||
$this->assertEquals(201, $datetime['headers']['status-code']);
|
||||
$this->assertEquals(202, $datetime['headers']['status-code']);
|
||||
$this->assertEquals('datetime', $datetime['body']['key']);
|
||||
$this->assertEquals('datetime', $datetime['body']['type']);
|
||||
$this->assertEquals(false, $datetime['body']['required']);
|
||||
|
@ -834,7 +834,7 @@ trait DatabasesBase
|
|||
'attributes' => ['birthDay'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $releaseWithDate['headers']['status-code']);
|
||||
$this->assertEquals(202, $releaseWithDate['headers']['status-code']);
|
||||
$this->assertEquals('birthDay', $releaseWithDate['body']['key']);
|
||||
$this->assertEquals('key', $releaseWithDate['body']['type']);
|
||||
$this->assertCount(1, $releaseWithDate['body']['attributes']);
|
||||
|
@ -1359,7 +1359,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['title.search("Captain America")'],
|
||||
'queries' => ['search("title", "Captain America")'],
|
||||
]);
|
||||
|
||||
$this->assertEquals($documents['headers']['status-code'], 200);
|
||||
|
@ -1370,7 +1370,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['$id.equal("' . $documents['body']['documents'][0]['$id'] . '")'],
|
||||
'queries' => ['equal("$id", "' . $documents['body']['documents'][0]['$id'] . '")'],
|
||||
]);
|
||||
|
||||
$this->assertEquals($documents['headers']['status-code'], 200);
|
||||
|
@ -1381,7 +1381,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['title.search("Homecoming")'],
|
||||
'queries' => ['search("title", "Homecoming")'],
|
||||
]);
|
||||
|
||||
$this->assertEquals($documents['headers']['status-code'], 200);
|
||||
|
@ -1392,7 +1392,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['title.search("spider")'],
|
||||
'queries' => ['search("title", "spider")'],
|
||||
]);
|
||||
|
||||
$this->assertEquals($documents['headers']['status-code'], 200);
|
||||
|
@ -1404,7 +1404,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['releaseYear.equal(1944)'],
|
||||
'queries' => ['equal("releaseYear", 1944)'],
|
||||
]);
|
||||
|
||||
$this->assertCount(1, $documents['body']['documents']);
|
||||
|
@ -1414,7 +1414,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['releaseYear.notEqual(1944)'],
|
||||
'queries' => ['notEqual("releaseYear", 1944)'],
|
||||
]);
|
||||
|
||||
$this->assertCount(2, $documents['body']['documents']);
|
||||
|
@ -1425,7 +1425,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['$createdAt.greater("1976-06-12")'],
|
||||
'queries' => ['greaterThan("$createdAt", "1976-06-12")'],
|
||||
]);
|
||||
|
||||
$this->assertCount(3, $documents['body']['documents']);
|
||||
|
@ -1434,7 +1434,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['$createdAt.lesser("1976-06-12")'],
|
||||
'queries' => ['lessThan("$createdAt", "1976-06-12")'],
|
||||
]);
|
||||
|
||||
$this->assertCount(0, $documents['body']['documents']);
|
||||
|
@ -1446,7 +1446,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['actors.equal("Tom Holland")'],
|
||||
'queries' => ['equal("actors", "Tom Holland")'],
|
||||
]);
|
||||
$this->assertEquals(400, $documents['headers']['status-code']);
|
||||
$this->assertEquals('Index not found: actors', $documents['body']['message']);
|
||||
|
@ -1461,7 +1461,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['releaseYear.equal(' . implode(',', $conditions) . ')'],
|
||||
'queries' => ['equal("releaseYear", [' . implode(',', $conditions) . '])'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $documents['headers']['status-code']);
|
||||
|
@ -1476,7 +1476,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['title.search(' . implode(',', $conditions) . ')'],
|
||||
'queries' => ['search("title", ' . implode(',', $conditions) . ')'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $documents['headers']['status-code']);
|
||||
|
@ -1486,7 +1486,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['birthDay.greater("1960-01-01 10:10:10+02:30")'],
|
||||
'queries' => ['greaterThan("birthDay", "1960-01-01 10:10:10+02:30")'],
|
||||
]);
|
||||
|
||||
$this->assertEquals($documents['headers']['status-code'], 200);
|
||||
|
|
|
@ -177,7 +177,7 @@ class FunctionsCustomClientTest extends Scope
|
|||
$deploymentId = $deployment['body']['$id'] ?? '';
|
||||
|
||||
// Wait for deployment to be built.
|
||||
sleep(5);
|
||||
sleep(10);
|
||||
|
||||
$this->assertEquals(202, $deployment['headers']['status-code']);
|
||||
|
||||
|
|
Loading…
Reference in a new issue