mirror of
https://github.com/appwrite/appwrite
synced 2026-05-24 09:28:40 +00:00
Merge pull request #10356 from appwrite/spatial-type-attributes
Spatial type attributes
This commit is contained in:
commit
0c139721e4
52 changed files with 5972 additions and 48 deletions
|
|
@ -842,6 +842,12 @@ return [
|
|||
'code' => 400,
|
||||
],
|
||||
|
||||
Exception::ATTRIBUTE_TYPE_NOT_SUPPORTED => [
|
||||
'name' => Exception::ATTRIBUTE_TYPE_NOT_SUPPORTED,
|
||||
'description' => 'Attribute type is not supported.',
|
||||
'code' => 400,
|
||||
],
|
||||
|
||||
/** Exists for both Attributes & Columns */
|
||||
Exception::RELATIONSHIP_VALUE_INVALID => [
|
||||
'name' => Exception::RELATIONSHIP_VALUE_INVALID,
|
||||
|
|
@ -900,6 +906,11 @@ return [
|
|||
'description' => "Existing data is too large for new size, truncate your existing data then try again.",
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::COLUMN_TYPE_NOT_SUPPORTED => [
|
||||
'name' => Exception::COLUMN_TYPE_NOT_SUPPORTED,
|
||||
'description' => 'Column type is not supported.',
|
||||
'code' => 400,
|
||||
],
|
||||
|
||||
/** Indexes */
|
||||
Exception::INDEX_NOT_FOUND => [
|
||||
|
|
|
|||
|
|
@ -46,6 +46,9 @@ const APP_DATABASE_ATTRIBUTE_DATETIME = 'datetime';
|
|||
const APP_DATABASE_ATTRIBUTE_URL = 'url';
|
||||
const APP_DATABASE_ATTRIBUTE_INT_RANGE = 'intRange';
|
||||
const APP_DATABASE_ATTRIBUTE_FLOAT_RANGE = 'floatRange';
|
||||
const APP_DATABASE_ATTRIBUTE_POINT = 'point';
|
||||
const APP_DATABASE_ATTRIBUTE_LINE = 'line';
|
||||
const APP_DATABASE_ATTRIBUTE_POLYGON = 'polygon';
|
||||
const APP_DATABASE_ATTRIBUTE_STRING_MAX_LENGTH = 1_073_741_824; // 2^32 bits / 4 bits per char
|
||||
const APP_DATABASE_TIMEOUT_MILLISECONDS_API = 15 * 1000; // 15 seconds
|
||||
const APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER = 300 * 1000; // 5 minutes
|
||||
|
|
|
|||
169
composer.lock
generated
169
composer.lock
generated
|
|
@ -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.3",
|
||||
"version": "1.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/database.git",
|
||||
"reference": "8a536fead840d9da6ee819fe6b80e0f047997f69"
|
||||
"reference": "06ffa2b1c977f5451200a1ee82a500be1390a789"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/8a536fead840d9da6ee819fe6b80e0f047997f69",
|
||||
"reference": "8a536fead840d9da6ee819fe6b80e0f047997f69",
|
||||
"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.3"
|
||||
"source": "https://github.com/utopia-php/database/tree/1.3.0"
|
||||
},
|
||||
"time": "2025-08-27T11:47:04+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
docs/references/databases/create-line-attribute.md
Normal file
1
docs/references/databases/create-line-attribute.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Create a geometric line attribute.
|
||||
1
docs/references/databases/create-point-attribute.md
Normal file
1
docs/references/databases/create-point-attribute.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Create a geometric 2d point attribute.
|
||||
1
docs/references/databases/create-polygon-attribute.md
Normal file
1
docs/references/databases/create-polygon-attribute.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Create a geometric polygon attribute.
|
||||
1
docs/references/databases/update-line-attribute.md
Normal file
1
docs/references/databases/update-line-attribute.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Update a line attribute. Changing the `default` value will not update already existing documents.
|
||||
1
docs/references/databases/update-point-attribute.md
Normal file
1
docs/references/databases/update-point-attribute.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Update a point attribute. Changing the `default` value will not update already existing documents.
|
||||
1
docs/references/databases/update-polygon-attribute.md
Normal file
1
docs/references/databases/update-polygon-attribute.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Update a polygon attribute. Changing the `default` value will not update already existing documents.
|
||||
1
docs/references/tablesdb/create-line-column.md
Normal file
1
docs/references/tablesdb/create-line-column.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Create a geometric line attribute.
|
||||
1
docs/references/tablesdb/create-point-column.md
Normal file
1
docs/references/tablesdb/create-point-column.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Create a geometric point attribute.
|
||||
1
docs/references/tablesdb/create-polygon-column.md
Normal file
1
docs/references/tablesdb/create-polygon-column.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Create a geometric polygon attribute.
|
||||
1
docs/references/tablesdb/update-line-column.md
Normal file
1
docs/references/tablesdb/update-line-column.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Update a line column. Changing the `default` value will not update already existing documents.
|
||||
1
docs/references/tablesdb/update-point-column.md
Normal file
1
docs/references/tablesdb/update-point-column.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Update a point column. Changing the `default` value will not update already existing documents.
|
||||
1
docs/references/tablesdb/update-polygon-column.md
Normal file
1
docs/references/tablesdb/update-polygon-column.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Update a polygon column. Changing the `default` value will not update already existing documents.
|
||||
|
|
@ -235,6 +235,8 @@ class Exception extends \Exception
|
|||
public const ATTRIBUTE_TYPE_INVALID = 'attribute_type_invalid';
|
||||
public const ATTRIBUTE_INVALID_RESIZE = 'attribute_invalid_resize';
|
||||
|
||||
public const ATTRIBUTE_TYPE_NOT_SUPPORTED = 'ATTRIBUTE_TYPE_NOT_SUPPORTED';
|
||||
|
||||
/** Columns */
|
||||
public const COLUMN_NOT_FOUND = 'column_not_found';
|
||||
public const COLUMN_UNKNOWN = 'column_unknown';
|
||||
|
|
@ -247,6 +249,8 @@ class Exception extends \Exception
|
|||
public const COLUMN_TYPE_INVALID = 'column_type_invalid';
|
||||
public const COLUMN_INVALID_RESIZE = 'column_invalid_resize';
|
||||
|
||||
public const COLUMN_TYPE_NOT_SUPPORTED = 'COLUMN_TYPE_NOT_SUPPORTED';
|
||||
|
||||
/** Relationship */
|
||||
public const RELATIONSHIP_VALUE_INVALID = 'relationship_value_invalid';
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ class Mapper
|
|||
'json' => Types::json(),
|
||||
'none' => Types::json(),
|
||||
'any' => Types::json(),
|
||||
'spatial' => Types::json(),
|
||||
];
|
||||
|
||||
foreach ($defaults as $type => $default) {
|
||||
|
|
@ -456,6 +457,9 @@ class Mapper
|
|||
'boolean' => static::model("{$prefix}Boolean"),
|
||||
'datetime' => static::model("{$prefix}Datetime"),
|
||||
'relationship' => static::model("{$prefix}Relationship"),
|
||||
'point' => static::model("{$prefix}Point"),
|
||||
'linestring' => static::model("{$prefix}Line"),
|
||||
'polygon' => static::model("{$prefix}Polygon"),
|
||||
default => throw new Exception('Unknown ' . strtolower($prefix) . ' implementation'),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -209,6 +209,14 @@ abstract class Action extends UtopiaAction
|
|||
: Exception::COLUMN_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the exception for spatial type attribute not supported by the database adapter
|
||||
*/
|
||||
protected function getSpatialTypeNotSupportedException(): string
|
||||
{
|
||||
return $this->isCollectionsAPI() ? Exception::ATTRIBUTE_TYPE_NOT_SUPPORTED : Exception::COLUMN_TYPE_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the correct collections context for Events queue.
|
||||
*/
|
||||
|
|
@ -245,6 +253,18 @@ abstract class Action extends UtopiaAction
|
|||
? UtopiaResponse::MODEL_ATTRIBUTE_RELATIONSHIP
|
||||
: UtopiaResponse::MODEL_COLUMN_RELATIONSHIP,
|
||||
|
||||
Database::VAR_POINT => $isCollections
|
||||
? UtopiaResponse::MODEL_ATTRIBUTE_POINT
|
||||
: UtopiaResponse::MODEL_COLUMN_POINT,
|
||||
|
||||
Database::VAR_LINESTRING => $isCollections
|
||||
? UtopiaResponse::MODEL_ATTRIBUTE_LINE
|
||||
: UtopiaResponse::MODEL_COLUMN_LINE,
|
||||
|
||||
Database::VAR_POLYGON => $isCollections
|
||||
? UtopiaResponse::MODEL_ATTRIBUTE_POLYGON
|
||||
: UtopiaResponse::MODEL_COLUMN_POLYGON,
|
||||
|
||||
Database::VAR_STRING => match ($format) {
|
||||
APP_DATABASE_ATTRIBUTE_EMAIL => $isCollections
|
||||
? UtopiaResponse::MODEL_ATTRIBUTE_EMAIL
|
||||
|
|
@ -286,6 +306,10 @@ abstract class Action extends UtopiaAction
|
|||
$default = $attribute->getAttribute('default');
|
||||
$options = $attribute->getAttribute('options', []);
|
||||
|
||||
if (in_array($type, Database::SPATIAL_TYPES) && !$dbForProject->getAdapter()->getSupportForSpatialAttributes()) {
|
||||
throw new Exception($this->getSpatialTypeNotSupportedException());
|
||||
}
|
||||
|
||||
$db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
|
||||
|
||||
if ($db->isEmpty()) {
|
||||
|
|
@ -434,7 +458,7 @@ abstract class Action extends UtopiaAction
|
|||
return $attribute;
|
||||
}
|
||||
|
||||
protected function updateAttribute(string $databaseId, string $collectionId, string $key, Database $dbForProject, Event $queueForEvents, string $type, int $size = null, string $filter = null, string|bool|int|float $default = null, bool $required = null, int|float|null $min = null, int|float|null $max = null, array $elements = null, array $options = [], string $newKey = null): Document
|
||||
protected function updateAttribute(string $databaseId, string $collectionId, string $key, Database $dbForProject, Event $queueForEvents, string $type, int $size = null, string $filter = null, string|bool|int|float|array $default = null, bool $required = null, int|float|null $min = null, int|float|null $max = null, array $elements = null, array $options = [], string $newKey = null): Document
|
||||
{
|
||||
$db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Line;
|
||||
|
||||
use Appwrite\Event\Database as EventDatabase;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Action;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Deprecated;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Database\Validator\Spatial;
|
||||
use Appwrite\Utopia\Response as UtopiaResponse;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Validator\Key;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Swoole\Response as SwooleResponse;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Nullable;
|
||||
|
||||
class Create extends Action
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'createLineAttribute';
|
||||
}
|
||||
|
||||
protected function getResponseModel(): string|array
|
||||
{
|
||||
return UtopiaResponse::MODEL_ATTRIBUTE_LINE;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(self::HTTP_REQUEST_METHOD_POST)
|
||||
->setHttpPath('/v1/databases/:databaseId/collections/:collectionId/attributes/line')
|
||||
->desc('Create line attribute')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create')
|
||||
->label('scope', 'collections.write')
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('audits.event', 'attribute.create')
|
||||
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
|
||||
->label('sdk', new Method(
|
||||
namespace: $this->getSdkNamespace(),
|
||||
group: $this->getSdkGroup(),
|
||||
name: self::getName(),
|
||||
description: '/docs/references/databases/create-line-attribute.md',
|
||||
auth: [AuthType::KEY],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: SwooleResponse::STATUS_CODE_ACCEPTED,
|
||||
model: $this->getResponseModel(),
|
||||
)
|
||||
],
|
||||
deprecated: new Deprecated(
|
||||
since: '1.8.0',
|
||||
replaceWith: 'tablesDB.createLineColumn',
|
||||
),
|
||||
))
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
|
||||
->param('key', '', new Key(), 'Attribute Key.')
|
||||
->param('required', null, new Boolean(), 'Is attribute required?')
|
||||
->param('default', null, new Nullable(new Spatial(Database::VAR_LINESTRING)), 'Default value for attribute when not provided, as JSON string. Cannot be set when attribute is required.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForDatabase')
|
||||
->inject('queueForEvents')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents): void
|
||||
{
|
||||
$default = \is_string($default) ? \json_decode($default, true) : $default;
|
||||
|
||||
$attribute = $this->createAttribute($databaseId, $collectionId, new Document([
|
||||
'key' => $key,
|
||||
'type' => Database::VAR_LINESTRING,
|
||||
'required' => $required,
|
||||
'default' => $default
|
||||
]), $response, $dbForProject, $queueForDatabase, $queueForEvents);
|
||||
|
||||
$response
|
||||
->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED)
|
||||
->dynamic($attribute, $this->getResponseModel());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Line;
|
||||
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Action;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\ContentType;
|
||||
use Appwrite\SDK\Deprecated;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Database\Validator\Spatial;
|
||||
use Appwrite\Utopia\Response as UtopiaResponse;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Validator\Key;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Swoole\Response as SwooleResponse;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Nullable;
|
||||
|
||||
class Update extends Action
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'updateLineAttribute';
|
||||
}
|
||||
|
||||
protected function getResponseModel(): string|array
|
||||
{
|
||||
return UtopiaResponse::MODEL_ATTRIBUTE_LINE;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH)
|
||||
->setHttpPath('/v1/databases/:databaseId/collections/:collectionId/attributes/line/:key')
|
||||
->desc('Update line attribute')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', 'collections.write')
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update')
|
||||
->label('audits.event', 'attribute.update')
|
||||
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
|
||||
->label('sdk', new Method(
|
||||
namespace: $this->getSdkNamespace(),
|
||||
group: $this->getSdkGroup(),
|
||||
name: self::getName(),
|
||||
description: '/docs/references/databases/update-line-attribute.md',
|
||||
auth: [AuthType::KEY],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: SwooleResponse::STATUS_CODE_OK,
|
||||
model: $this->getResponseModel(),
|
||||
)
|
||||
],
|
||||
contentType: ContentType::JSON,
|
||||
deprecated: new Deprecated(
|
||||
since: '1.8.0',
|
||||
replaceWith: 'tablesDB.updateLineColumn',
|
||||
),
|
||||
))
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->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_LINESTRING)), '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')
|
||||
->inject('queueForEvents')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents): void
|
||||
{
|
||||
$default = \is_string($default) ? \json_decode($default, true) : $default;
|
||||
|
||||
$attribute = $this->updateAttribute(
|
||||
databaseId: $databaseId,
|
||||
collectionId: $collectionId,
|
||||
key: $key,
|
||||
dbForProject: $dbForProject,
|
||||
queueForEvents: $queueForEvents,
|
||||
type: Database::VAR_LINESTRING,
|
||||
default: $default,
|
||||
required: $required,
|
||||
newKey: $newKey
|
||||
);
|
||||
|
||||
$response
|
||||
->setStatusCode(SwooleResponse::STATUS_CODE_OK)
|
||||
->dynamic($attribute, $this->getResponseModel());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Point;
|
||||
|
||||
use Appwrite\Event\Database as EventDatabase;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Action;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Deprecated;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Database\Validator\Spatial;
|
||||
use Appwrite\Utopia\Response as UtopiaResponse;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Validator\Key;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Swoole\Response as SwooleResponse;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Nullable;
|
||||
|
||||
class Create extends Action
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'createPointAttribute';
|
||||
}
|
||||
|
||||
protected function getResponseModel(): string|array
|
||||
{
|
||||
return UtopiaResponse::MODEL_ATTRIBUTE_POINT;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(self::HTTP_REQUEST_METHOD_POST)
|
||||
->setHttpPath('/v1/databases/:databaseId/collections/:collectionId/attributes/point')
|
||||
->desc('Create point attribute')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create')
|
||||
->label('scope', 'collections.write')
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('audits.event', 'attribute.create')
|
||||
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
|
||||
->label('sdk', new Method(
|
||||
namespace: $this->getSdkNamespace(),
|
||||
group: $this->getSdkGroup(),
|
||||
name: self::getName(),
|
||||
description: '/docs/references/databases/create-point-attribute.md',
|
||||
auth: [AuthType::KEY],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: SwooleResponse::STATUS_CODE_ACCEPTED,
|
||||
model: $this->getResponseModel(),
|
||||
)
|
||||
],
|
||||
deprecated: new Deprecated(
|
||||
since: '1.8.0',
|
||||
replaceWith: 'tablesDB.createPointColumn',
|
||||
),
|
||||
))
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
|
||||
->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)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForDatabase')
|
||||
->inject('queueForEvents')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents): void
|
||||
{
|
||||
$default = \is_string($default) ? \json_decode($default, true) : $default;
|
||||
|
||||
$attribute = $this->createAttribute($databaseId, $collectionId, new Document([
|
||||
'key' => $key,
|
||||
'type' => Database::VAR_POINT,
|
||||
'required' => $required,
|
||||
'default' => $default,
|
||||
]), $response, $dbForProject, $queueForDatabase, $queueForEvents);
|
||||
|
||||
$response
|
||||
->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED)
|
||||
->dynamic($attribute, $this->getResponseModel());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Point;
|
||||
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Action;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\ContentType;
|
||||
use Appwrite\SDK\Deprecated;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Database\Validator\Spatial;
|
||||
use Appwrite\Utopia\Response as UtopiaResponse;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Validator\Key;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Swoole\Response as SwooleResponse;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Nullable;
|
||||
|
||||
class Update extends Action
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'updatePointAttribute';
|
||||
}
|
||||
|
||||
protected function getResponseModel(): string|array
|
||||
{
|
||||
return UtopiaResponse::MODEL_ATTRIBUTE_POINT;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH)
|
||||
->setHttpPath('/v1/databases/:databaseId/collections/:collectionId/attributes/point/:key')
|
||||
->desc('Update point attribute')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', 'collections.write')
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update')
|
||||
->label('audits.event', 'attribute.update')
|
||||
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
|
||||
->label('sdk', new Method(
|
||||
namespace: $this->getSdkNamespace(),
|
||||
group: $this->getSdkGroup(),
|
||||
name: self::getName(),
|
||||
description: '/docs/references/databases/update-point-attribute.md',
|
||||
auth: [AuthType::KEY],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: SwooleResponse::STATUS_CODE_OK,
|
||||
model: $this->getResponseModel(),
|
||||
)
|
||||
],
|
||||
contentType: ContentType::JSON,
|
||||
deprecated: new Deprecated(
|
||||
since: '1.8.0',
|
||||
replaceWith: 'tablesDB.updatePointColumn',
|
||||
),
|
||||
))
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->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('newKey', null, new Key(), 'New attribute key.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents): void
|
||||
{
|
||||
$default = \is_string($default) ? \json_decode($default, true) : $default;
|
||||
|
||||
$attribute = $this->updateAttribute(
|
||||
databaseId: $databaseId,
|
||||
collectionId: $collectionId,
|
||||
key: $key,
|
||||
dbForProject: $dbForProject,
|
||||
queueForEvents: $queueForEvents,
|
||||
type: Database::VAR_POINT,
|
||||
default: $default,
|
||||
required: $required,
|
||||
newKey: $newKey
|
||||
);
|
||||
|
||||
$response
|
||||
->setStatusCode(SwooleResponse::STATUS_CODE_OK)
|
||||
->dynamic($attribute, $this->getResponseModel());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Polygon;
|
||||
|
||||
use Appwrite\Event\Database as EventDatabase;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Action;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Deprecated;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Database\Validator\Spatial;
|
||||
use Appwrite\Utopia\Response as UtopiaResponse;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Validator\Key;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Swoole\Response as SwooleResponse;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Nullable;
|
||||
|
||||
class Create extends Action
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'createPolygonAttribute';
|
||||
}
|
||||
|
||||
protected function getResponseModel(): string|array
|
||||
{
|
||||
return UtopiaResponse::MODEL_ATTRIBUTE_POLYGON;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(self::HTTP_REQUEST_METHOD_POST)
|
||||
->setHttpPath('/v1/databases/:databaseId/collections/:collectionId/attributes/polygon')
|
||||
->desc('Create polygon attribute')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create')
|
||||
->label('scope', 'collections.write')
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('audits.event', 'attribute.create')
|
||||
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
|
||||
->label('sdk', new Method(
|
||||
namespace: $this->getSdkNamespace(),
|
||||
group: $this->getSdkGroup(),
|
||||
name: self::getName(),
|
||||
description: '/docs/references/databases/create-polygon-attribute.md',
|
||||
auth: [AuthType::KEY],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: SwooleResponse::STATUS_CODE_ACCEPTED,
|
||||
model: $this->getResponseModel(),
|
||||
)
|
||||
],
|
||||
deprecated: new Deprecated(
|
||||
since: '1.8.0',
|
||||
replaceWith: 'tablesDB.createPolygonColumn',
|
||||
),
|
||||
))
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
|
||||
->param('key', '', new Key(), 'Attribute Key.')
|
||||
->param('required', null, new Boolean(), 'Is attribute required?')
|
||||
->param('default', null, new Nullable(new Spatial(Database::VAR_POLYGON)), 'Default value for attribute when not provided, as JSON string. Cannot be set when attribute is required.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForDatabase')
|
||||
->inject('queueForEvents')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents): void
|
||||
{
|
||||
$default = \is_string($default) ? \json_decode($default, true) : $default;
|
||||
|
||||
$attribute = $this->createAttribute($databaseId, $collectionId, new Document([
|
||||
'key' => $key,
|
||||
'type' => Database::VAR_POLYGON,
|
||||
'required' => $required,
|
||||
'default' => $default,
|
||||
]), $response, $dbForProject, $queueForDatabase, $queueForEvents);
|
||||
|
||||
$response
|
||||
->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED)
|
||||
->dynamic($attribute, $this->getResponseModel());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Polygon;
|
||||
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Action;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\ContentType;
|
||||
use Appwrite\SDK\Deprecated;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Database\Validator\Spatial;
|
||||
use Appwrite\Utopia\Response as UtopiaResponse;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Validator\Key;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Swoole\Response as SwooleResponse;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Nullable;
|
||||
|
||||
class Update extends Action
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'updatePolygonAttribute';
|
||||
}
|
||||
|
||||
protected function getResponseModel(): string|array
|
||||
{
|
||||
return UtopiaResponse::MODEL_ATTRIBUTE_POLYGON;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH)
|
||||
->setHttpPath('/v1/databases/:databaseId/collections/:collectionId/attributes/polygon/:key')
|
||||
->desc('Update polygon attribute')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', 'collections.write')
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update')
|
||||
->label('audits.event', 'attribute.update')
|
||||
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
|
||||
->label('sdk', new Method(
|
||||
namespace: $this->getSdkNamespace(),
|
||||
group: $this->getSdkGroup(),
|
||||
name: self::getName(),
|
||||
description: '/docs/references/databases/update-polygon-attribute.md',
|
||||
auth: [AuthType::KEY],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: SwooleResponse::STATUS_CODE_OK,
|
||||
model: $this->getResponseModel(),
|
||||
)
|
||||
],
|
||||
contentType: ContentType::JSON,
|
||||
deprecated: new Deprecated(
|
||||
since: '1.8.0',
|
||||
replaceWith: 'tablesDB.updatePolygonColumn',
|
||||
),
|
||||
))
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->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_POLYGON)), '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')
|
||||
->inject('queueForEvents')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents): void
|
||||
{
|
||||
$default = \is_string($default) ? \json_decode($default, true) : $default;
|
||||
|
||||
$attribute = $this->updateAttribute(
|
||||
databaseId: $databaseId,
|
||||
collectionId: $collectionId,
|
||||
key: $key,
|
||||
dbForProject: $dbForProject,
|
||||
queueForEvents: $queueForEvents,
|
||||
type: Database::VAR_POLYGON,
|
||||
default: $default,
|
||||
required: $required,
|
||||
newKey: $newKey
|
||||
);
|
||||
|
||||
$response
|
||||
->setStatusCode(SwooleResponse::STATUS_CODE_OK)
|
||||
->dynamic($attribute, $this->getResponseModel());
|
||||
}
|
||||
}
|
||||
|
|
@ -71,7 +71,7 @@ class Create extends Action
|
|||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
|
||||
->param('key', null, new Key(), 'Index Key.')
|
||||
->param('type', null, new WhiteList([Database::INDEX_KEY, Database::INDEX_FULLTEXT, Database::INDEX_UNIQUE]), 'Index type.')
|
||||
->param('type', null, new WhiteList([Database::INDEX_KEY, Database::INDEX_FULLTEXT, Database::INDEX_UNIQUE, Database::INDEX_SPATIAL]), 'Index type.')
|
||||
->param('attributes', null, new ArrayList(new Key(true), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of attributes to index. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' attributes are allowed, each 32 characters long.')
|
||||
->param('orders', [], new ArrayList(new WhiteList(['ASC', 'DESC'], false, Database::VAR_STRING), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of index orders. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' orders are allowed.', true)
|
||||
->param('lengths', [], new ArrayList(new Nullable(new Integer()), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Length of index. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE, optional: true)
|
||||
|
|
@ -190,11 +190,21 @@ class Create extends Action
|
|||
'orders' => $orders,
|
||||
]);
|
||||
|
||||
$maxIndexLength = $dbForProject->getAdapter()->getMaxIndexLength();
|
||||
$internalIndexesKeys = $dbForProject->getAdapter()->getInternalIndexesKeys();
|
||||
$supportForIndexArray = $dbForProject->getAdapter()->getSupportForIndexArray();
|
||||
$supportForSpatialAttributes = $dbForProject->getAdapter()->getSupportForSpatialAttributes();
|
||||
$supportForSpatialIndexNull = $dbForProject->getAdapter()->getSupportForSpatialIndexNull();
|
||||
$supportForSpatialIndexOrder = $dbForProject->getAdapter()->getSupportForSpatialIndexOrder();
|
||||
|
||||
$validator = new IndexValidator(
|
||||
$collection->getAttribute('attributes'),
|
||||
$dbForProject->getAdapter()->getMaxIndexLength(),
|
||||
$dbForProject->getAdapter()->getInternalIndexesKeys(),
|
||||
$dbForProject->getAdapter()->getSupportForIndexArray()
|
||||
$maxIndexLength,
|
||||
$internalIndexesKeys,
|
||||
$supportForIndexArray,
|
||||
$supportForSpatialAttributes,
|
||||
$supportForSpatialIndexNull,
|
||||
$supportForSpatialIndexOrder
|
||||
);
|
||||
|
||||
if (!$validator->isValid($index)) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Line;
|
||||
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Line\Create as LineCreate;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Database\Validator\Spatial;
|
||||
use Appwrite\Utopia\Response as UtopiaResponse;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Validator\Key;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Swoole\Response as SwooleResponse;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Nullable;
|
||||
|
||||
class Create extends LineCreate
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'createLineColumn';
|
||||
}
|
||||
|
||||
protected function getResponseModel(): string|array
|
||||
{
|
||||
return UtopiaResponse::MODEL_COLUMN_LINE;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(self::HTTP_REQUEST_METHOD_POST)
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/line')
|
||||
->desc('Create line column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create')
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('audits.event', 'column.create')
|
||||
->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}')
|
||||
->label('sdk', new Method(
|
||||
namespace: $this->getSdkNamespace(),
|
||||
group: $this->getSdkGroup(),
|
||||
name: self::getName(),
|
||||
description: '/docs/references/tablesdb/create-line-column.md',
|
||||
auth: [AuthType::KEY],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: SwooleResponse::STATUS_CODE_ACCEPTED,
|
||||
model: $this->getResponseModel(),
|
||||
)
|
||||
]
|
||||
))
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('tableId', '', new UID(), 'Table ID. You can create a new table using the TablesDB 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_LINESTRING)), 'Default value for column when not provided, as JSON string. Cannot be set when column is required.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForDatabase')
|
||||
->inject('queueForEvents')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Line;
|
||||
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Line\Update as LineUpdate;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\ContentType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Database\Validator\Spatial;
|
||||
use Appwrite\Utopia\Response as UtopiaResponse;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Validator\Key;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Swoole\Response as SwooleResponse;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Nullable;
|
||||
|
||||
class Update extends LineUpdate
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'updateLineColumn';
|
||||
}
|
||||
|
||||
protected function getResponseModel(): string|array
|
||||
{
|
||||
return UtopiaResponse::MODEL_COLUMN_LINE;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH)
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/line/:key')
|
||||
->desc('Update line column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
|
||||
->label('audits.event', 'column.update')
|
||||
->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}')
|
||||
->label('sdk', new Method(
|
||||
namespace: $this->getSdkNamespace(),
|
||||
group: $this->getSdkGroup(),
|
||||
name: self::getName(),
|
||||
description: '/docs/references/tablesdb/update-line-column.md',
|
||||
auth: [AuthType::KEY],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: SwooleResponse::STATUS_CODE_OK,
|
||||
model: $this->getResponseModel(),
|
||||
)
|
||||
],
|
||||
contentType: ContentType::JSON
|
||||
))
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('tableId', '', new UID(), 'Table ID. You can create a new table using the TablesDB 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_LINESTRING)), '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')
|
||||
->inject('queueForEvents')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Point;
|
||||
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Point\Create as PointCreate;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Database\Validator\Spatial;
|
||||
use Appwrite\Utopia\Response as UtopiaResponse;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Validator\Key;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Swoole\Response as SwooleResponse;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Nullable;
|
||||
|
||||
class Create extends PointCreate
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'createPointColumn';
|
||||
}
|
||||
|
||||
protected function getResponseModel(): string|array
|
||||
{
|
||||
return UtopiaResponse::MODEL_COLUMN_POINT;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(self::HTTP_REQUEST_METHOD_POST)
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/point')
|
||||
->desc('Create point column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create')
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('audits.event', 'column.create')
|
||||
->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}')
|
||||
->label('sdk', new Method(
|
||||
namespace: $this->getSdkNamespace(),
|
||||
group: $this->getSdkGroup(),
|
||||
name: self::getName(),
|
||||
description: '/docs/references/tablesdb/create-point-column.md',
|
||||
auth: [AuthType::KEY],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: SwooleResponse::STATUS_CODE_ACCEPTED,
|
||||
model: $this->getResponseModel(),
|
||||
)
|
||||
]
|
||||
))
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('tableId', '', new UID(), 'Table ID. You can create a new table using the TablesDB 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)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForDatabase')
|
||||
->inject('queueForEvents')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Point;
|
||||
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Point\Update as PointUpdate;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\ContentType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Database\Validator\Spatial;
|
||||
use Appwrite\Utopia\Response as UtopiaResponse;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Validator\Key;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Swoole\Response as SwooleResponse;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Nullable;
|
||||
|
||||
class Update extends PointUpdate
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'updatePointColumn';
|
||||
}
|
||||
|
||||
protected function getResponseModel(): string|array
|
||||
{
|
||||
return UtopiaResponse::MODEL_COLUMN_POINT;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH)
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/point/:key')
|
||||
->desc('Update point column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
|
||||
->label('audits.event', 'column.update')
|
||||
->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}')
|
||||
->label('sdk', new Method(
|
||||
namespace: $this->getSdkNamespace(),
|
||||
group: $this->getSdkGroup(),
|
||||
name: self::getName(),
|
||||
description: '/docs/references/tablesdb/update-point-column.md',
|
||||
auth: [AuthType::KEY],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: SwooleResponse::STATUS_CODE_OK,
|
||||
model: $this->getResponseModel(),
|
||||
)
|
||||
],
|
||||
contentType: ContentType::JSON
|
||||
))
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('tableId', '', new UID(), 'Table ID. You can create a new table using the TablesDB 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('newKey', null, new Key(), 'New Column Key.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Polygon;
|
||||
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Polygon\Create as PolygonCreate;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Database\Validator\Spatial;
|
||||
use Appwrite\Utopia\Response as UtopiaResponse;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Validator\Key;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Swoole\Response as SwooleResponse;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Nullable;
|
||||
|
||||
class Create extends PolygonCreate
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'createPolygonColumn';
|
||||
}
|
||||
|
||||
protected function getResponseModel(): string|array
|
||||
{
|
||||
return UtopiaResponse::MODEL_COLUMN_POLYGON;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(self::HTTP_REQUEST_METHOD_POST)
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/polygon')
|
||||
->desc('Create polygon column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create')
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('audits.event', 'column.create')
|
||||
->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}')
|
||||
->label('sdk', new Method(
|
||||
namespace: $this->getSdkNamespace(),
|
||||
group: $this->getSdkGroup(),
|
||||
name: self::getName(),
|
||||
description: '/docs/references/tablesdb/create-polygon-column.md',
|
||||
auth: [AuthType::KEY],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: SwooleResponse::STATUS_CODE_ACCEPTED,
|
||||
model: $this->getResponseModel(),
|
||||
)
|
||||
]
|
||||
))
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('tableId', '', new UID(), 'Table ID. You can create a new table using the TablesDB 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_POLYGON)), 'Default value for column when not provided, as JSON string. Cannot be set when column is required.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForDatabase')
|
||||
->inject('queueForEvents')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Polygon;
|
||||
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Polygon\Update as PolygonUpdate;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\ContentType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Database\Validator\Spatial;
|
||||
use Appwrite\Utopia\Response as UtopiaResponse;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Validator\Key;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Swoole\Response as SwooleResponse;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Nullable;
|
||||
|
||||
class Update extends PolygonUpdate
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'updatePolygonColumn';
|
||||
}
|
||||
|
||||
protected function getResponseModel(): string|array
|
||||
{
|
||||
return UtopiaResponse::MODEL_COLUMN_POLYGON;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH)
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/polygon/:key')
|
||||
->desc('Update polygon column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
|
||||
->label('audits.event', 'column.update')
|
||||
->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}')
|
||||
->label('sdk', new Method(
|
||||
namespace: $this->getSdkNamespace(),
|
||||
group: $this->getSdkGroup(),
|
||||
name: self::getName(),
|
||||
description: '/docs/references/tablesdb/update-polygon-column.md',
|
||||
auth: [AuthType::KEY],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: SwooleResponse::STATUS_CODE_OK,
|
||||
model: $this->getResponseModel(),
|
||||
)
|
||||
],
|
||||
contentType: ContentType::JSON
|
||||
))
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('tableId', '', new UID(), 'Table ID. You can create a new table using the TablesDB 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_POLYGON)), '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')
|
||||
->inject('queueForEvents')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
}
|
||||
|
|
@ -58,7 +58,7 @@ class Create extends IndexCreate
|
|||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->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', null, new Key(), 'Index Key.')
|
||||
->param('type', null, new WhiteList([Database::INDEX_KEY, Database::INDEX_FULLTEXT, Database::INDEX_UNIQUE]), 'Index type.')
|
||||
->param('type', null, new WhiteList([Database::INDEX_KEY, Database::INDEX_FULLTEXT, Database::INDEX_UNIQUE, Database::INDEX_SPATIAL]), 'Index type.')
|
||||
->param('columns', null, new ArrayList(new Key(true), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of columns to index. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' columns are allowed, each 32 characters long.')
|
||||
->param('orders', [], new ArrayList(new WhiteList(['ASC', 'DESC'], false, Database::VAR_STRING), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of index orders. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' orders are allowed.', true)
|
||||
->param('lengths', [], new ArrayList(new Nullable(new Integer()), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Length of index. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE, optional: true)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,12 @@ use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\In
|
|||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Integer\Update as UpdateIntegerAttribute;
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\IP\Create as CreateIPAttribute;
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\IP\Update as UpdateIPAttribute;
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Line\Create as CreateLineAttribute;
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Line\Update as UpdateLineAttribute;
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Point\Create as CreatePointAttribute;
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Point\Update as UpdatePointAttribute;
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Polygon\Create as CreatePolygonAttribute;
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Polygon\Update as UpdatePolygonAttribute;
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Relationship\Create as CreateRelationshipAttribute;
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Relationship\Update as UpdateRelationshipAttribute;
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\String\Create as CreateStringAttribute;
|
||||
|
|
@ -132,6 +138,18 @@ class Collections extends Base
|
|||
$service->addAction(CreateIPAttribute::getName(), new CreateIPAttribute());
|
||||
$service->addAction(UpdateIPAttribute::getName(), new UpdateIPAttribute());
|
||||
|
||||
// Attribute: Line
|
||||
$service->addAction(CreateLineAttribute::getName(), new CreateLineAttribute());
|
||||
$service->addAction(UpdateLineAttribute::getName(), new UpdateLineAttribute());
|
||||
|
||||
// Attribute: Point
|
||||
$service->addAction(CreatePointAttribute::getName(), new CreatePointAttribute());
|
||||
$service->addAction(UpdatePointAttribute::getName(), new UpdatePointAttribute());
|
||||
|
||||
// Attribute: Polygon
|
||||
$service->addAction(CreatePolygonAttribute::getName(), new CreatePolygonAttribute());
|
||||
$service->addAction(UpdatePolygonAttribute::getName(), new UpdatePolygonAttribute());
|
||||
|
||||
// Attribute: Relationship
|
||||
$service->addAction(CreateRelationshipAttribute::getName(), new CreateRelationshipAttribute());
|
||||
$service->addAction(UpdateRelationshipAttribute::getName(), new UpdateRelationshipAttribute());
|
||||
|
|
|
|||
|
|
@ -21,6 +21,12 @@ use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Integer\Cre
|
|||
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Integer\Update as UpdateInteger;
|
||||
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\IP\Create as CreateIP;
|
||||
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\IP\Update as UpdateIP;
|
||||
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Line\Create as CreateLine;
|
||||
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Line\Update as UpdateLine;
|
||||
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Point\Create as CreatePoint;
|
||||
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Point\Update as UpdatePoint;
|
||||
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Polygon\Create as CreatePolygon;
|
||||
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Polygon\Update as UpdatePolygon;
|
||||
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Relationship\Create as CreateRelationship;
|
||||
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Relationship\Update as UpdateRelationship;
|
||||
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\String\Create as CreateString;
|
||||
|
|
@ -134,6 +140,18 @@ class Tables extends Base
|
|||
$service->addAction(CreateIP::getName(), new CreateIP());
|
||||
$service->addAction(UpdateIP::getName(), new UpdateIP());
|
||||
|
||||
// Column: Line
|
||||
$service->addAction(CreateLine::getName(), new CreateLine());
|
||||
$service->addAction(UpdateLine::getName(), new UpdateLine());
|
||||
|
||||
// Column: Point
|
||||
$service->addAction(CreatePoint::getName(), new CreatePoint());
|
||||
$service->addAction(UpdatePoint::getName(), new UpdatePoint());
|
||||
|
||||
// Column: Polygon
|
||||
$service->addAction(CreatePolygon::getName(), new CreatePolygon());
|
||||
$service->addAction(UpdatePolygon::getName(), new UpdatePolygon());
|
||||
|
||||
// Column: Relationship
|
||||
$service->addAction(CreateRelationship::getName(), new CreateRelationship());
|
||||
$service->addAction(UpdateRelationship::getName(), new UpdateRelationship());
|
||||
|
|
|
|||
42
src/Appwrite/Utopia/Database/Validator/Spatial.php
Normal file
42
src/Appwrite/Utopia/Database/Validator/Spatial.php
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Utopia\Database\Validator;
|
||||
|
||||
use Utopia\Database\Validator\Spatial as SpatialValidator;
|
||||
use Utopia\Validator\JSON;
|
||||
|
||||
class Spatial extends JSON
|
||||
{
|
||||
private string $spatialAttributeType;
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Value must be a valid spatial type JSON string';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $spatialAttributeType
|
||||
*/
|
||||
public function __construct(string $spatialAttributeType)
|
||||
{
|
||||
$this->spatialAttributeType = $spatialAttributeType;
|
||||
}
|
||||
/**
|
||||
* Is valid.
|
||||
*
|
||||
* Returns true if valid or false if not.
|
||||
*
|
||||
* @param $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid($value): bool
|
||||
{
|
||||
if (!parent::isValid($value)) {
|
||||
return false;
|
||||
}
|
||||
$value = \json_decode($value, true);
|
||||
$validator = new SpatialValidator($this->spatialAttributeType);
|
||||
return $validator->isValid($value);
|
||||
}
|
||||
}
|
||||
|
|
@ -23,7 +23,10 @@ use Appwrite\Utopia\Response\Model\AttributeEnum;
|
|||
use Appwrite\Utopia\Response\Model\AttributeFloat;
|
||||
use Appwrite\Utopia\Response\Model\AttributeInteger;
|
||||
use Appwrite\Utopia\Response\Model\AttributeIP;
|
||||
use Appwrite\Utopia\Response\Model\AttributeLine;
|
||||
use Appwrite\Utopia\Response\Model\AttributeList;
|
||||
use Appwrite\Utopia\Response\Model\AttributePoint;
|
||||
use Appwrite\Utopia\Response\Model\AttributePolygon;
|
||||
use Appwrite\Utopia\Response\Model\AttributeRelationship;
|
||||
use Appwrite\Utopia\Response\Model\AttributeString;
|
||||
use Appwrite\Utopia\Response\Model\AttributeURL;
|
||||
|
|
@ -41,7 +44,10 @@ use Appwrite\Utopia\Response\Model\ColumnFloat;
|
|||
use Appwrite\Utopia\Response\Model\ColumnIndex;
|
||||
use Appwrite\Utopia\Response\Model\ColumnInteger;
|
||||
use Appwrite\Utopia\Response\Model\ColumnIP;
|
||||
use Appwrite\Utopia\Response\Model\ColumnLine;
|
||||
use Appwrite\Utopia\Response\Model\ColumnList;
|
||||
use Appwrite\Utopia\Response\Model\ColumnPoint;
|
||||
use Appwrite\Utopia\Response\Model\ColumnPolygon;
|
||||
use Appwrite\Utopia\Response\Model\ColumnRelationship;
|
||||
use Appwrite\Utopia\Response\Model\ColumnString;
|
||||
use Appwrite\Utopia\Response\Model\ColumnURL;
|
||||
|
|
@ -203,6 +209,9 @@ class Response extends SwooleResponse
|
|||
public const MODEL_ATTRIBUTE_URL = 'attributeUrl';
|
||||
public const MODEL_ATTRIBUTE_DATETIME = 'attributeDatetime';
|
||||
public const MODEL_ATTRIBUTE_RELATIONSHIP = 'attributeRelationship';
|
||||
public const MODEL_ATTRIBUTE_POINT = 'attributePoint';
|
||||
public const MODEL_ATTRIBUTE_LINE = 'attributeLine';
|
||||
public const MODEL_ATTRIBUTE_POLYGON = 'attributePolygon';
|
||||
|
||||
// Database Columns
|
||||
public const MODEL_COLUMN = 'column';
|
||||
|
|
@ -217,6 +226,9 @@ class Response extends SwooleResponse
|
|||
public const MODEL_COLUMN_URL = 'columnUrl';
|
||||
public const MODEL_COLUMN_DATETIME = 'columnDatetime';
|
||||
public const MODEL_COLUMN_RELATIONSHIP = 'columnRelationship';
|
||||
public const MODEL_COLUMN_POINT = 'columnPoint';
|
||||
public const MODEL_COLUMN_LINE = 'columnLine';
|
||||
public const MODEL_COLUMN_POLYGON = 'columnPolygon';
|
||||
|
||||
// Users
|
||||
public const MODEL_ACCOUNT = 'account';
|
||||
|
|
@ -482,6 +494,9 @@ class Response extends SwooleResponse
|
|||
->setModel(new AttributeURL())
|
||||
->setModel(new AttributeDatetime())
|
||||
->setModel(new AttributeRelationship())
|
||||
->setModel(new AttributePoint())
|
||||
->setModel(new AttributeLine())
|
||||
->setModel(new AttributePolygon())
|
||||
// Table API Models
|
||||
->setModel(new Table())
|
||||
->setModel(new Column())
|
||||
|
|
@ -496,6 +511,9 @@ class Response extends SwooleResponse
|
|||
->setModel(new ColumnURL())
|
||||
->setModel(new ColumnDatetime())
|
||||
->setModel(new ColumnRelationship())
|
||||
->setModel(new ColumnPoint())
|
||||
->setModel(new ColumnLine())
|
||||
->setModel(new ColumnPolygon())
|
||||
->setModel(new Index())
|
||||
->setModel(new ColumnIndex())
|
||||
->setModel(new Row())
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ abstract class Model
|
|||
public const TYPE_DATETIME_EXAMPLE = '2020-10-15T06:38:00.000+00:00';
|
||||
public const TYPE_RELATIONSHIP = 'relationship';
|
||||
public const TYPE_PAYLOAD = 'payload';
|
||||
public const TYPE_SPATIAL = 'spatial';
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
|
|
|
|||
43
src/Appwrite/Utopia/Response/Model/AttributeLine.php
Normal file
43
src/Appwrite/Utopia/Response/Model/AttributeLine.php
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Utopia\Response\Model;
|
||||
|
||||
use Appwrite\Utopia\Response;
|
||||
|
||||
class AttributeLine extends Attribute
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this
|
||||
->addRule('default', [
|
||||
'type' => self::TYPE_SPATIAL,
|
||||
'description' => 'Default value for attribute when not provided. Cannot be set when attribute is required.',
|
||||
'default' => null,
|
||||
'required' => false,
|
||||
'example' => '[[0, 0], [1, 1]]'
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'AttributeLine';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return Response::MODEL_ATTRIBUTE_LINE;
|
||||
}
|
||||
}
|
||||
|
|
@ -27,6 +27,9 @@ class AttributeList extends Model
|
|||
Response::MODEL_ATTRIBUTE_IP,
|
||||
Response::MODEL_ATTRIBUTE_DATETIME,
|
||||
Response::MODEL_ATTRIBUTE_RELATIONSHIP,
|
||||
Response::MODEL_ATTRIBUTE_POINT,
|
||||
Response::MODEL_ATTRIBUTE_LINE,
|
||||
Response::MODEL_ATTRIBUTE_POLYGON,
|
||||
Response::MODEL_ATTRIBUTE_STRING // needs to be last, since its condition would dominate any other string attribute
|
||||
],
|
||||
'description' => 'List of attributes.',
|
||||
|
|
|
|||
43
src/Appwrite/Utopia/Response/Model/AttributePoint.php
Normal file
43
src/Appwrite/Utopia/Response/Model/AttributePoint.php
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Utopia\Response\Model;
|
||||
|
||||
use Appwrite\Utopia\Response;
|
||||
|
||||
class AttributePoint extends Attribute
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this
|
||||
->addRule('default', [
|
||||
'type' => self::TYPE_SPATIAL,
|
||||
'description' => 'Default value for attribute when not provided. Cannot be set when attribute is required.',
|
||||
'default' => null,
|
||||
'required' => false,
|
||||
'example' => '[0, 0]'
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'AttributePoint';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return Response::MODEL_ATTRIBUTE_POINT;
|
||||
}
|
||||
}
|
||||
43
src/Appwrite/Utopia/Response/Model/AttributePolygon.php
Normal file
43
src/Appwrite/Utopia/Response/Model/AttributePolygon.php
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Utopia\Response\Model;
|
||||
|
||||
use Appwrite\Utopia\Response;
|
||||
|
||||
class AttributePolygon extends Attribute
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this
|
||||
->addRule('default', [
|
||||
'type' => self::TYPE_SPATIAL,
|
||||
'description' => 'Default value for attribute when not provided. Cannot be set when attribute is required.',
|
||||
'default' => null,
|
||||
'required' => false,
|
||||
'example' => '[[[0, 0], [0, 10]], [[10, 10], [0, 0]]]'
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'AttributePolygon';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return Response::MODEL_ATTRIBUTE_POLYGON;
|
||||
}
|
||||
}
|
||||
|
|
@ -70,6 +70,9 @@ class Collection extends Model
|
|||
Response::MODEL_ATTRIBUTE_IP,
|
||||
Response::MODEL_ATTRIBUTE_DATETIME,
|
||||
Response::MODEL_ATTRIBUTE_RELATIONSHIP,
|
||||
Response::MODEL_ATTRIBUTE_POINT,
|
||||
Response::MODEL_ATTRIBUTE_LINE,
|
||||
Response::MODEL_ATTRIBUTE_POLYGON,
|
||||
Response::MODEL_ATTRIBUTE_STRING, // needs to be last, since its condition would dominate any other string attribute
|
||||
],
|
||||
'description' => 'Collection attributes.',
|
||||
|
|
|
|||
43
src/Appwrite/Utopia/Response/Model/ColumnLine.php
Normal file
43
src/Appwrite/Utopia/Response/Model/ColumnLine.php
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Utopia\Response\Model;
|
||||
|
||||
use Appwrite\Utopia\Response;
|
||||
|
||||
class ColumnLine extends Column
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this
|
||||
->addRule('default', [
|
||||
'type' => self::TYPE_SPATIAL,
|
||||
'description' => 'Default value for column when not provided. Cannot be set when column is required.',
|
||||
'default' => null,
|
||||
'required' => false,
|
||||
'example' => '[[0, 0], [1, 1]]'
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'ColumnLine';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return Response::MODEL_COLUMN_LINE;
|
||||
}
|
||||
}
|
||||
|
|
@ -27,6 +27,9 @@ class ColumnList extends Model
|
|||
Response::MODEL_COLUMN_IP,
|
||||
Response::MODEL_COLUMN_DATETIME,
|
||||
Response::MODEL_COLUMN_RELATIONSHIP,
|
||||
Response::MODEL_COLUMN_POINT,
|
||||
Response::MODEL_COLUMN_LINE,
|
||||
Response::MODEL_COLUMN_POLYGON,
|
||||
Response::MODEL_COLUMN_STRING // needs to be last, since its condition would dominate any other string attribute
|
||||
],
|
||||
'description' => 'List of columns.',
|
||||
|
|
|
|||
43
src/Appwrite/Utopia/Response/Model/ColumnPoint.php
Normal file
43
src/Appwrite/Utopia/Response/Model/ColumnPoint.php
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Utopia\Response\Model;
|
||||
|
||||
use Appwrite\Utopia\Response;
|
||||
|
||||
class ColumnPoint extends Column
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this
|
||||
->addRule('default', [
|
||||
'type' => self::TYPE_SPATIAL,
|
||||
'description' => 'Default value for column when not provided. Cannot be set when column is required.',
|
||||
'default' => null,
|
||||
'required' => false,
|
||||
'example' => '[0, 0]'
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'ColumnPoint';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return Response::MODEL_COLUMN_POINT;
|
||||
}
|
||||
}
|
||||
43
src/Appwrite/Utopia/Response/Model/ColumnPolygon.php
Normal file
43
src/Appwrite/Utopia/Response/Model/ColumnPolygon.php
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Utopia\Response\Model;
|
||||
|
||||
use Appwrite\Utopia\Response;
|
||||
|
||||
class ColumnPolygon extends Column
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this
|
||||
->addRule('default', [
|
||||
'type' => self::TYPE_SPATIAL,
|
||||
'description' => 'Default value for column when not provided. Cannot be set when column is required.',
|
||||
'default' => null,
|
||||
'required' => false,
|
||||
'example' => '[[[0, 0], [0, 10]], [[10, 10], [0, 0]]]'
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'ColumnPolygon';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return Response::MODEL_COLUMN_POLYGON;
|
||||
}
|
||||
}
|
||||
|
|
@ -71,6 +71,9 @@ class Table extends Model
|
|||
Response::MODEL_COLUMN_IP,
|
||||
Response::MODEL_COLUMN_DATETIME,
|
||||
Response::MODEL_COLUMN_RELATIONSHIP,
|
||||
Response::MODEL_COLUMN_POINT,
|
||||
Response::MODEL_COLUMN_LINE,
|
||||
Response::MODEL_COLUMN_POLYGON,
|
||||
Response::MODEL_COLUMN_STRING, // needs to be last, since its condition would dominate any other string attribute
|
||||
],
|
||||
'description' => 'Table columns.',
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -6172,4 +6172,561 @@ class DatabasesCustomServerTest extends Scope
|
|||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
}
|
||||
|
||||
public function testSpatialBulkOperations(): void
|
||||
{
|
||||
// Create database
|
||||
$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 Bulk Operations Test Database'
|
||||
]);
|
||||
|
||||
$this->assertNotEmpty($database['body']['$id']);
|
||||
$databaseId = $database['body']['$id'];
|
||||
|
||||
// Create collection with spatial attributes
|
||||
$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 Bulk Operations Collection',
|
||||
'documentSecurity' => true,
|
||||
'permissions' => [
|
||||
Permission::create(Role::any()),
|
||||
Permission::read(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
Permission::update(Role::any()),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $collection['headers']['status-code']);
|
||||
$collectionId = $collection['body']['$id'];
|
||||
|
||||
// Create string attribute
|
||||
$nameAttribute = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'name',
|
||||
'size' => 256,
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
$this->assertEquals(202, $nameAttribute['headers']['status-code']);
|
||||
|
||||
// Create point attribute
|
||||
$pointAttribute = $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' => 'location',
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
$this->assertEquals(202, $pointAttribute['headers']['status-code']);
|
||||
|
||||
// Create polygon attribute
|
||||
$polygonAttribute = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/polygon', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'area',
|
||||
'required' => false,
|
||||
]);
|
||||
|
||||
$this->assertEquals(202, $polygonAttribute['headers']['status-code']);
|
||||
|
||||
// Wait for attributes to be created
|
||||
sleep(2);
|
||||
|
||||
// Test 1: Bulk create with spatial data
|
||||
$spatialDocuments = [];
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$spatialDocuments[] = [
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Location ' . $i,
|
||||
'location' => [10.0 + $i, 20.0 + $i], // POINT
|
||||
'area' => [
|
||||
[10.0 + $i, 20.0 + $i],
|
||||
[11.0 + $i, 20.0 + $i],
|
||||
[11.0 + $i, 21.0 + $i],
|
||||
[10.0 + $i, 21.0 + $i],
|
||||
[10.0 + $i, 20.0 + $i]
|
||||
] // POLYGON
|
||||
];
|
||||
}
|
||||
|
||||
$response = $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()), [
|
||||
'documents' => $spatialDocuments,
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$this->assertCount(5, $response['body']['documents']);
|
||||
|
||||
// Verify created documents have proper spatial data
|
||||
foreach ($response['body']['documents'] as $index => $document) {
|
||||
$this->assertNotEmpty($document['$id']);
|
||||
$this->assertNotEmpty($document['name']);
|
||||
$this->assertIsArray($document['location']);
|
||||
$this->assertIsArray($document['area']);
|
||||
$this->assertCount(2, $document['location']); // POINT has 2 coordinates
|
||||
|
||||
// Check polygon structure - it might be stored as an array of arrays
|
||||
if (is_array($document['area'][0])) {
|
||||
$this->assertGreaterThan(1, count($document['area'][0])); // POLYGON has multiple points
|
||||
} else {
|
||||
$this->assertGreaterThan(1, count($document['area'])); // POLYGON has multiple points
|
||||
}
|
||||
|
||||
$this->assertEquals('Location ' . $index, $document['name']);
|
||||
$this->assertEquals([10.0 + $index, 20.0 + $index], $document['location']);
|
||||
}
|
||||
|
||||
// Test 2: Bulk update with spatial data
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'data' => [
|
||||
'name' => 'Updated Location',
|
||||
'location' => [15.0, 25.0], // New POINT
|
||||
'area' => [
|
||||
[15.0, 25.0],
|
||||
[16.0, 25.0],
|
||||
[16.0, 26.0],
|
||||
[15.0, 26.0],
|
||||
[15.0, 25.0]
|
||||
] // New POLYGON
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(5, $response['body']['documents']);
|
||||
|
||||
// Verify updated documents
|
||||
foreach ($response['body']['documents'] as $document) {
|
||||
$this->assertEquals('Updated Location', $document['name']);
|
||||
$this->assertEquals([15.0, 25.0], $document['location']);
|
||||
// The area might be stored as an array of arrays, so check the first element
|
||||
$this->assertIsArray($document['area']);
|
||||
if (is_array($document['area'][0])) {
|
||||
// If it's an array of arrays, check the first polygon
|
||||
$this->assertEquals([
|
||||
[15.0, 25.0],
|
||||
[16.0, 25.0],
|
||||
[16.0, 26.0],
|
||||
[15.0, 26.0],
|
||||
[15.0, 25.0]
|
||||
], $document['area'][0]);
|
||||
} else {
|
||||
// If it's a direct array, check the whole thing
|
||||
$this->assertEquals([
|
||||
[15.0, 25.0],
|
||||
[16.0, 25.0],
|
||||
[16.0, 26.0],
|
||||
[15.0, 26.0],
|
||||
[15.0, 25.0]
|
||||
], $document['area']);
|
||||
}
|
||||
}
|
||||
|
||||
// Test 3: Bulk upsert with spatial data
|
||||
$upsertDocuments = [
|
||||
[
|
||||
'$id' => 'upsert1',
|
||||
'name' => 'Upsert Location 1',
|
||||
'location' => [30.0, 40.0],
|
||||
'area' => [
|
||||
[30.0, 40.0],
|
||||
[31.0, 40.0],
|
||||
[31.0, 41.0],
|
||||
[30.0, 41.0],
|
||||
[30.0, 40.0]
|
||||
]
|
||||
],
|
||||
[
|
||||
'$id' => 'upsert2',
|
||||
'name' => 'Upsert Location 2',
|
||||
'location' => [35.0, 45.0],
|
||||
'area' => [
|
||||
[35.0, 45.0],
|
||||
[36.0, 45.0],
|
||||
[36.0, 46.0],
|
||||
[35.0, 46.0],
|
||||
[35.0, 45.0]
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
$response = $this->client->call(Client::METHOD_PUT, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'documents' => $upsertDocuments,
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(2, $response['body']['documents']);
|
||||
|
||||
// Verify upserted documents
|
||||
foreach ($response['body']['documents'] as $document) {
|
||||
$this->assertNotEmpty($document['$id']);
|
||||
$this->assertIsArray($document['location']);
|
||||
$this->assertIsArray($document['area']);
|
||||
|
||||
// Verify the spatial data structure
|
||||
$this->assertCount(2, $document['location']); // POINT has 2 coordinates
|
||||
if (is_array($document['area'][0])) {
|
||||
$this->assertGreaterThan(1, count($document['area'][0])); // POLYGON has multiple points
|
||||
} else {
|
||||
$this->assertGreaterThan(1, count($document['area'])); // POLYGON has multiple points
|
||||
}
|
||||
}
|
||||
|
||||
// Test 4: Edge cases for spatial bulk operations
|
||||
|
||||
// Test 4a: Invalid point coordinates (should fail)
|
||||
$response = $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()), [
|
||||
'documents' => [
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Invalid Point',
|
||||
'location' => [1000.0, 2000.0],
|
||||
'area' => [10.0 , 10.0]
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
// 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',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'documents' => [
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Invalid Polygon',
|
||||
'location' => [10.0, 20.0],
|
||||
'area' => [
|
||||
[10.0, 20.0],
|
||||
[11.0, 20.0]
|
||||
]
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
$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',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'documents' => [
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Missing Location',
|
||||
// Missing required 'location' attribute
|
||||
'area' => [
|
||||
[10.0, 20.0],
|
||||
[11.0, 20.0],
|
||||
[11.0, 21.0],
|
||||
[10.0, 21.0],
|
||||
[10.0, 20.0]
|
||||
]
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
// This should fail due to missing required attribute
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
// Test 4e: Mixed valid and invalid documents in bulk (should fail)
|
||||
$response = $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()), [
|
||||
'documents' => [
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Valid Document',
|
||||
'location' => [10.0, 20.0],
|
||||
'area' => [
|
||||
[10.0, 20.0],
|
||||
[11.0, 20.0],
|
||||
[11.0, 21.0],
|
||||
[10.0, 21.0],
|
||||
[10.0, 20.0]
|
||||
]
|
||||
],
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Invalid Document',
|
||||
// Missing required 'location' attribute
|
||||
'area' => [
|
||||
[10.0, 20.0],
|
||||
[11.0, 20.0],
|
||||
[11.0, 21.0],
|
||||
[10.0, 21.0],
|
||||
[10.0, 20.0]
|
||||
]
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
// This should fail due to mixed valid/invalid documents
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
// Test 4f: Very large spatial data (stress test)
|
||||
$largePolygon = [];
|
||||
for ($i = 0; $i < 1000; $i++) {
|
||||
$largePolygon[] = [$i * 0.001, $i * 0.001];
|
||||
}
|
||||
$largePolygon[] = [0, 0]; // Close the polygon
|
||||
|
||||
$response = $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()), [
|
||||
'documents' => [
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Large Polygon Test',
|
||||
'location' => [0.0, 0.0],
|
||||
'area' => $largePolygon
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
|
||||
// Test 4g: Null values in spatial attributes (should fail)
|
||||
$response = $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()), [
|
||||
'documents' => [
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Null Values Test',
|
||||
'location' => null, // Null point
|
||||
'area' => null // Null polygon
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
// This should fail due to null values
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
// Test 4h: Bulk operations with spatial data exceeding limits
|
||||
$largeBulkDocuments = [];
|
||||
for ($i = 0; $i < 100; $i++) {
|
||||
$largeBulkDocuments[] = [
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Bulk Test ' . $i,
|
||||
'location' => [$i * 0.1, $i * 0.1],
|
||||
'area' => [
|
||||
[$i * 0.1, $i * 0.1],
|
||||
[($i + 1) * 0.1, $i * 0.1],
|
||||
[($i + 1) * 0.1, ($i + 1) * 0.1],
|
||||
[$i * 0.1, ($i + 1) * 0.1],
|
||||
[$i * 0.1, $i * 0.1]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
$response = $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()), [
|
||||
'documents' => $largeBulkDocuments,
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
|
||||
// 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']
|
||||
]));
|
||||
}
|
||||
|
||||
public function testSpatialBulkOperationsWithLineStrings(): void
|
||||
{
|
||||
// Create database
|
||||
$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 LineString Bulk Operations Test Database'
|
||||
]);
|
||||
|
||||
$this->assertNotEmpty($database['body']['$id']);
|
||||
$databaseId = $database['body']['$id'];
|
||||
|
||||
// Create collection with line string attributes
|
||||
$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 LineString Bulk Operations Collection',
|
||||
'documentSecurity' => true,
|
||||
'permissions' => [
|
||||
Permission::create(Role::any()),
|
||||
Permission::read(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
Permission::update(Role::any()),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $collection['headers']['status-code']);
|
||||
$collectionId = $collection['body']['$id'];
|
||||
|
||||
// Create string attribute
|
||||
$nameAttribute = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'name',
|
||||
'size' => 256,
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
$this->assertEquals(202, $nameAttribute['headers']['status-code']);
|
||||
|
||||
// Create line string attribute
|
||||
$lineAttribute = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/line', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'path',
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
// Handle both 201 (created) and 202 (accepted) status codes
|
||||
$this->assertEquals(202, $lineAttribute['headers']['status-code']);
|
||||
|
||||
// Wait for attributes to be created
|
||||
sleep(2);
|
||||
|
||||
// Test bulk create with line string data
|
||||
$lineStringDocuments = [];
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$lineStringDocuments[] = [
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Path ' . $i,
|
||||
'path' => [
|
||||
[$i * 10, $i * 10],
|
||||
[($i + 1) * 10, ($i + 1) * 10],
|
||||
[($i + 2) * 10, ($i + 2) * 10]
|
||||
] // LINE STRING with 3 points
|
||||
];
|
||||
}
|
||||
|
||||
$response = $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()), [
|
||||
'documents' => $lineStringDocuments,
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$this->assertCount(3, $response['body']['documents']);
|
||||
|
||||
// Verify created documents have proper line string data
|
||||
foreach ($response['body']['documents'] as $index => $document) {
|
||||
$this->assertNotEmpty($document['$id']);
|
||||
$this->assertNotEmpty($document['name']);
|
||||
$this->assertIsArray($document['path']);
|
||||
$this->assertGreaterThan(1, count($document['path'])); // LINE STRING has multiple points
|
||||
$this->assertEquals('Path ' . $index, $document['name']);
|
||||
$this->assertCount(3, $document['path']); // Each line string has 3 points
|
||||
}
|
||||
|
||||
// Test bulk update with line string data
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'data' => [
|
||||
'name' => 'Updated Path',
|
||||
'path' => [
|
||||
[0, 0],
|
||||
[50, 50],
|
||||
[100, 100]
|
||||
] // New LINE STRING
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(3, $response['body']['documents']);
|
||||
|
||||
// Verify updated documents
|
||||
foreach ($response['body']['documents'] as $document) {
|
||||
$this->assertEquals('Updated Path', $document['name']);
|
||||
$this->assertEquals([
|
||||
[0, 0],
|
||||
[50, 50],
|
||||
[100, 100]
|
||||
], $document['path']);
|
||||
}
|
||||
|
||||
// Test: Invalid line string (single point - should fail)
|
||||
$response = $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()), [
|
||||
'documents' => [
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Invalid Line String',
|
||||
'path' => [[10, 20]] // Single point - invalid line string
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
// 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']
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -6132,4 +6132,569 @@ class DatabasesCustomServerTest extends Scope
|
|||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
}
|
||||
|
||||
public function testSpatialBulkOperations(): void
|
||||
{
|
||||
// Create database
|
||||
$database = $this->client->call(Client::METHOD_POST, '/tablesdb', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
], [
|
||||
'databaseId' => ID::unique(),
|
||||
'name' => 'Spatial Bulk Operations Test Database'
|
||||
]);
|
||||
|
||||
$this->assertNotEmpty($database['body']['$id']);
|
||||
$databaseId = $database['body']['$id'];
|
||||
|
||||
// Create table with spatial columns
|
||||
$table = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'tableId' => ID::unique(),
|
||||
'name' => 'Spatial Bulk Operations Table',
|
||||
'rowSecurity' => true,
|
||||
'permissions' => [
|
||||
Permission::create(Role::any()),
|
||||
Permission::read(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
Permission::update(Role::any()),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $table['headers']['status-code']);
|
||||
$tableId = $table['body']['$id'];
|
||||
|
||||
// Create string column
|
||||
$nameColumn = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/string', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'name',
|
||||
'size' => 256,
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
$this->assertEquals(202, $nameColumn['headers']['status-code']);
|
||||
|
||||
// Create point column
|
||||
$pointColumn = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/point', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'location',
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
$this->assertEquals(202, $pointColumn['headers']['status-code']);
|
||||
|
||||
// Create polygon column
|
||||
$polygonColumn = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/polygon', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'area',
|
||||
'required' => false,
|
||||
]);
|
||||
|
||||
$this->assertEquals(202, $polygonColumn['headers']['status-code']);
|
||||
|
||||
// Wait for columns to be created
|
||||
sleep(2);
|
||||
|
||||
// Test 1: Bulk create with spatial data
|
||||
$spatialRows = [];
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$spatialRows[] = [
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Location ' . $i,
|
||||
'location' => [10.0 + $i, 20.0 + $i], // POINT
|
||||
'area' => [
|
||||
[10.0 + $i, 20.0 + $i],
|
||||
[11.0 + $i, 20.0 + $i],
|
||||
[11.0 + $i, 21.0 + $i],
|
||||
[10.0 + $i, 21.0 + $i],
|
||||
[10.0 + $i, 20.0 + $i]
|
||||
] // POLYGON
|
||||
];
|
||||
}
|
||||
|
||||
$response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rows' => $spatialRows,
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$this->assertCount(5, $response['body']['rows']);
|
||||
|
||||
// Verify created rows have proper spatial data
|
||||
foreach ($response['body']['rows'] as $index => $row) {
|
||||
$this->assertNotEmpty($row['$id']);
|
||||
$this->assertNotEmpty($row['name']);
|
||||
$this->assertIsArray($row['location']);
|
||||
$this->assertIsArray($row['area']);
|
||||
$this->assertCount(2, $row['location']); // POINT has 2 coordinates
|
||||
|
||||
// Check polygon structure - it might be stored as an array of arrays
|
||||
if (is_array($row['area'][0])) {
|
||||
$this->assertGreaterThan(1, count($row['area'][0])); // POLYGON has multiple points
|
||||
} else {
|
||||
$this->assertGreaterThan(1, count($row['area'])); // POLYGON has multiple points
|
||||
}
|
||||
|
||||
$this->assertEquals('Location ' . $index, $row['name']);
|
||||
$this->assertEquals([10.0 + $index, 20.0 + $index], $row['location']);
|
||||
}
|
||||
|
||||
// Test 2: Bulk update with spatial data
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'data' => [
|
||||
'name' => 'Updated Location',
|
||||
'location' => [15.0, 25.0], // New POINT
|
||||
'area' => [
|
||||
[15.0, 25.0],
|
||||
[16.0, 25.0],
|
||||
[16.0, 26.0],
|
||||
[15.0, 26.0],
|
||||
[15.0, 25.0]
|
||||
] // New POLYGON
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(5, $response['body']['rows']);
|
||||
|
||||
// Verify updated rows
|
||||
foreach ($response['body']['rows'] as $row) {
|
||||
$this->assertEquals('Updated Location', $row['name']);
|
||||
$this->assertEquals([15.0, 25.0], $row['location']);
|
||||
// The area might be stored as an array of arrays, so check the first element
|
||||
$this->assertIsArray($row['area']);
|
||||
if (is_array($row['area'][0])) {
|
||||
// If it's an array of arrays, check the first polygon
|
||||
$this->assertEquals([
|
||||
[15.0, 25.0],
|
||||
[16.0, 25.0],
|
||||
[16.0, 26.0],
|
||||
[15.0, 26.0],
|
||||
[15.0, 25.0]
|
||||
], $row['area'][0]);
|
||||
} else {
|
||||
// If it's a direct array, check the whole thing
|
||||
$this->assertEquals([
|
||||
[15.0, 25.0],
|
||||
[16.0, 25.0],
|
||||
[16.0, 26.0],
|
||||
[15.0, 26.0],
|
||||
[15.0, 25.0]
|
||||
], $row['area']);
|
||||
}
|
||||
}
|
||||
|
||||
// Test 3: Bulk upsert with spatial data
|
||||
$upsertRows = [
|
||||
[
|
||||
'$id' => 'upsert1',
|
||||
'name' => 'Upsert Location 1',
|
||||
'location' => [30.0, 40.0],
|
||||
'area' => [
|
||||
[30.0, 40.0],
|
||||
[31.0, 40.0],
|
||||
[31.0, 41.0],
|
||||
[30.0, 41.0],
|
||||
[30.0, 40.0]
|
||||
]
|
||||
],
|
||||
[
|
||||
'$id' => 'upsert2',
|
||||
'name' => 'Upsert Location 2',
|
||||
'location' => [35.0, 45.0],
|
||||
'area' => [
|
||||
[35.0, 45.0],
|
||||
[36.0, 45.0],
|
||||
[36.0, 46.0],
|
||||
[35.0, 46.0],
|
||||
[35.0, 45.0]
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
$response = $this->client->call(Client::METHOD_PUT, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rows' => $upsertRows,
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(2, $response['body']['rows']);
|
||||
|
||||
// Verify upserted rows
|
||||
foreach ($response['body']['rows'] as $row) {
|
||||
$this->assertNotEmpty($row['$id']);
|
||||
$this->assertIsArray($row['location']);
|
||||
$this->assertIsArray($row['area']);
|
||||
|
||||
// Verify the spatial data structure
|
||||
$this->assertCount(2, $row['location']); // POINT has 2 coordinates
|
||||
if (is_array($row['area'][0])) {
|
||||
$this->assertGreaterThan(1, count($row['area'][0])); // POLYGON has multiple points
|
||||
} else {
|
||||
$this->assertGreaterThan(1, count($row['area'])); // POLYGON has multiple points
|
||||
}
|
||||
}
|
||||
|
||||
// Test 4: Edge cases for spatial bulk operations
|
||||
|
||||
// Test 4a: Invalid point coordinates (should fail)
|
||||
$response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rows' => [
|
||||
[
|
||||
'$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]
|
||||
]
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
// Coordinates are not validated strictly; creation should succeed
|
||||
$this->assertEquals(201, $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([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rows' => [
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Invalid Polygon',
|
||||
'location' => [10.0, 20.0],
|
||||
'area' => [
|
||||
[10.0, 20.0],
|
||||
[11.0, 20.0]
|
||||
]
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
$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([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rows' => [
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Missing Location',
|
||||
// Missing required 'location' attribute
|
||||
'area' => [
|
||||
[10.0, 20.0],
|
||||
[11.0, 20.0],
|
||||
[11.0, 21.0],
|
||||
[10.0, 21.0],
|
||||
[10.0, 20.0]
|
||||
]
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
// This should fail due to missing required attribute
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
// Test 4d: Mixed valid and invalid rows in bulk (should fail)
|
||||
$response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rows' => [
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Valid Row',
|
||||
'location' => [10.0, 20.0],
|
||||
'area' => [
|
||||
[10.0, 20.0],
|
||||
[11.0, 20.0],
|
||||
[11.0, 21.0],
|
||||
[10.0, 21.0],
|
||||
[10.0, 20.0]
|
||||
]
|
||||
],
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Invalid Row',
|
||||
// Missing required 'location' attribute
|
||||
'area' => [
|
||||
[10.0, 20.0],
|
||||
[11.0, 20.0],
|
||||
[11.0, 21.0],
|
||||
[10.0, 21.0],
|
||||
[10.0, 20.0]
|
||||
]
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
// This should fail due to mixed valid/invalid rows
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
// Test 4e: Very large spatial data (stress test)
|
||||
$largePolygon = [];
|
||||
for ($i = 0; $i < 1000; $i++) {
|
||||
$largePolygon[] = [$i * 0.001, $i * 0.001];
|
||||
}
|
||||
$largePolygon[] = [0, 0]; // Close the polygon
|
||||
|
||||
$response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rows' => [
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Large Polygon Test',
|
||||
'location' => [0.0, 0.0],
|
||||
'area' => $largePolygon
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
|
||||
// Test 4f: Null values in spatial attributes (should fail)
|
||||
$response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rows' => [
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Null Values Test',
|
||||
'location' => null, // Null point
|
||||
'area' => null // Null polygon
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
// This should fail due to null values
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
// Test 4g: Bulk operations with spatial data exceeding limits
|
||||
$largeBulkRows = [];
|
||||
for ($i = 0; $i < 100; $i++) {
|
||||
$largeBulkRows[] = [
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Bulk Test ' . $i,
|
||||
'location' => [$i * 0.1, $i * 0.1],
|
||||
'area' => [
|
||||
[$i * 0.1, $i * 0.1],
|
||||
[($i + 1) * 0.1, $i * 0.1],
|
||||
[($i + 1) * 0.1, ($i + 1) * 0.1],
|
||||
[$i * 0.1, ($i + 1) * 0.1],
|
||||
[$i * 0.1, $i * 0.1]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
$response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rows' => $largeBulkRows,
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
|
||||
// Cleanup
|
||||
$this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId . '/tables/' . $tableId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
|
||||
$this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
}
|
||||
|
||||
public function testSpatialBulkOperationsWithLineStrings(): void
|
||||
{
|
||||
// Create database
|
||||
$database = $this->client->call(Client::METHOD_POST, '/tablesdb', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
], [
|
||||
'databaseId' => ID::unique(),
|
||||
'name' => 'Spatial LineString Bulk Operations Test Database'
|
||||
]);
|
||||
|
||||
$this->assertNotEmpty($database['body']['$id']);
|
||||
$databaseId = $database['body']['$id'];
|
||||
|
||||
// Create table with line string columns
|
||||
$table = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'tableId' => ID::unique(),
|
||||
'name' => 'Spatial LineString Bulk Operations Table',
|
||||
'rowSecurity' => true,
|
||||
'permissions' => [
|
||||
Permission::create(Role::any()),
|
||||
Permission::read(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
Permission::update(Role::any()),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $table['headers']['status-code']);
|
||||
$tableId = $table['body']['$id'];
|
||||
|
||||
// Create string column
|
||||
$nameColumn = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/string', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'name',
|
||||
'size' => 256,
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
$this->assertEquals(202, $nameColumn['headers']['status-code']);
|
||||
|
||||
// Create line string column
|
||||
$lineColumn = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/line', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'path',
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
// Handle both 201 (created) and 202 (accepted) status codes
|
||||
$this->assertEquals(202, $lineColumn['headers']['status-code']);
|
||||
|
||||
// Wait for columns to be created
|
||||
sleep(2);
|
||||
|
||||
// Test bulk create with line string data
|
||||
$lineStringRows = [];
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$lineStringRows[] = [
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Path ' . $i,
|
||||
'path' => [
|
||||
[$i * 10, $i * 10],
|
||||
[($i + 1) * 10, ($i + 1) * 10],
|
||||
[($i + 2) * 10, ($i + 2) * 10]
|
||||
] // LINE STRING with 3 points
|
||||
];
|
||||
}
|
||||
|
||||
$response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rows' => $lineStringRows,
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$this->assertCount(3, $response['body']['rows']);
|
||||
|
||||
// Verify created rows have proper line string data
|
||||
foreach ($response['body']['rows'] as $index => $row) {
|
||||
$this->assertNotEmpty($row['$id']);
|
||||
$this->assertNotEmpty($row['name']);
|
||||
$this->assertIsArray($row['path']);
|
||||
$this->assertGreaterThan(1, count($row['path'])); // LINE STRING has multiple points
|
||||
$this->assertEquals('Path ' . $index, $row['name']);
|
||||
$this->assertCount(3, $row['path']); // Each line string has 3 points
|
||||
}
|
||||
|
||||
// Test bulk update with line string data
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'data' => [
|
||||
'name' => 'Updated Path',
|
||||
'path' => [
|
||||
[0, 0],
|
||||
[50, 50],
|
||||
[100, 100]
|
||||
] // New LINE STRING
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(3, $response['body']['rows']);
|
||||
|
||||
// Verify updated rows
|
||||
foreach ($response['body']['rows'] as $row) {
|
||||
$this->assertEquals('Updated Path', $row['name']);
|
||||
$this->assertEquals([
|
||||
[0, 0],
|
||||
[50, 50],
|
||||
[100, 100]
|
||||
], $row['path']);
|
||||
}
|
||||
|
||||
// Test: Invalid line string (single point - should fail)
|
||||
$response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rows' => [
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Invalid Line String',
|
||||
'path' => [[10, 20]] // Single point - invalid line string
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
// Cleanup
|
||||
$this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId . '/tables/' . $tableId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
|
||||
$this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,9 @@ trait Base
|
|||
public const string CREATE_IP_ATTRIBUTE = 'create_ip_attribute';
|
||||
public const string CREATE_ENUM_ATTRIBUTE = 'create_enum_attribute';
|
||||
public const string CREATE_DATETIME_ATTRIBUTE = 'create_datetime_attribute';
|
||||
public const string CREATE_POINT_ATTRIBUTE = 'create_point_attribute';
|
||||
public const string CREATE_LINE_ATTRIBUTE = 'create_line_attribute';
|
||||
public const string CREATE_POLYGON_ATTRIBUTE = 'create_polygon_attribute';
|
||||
|
||||
public const string CREATE_RELATIONSHIP_ATTRIBUTE = 'create_relationship_attribute';
|
||||
public const string UPDATE_STRING_ATTRIBUTE = 'update_string_attribute';
|
||||
|
|
@ -56,6 +59,9 @@ trait Base
|
|||
public const string UPDATE_IP_ATTRIBUTE = 'update_ip_attribute';
|
||||
public const string UPDATE_ENUM_ATTRIBUTE = 'update_enum_attribute';
|
||||
public const string UPDATE_DATETIME_ATTRIBUTE = 'update_datetime_attribute';
|
||||
public const string UPDATE_POINT_ATTRIBUTE = 'update_point_attribute';
|
||||
public const string UPDATE_LINE_ATTRIBUTE = 'update_line_attribute';
|
||||
public const string UPDATE_POLYGON_ATTRIBUTE = 'update_polygon_attribute';
|
||||
|
||||
public const string UPDATE_RELATIONSHIP_ATTRIBUTE = 'update_relationship_attribute';
|
||||
public const string GET_ATTRIBUTES = 'get_attributes';
|
||||
|
|
@ -72,6 +78,9 @@ trait Base
|
|||
public const string CREATE_IP_COLUMN = 'create_ip_column';
|
||||
public const string CREATE_ENUM_COLUMN = 'create_enum_column';
|
||||
public const string CREATE_DATETIME_COLUMN = 'create_datetime_column';
|
||||
public const string CREATE_POINT_COLUMN = 'create_point_column';
|
||||
public const string CREATE_LINE_COLUMN = 'create_line_column';
|
||||
public const string CREATE_POLYGON_COLUMN = 'create_polygon_column';
|
||||
|
||||
public const string CREATE_RELATIONSHIP_COLUMN = 'create_relationship_column';
|
||||
public const string UPDATE_STRING_COLUMN = 'update_string_column';
|
||||
|
|
@ -83,6 +92,9 @@ trait Base
|
|||
public const string UPDATE_IP_COLUMN = 'update_ip_column';
|
||||
public const string UPDATE_ENUM_COLUMN = 'update_enum_column';
|
||||
public const string UPDATE_DATETIME_COLUMN = 'update_datetime_column';
|
||||
public const string UPDATE_POINT_COLUMN = 'update_point_column';
|
||||
public const string UPDATE_LINE_COLUMN = 'update_line_column';
|
||||
public const string UPDATE_POLYGON_COLUMN = 'update_polygon_column';
|
||||
|
||||
public const string UPDATE_RELATIONSHIP_COLUMN = 'update_relationship_column';
|
||||
public const string GET_COLUMNS = 'get_columns';
|
||||
|
|
@ -930,6 +942,35 @@ trait Base
|
|||
array
|
||||
}
|
||||
}';
|
||||
case self::CREATE_POINT_COLUMN:
|
||||
return 'mutation createPointColumn($databaseId: String!, $tableId: String!, $key: String!, $required: Boolean!, $array: Boolean){
|
||||
tablesDBCreatePointColumn(databaseId: $databaseId, tableId: $tableId, key: $key, required: $required, array: $array) {
|
||||
key
|
||||
required
|
||||
array
|
||||
status
|
||||
}
|
||||
}';
|
||||
|
||||
case self::CREATE_LINE_COLUMN:
|
||||
return 'mutation createLineColumn($databaseId: String!, $tableId: String!, $key: String!, $required: Boolean!, $array: Boolean){
|
||||
tablesDBCreateLineColumn(databaseId: $databaseId, tableId: $tableId, key: $key, required: $required, array: $array) {
|
||||
key
|
||||
required
|
||||
array
|
||||
status
|
||||
}
|
||||
}';
|
||||
|
||||
case self::CREATE_POLYGON_COLUMN:
|
||||
return 'mutation createPolygonColumn($databaseId: String!, $tableId: String!, $key: String!, $required: Boolean!, $array: Boolean){
|
||||
tablesDBCreatePolygonColumn(databaseId: $databaseId, tableId: $tableId, key: $key, required: $required, array: $array) {
|
||||
key
|
||||
required
|
||||
array
|
||||
status
|
||||
}
|
||||
}';
|
||||
case self::CREATE_RELATIONSHIP_COLUMN:
|
||||
return 'mutation createRelationshipColumn($databaseId: String!, $tableId: String!, $relatedTableId: String!, $type: String!, $twoWay: Boolean, $key: String, $twoWayKey: String, $onDelete: String){
|
||||
tablesDBCreateRelationshipColumn(databaseId: $databaseId, tableId: $tableId, relatedTableId: $relatedTableId, type: $type, twoWay: $twoWay, key: $key, twoWayKey: $twoWayKey, onDelete: $onDelete) {
|
||||
|
|
@ -1009,6 +1050,27 @@ trait Base
|
|||
default
|
||||
}
|
||||
}';
|
||||
case self::UPDATE_POINT_COLUMN:
|
||||
return 'mutation updatePointColumn($databaseId: String!, $tableId: String!, $key: String!, $required: Boolean!){
|
||||
tablesDBUpdatePointColumn(databaseId: $databaseId, tableId: $tableId, key: $key, required: $required) {
|
||||
required
|
||||
}
|
||||
}';
|
||||
|
||||
case self::UPDATE_LINE_COLUMN:
|
||||
return 'mutation updateLineColumn($databaseId: String!, $tableId: String!, $key: String!, $required: Boolean!){
|
||||
tablesDBUpdateLineColumn(databaseId: $databaseId, tableId: $tableId, key: $key, required: $required) {
|
||||
required
|
||||
}
|
||||
}';
|
||||
|
||||
case self::UPDATE_POLYGON_COLUMN:
|
||||
return 'mutation updatePolygonColumn($databaseId: String!, $tableId: String!, $key: String!, $required: Boolean!){
|
||||
tablesDBUpdatePolygonColumn(databaseId: $databaseId, tableId: $tableId, key: $key, required: $required) {
|
||||
required
|
||||
}
|
||||
}';
|
||||
|
||||
case self::UPDATE_RELATIONSHIP_COLUMN:
|
||||
return 'mutation updateRelationshipColumn($databaseId: String!, $tableId: String!, $key: String!, $onDelete: String){
|
||||
tablesDBUpdateRelationshipColumn(databaseId: $databaseId, tableId: $tableId, key: $key, onDelete: $onDelete) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue