From 5aff6969dbb4e1c251ca2b7f617889a28a2c7391 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 29 Mar 2023 23:31:49 +0300 Subject: [PATCH] add relations into attributes collection --- app/workers/databases.php | 42 +++++++++++++++++++ phpunit.xml | 2 +- .../e2e/Services/Databases/DatabasesBase.php | 24 ++++++++--- 3 files changed, 62 insertions(+), 6 deletions(-) diff --git a/app/workers/databases.php b/app/workers/databases.php index c073bf3b95..a88373e580 100644 --- a/app/workers/databases.php +++ b/app/workers/databases.php @@ -94,6 +94,7 @@ class DatabaseV1 extends Worker $options = $attribute->getAttribute('options', []); $project = $dbForConsole->getDocument('projects', $projectId); + $related = null; try { switch ($type) { case Database::VAR_RELATIONSHIP: @@ -114,6 +115,42 @@ class DatabaseV1 extends Worker ) { throw new Exception('Failed to create Attribute'); } + + $metadata = $dbForProject->getCollection('database_' . $database->getInternalId() . '_collection_' . $relatedCollection->getInternalId()); + + $related = \array_filter($metadata->getAttribute('attributes', []), function ($a) use ($options) { + return $a['$id'] === $options['twoWayKey']; + }); + + /** + * @var Document $related + */ + $related = end($related); + $options = $related->getAttribute('options', []); + $options['relatedCollection'] = $collection->getId(); + + $related = new Document([ + '$id' => ID::custom($database->getInternalId() . '_' . $relatedCollection->getInternalId() . '_' . $related->getId()), + 'key' => $related->getId(), + 'databaseInternalId' => $database->getInternalId(), + 'databaseId' => $database->getId(), + 'collectionInternalId' => $relatedCollection->getInternalId(), + 'collectionId' => $relatedCollection->getId(), + 'status' => 'available', + 'type' => Database::VAR_RELATIONSHIP, + 'size' => 0, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + 'signed' => false, + 'format' => '', + 'formatOptions' => [], + 'options' => $options, + ]); + + $related = $dbForProject->createDocument('attributes', $related); + break; default: if (!$dbForProject->createAttribute('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $key, $type, $size, $required, $default, $signed, $array, $format, $formatOptions, $filters)) { @@ -125,6 +162,11 @@ class DatabaseV1 extends Worker } catch (\Throwable $th) { Console::error($th->getMessage()); $dbForProject->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'failed')); + + if (Database::VAR_RELATIONSHIP === $type) { + $dbForProject->updateDocument('attributes', $related->getId(), $related->setAttribute('status', 'failed')); + // todo: needs to clean cache for related colllection? + } } finally { $target = Realtime::fromPayload( // Pass first, most verbose event pattern diff --git a/phpunit.xml b/phpunit.xml index 5b4bcdb99c..a448fcc8c7 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -6,7 +6,7 @@ convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" - stopOnFailure="false" + stopOnFailure="true" > diff --git a/tests/e2e/Services/Databases/DatabasesBase.php b/tests/e2e/Services/Databases/DatabasesBase.php index d073e96cb9..6829e8d3f1 100644 --- a/tests/e2e/Services/Databases/DatabasesBase.php +++ b/tests/e2e/Services/Databases/DatabasesBase.php @@ -3392,6 +3392,17 @@ trait DatabasesBase $this->assertArrayNotHasKey('library', $person1['body']); + $libraryAttributesResponse = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $library['body']['$id'] . '/attributes', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ])); + var_dump($libraryAttributesResponse); + + $this->assertIsArray($libraryAttributesResponse['body']['attributes']); + $this->assertEquals(2, $libraryAttributesResponse['body']['total']); + $this->assertEquals('person_attr', $libraryAttributesResponse['body']['attributes'][0]['key']); + die; return [ 'databaseId' => $databaseId, 'personCollection' => $person['body']['$id'], @@ -3418,7 +3429,7 @@ trait DatabasesBase 'type' => Database::RELATION_ONE_TO_MANY, 'twoWay' => true, 'key' => 'libraries', - 'twoWayKey' => 'person', + 'twoWayKey' => 'person_attr', // Person is in use ]); sleep(1); @@ -3428,9 +3439,12 @@ trait DatabasesBase 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] ])); +var_dump($libraryAttributesResponse); +die; $this->assertIsArray($libraryAttributesResponse['body']['attributes']); $this->assertEquals(2, $libraryAttributesResponse['body']['total']); // currently = 1 + $this->assertEquals('person_attr', $libraryAttributesResponse['body']['attributes'][0]['key']); $libraryCollectionResponse = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $libraryCollection, array_merge([ 'content-type' => 'application/json', @@ -3439,7 +3453,7 @@ trait DatabasesBase ])); $this->assertIsArray($libraryCollectionResponse['body']['attributes']); - $this->assertCount(2, $libraryCollectionResponse['body']['attributes']); // currently = 1 + $this->assertCount(2, $libraryCollectionResponse['body']['attributes']); $attribute = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$personCollection}/attributes/libraries", array_merge([ 'content-type' => 'application/json', @@ -3455,7 +3469,7 @@ trait DatabasesBase $this->assertEquals(false, $attribute['body']['array']); $this->assertEquals('oneToMany', $attribute['body']['relationType']); $this->assertEquals(true, $attribute['body']['twoWay']); - $this->assertEquals('person', $attribute['body']['twoWayKey']); + $this->assertEquals('person_attr', $attribute['body']['twoWayKey']); $this->assertEquals('restrict', $attribute['body']['onDelete']); $person2 = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $personCollection . '/documents', array_merge([ @@ -3513,8 +3527,8 @@ trait DatabasesBase ], $this->getHeaders())); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertArrayHasKey('person', $response['body']); - $this->assertEquals('person10', $response['body']['person']['$id']); + $this->assertArrayHasKey('person_attr', $response['body']); + $this->assertEquals('person10', $response['body']['person_attr']['$id']); $response = $this->client->call(Client::METHOD_PATCH, '/databases/' . $databaseId . '/collections/' . $personCollection . '/attributes/libraries/relationship', array_merge([ 'content-type' => 'application/json',