diff --git a/app/Console/Commands/System/CreatesDatabase.php b/app/Console/Commands/System/CreatesDatabase.php index 685aaf101d..93fc7f44fc 100644 --- a/app/Console/Commands/System/CreatesDatabase.php +++ b/app/Console/Commands/System/CreatesDatabase.php @@ -25,6 +25,7 @@ declare(strict_types=1); namespace FireflyIII\Console\Commands\System; use FireflyIII\Console\Commands\ShowsFriendlyMessages; +use FireflyIII\Console\Commands\Tools\VerifiesDatabaseConnectionTrait; use Illuminate\Console\Command; use PDO; use PDOException; @@ -32,23 +33,30 @@ use PDOException; class CreatesDatabase extends Command { use ShowsFriendlyMessages; + use VerifiesDatabaseConnectionTrait; protected $description = 'Tries to create the database if it doesn\'t exist yet.'; - protected $signature = 'firefly-iii:create-database'; + protected $signature = 'firefly-iii:create-database'; public function handle(): int { - if ('mysql' !== env('DB_CONNECTION')) { // @phpstan-ignore larastan.noEnvCallsOutsideOfConfig */ - $this->friendlyInfo(sprintf('CreateDB does not apply to "%s", skipped.', env('DB_CONNECTION'))); + $connected = $this->verifyDatabaseConnection(); + if (!$connected) { + $this->friendlyError('Failed to connect to the database. Is it up?'); + + return Command::FAILURE; + } + if ('mysql' !== config('database.default')) { // @phpstan-ignore larastan.noEnvCallsOutsideOfConfig */ + $this->friendlyInfo(sprintf('CreateDB does not apply to "%s", skipped.', config('database.default'))); return 0; } // try to set up a raw connection: - $exists = false; - $dsn = sprintf('mysql:host=%s;port=%d;charset=utf8mb4', env('DB_HOST'), env('DB_PORT')); + $exists = false; + $dsn = sprintf('mysql:host=%s;port=%d;charset=utf8mb4', env('DB_HOST'), env('DB_PORT')); - if ('' !== (string) env('DB_SOCKET')) { + if ('' !== (string)env('DB_SOCKET')) { $dsn = sprintf('mysql:unix_socket=%s;charset=utf8mb4', env('DB_SOCKET')); } $this->friendlyLine(sprintf('DSN is %s', $dsn)); @@ -61,7 +69,7 @@ class CreatesDatabase extends Command // when it fails, display error try { - $pdo = new PDO($dsn, (string) env('DB_USERNAME'), (string) env('DB_PASSWORD'), $options); + $pdo = new PDO($dsn, (string)env('DB_USERNAME'), (string)env('DB_PASSWORD'), $options); } catch (PDOException $e) { $this->friendlyError(sprintf('Error when connecting to DB: %s', $e->getMessage())); @@ -71,7 +79,7 @@ class CreatesDatabase extends Command // only continue when no error. // with PDO, try to list DB's ( /** @var array $stmt */ - $stmt = $pdo->query('SHOW DATABASES;'); + $stmt = $pdo->query('SHOW DATABASES;'); // slightly more complex but less error-prone. foreach ($stmt as $row) { $name = $row['Database'] ?? false; diff --git a/app/Console/Commands/Tools/VerifiesDatabaseConnection.php b/app/Console/Commands/Tools/VerifiesDatabaseConnection.php index ad9d504c4c..7169faaf17 100644 --- a/app/Console/Commands/Tools/VerifiesDatabaseConnection.php +++ b/app/Console/Commands/Tools/VerifiesDatabaseConnection.php @@ -26,21 +26,19 @@ namespace FireflyIII\Console\Commands\Tools; use FireflyIII\Console\Commands\ShowsFriendlyMessages; use Illuminate\Console\Command; -use Illuminate\Database\QueryException; -use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; -use Exception; class VerifiesDatabaseConnection extends Command { use ShowsFriendlyMessages; + use VerifiesDatabaseConnectionTrait; /** * The name and signature of the console command. * * @var string */ - protected $signature = 'firefly-iii:verify-database-connection'; + protected $signature = 'firefly-iii:verify-database-connection'; /** * The console command description. @@ -54,40 +52,12 @@ class VerifiesDatabaseConnection extends Command */ public function handle(): int { - $loops = 30; - $loop = 0; - $queries = ['pgsql' => 'SELECT * FROM pg_catalog.pg_tables;', 'sqlite' => 'SELECT name FROM sqlite_schema;', 'mysql' => 'SHOW TABLES;']; - $default = config('database.default'); - if (!array_key_exists($default, $queries)) { - $this->friendlyWarning(sprintf('Cannot validate database connection for "%s"', $default)); - - return Command::SUCCESS; - } - $query = $queries[$default]; - $connected = false; - Log::debug(sprintf('Connecting to database "%s"...', config('database.default'))); - while (!$connected && $loop < $loops) { - try { - DB::select($query); - $connected = true; - } catch (QueryException $e) { - Log::error(sprintf('Loop #%d: connection failed: %s', $loop, $e->getMessage())); - $this->friendlyWarning(sprintf('Database connection attempt #%d failed. Sleep for 10 seconds...', $loop + 1)); - sleep(10); - } catch (Exception $e) { - Log::error(sprintf('Loop #%d: not connected yet because of a %s: %s', $loop, get_class($e), $e->getMessage())); - $this->friendlyWarning(sprintf('Database connection attempt #%d failed. Sleep for 10 seconds...', $loop + 1)); - sleep(10); - } - ++$loop; - } + $connected = $this->verifyDatabaseConnection(); if ($connected) { - Log::debug(sprintf('Connected to database after %d attempt(s).', $loop)); $this->friendlyPositive('Connected to the database.'); return Command::SUCCESS; } - Log::error('Failed to connect to database.'); $this->friendlyError('Failed to connect to the database. Is it up?'); return Command::FAILURE; diff --git a/app/Console/Commands/Tools/VerifiesDatabaseConnectionTrait.php b/app/Console/Commands/Tools/VerifiesDatabaseConnectionTrait.php new file mode 100644 index 0000000000..f50a9b455f --- /dev/null +++ b/app/Console/Commands/Tools/VerifiesDatabaseConnectionTrait.php @@ -0,0 +1,67 @@ +. + */ + +namespace FireflyIII\Console\Commands\Tools; + +use Exception; +use Illuminate\Database\QueryException; +use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Log; + +trait VerifiesDatabaseConnectionTrait +{ + + protected function verifyDatabaseConnection(): bool + { + $loops = 30; + $loop = 0; + $queries = [ + 'pgsql' => 'SELECT * FROM pg_catalog.pg_tables;', + 'sqlite' => 'SELECT name FROM sqlite_schema;', + 'mysql' => 'SHOW TABLES;', + ]; + $default = config('database.default'); + if (!array_key_exists($default, $queries)) { + $this->friendlyWarning(sprintf('Cannot validate database connection for "%s"', $default)); + return true; + } + $query = $queries[$default]; + $connected = false; + Log::debug(sprintf('Connecting to database "%s"...', config('database.default'))); + while (!$connected && $loop < $loops) { + try { + DB::select($query); + $connected = true; + } catch (QueryException $e) { + Log::error(sprintf('Loop #%d: connection failed: %s', $loop, $e->getMessage())); + $this->friendlyWarning(sprintf('Database connection attempt #%d failed. Sleep for 10 seconds...', $loop + 1)); + sleep(10); + } catch (Exception $e) { + Log::error(sprintf('Loop #%d: not connected yet because of a %s: %s', $loop, get_class($e), $e->getMessage())); + $this->friendlyWarning(sprintf('Database connection attempt #%d failed. Sleep for 10 seconds...', $loop + 1)); + sleep(10); + } + ++$loop; + } + return $connected; + } + +}