Sub query support for indexes

This commit is contained in:
Eldad Fux 2021-08-22 18:00:00 +03:00
parent e39ed9cf9b
commit 31500cd675
4 changed files with 152 additions and 25 deletions

View file

@ -60,7 +60,7 @@ $collections = [
'required' => false,
'signed' => true,
'array' => false,
'filters' => ['subQuery'],
'filters' => ['subQueryAttributes'],
],
[
'$id' => 'indexes',
@ -69,7 +69,7 @@ $collections = [
'required' => false,
'signed' => true,
'array' => false,
'filters' => ['json'],
'filters' => ['subQueryIndexes'],
],
[
'$id' => 'search',
@ -228,13 +228,100 @@ $collections = [
],
],
'indexes' => [
// [filters
// '$id' => '_key_unique',
// 'type' => Database::INDEX_UNIQUE,
// 'attributes' => ['key', 'collectionId'],
// 'lengths' => [Database::LENGTH_KEY, Database::LENGTH_KEY],
// 'orders' => [Database::ORDER_ASC, Database::ORDER_ASC],
// ],
[
'$id' => '_key_collection',
'type' => Database::INDEX_KEY,
'attributes' => ['collectionId'],
'lengths' => [Database::LENGTH_KEY],
'orders' => [Database::ORDER_ASC],
],
],
],
'indexes' => [
'$collection' => Database::METADATA,
'$id' => 'attributes',
'name' => 'Attributes',
'attributes' => [
[
'$id' => 'collectionId',
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => 'key',
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => 'type',
'type' => Database::VAR_STRING,
'format' => '',
'size' => 256,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => 'status',
'type' => Database::VAR_STRING,
'format' => '',
'size' => 256,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => 'attributes',
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => false,
'default' => null,
'array' => true,
'filters' => [],
],
[
'$id' => 'lengths',
'type' => Database::VAR_INTEGER,
'format' => '',
'size' => 0,
'signed' => true,
'required' => false,
'default' => null,
'array' => true,
'filters' => [],
],
[
'$id' => 'orders',
'type' => Database::VAR_STRING,
'format' => '',
'size' => 255,
'signed' => true,
'required' => false,
'default' => null,
'array' => true,
'filters' => [],
],
],
'indexes' => [
[
'$id' => '_key_collection',
'type' => Database::INDEX_KEY,

View file

@ -922,14 +922,22 @@ App::post('/v1/database/collections/:collectionId/indexes')
}
// TODO@kodumbeats should $lengths be a part of the response model?
$index = new Document([
'$collection' => $collectionId,
'$id' => $indexId,
'type' => $type,
'attributes' => $attributes,
'lengths' => $lengths,
'orders' => $orders,
]);
try {
$index = $dbForInternal->createDocument('indexes', new Document([
'$id' => $collectionId.'_'.$indexId,
'key' => $indexId,
'status' => 'processing', // processing, available, failed, deleting
'collectionId' => $collectionId,
'type' => $type,
'attributes' => $attributes,
'lengths' => $lengths,
'orders' => $orders,
]));
} catch (DuplicateException $th) {
throw new Exception('Attribute already exists', 409);
}
$dbForInternal->purgeDocument('collections', $collectionId);
$database
->setParam('type', DATABASE_TYPE_CREATE_INDEX)
@ -944,7 +952,6 @@ App::post('/v1/database/collections/:collectionId/indexes')
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic($index, Response::MODEL_INDEX);
});
App::get('/v1/database/collections/:collectionId/indexes')

View file

@ -176,7 +176,7 @@ DatabaseOld::addFilter('encrypt',
}
);
Database::addFilter('subQuery',
Database::addFilter('subQueryAttributes',
function($value) {
return null;
},
@ -188,6 +188,18 @@ Database::addFilter('subQuery',
}
);
Database::addFilter('subQueryIndexes',
function($value) {
return null;
},
function($value, Document $document, Database $database) {
return $database
->find('indexes', [
new Query('collectionId', Query::TYPE_EQUAL, [$document->getId()])
], 100, 0, ['_id']);
}
);
Database::addFilter('encrypt',
function($value) {
$key = App::getEnv('_APP_OPENSSL_KEY_V1');

View file

@ -125,19 +125,28 @@ class DatabaseV1 extends Worker
*/
protected function createIndex(Document $collection, Document $index, string $projectId): void
{
$dbForInternal = $this->getInternalDB($projectId);
$dbForExternal = $this->getExternalDB($projectId);
$collectionId = $collection->getId();
$id = $index->getAttribute('$id', '');
$key = $index->getAttribute('key', '');
$type = $index->getAttribute('type', '');
$attributes = $index->getAttribute('attributes', []);
$lengths = $index->getAttribute('lengths', []);
$orders = $index->getAttribute('orders', []);
$success = $dbForExternal->createIndex($collectionId, $id, $type, $attributes, $lengths, $orders);
if ($success) {
$dbForExternal->removeIndexInQueue($collectionId, $id);
try {
if(!$dbForExternal->createIndex($collectionId, $key, $type, $attributes, $lengths, $orders)) {
throw new Exception('Failed to create Index');
}
$dbForInternal->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'available'));
} catch (\Throwable $th) {
Console::error($th->getMessage());
$dbForInternal->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'failed'));
}
$dbForInternal->purgeDocument('collections', $collectionId);
}
/**
@ -147,11 +156,23 @@ class DatabaseV1 extends Worker
*/
protected function deleteIndex(Document $collection, Document $index, string $projectId): void
{
$dbForInternal = $this->getInternalDB($projectId);
$dbForExternal = $this->getExternalDB($projectId);
$collectionId = $collection->getId();
$id = $index->getAttribute('$id');
$key = $index->getAttribute('key');
$success = $dbForExternal->deleteIndex($collectionId, $id);
try {
if(!$dbForExternal->deleteIndex($collectionId, $key)) {
throw new Exception('Failed to delete Attribute');
}
$dbForInternal->deleteDocument('indexes', $index->getId());
} catch (\Throwable $th) {
Console::error($th->getMessage());
$dbForInternal->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'failed'));
}
$dbForInternal->purgeDocument('collections', $collectionId);
}
}