diff --git a/src/Appwrite/Migration/Migration.php b/src/Appwrite/Migration/Migration.php index 7a1f3cad24..0ac6fdb22f 100644 --- a/src/Appwrite/Migration/Migration.php +++ b/src/Appwrite/Migration/Migration.php @@ -131,6 +131,10 @@ abstract class Migration */ public function forEachDocument(callable $callback): void { + + return; + + foreach ($this->collections as $collection) { if ($collection['$collection'] !== Database::METADATA) { continue; diff --git a/src/Appwrite/Migration/Version/V19.php b/src/Appwrite/Migration/Version/V19.php new file mode 100644 index 0000000000..b0fcaddd84 --- /dev/null +++ b/src/Appwrite/Migration/Version/V19.php @@ -0,0 +1,157 @@ + null, + fn () => [] + ); + } + + Console::log('Migrating Project: ' . $this->project->getAttribute('name') . ' (' . $this->project->getId() . ')'); + $this->projectDB->setNamespace("_{$this->project->getInternalId()}"); + + $this->alterPermissionIndex('_' . $this->project->getInternalId() . '__metadata'); + + Console::info('Migrating Databases'); + $this->migrateDatabases(); + + Console::info('Migrating Collections'); + $this->migrateCollections(); + + Console::info('Migrating Documents'); + $this->forEachDocument([$this, 'fixDocument']); + } + + /** + * Migrate all Databases. + * + * @return void + * @throws \Exception + */ + private function migrateDatabases(): void + { + foreach ($this->documentsIterator('databases') as $database) { + $databaseTable = "database_{$database->getInternalId()}"; + + Console::info("Migrating Collections of {$database->getId()} ({$database->getAttribute('name')})"); + + $this->alterPermissionIndex($databaseTable); + + foreach ($this->documentsIterator($databaseTable) as $collection) { + $collectionTable = "{$databaseTable}_collection_{$collection->getInternalId()}"; + + $this->alterPermissionIndex($collectionTable); + } + } + } + + /** + * Migrate all Collections. + * + * @return void + */ + private function migrateCollections(): void + { + foreach ($this->collections as $collection) { + $id = $collection['$id']; + + Console::log("Migrating Collection \"{$id}\""); + + $this->alterPermissionIndex($id); + + + usleep(50000); + } + } + + /** + * Fix run on each document + * + * @param Document $document + * @return Document + */ + protected function fixDocument(Document $document): Document + { + switch ($document->getCollection()) { + case 'projects': + /** + * Bump version number. + */ + $document->setAttribute('version', '1.3.0'); + + /** + * Set default passwordHistory + */ + $document->setAttribute('auths', array_merge([ + 'passwordHistory' => 0, + 'passwordDictionary' => false, + ], $document->getAttribute('auths', []))); + break; + case 'users': + /** + * Default Password history + */ + $document->setAttribute('passwordHistory', $document->getAttribute('passwordHistory', [])); + break; + case 'teams': + /** + * Default prefs + */ + $document->setAttribute('prefs', $document->getAttribute('prefs', new \stdClass())); + break; + case 'attributes': + /** + * Default options + */ + $document->setAttribute('options', $document->getAttribute('options', new \stdClass())); + break; + case 'buckets': + /** + * Set the bucket permission in the metadata table + */ + try { + $internalBucketId = "bucket_{$this->project->getInternalId()}"; + $permissions = $document->getPermissions(); + $fileSecurity = $document->getAttribute('fileSecurity', false); + $this->projectDB->updateCollection($internalBucketId, $permissions, $fileSecurity); + } catch (\Throwable $th) { + Console::warning($th->getMessage()); + } + break; + } + + return $document; + } + + protected function alterPermissionIndex($collectionName): void + { + $collectionName = "`{$this->projectDB->getDefaultDatabase()}`.`{$collectionName}_perms`"; + + try { + $this->pdo->prepare("ALTER TABLE {$collectionName} + DROP INDEX `_permission` , + ADD INDEX `_permission` (`_permission`, `_type`, `_document`); + ")->execute(); + } catch (\Throwable $th) { + Console::warning($th->getMessage()); + } + } +}