Implement mysqldump/backup service/command

This commit is contained in:
Tim 2021-12-16 00:58:17 +01:00
parent 0ff9021d6e
commit 11089d82bc
9 changed files with 122 additions and 29 deletions

View File

@ -7,15 +7,15 @@
"php": ">=8.0", "php": ">=8.0",
"ext-ctype": "*", "ext-ctype": "*",
"ext-iconv": "*", "ext-iconv": "*",
"ext-mysqli": "*",
"symfony/console": "5.3.*", "symfony/console": "5.3.*",
"symfony/dotenv": "5.3.*", "symfony/dotenv": "5.3.*",
"symfony/filesystem": "5.3.*",
"symfony/flex": "^1.3.1", "symfony/flex": "^1.3.1",
"symfony/framework-bundle": "5.3.*", "symfony/framework-bundle": "5.3.*",
"symfony/process": "5.3.*",
"symfony/runtime": "5.3.*", "symfony/runtime": "5.3.*",
"symfony/yaml": "5.3.*", "symfony/yaml": "5.3.*"
"ext-mysqli": "*"
},
"require-dev": {
}, },
"config": { "config": {
"optimize-autoloader": true, "optimize-autoloader": true,

73
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "e77b7d594056580678fe7de815ac7270", "content-hash": "8c7050f7bee5a93ee3509d8014488736",
"packages": [ "packages": [
{ {
"name": "psr/cache", "name": "psr/cache",
@ -2107,6 +2107,68 @@
], ],
"time": "2021-05-21T13:25:03+00:00" "time": "2021-05-21T13:25:03+00:00"
}, },
{
"name": "symfony/process",
"version": "v5.3.12",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
"reference": "e498803a6e95ede78e9d5646ad32a2255c033a6a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/e498803a6e95ede78e9d5646ad32a2255c033a6a",
"reference": "e498803a6e95ede78e9d5646ad32a2255c033a6a",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"symfony/polyfill-php80": "^1.16"
},
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\Process\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Executes commands in sub-processes",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/process/tree/v5.3.12"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2021-11-22T22:39:13+00:00"
},
{ {
"name": "symfony/routing", "name": "symfony/routing",
"version": "v5.3.7", "version": "v5.3.7",
@ -2680,12 +2742,11 @@
"prefer-stable": true, "prefer-stable": true,
"prefer-lowest": false, "prefer-lowest": false,
"platform": { "platform": {
"php": ">=7.2.5", "php": ">=8.0",
"ext-ctype": "*", "ext-ctype": "*",
"ext-iconv": "*" "ext-iconv": "*",
}, "ext-mysqli": "*"
"platform-dev": {
"php": "*"
}, },
"platform-dev": [],
"plugin-api-version": "2.1.0" "plugin-api-version": "2.1.0"
} }

View File

@ -2,19 +2,23 @@
namespace App\Console; namespace App\Console;
use App\Service\DatabaseManager; use App\Service\BackupService;
use App\Service\DatabaseService;
use App\Service\Traits\SelectDatabaseQuestion;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;
class BackupDatabase extends Command class BackupDatabase extends Command
{ {
protected static $defaultName = 'app:db:create'; use SelectDatabaseQuestion;
protected static $defaultName = 'app:db:backup';
public function __construct( public function __construct(
private DatabaseManager $db, private DatabaseService $db,
private BackupService $bs,
) )
{ {
parent::__construct(); parent::__construct();
@ -27,15 +31,10 @@ class BackupDatabase extends Command
protected function execute(InputInterface $input, OutputInterface $output): int protected function execute(InputInterface $input, OutputInterface $output): int
{ {
$question = $this->getHelper('question'); $db = $this->getDatabaseName($input, $output);
if (!$name = $input->getArgument('name')) { $output = $this->bs->backup($db);
$name = $question->ask($input, $output, new Question('Database name: ')); dump($output);
}
$this->db->createDatabase($name);
$output->writeln(sprintf('Database "%s" successfully created', $name));
return Command::SUCCESS; return Command::SUCCESS;
} }

View File

@ -2,7 +2,7 @@
namespace App\Console; namespace App\Console;
use App\Service\DatabaseManager; use App\Service\DatabaseService;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
@ -14,7 +14,7 @@ class CreateDatabaseCommand extends Command
protected static $defaultName = 'app:db:create'; protected static $defaultName = 'app:db:create';
public function __construct( public function __construct(
private DatabaseManager $db, private DatabaseService $db,
) )
{ {
parent::__construct(); parent::__construct();

View File

@ -2,7 +2,7 @@
namespace App\Console; namespace App\Console;
use App\Service\DatabaseManager; use App\Service\DatabaseService;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
@ -12,7 +12,7 @@ class ListDatabasesCommand extends Command
protected static $defaultName = 'app:db:list'; protected static $defaultName = 'app:db:list';
public function __construct( public function __construct(
private DatabaseManager $db, private DatabaseService $db,
) )
{ {
parent::__construct(); parent::__construct();

View File

@ -2,7 +2,7 @@
namespace App\Console; namespace App\Console;
use App\Service\DatabaseManager; use App\Service\DatabaseService;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
@ -12,7 +12,7 @@ class ListUsersCommand extends Command
protected static $defaultName = 'app:users:list'; protected static $defaultName = 'app:users:list';
public function __construct( public function __construct(
private DatabaseManager $db, private DatabaseService $db,
) )
{ {
parent::__construct(); parent::__construct();

View File

@ -0,0 +1,30 @@
<?php
namespace App\Service;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Process\Process;
class BackupService
{
public function __construct(private DatabaseCredentials $credentials)
{
}
public function backup(string $db): string
{
$filesystem = new Filesystem();
$process = new Process([
'mysqldump',
'-B', $db,
'-u', $this->credentials->getUser(),
]);
$process->setEnv(['MYSQL_PWD' => $this->credentials->getPassword()]);
$process->run();
$fileName = sprintf('%s_backup.sql', $db);
$filesystem->dumpFile($fileName, $process->getOutput());
return $fileName;
}
}

View File

@ -4,7 +4,7 @@ namespace App\Service;
use mysqli; use mysqli;
class DatabaseManager class DatabaseService
{ {
private mysqli $conn; private mysqli $conn;

View File

@ -114,6 +114,9 @@
"symfony/polyfill-php81": { "symfony/polyfill-php81": {
"version": "v1.23.0" "version": "v1.23.0"
}, },
"symfony/process": {
"version": "v5.3.12"
},
"symfony/routing": { "symfony/routing": {
"version": "5.3", "version": "5.3",
"recipe": { "recipe": {