mirror of
https://github.com/appwrite/appwrite
synced 2026-05-22 16:38:32 +00:00
Merge remote-tracking branch 'origin/1.8.x' into feat-txn
# Conflicts: # composer.lock
This commit is contained in:
commit
63aee11312
5 changed files with 89 additions and 64 deletions
|
|
@ -225,6 +225,8 @@ App::get('/v1/storage/buckets')
|
|||
$total = $dbForProject->count('buckets', $filterQueries, APP_LIMIT_COUNT);
|
||||
} catch (OrderException $e) {
|
||||
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
|
||||
} catch (QueryException $e) {
|
||||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
|
||||
}
|
||||
$response->dynamic(new Document([
|
||||
'buckets' => $buckets,
|
||||
|
|
@ -853,6 +855,8 @@ App::get('/v1/storage/buckets/:bucketId/files')
|
|||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
} catch (OrderException $e) {
|
||||
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
|
||||
} catch (QueryException $e) {
|
||||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
|
|
|
|||
58
composer.lock
generated
58
composer.lock
generated
|
|
@ -756,24 +756,21 @@
|
|||
},
|
||||
{
|
||||
"name": "google/protobuf",
|
||||
"version": "v4.32.0",
|
||||
"version": "v4.32.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/protocolbuffers/protobuf-php.git",
|
||||
"reference": "9a9a92ecbe9c671dc1863f6d4a91ea3ea12c8646"
|
||||
"reference": "c4ed1c1f9bbc1e91766e2cd6c0af749324fe87cb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/9a9a92ecbe9c671dc1863f6d4a91ea3ea12c8646",
|
||||
"reference": "9a9a92ecbe9c671dc1863f6d4a91ea3ea12c8646",
|
||||
"url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/c4ed1c1f9bbc1e91766e2cd6c0af749324fe87cb",
|
||||
"reference": "c4ed1c1f9bbc1e91766e2cd6c0af749324fe87cb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1.0"
|
||||
},
|
||||
"provide": {
|
||||
"ext-protobuf": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": ">=5.0.0 <8.5.27"
|
||||
},
|
||||
|
|
@ -797,9 +794,9 @@
|
|||
"proto"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.32.0"
|
||||
"source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.32.1"
|
||||
},
|
||||
"time": "2025-08-14T20:00:33+00:00"
|
||||
"time": "2025-09-14T05:14:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/csv",
|
||||
|
|
@ -3638,16 +3635,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/database",
|
||||
"version": "2.0.2",
|
||||
"version": "2.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/database.git",
|
||||
"reference": "e68f2e358bdfbc682aaad4956d325535664ec7d5"
|
||||
"reference": "732ffef52fd76483722537ee1f4f83726125a7ec"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/e68f2e358bdfbc682aaad4956d325535664ec7d5",
|
||||
"reference": "e68f2e358bdfbc682aaad4956d325535664ec7d5",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/732ffef52fd76483722537ee1f4f83726125a7ec",
|
||||
"reference": "732ffef52fd76483722537ee1f4f83726125a7ec",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -3688,9 +3685,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/database/issues",
|
||||
"source": "https://github.com/utopia-php/database/tree/2.0.2"
|
||||
"source": "https://github.com/utopia-php/database/tree/2.1.0"
|
||||
},
|
||||
"time": "2025-09-12T12:29:38+00:00"
|
||||
"time": "2025-09-16T13:44:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/detector",
|
||||
|
|
@ -5281,16 +5278,16 @@
|
|||
},
|
||||
{
|
||||
"name": "laravel/pint",
|
||||
"version": "v1.24.0",
|
||||
"version": "v1.25.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/pint.git",
|
||||
"reference": "0345f3b05f136801af8c339f9d16ef29e6b4df8a"
|
||||
"reference": "595de38458c6b0ab4cae4bcc769c2e5c5d5b8e96"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/pint/zipball/0345f3b05f136801af8c339f9d16ef29e6b4df8a",
|
||||
"reference": "0345f3b05f136801af8c339f9d16ef29e6b4df8a",
|
||||
"url": "https://api.github.com/repos/laravel/pint/zipball/595de38458c6b0ab4cae4bcc769c2e5c5d5b8e96",
|
||||
"reference": "595de38458c6b0ab4cae4bcc769c2e5c5d5b8e96",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -5301,9 +5298,9 @@
|
|||
"php": "^8.2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^3.82.2",
|
||||
"illuminate/view": "^11.45.1",
|
||||
"larastan/larastan": "^3.5.0",
|
||||
"friendsofphp/php-cs-fixer": "^3.87.2",
|
||||
"illuminate/view": "^11.46.0",
|
||||
"larastan/larastan": "^3.7.1",
|
||||
"laravel-zero/framework": "^11.45.0",
|
||||
"mockery/mockery": "^1.6.12",
|
||||
"nunomaduro/termwind": "^2.3.1",
|
||||
|
|
@ -5314,9 +5311,6 @@
|
|||
],
|
||||
"type": "project",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"overrides/Runner/Parallel/ProcessFactory.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"App\\": "app/",
|
||||
"Database\\Seeders\\": "database/seeders/",
|
||||
|
|
@ -5346,7 +5340,7 @@
|
|||
"issues": "https://github.com/laravel/pint/issues",
|
||||
"source": "https://github.com/laravel/pint"
|
||||
},
|
||||
"time": "2025-07-10T18:09:32+00:00"
|
||||
"time": "2025-09-17T01:36:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "matthiasmullie/minify",
|
||||
|
|
@ -6236,16 +6230,16 @@
|
|||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "9.6.26",
|
||||
"version": "9.6.27",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "a0139ea157533454f611038326f3020b3051f129"
|
||||
"reference": "0a9aa4440b6a9528cf360071502628d717af3e0a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a0139ea157533454f611038326f3020b3051f129",
|
||||
"reference": "a0139ea157533454f611038326f3020b3051f129",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0a9aa4440b6a9528cf360071502628d717af3e0a",
|
||||
"reference": "0a9aa4440b6a9528cf360071502628d717af3e0a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -6319,7 +6313,7 @@
|
|||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.26"
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.27"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -6343,7 +6337,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-09-11T06:17:45+00:00"
|
||||
"time": "2025-09-14T06:18:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/cache",
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@ class V16 extends Filter
|
|||
{
|
||||
switch ($model) {
|
||||
case 'functions.create':
|
||||
$content['commands'] = $this->getCommands($content['runtime'] ?? '');
|
||||
break;
|
||||
case 'functions.update':
|
||||
$content['commands'] = $this->getCommands($content['runtime'] ?? '');
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Appwrite\Utopia\Request\Filters;
|
||||
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Utopia\Request\Filter;
|
||||
use Utopia\Database\Query;
|
||||
|
||||
|
|
@ -67,9 +68,9 @@ class V17 extends Filter
|
|||
foreach ($content['queries'] as $query) {
|
||||
try {
|
||||
$query = $this->parseQuery($query);
|
||||
$parsed[] = json_encode(array_filter($query->toArray()));
|
||||
$parsed[] = \json_encode(\array_filter($query->toArray()));
|
||||
} catch (\Throwable $th) {
|
||||
throw new \Exception("Invalid query: {$query}", previous: $th);
|
||||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $th->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -83,6 +84,7 @@ class V17 extends Filter
|
|||
{
|
||||
// Init empty vars we fill later
|
||||
$method = '';
|
||||
$attribute = null;
|
||||
$params = [];
|
||||
|
||||
// Separate method from filter
|
||||
|
|
@ -92,7 +94,7 @@ class V17 extends Filter
|
|||
throw new \Exception('Invalid query');
|
||||
}
|
||||
|
||||
$method = mb_substr($filter, 0, $paramsStart);
|
||||
$method = \mb_substr($filter, 0, $paramsStart);
|
||||
|
||||
// Separate params from filter
|
||||
$paramsEnd = \strlen($filter) - 1; // -1 to ignore )
|
||||
|
|
@ -103,14 +105,13 @@ class V17 extends Filter
|
|||
throw new \Exception('Invalid query method');
|
||||
}
|
||||
|
||||
$currentParam = ""; // We build param here before pushing when it's ended
|
||||
$currentParam = ''; // We build param here before pushing when it's ended
|
||||
$currentArrayParam = []; // We build array param here before pushing when it's ended
|
||||
|
||||
$stack = []; // State for stack of parentheses
|
||||
$stackCount = 0; // Length of stack array. Kept as variable to improve performance
|
||||
$stringStackState = null; // State for string support
|
||||
|
||||
|
||||
// Loop thorough all characters
|
||||
for ($i = $parametersStart; $i < $paramsEnd; $i++) {
|
||||
$char = $filter[$i];
|
||||
|
|
@ -135,20 +136,25 @@ class V17 extends Filter
|
|||
($filter[$i - 1] !== static::CHAR_BACKSLASH || $filter[$i - 2] === static::CHAR_BACKSLASH) // Must not be escaped;
|
||||
) {
|
||||
if ($isStringStack) {
|
||||
// Dont mix-up string symbols. Only allow the same as on start
|
||||
// Don't mix up string symbols. Only allow the same as on start
|
||||
if ($char === $stringStackState) {
|
||||
// End of string
|
||||
$stringStackState = null;
|
||||
}
|
||||
|
||||
// Either way, add symbol to builder
|
||||
static::appendSymbol($isStringStack, $char, $i, $filter, $currentParam);
|
||||
} else {
|
||||
// Start of string
|
||||
$stringStackState = $char;
|
||||
static::appendSymbol($isStringStack, $char, $i, $filter, $currentParam);
|
||||
}
|
||||
|
||||
// Either way, add symbol to builder
|
||||
static::appendSymbol(
|
||||
$isStringStack,
|
||||
$char,
|
||||
$i,
|
||||
$filter,
|
||||
$currentParam,
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -174,12 +180,12 @@ class V17 extends Filter
|
|||
|
||||
continue;
|
||||
} elseif ($char === static::CHAR_COMMA) { // Params separation support
|
||||
// If in array stack, dont merge yet, just mark it in array param builder
|
||||
// If in array stack, don't merge yet, just mark it in array param builder
|
||||
if ($isArrayStack) {
|
||||
$currentArrayParam[] = $currentParam;
|
||||
$currentParam = "";
|
||||
} else {
|
||||
// Append from parap builder. Either value, or array
|
||||
// Append from param builder. Either value, or array
|
||||
if (empty($currentArrayParam)) {
|
||||
if (strlen($currentParam)) {
|
||||
$params[] = $currentParam;
|
||||
|
|
@ -193,23 +199,28 @@ class V17 extends Filter
|
|||
}
|
||||
|
||||
// Value, not relevant to syntax
|
||||
static::appendSymbol($isStringStack, $char, $i, $filter, $currentParam);
|
||||
static::appendSymbol(
|
||||
$isStringStack,
|
||||
$char,
|
||||
$i,
|
||||
$filter,
|
||||
$currentParam,
|
||||
);
|
||||
}
|
||||
|
||||
if (strlen($currentParam)) {
|
||||
if (\strlen($currentParam)) {
|
||||
$params[] = $currentParam;
|
||||
$currentParam = "";
|
||||
$currentParam = '';
|
||||
}
|
||||
|
||||
$parsedParams = [];
|
||||
|
||||
foreach ($params as $param) {
|
||||
// If array, parse each child separatelly
|
||||
// If array, parse each child separately
|
||||
if (\is_array($param)) {
|
||||
foreach ($param as $element) {
|
||||
$arr[] = self::parseValue($element);
|
||||
}
|
||||
|
||||
$parsedParams[] = $arr ?? [];
|
||||
} else {
|
||||
$parsedParams[] = self::parseValue($param);
|
||||
|
|
@ -295,8 +306,13 @@ class V17 extends Filter
|
|||
* @param string $currentParam
|
||||
* @return void
|
||||
*/
|
||||
private function appendSymbol(bool $isStringStack, string $char, int $index, string $filter, string &$currentParam): void
|
||||
{
|
||||
private function appendSymbol(
|
||||
bool $isStringStack,
|
||||
string $char,
|
||||
int $index,
|
||||
string $filter,
|
||||
string &$currentParam
|
||||
): void {
|
||||
// Ignore spaces and commas outside of string
|
||||
$canBeIgnored = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
|
||||
namespace Appwrite\Utopia\Request\Filters;
|
||||
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Utopia\Request\Filter;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Exception\NotFound;
|
||||
use Utopia\Database\Exception\Query as QueryException;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
|
|
@ -54,8 +56,8 @@ class V20 extends Filter
|
|||
|
||||
try {
|
||||
$parsed = Query::parseQueries($content['queries']);
|
||||
} catch (QueryException) {
|
||||
return $content;
|
||||
} catch (QueryException $e) {
|
||||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
|
||||
}
|
||||
|
||||
$selections = Query::groupByType($parsed)['selections'] ?? [];
|
||||
|
|
@ -136,17 +138,28 @@ class V20 extends Filter
|
|||
return [];
|
||||
}
|
||||
|
||||
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
|
||||
if ($database->isEmpty()) {
|
||||
return [];
|
||||
try {
|
||||
$database = Authorization::skip(fn () => $dbForProject->getDocument(
|
||||
'databases',
|
||||
$databaseId
|
||||
));
|
||||
if ($database->isEmpty()) {
|
||||
return [];
|
||||
}
|
||||
} catch (NotFound) {
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = Authorization::skip(fn () => $dbForProject->getDocument(
|
||||
'database_' . $database->getSequence(),
|
||||
$collectionId
|
||||
));
|
||||
if ($collection->isEmpty()) {
|
||||
return [];
|
||||
try {
|
||||
$collection = Authorization::skip(fn () => $dbForProject->getDocument(
|
||||
'database_' . $database->getSequence(),
|
||||
$collectionId
|
||||
));
|
||||
if ($collection->isEmpty()) {
|
||||
return [];
|
||||
}
|
||||
} catch (NotFound) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$attributes = $collection->getAttribute('attributes', []);
|
||||
|
|
|
|||
Loading…
Reference in a new issue