Merge pull request #1179 from bolt/better-non-existant-db-handling

Better non existant db handling
This commit is contained in:
Bob den Otter
2020-03-14 13:06:31 +01:00
committed by GitHub
7 changed files with 53 additions and 23 deletions

View File

@@ -21,6 +21,7 @@ services:
$emailSender: '%app.notifications.email_sender%'
$projectDir: '%kernel.project_dir%'
$publicFolder: '%bolt.public_folder%'
$tablePrefix: '%bolt.table_prefix%'
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
@@ -41,7 +42,6 @@ services:
$debug: '%kernel.debug%'
Bolt\Doctrine\TablePrefix:
arguments: [ "%bolt.table_prefix%" ]
tags:
- { name: doctrine.event_listener, event: loadClassMetadata, lazy: true }
@@ -54,9 +54,6 @@ services:
tags:
- { name: doctrine.event_listener, event: loadClassMetadata }
Bolt\Event\Subscriber\TimedPublishSubscriber:
arguments: [ "%bolt.table_prefix%" ]
Bolt\Extension\RoutesLoader:
tags: [routing.loader]

View File

@@ -141,7 +141,7 @@ class AddUserCommand extends Command
if ($password !== null) {
$this->io->text(' > <info>Password</info>: ' . str_repeat('*', mb_strlen($password)));
} else {
$passwordQuestion = new Question('Password', Str::generatePassword());
$passwordQuestion = new Question('Password (input is hidden)', Str::generatePassword());
$passwordQuestion->setHidden(true);
$passwordQuestion->setValidator([$this->validator, 'validatePassword']);

View File

@@ -58,9 +58,11 @@ HELP
$connection = ! empty($platform['connection_status']) ? sprintf('- <comment>%s</comment>', $platform['connection_status']) : '';
$tableExists = $this->doctrineVersion->tableContentExists() ? '' : sprintf('- <error>Tables not initialised</error>');
$io->listing([
sprintf('Install type: <info>%s</info>', Version::installType()),
sprintf('Database: <info>%s %s</info> %s', $platform['driver_name'], $platform['server_version'], $connection),
sprintf('Database: <info>%s %s</info> %s %s', $platform['driver_name'], $platform['server_version'], $connection, $tableExists),
sprintf('PHP version: <info>%s</info>', PHP_VERSION),
sprintf('Operating System: <info>%s</info> - <comment>%s</comment>', php_uname('s'), php_uname('r')),
]);

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Bolt\Command;
use Doctrine\DBAL\Connection;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputInterface;
@@ -15,6 +16,16 @@ class SetupCommand extends Command
{
protected static $defaultName = 'bolt:setup';
/** @var Connection */
private $connection;
public function __construct(Connection $connection)
{
$this->connection = $connection;
parent::__construct();
}
protected function configure(): void
{
$this
@@ -28,17 +39,21 @@ class SetupCommand extends Command
$exitCode = 0;
$io = new SymfonyStyle($input, $output);
// Because SQLite breaks on `--if-not-exists`, we need to check for that here.
// See: https://github.com/doctrine/DoctrineBundle/issues/542
$options = ['-q' => true];
if ($this->connection->getDatabasePlatform()->getName() !== 'sqlite') {
$options[] = ['--if-not-exists' => true];
}
$command = $this->getApplication()->find('doctrine:database:create');
$commandInput = new ArrayInput(['-q' => true]);
$exitCode += $command->run($commandInput, $output);
$exitCode += $command->run(new ArrayInput($options), $output);
$command = $this->getApplication()->find('doctrine:schema:create');
$commandInput = new ArrayInput([]);
$exitCode += $command->run($commandInput, $output);
$exitCode += $command->run(new ArrayInput([]), $output);
$command = $this->getApplication()->find('bolt:reset-secret');
$commandInput = new ArrayInput([]);
$exitCode += $command->run($commandInput, $output);
$exitCode += $command->run(new ArrayInput([]), $output);
$command = $this->getApplication()->find('bolt:add-user');
$commandInput = new ArrayInput(['--admin' => true]);

View File

@@ -10,11 +10,11 @@ use Doctrine\ORM\Mapping\ClassMetadataInfo;
class TablePrefix
{
private $prefix;
private $tablePrefix;
public function __construct(string $prefix)
public function __construct(string $tablePrefix)
{
$this->prefix = Str::ensureEndsWith($prefix, '_');
$this->tablePrefix = Str::ensureEndsWith($tablePrefix, '_');
}
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs): void
@@ -23,14 +23,14 @@ class TablePrefix
if (! $classMetadata->isInheritanceTypeSingleTable() || $classMetadata->getName() === $classMetadata->rootEntityName) {
$classMetadata->setPrimaryTable([
'name' => $this->prefix . $classMetadata->getTableName(),
'name' => $this->tablePrefix . $classMetadata->getTableName(),
]);
}
foreach ($classMetadata->getAssociationMappings() as $fieldName => $mapping) {
if ($mapping['type'] === ClassMetadataInfo::MANY_TO_MANY && $mapping['isOwningSide']) {
$mappedTableName = $mapping['joinTable']['name'];
$classMetadata->associationMappings[$fieldName]['joinTable']['name'] = $this->prefix . $mappedTableName;
$classMetadata->associationMappings[$fieldName]['joinTable']['name'] = $this->tablePrefix . $mappedTableName;
}
}
}

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Bolt\Doctrine;
use Bolt\Common\Str;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver\PDOConnection;
@@ -12,9 +13,13 @@ class Version
/** @var Connection */
private $connection;
public function __construct(Connection $connection)
/** @var string */
private $tablePrefix;
public function __construct(Connection $connection, string $tablePrefix = 'bolt')
{
$this->connection = $connection;
$this->tablePrefix = Str::ensureEndsWith($tablePrefix, '_');
}
public function getPlatform(): array
@@ -37,4 +42,15 @@ class Version
'server_version' => $wrapped->getAttribute(\PDO::ATTR_SERVER_VERSION),
];
}
public function tableContentExists(): bool
{
try {
$this->connection->executeQuery('SELECT 1 FROM ' . $this->tablePrefix . 'content LIMIT 1; ');
} catch (\Throwable $e) {
return false;
}
return true;
}
}

View File

@@ -19,12 +19,12 @@ class TimedPublishSubscriber implements EventSubscriberInterface
private $entityManager;
/** @var string */
private $prefix;
private $tablePrefix;
public function __construct(string $prefix, EntityManagerInterface $entityManager)
public function __construct(string $tablePrefix, EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
$this->prefix = Str::ensureEndsWith($prefix, '_');
$this->tablePrefix = Str::ensureEndsWith($tablePrefix, '_');
}
/**
@@ -37,8 +37,8 @@ class TimedPublishSubscriber implements EventSubscriberInterface
// Publish timed Content records when 'publish_at' has passed and Depublish published Content
// records when 'depublish_at' has passed. Note: Placeholders in DBAL don't work for tablenames.
$queryPublish = sprintf('update %scontent SET status = "published", published_at = :now WHERE status = "timed" AND published_at < :now', $this->prefix);
$queryDepublish = sprintf('update %scontent SET status = "held", depublished_at = :now WHERE status = "published" AND depublished_at < :now', $this->prefix);
$queryPublish = sprintf('update %scontent SET status = "published", published_at = :now WHERE status = "timed" AND published_at < :now', $this->tablePrefix);
$queryDepublish = sprintf('update %scontent SET status = "held", depublished_at = :now WHERE status = "published" AND depublished_at < :now', $this->tablePrefix);
try {
$conn->executeUpdate($queryPublish, [':now' => $now]);