diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 983e13b295..be81bd888f 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -516,125 +516,136 @@ class Deletes extends Action $dsn = new DSN('mysql://' . $document->getAttribute('database', 'console')); } - $dbForProject = $getProjectDB($document); - - $projectCollectionIds = [ - ...\array_keys(Config::getParam('collections', [])['projects']), - SQL::COLLECTION, - AbuseDatabase::COLLECTION, - ]; - - $sharedTables = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', '')); - $sharedTablesV1 = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES_V1', '')); - - $projectTables = !\in_array($dsn->getHost(), $sharedTables); - $sharedTablesV1 = \in_array($dsn->getHost(), $sharedTablesV1); - $sharedTablesV2 = !$projectTables && !$sharedTablesV1; - /** * @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 - ); + $dbForProject = $getProjectDB($document); + + try { + /** + * Disable validation because of Cursor validation on $id underscores + */ + $dbForProject->disableValidation(); + + + $projectCollectionIds = [ + ...\array_keys(Config::getParam('collections', [])['projects']), + SQL::COLLECTION, + AbuseDatabase::COLLECTION, + ]; + + $sharedTables = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', '')); + $sharedTablesV1 = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES_V1', '')); + + $projectTables = !\in_array($dsn->getHost(), $sharedTables); + $sharedTablesV1 = \in_array($dsn->getHost(), $sharedTablesV1); + $sharedTablesV2 = !$projectTables && !$sharedTablesV1; + + $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()); } - } catch (Throwable $e) { - Console::error('Error deleting ' . $collection->getId() . ' ' . $e->getMessage()); + }); + + // Delete Platforms + $this->deleteByGroup('platforms', [ + Query::equal('projectInternalId', [$projectInternalId]), + Query::orderAsc() + ], $dbForPlatform); + + // Delete project and function rules + $this->deleteByGroup('rules', [ + Query::equal('projectInternalId', [$projectInternalId]), + Query::orderAsc() + ], $dbForPlatform, function (Document $document) use ($dbForPlatform, $certificates) { + $this->deleteRule($dbForPlatform, $document, $certificates); + }); + + // Delete Keys + $this->deleteByGroup('keys', [ + Query::equal('resourceType', ['projects']), + Query::equal('resourceInternalId', [$projectInternalId]), + Query::orderAsc() + ], $dbForPlatform); + + // Delete Webhooks + $this->deleteByGroup('webhooks', [ + Query::equal('projectInternalId', [$projectInternalId]), + Query::orderAsc() + ], $dbForPlatform); + + // Delete VCS Installations + $this->deleteByGroup('installations', [ + Query::equal('projectInternalId', [$projectInternalId]), + Query::orderAsc() + ], $dbForPlatform); + + // Delete VCS Repositories + $this->deleteByGroup('repositories', [ + Query::equal('projectInternalId', [$projectInternalId]), + Query::orderAsc() + ], $dbForPlatform); + + // Delete VCS comments + $this->deleteByGroup('vcsComments', [ + Query::equal('projectInternalId', [$projectInternalId]), + Query::orderAsc() + ], $dbForPlatform); + + // Delete Schedules + $this->deleteByGroup('schedules', [ + Query::equal('projectId', [$projectId]), + Query::orderAsc() + ], $dbForPlatform); + + // Delete metadata table + if ($projectTables) { + $dbForProject->deleteCollection(Database::METADATA); + } elseif ($sharedTablesV1) { + $this->deleteByGroup( + Database::METADATA, + [ + Query::orderAsc() + ], + $dbForProject + ); + } elseif ($sharedTablesV2) { + $queries = \array_map( + fn ($id) => Query::notEqual('$id', $id), + $projectCollectionIds + ); + + $queries[] = Query::orderAsc(); + + $this->deleteByGroup( + Database::METADATA, + $queries, + $dbForProject + ); } - }); - // Delete Platforms - $this->deleteByGroup('platforms', [ - Query::equal('projectInternalId', [$projectInternalId]), - Query::orderAsc() - ], $dbForPlatform); + // Delete all storage directories + $deviceForFiles->delete($deviceForFiles->getRoot(), true); + $deviceForSites->delete($deviceForSites->getRoot(), true); + $deviceForFunctions->delete($deviceForFunctions->getRoot(), true); + $deviceForBuilds->delete($deviceForBuilds->getRoot(), true); + $deviceForCache->delete($deviceForCache->getRoot(), true); - // Delete project and function rules - $this->deleteByGroup('rules', [ - Query::equal('projectInternalId', [$projectInternalId]), - Query::orderAsc() - ], $dbForPlatform, function (Document $document) use ($dbForPlatform, $certificates) { - $this->deleteRule($dbForPlatform, $document, $certificates); - }); - - // Delete Keys - $this->deleteByGroup('keys', [ - Query::equal('resourceType', ['projects']), - Query::equal('resourceInternalId', [$projectInternalId]), - Query::orderAsc() - ], $dbForPlatform); - - // Delete Webhooks - $this->deleteByGroup('webhooks', [ - Query::equal('projectInternalId', [$projectInternalId]), - Query::orderAsc() - ], $dbForPlatform); - - // Delete VCS Installations - $this->deleteByGroup('installations', [ - Query::equal('projectInternalId', [$projectInternalId]), - Query::orderAsc() - ], $dbForPlatform); - - // Delete VCS Repositories - $this->deleteByGroup('repositories', [ - Query::equal('projectInternalId', [$projectInternalId]), - Query::orderAsc() - ], $dbForPlatform); - - // Delete VCS comments - $this->deleteByGroup('vcsComments', [ - Query::equal('projectInternalId', [$projectInternalId]), - Query::orderAsc() - ], $dbForPlatform); - - // Delete Schedules - $this->deleteByGroup('schedules', [ - Query::equal('projectId', [$projectId]), - Query::orderAsc() - ], $dbForPlatform); - - // Delete metadata table - if ($projectTables) { - $dbForProject->deleteCollection(Database::METADATA); - } elseif ($sharedTablesV1) { - $this->deleteByGroup( - Database::METADATA, - [ - Query::orderAsc() - ], - $dbForProject - ); - } elseif ($sharedTablesV2) { - $queries = \array_map( - fn ($id) => Query::notEqual('$id', $id), - $projectCollectionIds - ); - - $queries[] = Query::orderAsc(); - - $this->deleteByGroup( - Database::METADATA, - $queries, - $dbForProject - ); + } finally { + $dbForProject->enableValidation(); } - - // Delete all storage directories - $deviceForFiles->delete($deviceForFiles->getRoot(), true); - $deviceForSites->delete($deviceForSites->getRoot(), true); - $deviceForFunctions->delete($deviceForFunctions->getRoot(), true); - $deviceForBuilds->delete($deviceForBuilds->getRoot(), true); - $deviceForCache->delete($deviceForCache->getRoot(), true); } /**