1 <?php declare(strict_types=1);
3 namespace Cli\Services;
9 public function __construct(
10 protected string $host,
11 protected string $user,
12 protected string $password,
13 protected string $database,
14 protected int $port = 3306
21 public function ensureOptionsSet(): void
23 $options = ['host', 'user', 'password', 'database'];
24 foreach ($options as $option) {
25 if (!$this->$option) {
26 throw new Exception("Could not find a valid value for the \"{$option}\" database option.");
31 public function testConnection(): bool
33 $output = (new ProgramRunner('mysql', '/usr/bin/mysql'))
34 ->withEnvironment(['MYSQL_PWD' => $this->password])
37 ->runCapturingStdErr([
49 public function importSqlFile(string $sqlFilePath): void
51 $output = (new ProgramRunner('mysql', '/usr/bin/mysql'))
52 ->withEnvironment(['MYSQL_PWD' => $this->password])
55 ->runCapturingStdErr([
61 '-e', "source {$sqlFilePath}"
65 throw new Exception("Failed mysql file import with errors:\n" . $output);
69 public function dropTablesSql(): string
72 SET FOREIGN_KEY_CHECKS = 0;
73 SET GROUP_CONCAT_MAX_LEN=32768;
75 SELECT GROUP_CONCAT('`', table_name, '`') INTO @tables
76 FROM information_schema.tables
77 WHERE table_schema = (SELECT DATABASE());
78 SELECT IFNULL(@tables,'dummy') INTO @tables;
80 SET @tables = CONCAT('DROP TABLE IF EXISTS ', @tables);
81 PREPARE stmt FROM @tables;
83 DEALLOCATE PREPARE stmt;
84 SET FOREIGN_KEY_CHECKS = 1;
88 public function runDumpToFile(string $filePath): string
90 $file = fopen($filePath, 'w');
96 (new ProgramRunner('mysqldump', '/usr/bin/mysqldump'))
99 ->withEnvironment(['MYSQL_PWD' => $this->password])
100 ->runWithoutOutputCallbacks([
105 '--single-transaction',
108 ], function ($data) use (&$file, &$hasOutput) {
109 fwrite($file, $data);
111 }, function ($error) use (&$errors, &$warnings) {
112 $lines = explode("\n", $error);
113 foreach ($lines as $line) {
114 if (str_starts_with(strtolower($line), 'warning: ')) {
117 $errors .= $line . "\n";
121 } catch (\Exception $exception) {
123 if ($exception instanceof ProcessTimedOutException) {
125 throw new Exception("mysqldump operation timed-out.\nNo data has been received so the connection to your database may have failed.");
127 throw new Exception("mysqldump operation timed-out after data was received.");
130 throw new Exception($exception->getMessage());
136 throw new Exception("Failed mysqldump with errors:\n" . $errors);
142 public static function fromEnvOptions(array $env): static
144 $host = ($env['DB_HOST'] ?? '');
145 $username = ($env['DB_USERNAME'] ?? '');
146 $password = ($env['DB_PASSWORD'] ?? '');
147 $database = ($env['DB_DATABASE'] ?? '');
148 $port = intval($env['DB_PORT'] ?? 3306);
150 return new static($host, $username, $password, $database, $port);