diff --git a/app/Console/Commands/Wiki/DropDatabase.php b/app/Console/Commands/Wiki/DropDatabase.php new file mode 100644 index 000000000..69756e33b --- /dev/null +++ b/app/Console/Commands/Wiki/DropDatabase.php @@ -0,0 +1,71 @@ +argument('wikiDomain')); + $wiki = Wiki::with('wikidb')->firstWhere('domain', $wikiDomain); + + if (!$wiki) { + $this->error("Wiki not found by domain '$wikiDomain'"); + + return 1; + } + + if (!$this->dropWikiDb($wiki->wikidb)) { + $this->error('Failed to drop the mediawiki database of wiki.'); + $this->error($wiki); + + return 2; + } + + $this->info('MediaWiki database dropped.'); + + $wiki->delete(); + + $this->info('Wiki soft-deleted.'); + $this->info($wiki); + + return 0; + } + + private function dropWikiDb(WikiDb $wikiDb): bool { + $connection = $this->getWikiDbConnection($wikiDb); + + if (!$connection instanceof \Illuminate\Database\Connection) { + throw new \RuntimeException('Must be run on a PDO based DB connection'); + } + + $mediawikiPdo = $connection->getPdo(); + $statement = $mediawikiPdo->prepare('DROP DATABASE ' . $wikiDb->name); + + return $statement->execute([$wikiDb->name]); + } + + // Creates a temporary DB connection with wiki scoped credentials + private function getWikiDbConnection(WikiDb $wikiDb): mixed { + $wikiDbConnectionConfig = array_replace( + app()->config->get('database.connections.mw'), + [ + 'database' => $wikiDb->name, + 'username' => $wikiDb->user, + 'password' => $wikiDb->password, + ] + ); + + app()->config->set('database.connections.wikiTemp', $wikiDbConnectionConfig); + + return App::make(DatabaseManager::class)->connection('wikiTemp'); + } +} diff --git a/tests/Commands/Wiki/DropDatabaseTest.php b/tests/Commands/Wiki/DropDatabaseTest.php new file mode 100644 index 000000000..4e2e2c1ae --- /dev/null +++ b/tests/Commands/Wiki/DropDatabaseTest.php @@ -0,0 +1,19 @@ +artisan( + 'wbs-wiki:dropDatabase', [ + 'wikiDomain' => 'imaginarywiki.wbaas.dev', + ]) + ->assertExitCode(1) + ->assertFailed(); + } +}