diff --git a/composer.json b/composer.json index 0c662c775f..cb8ac9c744 100644 --- a/composer.json +++ b/composer.json @@ -30,6 +30,12 @@ "Appwrite\\Tests\\": "tests/extensions" } }, + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/ArnabChatterjee20k/php-utopia-database.git" + } + ], "require": { "php": ">=8.3.0", "ext-curl": "*", @@ -52,7 +58,7 @@ "utopia-php/cache": "0.13.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "1.*", + "utopia-php/database": "dev-spatial-attribute-support as 1.1.6", "utopia-php/detector": "0.1.*", "utopia-php/domains": "0.8.*", "utopia-php/dns": "0.3.*", diff --git a/composer.lock b/composer.lock index 3b0d7e724a..d36f3cc2b9 100644 --- a/composer.lock +++ b/composer.lock @@ -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": "0da713ee5642eba1d30bc51c1a04a723", + "content-hash": "cc71910a644cb4707dcf1b9503acc458", "packages": [ { "name": "adhocore/jwt", @@ -3557,16 +3557,16 @@ }, { "name": "utopia-php/database", - "version": "1.1.0", + "version": "dev-spatial-attribute-support", "source": { "type": "git", - "url": "https://github.com/utopia-php/database.git", - "reference": "670e8efe7fb91f0fe43570caa5db97a1a5223357" + "url": "https://github.com/ArnabChatterjee20k/php-utopia-database.git", + "reference": "88998edfc808821fc0c04883b922335ae090e5b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/670e8efe7fb91f0fe43570caa5db97a1a5223357", - "reference": "670e8efe7fb91f0fe43570caa5db97a1a5223357", + "url": "https://api.github.com/repos/ArnabChatterjee20k/php-utopia-database/zipball/88998edfc808821fc0c04883b922335ae090e5b5", + "reference": "88998edfc808821fc0c04883b922335ae090e5b5", "shasum": "" }, "require": { @@ -3593,7 +3593,38 @@ "Utopia\\Database\\": "src/Database" } }, - "notification-url": "https://packagist.org/downloads/", + "autoload-dev": { + "psr-4": { + "Tests\\E2E\\": "tests/e2e", + "Tests\\Unit\\": "tests/unit" + } + }, + "scripts": { + "build": [ + "Composer\\Config::disableProcessTimeout", + "docker compose build" + ], + "start": [ + "Composer\\Config::disableProcessTimeout", + "docker compose up -d" + ], + "test": [ + "Composer\\Config::disableProcessTimeout", + "docker compose exec tests vendor/bin/phpunit --configuration phpunit.xml" + ], + "lint": [ + "php -d memory_limit=2G ./vendor/bin/pint --test" + ], + "format": [ + "php -d memory_limit=2G ./vendor/bin/pint" + ], + "check": [ + "./vendor/bin/phpstan analyse --level 7 src tests --memory-limit 2G" + ], + "coverage": [ + "./vendor/bin/coverage-check ./tmp/clover.xml 90" + ] + }, "license": [ "MIT" ], @@ -3606,10 +3637,9 @@ "utopia" ], "support": { - "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/1.1.0" + "source": "https://github.com/ArnabChatterjee20k/php-utopia-database/tree/spatial-attribute-support" }, - "time": "2025-08-21T15:37:11+00:00" + "time": "2025-08-26T15:18:37+00:00" }, { "name": "utopia-php/detector", @@ -3861,16 +3891,16 @@ }, { "name": "utopia-php/framework", - "version": "0.33.21", + "version": "0.33.22", "source": { "type": "git", "url": "https://github.com/utopia-php/http.git", - "reference": "eb0e82e90b8fa493f99b8d131bdd25173422c493" + "reference": "c01a815cb976c9255e045fc3bcc3f5fcf477e0bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/http/zipball/eb0e82e90b8fa493f99b8d131bdd25173422c493", - "reference": "eb0e82e90b8fa493f99b8d131bdd25173422c493", + "url": "https://api.github.com/repos/utopia-php/http/zipball/c01a815cb976c9255e045fc3bcc3f5fcf477e0bc", + "reference": "c01a815cb976c9255e045fc3bcc3f5fcf477e0bc", "shasum": "" }, "require": { @@ -3902,9 +3932,9 @@ ], "support": { "issues": "https://github.com/utopia-php/http/issues", - "source": "https://github.com/utopia-php/http/tree/0.33.21" + "source": "https://github.com/utopia-php/http/tree/0.33.22" }, - "time": "2025-08-19T10:52:15+00:00" + "time": "2025-08-26T10:29:50+00:00" }, { "name": "utopia-php/image", @@ -4926,16 +4956,16 @@ "packages-dev": [ { "name": "appwrite/sdk-generator", - "version": "1.1.4", + "version": "1.1.14", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "4196a50d4cd847e2d7f8dd1136fc0ee96e931043" + "reference": "662c7a53e683ed941c7d1374cfd32533bf54fbca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/4196a50d4cd847e2d7f8dd1136fc0ee96e931043", - "reference": "4196a50d4cd847e2d7f8dd1136fc0ee96e931043", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/662c7a53e683ed941c7d1374cfd32533bf54fbca", + "reference": "662c7a53e683ed941c7d1374cfd32533bf54fbca", "shasum": "" }, "require": { @@ -4971,9 +5001,9 @@ "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", "support": { "issues": "https://github.com/appwrite/sdk-generator/issues", - "source": "https://github.com/appwrite/sdk-generator/tree/1.1.4" + "source": "https://github.com/appwrite/sdk-generator/tree/1.1.14" }, - "time": "2025-08-21T09:46:01+00:00" + "time": "2025-08-26T13:17:07+00:00" }, { "name": "doctrine/annotations", @@ -8425,9 +8455,18 @@ "time": "2024-03-07T20:33:40+00:00" } ], - "aliases": [], + "aliases": [ + { + "package": "utopia-php/database", + "version": "dev-spatial-attribute-support", + "alias": "1.1.6", + "alias_normalized": "1.1.6.0" + } + ], "minimum-stability": "stable", - "stability-flags": {}, + "stability-flags": { + "utopia-php/database": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { diff --git a/tests/e2e/Services/Databases/Legacy/DatabasesBase.php b/tests/e2e/Services/Databases/Legacy/DatabasesBase.php index ede9abf658..cb1244aad3 100644 --- a/tests/e2e/Services/Databases/Legacy/DatabasesBase.php +++ b/tests/e2e/Services/Databases/Legacy/DatabasesBase.php @@ -6563,7 +6563,7 @@ trait DatabasesBase 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'queries' => [Query::distance('pointAttr', [[[6.0, 6.0], 1.0]])->toString()] + 'queries' => [Query::distanceEqual('pointAttr', [6.0, 6.0], 1.0)->toString()] ]); $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals(1, $response['body']['total']); @@ -6574,7 +6574,7 @@ trait DatabasesBase 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'queries' => [Query::notDistance('pointAttr', [[[6.0, 6.0], 1.0]])->toString()] + 'queries' => [Query::distanceNotEqual('pointAttr', [6.0, 6.0], 1.0)->toString()] ]); $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals(2, $response['body']['total']); @@ -6584,7 +6584,7 @@ trait DatabasesBase 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'queries' => [Query::distanceGreaterThan('pointAttr', [[[6.0, 6.0], 5.0]])->toString()] + 'queries' => [Query::distanceGreaterThan('pointAttr', [6.0, 6.0], 5.0)->toString()] ]); $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals(1, $response['body']['total']); @@ -6594,7 +6594,7 @@ trait DatabasesBase 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'queries' => [Query::distanceLessThan('pointAttr', [[[6.0, 6.0], 0.5]])->toString()] + 'queries' => [Query::distanceLessThan('pointAttr', [6.0, 6.0], 0.5)->toString()] ]); $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals(1, $response['body']['total']); diff --git a/tests/e2e/Services/Databases/TablesDB/DatabasesBase.php b/tests/e2e/Services/Databases/TablesDB/DatabasesBase.php index 8c0670e191..2e83719909 100644 --- a/tests/e2e/Services/Databases/TablesDB/DatabasesBase.php +++ b/tests/e2e/Services/Databases/TablesDB/DatabasesBase.php @@ -7719,8 +7719,8 @@ trait DatabasesBase 'queries' => [Query::equal('name', ['Test Row 1'])->toString()] ]); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertCount(1, $response['body']['documents']); - $this->assertEquals('row1', $response['body']['documents'][0]['$id']); + $this->assertCount(1, $response['body']['rows']); + $this->assertEquals('row1', $response['body']['rows'][0]['$id']); // Polygon column queries $response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([ @@ -7730,8 +7730,8 @@ trait DatabasesBase 'queries' => [Query::equal('polyAttr', [[[[0.0, 0.0], [10.0, 0.0], [10.0, 10.0], [0.0, 10.0], [0.0, 0.0]]]])->toString()] ]); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertCount(1, $response['body']['documents']); - $this->assertEquals('row1', $response['body']['documents'][0]['$id']); + $this->assertCount(1, $response['body']['rows']); + $this->assertEquals('row1', $response['body']['rows'][0]['$id']); // Not equal queries $response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([ @@ -7741,7 +7741,7 @@ trait DatabasesBase 'queries' => [Query::notEqual('pointAttr', [[6.0, 6.0]])->toString()] ]); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertCount(2, $response['body']['documents']); + $this->assertCount(2, $response['body']['rows']); // contains on line (point on line) $response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([ @@ -7751,8 +7751,8 @@ trait DatabasesBase 'queries' => [Query::contains('lineAttr', [[1.0, 1.0]])->toString()] ]); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertCount(1, $response['body']['documents']); - $this->assertEquals('row1', $response['body']['documents'][0]['$id']); + $this->assertCount(1, $response['body']['rows']); + $this->assertEquals('row1', $response['body']['rows'][0]['$id']); // notContains on polygon (point outside all polygons) $response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([ @@ -7773,7 +7773,7 @@ trait DatabasesBase ]); $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals(1, $response['body']['total']); - $this->assertEquals('row1', $response['body']['documents'][0]['$id']); + $this->assertEquals('row1', $response['body']['rows'][0]['$id']); // notIntersects on polygon (point outside all polygons) $response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([ @@ -7795,7 +7795,7 @@ trait DatabasesBase ]); $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals(1, $response['body']['total']); - $this->assertEquals('row1', $response['body']['documents'][0]['$id']); + $this->assertEquals('row1', $response['body']['rows'][0]['$id']); // notOverlaps on polygon (polygon that overlaps none) $noOverlapPoly = [[[60.0, 60.0], [70.0, 60.0], [70.0, 70.0], [60.0, 70.0], [60.0, 60.0]]]; @@ -7813,18 +7813,18 @@ trait DatabasesBase 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'queries' => [Query::distance('pointAttr', [[[6.0, 6.0], 1.0]])->toString()] + 'queries' => [Query::distanceEqual('pointAttr', [6.0, 6.0], 1.0)->toString()] ]); $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals(1, $response['body']['total']); - $this->assertEquals('row2', $response['body']['documents'][0]['$id']); + $this->assertEquals('row2', $response['body']['rows'][0]['$id']); // notDistance (outside radius) on point $response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'queries' => [Query::notDistance('pointAttr', [[[6.0, 6.0], 1.0]])->toString()] + 'queries' => [Query::distanceNotEqual('pointAttr', [6.0, 6.0], 1.0)->toString()] ]); $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals(2, $response['body']['total']); @@ -7834,7 +7834,7 @@ trait DatabasesBase 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'queries' => [Query::distanceGreaterThan('pointAttr', [[[6.0, 6.0], 5.0]])->toString()] + 'queries' => [Query::distanceGreaterThan('pointAttr', [6.0, 6.0], 5.0)->toString()] ]); $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals(1, $response['body']['total']); @@ -7844,7 +7844,7 @@ trait DatabasesBase 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'queries' => [Query::distanceLessThan('pointAttr', [[[6.0, 6.0], 0.5]])->toString()] + 'queries' => [Query::distanceLessThan('pointAttr', [6.0, 6.0], 0.5)->toString()] ]); $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals(1, $response['body']['total']); @@ -7859,7 +7859,7 @@ trait DatabasesBase ]); $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals(1, $response['body']['total']); - $this->assertEquals('row1', $response['body']['documents'][0]['$id']); + $this->assertEquals('row1', $response['body']['rows'][0]['$id']); // notCrosses on line (query line does not cross any stored lines) $nonCrossLine = [[0.0, 1.0], [0.0, 2.0]]; @@ -7882,7 +7882,7 @@ trait DatabasesBase ]); $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals(2, $response['body']['total']); - $this->assertEquals('row1', $response['body']['documents'][0]['$id']); + $this->assertEquals('row1', $response['body']['rows'][0]['$id']); // notTouches on polygon (polygon far away should not touch) $farPoly = [[[60.0, 60.0], [70.0, 60.0], [70.0, 70.0], [60.0, 70.0], [60.0, 60.0]]]; @@ -7903,8 +7903,8 @@ trait DatabasesBase 'queries' => [Query::select(['name', 'pointAttr'])->toString()] ]); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertCount(3, $response['body']['documents']); - foreach ($response['body']['documents'] as $doc) { + $this->assertCount(3, $response['body']['rows']); + foreach ($response['body']['rows'] as $doc) { $this->assertArrayHasKey('name', $doc); $this->assertArrayHasKey('pointAttr', $doc); $this->assertArrayNotHasKey('lineAttr', $doc); @@ -7919,10 +7919,10 @@ trait DatabasesBase 'queries' => [Query::orderAsc('name')->toString()] ]); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertCount(3, $response['body']['documents']); - $this->assertEquals('Test Row 1', $response['body']['documents'][0]['name']); - $this->assertEquals('Test Row 2', $response['body']['documents'][1]['name']); - $this->assertEquals('Test Row 3', $response['body']['documents'][2]['name']); + $this->assertCount(3, $response['body']['rows']); + $this->assertEquals('Test Row 1', $response['body']['rows'][0]['name']); + $this->assertEquals('Test Row 2', $response['body']['rows'][1]['name']); + $this->assertEquals('Test Row 3', $response['body']['rows'][2]['name']); // Limit results $response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([ @@ -7932,7 +7932,7 @@ trait DatabasesBase 'queries' => [Query::limit(2)->toString()] ]); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertCount(2, $response['body']['documents']); + $this->assertCount(2, $response['body']['rows']); // Offset results $response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([ @@ -7942,7 +7942,7 @@ trait DatabasesBase 'queries' => [Query::offset(1)->toString(), Query::limit(2)->toString()] ]); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertEquals(2, $response['body']['documents']); + $this->assertCount(2, $response['body']['rows']); // Complex query with multiple conditions $response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([ @@ -7956,8 +7956,8 @@ trait DatabasesBase ] ]); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertCount(1, $response['body']['documents']); - $this->assertEquals('Test Row 1', $response['body']['documents'][0]['name']); + $this->assertCount(1, $response['body']['rows']); + $this->assertEquals('Test Row 1', $response['body']['rows'][0]['name']); // Query with no results $response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([ @@ -7967,7 +7967,7 @@ trait DatabasesBase 'queries' => [Query::equal('name', ['Non-existent Row'])->toString()] ]); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertCount(0, $response['body']['documents']); + $this->assertCount(0, $response['body']['rows']); // Cleanup $this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId . '/tables/' . $tableId, array_merge([