This commit is contained in:
Your Name
2026-04-22 13:39:28 +08:00
parent b943ea2ab7
commit c1ac050c6a
17 changed files with 893 additions and 20 deletions

View File

@@ -0,0 +1,102 @@
<?php
declare(strict_types=1);
namespace db;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\Output;
class DatabaseManage extends Command
{
protected function configure()
{
$this->setName('db:manage')
->setDescription('Manage the database: backup or initialize')
->addArgument('action', Argument::OPTIONAL, 'The action to perform: backup or init or seed');
}
protected function execute(Input $input, Output $output): int
{
$strAction = strtolower((string) $input->getArgument('action'));
return match ($strAction) {
'backup' => $this->runBackupDatabase($output),
'init' => $this->runCommand($output, 'migrate:run') | $this->runCommand($output, 'seed:run'),
'seed' => $this->runCommand($output, 'seed:run'),
default => $this->invalidAction($output),
};
}
public function seed(): int
{
return 0;
}
public function backupDatabase(): int
{
return 0;
}
public function initializeDatabase(): int
{
return 0;
}
private function invalidAction(Output $output): int
{
$output->writeln("Invalid action. Use 'backup' or 'init'. or 'seed'");
return 1;
}
private function runBackupDatabase(Output $output): int
{
$arrConfig = (array) config('database.connections.mysql', []);
$strDir = runtime_path() . 'db-backup';
if (!is_dir($strDir)) {
@mkdir($strDir, 0777, true);
}
$strFile = $strDir . '/' . date('Ymd-His') . '.sql';
$arrParts = [
'mysqldump',
'-h' . escapeshellarg((string) ($arrConfig['hostname'] ?? '127.0.0.1')),
'-P' . escapeshellarg((string) ($arrConfig['hostport'] ?? '3306')),
'-u' . escapeshellarg((string) ($arrConfig['username'] ?? 'root')),
];
$strPassword = (string) ($arrConfig['password'] ?? '');
if ($strPassword !== '') {
$arrParts[] = '-p' . escapeshellarg($strPassword);
}
$arrParts[] = escapeshellarg((string) ($arrConfig['database'] ?? ''));
$strCommand = implode(' ', $arrParts) . ' > ' . escapeshellarg($strFile) . ' 2>&1';
exec($strCommand, $arrOutput, $intCode);
if ($intCode !== 0) {
$output->writeln('Database backup failed.');
return 1;
}
$output->writeln('Database backup written to: ' . $strFile);
return 0;
}
private function runCommand(Output $output, string $strCommand): int
{
$strRoot = rtrim(root_path(), '/');
$strExec = sprintf(
'cd %s && %s think %s 2>&1',
escapeshellarg($strRoot),
escapeshellarg(PHP_BINARY),
escapeshellarg($strCommand)
);
exec($strExec, $arrOutput, $intCode);
foreach ($arrOutput as $strLine) {
$output->writeln($strLine);
}
return $intCode;
}
}

View File

@@ -0,0 +1,88 @@
<?php
declare(strict_types=1);
namespace db;
use MongoDB\Client;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\Output;
class MongoMigrate extends Command
{
protected function configure()
{
$this->setName('mongo:manage')
->setDescription('Manage the mongo, migarte index or drop all index')
->addArgument('action', Argument::OPTIONAL, 'The action to perform: migrate');
}
protected function execute(Input $input, Output $output): int
{
$strAction = strtolower((string) $input->getArgument('action'));
return match ($strAction) {
'migrate' => $this->migrate($output),
'drop' => $this->dropAllIndexes($output),
default => $this->invalidAction($output),
};
}
public function dropAllIndexes(Output $output): int
{
$db = $this->getMongoDatabase();
foreach ($db->listCollections() as $CollectionInfo) {
$Collection = $db->selectCollection($CollectionInfo->getName());
foreach ($Collection->listIndexes() as $IndexInfo) {
$strIndexName = (string) $IndexInfo->getName();
if ($strIndexName === '_id_') {
continue;
}
$Collection->dropIndex($strIndexName);
$output->writeln(sprintf('Dropped index %s on %s', $strIndexName, $CollectionInfo->getName()));
}
}
return 0;
}
public function migrate(Output $output): int
{
$db = $this->getMongoDatabase();
$intCount = 0;
foreach ($db->listCollections() as $CollectionInfo) {
$intCount++;
$output->writeln('Checked collection: ' . $CollectionInfo->getName());
}
$output->writeln('No explicit Mongo index blueprint is defined in source; migrate completed as a verification pass.');
return $intCount >= 0 ? 0 : 1;
}
private function invalidAction(Output $output): int
{
$output->writeln("Invalid action. Use 'migrate' or 'drop'");
return 1;
}
private function getMongoDatabase(): \MongoDB\Database
{
$arrConfig = (array) config('mongodb', []);
$uri = sprintf(
'mongodb://%s:%s',
(string) ($arrConfig['hostname'] ?? '127.0.0.1'),
(string) ($arrConfig['hostport'] ?? '27017')
);
$arrOptions = [];
$strUsername = (string) ($arrConfig['username'] ?? '');
if ($strUsername !== '') {
$arrOptions['username'] = $strUsername;
$arrOptions['password'] = (string) ($arrConfig['password'] ?? '');
$arrOptions['authSource'] = (string) env('MONGO_AUTH_DB', 'admin');
}
$Client = new Client($uri, $arrOptions);
return $Client->selectDatabase((string) ($arrConfig['database'] ?? ''));
}
}

View File

@@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
namespace db;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\Output;
use think\facade\Cache;
class NovelManage extends Command
{
protected function configure()
{
$this->setName('novel:manage')
->setDescription('Manage the novel data: reset or ...')
->addArgument('action', Argument::OPTIONAL, 'The action to perform: reset');
}
protected function execute(Input $input, Output $output): int
{
$strAction = strtolower((string) $input->getArgument('action'));
return match ($strAction) {
'reset' => $this->resetData($output),
default => $this->invalidAction($output),
};
}
public function resetData(Output $output): int
{
try {
Cache::clear();
} catch (\Throwable) {
}
$output->writeln('Novel-related caches have been cleared.');
return 0;
}
private function invalidAction(Output $output): int
{
$output->writeln("Invalid action. Use 'reset' ");
return 1;
}
}