Merge branch '1.8.x' of github.com:appwrite/appwrite into feat-mongodb-pulls

# Conflicts:
#	composer.lock
#	tests/e2e/Services/Databases/TablesDB/DatabasesBase.php
This commit is contained in:
shimon
2025-09-16 10:26:43 +03:00
14 changed files with 122 additions and 311 deletions
+1 -1
View File
@@ -538,7 +538,7 @@ App::get('/v1/health/queue/databases')
->inject('response')
->action(function (string $name, int|string $threshold, Database $queueForDatabase, Response $response) {
$threshold = \intval($threshold);
$size = $queueForDatabase->getSize();
$size = $queueForDatabase->setQueue($name)->getSize();
if ($size >= $threshold) {
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
+3 -2
View File
@@ -246,10 +246,11 @@ App::init()
$role = $apiKey->getRole();
$scopes = $apiKey->getScopes();
// Disable authorization checks for API keys
Authorization::setDefaultStatus(false);
if ($apiKey->getRole() === Auth::USER_ROLE_APPS) {
// Disable authorization checks for API keys
Authorization::setDefaultStatus(false);
$user = new Document([
'$id' => '',
'status' => true,
+9 -5
View File
@@ -10,6 +10,7 @@ use Swoole\Http\Response as SwooleResponse;
use Swoole\Http\Server;
use Swoole\Process;
use Swoole\Table;
use Swoole\Timer;
use Utopia\App;
use Utopia\Audit\Audit;
use Utopia\CLI\Console;
@@ -156,11 +157,16 @@ $http->on(Constant::EVENT_WORKER_START, function ($server, $workerId) {
Console::success('Worker ' . ++$workerId . ' started successfully');
});
$http->on(Constant::EVENT_BEFORE_RELOAD, function ($server, $workerId) {
$http->on(Constant::EVENT_WORKER_STOP, function ($server, $workerId) {
Timer::clearAll();
Console::success('Worker ' . ++$workerId . ' stopped successfully');
});
$http->on(Constant::EVENT_BEFORE_RELOAD, function ($server) {
Console::success('Starting reload...');
});
$http->on(Constant::EVENT_AFTER_RELOAD, function ($server, $workerId) {
$http->on(Constant::EVENT_AFTER_RELOAD, function ($server) {
Console::success('Reload completed...');
});
@@ -551,7 +557,7 @@ $http->on(Constant::EVENT_TASK, function () use ($register, $domains) {
/** @var Utopia\Database\Database $dbForPlatform */
$dbForPlatform = $app->getResource('dbForPlatform');
Console::loop(function () use ($dbForPlatform, $domains, &$lastSyncUpdate) {
Timer::tick(DOMAIN_SYNC_TIMER * 1000, function () use ($dbForPlatform, $domains, &$lastSyncUpdate) {
try {
$time = DateTime::now();
$limit = 1000;
@@ -590,8 +596,6 @@ $http->on(Constant::EVENT_TASK, function () use ($register, $domains) {
} catch (Throwable $th) {
Console::error($th->getMessage());
}
}, DOMAIN_SYNC_TIMER, 0, function ($error) {
Console::error($error);
});
});
Generated
+18 -246
View File
@@ -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": "ce433cef8711249299b58cc36419d912",
"content-hash": "7553e976312b0423cc31544abb91caec",
"packages": [
{
"name": "adhocore/jwt",
@@ -962,83 +962,6 @@
},
"time": "2025-08-20T17:20:16+00:00"
},
{
"name": "mongodb/mongodb",
"version": "2.1.0",
"source": {
"type": "git",
"url": "https://github.com/mongodb/mongo-php-library.git",
"reference": "3bbe7ba9578724c7e1f47fcd17c881c0995baaad"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mongodb/mongo-php-library/zipball/3bbe7ba9578724c7e1f47fcd17c881c0995baaad",
"reference": "3bbe7ba9578724c7e1f47fcd17c881c0995baaad",
"shasum": ""
},
"require": {
"composer-runtime-api": "^2.0",
"ext-mongodb": "^2.1",
"php": "^8.1",
"psr/log": "^1.1.4|^2|^3",
"symfony/polyfill-php85": "^1.32"
},
"replace": {
"mongodb/builder": "*"
},
"require-dev": {
"doctrine/coding-standard": "^12.0",
"phpunit/phpunit": "^10.5.35",
"rector/rector": "^1.2",
"squizlabs/php_codesniffer": "^3.7",
"vimeo/psalm": "6.5.*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.x-dev"
}
},
"autoload": {
"files": [
"src/functions.php"
],
"psr-4": {
"MongoDB\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"authors": [
{
"name": "Andreas Braun",
"email": "andreas.braun@mongodb.com"
},
{
"name": "Jeremy Mikola",
"email": "jmikola@gmail.com"
},
{
"name": "Jérôme Tamarelle",
"email": "jerome.tamarelle@mongodb.com"
}
],
"description": "MongoDB driver library",
"homepage": "https://jira.mongodb.org/browse/PHPLIB",
"keywords": [
"database",
"driver",
"mongodb",
"persistence"
],
"support": {
"issues": "https://github.com/mongodb/mongo-php-library/issues",
"source": "https://github.com/mongodb/mongo-php-library/tree/2.1.0"
},
"time": "2025-05-23T10:48:05+00:00"
},
{
"name": "mustangostang/spyc",
"version": "0.6.3",
@@ -3097,86 +3020,6 @@
],
"time": "2025-07-08T02:45:35+00:00"
},
{
"name": "symfony/polyfill-php85",
"version": "v1.33.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php85.git",
"reference": "d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91",
"reference": "d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91",
"shasum": ""
},
"require": {
"php": ">=7.2"
},
"type": "library",
"extra": {
"thanks": {
"url": "https://github.com/symfony/polyfill",
"name": "symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Php85\\": ""
},
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 8.5+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php85/tree/v1.33.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://github.com/nicolas-grekas",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2025-06-23T16:12:55+00:00"
},
{
"name": "symfony/service-contracts",
"version": "v3.6.0",
@@ -3795,16 +3638,16 @@
},
{
"name": "utopia-php/database",
"version": "dev-feat-mongo-tmp-pulls",
"version": "1.4.8",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/database.git",
"reference": "c967e720efb4b5ad6f14b8313c85faac3d7bdb16"
"reference": "dbecdf89fde33a5f81ec19f4f97fe0c3715dc83a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/database/zipball/c967e720efb4b5ad6f14b8313c85faac3d7bdb16",
"reference": "c967e720efb4b5ad6f14b8313c85faac3d7bdb16",
"url": "https://api.github.com/repos/utopia-php/database/zipball/dbecdf89fde33a5f81ec19f4f97fe0c3715dc83a",
"reference": "dbecdf89fde33a5f81ec19f4f97fe0c3715dc83a",
"shasum": ""
},
"require": {
@@ -3813,7 +3656,6 @@
"php": ">=8.1",
"utopia-php/cache": "0.13.*",
"utopia-php/framework": "0.33.*",
"utopia-php/mongo": "dev-feat-create-UUID as 0.5.3",
"utopia-php/pools": "0.8.*"
},
"require-dev": {
@@ -3846,9 +3688,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/database/issues",
"source": "https://github.com/utopia-php/database/tree/feat-mongo-tmp-pulls"
"source": "https://github.com/utopia-php/database/tree/1.4.8"
},
"time": "2025-09-11T09:50:34+00:00"
"time": "2025-09-12T03:35:59+00:00"
},
{
"name": "utopia-php/detector",
@@ -4402,67 +4244,6 @@
},
"time": "2025-09-10T06:17:20+00:00"
},
{
"name": "utopia-php/mongo",
"version": "dev-feat-create-UUID",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/mongo.git",
"reference": "682c2e0b8474acfca1953eaca321f6f9bb0245f0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/mongo/zipball/682c2e0b8474acfca1953eaca321f6f9bb0245f0",
"reference": "682c2e0b8474acfca1953eaca321f6f9bb0245f0",
"shasum": ""
},
"require": {
"ext-mongodb": "2.1.1",
"mongodb/mongodb": "2.1.0",
"php": ">=8.0",
"ramsey/uuid": "^4.9.0"
},
"require-dev": {
"fakerphp/faker": "^1.14",
"laravel/pint": "1.2.*",
"phpstan/phpstan": "2.1.*",
"phpunit/phpunit": "^9.4",
"swoole/ide-helper": "4.8.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Utopia\\Mongo\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Eldad Fux",
"email": "eldad@appwrite.io"
},
{
"name": "Wess",
"email": "wess@appwrite.io"
}
],
"description": "A simple library to manage Mongo database",
"keywords": [
"database",
"mongo",
"php",
"upf",
"utopia"
],
"support": {
"issues": "https://github.com/utopia-php/mongo/issues",
"source": "https://github.com/utopia-php/mongo/tree/feat-create-UUID"
},
"time": "2025-09-11T10:51:49+00:00"
},
{
"name": "utopia-php/orchestration",
"version": "0.9.1",
@@ -4670,16 +4451,16 @@
},
{
"name": "utopia-php/queue",
"version": "0.11.0",
"version": "0.11.1",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/queue.git",
"reference": "06b5ced0eaed2ecc6aab6d8e1b4d96bff37a1ce5"
"reference": "498bbbef418b1db71b51e1bb62f5d1d752ddd8d6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/queue/zipball/06b5ced0eaed2ecc6aab6d8e1b4d96bff37a1ce5",
"reference": "06b5ced0eaed2ecc6aab6d8e1b4d96bff37a1ce5",
"url": "https://api.github.com/repos/utopia-php/queue/zipball/498bbbef418b1db71b51e1bb62f5d1d752ddd8d6",
"reference": "498bbbef418b1db71b51e1bb62f5d1d752ddd8d6",
"shasum": ""
},
"require": {
@@ -4730,9 +4511,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/queue/issues",
"source": "https://github.com/utopia-php/queue/tree/0.11.0"
"source": "https://github.com/utopia-php/queue/tree/0.11.1"
},
"time": "2025-05-30T09:52:38+00:00"
"time": "2025-05-30T11:50:34+00:00"
},
{
"name": "utopia-php/registry",
@@ -8729,19 +8510,10 @@
"time": "2024-03-07T20:33:40+00:00"
}
],
"aliases": [
{
"package": "utopia-php/database",
"version": "dev-feat-mongo-tmp-pulls",
"alias": "1.4.6",
"alias_normalized": "1.4.6.0"
}
],
"minimum-stability": "dev",
"stability-flags": {
"utopia-php/database": 20
},
"prefer-stable": true,
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": ">=8.3.0",
@@ -8764,5 +8536,5 @@
"platform-overrides": {
"php": "8.3"
},
"plugin-api-version": "2.2.0"
"plugin-api-version": "2.6.0"
}
+6 -2
View File
@@ -4,5 +4,9 @@
"repository": {
"type": "git",
"url": "git+https://github.com/appwrite/appwrite.git"
}
}
},
"files": [
"docs/examples",
"app/config/specs"
]
}
+11 -8
View File
@@ -161,17 +161,20 @@ class Database extends Event
return $this->document;
}
public function getQueue(): string
public function setProject(Document $project): self
{
try {
$dsn = new DSN($this->getProject()->getAttribute('database'));
} catch (\InvalidArgumentException) {
// TODO: Temporary until all projects are using shared tables
$dsn = new DSN('mysql://' . $this->getProject()->getAttribute('database'));
$database = $project->getAttribute('database');
if (!empty($database)) {
try {
$dsn = new DSN($database);
} catch (\InvalidArgumentException) {
// TODO: Temporary until all projects are using shared tables
$dsn = new DSN("mysql://$database");
}
$this->queue = $dsn->getHost();
}
$this->queue = $dsn->getHost();
return $this->queue;
return parent::setProject($project);
}
/**
@@ -77,8 +77,8 @@ class Get extends Action
str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_COLLECTIONS),
str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_DOCUMENTS),
str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_STORAGE),
str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASES_OPERATIONS_READS),
str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASES_OPERATIONS_WRITES)
str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_READS),
str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES)
];
Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) {
@@ -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;
+35 -19
View File
@@ -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;
+24 -11
View File
@@ -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', []);
@@ -6010,12 +6010,12 @@ trait DatabasesBase
'documentId' => ID::unique(),
'data' => [
'name' => 'Upserted Location',
'location' => [34.0522, -118.2437] // Los Angeles coordinates
'location' => [34.0522, -80] // Los Angeles coordinates
]
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals([34.0522, -118.2437], $response['body']['location']);
$this->assertEquals([34.0522, -80], $response['body']['location']);
// Test 5: Create document without permissions (should fail)
$response = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', [
@@ -6145,12 +6145,12 @@ trait DatabasesBase
'documentId' => ID::unique(),
'data' => [
'distance' => 200,
'route' => [[34.0522, -118.2437], [34.0736, -118.2400]] // LA route
'route' => [[34.0522, -80], [34.0736, -90]] // LA route
]
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals([[34.0522, -118.2437], [34.0736, -118.2400]], $response['body']['route']);
$this->assertEquals([[34.0522, -80], [34.0736, -90]], $response['body']['route']);
// Test 5: Delete document
$response = $this->client->call(Client::METHOD_DELETE, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $documentId, array_merge([
@@ -6282,12 +6282,12 @@ trait DatabasesBase
'documentId' => ID::unique(),
'data' => [
'active' => false,
'area' => [[[34.0522, -118.2437], [34.0736, -118.2437], [34.0736, -118.2400], [34.0522, -118.2400], [34.0522, -118.2437]]] // LA area
'area' => [[[34.0522, -80], [34.0736, -80], [34.0736, -90], [34.0522, -90], [34.0522, -80]]] // LA area
]
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals([[[34.0522, -118.2437], [34.0736, -118.2437], [34.0736, -118.2400], [34.0522, -118.2400], [34.0522, -118.2437]]], $response['body']['area']);
$this->assertEquals([[[34.0522, -80], [34.0736, -80], [34.0736, -90], [34.0522, -90], [34.0522, -80]]], $response['body']['area']);
// Test 5: Create document without required polygon attribute (should fail)
$response = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', array_merge([
@@ -6722,7 +6722,7 @@ trait DatabasesBase
'$id' => 'doc1',
'name' => 'Test Document 1',
'pointAttr' => [6.0, 6.0],
'lineAttr' => [[1.0, 1.0], [2.0, 2.0]],
'lineAttr' => [[1.0, 1.0], [1.1,1.1] , [2.0, 2.0]],
'polyAttr' => [[[0.0, 0.0], [10.0, 0.0], [10.0, 10.0], [0.0, 10.0], [0.0, 0.0]]]
],
[
@@ -6804,6 +6804,7 @@ trait DatabasesBase
$this->assertCount(1, $response['body']['documents']);
$this->assertEquals('doc1', $response['body']['documents'][0]['$id']);
// Test 4.2: notContains on polygon (point outside all polygons)
$response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', array_merge([
'content-type' => 'application/json',
@@ -6710,7 +6710,7 @@ class DatabasesCustomServerTest extends Scope
'path' => [
[0, 0],
[50, 50],
[100, 100]
[80, 80]
] // New LINE STRING
],
]);
@@ -6724,7 +6724,7 @@ class DatabasesCustomServerTest extends Scope
$this->assertEquals([
[0, 0],
[50, 50],
[100, 100]
[80, 80]
], $document['path']);
}
@@ -414,7 +414,6 @@ trait DatabasesBase
Query::cursorAfter(new Document(['$id' => 'title']))->toString()
],
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(2, \count($response['body']['columns']));
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $data['moviesId'] . '/columns', array_merge([
@@ -6413,7 +6413,7 @@ class DatabasesCustomServerTest extends Scope
]);
// Coordinates are not validated strictly; creation should succeed
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertEquals(400, $response['headers']['status-code']);
// Test 4b: Invalid polygon (insufficient points - should fail)
$response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([
@@ -6684,7 +6684,7 @@ class DatabasesCustomServerTest extends Scope
'path' => [
[0, 0],
[50, 50],
[100, 100]
[80, 80]
] // New LINE STRING
],
]);
@@ -6698,7 +6698,7 @@ class DatabasesCustomServerTest extends Scope
$this->assertEquals([
[0, 0],
[50, 50],
[100, 100]
[80, 80]
], $row['path']);
}