regularConn = $this->em->getConnection(); parent::__construct($locker, $processRunner, $phpFinder); } protected function configure(): void { $this ->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->getDriver()->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(); // We cannot use getDatabase() to get the database name here, because then the driver will try to connect, and // it does not exist yet. We need to read from the raw params instead. $shlinkDatabase = $this->regularConn->getParams()['dbname'] ?? null; if ($shlinkDatabase !== null && ! contains($databases, $shlinkDatabase)) { $schemaManager->createDatabase($shlinkDatabase); } } private function schemaExists(): bool { $schemaManager = $this->regularConn->createSchemaManager(); $existingTables = $schemaManager->listTableNames(); $allMetadata = $this->em->getMetadataFactory()->getAllMetadata(); $shlinkTables = map($allMetadata, static fn (ClassMetadata $metadata) => $metadata->getTableName()); // If at least one of the shlink tables exist, we will consider the database exists somehow. // Any other inconsistency will be taken care of by the migrations. return some($shlinkTables, static fn (string $shlinkTable) => contains($existingTables, $shlinkTable)); } }