From 5fa348d7ee0f8355d80436a7b5bd7150da9ae9a2 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Fri, 1 May 2026 13:21:15 +1200 Subject: [PATCH] refactor: drop compound resourceId end-to-end, remove V25 SDK filters The previous commit kept a getCompoundResourceId() helper and a pair of V25 request/response filters that recomposed the legacy "id:id" shape at the boundary to utopia-php/migration. That was a workaround for the library still requiring a composite. The library has now been updated in utopia-php/migration#feat/drop-compound-resource-id to take separate databaseId/tableId and a separate rootResourceChildId, so the compromise is no longer needed. - Worker now reads parentResourceId/resourceId straight from the migration document and passes them as separate args to CSV/JSON source/destination constructors and to Transfer::run. - getCompoundResourceId() helper removed. - Request/V25 and Response/V25 filters removed (their only job was to translate the dropped composite shape). - composer.json pinned to the migration library branch via VCS until it ships a tagged release. Co-Authored-By: Claude Opus 4.7 (1M context) --- app/controllers/general.php | 8 --- composer.json | 8 ++- composer.lock | 63 ++++++++++++++------ src/Appwrite/Platform/Workers/Migrations.php | 40 +++++-------- src/Appwrite/Utopia/Request/Filters/V25.php | 43 ------------- src/Appwrite/Utopia/Response/Filters/V25.php | 38 ------------ 6 files changed, 67 insertions(+), 133 deletions(-) delete mode 100644 src/Appwrite/Utopia/Request/Filters/V25.php delete mode 100644 src/Appwrite/Utopia/Response/Filters/V25.php diff --git a/app/controllers/general.php b/app/controllers/general.php index 21bcded22c..eb4899a3d8 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -28,7 +28,6 @@ use Appwrite\Utopia\Request\Filters\V21 as RequestV21; use Appwrite\Utopia\Request\Filters\V22 as RequestV22; use Appwrite\Utopia\Request\Filters\V23 as RequestV23; use Appwrite\Utopia\Request\Filters\V24 as RequestV24; -use Appwrite\Utopia\Request\Filters\V25 as RequestV25; use Appwrite\Utopia\Response; use Appwrite\Utopia\Response\Filters\V16 as ResponseV16; use Appwrite\Utopia\Response\Filters\V17 as ResponseV17; @@ -39,7 +38,6 @@ use Appwrite\Utopia\Response\Filters\V21 as ResponseV21; use Appwrite\Utopia\Response\Filters\V22 as ResponseV22; use Appwrite\Utopia\Response\Filters\V23 as ResponseV23; use Appwrite\Utopia\Response\Filters\V24 as ResponseV24; -use Appwrite\Utopia\Response\Filters\V25 as ResponseV25; use Appwrite\Utopia\View; use Executor\Executor; use MaxMind\Db\Reader; @@ -906,9 +904,6 @@ Http::init() if (version_compare($requestFormat, '1.9.3', '<')) { $request->addFilter(new RequestV24()); } - if (version_compare($requestFormat, '1.9.4', '<')) { - $request->addFilter(new RequestV25()); - } } $localeParam = (string) $request->getParam('locale', $request->getHeader('x-appwrite-locale', '')); @@ -933,9 +928,6 @@ Http::init() */ $responseFormat = $request->getHeader('x-appwrite-response-format', System::getEnv('_APP_SYSTEM_RESPONSE_FORMAT', '')); if ($responseFormat) { - if (version_compare($responseFormat, '1.9.4', '<')) { - $response->addFilter(new ResponseV25()); - } if (version_compare($responseFormat, '1.9.3', '<')) { $response->addFilter(new ResponseV24()); } diff --git a/composer.json b/composer.json index 683da6f21b..9131bd2f6a 100644 --- a/composer.json +++ b/composer.json @@ -35,6 +35,12 @@ }, "minimum-stability": "dev", "prefer-stable": true, + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/utopia-php/migration" + } + ], "require": { "php": ">=8.3.0", "ext-curl": "*", @@ -74,7 +80,7 @@ "utopia-php/locale": "0.8.*", "utopia-php/logger": "0.6.*", "utopia-php/messaging": "0.22.*", - "utopia-php/migration": "1.9.*", + "utopia-php/migration": "dev-feat/drop-compound-resource-id#53a1426675df9c2d07e9706ed212d71c1e272294 as 1.9.7", "utopia-php/platform": "0.13.*", "utopia-php/pools": "1.*", "utopia-php/span": "1.1.*", diff --git a/composer.lock b/composer.lock index 3edbc39614..5ab3048195 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4bee36b21a57e754d2b3417e72dc9599", + "content-hash": "2fba7e6fed2dc298fcd3c77e71f7b188", "packages": [ { "name": "adhocore/jwt", @@ -3850,16 +3850,16 @@ }, { "name": "utopia-php/database", - "version": "5.4.1", + "version": "5.4.2", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "688d9422b5ff42ac2ecc29397d94891cfd772e93" + "reference": "a1bb3e2a4fba13032ea625b21a21039c43cffeda" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/688d9422b5ff42ac2ecc29397d94891cfd772e93", - "reference": "688d9422b5ff42ac2ecc29397d94891cfd772e93", + "url": "https://api.github.com/repos/utopia-php/database/zipball/a1bb3e2a4fba13032ea625b21a21039c43cffeda", + "reference": "a1bb3e2a4fba13032ea625b21a21039c43cffeda", "shasum": "" }, "require": { @@ -3903,9 +3903,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/5.4.1" + "source": "https://github.com/utopia-php/database/tree/5.4.2" }, - "time": "2026-04-29T07:32:59+00:00" + "time": "2026-04-30T09:59:57+00:00" }, { "name": "utopia-php/detector", @@ -4530,16 +4530,16 @@ }, { "name": "utopia-php/migration", - "version": "1.9.5", + "version": "dev-feat/drop-compound-resource-id", "source": { "type": "git", "url": "https://github.com/utopia-php/migration.git", - "reference": "952a4dfe232702f80e45c35129466a8d8cb4c599" + "reference": "53a1426675df9c2d07e9706ed212d71c1e272294" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/migration/zipball/952a4dfe232702f80e45c35129466a8d8cb4c599", - "reference": "952a4dfe232702f80e45c35129466a8d8cb4c599", + "url": "https://api.github.com/repos/utopia-php/migration/zipball/53a1426675df9c2d07e9706ed212d71c1e272294", + "reference": "53a1426675df9c2d07e9706ed212d71c1e272294", "shasum": "" }, "require": { @@ -4565,7 +4565,25 @@ "Utopia\\Migration\\": "src/Migration" } }, - "notification-url": "https://packagist.org/downloads/", + "autoload-dev": { + "psr-4": { + "Utopia\\Tests\\": "tests/Migration" + } + }, + "scripts": { + "test": [ + "./vendor/bin/phpunit" + ], + "lint": [ + "./vendor/bin/pint --test" + ], + "format": [ + "./vendor/bin/pint" + ], + "check": [ + "./vendor/bin/phpstan analyse --level 3 src tests --memory-limit 2G" + ] + }, "license": [ "MIT" ], @@ -4578,10 +4596,10 @@ "utopia" ], "support": { - "issues": "https://github.com/utopia-php/migration/issues", - "source": "https://github.com/utopia-php/migration/tree/1.9.5" + "source": "https://github.com/utopia-php/migration/tree/feat/drop-compound-resource-id", + "issues": "https://github.com/utopia-php/migration/issues" }, - "time": "2026-04-29T11:19:13+00:00" + "time": "2026-05-01T01:13:21+00:00" }, { "name": "utopia-php/mongo", @@ -8442,9 +8460,18 @@ "time": "2024-11-07T12:36:22+00:00" } ], - "aliases": [], + "aliases": [ + { + "package": "utopia-php/migration", + "version": "dev-feat/drop-compound-resource-id", + "alias": "1.9.7", + "alias_normalized": "1.9.7.0" + } + ], "minimum-stability": "dev", - "stability-flags": [], + "stability-flags": { + "utopia-php/migration": 20 + }, "prefer-stable": true, "prefer-lowest": false, "platform": { @@ -8465,5 +8492,5 @@ "platform-dev": { "ext-fileinfo": "*" }, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.9.0" } diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 4997e8f330..451c644253 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -189,7 +189,8 @@ class Migrations extends Action { $source = $migration->getAttribute('source'); $destination = $migration->getAttribute('destination'); - $resourceId = $this->getCompoundResourceId($migration); + $databaseId = (string) $migration->getAttribute('parentResourceId', ''); + $tableId = (string) $migration->getAttribute('resourceId', ''); $credentials = $migration->getAttribute('credentials'); $migrationOptions = $migration->getAttribute('options'); /** @var Database|null $projectDB */ @@ -253,14 +254,16 @@ class Migrations extends Action $queries ), CSV::getName() => new CSV( - $resourceId, + $databaseId, + $tableId, $migrationOptions['path'], $this->deviceForMigrations, $this->dbForProject, $getDatabasesDB ), JSON::getName() => new JSON( - $resourceId, + $databaseId, + $tableId, $migrationOptions['path'], $this->deviceForMigrations, $this->dbForProject, @@ -282,6 +285,8 @@ class Migrations extends Action $destination = $migration->getAttribute('destination'); $options = $migration->getAttribute('options', []); $credentials = $migration->getAttribute('credentials'); + $databaseId = (string) $migration->getAttribute('parentResourceId', ''); + $tableId = (string) $migration->getAttribute('resourceId', ''); return match ($destination) { DestinationAppwrite::getName() => new DestinationAppwrite( @@ -294,7 +299,8 @@ class Migrations extends Action ), DestinationCSV::getName() => new DestinationCSV( $this->deviceForFiles, - $this->getCompoundResourceId($migration), + $databaseId, + $tableId, $options['bucketId'], $options['filename'], $options['columns'], @@ -305,7 +311,8 @@ class Migrations extends Action ), DestinationJSON::getName() => new DestinationJSON( $this->deviceForFiles, - $this->getCompoundResourceId($migration), + $databaseId, + $tableId, $options['bucketId'] ?? 'default', $options['filename'], $options['columns'] ?? [], @@ -507,8 +514,9 @@ class Migrations extends Action } $this->updateMigrationDocument($migration, $project, $queueForRealtime); }, - $this->getCompoundResourceId($migration), - $migration->getAttribute('parentResourceType') + $migration->getAttribute('parentResourceId'), + $migration->getAttribute('parentResourceType'), + $migration->getAttribute('resourceId'), ); $destination->shutdown(); @@ -609,24 +617,6 @@ class Migrations extends Action return ($this->getDatabasesDB)($database); } - /** - * Returns a "{parentResourceId}:{resourceId}" string when both are set, - * or the leaf resourceId on its own otherwise. Returning a parent-only - * value would feed the utopia-php/migration library a malformed - * compound, so an unanchored parent yields null instead. - */ - protected function getCompoundResourceId(Document $migration): ?string - { - $parentResourceId = $migration->getAttribute('parentResourceId'); - $resourceId = $migration->getAttribute('resourceId'); - - if (!empty($parentResourceId) && !empty($resourceId)) { - return $parentResourceId . ':' . $resourceId; - } - - return !empty($resourceId) ? $resourceId : null; - } - /** * Handle actions to be performed when a CSV export migration is successfully completed * diff --git a/src/Appwrite/Utopia/Request/Filters/V25.php b/src/Appwrite/Utopia/Request/Filters/V25.php deleted file mode 100644 index 36e5c5e19f..0000000000 --- a/src/Appwrite/Utopia/Request/Filters/V25.php +++ /dev/null @@ -1,43 +0,0 @@ -parseMigrationResource($content); - break; - } - - return $content; - } - - protected function parseMigrationResource(array $content): array - { - if (!isset($content['resourceId']) || !\is_string($content['resourceId'])) { - return $content; - } - - if (!\str_contains($content['resourceId'], ':')) { - // Leave malformed resourceId in place so the new UID validator - // surfaces it to the caller instead of silently scrubbing it. - return $content; - } - - [$databaseId, $collectionId] = \explode(':', $content['resourceId'], 2); - $content['databaseId'] = $content['databaseId'] ?? $databaseId; - $content['collectionId'] = $content['collectionId'] ?? $collectionId; - unset($content['resourceId']); - - return $content; - } -} diff --git a/src/Appwrite/Utopia/Response/Filters/V25.php b/src/Appwrite/Utopia/Response/Filters/V25.php deleted file mode 100644 index b53f895166..0000000000 --- a/src/Appwrite/Utopia/Response/Filters/V25.php +++ /dev/null @@ -1,38 +0,0 @@ - $this->parseMigration($content), - Response::MODEL_MIGRATION_LIST => $this->handleList($content, 'migrations', fn ($item) => $this->parseMigration($item)), - default => $content, - }; - } - - protected function parseMigration(array $content): array - { - $parentResourceId = $content['parentResourceId'] ?? ''; - $resourceId = $content['resourceId'] ?? ''; - - if ($parentResourceId !== '' && $resourceId !== '') { - $content['resourceId'] = $parentResourceId . ':' . $resourceId; - } - - $content['resourceType'] = $content['parentResourceType'] ?? $content['resourceType'] ?? ''; - - unset($content['resourceInternalId']); - unset($content['parentResourceId']); - unset($content['parentResourceInternalId']); - unset($content['parentResourceType']); - - return $content; - } -}