diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 38624367c9..8ec487a559 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -31,6 +31,8 @@ use Utopia\Queue\Message; use Utopia\Storage\Device; use Utopia\System\System; +use function Swoole\Coroutine\batch; + class Deletes extends Action { protected array $selects = ['$sequence', '$id', '$collection', '$permissions', '$updatedAt']; @@ -51,6 +53,7 @@ class Deletes extends Action ->inject('project') ->inject('dbForPlatform') ->inject('getProjectDB') + ->inject('getDatabasesDB') ->inject('getLogsDB') ->inject('deviceForFiles') ->inject('deviceForFunctions') @@ -74,6 +77,7 @@ class Deletes extends Action Document $project, Database $dbForPlatform, callable $getProjectDB, + callable $getDatabasesDB, callable $getLogsDB, Device $deviceForFiles, Device $deviceForFunctions, @@ -106,7 +110,7 @@ class Deletes extends Action case DELETE_TYPE_DOCUMENT: switch ($document->getCollection()) { case DELETE_TYPE_PROJECTS: - $this->deleteProject($dbForPlatform, $getProjectDB, $deviceForFiles, $deviceForSites, $deviceForFunctions, $deviceForBuilds, $deviceForCache, $certificates, $document); + $this->deleteProject($dbForPlatform, $getProjectDB, $getDatabasesDB, $deviceForFiles, $deviceForSites, $deviceForFunctions, $deviceForBuilds, $deviceForCache, $certificates, $document); break; case DELETE_TYPE_SITES: $this->deleteSite($dbForPlatform, $getProjectDB, $deviceForSites, $deviceForBuilds, $deviceForFiles, $document, $certificates, $project); @@ -138,7 +142,7 @@ class Deletes extends Action } break; case DELETE_TYPE_TEAM_PROJECTS: - $this->deleteProjectsByTeam($dbForPlatform, $getProjectDB, $certificates, $document); + $this->deleteProjectsByTeam($dbForPlatform, $getProjectDB, $getDatabasesDB, $certificates, $document); break; case DELETE_TYPE_EXECUTIONS: $this->deleteExecutionLogs($project, $getProjectDB, $executionRetention); @@ -468,7 +472,7 @@ class Deletes extends Action * @throws Structure * @throws Exception */ - protected function deleteProjectsByTeam(Database $dbForPlatform, callable $getProjectDB, CertificatesAdapter $certificates, Document $document): void + protected function deleteProjectsByTeam(Database $dbForPlatform, callable $getProjectDB, callable $getDatabasesDB, CertificatesAdapter $certificates, Document $document): void { $projects = $dbForPlatform->find('projects', [ @@ -483,7 +487,7 @@ class Deletes extends Action $deviceForBuilds = getDevice(APP_STORAGE_BUILDS . '/app-' . $project->getId()); $deviceForCache = getDevice(APP_STORAGE_CACHE . '/app-' . $project->getId()); - $this->deleteProject($dbForPlatform, $getProjectDB, $deviceForFiles, $deviceForSites, $deviceForFunctions, $deviceForBuilds, $deviceForCache, $certificates, $project); + $this->deleteProject($dbForPlatform, $getProjectDB, $getDatabasesDB, $deviceForFiles, $deviceForSites, $deviceForFunctions, $deviceForBuilds, $deviceForCache, $certificates, $project); $dbForPlatform->deleteDocument('projects', $project->getId()); } } @@ -501,7 +505,7 @@ class Deletes extends Action * @throws Authorization * @throws DatabaseException */ - protected function deleteProject(Database $dbForPlatform, callable $getProjectDB, Device $deviceForFiles, Device $deviceForSites, Device $deviceForFunctions, Device $deviceForBuilds, Device $deviceForCache, CertificatesAdapter $certificates, Document $document): void + protected function deleteProject(Database $dbForPlatform, callable $getProjectDB, callable $getDatabasesDB, Device $deviceForFiles, Device $deviceForSites, Device $deviceForFunctions, Device $deviceForBuilds, Device $deviceForCache, CertificatesAdapter $certificates, Document $document): void { $projectInternalId = $document->getSequence(); $projectId = $document->getId(); @@ -527,27 +531,45 @@ class Deletes extends Action $projectTables = !\in_array($dsn->getHost(), $sharedTables); $sharedTablesV1 = \in_array($dsn->getHost(), $sharedTablesV1); $sharedTablesV2 = !$projectTables && !$sharedTablesV1; + $databaseDSNKeys = ['database','documentsDatabase']; - /** - * @var $dbForProject Database - */ - $dbForProject->foreach(Database::METADATA, function (Document $collection) use ($dbForProject, $projectTables, $projectCollectionIds) { - try { - if ($projectTables || !\in_array($collection->getId(), $projectCollectionIds)) { - $dbForProject->deleteCollection($collection->getId()); - } else { - $this->deleteByGroup( - $collection->getId(), - [ - Query::orderAsc() - ], - database: $dbForProject - ); - } - } catch (Throwable $e) { - Console::error('Error deleting ' . $collection->getId() . ' ' . $e->getMessage()); - } - }); + $exectionActionPerDatabase = function (string $databaseDSNKey, $callback) use ($getDatabasesDB, $document) { + /** + * @var Database $dbForDatabases + */ + $dbForDatabases = $getDatabasesDB(new Document(['database' => $document->getAttribute($databaseDSNKey)]), $document); + $callback($dbForDatabases); + }; + + batch(array_map( + fn ($databaseDSNKey) => + fn () => $exectionActionPerDatabase( + $databaseDSNKey, + function (Database $dbForDatabases) use ($projectTables, $projectCollectionIds) { + $dbForDatabases->foreach( + Database::METADATA, + function (Document $collection) use ($dbForDatabases, $projectTables, $projectCollectionIds) { + try { + if ($projectTables || !\in_array($collection->getId(), $projectCollectionIds, true)) { + $dbForDatabases->deleteCollection($collection->getId()); + } else { + $this->deleteByGroup( + $collection->getId(), + [Query::orderAsc()], + database: $dbForDatabases + ); + } + } catch (Throwable $e) { + Console::error( + 'Error deleting ' . $collection->getId() . ' ' . $e->getMessage() + ); + } + } + ); + } + ), + $databaseDSNKeys + )); // Delete Platforms $this->deleteByGroup('platforms', [ @@ -601,7 +623,15 @@ class Deletes extends Action // Delete metadata table if ($projectTables) { - $dbForProject->deleteCollection(Database::METADATA); + batch(array_map( + fn ($databaseDSNKey) => fn () => + $exectionActionPerDatabase( + $databaseDSNKey, + fn (Database $dbForDatabases) => + $dbForDatabases->deleteCollection(Database::METADATA) + ), + $databaseDSNKeys + )); } elseif ($sharedTablesV1) { $this->deleteByGroup( Database::METADATA, diff --git a/src/Appwrite/Platform/Workers/StatsUsage.php b/src/Appwrite/Platform/Workers/StatsUsage.php index 09860520af..092582123a 100644 --- a/src/Appwrite/Platform/Workers/StatsUsage.php +++ b/src/Appwrite/Platform/Workers/StatsUsage.php @@ -67,6 +67,8 @@ class StatsUsage extends Action METRIC_BUILDS => true, METRIC_COLLECTIONS => true, METRIC_DOCUMENTS => true, + METRIC_COLLECTIONS_DOCUMENTSDB => true, + METRIC_DOCUMENTS_DOCUMENTSDB => true, METRIC_DATABASES_STORAGE => true, METRIC_DATABASES_STORAGE_DOCUMENTSDB => true, ];