diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml
index 33a8d30..2cc2446 100644
--- a/.github/workflows/phpunit.yml
+++ b/.github/workflows/phpunit.yml
@@ -73,6 +73,7 @@ jobs:
# apk add --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/edge/community docker
# docker-compose up -d postgres mysql
- run: composer install
+ - run: ./vendor/bin/psalm
- run: ./vendor/bin/phpunit
- run: ./vendor/bin/phpunit tests/SqliteDatabase*
- run: ./vendor/bin/phpunit tests/MysqlDatabase*
diff --git a/.idea/runConfigurations/Psalm.xml b/.idea/runConfigurations/Psalm.xml
new file mode 100644
index 0000000..6f80a21
--- /dev/null
+++ b/.idea/runConfigurations/Psalm.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/composer.json b/composer.json
index ed150f1..66a73ef 100644
--- a/composer.json
+++ b/composer.json
@@ -4,16 +4,23 @@
"minimum-stability": "dev",
"prefer-stable": true,
"require": {
- "byjg/anydataset-db": "4.9.*",
- "ext-pdo": "*"
+ "ext-pdo": "*",
+ "byjg/anydataset-db": "^5.0"
},
"require-dev": {
- "phpunit/phpunit": "^9.6"
+ "php": ">=8.1 <8.4",
+ "phpunit/phpunit": "^9.6",
+ "vimeo/psalm": "^5.9"
},
"autoload": {
"psr-4": {
"ByJG\\DbMigration\\": "src/"
}
},
+ "autoload-dev": {
+ "psr-4": {
+ "Tests\\": "tests/"
+ }
+ },
"license": "MIT"
}
diff --git a/psalm.xml b/psalm.xml
new file mode 100644
index 0000000..ebabb1a
--- /dev/null
+++ b/psalm.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Database/AbstractDatabase.php b/src/Database/AbstractDatabase.php
index a4cd160..958bf22 100644
--- a/src/Database/AbstractDatabase.php
+++ b/src/Database/AbstractDatabase.php
@@ -6,24 +6,25 @@
use ByJG\AnyDataset\Db\Factory;
use ByJG\DbMigration\Exception\DatabaseNotVersionedException;
use ByJG\DbMigration\Exception\OldVersionSchemaException;
-use ByJG\DbMigration\Migration;
+use ByJG\DbMigration\MigrationStatus;
+use Exception;
use Psr\Http\Message\UriInterface;
abstract class AbstractDatabase implements DatabaseInterface
{
/**
- * @var DbDriverInterface
+ * @var DbDriverInterface|null
*/
- private $dbDriver;
+ private ?DbDriverInterface $dbDriver = null;
/**
* @var UriInterface
*/
- private $uri;
+ private UriInterface $uri;
/**
* @var string
*/
- private $migrationTable;
+ private string $migrationTable;
/**
* Command constructor.
@@ -31,7 +32,7 @@ abstract class AbstractDatabase implements DatabaseInterface
* @param UriInterface $uri
* @param string $migrationTable
*/
- public function __construct(UriInterface $uri, $migrationTable = 'migration_version')
+ public function __construct(UriInterface $uri, string $migrationTable = 'migration_version')
{
$this->uri = $uri;
$this->migrationTable = $migrationTable;
@@ -40,7 +41,7 @@ public function __construct(UriInterface $uri, $migrationTable = 'migration_vers
/**
* @return string
*/
- public function getMigrationTable()
+ public function getMigrationTable(): string
{
return $this->migrationTable;
}
@@ -48,31 +49,31 @@ public function getMigrationTable()
/**
* @return DbDriverInterface
*/
- public function getDbDriver()
+ public function getDbDriver(): DbDriverInterface
{
if (is_null($this->dbDriver)) {
- $this->dbDriver = Factory::getDbRelationalInstance($this->uri->__toString());
+ $this->dbDriver = Factory::getDbInstance($this->uri->__toString());
}
return $this->dbDriver;
}
/**
* @return array
- * @throws \ByJG\DbMigration\Exception\DatabaseNotVersionedException
- * @throws \ByJG\DbMigration\Exception\OldVersionSchemaException
+ * @throws DatabaseNotVersionedException
+ * @throws OldVersionSchemaException
*/
- public function getVersion()
+ public function getVersion(): array
{
$result = [];
try {
$result['version'] = $this->getDbDriver()->getScalar('SELECT version FROM ' . $this->getMigrationTable());
- } catch (\Exception $ex) {
+ } catch (Exception $ex) {
throw new DatabaseNotVersionedException('This database does not have a migration version. Please use "migrate reset" or "migrate install" to create one.');
}
try {
$result['status'] = $this->getDbDriver()->getScalar('SELECT status FROM ' . $this->getMigrationTable());
- } catch (\Exception $ex) {
+ } catch (Exception $ex) {
throw new OldVersionSchemaException('This database does not have a migration version. Please use "migrate install" for update it.');
}
@@ -80,25 +81,25 @@ public function getVersion()
}
/**
- * @param $version
- * @param $status
+ * @param int $version
+ * @param MigrationStatus $status
*/
- public function setVersion($version, $status)
+ public function setVersion(int $version, MigrationStatus $status): void
{
$this->getDbDriver()->execute(
'UPDATE ' . $this->getMigrationTable() . ' SET version = :version, status = :status',
[
'version' => $version,
- 'status' => $status,
+ 'status' => $status->value,
]
);
}
/**
- * @throws \ByJG\DbMigration\Exception\DatabaseNotVersionedException
- * @throws \ByJG\DbMigration\Exception\OldVersionSchemaException
+ * @throws DatabaseNotVersionedException
+ * @throws OldVersionSchemaException
*/
- protected function checkExistsVersion()
+ protected function checkExistsVersion(): void
{
// Get the version to check if exists
$versionInfo = $this->getVersion();
@@ -106,7 +107,7 @@ protected function checkExistsVersion()
$this->getDbDriver()->execute(sprintf(
"insert into %s values(0, '%s')",
$this->getMigrationTable(),
- Migration::VERSION_STATUS_UNKNOWN)
+ MigrationStatus::unknown->value)
);
}
}
@@ -114,20 +115,20 @@ protected function checkExistsVersion()
/**
*
*/
- public function updateVersionTable()
+ public function updateVersionTable(): void
{
$currentVersion = $this->getDbDriver()->getScalar(sprintf('select version from %s', $this->getMigrationTable()));
$this->getDbDriver()->execute(sprintf('drop table %s', $this->getMigrationTable()));
$this->createVersion();
- $this->setVersion($currentVersion, Migration::VERSION_STATUS_UNKNOWN);
+ $this->setVersion($currentVersion, MigrationStatus::unknown);
}
- protected function isTableExists($schema, $table)
+ protected function isTableExists(?string $schema, string $table): bool
{
$count = $this->getDbDriver()->getScalar(
'SELECT count(*) FROM information_schema.tables ' .
- ' WHERE table_schema = [[schema]] ' .
- ' AND table_name = [[table]] ',
+ ' WHERE table_schema = :schema ' .
+ ' AND table_name = :table ',
[
"schema" => $schema,
"table" => $table
@@ -137,12 +138,12 @@ protected function isTableExists($schema, $table)
return (intval($count) !== 0);
}
- public function isDatabaseVersioned()
+ public function isDatabaseVersioned(): bool
{
return $this->isTableExists(ltrim($this->getDbDriver()->getUri()->getPath(), "/"), $this->getMigrationTable());
}
- public function supportsTransaction()
+ public function supportsTransaction(): bool
{
return true;
}
diff --git a/src/Database/DatabaseInterface.php b/src/Database/DatabaseInterface.php
index 1fb1826..9d6b5d7 100644
--- a/src/Database/DatabaseInterface.php
+++ b/src/Database/DatabaseInterface.php
@@ -2,38 +2,42 @@
namespace ByJG\DbMigration\Database;
+use ByJG\AnyDataset\Db\DbDriverInterface;
+use ByJG\DbMigration\Exception\DatabaseNotVersionedException;
+use ByJG\DbMigration\Exception\OldVersionSchemaException;
+use ByJG\DbMigration\MigrationStatus;
use Psr\Http\Message\UriInterface;
interface DatabaseInterface
{
public static function schema();
- public static function prepareEnvironment(UriInterface $dbDriver);
+ public static function prepareEnvironment(UriInterface $uri);
- public function createDatabase();
+ public function createDatabase(): void;
- public function dropDatabase();
+ public function dropDatabase(): void;
/**
* @return array
- * @throws \ByJG\DbMigration\Exception\DatabaseNotVersionedException
- * @throws \ByJG\DbMigration\Exception\OldVersionSchemaException
+ * @throws DatabaseNotVersionedException
+ * @throws OldVersionSchemaException
*/
- public function getVersion();
+ public function getVersion(): array;
- public function updateVersionTable();
+ public function updateVersionTable(): void;
- public function executeSql($sql);
+ public function executeSql(string $sql): void;
- public function setVersion($version, $status);
+ public function setVersion(int $version, MigrationStatus $status): void;
- public function createVersion();
+ public function createVersion(): void;
- public function isDatabaseVersioned();
+ public function isDatabaseVersioned(): bool;
- public function getDbDriver();
+ public function getDbDriver(): DbDriverInterface;
- public function getMigrationTable();
+ public function getMigrationTable(): string;
- public function supportsTransaction();
+ public function supportsTransaction(): bool;
}
diff --git a/src/Database/DblibDatabase.php b/src/Database/DblibDatabase.php
index 940b3a7..58f1dc8 100644
--- a/src/Database/DblibDatabase.php
+++ b/src/Database/DblibDatabase.php
@@ -3,27 +3,29 @@
namespace ByJG\DbMigration\Database;
use ByJG\AnyDataset\Db\Factory;
+use ByJG\DbMigration\Exception\DatabaseNotVersionedException;
+use ByJG\DbMigration\Exception\OldVersionSchemaException;
use ByJG\Util\Uri;
use Psr\Http\Message\UriInterface;
class DblibDatabase extends AbstractDatabase
{
- public static function schema()
+ public static function schema(): array
{
return ['dblib', 'sqlsrv'];
}
- public static function prepareEnvironment(UriInterface $uri)
+ public static function prepareEnvironment(UriInterface $uri): void
{
$database = preg_replace('~^/~', '', $uri->getPath());
$customUri = new Uri($uri->__toString());
- $dbDriver = Factory::getDbRelationalInstance($customUri->withPath('/')->__toString());
+ $dbDriver = Factory::getDbInstance($customUri->withPath('/')->__toString());
$dbDriver->execute("IF NOT EXISTS(select * from sys.databases where name='$database') CREATE DATABASE $database");
}
- public function createDatabase()
+ public function createDatabase(): void
{
$database = preg_replace('~^/~', '', $this->getDbDriver()->getUri()->getPath());
@@ -31,7 +33,7 @@ public function createDatabase()
$this->getDbDriver()->execute("USE $database");
}
- public function dropDatabase()
+ public function dropDatabase(): void
{
$database = preg_replace('~^/~', '', $this->getDbDriver()->getUri()->getPath());
@@ -39,7 +41,7 @@ public function dropDatabase()
$this->getDbDriver()->execute("drop database $database");
}
- protected function createTableIfNotExists($database, $createTable)
+ protected function createTableIfNotExists(string $database, string $createTable): void
{
$this->getDbDriver()->execute("use $database");
@@ -55,10 +57,10 @@ protected function createTableIfNotExists($database, $createTable)
}
/**
- * @throws \ByJG\DbMigration\Exception\DatabaseNotVersionedException
- * @throws \ByJG\DbMigration\Exception\OldVersionSchemaException
+ * @throws DatabaseNotVersionedException
+ * @throws OldVersionSchemaException
*/
- public function createVersion()
+ public function createVersion(): void
{
$database = preg_replace('~^/~', '', $this->getDbDriver()->getUri()->getPath());
$createTable = 'CREATE TABLE ' . $this->getMigrationTable() . ' (version int, status varchar(20), PRIMARY KEY (version))';
@@ -66,7 +68,7 @@ public function createVersion()
$this->checkExistsVersion();
}
- public function executeSql($sql)
+ public function executeSql(string $sql): void
{
$statements = preg_split("/;(\r\n|\r|\n)/", $sql);
@@ -75,7 +77,7 @@ public function executeSql($sql)
}
}
- protected function executeSqlInternal($sql)
+ protected function executeSqlInternal(string $sql): void
{
if (empty(trim($sql))) {
return;
@@ -84,16 +86,16 @@ protected function executeSqlInternal($sql)
}
/**
- * @param $schema
- * @param $table
+ * @param string|null $schema
+ * @param string $table
* @return bool
*/
- protected function isTableExists($schema, $table)
+ protected function isTableExists(?string $schema, string $table): bool
{
$count = $this->getDbDriver()->getScalar(
'SELECT count(*) FROM information_schema.tables ' .
- ' WHERE table_catalog = [[schema]] ' .
- ' AND table_name = [[table]] ',
+ ' WHERE table_catalog = :schema ' .
+ ' AND table_name = :table ',
[
"schema" => $schema,
"table" => $table
diff --git a/src/Database/MySqlDatabase.php b/src/Database/MySqlDatabase.php
index d8238d3..7a33543 100644
--- a/src/Database/MySqlDatabase.php
+++ b/src/Database/MySqlDatabase.php
@@ -3,27 +3,29 @@
namespace ByJG\DbMigration\Database;
use ByJG\AnyDataset\Db\Factory;
+use ByJG\DbMigration\Exception\DatabaseNotVersionedException;
+use ByJG\DbMigration\Exception\OldVersionSchemaException;
use ByJG\Util\Uri;
use Psr\Http\Message\UriInterface;
class MySqlDatabase extends AbstractDatabase
{
- public static function schema()
+ public static function schema(): array
{
return ['mysql', 'mariadb'];
}
- public static function prepareEnvironment(UriInterface $uri)
+ public static function prepareEnvironment(UriInterface $uri): void
{
$database = preg_replace('~^/~', '', $uri->getPath());
$customUri = new Uri($uri->__toString());
- $dbDriver = Factory::getDbRelationalInstance($customUri->withPath('/')->__toString());
+ $dbDriver = Factory::getDbInstance($customUri->withPath('/')->__toString());
$dbDriver->execute("CREATE SCHEMA IF NOT EXISTS `$database` DEFAULT CHARACTER SET utf8 ;");
}
- public function createDatabase()
+ public function createDatabase(): void
{
$database = preg_replace('~^/~', '', $this->getDbDriver()->getUri()->getPath());
@@ -31,7 +33,7 @@ public function createDatabase()
$this->getDbDriver()->execute("USE `$database`");
}
- public function dropDatabase()
+ public function dropDatabase(): void
{
$database = preg_replace('~^/~', '', $this->getDbDriver()->getUri()->getPath());
@@ -39,21 +41,21 @@ public function dropDatabase()
}
/**
- * @throws \ByJG\DbMigration\Exception\DatabaseNotVersionedException
- * @throws \ByJG\DbMigration\Exception\OldVersionSchemaException
+ * @throws DatabaseNotVersionedException
+ * @throws OldVersionSchemaException
*/
- public function createVersion()
+ public function createVersion(): void
{
$this->getDbDriver()->execute('CREATE TABLE IF NOT EXISTS ' . $this->getMigrationTable() . ' (version int, status varchar(20), PRIMARY KEY (version))');
$this->checkExistsVersion();
}
- public function executeSql($sql)
+ public function executeSql(string $sql): void
{
$this->getDbDriver()->execute($sql);
}
- public function supportsTransaction()
+ public function supportsTransaction(): bool
{
// MySQL doesn't support transaction for DDL commands
// https://dev.mysql.com/doc/refman/8.0/en/cannot-roll-back.html
diff --git a/src/Database/PgsqlDatabase.php b/src/Database/PgsqlDatabase.php
index f1eaaea..80e7ff4 100644
--- a/src/Database/PgsqlDatabase.php
+++ b/src/Database/PgsqlDatabase.php
@@ -2,35 +2,38 @@
namespace ByJG\DbMigration\Database;
+use ByJG\AnyDataset\Db\DbDriverInterface;
use ByJG\AnyDataset\Db\Factory;
+use ByJG\DbMigration\Exception\DatabaseNotVersionedException;
+use ByJG\DbMigration\Exception\OldVersionSchemaException;
use ByJG\Util\Uri;
use Psr\Http\Message\UriInterface;
class PgsqlDatabase extends AbstractDatabase
{
- public static function schema()
+ public static function schema(): string
{
return 'pgsql';
}
- public static function prepareEnvironment(UriInterface $uri)
+ public static function prepareEnvironment(UriInterface $uri): void
{
$database = preg_replace('~^/~', '', $uri->getPath());
$dbDriver = static::getDbDriverWithoutDatabase($uri);
static::createDatabaseIfNotExists($dbDriver, $database);
}
- protected static function getDbDriverWithoutDatabase(UriInterface $uri)
+ protected static function getDbDriverWithoutDatabase(UriInterface $uri): DbDriverInterface
{
$customUri = new Uri($uri->__toString());
- return Factory::getDbRelationalInstance($customUri->withPath('/postgres')->__toString());
+ return Factory::getDbInstance($customUri->withPath('/postgres')->__toString());
}
/**
- * @param \ByJG\AnyDataset\Db\DbDriverInterface $dbDriver
+ * @param DbDriverInterface $dbDriver
* @param $database
*/
- protected static function createDatabaseIfNotExists($dbDriver, $database)
+ protected static function createDatabaseIfNotExists(DbDriverInterface $dbDriver, string $database): void
{
$currentDbName = $dbDriver->getScalar(
"SELECT datname FROM pg_catalog.pg_database WHERE lower(datname) = lower(:dbname)",
@@ -42,13 +45,13 @@ protected static function createDatabaseIfNotExists($dbDriver, $database)
}
}
- public function createDatabase()
+ public function createDatabase(): void
{
$database = preg_replace('~^/~', '', $this->getDbDriver()->getUri()->getPath());
static::createDatabaseIfNotExists($this->getDbDriver(), $database);
}
- public function dropDatabase()
+ public function dropDatabase(): void
{
$iterator = $this->getDbDriver()->getIterator(
"select 'drop table if exists \"' || tablename || '\" cascade;' command from pg_tables where schemaname = 'public';"
@@ -59,16 +62,16 @@ public function dropDatabase()
}
/**
- * @throws \ByJG\DbMigration\Exception\DatabaseNotVersionedException
- * @throws \ByJG\DbMigration\Exception\OldVersionSchemaException
+ * @throws DatabaseNotVersionedException
+ * @throws OldVersionSchemaException
*/
- public function createVersion()
+ public function createVersion(): void
{
$this->getDbDriver()->execute('CREATE TABLE IF NOT EXISTS ' . $this->getMigrationTable() . ' (version int, status varchar(20), PRIMARY KEY (version))');
$this->checkExistsVersion();
}
- public function executeSql($sql)
+ public function executeSql(string $sql): void
{
$statements = preg_split("/;(\r\n|\r|\n)/", $sql);
@@ -77,7 +80,7 @@ public function executeSql($sql)
}
}
- protected function executeSqlInternal($sql)
+ protected function executeSqlInternal(string $sql): void
{
if (empty(trim($sql))) {
return;
@@ -85,7 +88,7 @@ protected function executeSqlInternal($sql)
$this->getDbDriver()->execute($sql);
}
- public function isDatabaseVersioned()
+ public function isDatabaseVersioned(): bool
{
return $this->isTableExists('public', $this->getMigrationTable());
}
diff --git a/src/Database/SqliteDatabase.php b/src/Database/SqliteDatabase.php
index c682952..82a0f0f 100644
--- a/src/Database/SqliteDatabase.php
+++ b/src/Database/SqliteDatabase.php
@@ -2,24 +2,28 @@
namespace ByJG\DbMigration\Database;
+use ByJG\DbMigration\Exception\DatabaseNotVersionedException;
+use ByJG\DbMigration\Exception\OldVersionSchemaException;
use Psr\Http\Message\UriInterface;
class SqliteDatabase extends AbstractDatabase
{
- public static function schema()
+ public static function schema(): string
{
return 'sqlite';
}
- public static function prepareEnvironment(UriInterface $uri)
+ public static function prepareEnvironment(UriInterface $uri): void
{
+ // There is no need to prepare the database
}
- public function createDatabase()
+ public function createDatabase(): void
{
+ // There is no need to create a database in SQLite
}
- public function dropDatabase()
+ public function dropDatabase(): void
{
$iterator = $this->getDbDriver()->getIterator("
select
@@ -40,16 +44,16 @@ public function dropDatabase()
}
/**
- * @throws \ByJG\DbMigration\Exception\DatabaseNotVersionedException
- * @throws \ByJG\DbMigration\Exception\OldVersionSchemaException
+ * @throws DatabaseNotVersionedException
+ * @throws OldVersionSchemaException
*/
- public function createVersion()
+ public function createVersion(): void
{
$this->getDbDriver()->execute('CREATE TABLE IF NOT EXISTS ' . $this->getMigrationTable() . ' (version int, status varchar(20), PRIMARY KEY (version))');
$this->checkExistsVersion();
}
- public function executeSql($sql)
+ public function executeSql(string $sql): void
{
$statements = preg_split("/;(\r\n|\r|\n)/", $sql);
@@ -58,7 +62,7 @@ public function executeSql($sql)
}
}
- protected function executeSqlInternal($sql)
+ protected function executeSqlInternal(string $sql): void
{
if (empty(trim($sql))) {
return;
@@ -66,10 +70,10 @@ protected function executeSqlInternal($sql)
$this->getDbDriver()->execute($sql);
}
- protected function isTableExists($schema, $table)
+ protected function isTableExists(?string $schema, string $table): bool
{
$count = $this->getDbDriver()->getScalar(
- "SELECT count(*) FROM sqlite_master WHERE type='table' AND name=[[table]]",
+ "SELECT count(*) FROM sqlite_master WHERE type='table' AND name=:table",
[
"table" => $table
]
@@ -78,7 +82,7 @@ protected function isTableExists($schema, $table)
return (intval($count) !== 0);
}
- public function isDatabaseVersioned()
+ public function isDatabaseVersioned(): bool
{
return $this->isTableExists(null, $this->getMigrationTable());
}
diff --git a/src/Migration.php b/src/Migration.php
index 4a8fb80..379dd60 100644
--- a/src/Migration.php
+++ b/src/Migration.php
@@ -6,51 +6,51 @@
use ByJG\DbMigration\Database\DatabaseInterface;
use ByJG\DbMigration\Exception\DatabaseDoesNotRegistered;
use ByJG\DbMigration\Exception\DatabaseIsIncompleteException;
+use ByJG\DbMigration\Exception\DatabaseNotVersionedException;
use ByJG\DbMigration\Exception\InvalidMigrationFile;
+use ByJG\DbMigration\Exception\OldVersionSchemaException;
+use Closure;
+use Exception;
use InvalidArgumentException;
use Psr\Http\Message\UriInterface;
class Migration
{
- const VERSION_STATUS_UNKNOWN = "unknown";
- const VERSION_STATUS_PARTIAL = "partial";
- const VERSION_STATUS_COMPLETE = "complete";
-
/**
* @var UriInterface
*/
- protected $uri;
+ protected UriInterface $uri;
/**
* @var string
*/
- protected $folder;
+ protected string $folder;
/**
* @var DbDriverInterface
*/
- protected $dbDriver;
+ protected DbDriverInterface $dbDriver;
/**
- * @var DatabaseInterface
+ * @var DatabaseInterface|null
*/
- protected $dbCommand;
+ protected ?DatabaseInterface $dbCommand = null;
/**
- * @var Callable
+ * @var Closure|null
*/
- protected $callableProgress;
+ protected ?Closure $callableProgress = null;
/**
* @var array
*/
- protected static $databases = [];
+ protected static array $databases = [];
/**
* @var string
*/
- private $migrationTable;
+ private string $migrationTable;
- private $transaction = false;
+ private bool $transaction = false;
/**
* Migration constructor.
@@ -61,7 +61,7 @@ class Migration
* @param string $migrationTable
* @throws InvalidMigrationFile
*/
- public function __construct(UriInterface $uri, $folder, $requiredBase = true, $migrationTable = 'migration_version')
+ public function __construct(UriInterface $uri, string $folder, bool $requiredBase = true, string $migrationTable = 'migration_version')
{
$this->uri = $uri;
$this->folder = $folder;
@@ -71,21 +71,22 @@ public function __construct(UriInterface $uri, $folder, $requiredBase = true, $m
$this->migrationTable = $migrationTable;
}
- public function withTransactionEnabled($enabled = true)
+ public function withTransactionEnabled($enabled = true): static
{
$this->transaction = $enabled;
return $this;
}
/**
- * @param $class
+ * @param string $class
*/
- public static function registerDatabase($class)
+ public static function registerDatabase(string $class): void
{
if (!in_array(DatabaseInterface::class, class_implements($class))) {
throw new InvalidArgumentException('Class not implements DatabaseInterface!');
}
+ /** @var DatabaseInterface $class */
$protocolList = $class::schema();
foreach ((array)$protocolList as $item) {
self::$databases[$item] = $class;
@@ -94,18 +95,18 @@ public static function registerDatabase($class)
/**
* @return DbDriverInterface
- * @throws \ByJG\DbMigration\Exception\DatabaseDoesNotRegistered
+ * @throws DatabaseDoesNotRegistered
*/
- public function getDbDriver()
+ public function getDbDriver(): DbDriverInterface
{
return $this->getDbCommand()->getDbDriver();
}
/**
* @return DatabaseInterface
- * @throws \ByJG\DbMigration\Exception\DatabaseDoesNotRegistered
+ * @throws DatabaseDoesNotRegistered
*/
- public function getDbCommand()
+ public function getDbCommand(): DatabaseInterface
{
if (is_null($this->dbCommand)) {
$class = $this->getDatabaseClassName();
@@ -114,16 +115,16 @@ public function getDbCommand()
return $this->dbCommand;
}
- public function getMigrationTable()
+ public function getMigrationTable(): string
{
return $this->migrationTable;
}
/**
* @return mixed
- * @throws \ByJG\DbMigration\Exception\DatabaseDoesNotRegistered
+ * @throws DatabaseDoesNotRegistered
*/
- protected function getDatabaseClassName()
+ protected function getDatabaseClassName(): mixed
{
if (isset(self::$databases[$this->uri->getScheme()])) {
return self::$databases[$this->uri->getScheme()];
@@ -138,7 +139,7 @@ protected function getDatabaseClassName()
*
* @return string
*/
- public function getBaseSql()
+ public function getBaseSql(): string
{
return $this->folder . "/base.sql";
}
@@ -146,18 +147,18 @@ public function getBaseSql()
/**
* Get the full path script based on the version
*
- * @param $version
- * @param $increment
- * @return string
- * @throws \ByJG\DbMigration\Exception\InvalidMigrationFile
+ * @param int $version
+ * @param int $increment
+ * @return string|null
+ * @throws InvalidMigrationFile
*/
- public function getMigrationSql($version, $increment)
+ public function getMigrationSql(int $version, int $increment): ?string
{
- // I could use the GLOB_BRACE but it is not supported on ALPINE distros.
+ // I could use the GLOB_BRACE, but it is not supported on ALPINE distros.
// So, I have to call multiple times to simulate the braces.
if (intval($version) != $version) {
- throw new \InvalidArgumentException("Version '$version' should be a integer number");
+ throw new InvalidArgumentException("Version '$version' should be a integer number");
}
$version = intval($version);
@@ -188,7 +189,7 @@ public function getMigrationSql($version, $increment)
* @param $file
* @return array
*/
- public function getFileContent($file)
+ public function getFileContent($file): array
{
$data = [
"file" => $file,
@@ -214,11 +215,11 @@ public function getFileContent($file)
}
/**
- * Create the database it it does not exists. Does not use this methos in a production environment
+ * Create the database it is not exists. Does not use these methods in a production environment
*
- * @throws \ByJG\DbMigration\Exception\DatabaseDoesNotRegistered
+ * @throws DatabaseDoesNotRegistered
*/
- public function prepareEnvironment()
+ public function prepareEnvironment(): void
{
$class = $this->getDatabaseClassName();
$class::prepareEnvironment($this->uri);
@@ -226,16 +227,16 @@ public function prepareEnvironment()
/**
* Restore the database using the "base.sql" script and run all migration scripts
- * Note: the database must exists. If dont exist run the method prepareEnvironment
+ * Note: the database must exist. If it don't exist run the method prepareEnvironment
*
- * @param int $upVersion
- * @throws \ByJG\DbMigration\Exception\DatabaseDoesNotRegistered
- * @throws \ByJG\DbMigration\Exception\DatabaseIsIncompleteException
- * @throws \ByJG\DbMigration\Exception\DatabaseNotVersionedException
- * @throws \ByJG\DbMigration\Exception\InvalidMigrationFile
- * @throws \ByJG\DbMigration\Exception\OldVersionSchemaException
+ * @param int|null $upVersion
+ * @throws DatabaseDoesNotRegistered
+ * @throws DatabaseIsIncompleteException
+ * @throws DatabaseNotVersionedException
+ * @throws InvalidMigrationFile
+ * @throws OldVersionSchemaException
*/
- public function reset($upVersion = null)
+ public function reset(int $upVersion = null): void
{
$fileInfo = $this->getFileContent($this->getBaseSql());
@@ -250,22 +251,22 @@ public function reset($upVersion = null)
$this->getDbCommand()->executeSql($fileInfo["content"]);
}
- $this->getDbCommand()->setVersion(0, Migration::VERSION_STATUS_COMPLETE);
+ $this->getDbCommand()->setVersion(0, MigrationStatus::complete);
$this->up($upVersion);
}
/**
- * @throws \ByJG\DbMigration\Exception\DatabaseDoesNotRegistered
+ * @throws DatabaseDoesNotRegistered
*/
- public function createVersion()
+ public function createVersion(): void
{
$this->getDbCommand()->createVersion();
}
/**
- * @throws \ByJG\DbMigration\Exception\DatabaseDoesNotRegistered
+ * @throws DatabaseDoesNotRegistered
*/
- public function updateTableVersion()
+ public function updateTableVersion(): void
{
$this->getDbCommand()->updateVersionTable();
}
@@ -274,11 +275,11 @@ public function updateTableVersion()
* Get the current database version
*
* @return string[] The current 'version' and 'status' as an associative array
- * @throws \ByJG\DbMigration\Exception\DatabaseDoesNotRegistered
- * @throws \ByJG\DbMigration\Exception\DatabaseNotVersionedException
- * @throws \ByJG\DbMigration\Exception\OldVersionSchemaException
+ * @throws DatabaseDoesNotRegistered
+ * @throws DatabaseNotVersionedException
+ * @throws OldVersionSchemaException
*/
- public function getCurrentVersion()
+ public function getCurrentVersion(): array
{
return $this->getDbCommand()->getVersion();
}
@@ -289,35 +290,35 @@ public function getCurrentVersion()
* @param $increment
* @return bool
*/
- protected function canContinue($currentVersion, $upVersion, $increment)
+ protected function canContinue(int $currentVersion, ?int $upVersion, int $increment): bool
{
$existsUpVersion = ($upVersion !== null);
$compareVersion =
- intval($currentVersion) < intval($upVersion)
+ $currentVersion < intval($upVersion)
? -1
- : (intval($currentVersion) > intval($upVersion) ? 1 : 0);
+ : ($currentVersion > intval($upVersion) ? 1 : 0);
- return !($existsUpVersion && ($compareVersion === intval($increment)));
+ return !($existsUpVersion && ($compareVersion === $increment));
}
/**
* Method for execute the migration.
*
- * @param int $upVersion
+ * @param int|null $upVersion
* @param int $increment Can accept 1 for UP or -1 for down
* @param bool $force
- * @throws \ByJG\DbMigration\Exception\DatabaseDoesNotRegistered
- * @throws \ByJG\DbMigration\Exception\DatabaseIsIncompleteException
- * @throws \ByJG\DbMigration\Exception\DatabaseNotVersionedException
- * @throws \ByJG\DbMigration\Exception\InvalidMigrationFile
- * @throws \ByJG\DbMigration\Exception\OldVersionSchemaException
+ * @throws DatabaseDoesNotRegistered
+ * @throws DatabaseIsIncompleteException
+ * @throws DatabaseNotVersionedException
+ * @throws InvalidMigrationFile
+ * @throws OldVersionSchemaException
*/
- protected function migrate($upVersion, $increment, $force)
+ protected function migrate(?int $upVersion, int $increment, bool $force): void
{
$versionInfo = $this->getCurrentVersion();
$currentVersion = intval($versionInfo['version']) + $increment;
- if (strpos($versionInfo['status'], Migration::VERSION_STATUS_PARTIAL) !== false && !$force) {
+ if (in_array($versionInfo['status'], [MigrationStatus::partialUp, MigrationStatus::partialDown]) && !$force) {
throw new DatabaseIsIncompleteException('Database was not fully updated. Use --force for migrate.');
}
@@ -339,13 +340,13 @@ protected function migrate($upVersion, $increment, $force)
if ($useTransaction) {
$this->getDbDriver()->beginTransaction();
}
- $this->getDbCommand()->setVersion($currentVersion, Migration::VERSION_STATUS_PARTIAL . ' ' . ($increment>0 ? 'up' : 'down'));
+ $this->getDbCommand()->setVersion($currentVersion, $increment>0 ? MigrationStatus::partialUp : MigrationStatus::partialDown);
$this->getDbCommand()->executeSql($fileInfo["content"]);
- $this->getDbCommand()->setVersion($currentVersion, Migration::VERSION_STATUS_COMPLETE);
+ $this->getDbCommand()->setVersion($currentVersion, MigrationStatus::complete);
if ($useTransaction) {
$this->getDbDriver()->commitTransaction();
}
- } catch (\Exception $e) {
+ } catch (Exception $e) {
if ($useTransaction) {
$this->getDbDriver()->rollbackTransaction();
}
@@ -358,15 +359,15 @@ protected function migrate($upVersion, $increment, $force)
/**
* Run all scripts to up the database version from current up to latest version or the specified version.
*
- * @param int $upVersion
+ * @param int|null $upVersion
* @param bool $force
- * @throws \ByJG\DbMigration\Exception\DatabaseDoesNotRegistered
- * @throws \ByJG\DbMigration\Exception\DatabaseIsIncompleteException
- * @throws \ByJG\DbMigration\Exception\DatabaseNotVersionedException
- * @throws \ByJG\DbMigration\Exception\InvalidMigrationFile
- * @throws \ByJG\DbMigration\Exception\OldVersionSchemaException
+ * @throws DatabaseDoesNotRegistered
+ * @throws DatabaseIsIncompleteException
+ * @throws DatabaseNotVersionedException
+ * @throws InvalidMigrationFile
+ * @throws OldVersionSchemaException
*/
- public function up($upVersion = null, $force = false)
+ public function up(?int $upVersion = null, bool $force = false): void
{
$this->migrate($upVersion, 1, $force);
}
@@ -374,15 +375,15 @@ public function up($upVersion = null, $force = false)
/**
* Run all scripts to up or down the database version from current up to latest version or the specified version.
*
- * @param int $upVersion
+ * @param int|null $upVersion
* @param bool $force
- * @throws \ByJG\DbMigration\Exception\DatabaseDoesNotRegistered
- * @throws \ByJG\DbMigration\Exception\DatabaseIsIncompleteException
- * @throws \ByJG\DbMigration\Exception\DatabaseNotVersionedException
- * @throws \ByJG\DbMigration\Exception\InvalidMigrationFile
- * @throws \ByJG\DbMigration\Exception\OldVersionSchemaException
+ * @throws DatabaseDoesNotRegistered
+ * @throws DatabaseIsIncompleteException
+ * @throws DatabaseNotVersionedException
+ * @throws InvalidMigrationFile
+ * @throws OldVersionSchemaException
*/
- public function update($upVersion = null, $force = false)
+ public function update(?int $upVersion = null, bool $force = false): void
{
$versionInfo = $this->getCurrentVersion();
$version = intval($versionInfo['version']);
@@ -398,13 +399,13 @@ public function update($upVersion = null, $force = false)
*
* @param int $upVersion
* @param bool $force
- * @throws \ByJG\DbMigration\Exception\DatabaseDoesNotRegistered
- * @throws \ByJG\DbMigration\Exception\DatabaseIsIncompleteException
- * @throws \ByJG\DbMigration\Exception\DatabaseNotVersionedException
- * @throws \ByJG\DbMigration\Exception\InvalidMigrationFile
- * @throws \ByJG\DbMigration\Exception\OldVersionSchemaException
+ * @throws DatabaseDoesNotRegistered
+ * @throws DatabaseIsIncompleteException
+ * @throws DatabaseNotVersionedException
+ * @throws InvalidMigrationFile
+ * @throws OldVersionSchemaException
*/
- public function down($upVersion, $force = false)
+ public function down(int $upVersion, bool $force = false): void
{
$this->migrate($upVersion, -1, $force);
}
@@ -412,12 +413,15 @@ public function down($upVersion, $force = false)
/**
* @param callable $callable
*/
- public function addCallbackProgress(callable $callable)
+ public function addCallbackProgress(callable $callable): void
{
$this->callableProgress = $callable;
}
- public function isDatabaseVersioned()
+ /**
+ * @throws DatabaseDoesNotRegistered
+ */
+ public function isDatabaseVersioned(): bool
{
return $this->getDbCommand()->isDatabaseVersioned();
}
diff --git a/src/MigrationStatus.php b/src/MigrationStatus.php
new file mode 100644
index 0000000..1d52a51
--- /dev/null
+++ b/src/MigrationStatus.php
@@ -0,0 +1,11 @@
+assertVersion0();
}
- protected function getExpectedUsersVersion0()
+ protected function getExpectedUsersVersion0(): array
{
return [
["id" => 1, "name" => 'John Doe', 'createdate' => '20160110'],
@@ -125,7 +133,7 @@ protected function getExpectedUsersVersion0()
];
}
- protected function getExpectedUsersVersion1()
+ protected function getExpectedUsersVersion1(): array
{
return [
["id" => 1, "name" => 'John Doe', 'createdate' => '2016-01-10'],
@@ -133,7 +141,7 @@ protected function getExpectedUsersVersion1()
];
}
- protected function getExpectedPostsVersion2()
+ protected function getExpectedPostsVersion2(): array
{
return [
["id" => 1, "userid" => 1, "title" => 'Testing', 'post' => "\\n
This is an example page. It's different from a blog post because it will stay in one place and will show up in your site navigation (in most themes). Most people start with an About page that introduces them to potential site visitors. It might say something like this:
\\n\\n\\n\\nHi there! I'm a bike messenger by day, aspiring actor by night, and this is my website. I live in Los Angeles, have a great dog named Jack, and I like piña coladas. (And gettin' caught in the rain.)
\\n\\n\\n\\n...or something like this:
\\n\\n\\n\\nThe XYZ Doohickey Company was founded in 1971, and has been providing quality doohickeys to the public ever since. Located in Gotham City, XYZ employs over 2,000 people and does all kinds of awesome things for the Gotham community.
\\n\\n\\n\\nAs a new WordPress user, you should go to your dashboard to delete this page and create new pages for your content. Have fun!
\\n"],
@@ -141,15 +149,14 @@ protected function getExpectedPostsVersion2()
}
/**
- * @throws \ByJG\DbMigration\Exception\DatabaseDoesNotRegistered
- * @throws \ByJG\Serializer\Exception\InvalidArgumentException
+ * @throws DatabaseDoesNotRegistered
*/
- protected function assertVersion0()
+ protected function assertVersion0(): void
{
$version = $this->migrate->getDbDriver()->getScalar('select version from '. $this->migrationTable);
$this->assertEquals(0, $version);
$status = $this->migrate->getDbDriver()->getScalar('select status from '. $this->migrationTable);
- $this->assertEquals(Migration::VERSION_STATUS_COMPLETE, $status);
+ $this->assertEquals(MigrationStatus::complete->value, $status);
$iterator = $this->migrate->getDbDriver()->getIterator('select * from users');
@@ -171,21 +178,20 @@ protected function assertVersion0()
try {
$this->migrate->getDbDriver()->getIterator('select * from roles');
- } catch (PDOException $ex) {
+ } catch (\PDOException $ex) {
$this->assertTrue(true);
}
}
/**
- * @throws \ByJG\DbMigration\Exception\DatabaseDoesNotRegistered
- * @throws \ByJG\Serializer\Exception\InvalidArgumentException
+ * @throws DatabaseDoesNotRegistered
*/
- protected function assertVersion1()
+ protected function assertVersion1(): void
{
$version = $this->migrate->getDbDriver()->getScalar('select version from '. $this->migrationTable);
$this->assertEquals(1, $version);
$status = $this->migrate->getDbDriver()->getScalar('select status from '. $this->migrationTable);
- $this->assertEquals(Migration::VERSION_STATUS_COMPLETE, $status);
+ $this->assertEquals(MigrationStatus::complete->value, $status);
$iterator = $this->migrate->getDbDriver()->getIterator('select * from users');
@@ -207,21 +213,21 @@ protected function assertVersion1()
try {
$this->migrate->getDbDriver()->getIterator('select * from roles');
- } catch (PDOException $ex) {
+ } catch (\PDOException $ex) {
$this->assertTrue(true);
}
}
/**
- * @throws \ByJG\DbMigration\Exception\DatabaseDoesNotRegistered
- * @throws \ByJG\Serializer\Exception\InvalidArgumentException
+ * @throws DatabaseDoesNotRegistered
+ * @throws InvalidArgumentException
*/
protected function assertVersion2()
{
$version = $this->migrate->getDbDriver()->getScalar('select version from '. $this->migrationTable);
$this->assertEquals(2, $version);
$status = $this->migrate->getDbDriver()->getScalar('select status from '. $this->migrationTable);
- $this->assertEquals(Migration::VERSION_STATUS_COMPLETE, $status);
+ $this->assertEquals(MigrationStatus::complete->value, $status);
// Users
$iterator = $this->migrate->getDbDriver()->getIterator('select * from users');
@@ -254,8 +260,8 @@ protected function assertVersion2()
}
/**
- * @throws \ByJG\DbMigration\Exception\DatabaseDoesNotRegistered
- * @throws \ByJG\DbMigration\Exception\OldVersionSchemaException
+ * @throws DatabaseDoesNotRegistered
+ * @throws OldVersionSchemaException
*/
public function testGetCurrentVersionIsEmpty()
{
@@ -264,8 +270,7 @@ public function testGetCurrentVersionIsEmpty()
}
/**
- * @throws \ByJG\DbMigration\Exception\DatabaseDoesNotRegistered
- * @throws \ByJG\Serializer\Exception\InvalidArgumentException
+ * @throws DatabaseDoesNotRegistered
*/
public function testCreateVersion()
{
@@ -274,7 +279,7 @@ public function testCreateVersion()
$this->assertEquals([
[
'version' => '0',
- 'status' => Migration::VERSION_STATUS_UNKNOWN
+ 'status' => MigrationStatus::unknown->value
]
], $records);
@@ -284,7 +289,7 @@ public function testCreateVersion()
$this->assertEquals([
[
'version' => '0',
- 'status' => Migration::VERSION_STATUS_UNKNOWN
+ 'status' => MigrationStatus::unknown->value
]
], $records);
}
diff --git a/tests/MigrationTest.php b/tests/MigrationTest.php
index 68269ee..45d2a2c 100644
--- a/tests/MigrationTest.php
+++ b/tests/MigrationTest.php
@@ -1,5 +1,5 @@
scheme == "sqlsrv") {
return parent::getExpectedUsersVersion1();
diff --git a/tests/SqlServerSqlsrvDatabaseCustomTest.php b/tests/SqlServerSqlsrvDatabaseCustomTest.php
index 02beee2..788bfb8 100644
--- a/tests/SqlServerSqlsrvDatabaseCustomTest.php
+++ b/tests/SqlServerSqlsrvDatabaseCustomTest.php
@@ -1,11 +1,11 @@