From e808bdd6c7206d26adf8b46ae91aaedaba89e369 Mon Sep 17 00:00:00 2001 From: Prem Palanisamy Date: Wed, 8 Apr 2026 06:50:33 +0100 Subject: [PATCH 1/5] Add overwrite and skip options to Appwrite destination - Add setOverwrite() / setSkip() methods to Appwrite destination - When overwrite is true, use upsertDocuments to update existing rows - When skip is true, pass ignore: true to createDocuments to silently skip duplicates - Point utopia-php/database to csv-import-upsert branch for ignore support --- composer.json | 2 +- composer.lock | 117 ++++++++---------------- src/Migration/Destinations/Appwrite.php | 33 ++++++- 3 files changed, 70 insertions(+), 82 deletions(-) diff --git a/composer.json b/composer.json index 5585f2a5..9467d498 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,7 @@ "ext-curl": "*", "ext-openssl": "*", "appwrite/appwrite": "19.*", - "utopia-php/database": "5.*", + "utopia-php/database": "dev-csv-import-upsert as 5.0.0", "utopia-php/storage": "1.0.*", "utopia-php/dsn": "0.2.*", "halaxa/json-machine": "^1.2" diff --git a/composer.lock b/composer.lock index 17d14221..1ec1fe59 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": "37980b9001fbbd4f213f3102c1332727", + "content-hash": "dabc86460a51ec9fcff7d13028401c27", "packages": [ { "name": "appwrite/appwrite", @@ -2181,17 +2181,17 @@ "time": "2026-01-28T10:55:44+00:00" }, { - "name": "utopia-php/compression", - "version": "0.1.3", + "name": "utopia-php/console", + "version": "0.1.1", "source": { "type": "git", - "url": "https://github.com/utopia-php/compression.git", - "reference": "66f093557ba66d98245e562036182016c7dcfe8a" + "url": "https://github.com/utopia-php/console.git", + "reference": "d298e43960780e6d76e66de1228c75dc81220e3e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/compression/zipball/66f093557ba66d98245e562036182016c7dcfe8a", - "reference": "66f093557ba66d98245e562036182016c7dcfe8a", + "url": "https://api.github.com/repos/utopia-php/console/zipball/d298e43960780e6d76e66de1228c75dc81220e3e", + "reference": "d298e43960780e6d76e66de1228c75dc81220e3e", "shasum": "" }, "require": { @@ -2199,45 +2199,47 @@ }, "require-dev": { "laravel/pint": "1.2.*", + "phpstan/phpstan": "^1.10", "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" + "squizlabs/php_codesniffer": "^3.6", + "swoole/ide-helper": "4.8.8" }, "type": "library", "autoload": { "psr-4": { - "Utopia\\Compression\\": "src/Compression" + "Utopia\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "A simple Compression library to handle file compression", + "description": "Console helpers for logging, prompting, and executing commands", "keywords": [ - "compression", - "framework", + "cli", + "console", "php", - "upf", + "terminal", "utopia" ], "support": { - "issues": "https://github.com/utopia-php/compression/issues", - "source": "https://github.com/utopia-php/compression/tree/0.1.3" + "issues": "https://github.com/utopia-php/console/issues", + "source": "https://github.com/utopia-php/console/tree/0.1.1" }, - "time": "2025-01-15T15:15:51+00:00" + "time": "2026-02-10T10:20:29+00:00" }, { "name": "utopia-php/database", - "version": "5.2.1", + "version": "dev-csv-import-upsert", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "adfdf201144353a1d2ce14bb197ab746079894e0" + "reference": "ba749b981933fa68818950f5f44057e09c994d60" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/adfdf201144353a1d2ce14bb197ab746079894e0", - "reference": "adfdf201144353a1d2ce14bb197ab746079894e0", + "url": "https://api.github.com/repos/utopia-php/database/zipball/ba749b981933fa68818950f5f44057e09c994d60", + "reference": "ba749b981933fa68818950f5f44057e09c994d60", "shasum": "" }, "require": { @@ -2246,9 +2248,10 @@ "ext-pdo": "*", "php": ">=8.4", "utopia-php/cache": "1.*", - "utopia-php/framework": "0.33.*", + "utopia-php/console": "0.1.*", "utopia-php/mongo": "1.*", - "utopia-php/pools": "1.*" + "utopia-php/pools": "1.*", + "utopia-php/validators": "0.2.*" }, "require-dev": { "fakerphp/faker": "1.23.*", @@ -2258,7 +2261,7 @@ "phpunit/phpunit": "9.*", "rregeer/phpunit-coverage-check": "0.3.*", "swoole/ide-helper": "5.1.3", - "utopia-php/cli": "0.14.*" + "utopia-php/cli": "0.22.*" }, "type": "library", "autoload": { @@ -2280,9 +2283,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/5.2.1" + "source": "https://github.com/utopia-php/database/tree/csv-import-upsert" }, - "time": "2026-02-16T11:01:13+00:00" + "time": "2026-04-07T15:26:34+00:00" }, { "name": "utopia-php/dsn", @@ -2331,55 +2334,6 @@ }, "time": "2024-05-07T02:01:25+00:00" }, - { - "name": "utopia-php/framework", - "version": "0.33.39", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/http.git", - "reference": "409a258814d664d3a50fa2f48b6695679334d30b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/http/zipball/409a258814d664d3a50fa2f48b6695679334d30b", - "reference": "409a258814d664d3a50fa2f48b6695679334d30b", - "shasum": "" - }, - "require": { - "php": ">=8.3", - "utopia-php/compression": "0.1.*", - "utopia-php/telemetry": "0.2.*", - "utopia-php/validators": "0.2.*" - }, - "require-dev": { - "laravel/pint": "1.*", - "phpbench/phpbench": "1.*", - "phpstan/phpstan": "1.*", - "phpunit/phpunit": "9.*", - "swoole/ide-helper": "^6.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A simple, light and advanced PHP framework", - "keywords": [ - "framework", - "php", - "upf" - ], - "support": { - "issues": "https://github.com/utopia-php/http/issues", - "source": "https://github.com/utopia-php/http/tree/0.33.39" - }, - "time": "2026-02-11T06:33:42+00:00" - }, { "name": "utopia-php/mongo", "version": "1.0.0", @@ -4995,9 +4949,18 @@ "time": "2025-12-27T19:49:13+00:00" } ], - "aliases": [], + "aliases": [ + { + "package": "utopia-php/database", + "version": "dev-csv-import-upsert", + "alias": "5.0.0", + "alias_normalized": "5.0.0.0" + } + ], "minimum-stability": "stable", - "stability-flags": {}, + "stability-flags": { + "utopia-php/database": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { @@ -5008,5 +4971,5 @@ "platform-dev": { "ext-pdo": "*" }, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.9.0" } diff --git a/src/Migration/Destinations/Appwrite.php b/src/Migration/Destinations/Appwrite.php index 6b730a18..7ca153ac 100644 --- a/src/Migration/Destinations/Appwrite.php +++ b/src/Migration/Destinations/Appwrite.php @@ -71,6 +71,21 @@ class Appwrite extends Destination */ private array $rowBuffer = []; + private bool $overwrite = false; + private bool $skip = false; + + public function setOverwrite(bool $overwrite): self + { + $this->overwrite = $overwrite; + return $this; + } + + public function setSkip(bool $skip): self + { + $this->skip = $skip; + return $this; + } + /** * @param string $project * @param string $endpoint @@ -1055,10 +1070,20 @@ protected function createRow(Row $resource, bool $isLast): bool } } - $this->database->skipRelationshipsExistCheck(fn () => $this->database->createDocuments( - 'database_' . $databaseInternalId . '_collection_' . $tableInternalId, - $this->rowBuffer - )); + $collectionName = 'database_' . $databaseInternalId . '_collection_' . $tableInternalId; + + if ($this->overwrite) { + $this->database->skipRelationshipsExistCheck(fn () => $this->database->upsertDocuments( + $collectionName, + $this->rowBuffer + )); + } else { + $this->database->skipRelationshipsExistCheck(fn () => $this->database->createDocuments( + $collectionName, + $this->rowBuffer, + ignore: $this->skip + )); + } } finally { $this->rowBuffer = []; From 685698eca410f54aeae71927fe55ca2a4b3ed10c Mon Sep 17 00:00:00 2001 From: Prem Palanisamy Date: Wed, 8 Apr 2026 07:12:35 +0100 Subject: [PATCH 2/5] Fix cache bypass for overwrite mode and validate overwrite+skip exclusivity --- src/Migration/Destinations/Appwrite.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Migration/Destinations/Appwrite.php b/src/Migration/Destinations/Appwrite.php index f7561e78..7ea67479 100644 --- a/src/Migration/Destinations/Appwrite.php +++ b/src/Migration/Destinations/Appwrite.php @@ -90,12 +90,18 @@ class Appwrite extends Destination public function setOverwrite(bool $overwrite): self { + if ($overwrite && $this->skip) { + throw new \InvalidArgumentException('Cannot set both overwrite and skip to true.'); + } $this->overwrite = $overwrite; return $this; } public function setSkip(bool $skip): self { + if ($skip && $this->overwrite) { + throw new \InvalidArgumentException('Cannot set both skip and overwrite to true.'); + } $this->skip = $skip; return $this; } @@ -1001,7 +1007,7 @@ protected function createRecord(Row $resource, bool $isLast): bool $this->cache->get($resource->getName()) ); - if ($exists) { + if ($exists && !$this->overwrite) { $resource->setStatus( Resource::STATUS_SKIPPED, 'Row has already been created' From a3a84bd20a946828e0f34dfa83c43e14b1749c2c Mon Sep 17 00:00:00 2001 From: Prem Palanisamy Date: Thu, 9 Apr 2026 01:56:44 +0100 Subject: [PATCH 3/5] Point utopia-php/database to csv-import-upsert-v2 branch --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 9467d498..ab271cc5 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,7 @@ "ext-curl": "*", "ext-openssl": "*", "appwrite/appwrite": "19.*", - "utopia-php/database": "dev-csv-import-upsert as 5.0.0", + "utopia-php/database": "dev-csv-import-upsert-v2 as 5.0.0", "utopia-php/storage": "1.0.*", "utopia-php/dsn": "0.2.*", "halaxa/json-machine": "^1.2" From 8c85cbebcb98724c03c5e50af4defeabe020ab9e Mon Sep 17 00:00:00 2001 From: Prem Palanisamy Date: Thu, 9 Apr 2026 01:59:50 +0100 Subject: [PATCH 4/5] Update composer.lock for database csv-import-upsert-v2 --- composer.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/composer.lock b/composer.lock index 1ec1fe59..53a14be3 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": "dabc86460a51ec9fcff7d13028401c27", + "content-hash": "6ea71156f3e91271eaa877a54a4f3d4c", "packages": [ { "name": "appwrite/appwrite", @@ -2230,16 +2230,16 @@ }, { "name": "utopia-php/database", - "version": "dev-csv-import-upsert", + "version": "dev-csv-import-upsert-v2", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "ba749b981933fa68818950f5f44057e09c994d60" + "reference": "bb419ba6a5da1975373bbd958f9fd4d61fb3ee48" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/ba749b981933fa68818950f5f44057e09c994d60", - "reference": "ba749b981933fa68818950f5f44057e09c994d60", + "url": "https://api.github.com/repos/utopia-php/database/zipball/bb419ba6a5da1975373bbd958f9fd4d61fb3ee48", + "reference": "bb419ba6a5da1975373bbd958f9fd4d61fb3ee48", "shasum": "" }, "require": { @@ -2283,9 +2283,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/csv-import-upsert" + "source": "https://github.com/utopia-php/database/tree/csv-import-upsert-v2" }, - "time": "2026-04-07T15:26:34+00:00" + "time": "2026-04-09T00:55:20+00:00" }, { "name": "utopia-php/dsn", @@ -4952,7 +4952,7 @@ "aliases": [ { "package": "utopia-php/database", - "version": "dev-csv-import-upsert", + "version": "dev-csv-import-upsert-v2", "alias": "5.0.0", "alias_normalized": "5.0.0.0" } From 9d389efec5f6b3d8b5e9fa5355508f185b691f10 Mon Sep 17 00:00:00 2001 From: Prem Palanisamy Date: Mon, 13 Apr 2026 08:24:19 +0100 Subject: [PATCH 5/5] Use skipDuplicates() scope guard instead of removed ignore: parameter The bool $ignore parameter on Database::createDocuments() was replaced with a skipDuplicates(callable, bool) scope guard in utopia-php/database csv-import-upsert-v2. The previous named-argument call would throw "Unknown named argument" at runtime against the current database branch. Wrap createDocuments in skipDuplicates() so the orchestrator picks up the flag through its instance state instead of via parameter. --- src/Migration/Destinations/Appwrite.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Migration/Destinations/Appwrite.php b/src/Migration/Destinations/Appwrite.php index 7ea67479..b3afe348 100644 --- a/src/Migration/Destinations/Appwrite.php +++ b/src/Migration/Destinations/Appwrite.php @@ -1096,10 +1096,12 @@ protected function createRecord(Row $resource, bool $isLast): bool $this->rowBuffer )); } else { - $dbForDatabases->skipRelationshipsExistCheck(fn () => $dbForDatabases->createDocuments( - $collectionName, - $this->rowBuffer, - ignore: $this->skip + $dbForDatabases->skipRelationshipsExistCheck(fn () => $dbForDatabases->skipDuplicates( + fn () => $dbForDatabases->createDocuments( + $collectionName, + $this->rowBuffer + ), + $this->skip )); }