mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
pr followups
This commit is contained in:
Generated
+127
-42
@@ -2599,16 +2599,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-client",
|
||||
"version": "v7.3.2",
|
||||
"version": "v7.3.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/http-client.git",
|
||||
"reference": "1c064a0c67749923483216b081066642751cc2c7"
|
||||
"reference": "333b9bd7639cbdaecd25a3a48a9d2dcfaa86e019"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/http-client/zipball/1c064a0c67749923483216b081066642751cc2c7",
|
||||
"reference": "1c064a0c67749923483216b081066642751cc2c7",
|
||||
"url": "https://api.github.com/repos/symfony/http-client/zipball/333b9bd7639cbdaecd25a3a48a9d2dcfaa86e019",
|
||||
"reference": "333b9bd7639cbdaecd25a3a48a9d2dcfaa86e019",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2616,6 +2616,7 @@
|
||||
"psr/log": "^1|^2|^3",
|
||||
"symfony/deprecation-contracts": "^2.5|^3",
|
||||
"symfony/http-client-contracts": "~3.4.4|^3.5.2",
|
||||
"symfony/polyfill-php83": "^1.29",
|
||||
"symfony/service-contracts": "^2.5|^3"
|
||||
},
|
||||
"conflict": {
|
||||
@@ -2674,7 +2675,7 @@
|
||||
"http"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/http-client/tree/v7.3.2"
|
||||
"source": "https://github.com/symfony/http-client/tree/v7.3.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2694,7 +2695,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-07-15T11:36:08+00:00"
|
||||
"time": "2025-08-27T07:45:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-client-contracts",
|
||||
@@ -2939,6 +2940,86 @@
|
||||
],
|
||||
"time": "2024-09-09T11:45:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php83",
|
||||
"version": "v1.33.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php83.git",
|
||||
"reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/17f6f9a6b1735c0f163024d959f700cfbc5155e5",
|
||||
"reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5",
|
||||
"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\\Php83\\": ""
|
||||
},
|
||||
"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.3+ features to lower PHP versions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php83/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-07-08T02:45:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/service-contracts",
|
||||
"version": "v3.6.0",
|
||||
@@ -3557,16 +3638,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/database",
|
||||
"version": "1.2.2",
|
||||
"version": "1.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/database.git",
|
||||
"reference": "d59a207c079cc9e821ee4cab045a411bdad79e8c"
|
||||
"reference": "06ffa2b1c977f5451200a1ee82a500be1390a789"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/d59a207c079cc9e821ee4cab045a411bdad79e8c",
|
||||
"reference": "d59a207c079cc9e821ee4cab045a411bdad79e8c",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/06ffa2b1c977f5451200a1ee82a500be1390a789",
|
||||
"reference": "06ffa2b1c977f5451200a1ee82a500be1390a789",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3607,9 +3688,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/database/issues",
|
||||
"source": "https://github.com/utopia-php/database/tree/1.2.2"
|
||||
"source": "https://github.com/utopia-php/database/tree/1.3.0"
|
||||
},
|
||||
"time": "2025-08-27T11:27:06+00:00"
|
||||
"time": "2025-09-02T16:20:02+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/detector",
|
||||
@@ -4109,16 +4190,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/migration",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/migration.git",
|
||||
"reference": "0e4499d9dd2c90c2be188cc5fb7a32d9a892b569"
|
||||
"reference": "38171023efd3abe650d2abc5ac65f5df52311da6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/migration/zipball/0e4499d9dd2c90c2be188cc5fb7a32d9a892b569",
|
||||
"reference": "0e4499d9dd2c90c2be188cc5fb7a32d9a892b569",
|
||||
"url": "https://api.github.com/repos/utopia-php/migration/zipball/38171023efd3abe650d2abc5ac65f5df52311da6",
|
||||
"reference": "38171023efd3abe650d2abc5ac65f5df52311da6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4159,9 +4240,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/migration/issues",
|
||||
"source": "https://github.com/utopia-php/migration/tree/1.0.0"
|
||||
"source": "https://github.com/utopia-php/migration/tree/1.0.1"
|
||||
},
|
||||
"time": "2025-08-13T09:15:53+00:00"
|
||||
"time": "2025-08-28T13:41:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/orchestration",
|
||||
@@ -7410,16 +7491,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v7.3.2",
|
||||
"version": "v7.3.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "5f360ebc65c55265a74d23d7fe27f957870158a1"
|
||||
"reference": "cb0102a1c5ac3807cf3fdf8bea96007df7fdbea7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/5f360ebc65c55265a74d23d7fe27f957870158a1",
|
||||
"reference": "5f360ebc65c55265a74d23d7fe27f957870158a1",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/cb0102a1c5ac3807cf3fdf8bea96007df7fdbea7",
|
||||
"reference": "cb0102a1c5ac3807cf3fdf8bea96007df7fdbea7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -7484,7 +7565,7 @@
|
||||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v7.3.2"
|
||||
"source": "https://github.com/symfony/console/tree/v7.3.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -7504,7 +7585,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-07-30T17:13:41+00:00"
|
||||
"time": "2025-08-25T06:35:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
@@ -7646,16 +7727,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/options-resolver",
|
||||
"version": "v7.3.2",
|
||||
"version": "v7.3.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/options-resolver.git",
|
||||
"reference": "119bcf13e67dbd188e5dbc74228b1686f66acd37"
|
||||
"reference": "0ff2f5c3df08a395232bbc3c2eb7e84912df911d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/119bcf13e67dbd188e5dbc74228b1686f66acd37",
|
||||
"reference": "119bcf13e67dbd188e5dbc74228b1686f66acd37",
|
||||
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/0ff2f5c3df08a395232bbc3c2eb7e84912df911d",
|
||||
"reference": "0ff2f5c3df08a395232bbc3c2eb7e84912df911d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -7693,7 +7774,7 @@
|
||||
"options"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/options-resolver/tree/v7.3.2"
|
||||
"source": "https://github.com/symfony/options-resolver/tree/v7.3.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -7713,7 +7794,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-07-15T11:36:08+00:00"
|
||||
"time": "2025-08-05T10:16:07+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
@@ -8047,16 +8128,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v7.3.0",
|
||||
"version": "v7.3.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af"
|
||||
"reference": "32241012d521e2e8a9d713adb0812bb773b907f1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/40c295f2deb408d5e9d2d32b8ba1dd61e36f05af",
|
||||
"reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/32241012d521e2e8a9d713adb0812bb773b907f1",
|
||||
"reference": "32241012d521e2e8a9d713adb0812bb773b907f1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -8088,7 +8169,7 @@
|
||||
"description": "Executes commands in sub-processes",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/process/tree/v7.3.0"
|
||||
"source": "https://github.com/symfony/process/tree/v7.3.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -8099,25 +8180,29 @@
|
||||
"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-04-17T09:11:12+00:00"
|
||||
"time": "2025-08-18T09:42:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/string",
|
||||
"version": "v7.3.2",
|
||||
"version": "v7.3.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/string.git",
|
||||
"reference": "42f505aff654e62ac7ac2ce21033818297ca89ca"
|
||||
"reference": "17a426cce5fd1f0901fefa9b2a490d0038fd3c9c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/42f505aff654e62ac7ac2ce21033818297ca89ca",
|
||||
"reference": "42f505aff654e62ac7ac2ce21033818297ca89ca",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/17a426cce5fd1f0901fefa9b2a490d0038fd3c9c",
|
||||
"reference": "17a426cce5fd1f0901fefa9b2a490d0038fd3c9c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -8175,7 +8260,7 @@
|
||||
"utf8"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/string/tree/v7.3.2"
|
||||
"source": "https://github.com/symfony/string/tree/v7.3.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -8195,7 +8280,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-07-10T08:47:49+00:00"
|
||||
"time": "2025-08-25T06:35:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "textalk/websocket",
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@ class Update extends Action
|
||||
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#createCollection).')
|
||||
->param('key', '', new Key(), 'Attribute Key.')
|
||||
->param('required', null, new Boolean(), 'Is attribute required?')
|
||||
->param('default', null, new Nullable(new Spatial(Database::VAR_POINT)), 'Default value for attribute when not provided, as JSON string. Cannot be set when attribute is required.',true)
|
||||
->param('default', null, new Nullable(new Spatial(Database::VAR_POINT)), 'Default value for attribute when not provided, as JSON string. Cannot be set when attribute is required.', true)
|
||||
->param('newKey', null, new Key(), 'New attribute key.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ class Create extends PointCreate
|
||||
->param('tableId', '', new UID(), 'Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreate).')
|
||||
->param('key', '', new Key(), 'Column Key.')
|
||||
->param('required', null, new Boolean(), 'Is column required?')
|
||||
->param('default', null, new Nullable(new Spatial(Database::VAR_POINT)), 'Default value for column when not provided, as JSON string. Cannot be set when column is required.',true)
|
||||
->param('default', null, new Nullable(new Spatial(Database::VAR_POINT)), 'Default value for column when not provided, as JSON string. Cannot be set when column is required.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForDatabase')
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@ class Update extends PointUpdate
|
||||
->param('tableId', '', new UID(), 'Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreate).')
|
||||
->param('key', '', new Key(), 'Column Key.')
|
||||
->param('required', null, new Boolean(), 'Is column required?')
|
||||
->param('default', null, new Nullable(new Spatial(Database::VAR_POINT)), 'Default value for column when not provided, as JSON string. Cannot be set when column is required.',true)
|
||||
->param('default', null, new Nullable(new Spatial(Database::VAR_POINT)), 'Default value for column when not provided, as JSON string. Cannot be set when column is required.', true)
|
||||
->param('newKey', null, new Key(), 'New Column Key.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
|
||||
-1
@@ -57,7 +57,6 @@ class Create extends PolygonCreate
|
||||
->param('key', '', new Key(), 'Column Key.')
|
||||
->param('required', null, new Boolean(), 'Is column required?')
|
||||
->param('default', null, new Nullable(new Spatial(Database::VAR_POLYGON)), 'Default value for column when not provided, as JSON string. Cannot be set when column is required.', true)
|
||||
->param('array', false, new Boolean(), 'Is column an array?', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForDatabase')
|
||||
|
||||
@@ -7572,4 +7572,159 @@ trait DatabasesBase
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
}
|
||||
|
||||
public function testSpatialDistanceInMeter(): void
|
||||
{
|
||||
$database = $this->client->call(Client::METHOD_POST, '/databases', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
], [
|
||||
'databaseId' => ID::unique(),
|
||||
'name' => 'Spatial Distance Meters Database'
|
||||
]);
|
||||
|
||||
$databaseId = $database['body']['$id'];
|
||||
|
||||
// Create collection with spatial attribute
|
||||
$collection = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'collectionId' => ID::unique(),
|
||||
'name' => 'Spatial Distance Meters Collection',
|
||||
'documentSecurity' => true,
|
||||
'permissions' => [
|
||||
Permission::create(Role::any()),
|
||||
Permission::read(Role::any()),
|
||||
Permission::update(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
],
|
||||
]);
|
||||
|
||||
$collectionId = $collection['body']['$id'];
|
||||
|
||||
// Create point attribute
|
||||
$response = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/point', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'loc',
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
$this->assertEquals(202, $response['headers']['status-code']);
|
||||
sleep(2);
|
||||
|
||||
// Create spatial index
|
||||
$indexResponse = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/indexes', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'idx_loc',
|
||||
'type' => Database::INDEX_SPATIAL,
|
||||
'attributes' => ['loc'],
|
||||
]);
|
||||
|
||||
sleep(2);
|
||||
$this->assertEquals(202, $indexResponse['headers']['status-code']);
|
||||
|
||||
|
||||
// Two points roughly ~1000 meters apart by latitude delta (~0.009 deg ≈ 1km)
|
||||
$p0 = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'documentId' => 'p0',
|
||||
'data' => [
|
||||
'loc' => [0.0000, 0.0000]
|
||||
]
|
||||
]);
|
||||
|
||||
$p1 = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'documentId' => 'p1',
|
||||
'data' => [
|
||||
'loc' => [0.0090, 0.0000]
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $p0['headers']['status-code']);
|
||||
$this->assertEquals(201, $p1['headers']['status-code']);
|
||||
|
||||
// distanceLessThan with meters=true: within 1500m should include both
|
||||
$within1_5km = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::distanceLessThan('loc', [0.0000, 0.0000], 1500, true)->toString()]
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $within1_5km['headers']['status-code']);
|
||||
$this->assertCount(2, $within1_5km['body']['documents']);
|
||||
|
||||
// Within 500m should include only p0 (exact point)
|
||||
$within500m = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::distanceLessThan('loc', [0.0000, 0.0000], 500, true)->toString()]
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $within500m['headers']['status-code']);
|
||||
$this->assertCount(1, $within500m['body']['documents']);
|
||||
$this->assertEquals('p0', $within500m['body']['documents'][0]['$id']);
|
||||
|
||||
// distanceGreaterThan 500m should include only p1
|
||||
$greater500m = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::distanceGreaterThan('loc', [0.0000, 0.0000], 500, true)->toString()]
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $greater500m['headers']['status-code']);
|
||||
$this->assertCount(1, $greater500m['body']['documents']);
|
||||
$this->assertEquals('p1', $greater500m['body']['documents'][0]['$id']);
|
||||
|
||||
// distanceEqual with 0m should return exact match p0
|
||||
$equalZero = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::distanceEqual('loc', [0.0000, 0.0000], 0, true)->toString()]
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $equalZero['headers']['status-code']);
|
||||
$this->assertEquals('p0', $equalZero['body']['documents'][0]['$id']);
|
||||
|
||||
// distanceNotEqual with 0m should return p1
|
||||
$notEqualZero = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::distanceNotEqual('loc', [0.0000, 0.0000], 0, true)->toString()]
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $notEqualZero['headers']['status-code']);
|
||||
$this->assertEquals('p1', $notEqualZero['body']['documents'][0]['$id']);
|
||||
|
||||
// Cleanup
|
||||
$this->client->call(Client::METHOD_DELETE, '/databases/' . $databaseId . '/collections/' . $collectionId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
|
||||
$this->client->call(Client::METHOD_DELETE, '/databases/' . $databaseId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6406,20 +6406,14 @@ class DatabasesCustomServerTest extends Scope
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Invalid Point',
|
||||
'location' => [1000.0, 2000.0], // Invalid coordinates
|
||||
'area' => [
|
||||
[10.0, 20.0],
|
||||
[11.0, 20.0],
|
||||
[11.0, 21.0],
|
||||
[10.0, 21.0],
|
||||
[10.0, 20.0]
|
||||
]
|
||||
'location' => [1000.0, 2000.0],
|
||||
'area' => [10.0 , 10.0]
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
// Coordinates are not validated strictly; creation should succeed
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
// invalid polygon
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([
|
||||
'content-type' => 'application/json',
|
||||
@@ -6438,7 +6432,7 @@ class DatabasesCustomServerTest extends Scope
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([
|
||||
'content-type' => 'application/json',
|
||||
@@ -6720,8 +6714,7 @@ class DatabasesCustomServerTest extends Scope
|
||||
],
|
||||
]);
|
||||
|
||||
// Single point linestrings are accepted as arrays; creation should succeed
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
// Cleanup
|
||||
$this->client->call(Client::METHOD_DELETE, '/databases/' . $databaseId . '/collections/' . $collectionId, array_merge([
|
||||
|
||||
@@ -8106,7 +8106,31 @@ trait DatabasesBase
|
||||
'type' => Database::INDEX_SPATIAL,
|
||||
'columns' => ['pOptional'],
|
||||
]);
|
||||
$this->assertEquals(202, $badIndex['headers']['status-code']);
|
||||
$this->assertEquals(400, $badIndex['headers']['status-code']);
|
||||
|
||||
// making it required to create index on it
|
||||
$updated = $this->client->call(Client::METHOD_PATCH, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/point/'.'pOptional', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'required' => true,
|
||||
'default' => null
|
||||
]);
|
||||
$this->assertEquals(200, $updated['headers']['status-code']);
|
||||
|
||||
sleep(2);
|
||||
|
||||
$retriedIndex = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/indexes', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'idx_optional_point',
|
||||
'type' => Database::INDEX_SPATIAL,
|
||||
'columns' => ['pOptional'],
|
||||
]);
|
||||
$this->assertEquals(202, $retriedIndex['headers']['status-code']);
|
||||
|
||||
// Passing orders to spatial index should not throw error (in case of mariadb)
|
||||
$ordersIndex = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/indexes', array_merge([
|
||||
@@ -8292,4 +8316,100 @@ trait DatabasesBase
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
}
|
||||
public function testSpatialDistanceInMeter(): void
|
||||
{
|
||||
$headers = [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
];
|
||||
|
||||
// Create database
|
||||
$database = $this->client->call(Client::METHOD_POST, '/tablesdb', $headers, [
|
||||
'databaseId' => ID::unique(),
|
||||
'name' => 'Spatial Distance Meters Database'
|
||||
]);
|
||||
$databaseId = $database['body']['$id'];
|
||||
|
||||
// Create table
|
||||
$table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", $headers, [
|
||||
'tableId' => ID::unique(),
|
||||
'name' => 'Spatial Distance Meters Table',
|
||||
'rowSecurity' => true,
|
||||
'permissions' => [
|
||||
Permission::create(Role::any()),
|
||||
Permission::read(Role::any()),
|
||||
Permission::update(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
],
|
||||
]);
|
||||
$tableId = $table['body']['$id'];
|
||||
|
||||
// Create point column
|
||||
$resp = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/point", $headers, [
|
||||
'key' => 'loc',
|
||||
'required' => true,
|
||||
]);
|
||||
$this->assertEquals(202, $resp['headers']['status-code']);
|
||||
|
||||
sleep(2);
|
||||
|
||||
// Create spatial index
|
||||
$indexResp = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/indexes", $headers, [
|
||||
'key' => 'idx_loc',
|
||||
'type' => Database::INDEX_SPATIAL,
|
||||
'columns' => ['loc'],
|
||||
]);
|
||||
$this->assertEquals(202, $indexResp['headers']['status-code']);
|
||||
|
||||
|
||||
// Insert two points ~1km apart
|
||||
$points = [
|
||||
'p0' => [0.0000, 0.0000],
|
||||
'p1' => [0.0090, 0.0000]
|
||||
];
|
||||
|
||||
foreach ($points as $id => $loc) {
|
||||
$rowResp = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", $headers, [
|
||||
'rowId' => $id,
|
||||
'data' => ['loc' => $loc]
|
||||
]);
|
||||
$this->assertEquals(201, $rowResp['headers']['status-code']);
|
||||
}
|
||||
|
||||
// Queries
|
||||
$queries = [
|
||||
'within1_5km' => Query::distanceLessThan('loc', [0.0, 0.0], 1500, true),
|
||||
'within500m' => Query::distanceLessThan('loc', [0.0, 0.0], 500, true),
|
||||
'greater500m' => Query::distanceGreaterThan('loc', [0.0, 0.0], 500, true),
|
||||
'equal0m' => Query::distanceEqual('loc', [0.0, 0.0], 0, true),
|
||||
'notEqual0m' => Query::distanceNotEqual('loc', [0.0, 0.0], 0, true),
|
||||
];
|
||||
|
||||
// Assertions
|
||||
$results = [
|
||||
'within1_5km' => 2,
|
||||
'within500m' => 1,
|
||||
'greater500m' => 1,
|
||||
'equal0m' => 'p0',
|
||||
'notEqual0m' => 'p1'
|
||||
];
|
||||
|
||||
foreach ($queries as $key => $query) {
|
||||
$resp = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", $headers, [
|
||||
'queries' => [$query->toString()]
|
||||
]);
|
||||
$this->assertEquals(200, $resp['headers']['status-code']);
|
||||
if (is_int($results[$key])) {
|
||||
$this->assertCount($results[$key], $resp['body']['rows']);
|
||||
} else {
|
||||
$this->assertEquals($results[$key], $resp['body']['rows'][0]['$id']);
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
$this->client->call(Client::METHOD_DELETE, "/tablesdb/{$databaseId}/tables/{$tableId}", $headers);
|
||||
$this->client->call(Client::METHOD_DELETE, "/tablesdb/{$databaseId}", $headers);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6399,7 +6399,7 @@ class DatabasesCustomServerTest extends Scope
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
// Test 4c: Missing required location (should fail)
|
||||
$response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([
|
||||
@@ -6682,8 +6682,7 @@ class DatabasesCustomServerTest extends Scope
|
||||
],
|
||||
]);
|
||||
|
||||
// Single point linestrings are accepted as arrays; creation should succeed
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
// Cleanup
|
||||
$this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId . '/tables/' . $tableId, array_merge([
|
||||
|
||||
Reference in New Issue
Block a user