From 71ad9c203e7d03be19958618a71ba234d34959ec Mon Sep 17 00:00:00 2001 From: Darshan Date: Mon, 5 May 2025 13:53:57 +0530 Subject: [PATCH] fix: response modals, mappings, filters. --- .../Databases/Http/Tables/Usage/Get.php | 4 +- src/Appwrite/Utopia/Request/Filters/V19.php | 19 +++-- src/Appwrite/Utopia/Response.php | 6 +- src/Appwrite/Utopia/Response/Filters/V19.php | 77 ++++++++++++++++++- .../Response/Model/ColumnRelationship.php | 4 +- src/Appwrite/Utopia/Response/Model/Table.php | 38 +++++++++ .../Utopia/Response/Model/UsageDatabase.php | 16 ++-- .../Utopia/Response/Model/UsageDatabases.php | 16 ++-- .../{UsageCollection.php => UsageTable.php} | 14 ++-- 9 files changed, 152 insertions(+), 42 deletions(-) rename src/Appwrite/Utopia/Response/Model/{UsageCollection.php => UsageTable.php} (77%) diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Tables/Usage/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/Tables/Usage/Get.php index b55fa84282..4c591bff1a 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Tables/Usage/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Tables/Usage/Get.php @@ -47,7 +47,7 @@ class Get extends Action responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_OK, - model: UtopiaResponse::MODEL_USAGE_COLLECTION, + model: UtopiaResponse::MODEL_USAGE_TABLE, ) ], contentType: ContentType::JSON, @@ -126,6 +126,6 @@ class Get extends Action 'range' => $range, 'rows' => $usage[$metrics[0]]['data'], 'rowsTotal' => $usage[$metrics[0]]['total'], - ]), UtopiaResponse::MODEL_USAGE_COLLECTION); + ]), UtopiaResponse::MODEL_USAGE_TABLE); } } diff --git a/src/Appwrite/Utopia/Request/Filters/V19.php b/src/Appwrite/Utopia/Request/Filters/V19.php index 041c126a69..ee04cea038 100644 --- a/src/Appwrite/Utopia/Request/Filters/V19.php +++ b/src/Appwrite/Utopia/Request/Filters/V19.php @@ -9,15 +9,18 @@ class V19 extends Filter // Convert 1.6 params to 1.7 public function parse(array $content, string $model): array { - /* - Uncomment with first request filter; current is just a copy of V18 - switch ($model) { - case 'functions.create': - $content['something'] = $content['somethingElse'] ?? ""; - unset($content['something']); - break; + return match ($model) { + 'databases.createRelationshipColumn' => $this->convertV16RelationshipParams($content), + default => $content + }; + } + + protected function convertV16RelationshipParams(array $content): array + { + if (isset($content['relatedCollectionId'])) { + $content['relatedTableId'] = $content['relatedCollectionId']; + unset($content['relatedCollectionId']); } - */ return $content; } diff --git a/src/Appwrite/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index 2ea399c450..62822e9956 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -106,7 +106,6 @@ use Appwrite\Utopia\Response\Model\TemplateVariable; use Appwrite\Utopia\Response\Model\Token; use Appwrite\Utopia\Response\Model\Topic; use Appwrite\Utopia\Response\Model\UsageBuckets; -use Appwrite\Utopia\Response\Model\UsageCollection; use Appwrite\Utopia\Response\Model\UsageDatabase; use Appwrite\Utopia\Response\Model\UsageDatabases; use Appwrite\Utopia\Response\Model\UsageFunction; @@ -115,6 +114,7 @@ use Appwrite\Utopia\Response\Model\UsageProject; use Appwrite\Utopia\Response\Model\UsageSite; use Appwrite\Utopia\Response\Model\UsageSites; use Appwrite\Utopia\Response\Model\UsageStorage; +use Appwrite\Utopia\Response\Model\UsageTable; use Appwrite\Utopia\Response\Model\UsageUsers; use Appwrite\Utopia\Response\Model\User; use Appwrite\Utopia\Response\Model\Variable; @@ -147,7 +147,7 @@ class Response extends SwooleResponse public const MODEL_BASE_LIST = 'baseList'; public const MODEL_USAGE_DATABASES = 'usageDatabases'; public const MODEL_USAGE_DATABASE = 'usageDatabase'; - public const MODEL_USAGE_COLLECTION = 'usageCollection'; + public const MODEL_USAGE_TABLE = 'usageTable'; public const MODEL_USAGE_USERS = 'usageUsers'; public const MODEL_USAGE_BUCKETS = 'usageBuckets'; public const MODEL_USAGE_STORAGE = 'usageStorage'; @@ -508,7 +508,7 @@ class Response extends SwooleResponse ->setModel(new MetricBreakdown()) ->setModel(new UsageDatabases()) ->setModel(new UsageDatabase()) - ->setModel(new UsageCollection()) + ->setModel(new UsageTable()) ->setModel(new UsageUsers()) ->setModel(new UsageStorage()) ->setModel(new UsageBuckets()) diff --git a/src/Appwrite/Utopia/Response/Filters/V19.php b/src/Appwrite/Utopia/Response/Filters/V19.php index 2987c5a7e4..5e1a7e40e7 100644 --- a/src/Appwrite/Utopia/Response/Filters/V19.php +++ b/src/Appwrite/Utopia/Response/Filters/V19.php @@ -7,24 +7,93 @@ use Appwrite\Utopia\Response\Filter; class V19 extends Filter { + private const DATABASE_MAPPINGS = [ + 'table' => 'collection', + 'tables' => 'collections', + 'tablesTotal' => 'collectionsTotal', + 'relatedTable' => 'relatedCollection', + + 'column' => 'attribute', + 'columns' => 'attributes', + 'columnsTotal' => 'attributesTotal', + + 'row' => 'document', + 'rows' => 'documents', + 'rowsTotal' => 'documentsTotal' + ]; + // Convert 1.7 Data format to 1.6 format public function parse(array $content, string $model): array { $parsedResponse = $content; - $parsedResponse = match($model) { + return match ($model) { + Response::MODEL_ROW, + Response::MODEL_TABLE, + Response::MODEL_COLUMN, + Response::MODEL_ROW_LIST, + Response::MODEL_TABLE_LIST, + Response::MODEL_COLUMN_LIST, + Response::MODEL_USAGE_TABLE, + Response::MODEL_USAGE_DATABASE, + Response::MODEL_USAGE_DATABASES, + Response::MODEL_COLUMN_RELATIONSHIP => $this->handleDBTerminology($model, $content), + Response::MODEL_FUNCTION => $this->parseFunction($content), Response::MODEL_FUNCTION_LIST => $this->handleList($content, 'functions', fn ($item) => $this->parseFunction($item)), default => $parsedResponse, }; - - return $parsedResponse; } - protected function parseFunction(array $content) + protected function parseFunction(array $content): array { $content['deployment'] = $content['deploymentId'] ?? ''; unset($content['deploymentId']); return $content; } + + protected function handleDBTerminology(string $model, array $content): array + { + $isListModel = match ($model) { + Response::MODEL_ROW_LIST, + Response::MODEL_TABLE_LIST, + Response::MODEL_COLUMN_LIST => true, + + default => false + }; + + if ($isListModel) { + foreach (self::DATABASE_MAPPINGS as $oldKey => $newKey) { + if (isset($content[$oldKey])) { + $content[$newKey] = array_map(fn ($item) => $this->remapKeys($item), $content[$oldKey]); + unset($content[$oldKey]); + } + } + } else { + $content = $this->remapKeysRecursive($content); + } + + return $content; + } + + private function remapKeys(array $data): array + { + foreach (self::DATABASE_MAPPINGS as $old => $new) { + if (isset($data[$old])) { + $data[$new] = $data[$old]; + unset($data[$old]); + } + } + return $data; + } + + private function remapKeysRecursive(array $data): array + { + $result = []; + foreach ($data as $key => $value) { + $newKey = self::DATABASE_MAPPINGS[$key] ?? $key; + $result[$newKey] = \is_array($value) ? $this->remapKeysRecursive($value) : $value; + } + return $result; + } } diff --git a/src/Appwrite/Utopia/Response/Model/ColumnRelationship.php b/src/Appwrite/Utopia/Response/Model/ColumnRelationship.php index 2c5649b5bf..877982365b 100644 --- a/src/Appwrite/Utopia/Response/Model/ColumnRelationship.php +++ b/src/Appwrite/Utopia/Response/Model/ColumnRelationship.php @@ -12,7 +12,7 @@ class ColumnRelationship extends Column parent::__construct(); $this - ->addRule('relatedCollection', [ + ->addRule('relatedTable', [ 'type' => self::TYPE_STRING, 'description' => 'The ID of the related table.', 'default' => null, @@ -84,7 +84,7 @@ class ColumnRelationship extends Column { $options = $document->getAttribute('options'); if (!\is_null($options)) { - $document->setAttribute('relatedCollection', $options['relatedCollection']); + $document->setAttribute('relatedTable', $options['relatedCollection']); $document->setAttribute('relationType', $options['relationType']); $document->setAttribute('twoWay', $options['twoWay']); $document->setAttribute('twoWayKey', $options['twoWayKey']); diff --git a/src/Appwrite/Utopia/Response/Model/Table.php b/src/Appwrite/Utopia/Response/Model/Table.php index d7098f313f..e36cb1dabd 100644 --- a/src/Appwrite/Utopia/Response/Model/Table.php +++ b/src/Appwrite/Utopia/Response/Model/Table.php @@ -4,6 +4,7 @@ namespace Appwrite\Utopia\Response\Model; use Appwrite\Utopia\Response; use Appwrite\Utopia\Response\Model; +use Utopia\Database\Document; class Table extends Model { @@ -106,4 +107,41 @@ class Table extends Model { return Response::MODEL_TABLE; } + + /** + * Process Document before returning it to the client for backwards compatibility! + */ + public function filter(Document $document): Document + { + $columns = $document->getAttribute('attributes', []); + if (!empty($columns) && \is_array($columns)) { + $columns = $this->remapNestedRelatedCollections($columns); + } + + $document + ->setAttribute('columns', $columns) + ->removeAttribute('attributes'); + + $related = $document->getAttribute('relatedCollection'); + if ($related !== null) { + $document + ->setAttribute('relatedTable', $related) + ->removeAttribute('relatedCollection'); + } + + return $document; + } + + // 1.7 now sends back `relatedTable` instead of `relatedCollection`. + // This is necessary because the actual database underneath uses `relatedCollection`. + private function remapNestedRelatedCollections(array $columns): array + { + foreach ($columns as $i => $column) { + if (isset($column['relatedCollection'])) { + $columns[$i]['relatedTable'] = $column['relatedCollection']; + unset($columns[$i]['relatedCollection']); + } + } + return $columns; + } } diff --git a/src/Appwrite/Utopia/Response/Model/UsageDatabase.php b/src/Appwrite/Utopia/Response/Model/UsageDatabase.php index a0fe421f5f..a3212017a4 100644 --- a/src/Appwrite/Utopia/Response/Model/UsageDatabase.php +++ b/src/Appwrite/Utopia/Response/Model/UsageDatabase.php @@ -16,15 +16,15 @@ class UsageDatabase extends Model 'default' => '', 'example' => '30d', ]) - ->addRule('collectionsTotal', [ + ->addRule('tablesTotal', [ 'type' => self::TYPE_INTEGER, - 'description' => 'Total aggregated number of collections.', + 'description' => 'Total aggregated number of tables.', 'default' => 0, 'example' => 0, ]) - ->addRule('documentsTotal', [ + ->addRule('rowsTotal', [ 'type' => self::TYPE_INTEGER, - 'description' => 'Total aggregated number of documents.', + 'description' => 'Total aggregated number of rows.', 'default' => 0, 'example' => 0, ]) @@ -46,16 +46,16 @@ class UsageDatabase extends Model 'default' => 0, 'example' => 0, ]) - ->addRule('collections', [ + ->addRule('tables', [ 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated number of collections per period.', + 'description' => 'Aggregated number of tables per period.', 'default' => [], 'example' => [], 'array' => true ]) - ->addRule('documents', [ + ->addRule('rows', [ 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated number of documents per period.', + 'description' => 'Aggregated number of rows per period.', 'default' => [], 'example' => [], 'array' => true diff --git a/src/Appwrite/Utopia/Response/Model/UsageDatabases.php b/src/Appwrite/Utopia/Response/Model/UsageDatabases.php index 4e053e5223..11392f6efb 100644 --- a/src/Appwrite/Utopia/Response/Model/UsageDatabases.php +++ b/src/Appwrite/Utopia/Response/Model/UsageDatabases.php @@ -22,15 +22,15 @@ class UsageDatabases extends Model 'default' => 0, 'example' => 0, ]) - ->addRule('collectionsTotal', [ + ->addRule('tablesTotal', [ 'type' => self::TYPE_INTEGER, - 'description' => 'Total aggregated number of collections.', + 'description' => 'Total aggregated number of tables.', 'default' => 0, 'example' => 0, ]) - ->addRule('documentsTotal', [ + ->addRule('rowsTotal', [ 'type' => self::TYPE_INTEGER, - 'description' => 'Total aggregated number of documents.', + 'description' => 'Total aggregated number of rows.', 'default' => 0, 'example' => 0, ]) @@ -59,16 +59,16 @@ class UsageDatabases extends Model 'example' => [], 'array' => true ]) - ->addRule('collections', [ + ->addRule('tables', [ 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated number of collections per period.', + 'description' => 'Aggregated number of tables per period.', 'default' => [], 'example' => [], 'array' => true ]) - ->addRule('documents', [ + ->addRule('rows', [ 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated number of documents per period.', + 'description' => 'Aggregated number of rows per period.', 'default' => [], 'example' => [], 'array' => true diff --git a/src/Appwrite/Utopia/Response/Model/UsageCollection.php b/src/Appwrite/Utopia/Response/Model/UsageTable.php similarity index 77% rename from src/Appwrite/Utopia/Response/Model/UsageCollection.php rename to src/Appwrite/Utopia/Response/Model/UsageTable.php index b2336d65ba..553a4b5001 100644 --- a/src/Appwrite/Utopia/Response/Model/UsageCollection.php +++ b/src/Appwrite/Utopia/Response/Model/UsageTable.php @@ -5,7 +5,7 @@ namespace Appwrite\Utopia\Response\Model; use Appwrite\Utopia\Response; use Appwrite\Utopia\Response\Model; -class UsageCollection extends Model +class UsageTable extends Model { public function __construct() { @@ -16,15 +16,15 @@ class UsageCollection extends Model 'default' => '', 'example' => '30d', ]) - ->addRule('documentsTotal', [ + ->addRule('rowsTotal', [ 'type' => self::TYPE_INTEGER, - 'description' => 'Total aggregated number of of documents.', + 'description' => 'Total aggregated number of of rows.', 'default' => 0, 'example' => 0, ]) - ->addRule('documents', [ + ->addRule('rows', [ 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated number of documents per period.', + 'description' => 'Aggregated number of rows per period.', 'default' => [], 'example' => [], 'array' => true @@ -39,7 +39,7 @@ class UsageCollection extends Model */ public function getName(): string { - return 'UsageCollection'; + return 'UsageTable'; } /** @@ -49,6 +49,6 @@ class UsageCollection extends Model */ public function getType(): string { - return Response::MODEL_USAGE_COLLECTION; + return Response::MODEL_USAGE_TABLE; } }