1
0
Fork 0
mirror of synced 2024-10-01 17:58:02 +13:00

Recurse through nested documents to set collection ID

This commit is contained in:
Jake Barnby 2023-03-27 19:03:00 +13:00
parent 0465fb2268
commit 1cf25199ab
No known key found for this signature in database
GPG key ID: C437A8CC85B96E9C
2 changed files with 128 additions and 42 deletions

View file

@ -2643,18 +2643,36 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents')
throw new Exception(Exception::DOCUMENT_ALREADY_EXISTS);
}
$document->setAttribute('$collectionId', $collectionId);
// Add $collectionId and $databaseId for all documents
$setIds = function (Document $collection, Document $document) use (&$setIds, $dbForProject, $database) {
$document->setAttribute('$databaseId', $database->getId());
$document->setAttribute('$collectionId', $collection->getId());
// Add $databaseId to all documents
$resetIds = function (Document $document) use (&$resetIds, $databaseId) {
$document->setAttribute('$databaseId', $databaseId);
foreach ($document->getAttributes() as $attribute) {
if ($attribute instanceof Document) {
$resetIds($attribute);
$relationships = \array_filter(
$collection->getAttribute('attributes', []),
fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP
);
foreach ($document->getAttributes() as $key => $attribute) {
if (!$attribute instanceof Document) {
continue;
}
foreach ($relationships as $relationship) {
if ($key === $relationship->getAttribute('key')) {
$relatedCollectionId = $relationship->getAttribute('relatedCollection');
$relatedCollection = Authorization::skip(
fn() => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId)
);
$setIds($relatedCollection, $attribute);
continue 2;
}
}
}
};
$resetIds($document);
$setIds($collection, $document);
$events
->setParam('databaseId', $databaseId)
@ -2758,19 +2776,38 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
$total = Authorization::skip(fn () => $dbForProject->count('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $filterQueries, APP_LIMIT_COUNT));
}
// Add $databaseId for all documents
$resetIds = function (Document $document) use (&$resetIds, $databaseId) {
$document->setAttribute('$databaseId', $databaseId);
foreach ($document->getAttributes() as $attribute) {
if ($attribute instanceof Document) {
$resetIds($attribute);
// Add $collectionId and $databaseId for all documents
$setIds = function (Document $collection, Document $document) use (&$setIds, $dbForProject, $database) {
$document->setAttribute('$databaseId', $database->getId());
$document->setAttribute('$collectionId', $collection->getId());
$relationships = \array_filter(
$collection->getAttribute('attributes', []),
fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP
);
foreach ($document->getAttributes() as $key => $attribute) {
if (!$attribute instanceof Document) {
continue;
}
foreach ($relationships as $relationship) {
if ($key === $relationship->getAttribute('key')) {
$relatedCollectionId = $relationship->getAttribute('relatedCollection');
$relatedCollection = Authorization::skip(
fn() => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId)
);
$setIds($relatedCollection, $attribute);
continue 2;
}
}
}
};
// The linter is forcing this indentation
foreach ($documents as $document) {
$document->setAttribute('$collectionId', $collectionId);
$resetIds($document);
$setIds($collection, $document);
}
$response->dynamic(new Document([
@ -2844,18 +2881,36 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
throw new Exception(Exception::DOCUMENT_NOT_FOUND);
}
$document->setAttribute('$collectionId', $collectionId);
// Add $collectionId and $databaseId for all documents
$setIds = function (Document $collection, Document $document) use (&$setIds, $dbForProject, $database) {
$document->setAttribute('$databaseId', $database->getId());
$document->setAttribute('$collectionId', $collection->getId());
// Add $databaseId to all documents
$resetIds = function (Document $document) use (&$resetIds, $databaseId) {
$document->setAttribute('$databaseId', $databaseId);
foreach ($document->getAttributes() as $attribute) {
if ($attribute instanceof Document) {
$resetIds($attribute);
$relationships = \array_filter(
$collection->getAttribute('attributes', []),
fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP
);
foreach ($document->getAttributes() as $key => $attribute) {
if (!$attribute instanceof Document) {
continue;
}
foreach ($relationships as $relationship) {
if ($key === $relationship->getAttribute('key')) {
$relatedCollectionId = $relationship->getAttribute('relatedCollection');
$relatedCollection = Authorization::skip(
fn() => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId)
);
$setIds($relatedCollection, $attribute);
continue 2;
}
}
}
};
$resetIds($document);
$setIds($collection, $document);
$response->dynamic($document, Response::MODEL_DOCUMENT);
});
@ -3103,18 +3158,31 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum
throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, $exception->getMessage());
}
$document->setAttribute('$collectionId', $collectionId);
// Add $collectionId and $databaseId for all documents
$setIds = function (Document $collection, Document $document) use (&$setIds, $dbForProject, $database) {
$document->setAttribute('$databaseId', $database->getId());
$document->setAttribute('$collectionId', $collection->getId());
// Add $databaseId to all documents
$resetIds = function (Document $document) use (&$resetIds, $databaseId) {
$document->setAttribute('$databaseId', $databaseId);
foreach ($document->getAttributes() as $attribute) {
if ($attribute instanceof Document) {
$resetIds($attribute);
$relationships = \array_filter(
$collection->getAttribute('attributes', []),
fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP
);
foreach ($document->getAttributes() as $key => $attribute) {
foreach ($relationships as $relationship) {
if ($key === $relationship->getAttribute('key')) {
$relatedCollectionId = $relationship->getAttribute('relatedCollection');
$relatedCollection = Authorization::skip(
fn() => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId)
);
$setIds($relatedCollection, $attribute);
}
}
}
};
$resetIds($document);
$setIds($collection, $document);
$events
->setParam('databaseId', $databaseId)
@ -3207,18 +3275,36 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/documents/:docu
$dbForProject->deleteCachedDocument($privateCollectionId, $documentId);
$document->setAttribute('$collectionId', $collectionId);
// Add $collectionId and $databaseId for all documents
$setIds = function (Document $collection, Document $document) use (&$setIds, $dbForProject, $database) {
$document->setAttribute('$databaseId', $database->getId());
$document->setAttribute('$collectionId', $collection->getId());
// Add $databaseId to all documents
$resetIds = function (Document $document) use (&$resetIds, $databaseId) {
$document->setAttribute('$databaseId', $databaseId);
foreach ($document->getAttributes() as $attribute) {
if ($attribute instanceof Document) {
$resetIds($attribute);
$relationships = \array_filter(
$collection->getAttribute('attributes', []),
fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP
);
foreach ($document->getAttributes() as $key => $attribute) {
if (!$attribute instanceof Document) {
continue;
}
foreach ($relationships as $relationship) {
if ($key === $relationship->getAttribute('key')) {
$relatedCollectionId = $relationship->getAttribute('relatedCollection');
$relatedCollection = Authorization::skip(
fn() => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId)
);
$setIds($relatedCollection, $attribute);
continue 2;
}
}
}
};
$resetIds($document);
$setIds($collection, $document);
$deletes
->setType(DELETE_TYPE_AUDIT)

View file

@ -10,7 +10,7 @@ use Utopia\Database\Helpers\ID;
use Utopia\Database\Helpers\Permission;
use Utopia\Database\Helpers\Role;
use Utopia\Database\Validator\Datetime as DatetimeValidator;
use Utopia\Database\Query;
trait DatabasesBase
{
@ -3320,7 +3320,7 @@ trait DatabasesBase
$this->assertEquals($databaseId, $person1['body']['library']['$databaseId']);
$this->assertEquals($person['body']['$id'], $person1['body']['$collectionId']);
//$this->assertEquals($library['body']['$id'], $person1['body']['library']['$collectionId']);
$this->assertEquals($library['body']['$id'], $person1['body']['library']['$collectionId']);
$this->assertArrayNotHasKey('$collection', $person1['body']);
$this->assertArrayNotHasKey('$collection', $person1['body']['library']);