setName(self::NAME) ->setHidden() ->setDescription( 'Creates the database needed for shlink to work. It will do nothing if the database already exists', ); } protected function lockedExecute(InputInterface $input, OutputInterface $output): int { $io = new SymfonyStyle($input, $output); $this->checkDbExists(); if ($this->schemaExists()) { $io->success('Database already exists. Run "db:migrate" command to make sure it is up to date.'); return ExitCodes::EXIT_SUCCESS; } // Create database $io->writeln('Creating database tables...'); $this->runPhpCommand($output, [self::DOCTRINE_SCRIPT, self::DOCTRINE_CREATE_SCHEMA_COMMAND]); $io->success('Database properly created!'); return ExitCodes::EXIT_SUCCESS; } private function checkDbExists(): void { if ($this->regularConn->getDatabasePlatform() instanceof SqlitePlatform) { return; } // In order to create the new database, we have to use a connection where the dbname was not set. // Otherwise, it will fail to connect and will not be able to create the new database $schemaManager = $this->noDbNameConn->createSchemaManager(); $databases = $schemaManager->listDatabases(); $shlinkDatabase = $this->regularConn->getDatabase(); if ($shlinkDatabase !== null && ! contains($databases, $shlinkDatabase)) { $schemaManager->createDatabase($shlinkDatabase); } } private function schemaExists(): bool { // If at least one of the shlink tables exist, we will consider the database exists somehow. // We exclude the migrations table, in case db:migrate was run first by mistake. // Any other inconsistency will be taken care by the migrations. $schemaManager = $this->regularConn->createSchemaManager(); return ! empty(filter($schemaManager->listTableNames(), fn (string $table) => $table !== MIGRATIONS_TABLE)); } }