Skip to content

Commit

Permalink
Add more type hints
Browse files Browse the repository at this point in the history
  • Loading branch information
ilijastuden committed Dec 21, 2019
1 parent 76863e4 commit ae3c1a7
Show file tree
Hide file tree
Showing 13 changed files with 115 additions and 232 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ class AddUserRolesTable extends Migration
public function up()
{
if (!in_array('user_roles', $this->connection->getTableNames()) {
$this->log->debug('{table} not found in the database', ['table' => 'user_roles']);
$this->logger->debug('{table} not found in the database', ['table' => 'user_roles']);
$thos->connection->execute('CREATE TABLE STATEMENT');
$this->log->debug('{table} created', ['table' => 'user_roles']);
$this->logger->debug('{table} created', ['table' => 'user_roles']);
}
}
}
Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"psr/log": "^1.0"
},
"require-dev": {
"ext-mysqli": "*",
"friendsofphp/php-cs-fixer": "^2.0",
"monolog/monolog": "^1.0",
"phpunit/phpunit": "^5.0",
Expand Down
47 changes: 9 additions & 38 deletions src/Migration/Migration.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,72 +6,43 @@
* (c) A51 doo <info@activecollab.com>. All rights reserved.
*/

declare(strict_types=1);

namespace ActiveCollab\DatabaseMigrations\Migration;

use ActiveCollab\DatabaseConnection\ConnectionInterface;
use Psr\Log\LoggerInterface;

/**
* @package ActiveCollab\DatabaseMigrations\Migration
*/
abstract class Migration implements MigrationInterface
{
/**
* @var ConnectionInterface
*/
protected $connection;
protected $logger;

/**
* @var LoggerInterface
*/
protected $log;

/**
* @param ConnectionInterface $connection
* @param LoggerInterface|null $log
*/
public function __construct(ConnectionInterface &$connection, LoggerInterface &$log)
public function __construct(ConnectionInterface $connection, LoggerInterface $logger)
{
$this->connection = $connection;
$this->log = $log;
$this->logger = $logger;

$this->configure();
}

/**
* Configure migration, after it has been constructed.
*/
protected function configure()
protected function configure(): void
{
}

/**
* {@inheritdoc}
*/
public function canExecute(&$reason = null)
public function canExecute(string &$reason = null): bool
{
return true;
}

/**
* @var string[]
*/
private $execute_after = [];

/**
* {@inheritdoc}
*/
public function getExecuteAfter()
public function getExecuteAfter(): array
{
return $this->execute_after;
}

/**
* Make sure that this migration is executed after given list of migrations.
*
* @param array ...$migration_paths
*/
protected function executeAfter(...$migration_paths)
protected function executeAfter(string ...$migration_paths): void
{
$this->execute_after = array_merge($this->execute_after, $migration_paths);
}
Expand Down
27 changes: 5 additions & 22 deletions src/Migration/MigrationInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,13 @@
* (c) A51 doo <info@activecollab.com>. All rights reserved.
*/

declare(strict_types=1);

namespace ActiveCollab\DatabaseMigrations\Migration;

/**
* @package ActiveCollab\DatabaseMigrations\Migration
*/
interface MigrationInterface
{
/**
* Return true if all pre-conditions are met for this migration to run.
*
* @param string|null $reason
* @return bool
*/
public function canExecute(&$reason = null);

/**
* Return array of migrations that need to be executed before this migration can be executed.
*
* @return array
*/
public function getExecuteAfter();

/**
* Migrate up.
*/
public function up();
public function canExecute(string &$reason = null): bool;
public function getExecuteAfter(): array;
public function up(): void;
}
154 changes: 66 additions & 88 deletions src/Migrations.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
* (c) A51 doo <info@activecollab.com>. All rights reserved.
*/

declare(strict_types=1);

namespace ActiveCollab\DatabaseMigrations;

use ActiveCollab\DatabaseConnection\ConnectionInterface;
Expand All @@ -18,68 +20,43 @@
use ReflectionClass;
use RuntimeException;

/**
* @package ActiveCollab\DatabaseMigrations
*/
class Migrations implements MigrationsInterface
{
/**
* @var ConnectionInterface
*/
private $connection;

/**
* @var FinderInterface
*/
private $finder;

/**
* @var LoggerInterface
*/
private $log;

/**
* @var string
*/
private $table_name;

/**
* @param ConnectionInterface $connection
* @param FinderInterface $finder
* @param LoggerInterface $log
* @param string $table_name
*/
public function __construct(ConnectionInterface &$connection, FinderInterface &$finder, LoggerInterface &$log, $table_name = 'executed_database_migrations')
private $logger;
private $xecuted_migrations_table_name;

public function __construct(
ConnectionInterface $connection,
FinderInterface $finder,
LoggerInterface $logger,
string $executed_migrations_table_name = 'executed_database_migrations'
)
{
if (empty($table_name)) {
if (empty($executed_migrations_table_name)) {
throw new InvalidArgumentException('Table name is required');
}

$this->connection = $connection;
$this->finder = $finder;
$this->log = $log;
$this->table_name = $table_name;
$this->logger = $logger;
$this->xecuted_migrations_table_name = $executed_migrations_table_name;
}

public function getFinder(): FinderInterface
{
return $this->finder;
}

/**
* @var bool
*/
private $migrations_are_found = false;

/**
* @var MigrationInterface[]
*/
private $migrations = [];

/**
* {@inheritdoc}
*/
public function getMigrations()
public function getMigrations(): array
{
if (!$this->migrations_are_found) {
$migration_class_file_path_map = $this->finder->getMigrationClassFilePathMap();
Expand Down Expand Up @@ -129,7 +106,7 @@ private function getMigrationInstances(array $migration_class_file_path_map)
$reflection = new ReflectionClass($migration_class);

if ($reflection->implementsInterface(MigrationInterface::class) && !$reflection->isAbstract()) {
$result[$migration_class] = new $migration_class($this->connection, $this->log);
$result[$migration_class] = new $migration_class($this->connection, $this->logger);
}
} else {
throw new RuntimeException("Migration class '$migration_class' not found");
Expand Down Expand Up @@ -158,22 +135,19 @@ private function getMigrationClassByMigrationPath($migration_file_path, array $m
}
}

/**
* {@inheritdoc}
*/
public function up(callable $output = null)
public function up(callable $output = null): void
{
foreach ($this->getMigrations() as $migration) {
$migration_class = get_class($migration);

if ($this->isExecuted($migration)) {
$this->log->debug('Migration {migration} already executed', ['migration' => $migration_class]);
$this->logger->debug('Migration {migration} already executed', ['migration' => $migration_class]);

if ($output) {
$output("Migration <comment>$migration_class</comment> is already executed");
}
} else {
$this->log->debug('Ready to execute {migration} migration', ['migration' => $migration_class]);
$this->logger->debug('Ready to execute {migration} migration', ['migration' => $migration_class]);

if ($output) {
$output("Ready to execute <comment>$migration_class</comment> migration");
Expand All @@ -183,7 +157,7 @@ public function up(callable $output = null)
$this->execute($migration);
$exec_time = number_format(microtime(true) - $reference_time, 5, '.', '');

$this->log->debug('Migration {migration} executed', ['migration' => $migration_class, 'exec_time' => (float) $exec_time]);
$this->logger->debug('Migration {migration} executed', ['migration' => $migration_class, 'exec_time' => (float) $exec_time]);

if ($output) {
$output("Migration <comment>$migration_class</comment> is executed in <comment>$exec_time seconds</comment>");
Expand All @@ -202,10 +176,10 @@ public function up(callable $output = null)
*
* @return string
*/
public function getTableName()
public function getXecutedmigrationsTableName()
{
if ($this->table_exists === null && !in_array($this->table_name, $this->connection->getTableNames())) {
$this->connection->execute('CREATE TABLE ' . $this->connection->escapeTableName($this->table_name) . ' (
if ($this->table_exists === null && !in_array($this->xecuted_migrations_table_name, $this->connection->getTableNames())) {
$this->connection->execute('CREATE TABLE ' . $this->connection->escapeTableName($this->xecuted_migrations_table_name) . ' (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`migration` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`executed_at` datetime NOT NULL,
Expand All @@ -217,59 +191,63 @@ public function getTableName()
$this->table_exists = true;
}

return $this->table_name;
return $this->xecuted_migrations_table_name;
}

/**
* {@inheritdoc}
*/
public function execute(MigrationInterface $migration)
public function execute(MigrationInterface $migration): void
{
if ($this->isExecuted($migration)) {
throw new LogicException('Migration ' . get_class($migration) . ' is already executed');
}

$this->connection->transact(function () use ($migration) {
$migration->up();

$this->connection->insert($this->getTableName(), [
'migration' => get_class($migration),
'executed_at' => new DateTimeValue(),
]);
});
$this->connection->transact(
function () use ($migration) {
$migration->up();

$this->connection->insert
($this->getXecutedmigrationsTableName(),
[
'migration' => get_class($migration),
'executed_at' => new DateTimeValue(),
]
);
}
);
}

/**
* {@inheritdoc}
*/
public function isExecuted(MigrationInterface $migration)
public function isExecuted(MigrationInterface $migration): bool
{
return (bool) $this->connection->count($this->getTableName(), ['`migration` = ?', get_class($migration)]);
return (bool) $this->connection->count(
$this->getXecutedmigrationsTableName(),
[
'`migration` = ?',
get_class($migration)
]
);
}

/**
* {@inheritdoc}
*/
public function setAllAsExecuted()
public function setAllAsExecuted(): void
{
$this->connection->transact(function () {
$timestamp = new DateTimeValue();

$batch = $this->connection->batchInsert(
$this->getTableName(),
[
'migration',
'executed_at',
],
50,
ConnectionInterface::REPLACE
);
$this->connection->transact(
function () {
$timestamp = new DateTimeValue();

$batch = $this->connection->batchInsert(
$this->getXecutedmigrationsTableName(),
[
'migration',
'executed_at',
],
50,
ConnectionInterface::REPLACE
);

foreach ($this->getMigrations() as $migration) {
$batch->insert(get_class($migration), $timestamp);
}

foreach ($this->getMigrations() as $migration) {
$batch->insert(get_class($migration), $timestamp);
$batch->done();
}

$batch->done();
});
);
}
}
Loading

0 comments on commit ae3c1a7

Please sign in to comment.