mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
added spatial index tests
This commit is contained in:
+22
-4
@@ -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,29 @@ class Create extends Action
|
||||
'orders' => $orders,
|
||||
]);
|
||||
|
||||
// Determine adapter capabilities. For TablesDB, be permissive to accept requests
|
||||
// and let the background worker enforce engine-specific constraints.
|
||||
$maxIndexLength = $dbForProject->getAdapter()->getMaxIndexLength();
|
||||
$internalIndexesKeys = $dbForProject->getAdapter()->getInternalIndexesKeys();
|
||||
$supportForIndexArray = $dbForProject->getAdapter()->getSupportForIndexArray();
|
||||
$supportForSpatialAttributes = $dbForProject->getAdapter()->getSupportForSpatialAttributes();
|
||||
$supportForSpatialIndexNull = $dbForProject->getAdapter()->getSupportForSpatialIndexNull();
|
||||
$supportForSpatialIndexOrder = $dbForProject->getAdapter()->getSupportForSpatialIndexOrder();
|
||||
|
||||
if (!$this->isCollectionsAPI()) {
|
||||
// Relax spatial constraints for TablesDB API
|
||||
$supportForSpatialIndexNull = true;
|
||||
$supportForSpatialIndexOrder = true;
|
||||
}
|
||||
|
||||
$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)) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -7261,4 +7261,104 @@ trait DatabasesBase
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
}
|
||||
|
||||
public function testSpatialIndex(): void
|
||||
{
|
||||
$database = $this->client->call(Client::METHOD_POST, '/databases', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
], [
|
||||
'databaseId' => ID::unique(),
|
||||
'name' => 'Spatial Index Test DB'
|
||||
]);
|
||||
$this->assertEquals(201, $database['headers']['status-code']);
|
||||
$databaseId = $database['body']['$id'];
|
||||
|
||||
$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' => 'SpatialIdx',
|
||||
'documentSecurity' => true,
|
||||
'permissions' => [
|
||||
Permission::create(Role::any()),
|
||||
Permission::read(Role::any()),
|
||||
Permission::update(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
],
|
||||
]);
|
||||
$this->assertEquals(201, $collection['headers']['status-code']);
|
||||
$collectionId = $collection['body']['$id'];
|
||||
|
||||
// Create spatial attributes: one required, one optional
|
||||
$reqPoint = $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' => 'pRequired',
|
||||
'required' => true,
|
||||
]);
|
||||
$this->assertEquals(202, $reqPoint['headers']['status-code']);
|
||||
|
||||
$optPoint = $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' => 'pOptional',
|
||||
'required' => false,
|
||||
]);
|
||||
$this->assertEquals(202, $optPoint['headers']['status-code']);
|
||||
|
||||
// Ensure attributes are available
|
||||
sleep(2);
|
||||
|
||||
// Create index on required spatial attribute (should succeed)
|
||||
$okIndex = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/indexes', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'idx_required_point',
|
||||
'type' => Database::INDEX_SPATIAL,
|
||||
'attributes' => ['pRequired'],
|
||||
]);
|
||||
$this->assertEquals(202, $okIndex['headers']['status-code']);
|
||||
|
||||
// Create index on optional spatial attribute (should fail in case of mariadb)
|
||||
$badIndex = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/indexes', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'idx_optional_point',
|
||||
'type' => Database::INDEX_SPATIAL,
|
||||
'attributes' => ['pOptional'],
|
||||
]);
|
||||
$this->assertEquals(400, $badIndex['headers']['status-code']);
|
||||
|
||||
// Passing orders to spatial index should not throw error(in case of mariadb)
|
||||
$ordersIndex = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/indexes', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'idx_required_point_with_orders',
|
||||
'type' => Database::INDEX_SPATIAL,
|
||||
'attributes' => ['pRequired'],
|
||||
'orders' => ['ASC']
|
||||
]);
|
||||
$this->assertEquals(202, $ordersIndex['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']
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7969,6 +7969,106 @@ trait DatabasesBase
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(0, $response['body']['documents']);
|
||||
|
||||
// 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']
|
||||
]));
|
||||
}
|
||||
|
||||
public function testSpatialIndex(): void
|
||||
{
|
||||
$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 Index Test DB'
|
||||
]);
|
||||
$this->assertEquals(201, $database['headers']['status-code']);
|
||||
$databaseId = $database['body']['$id'];
|
||||
|
||||
$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' => 'SpatialIdx',
|
||||
'rowSecurity' => true,
|
||||
'permissions' => [
|
||||
Permission::create(Role::any()),
|
||||
Permission::read(Role::any()),
|
||||
Permission::update(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
],
|
||||
]);
|
||||
$this->assertEquals(201, $table['headers']['status-code']);
|
||||
$tableId = $table['body']['$id'];
|
||||
|
||||
// Create spatial columns: one required, one optional
|
||||
$reqPoint = $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' => 'pRequired',
|
||||
'required' => true,
|
||||
]);
|
||||
$this->assertEquals(202, $reqPoint['headers']['status-code']);
|
||||
|
||||
$optPoint = $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' => 'pOptional',
|
||||
'required' => false,
|
||||
]);
|
||||
$this->assertEquals(202, $optPoint['headers']['status-code']);
|
||||
|
||||
// Ensure columns are available
|
||||
sleep(2);
|
||||
|
||||
// Create index on required spatial column (should succeed)
|
||||
$okIndex = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/indexes', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'idx_required_point',
|
||||
'type' => Database::INDEX_SPATIAL,
|
||||
'columns' => ['pRequired'],
|
||||
]);
|
||||
$this->assertEquals(202, $okIndex['headers']['status-code']);
|
||||
|
||||
// Create index on optional spatial column (should fail in case of mariadb)
|
||||
$badIndex = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/indexes', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'idx_optional_point',
|
||||
'type' => Database::INDEX_SPATIAL,
|
||||
'columns' => ['pOptional'],
|
||||
]);
|
||||
$this->assertEquals(202, $badIndex['headers']['status-code']);
|
||||
|
||||
// Passing orders to spatial index should not throw error (in case of mariadb)
|
||||
$ordersIndex = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/indexes', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'idx_required_point_with_orders',
|
||||
'type' => Database::INDEX_SPATIAL,
|
||||
'columns' => ['pRequired'],
|
||||
'orders' => ['ASC']
|
||||
]);
|
||||
$this->assertEquals(202, $ordersIndex['headers']['status-code']);
|
||||
|
||||
// Cleanup
|
||||
$this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId . '/tables/' . $tableId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
|
||||
Reference in New Issue
Block a user