diff --git a/app/init.php b/app/init.php index 4e8e8103c9..4cbf08cf2f 100644 --- a/app/init.php +++ b/app/init.php @@ -767,6 +767,25 @@ $register->set('pools', function () { return $group; }); +$register->set('db', function () { + // This is usually for our workers or CLI commands scope + $dbHost = App::getEnv('_APP_DB_HOST', ''); + $dbPort = App::getEnv('_APP_DB_PORT', ''); + $dbUser = App::getEnv('_APP_DB_USER', ''); + $dbPass = App::getEnv('_APP_DB_PASS', ''); + $dbScheme = App::getEnv('_APP_DB_SCHEMA', ''); + + $pdo = new PDO("mysql:host={$dbHost};port={$dbPort};dbname={$dbScheme};charset=utf8mb4", $dbUser, $dbPass, array( + PDO::ATTR_TIMEOUT => 3, // Seconds + PDO::ATTR_PERSISTENT => true, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_EMULATE_PREPARES => true, + PDO::ATTR_STRINGIFY_FETCHES => true, + )); + + return $pdo; +}); $register->set('influxdb', function () { // Register DB connection diff --git a/src/Appwrite/Migration/Migration.php b/src/Appwrite/Migration/Migration.php index 0a2dd2f186..9ee4d9236a 100644 --- a/src/Appwrite/Migration/Migration.php +++ b/src/Appwrite/Migration/Migration.php @@ -195,17 +195,24 @@ abstract class Migration * @return iterable * @throws \Exception */ - public function documentsIterator(string $collectionId): iterable + public function documentsIterator(string $collectionId, $queries = []): iterable { $sum = 0; $nextDocument = null; $collectionCount = $this->projectDB->count($collectionId); + $queries[] = Query::limit($this->limit); do { - $queries = [Query::limit($this->limit)]; if ($nextDocument !== null) { - $queries[] = Query::cursorAfter($nextDocument); + $cursorQueryIndex = \array_search('cursorAfter', \array_map(fn (Query $query) => $query->getMethod(), $queries)); + + if ($cursorQueryIndex !== false) { + $queries[$cursorQueryIndex] = Query::cursorAfter($nextDocument); + } else { + $queries[] = Query::cursorAfter($nextDocument); + } } + $documents = $this->projectDB->find($collectionId, $queries); $count = count($documents); $sum += $count; diff --git a/src/Appwrite/Migration/Version/V19.php b/src/Appwrite/Migration/Version/V19.php index b9ccf3c302..46a0a073a6 100644 --- a/src/Appwrite/Migration/Version/V19.php +++ b/src/Appwrite/Migration/Version/V19.php @@ -10,6 +10,7 @@ use Utopia\Database\Database; use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Exception; +use Utopia\Database\Query; class V19 extends Migration { @@ -41,6 +42,11 @@ class V19 extends Migration Console::info('Migrating Buckets'); $this->migrateBuckets(); + if ($this->project->getId() !== 'console') { + Console::info('Migrating Enum Attribute Size'); + $this->migrateEnumAttributeSize(); + } + Console::info('Migrating Documents'); $this->forEachDocument([$this, 'fixDocument']); @@ -640,6 +646,22 @@ class V19 extends Migration return $commands; } + private function migrateEnumAttributeSize(): void + { + foreach ( + $this->documentsIterator('attributes', [ + Query::equal('format', ['enum']), + Query::lessThan('size', Database::LENGTH_KEY) + ]) as $attribute + ) { + $attribute->setAttribute('size', Database::LENGTH_KEY); + $this->projectDB->updateDocument('attributes', $attribute->getId(), $attribute); + $databaseInternalId = $attribute->getAttribute('databaseInternalId'); + $collectionInternalId = $attribute->getAttribute('collectionInternalId'); + $this->projectDB->updateAttribute('database_' . $databaseInternalId . '_collection_' . $collectionInternalId, $attribute->getAttribute('key'), size: 255); + } + } + /** * Fix run on each document * diff --git a/src/Appwrite/Platform/Tasks/Migrate.php b/src/Appwrite/Platform/Tasks/Migrate.php index 38e5c8aa46..682b9b5559 100644 --- a/src/Appwrite/Platform/Tasks/Migrate.php +++ b/src/Appwrite/Platform/Tasks/Migrate.php @@ -11,6 +11,7 @@ use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; +use Utopia\Registry\Registry; use Utopia\Validator\Text; class Migrate extends Action @@ -29,7 +30,8 @@ class Migrate extends Action ->inject('cache') ->inject('dbForConsole') ->inject('getProjectDB') - ->callback(fn ($version, $cache, $dbForConsole, $getProjectDB) => $this->action($version, $cache, $dbForConsole, $getProjectDB)); + ->inject('register') + ->callback(fn ($version, $cache, $dbForConsole, $getProjectDB, Registry $register) => $this->action($version, $cache, $dbForConsole, $getProjectDB, $register)); } private function clearProjectsCache(Cache $cache, Document $project) @@ -41,7 +43,7 @@ class Migrate extends Action } } - public function action(string $version, Cache $cache, Database $dbForConsole, callable $getProjectDB) + public function action(string $version, Cache $cache, Database $dbForConsole, callable $getProjectDB, Registry $register) { Authorization::disable(); if (!array_key_exists($version, Migration::$versions)) { @@ -89,9 +91,11 @@ class Migrate extends Action try { // TODO: Iterate through all project DBs + /** @var Database $projectDB */ $projectDB = $getProjectDB($project); $migration ->setProject($project, $projectDB, $dbForConsole) + ->setPDO($register->get('db', true)) ->execute(); } catch (\Throwable $th) { Console::error('Failed to update project ("' . $project->getId() . '") version with error: ' . $th->getMessage());