From 5eecce7f5b740eee2f6dc48a7066a580836b679b Mon Sep 17 00:00:00 2001 From: Kit Loong Date: Tue, 6 Feb 2024 23:16:45 +0800 Subject: [PATCH 01/20] Add Laravel v11 support - Add DBAL v4 support - Remove DBAL v2 support - Remove version support prior to Laravel v8 - Require minimum PHP 8.0 - Misc bug fix --- .github/workflows/check.yml | 8 +- .github/workflows/tests.yml | 31 +-- .phpmd.xml | 10 +- composer.json | 19 +- phpcs.xml | 5 +- phpstan.neon | 2 +- phpunit8.xml | 21 -- src/DBAL/Connection.php | 91 +++++++++ src/DBAL/DBALSchema.php | 25 +-- src/DBAL/Models/DBALColumn.php | 92 ++++++++- src/DBAL/Models/DBALCustomColumn.php | 40 +++- src/DBAL/Models/DBALView.php | 4 +- src/DBAL/Models/MySQL/MySQLColumn.php | 32 +++ src/DBAL/Models/MySQL/MySQLView.php | 4 +- src/DBAL/Models/PgSQL/PgSQLColumn.php | 81 ++++++-- src/DBAL/Models/PgSQL/PgSQLView.php | 7 +- src/DBAL/MySQLSchema.php | 1 + src/DBAL/PDO/Concerns/ConnectsToDatabase.php | 27 +++ src/DBAL/PDO/Connection.php | 186 ++++++++++++++++++ src/DBAL/PDO/MySqlDriver.php | 16 ++ src/DBAL/PDO/PostgresDriver.php | 16 ++ src/DBAL/PDO/SQLiteDriver.php | 16 ++ src/DBAL/PDO/SqlServerConnection.php | 152 ++++++++++++++ src/DBAL/PDO/SqlServerDriver.php | 27 +++ src/DBAL/PgSQLSchema.php | 1 + src/DBAL/RegisterColumnType.php | 24 ++- src/DBAL/SQLSrvSchema.php | 1 + src/DBAL/SQLiteSchema.php | 3 +- src/DBAL/Types/DoubleType.php | 4 +- src/DBAL/Types/EnumType.php | 4 +- src/DBAL/Types/GeographyType.php | 29 +++ src/DBAL/Types/GeometryCollectionType.php | 4 +- src/DBAL/Types/GeometryType.php | 4 +- src/DBAL/Types/IpAddressType.php | 4 +- src/DBAL/Types/JsonbType.php | 4 +- src/DBAL/Types/LineStringType.php | 4 +- src/DBAL/Types/MacAddressType.php | 4 +- src/DBAL/Types/MediumIntegerType.php | 4 +- src/DBAL/Types/MultiLineStringType.php | 4 +- src/DBAL/Types/MultiPointType.php | 4 +- src/DBAL/Types/MultiPolygonType.php | 4 +- src/DBAL/Types/PointType.php | 4 +- src/DBAL/Types/PolygonType.php | 4 +- src/DBAL/Types/SetType.php | 4 +- src/DBAL/Types/TimeTzType.php | 4 +- src/DBAL/Types/TimestampType.php | 4 +- src/DBAL/Types/TimestampTzType.php | 4 +- src/DBAL/Types/TinyIntegerType.php | 4 +- src/DBAL/Types/Types.php | 11 ++ src/DBAL/Types/UUIDType.php | 4 +- src/DBAL/Types/YearType.php | 4 +- src/Enum/Migrations/Method/ColumnType.php | 17 +- src/MigrateGenerateCommand.php | 6 +- src/Migration/ForeignKeyMigration.php | 8 +- .../Generator/Columns/DecimalColumn.php | 12 +- .../Generator/Columns/DoubleColumn.php | 7 + .../Generator/Columns/FloatColumn.php | 13 +- .../Generator/Columns/SpatialColumn.php | 73 +++++++ .../Generator/Modifiers/DefaultModifier.php | 1 - src/MigrationsGeneratorServiceProvider.php | 20 +- src/Repositories/MySQLRepository.php | 32 +++ src/Schema/Models/Column.php | 12 +- src/Schema/Schema.php | 2 +- src/Support/CheckLaravelVersion.php | 9 + src/Support/CheckMigrationMethod.php | 8 + testbench.yaml | 2 +- tests/Feature/FeatureTestCase.php | 5 +- tests/Feature/PgSQL/PgSQLTestCase.php | 3 +- tests/Feature/SQLSrv/SQLSrvTestCase.php | 5 +- tests/Feature/SQLite/CommandTest.php | 24 +-- tests/TestMigration.php | 4 +- ...00_expected_create_collations_db_table.php | 5 +- ...0_expected_create_all_columns_db_table.php | 74 +++++-- ...00_expected_create_test_index_db_table.php | 13 +- 74 files changed, 1181 insertions(+), 240 deletions(-) delete mode 100644 phpunit8.xml create mode 100644 src/DBAL/Connection.php create mode 100644 src/DBAL/PDO/Concerns/ConnectsToDatabase.php create mode 100644 src/DBAL/PDO/Connection.php create mode 100644 src/DBAL/PDO/MySqlDriver.php create mode 100644 src/DBAL/PDO/PostgresDriver.php create mode 100644 src/DBAL/PDO/SQLiteDriver.php create mode 100644 src/DBAL/PDO/SqlServerConnection.php create mode 100644 src/DBAL/PDO/SqlServerDriver.php create mode 100644 src/DBAL/Types/GeographyType.php create mode 100644 src/Migration/Generator/Columns/SpatialColumn.php diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 9ee06f6d..efc3db46 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -18,19 +18,21 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: 8.1 + php-version: 8.3 extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, gd, redis, memcached tools: composer:v2 coverage: none - name: Install dependencies - run: composer install --prefer-dist --no-interaction + run: | + composer require "laravel/framework:^11.0" --no-interaction --no-update + composer update --prefer-stable --prefer-dist --no-interaction --no-progress - name: phpcs run: composer run phpcs - name: phpstan - run: composer run phpstan + run: ./vendor/bin/phpstan analyse --memory-limit=2G - name: phpmd run: composer run phpmd diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 52d9fdbf..77d69258 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -82,21 +82,15 @@ jobs: dbal: [ 3.* ] sqlsrv_extension: [ pdo_sqlsrv ] include: - - php: 7.1 - laravel: 5.7.* - dbal: 2.* - - php: 7.2 - laravel: 5.8.* - dbal: 2.* - - php: 7.3 - laravel: 6.* - dbal: 2.* - - php: 7.4 - laravel: 7.* - dbal: 2.* - php: 8.0 laravel: 8.* - dbal: 2.* + dbal: 3.* + - php: 8.2 + laravel: 11.* + dbal: 4.* + - php: 8.3 + laravel: 11.* + dbal: 4.* name: PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }} @@ -128,23 +122,12 @@ jobs: composer require "laravel/framework:${{ matrix.laravel }}" "doctrine/dbal:${{ matrix.dbal }}" --no-interaction --no-update composer update --prefer-stable --prefer-dist --no-interaction --no-progress - - name: Setup PCOV - if: ${{ matrix.laravel == '5.7.*' }} - run: | - composer require pcov/clobber - vendor/bin/pcov clobber - - name: Setup .env run: | mkdir ./database composer run action-env-setup - - name: Execute tests with PHPUnit 8 or below - if: ${{ matrix.laravel == '5.7.*' || matrix.laravel == '5.8.*' }} - run: vendor/bin/phpunit -c ./phpunit8.xml --coverage-clover=coverage.xml - - name: Execute tests - if: ${{ matrix.laravel != '5.7.*' && matrix.laravel != '5.8.*' }} run: vendor/bin/phpunit --coverage-clover=coverage.xml - name: Upload to codecov diff --git a/.phpmd.xml b/.phpmd.xml index a7c4ecde..51b4b282 100644 --- a/.phpmd.xml +++ b/.phpmd.xml @@ -18,12 +18,13 @@ + - + @@ -36,9 +37,14 @@ + + + + + - + diff --git a/composer.json b/composer.json index 60cfee01..2d972eb4 100644 --- a/composer.json +++ b/composer.json @@ -17,21 +17,20 @@ } ], "require": { - "php": ">=7.1.3", - "illuminate/support": "^5.6|^6.0|^7.0|^8.0|^9.0|^10.0", - "doctrine/dbal": "^2.4|^3.0", - "myclabs/php-enum": "^1.6|^1.7|^1.8", + "php": "^8.0", + "illuminate/support": "^8.0|^9.0|^10.0|^11.0", + "doctrine/dbal": "^3.0|^4.0", + "myclabs/php-enum": "^1.8", "ext-pdo": "*" }, "require-dev": { - "orchestra/testbench": "^3.6|^4.0|^5.0|^6.0|^7.0|^8.0", + "orchestra/testbench": "^6.0|^7.0|^8.0|^9.0", "squizlabs/php_codesniffer": "^3.5", "mockery/mockery": "^1.0", - "friendsofphp/php-cs-fixer": "^2.19.0|^3.1", - "larastan/larastan": "^0.4|^0.5|^0.6|^0.7|^1.0|^2.0", - "phpmd/phpmd": "^2.10", - "barryvdh/laravel-ide-helper": "^2.5", - "slevomat/coding-standard": "^6.0|^7.0|^8.5" + "friendsofphp/php-cs-fixer": "^3.1", + "larastan/larastan": "^1.0|^2.0", + "slevomat/coding-standard": "^8.0", + "phpmd/phpmd": "^2.10" }, "autoload": { "psr-4": { diff --git a/phpcs.xml b/phpcs.xml index 69b85ae5..06ab786c 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -6,6 +6,7 @@ tests tests/resources/database/migrations/*.php + src/DBAL/PDO/* @@ -183,8 +184,8 @@ - - + + diff --git a/phpstan.neon b/phpstan.neon index 1134e54c..b8377ceb 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -16,10 +16,10 @@ parameters: - '#Constant (.*)\\Enum\\(.*) is unused#' - '#Method KitLoong\\MigrationsGenerator\\DBAL\\(.*)Schema::getViews\(\) should return Illuminate\\Support\\Collection but returns Illuminate\\Support\\Collection<(int|\(int\|string\)), KitLoong\\MigrationsGenerator\\DBAL\\Models\\(.*)\\(.*)View>.#' - '#Method KitLoong\\MigrationsGenerator\\DBAL\\(.*)Schema::getProcedures\(\) should return Illuminate\\Support\\Collection but returns Illuminate\\Support\\Collection<(int|\(int\|string\)), KitLoong\\MigrationsGenerator\\DBAL\\Models\\(.*)\\(.*)Procedure>.#' - - '#Method KitLoong\\MigrationsGenerator\\DBAL\\(.*)Schema::getTableForeignKeys\(\) should return Illuminate\\Support\\Collection but returns Illuminate\\Support\\Collection<(int|\(int\|string\)), KitLoong\\MigrationsGenerator\\DBAL\\Models\\(.*)\\(.*)ForeignKey>.#' - '#(.*)expects Illuminate\\Support\\Collection, Illuminate\\Support\\Collection given.#' excludePaths: - ./*/*/FileToBeExcluded.php + - ./src/DBAL/PDO/* checkMissingIterableValueType: true diff --git a/phpunit8.xml b/phpunit8.xml deleted file mode 100644 index 0bfa86f6..00000000 --- a/phpunit8.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - tests - - - - - src - - src/KitLoong/MigrationsGenerator/Types - - - - diff --git a/src/DBAL/Connection.php b/src/DBAL/Connection.php new file mode 100644 index 00000000..ea9b134e --- /dev/null +++ b/src/DBAL/Connection.php @@ -0,0 +1,91 @@ +doctrineConnection === null) { + $driver = $this->getDoctrineDriver(); + + $this->doctrineConnection = new DoctrineConnection(array_filter([ + 'pdo' => DB::connection()->getPdo(), + 'dbname' => DB::connection()->getDatabaseName(), + 'driver' => $driver->getName(), + 'serverVersion' => DB::connection()->getConfig('server_version'), + ]), $driver); + } + + return $this->doctrineConnection; + } + + /** + * Get the Doctrine DBAL schema manager for the connection. + * + * @return \Doctrine\DBAL\Schema\AbstractSchemaManager + * @throws \Doctrine\DBAL\Exception + */ + public function getDoctrineSchemaManager(): AbstractSchemaManager + { + if (method_exists($this->getDoctrineConnection(), 'createSchemaManager')) { + return $this->getDoctrineConnection()->createSchemaManager(); + } + + // @codeCoverageIgnoreStart + // @phpstan-ignore-next-line + return $this->getDoctrineConnection()->getSchemaManager(); + // @codeCoverageIgnoreEnd + } + + /** + * Get the Doctrine DBAL driver. + * + * @return \KitLoong\MigrationsGenerator\DBAL\PDO\MySqlDriver|\KitLoong\MigrationsGenerator\DBAL\PDO\PostgresDriver|\KitLoong\MigrationsGenerator\DBAL\PDO\SQLiteDriver|\KitLoong\MigrationsGenerator\DBAL\PDO\SqlServerDriver + */ + protected function getDoctrineDriver() + { + switch (true) { + case DB::connection() instanceof MySqlConnection: + return new MySqlDriver(); + + case DB::connection() instanceof SqlServerConnection: + return new SqlServerDriver(); + + case DB::connection() instanceof PostgresConnection: + return new PostgresDriver(); + + default: + return new SQLiteDriver(); + } + } +} diff --git a/src/DBAL/DBALSchema.php b/src/DBAL/DBALSchema.php index 6d71baa5..6e62bf9c 100644 --- a/src/DBAL/DBALSchema.php +++ b/src/DBAL/DBALSchema.php @@ -2,10 +2,8 @@ namespace KitLoong\MigrationsGenerator\DBAL; -use Doctrine\DBAL\Schema\AbstractSchemaManager; use Doctrine\DBAL\Schema\Table; use Illuminate\Support\Collection; -use Illuminate\Support\Facades\DB; use KitLoong\MigrationsGenerator\Schema\Schema; use KitLoong\MigrationsGenerator\Support\AssetNameQuote; @@ -26,7 +24,8 @@ abstract class DBALSchema implements Schema */ public function __construct(RegisterColumnType $registerColumnType) { - $this->dbalSchema = $this->makeSchemaManager(); + // @phpstan-ignore-next-line + $this->dbalSchema = app(Connection::class)->getDoctrineSchemaManager(); $registerColumnType->handle(); } @@ -61,25 +60,7 @@ protected function introspectTable(string $name): Table return $this->dbalSchema->introspectTable($name); } + // @phpstan-ignore-next-line return $this->dbalSchema->listTableDetails($name); } - - /** - * Make a schema manager. - * - * @return \Doctrine\DBAL\Schema\AbstractSchemaManager - * @throws \Doctrine\DBAL\Exception - */ - private function makeSchemaManager(): AbstractSchemaManager - { - $doctrineConnection = DB::getDoctrineConnection(); - - if (method_exists($doctrineConnection, 'createSchemaManager')) { - return $doctrineConnection->createSchemaManager(); - } - - // @codeCoverageIgnoreStart - return $doctrineConnection->getSchemaManager(); - // @codeCoverageIgnoreEnd - } } diff --git a/src/DBAL/Models/DBALColumn.php b/src/DBAL/Models/DBALColumn.php index 0485c501..b3fad579 100644 --- a/src/DBAL/Models/DBALColumn.php +++ b/src/DBAL/Models/DBALColumn.php @@ -3,12 +3,24 @@ namespace KitLoong\MigrationsGenerator\DBAL\Models; use Doctrine\DBAL\Schema\Column as DoctrineDBALColumn; +use Doctrine\DBAL\Types\Type; +use KitLoong\MigrationsGenerator\DBAL\Types\GeometryCollectionType; +use KitLoong\MigrationsGenerator\DBAL\Types\LineStringType; +use KitLoong\MigrationsGenerator\DBAL\Types\MultiLineStringType; +use KitLoong\MigrationsGenerator\DBAL\Types\MultiPointType; +use KitLoong\MigrationsGenerator\DBAL\Types\MultiPolygonType; +use KitLoong\MigrationsGenerator\DBAL\Types\PointType; +use KitLoong\MigrationsGenerator\DBAL\Types\PolygonType; +use KitLoong\MigrationsGenerator\DBAL\Types\Types; use KitLoong\MigrationsGenerator\Enum\Migrations\ColumnName; use KitLoong\MigrationsGenerator\Enum\Migrations\Method\ColumnType; use KitLoong\MigrationsGenerator\Schema\Models\Column; +use KitLoong\MigrationsGenerator\Support\CheckLaravelVersion; abstract class DBALColumn implements Column { + use CheckLaravelVersion; + /** * @var bool */ @@ -60,7 +72,7 @@ abstract class DBALColumn implements Column protected $onUpdateCurrentTimestamp; /** - * @var int + * @var int|null */ protected $precision; @@ -104,14 +116,24 @@ abstract class DBALColumn implements Column */ protected $storedDefinition; + /** + * @var string|null + */ + protected $spatialSubType; + + /** + * @var int|null + */ + protected $spatialSrID; + private const REMEMBER_TOKEN_LENGTH = 100; public function __construct(string $table, DoctrineDBALColumn $column) { $this->tableName = $table; $this->name = $column->getName(); - $this->type = ColumnType::fromDBALType($column->getType()); $this->length = $column->getLength(); + $this->type = Types::toColumnType($column->getType()); $this->scale = $column->getScale(); $this->precision = $column->getPrecision(); $this->comment = $this->escapeComment($column->getComment()); @@ -127,10 +149,13 @@ public function __construct(string $table, DoctrineDBALColumn $column) $this->rawDefault = false; $this->virtualDefinition = null; $this->storedDefinition = null; + $this->spatialSubType = null; + $this->spatialSrID = null; $this->setTypeToSoftDeletes(); $this->setTypeToRememberToken(); $this->setTypeToChar(); + $this->setSpatialSubType($column->getType()); $this->fixDoubleLength(); $this->handle(); @@ -184,7 +209,7 @@ public function getScale(): int /** * @inheritDoc */ - public function getPrecision(): int + public function getPrecision(): ?int { return $this->precision; } @@ -261,6 +286,22 @@ public function getPresetValues(): array return $this->presetValues; } + /** + * @inheritDoc + */ + public function getSpatialSubType(): ?string + { + return $this->spatialSubType; + } + + /** + * @inheritDoc + */ + public function getSpatialSrID(): ?int + { + return $this->spatialSrID; + } + /** * @inheritDoc */ @@ -341,7 +382,6 @@ protected function setTypeToUnsigned(): void ColumnType::MEDIUM_INTEGER(), ColumnType::SMALL_INTEGER(), ColumnType::TINY_INTEGER(), - ColumnType::DECIMAL(), ]) || !$this->unsigned ) { @@ -399,6 +439,48 @@ private function setTypeToChar(): void $this->type = ColumnType::CHAR(); } + /** + * Set the column spatial subtype. + */ + private function setSpatialSubType(Type $dbalColumnType): void + { + if (!$this->atLeastLaravel11()) { + return; + } + + switch (true) { + case $dbalColumnType instanceof GeometryCollectionType: + $this->spatialSubType = 'geometryCollection'; + break; + + case $dbalColumnType instanceof LineStringType: + $this->spatialSubType = 'lineString'; + break; + + case $dbalColumnType instanceof MultiLineStringType: + $this->spatialSubType = 'multiLineString'; + break; + + case $dbalColumnType instanceof PointType: + $this->spatialSubType = 'point'; + break; + + case $dbalColumnType instanceof MultiPointType: + $this->spatialSubType = 'multiPoint'; + break; + + case $dbalColumnType instanceof PolygonType: + $this->spatialSubType = 'polygon'; + break; + + case $dbalColumnType instanceof MultiPolygonType: + $this->spatialSubType = 'multiPolygon'; + break; + + default: + } + } + /** * When double is created without total and places, $table->double('double'); * Doctrine DBAL return precisions 10 and scale 0. @@ -436,7 +518,7 @@ protected function escapeDefault(?string $default): ?string */ protected function escapeComment(?string $comment): ?string { - if ($comment === null) { + if ($comment === null || $comment === '') { return null; } diff --git a/src/DBAL/Models/DBALCustomColumn.php b/src/DBAL/Models/DBALCustomColumn.php index 3f9d5204..3ba320ab 100644 --- a/src/DBAL/Models/DBALCustomColumn.php +++ b/src/DBAL/Models/DBALCustomColumn.php @@ -3,12 +3,16 @@ namespace KitLoong\MigrationsGenerator\DBAL\Models; use Doctrine\DBAL\Schema\Column as DoctrineDBALColumn; +use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\TableDiff; -use Illuminate\Support\Facades\DB; +use KitLoong\MigrationsGenerator\DBAL\Connection; use KitLoong\MigrationsGenerator\Schema\Models\CustomColumn; +use KitLoong\MigrationsGenerator\Support\CheckLaravelVersion; abstract class DBALCustomColumn implements CustomColumn { + use CheckLaravelVersion; + /** * @var string */ @@ -38,7 +42,9 @@ public function __construct(string $table, DoctrineDBALColumn $column) unset($platformOptions['collation']); $column->setPlatformOptions($platformOptions); - $this->sqls = DB::getDoctrineConnection()->getDatabasePlatform()->getAlterTableSQL(new TableDiff($this->tableName, [$column])); + $tableDiff = $this->getTableDiff($column); + + $this->sqls = app(Connection::class)->getDoctrineConnection()->getDatabasePlatform()->getAlterTableSQL($tableDiff); } /** @@ -64,4 +70,34 @@ public function getSqls(): array { return $this->sqls; } + + /** + * Init TableDiff by table name. + * This method compare Laravel version to determine which TableDiff constructor to use. + * To be precise, it uses Laravel version to determine which constructor to use because Laravel 11 uses Doctrine DBAL 4. + * + * @see https://github.com/doctrine/dbal/pull/5683 + */ + private function getTableDiff(DoctrineDBALColumn $column): TableDiff + { + if ($this->atLeastLaravel11()) { + return new TableDiff( + new Table($this->tableName), + [$column], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [] + ); + } + + // @phpstan-ignore-next-line + return new TableDiff($this->tableName, [$column]); + } } diff --git a/src/DBAL/Models/DBALView.php b/src/DBAL/Models/DBALView.php index fecc6efa..ff805af8 100644 --- a/src/DBAL/Models/DBALView.php +++ b/src/DBAL/Models/DBALView.php @@ -3,7 +3,7 @@ namespace KitLoong\MigrationsGenerator\DBAL\Models; use Doctrine\DBAL\Schema\View as DoctrineDBALView; -use Illuminate\Support\Facades\DB; +use KitLoong\MigrationsGenerator\DBAL\Connection; use KitLoong\MigrationsGenerator\Schema\Models\View; use KitLoong\MigrationsGenerator\Support\AssetNameQuote; @@ -34,7 +34,7 @@ abstract class DBALView implements View public function __construct(DoctrineDBALView $view) { $this->name = $this->trimQuotes($view->getName()); - $this->quotedName = DB::getDoctrineConnection()->quoteIdentifier($this->name); + $this->quotedName = app(Connection::class)->getDoctrineConnection()->quoteIdentifier($this->name); $this->definition = ''; $this->dropDefinition = "DROP VIEW IF EXISTS $this->quotedName"; diff --git a/src/DBAL/Models/MySQL/MySQLColumn.php b/src/DBAL/Models/MySQL/MySQLColumn.php index 4ea7f1b3..4c68a838 100644 --- a/src/DBAL/Models/MySQL/MySQLColumn.php +++ b/src/DBAL/Models/MySQL/MySQLColumn.php @@ -62,6 +62,18 @@ protected function handle(): void $this->onUpdateCurrentTimestamp = $this->hasOnUpdateCurrentTimestamp(); break; + case ColumnType::GEOGRAPHY(): + case ColumnType::GEOMETRY(): + case ColumnType::GEOMETRY_COLLECTION(): + case ColumnType::LINE_STRING(): + case ColumnType::MULTI_LINE_STRING(): + case ColumnType::POINT(): + case ColumnType::MULTI_POINT(): + case ColumnType::POLYGON(): + case ColumnType::MULTI_POLYGON(): + $this->setRealSpatialColumn(); + break; + default: } @@ -224,6 +236,26 @@ private function setStoredDefinition(): void $this->storedDefinition = str_replace("\'", "'", $storedDefinition); } + /** + * Set to geometry or geography. + */ + private function setRealSpatialColumn(): void + { + if (!$this->atLeastLaravel11()) { + return; + } + + $this->type = ColumnType::GEOMETRY(); + + $this->spatialSrID = $this->mysqlRepository->getSrID($this->tableName, $this->name); + + if ($this->spatialSrID === null) { + return; + } + + $this->type = ColumnType::GEOGRAPHY(); + } + /** * @inheritDoc */ diff --git a/src/DBAL/Models/MySQL/MySQLView.php b/src/DBAL/Models/MySQL/MySQLView.php index ed1dce08..6a01c6a3 100644 --- a/src/DBAL/Models/MySQL/MySQLView.php +++ b/src/DBAL/Models/MySQL/MySQLView.php @@ -3,7 +3,7 @@ namespace KitLoong\MigrationsGenerator\DBAL\Models\MySQL; use Doctrine\DBAL\Schema\View as DoctrineDBALView; -use Illuminate\Support\Facades\DB; +use KitLoong\MigrationsGenerator\DBAL\Connection; use KitLoong\MigrationsGenerator\DBAL\Models\DBALView; class MySQLView extends DBALView @@ -14,7 +14,7 @@ class MySQLView extends DBALView */ protected function handle(DoctrineDBALView $view): void { - $this->definition = DB::getDoctrineConnection() + $this->definition = app(Connection::class)->getDoctrineConnection() ->getDatabasePlatform() ->getCreateViewSQL($this->quotedName, $view->getSql()); } diff --git a/src/DBAL/Models/PgSQL/PgSQLColumn.php b/src/DBAL/Models/PgSQL/PgSQLColumn.php index af0a7659..2daff3ce 100644 --- a/src/DBAL/Models/PgSQL/PgSQLColumn.php +++ b/src/DBAL/Models/PgSQL/PgSQLColumn.php @@ -2,6 +2,7 @@ namespace KitLoong\MigrationsGenerator\DBAL\Models\PgSQL; +use Illuminate\Support\Str; use KitLoong\MigrationsGenerator\DBAL\Models\DBALColumn; use KitLoong\MigrationsGenerator\Enum\Migrations\Method\ColumnType; use KitLoong\MigrationsGenerator\Repositories\PgSQLRepository; @@ -38,8 +39,9 @@ protected function handle(): void $this->fixFloatLength(); break; + case ColumnType::GEOGRAPHY(): case ColumnType::GEOMETRY(): - $this->type = $this->setGeometryType(); + $this->setRealSpatialColumn(); break; case ColumnType::STRING(): @@ -104,45 +106,62 @@ private function setRawDefault(): void } /** - * Get geography mapping. + * Get geometry mapping. * * @return array */ - private function getGeographyMap(): array + private function getGeometryMap(): array { return [ - 'geography(geometry,4326)' => ColumnType::GEOMETRY(), - 'geography(geometrycollection,4326)' => ColumnType::GEOMETRY_COLLECTION(), - 'geography(linestring,4326)' => ColumnType::LINE_STRING(), - 'geography(multilinestring,4326)' => ColumnType::MULTI_LINE_STRING(), - 'geography(multipoint,4326)' => ColumnType::MULTI_POINT(), - 'geography(multipolygon,4326)' => ColumnType::MULTI_POLYGON(), - 'geography(point,4326)' => ColumnType::POINT(), - 'geography(polygon,4326)' => ColumnType::POLYGON(), + 'geometry' => ColumnType::GEOMETRY(), + 'geometrycollection' => ColumnType::GEOMETRY_COLLECTION(), + 'linestring' => ColumnType::LINE_STRING(), + 'multilinestring' => ColumnType::MULTI_LINE_STRING(), + 'multipoint' => ColumnType::MULTI_POINT(), + 'multipolygon' => ColumnType::MULTI_POLYGON(), + 'point' => ColumnType::POINT(), + 'polygon' => ColumnType::POLYGON(), ]; } /** * Set to geometry type base on geography map. */ - private function setGeometryType(): ColumnType + private function setRealSpatialColumn(): void { $dataType = $this->repository->getTypeByColumnName($this->tableName, $this->name); if ($dataType === null) { - return $this->type; + return; } $dataType = strtolower($dataType); $dataType = preg_replace('/\s+/', '', $dataType); - $map = $this->getGeographyMap(); + if ($dataType === 'geography' || $dataType === 'geometry') { + return; + } + + if (!preg_match('/(\w+)(?:\((\w+)(?:,\s*(\w+))?\))?/', $dataType, $matches)) { + return; + } + + $spatialSubType = $matches[2]; + $spatialSrID = isset($matches[3]) ? (int) $matches[3] : null; + + if (!$this->atLeastLaravel11()) { + $map = $this->getGeometryMap(); + + if (!isset($map[$spatialSubType])) { + return; + } - if (!isset($map[$dataType])) { - return $this->type; + $this->type = $map[$spatialSubType]; + return; } - return $map[$dataType]; + $this->spatialSubType = $spatialSubType; + $this->spatialSrID = $spatialSrID; } /** @@ -200,4 +219,32 @@ private function setStoredDefinition(): void $this->default = null; } + + protected function setTypeToIncrements(bool $supportUnsigned): void + { + // https://www.postgresqltutorial.com/postgresql-tutorial/postgresql-identity-column/ + // https://github.com/doctrine/dbal/pull/5396 + if ( + !in_array($this->type, [ + ColumnType::BIG_INTEGER(), + ColumnType::INTEGER(), + ColumnType::MEDIUM_INTEGER(), + ColumnType::SMALL_INTEGER(), + ColumnType::TINY_INTEGER(), + ]) + ) { + return; + } + + if ( + $this->default !== null && ( + Str::endsWith($this->default, '_seq') || Str::endsWith($this->default, '_seq"') + ) + ) { + $this->default = null; + $this->autoincrement = true; + } + + parent::setTypeToIncrements($supportUnsigned); + } } diff --git a/src/DBAL/Models/PgSQL/PgSQLView.php b/src/DBAL/Models/PgSQL/PgSQLView.php index 0a9b8a9b..78e8b124 100644 --- a/src/DBAL/Models/PgSQL/PgSQLView.php +++ b/src/DBAL/Models/PgSQL/PgSQLView.php @@ -4,6 +4,7 @@ use Doctrine\DBAL\Schema\View as DoctrineDBALView; use Illuminate\Support\Facades\DB; +use KitLoong\MigrationsGenerator\DBAL\Connection; use KitLoong\MigrationsGenerator\DBAL\Models\DBALView; class PgSQLView extends DBALView @@ -17,7 +18,7 @@ protected function handle(DoctrineDBALView $view): void $searchPath = DB::connection()->getConfig('search_path') ?: DB::connection()->getConfig('schema'); if ($view->getNamespaceName() !== $searchPath) { - $this->definition = DB::getDoctrineConnection() + $this->definition = app(Connection::class)->getDoctrineConnection() ->getDatabasePlatform() ->getCreateViewSQL($this->quotedName, $view->getSql()); return; @@ -26,8 +27,8 @@ protected function handle(DoctrineDBALView $view): void // Strip namespace from name. $name = $view->getShortestName($view->getNamespaceName()); $this->name = $this->trimQuotes($name); - $this->quotedName = DB::getDoctrineConnection()->quoteIdentifier($this->name); - $this->definition = DB::getDoctrineConnection() + $this->quotedName = app(Connection::class)->getDoctrineConnection()->quoteIdentifier($this->name); + $this->definition = app(Connection::class)->getDoctrineConnection() ->getDatabasePlatform() ->getCreateViewSQL($this->quotedName, $view->getSql()); $this->dropDefinition = "DROP VIEW IF EXISTS $this->quotedName"; diff --git a/src/DBAL/MySQLSchema.php b/src/DBAL/MySQLSchema.php index 3749a802..67369a11 100644 --- a/src/DBAL/MySQLSchema.php +++ b/src/DBAL/MySQLSchema.php @@ -85,6 +85,7 @@ public function getProcedures(): Collection */ public function getTableForeignKeys(string $table): Collection { + // @phpstan-ignore-next-line return (new Collection($this->dbalSchema->listTableForeignKeys($table))) ->map(function (ForeignKeyConstraint $foreignKeyConstraint) use ($table) { return new MySQLForeignKey($table, $foreignKeyConstraint); diff --git a/src/DBAL/PDO/Concerns/ConnectsToDatabase.php b/src/DBAL/PDO/Concerns/ConnectsToDatabase.php new file mode 100644 index 00000000..fc75596c --- /dev/null +++ b/src/DBAL/PDO/Concerns/ConnectsToDatabase.php @@ -0,0 +1,27 @@ +connection = $connection; + } + + /** + * Execute an SQL statement. + * + * @param string $statement + * @return int + */ + public function exec(string $statement): int + { + try { + $result = $this->connection->exec($statement); + + \assert($result !== false); + + return $result; + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + /** + * Prepare a new SQL statement. + * + * @param string $sql + * @return \Doctrine\DBAL\Driver\Statement + * + * @throws \Doctrine\DBAL\Driver\PDO\Exception + */ + public function prepare(string $sql): StatementInterface + { + try { + return $this->createStatement( + $this->connection->prepare($sql) + ); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + /** + * Execute a new query against the connection. + * + * @param string $sql + * @return \Doctrine\DBAL\Driver\Result + */ + public function query(string $sql): ResultInterface + { + try { + $stmt = $this->connection->query($sql); + + \assert($stmt instanceof PDOStatement); + + return new Result($stmt); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + /** + * Get the last insert ID. + * + * @param string|null $name + * @return string|int + * + * @throws \Doctrine\DBAL\Driver\PDO\Exception + */ + public function lastInsertId($name = null): int|string + { + try { + if ($name === null) { + return $this->connection->lastInsertId(); + } + + return $this->connection->lastInsertId($name); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + /** + * Create a new statement instance. + * + * @param \PDOStatement $stmt + * @return \Doctrine\DBAL\Driver\PDO\Statement + */ + protected function createStatement(PDOStatement $stmt): Statement + { + return new Statement($stmt); + } + + /** + * Begin a new database transaction. + * + * @return void + */ + public function beginTransaction(): void + { + $this->connection->beginTransaction(); + } + + /** + * Commit a database transaction. + * + * @return void + */ + public function commit(): void + { + $this->connection->commit(); + } + + /** + * Rollback a database transaction. + * + * @return void + */ + public function rollBack(): void + { + $this->connection->rollBack(); + } + + /** + * Wrap quotes around the given input. + * + * @param string $input + * @param string $type + * @return string + */ + public function quote($input, $type = ParameterType::STRING): string + { + return $this->connection->quote($input, $type); + } + + /** + * Get the server version for the connection. + * + * @return string + */ + public function getServerVersion(): string + { + return $this->connection->getAttribute(PDO::ATTR_SERVER_VERSION); + } + + /** + * Get the native PDO connection. + * + * @return \PDO + */ + public function getNativeConnection(): PDO + { + return $this->connection; + } +} diff --git a/src/DBAL/PDO/MySqlDriver.php b/src/DBAL/PDO/MySqlDriver.php new file mode 100644 index 00000000..27da286f --- /dev/null +++ b/src/DBAL/PDO/MySqlDriver.php @@ -0,0 +1,16 @@ +connection = $connection; + } + + /** + * Prepare a new SQL statement. + * + * @param string $sql + * @return \Doctrine\DBAL\Driver\Statement + */ + public function prepare(string $sql): StatementInterface + { + return new Statement( + $this->connection->prepare($sql) + ); + } + + /** + * Execute a new query against the connection. + * + * @param string $sql + * @return \Doctrine\DBAL\Driver\Result + */ + public function query(string $sql): Result + { + return $this->connection->query($sql); + } + + /** + * Execute an SQL statement. + * + * @param string $statement + * @return int + */ + public function exec(string $statement): int + { + return $this->connection->exec($statement); + } + + /** + * Get the last insert ID. + * + * @param string|null $name + * @return string|int + */ + public function lastInsertId($name = null): string|int + { + if ($name === null) { + return $this->connection->lastInsertId($name); + } + + return $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?') + ->execute([$name]) + ->fetchOne(); + } + + /** + * Begin a new database transaction. + * + * @return void + */ + public function beginTransaction(): void + { + $this->connection->beginTransaction(); + } + + /** + * Commit a database transaction. + * + * @return void + */ + public function commit(): void + { + $this->connection->commit(); + } + + /** + * Rollback a database transaction. + * + * @return void + */ + public function rollBack(): void + { + $this->connection->rollBack(); + } + + /** + * Wrap quotes around the given input. + * + * @param string $value + * @param int $type + * @return string + */ + public function quote($value, $type = ParameterType::STRING): string + { + $val = $this->connection->quote($value, $type); + + // Fix for a driver version terminating all values with null byte... + if (\is_string($val) && str_contains($val, "\0")) { + $val = \substr($val, 0, -1); + } + + return $val; + } + + /** + * Get the server version for the connection. + * + * @return string + */ + public function getServerVersion(): string + { + return $this->connection->getServerVersion(); + } + + /** + * Get the native PDO connection. + * + * @return \PDO + */ + public function getNativeConnection(): PDO + { + return $this->connection->getWrappedConnection(); + } +} diff --git a/src/DBAL/PDO/SqlServerDriver.php b/src/DBAL/PDO/SqlServerDriver.php new file mode 100644 index 00000000..442dbfa1 --- /dev/null +++ b/src/DBAL/PDO/SqlServerDriver.php @@ -0,0 +1,27 @@ +dbalSchema->listTableForeignKeys($table))) ->map(function (ForeignKeyConstraint $foreignKeyConstraint) use ($table) { return new PgSQLForeignKey($table, $foreignKeyConstraint); diff --git a/src/DBAL/RegisterColumnType.php b/src/DBAL/RegisterColumnType.php index 7b28757a..7a8bfff7 100644 --- a/src/DBAL/RegisterColumnType.php +++ b/src/DBAL/RegisterColumnType.php @@ -48,19 +48,17 @@ public function handle(): void 'tinyint' => ColumnType::TINY_INTEGER, ], Driver::PGSQL()->getValue() => [ - '_int4' => DoctrineDBALTypes::TEXT, - '_int8' => DoctrineDBALTypes::TEXT, - '_numeric' => DoctrineDBALTypes::FLOAT, - '_text' => DoctrineDBALTypes::TEXT, - 'cidr' => DoctrineDBALTypes::STRING, - 'geography' => ColumnType::GEOMETRY, - 'inet' => ColumnType::IP_ADDRESS, - 'macaddr' => ColumnType::MAC_ADDRESS, - 'oid' => DoctrineDBALTypes::STRING, + '_int4' => DoctrineDBALTypes::TEXT, + '_int8' => DoctrineDBALTypes::TEXT, + '_numeric' => DoctrineDBALTypes::FLOAT, + '_text' => DoctrineDBALTypes::TEXT, + 'cidr' => DoctrineDBALTypes::STRING, + 'inet' => ColumnType::IP_ADDRESS, + 'macaddr' => ColumnType::MAC_ADDRESS, + 'oid' => DoctrineDBALTypes::STRING, ], Driver::SQLITE()->getValue() => [], Driver::SQLSRV()->getValue() => [ - 'geography' => ColumnType::GEOMETRY, 'sysname' => DoctrineDBALTypes::STRING, 'hierarchyid' => DoctrineDBALTypes::STRING, 'money' => DoctrineDBALTypes::DECIMAL, @@ -116,7 +114,7 @@ private function registerLaravelCustomColumnType(): void /** * @inheritDoc */ - public function getSQLDeclaration(array $column, AbstractPlatform $platform) + public function getSQLDeclaration(array $column, AbstractPlatform $platform): string { return $this->type; } @@ -124,7 +122,7 @@ public function getSQLDeclaration(array $column, AbstractPlatform $platform) /** * @inheritDoc */ - public function getName() + public function getName(): string { return $this->type; } @@ -182,7 +180,7 @@ private function addOrOverrideType(string $type, string $class): void */ private function registerDoctrineTypeMapping(string $dbType, string $doctrineType): void { - DB::getDoctrineConnection() + app(Connection::class)->getDoctrineConnection() ->getDatabasePlatform() ->registerDoctrineTypeMapping($dbType, $doctrineType); } diff --git a/src/DBAL/SQLSrvSchema.php b/src/DBAL/SQLSrvSchema.php index 0c27c39c..a9df01b4 100644 --- a/src/DBAL/SQLSrvSchema.php +++ b/src/DBAL/SQLSrvSchema.php @@ -88,6 +88,7 @@ public function getProcedures(): Collection */ public function getTableForeignKeys(string $table): Collection { + // @phpstan-ignore-next-line return (new Collection($this->dbalSchema->listTableForeignKeys($table))) ->map(function (ForeignKeyConstraint $foreignKeyConstraint) use ($table) { return new SQLSrvForeignKey($table, $foreignKeyConstraint); diff --git a/src/DBAL/SQLiteSchema.php b/src/DBAL/SQLiteSchema.php index 042dae8b..e9d534d6 100644 --- a/src/DBAL/SQLiteSchema.php +++ b/src/DBAL/SQLiteSchema.php @@ -12,7 +12,7 @@ use KitLoong\MigrationsGenerator\Schema\Models\View; /** - * @extends \KitLoong\MigrationsGenerator\DBAL\DBALSchema<\Doctrine\DBAL\Platforms\SqlitePlatform> + * @extends \KitLoong\MigrationsGenerator\DBAL\DBALSchema<\Doctrine\DBAL\Platforms\SQLitePlatform> */ class SQLiteSchema extends DBALSchema { @@ -68,6 +68,7 @@ public function getProcedures(): Collection */ public function getTableForeignKeys(string $table): Collection { + // @phpstan-ignore-next-line return (new Collection($this->dbalSchema->listTableForeignKeys($table))) ->map(function (ForeignKeyConstraint $foreignKeyConstraint) use ($table) { return new SQLiteForeignKey($table, $foreignKeyConstraint); diff --git a/src/DBAL/Types/DoubleType.php b/src/DBAL/Types/DoubleType.php index ad841b80..3f240458 100644 --- a/src/DBAL/Types/DoubleType.php +++ b/src/DBAL/Types/DoubleType.php @@ -14,7 +14,7 @@ class DoubleType extends Type * @codeCoverageIgnore * @inheritDoc */ - public function getSQLDeclaration(array $column, AbstractPlatform $platform) + public function getSQLDeclaration(array $column, AbstractPlatform $platform): string { return 'DOUBLE'; } @@ -22,7 +22,7 @@ public function getSQLDeclaration(array $column, AbstractPlatform $platform) /** * @inheritDoc */ - public function getName() + public function getName(): string { return ''; } diff --git a/src/DBAL/Types/EnumType.php b/src/DBAL/Types/EnumType.php index 049808f4..d7207a0d 100644 --- a/src/DBAL/Types/EnumType.php +++ b/src/DBAL/Types/EnumType.php @@ -14,7 +14,7 @@ class EnumType extends Type * @codeCoverageIgnore * @inheritDoc */ - public function getSQLDeclaration(array $column, AbstractPlatform $platform) + public function getSQLDeclaration(array $column, AbstractPlatform $platform): string { return 'ENUM'; } @@ -22,7 +22,7 @@ public function getSQLDeclaration(array $column, AbstractPlatform $platform) /** * @inheritDoc */ - public function getName() + public function getName(): string { return ''; } diff --git a/src/DBAL/Types/GeographyType.php b/src/DBAL/Types/GeographyType.php new file mode 100644 index 00000000..394258cf --- /dev/null +++ b/src/DBAL/Types/GeographyType.php @@ -0,0 +1,29 @@ + ColumnType::DOUBLE, EnumType::class => ColumnType::ENUM, + GeographyType::class => ColumnType::GEOGRAPHY, GeometryType::class => ColumnType::GEOMETRY, GeometryCollectionType::class => ColumnType::GEOMETRY_COLLECTION, IpAddressType::class => ColumnType::IP_ADDRESS, @@ -84,4 +86,13 @@ final class Types UUIDType::class => ColumnType::UUID, YearType::class => ColumnType::YEAR, ]; + + /** + * Create instance from {@see \Doctrine\DBAL\Types\Type}. + */ + public static function toColumnType(Type $dbalType): ColumnType + { + $map = self::BUILTIN_TYPES_MAP + self::ADDITIONAL_TYPES_MAP; + return ColumnType::fromValue($map[get_class($dbalType)]); + } } diff --git a/src/DBAL/Types/UUIDType.php b/src/DBAL/Types/UUIDType.php index 4fc87980..35437437 100644 --- a/src/DBAL/Types/UUIDType.php +++ b/src/DBAL/Types/UUIDType.php @@ -14,7 +14,7 @@ class UUIDType extends Type * @codeCoverageIgnore * @inheritDoc */ - public function getSQLDeclaration(array $column, AbstractPlatform $platform) + public function getSQLDeclaration(array $column, AbstractPlatform $platform): string { return 'UUID'; } @@ -22,7 +22,7 @@ public function getSQLDeclaration(array $column, AbstractPlatform $platform) /** * @inheritDoc */ - public function getName() + public function getName(): string { return ''; } diff --git a/src/DBAL/Types/YearType.php b/src/DBAL/Types/YearType.php index 13aaafd7..00d13c91 100644 --- a/src/DBAL/Types/YearType.php +++ b/src/DBAL/Types/YearType.php @@ -14,7 +14,7 @@ class YearType extends Type * @codeCoverageIgnore * @inheritDoc */ - public function getSQLDeclaration(array $column, AbstractPlatform $platform) + public function getSQLDeclaration(array $column, AbstractPlatform $platform): string { return 'YEAR'; } @@ -22,7 +22,7 @@ public function getSQLDeclaration(array $column, AbstractPlatform $platform) /** * @inheritDoc */ - public function getName() + public function getName(): string { return ''; } diff --git a/src/Enum/Migrations/Method/ColumnType.php b/src/Enum/Migrations/Method/ColumnType.php index 1cc5cd00..0a64ca5d 100644 --- a/src/Enum/Migrations/Method/ColumnType.php +++ b/src/Enum/Migrations/Method/ColumnType.php @@ -2,8 +2,6 @@ namespace KitLoong\MigrationsGenerator\Enum\Migrations\Method; -use Doctrine\DBAL\Types\Type; -use KitLoong\MigrationsGenerator\DBAL\Types\Types; use MyCLabs\Enum\Enum; use UnexpectedValueException; @@ -26,6 +24,7 @@ * @method static self DOUBLE() * @method static self ENUM() * @method static self FLOAT() + * @method static self GEOGRAPHY() * @method static self GEOMETRY() * @method static self GEOMETRY_COLLECTION() * @method static self INCREMENTS() @@ -62,7 +61,6 @@ * @method static self TINY_INTEGER() * @method static self TINY_TEXT() * @method static self UNSIGNED_BIG_INTEGER() - * @method static self UNSIGNED_DECIMAL() * @method static self UNSIGNED_INTEGER() * @method static self UNSIGNED_MEDIUM_INTEGER() * @method static self UNSIGNED_SMALL_INTEGER() @@ -85,6 +83,7 @@ final class ColumnType extends Enum public const DOUBLE = 'double'; public const ENUM = 'enum'; public const FLOAT = 'float'; + public const GEOGRAPHY = 'geography'; public const GEOMETRY = 'geometry'; public const GEOMETRY_COLLECTION = 'geometryCollection'; public const INCREMENTS = 'increments'; @@ -121,7 +120,6 @@ final class ColumnType extends Enum public const TINY_INTEGER = 'tinyInteger'; public const TINY_TEXT = 'tinyText'; public const UNSIGNED_BIG_INTEGER = 'unsignedBigInteger'; - public const UNSIGNED_DECIMAL = 'unsignedDecimal'; public const UNSIGNED_INTEGER = 'unsignedInteger'; public const UNSIGNED_MEDIUM_INTEGER = 'unsignedMediumInteger'; public const UNSIGNED_SMALL_INTEGER = 'unsignedSmallInteger'; @@ -129,17 +127,6 @@ final class ColumnType extends Enum public const UUID = 'uuid'; public const YEAR = 'year'; - /** - * Create instance from {@see \Doctrine\DBAL\Types\Type}. - * - * @return static - */ - public static function fromDBALType(Type $dbalType): self - { - $map = Types::BUILTIN_TYPES_MAP + Types::ADDITIONAL_TYPES_MAP; - return self::fromValue($map[get_class($dbalType)]); - } - /** * Initiate an instance from value. * diff --git a/src/MigrateGenerateCommand.php b/src/MigrateGenerateCommand.php index ef2e9154..577cd2e1 100644 --- a/src/MigrateGenerateCommand.php +++ b/src/MigrateGenerateCommand.php @@ -295,8 +295,10 @@ protected function filterAndExcludeAsset(Collection $allAssets): Collection */ protected function getExcludedTables(): array { - $prefix = DB::getTablePrefix(); - $migrationTable = $prefix . Config::get('database.migrations'); + $prefix = DB::getTablePrefix(); + + // https://github.com/laravel/framework/pull/49330 + $migrationTable = $prefix . (Config::get('database.migrations.table') ?? Config::get('database.migrations')); $excludes = [$migrationTable]; $ignore = (string) $this->option('ignore'); diff --git a/src/Migration/ForeignKeyMigration.php b/src/Migration/ForeignKeyMigration.php index 93b92dab..e421f0d9 100644 --- a/src/Migration/ForeignKeyMigration.php +++ b/src/Migration/ForeignKeyMigration.php @@ -60,7 +60,7 @@ public function __construct( /** * Create foreign key migration. * - * @param \Illuminate\Support\Collection $foreignKeys + * @param \Illuminate\Support\Collection $foreignKeys * @return string The migration file path. */ public function write(string $table, Collection $foreignKeys): string @@ -83,7 +83,7 @@ public function write(string $table, Collection $foreignKeys): string /** * Write foreign key migration into temporary file. * - * @param \Illuminate\Support\Collection $foreignKeys + * @param \Illuminate\Support\Collection $foreignKeys */ public function writeToTemp(string $table, Collection $foreignKeys): void { @@ -96,7 +96,7 @@ public function writeToTemp(string $table, Collection $foreignKeys): void /** * Generates `up` schema for foreign key. * - * @param \Illuminate\Support\Collection $foreignKeys + * @param \Illuminate\Support\Collection $foreignKeys */ private function up(string $table, Collection $foreignKeys): SchemaBlueprint { @@ -116,7 +116,7 @@ private function up(string $table, Collection $foreignKeys): SchemaBlueprint /** * Generates `down` schema for foreign key. * - * @param \Illuminate\Support\Collection $foreignKeys + * @param \Illuminate\Support\Collection $foreignKeys */ private function down(string $table, Collection $foreignKeys): SchemaBlueprint { diff --git a/src/Migration/Generator/Columns/DecimalColumn.php b/src/Migration/Generator/Columns/DecimalColumn.php index d170f889..8acf1880 100644 --- a/src/Migration/Generator/Columns/DecimalColumn.php +++ b/src/Migration/Generator/Columns/DecimalColumn.php @@ -2,6 +2,7 @@ namespace KitLoong\MigrationsGenerator\Migration\Generator\Columns; +use KitLoong\MigrationsGenerator\Enum\Migrations\Method\ColumnModifier; use KitLoong\MigrationsGenerator\Migration\Blueprint\Method; use KitLoong\MigrationsGenerator\Schema\Models\Column; use KitLoong\MigrationsGenerator\Schema\Models\Table; @@ -18,7 +19,14 @@ class DecimalColumn implements ColumnTypeGenerator public function generate(Table $table, Column $column): Method { $precisions = $this->getDecimalPrecisions($column->getPrecision(), $column->getScale()); - return new Method($column->getType(), $column->getName(), ...$precisions); + + $method = new Method($column->getType(), $column->getName(), ...$precisions); + + if ($column->isUnsigned()) { + $method->chain(ColumnModifier::UNSIGNED()); + } + + return $method; } /** @@ -27,7 +35,7 @@ public function generate(Table $table, Column $column): Method * * @return int[] "[]|[precision]|[precision, scale]" */ - private function getDecimalPrecisions(int $precision, int $scale): array + private function getDecimalPrecisions(?int $precision, int $scale): array { if ($precision === self::DEFAULT_PRECISION && $scale === self::DEFAULT_SCALE) { return []; diff --git a/src/Migration/Generator/Columns/DoubleColumn.php b/src/Migration/Generator/Columns/DoubleColumn.php index 2ee09c74..368ed386 100644 --- a/src/Migration/Generator/Columns/DoubleColumn.php +++ b/src/Migration/Generator/Columns/DoubleColumn.php @@ -6,9 +6,12 @@ use KitLoong\MigrationsGenerator\Migration\Blueprint\Method; use KitLoong\MigrationsGenerator\Schema\Models\Column; use KitLoong\MigrationsGenerator\Schema\Models\Table; +use KitLoong\MigrationsGenerator\Support\CheckLaravelVersion; class DoubleColumn implements ColumnTypeGenerator { + use CheckLaravelVersion; + private const EMPTY_PRECISION = 0; private const EMPTY_SCALE = 0; @@ -36,6 +39,10 @@ public function generate(Table $table, Column $column): Method */ private function getPrecisions(Column $column): array { + if ($this->atLeastLaravel11()) { + return []; + } + if ( $column->getPrecision() === self::EMPTY_PRECISION && $column->getScale() === self::EMPTY_SCALE diff --git a/src/Migration/Generator/Columns/FloatColumn.php b/src/Migration/Generator/Columns/FloatColumn.php index c925d440..92d941c6 100644 --- a/src/Migration/Generator/Columns/FloatColumn.php +++ b/src/Migration/Generator/Columns/FloatColumn.php @@ -6,10 +6,13 @@ use KitLoong\MigrationsGenerator\Migration\Blueprint\Method; use KitLoong\MigrationsGenerator\Schema\Models\Column; use KitLoong\MigrationsGenerator\Schema\Models\Table; +use KitLoong\MigrationsGenerator\Support\CheckLaravelVersion; class FloatColumn implements ColumnTypeGenerator { - // Framework set (8, 2) as default precision. + use CheckLaravelVersion; + + // Laravel version before 11 set (8, 2) as default precision. private const DEFAULT_PRECISION = 8; private const DEFAULT_SCALE = 2; @@ -37,6 +40,14 @@ public function generate(Table $table, Column $column): Method */ private function getPrecisions(Column $column): array { + if ($this->atLeastLaravel11()) { + if ($column->getPrecision() === null) { + return []; + } + + return [$column->getPrecision()]; + } + if ( $column->getPrecision() === self::DEFAULT_PRECISION && $column->getScale() === self::DEFAULT_SCALE diff --git a/src/Migration/Generator/Columns/SpatialColumn.php b/src/Migration/Generator/Columns/SpatialColumn.php new file mode 100644 index 00000000..16d3e933 --- /dev/null +++ b/src/Migration/Generator/Columns/SpatialColumn.php @@ -0,0 +1,73 @@ +hasGeography()) { + if ($column->getType()->equals(ColumnType::GEOGRAPHY())) { + return new Method(ColumnType::GEOMETRY(), $column->getName()); + } + + return new Method($column->getType(), $column->getName()); + } + + $methodValues = [$column->getName()]; + + if ($column->getSpatialSubType() !== null) { + $methodValues[] = $column->getSpatialSubType(); + } + + $srID = $this->getSrIDArg($column); + + if ($srID !== null) { + if (count($methodValues) === 1) { + $methodValues[] = null; + } + + $methodValues[] = $srID; + } + + return new Method($column->getType(), ...$methodValues); + } + + private function getSrIDArg(Column $column): ?int + { + if ($column->getSpatialSrID() === null) { + return null; + } + + switch ($column->getType()) { + case ColumnType::GEOMETRY(): + if ($column->getSpatialSrID() !== self::GEOMETRY_DEFAULT_SRID) { + return $column->getSpatialSrID(); + } + + break; + + default: + if ($column->getSpatialSrID() !== self::GEOGRAPHY_DEFAULT_SRID) { + return $column->getSpatialSrID(); + } + } + + return null; + } +} diff --git a/src/Migration/Generator/Modifiers/DefaultModifier.php b/src/Migration/Generator/Modifiers/DefaultModifier.php index 916d8a00..e749c4b0 100644 --- a/src/Migration/Generator/Modifiers/DefaultModifier.php +++ b/src/Migration/Generator/Modifiers/DefaultModifier.php @@ -43,7 +43,6 @@ public function __construct() foreach ( [ ColumnType::DECIMAL(), - ColumnType::UNSIGNED_DECIMAL(), ColumnType::FLOAT(), ColumnType::DOUBLE(), ] as $columnType diff --git a/src/MigrationsGeneratorServiceProvider.php b/src/MigrationsGeneratorServiceProvider.php index b5d66a22..a9b72c77 100644 --- a/src/MigrationsGeneratorServiceProvider.php +++ b/src/MigrationsGeneratorServiceProvider.php @@ -4,6 +4,7 @@ use Illuminate\Database\Migrations\MigrationRepositoryInterface; use Illuminate\Support\ServiceProvider; +use KitLoong\MigrationsGenerator\DBAL\Connection; use KitLoong\MigrationsGenerator\DBAL\MySQLSchema as DBALMySQLSchema; use KitLoong\MigrationsGenerator\DBAL\PgSQLSchema as DBALPgSQLSchema; use KitLoong\MigrationsGenerator\DBAL\SQLiteSchema as DBALSQLiteSchema; @@ -19,6 +20,7 @@ use KitLoong\MigrationsGenerator\Migration\Generator\Columns\OmitNameColumn; use KitLoong\MigrationsGenerator\Migration\Generator\Columns\PresetValuesColumn; use KitLoong\MigrationsGenerator\Migration\Generator\Columns\SoftDeleteColumn; +use KitLoong\MigrationsGenerator\Migration\Generator\Columns\SpatialColumn; use KitLoong\MigrationsGenerator\Migration\Generator\Columns\StringColumn; use KitLoong\MigrationsGenerator\Migration\Migrator\Migrator; use KitLoong\MigrationsGenerator\Repositories\MariaDBRepository; @@ -50,6 +52,7 @@ public function register(): void SQLiteRepository::class => SQLiteRepository::class, SQLSrvRepository::class => SQLSrvRepository::class, MariaDBRepository::class => MariaDBRepository::class, + Connection::class => Connection::class, ] as $abstract => $concrete ) { $this->app->singleton($abstract, $concrete); @@ -163,7 +166,6 @@ protected function registerColumnTypeGenerator(): void foreach ( [ ColumnType::DECIMAL(), - ColumnType::UNSIGNED_DECIMAL(), ] as $columnType ) { $this->columnTypeSingleton($columnType, DecimalColumn::class); @@ -187,6 +189,22 @@ protected function registerColumnTypeGenerator(): void $this->columnTypeSingleton($columnType, StringColumn::class); } + foreach ( + [ + ColumnType::GEOGRAPHY(), + ColumnType::GEOMETRY(), + ColumnType::GEOMETRY_COLLECTION(), + ColumnType::LINE_STRING(), + ColumnType::MULTI_LINE_STRING(), + ColumnType::POINT(), + ColumnType::MULTI_POINT(), + ColumnType::MULTI_POLYGON(), + ColumnType::POLYGON(), + ] as $columnType + ) { + $this->columnTypeSingleton($columnType, SpatialColumn::class); + } + $this->columnTypeSingleton(ColumnType::BOOLEAN(), BooleanColumn::class); $this->columnTypeSingleton(ColumnType::DOUBLE(), DoubleColumn::class); $this->columnTypeSingleton(ColumnType::FLOAT(), FloatColumn::class); diff --git a/src/Repositories/MySQLRepository.php b/src/Repositories/MySQLRepository.php index 05d53600..dcb43886 100644 --- a/src/Repositories/MySQLRepository.php +++ b/src/Repositories/MySQLRepository.php @@ -188,4 +188,36 @@ private function getGenerationExpression(string $table, string $column, string $ $definitionArr = array_change_key_case((array) $definition); return $definitionArr['generation_expression'] !== '' ? $definitionArr['generation_expression'] : null; } + + public function getSrID(string $table, string $column): ?int + { + try { + $srsID = DB::selectOne( + "SELECT SRS_ID + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = '" . DB::getDatabaseName() . "' + AND TABLE_NAME = '" . $table . "' + AND COLUMN_NAME = '" . $column . "'" + ); + } catch (QueryException $exception) { + if ( + Str::contains( + $exception->getMessage(), + "SQLSTATE[42S22]: Column not found: 1054 Unknown column 'SRS_ID'", + true + ) + ) { + return null; + } + + throw $exception; + } + + if ($srsID === null) { + return null; + } + + $srsIDArr = array_change_key_case((array) $srsID); + return $srsIDArr['srs_id'] ?? null; + } } diff --git a/src/Schema/Models/Column.php b/src/Schema/Models/Column.php index 054c2f82..f37fc09e 100644 --- a/src/Schema/Models/Column.php +++ b/src/Schema/Models/Column.php @@ -73,7 +73,7 @@ public function isAutoincrement(): bool; /** * Get the column precision. */ - public function getPrecision(): int; + public function getPrecision(): ?int; /** * Get the column comment. @@ -88,6 +88,16 @@ public function getComment(): ?string; */ public function getPresetValues(): array; + /** + * Get the spatial column subtype. + */ + public function getSpatialSubType(): ?string; + + /** + * Get the spatial column srID. + */ + public function getSpatialSrID(): ?int; + /** * Check if the column uses "on update CURRENT_TIMESTAMP". * This is usually used for MySQL `timestamp` and `timestampTz`. diff --git a/src/Schema/Schema.php b/src/Schema/Schema.php index d109ef5a..2fb79500 100644 --- a/src/Schema/Schema.php +++ b/src/Schema/Schema.php @@ -38,7 +38,7 @@ public function getViews(): Collection; /** * Get a list of foreign keys. * - * @return \Illuminate\Support\Collection + * @return \Illuminate\Support\Collection */ public function getTableForeignKeys(string $table): Collection; diff --git a/src/Support/CheckLaravelVersion.php b/src/Support/CheckLaravelVersion.php index 50b066e7..812f0351 100644 --- a/src/Support/CheckLaravelVersion.php +++ b/src/Support/CheckLaravelVersion.php @@ -36,6 +36,15 @@ public function atLeastLaravel9(): bool return $this->atLeastLaravelVersion('9.0'); } + public function atLeastLaravel11(): bool + { + if (App::version() === '11.x-dev') { + return true; + } + + return $this->atLeastLaravelVersion('11.0'); + } + private function atLeastLaravelVersion(string $version): bool { return version_compare(App::version(), $version, '>='); diff --git a/src/Support/CheckMigrationMethod.php b/src/Support/CheckMigrationMethod.php index e1434901..4f60da22 100644 --- a/src/Support/CheckMigrationMethod.php +++ b/src/Support/CheckMigrationMethod.php @@ -67,4 +67,12 @@ public function hasTableComment(): bool { return method_exists(Blueprint::class, 'comment'); } + + /** + * `geography` added since Laravel 11. + */ + public function hasGeography(): bool + { + return method_exists(Blueprint::class, 'geography'); + } } diff --git a/testbench.yaml b/testbench.yaml index df049c3a..d5ab53bd 100644 --- a/testbench.yaml +++ b/testbench.yaml @@ -1,3 +1,3 @@ providers: - - Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider + # - Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider - KitLoong\MigrationsGenerator\MigrationsGeneratorServiceProvider diff --git a/tests/Feature/FeatureTestCase.php b/tests/Feature/FeatureTestCase.php index ddeac5b6..33244e8b 100644 --- a/tests/Feature/FeatureTestCase.php +++ b/tests/Feature/FeatureTestCase.php @@ -8,6 +8,7 @@ use Illuminate\Database\Migrations\MigrationRepositoryInterface; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\File; +use KitLoong\MigrationsGenerator\DBAL\Connection; use KitLoong\MigrationsGenerator\Support\AssetNameQuote; use KitLoong\MigrationsGenerator\Tests\TestCase; @@ -238,7 +239,7 @@ protected function truncateMigrationsTable(): void */ protected function getTableNames(): array { - return collect(DB::getDoctrineSchemaManager()->listTableNames()) + return collect(app(Connection::class)->getDoctrineSchemaManager()->listTableNames()) ->map(function ($table) { // The table name may contain quotes. // Always trim quotes before set into list. @@ -258,7 +259,7 @@ protected function getTableNames(): array */ protected function getViewNames(): array { - return collect(DB::getDoctrineSchemaManager()->listViews()) + return collect(app(Connection::class)->getDoctrineSchemaManager()->listViews()) ->map(function (View $view) { return $view->getName(); }) diff --git a/tests/Feature/PgSQL/PgSQLTestCase.php b/tests/Feature/PgSQL/PgSQLTestCase.php index bfa72095..968bfa8b 100644 --- a/tests/Feature/PgSQL/PgSQLTestCase.php +++ b/tests/Feature/PgSQL/PgSQLTestCase.php @@ -4,6 +4,7 @@ use Illuminate\Support\Facades\DB; use Illuminate\Support\Str; +use KitLoong\MigrationsGenerator\DBAL\Connection; use KitLoong\MigrationsGenerator\Tests\Feature\FeatureTestCase; abstract class PgSQLTestCase extends FeatureTestCase @@ -69,7 +70,7 @@ protected function refreshDatabase(): void protected function dropAllTablesAndViews(): void { - $tables = DB::getDoctrineSchemaManager()->listTableNames(); + $tables = app(Connection::class)->getDoctrineSchemaManager()->listTableNames(); foreach ($tables as $table) { if (Str::startsWith($table, 'tiger.')) { diff --git a/tests/Feature/SQLSrv/SQLSrvTestCase.php b/tests/Feature/SQLSrv/SQLSrvTestCase.php index dcf555e8..72bfcc40 100644 --- a/tests/Feature/SQLSrv/SQLSrvTestCase.php +++ b/tests/Feature/SQLSrv/SQLSrvTestCase.php @@ -5,6 +5,7 @@ use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\File; use Illuminate\Support\Facades\Schema; +use KitLoong\MigrationsGenerator\DBAL\Connection; use KitLoong\MigrationsGenerator\Support\CheckLaravelVersion; use KitLoong\MigrationsGenerator\Tests\Feature\FeatureTestCase; @@ -47,14 +48,14 @@ protected function setUp(): void protected function dumpSchemaAs(string $destination): void { - $tables = DB::getDoctrineSchemaManager()->listTableNames(); + $tables = app(Connection::class)->getDoctrineSchemaManager()->listTableNames(); $sqls = []; foreach ($tables as $table) { $sqls[] = "EXEC sp_help '" . $table . "';"; } - $views = DB::getDoctrineSchemaManager()->listViews(); + $views = app(Connection::class)->getDoctrineSchemaManager()->listViews(); foreach ($views as $view) { $sqls[] = "EXEC sp_helptext '" . $view->getName() . "';"; diff --git a/tests/Feature/SQLite/CommandTest.php b/tests/Feature/SQLite/CommandTest.php index 4ded17f3..d78771d4 100644 --- a/tests/Feature/SQLite/CommandTest.php +++ b/tests/Feature/SQLite/CommandTest.php @@ -45,18 +45,18 @@ public function testDown(): void $this->assertSame(0, DB::table('migrations')->count()); } - public function testCollation(): void - { - $migrateTemplates = function (): void { - $this->migrateCollation('sqlite'); - }; - - $generateMigrations = function (): void { - $this->generateMigrations(['--use-db-collation' => true]); - }; - - $this->verify($migrateTemplates, $generateMigrations); - } +// public function testCollation(): void +// { +// $migrateTemplates = function (): void { +// $this->migrateCollation('sqlite'); +// }; +// +// $generateMigrations = function (): void { +// $this->generateMigrations(['--use-db-collation' => true]); +// }; +// +// $this->verify($migrateTemplates, $generateMigrations); +// } public function testSkipVendor(): void { diff --git a/tests/TestMigration.php b/tests/TestMigration.php index f776f23c..77663a33 100644 --- a/tests/TestMigration.php +++ b/tests/TestMigration.php @@ -3,12 +3,12 @@ namespace KitLoong\MigrationsGenerator\Tests; use Illuminate\Database\Migrations\Migration; -use Illuminate\Support\Facades\DB; +use KitLoong\MigrationsGenerator\DBAL\Connection; abstract class TestMigration extends Migration { protected function quoteIdentifier(string $string): string { - return DB::getDoctrineConnection()->quoteIdentifier($string); + return app(Connection::class)->getDoctrineConnection()->quoteIdentifier($string); } } diff --git a/tests/resources/database/migrations/collation/2020_03_21_000000_expected_create_collations_db_table.php b/tests/resources/database/migrations/collation/2020_03_21_000000_expected_create_collations_db_table.php index 5e1f1de9..69de0e6b 100644 --- a/tests/resources/database/migrations/collation/2020_03_21_000000_expected_create_collations_db_table.php +++ b/tests/resources/database/migrations/collation/2020_03_21_000000_expected_create_collations_db_table.php @@ -33,8 +33,11 @@ public function up() case Driver::SQLSRV(): $collation = 'Latin1_General_100_CI_AI_SC_UTF8'; break; - default: + case Driver::MYSQL(): $collation = 'utf8_unicode_ci'; + break; + default: + $collation = 'BINARY'; } $table->char('char'); diff --git a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_db_table.php b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_db_table.php index 673b81d4..68a7a9ba 100644 --- a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_db_table.php +++ b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_db_table.php @@ -62,37 +62,65 @@ public function up() $table->decimal('decimal_53', 5, 3); $table->decimal('decimal_default')->default(10.8); $table->double('double'); - $table->double('double_82', 8, 2); - $table->double('double_83', 8, 3); - $table->double('double_92', 9, 2); - $table->double('double_53', 5, 3); $table->double('double_default')->default(10.8); $table->enum('enum', ['easy', 'hard']); $table->enum('enum_default', ['easy', 'hard'])->default('easy'); $table->float('float'); - $table->float('float_82', 8, 2); - $table->float('float_83', 8, 3); - $table->float('float_92', 9, 2); - $table->float('float_53', 5, 3); $table->float('float_default')->default(10.8); - $table->geometry('geometry'); - $table->geometryCollection('geometryCollection'); $table->integer('integer'); $table->integer('integer_default')->default(1080); $table->ipAddress('ipAddress'); $table->ipAddress('ipAddress_default')->default('10.0.0.8'); $table->json('json'); $table->jsonb('jsonb'); - $table->lineString('lineString'); $table->longText('longText'); $table->mediumInteger('mediumInteger'); $table->mediumInteger('mediumInteger_default')->default(1080); $table->mediumText('mediumText'); - $table->multiLineString('multiLineString'); - $table->multiPoint('multiPoint'); - $table->multiPolygon('multiPolygon'); - $table->point('point'); - $table->polygon('polygon'); + $table->geometry('geometry'); + + // https://github.com/laravel/framework/pull/49634 + if ($this->atLeastLaravel11()) { + if ( + DB::getDriverName() !== Driver::MYSQL()->getValue() || + version_compare(DB::getServerVersion(), '5.8', '>') + ) { + $table->geography('geography'); + $table->geography('geographyGeometryCollection', 'geometryCollection'); + $table->geography('geographyLineString', 'lineString'); + $table->geography('geographyMultiLineString', 'multiLineString'); + $table->geography('geographyMultiPoint', 'multiPoint'); + $table->geography('geographyMultiPolygon', 'multiPolygon'); + $table->geography('geographyPoint', 'point'); + $table->geography('geographyPolygon', 'polygon'); + $table->geography('geography1', null, 3857); + + if (DB::getDriverName() !== Driver::PGSQL()->getValue()) { + $table->geography('geography2', 'geometryCollection', 3857); + } + + $table->geometry('geometryCollection', 'geometryCollection'); + $table->geometry('lineString', 'lineString'); + $table->geometry('multiLineString', 'multiLineString'); + $table->geometry('multiPoint', 'multiPoint'); + $table->geometry('multiPolygon', 'multiPolygon'); + $table->geometry('point', 'point'); + $table->geometry('polygon', 'polygon'); + $table->geometry('geometry1', null, 3857); + $table->geometry('geometry2', 'geometryCollection', 3857); + } + } + + if (!$this->atLeastLaravel11()) { + $table->geometryCollection('geometryCollection'); // @phpstan-ignore-line + $table->lineString('lineString'); // @phpstan-ignore-line + $table->multiLineString('multiLineString'); // @phpstan-ignore-line + $table->multiPoint('multiPoint'); // @phpstan-ignore-line + $table->multiPolygon('multiPolygon'); // @phpstan-ignore-line + $table->point('point'); // @phpstan-ignore-line + $table->polygon('polygon'); // @phpstan-ignore-line + } + $table->smallInteger('smallInteger'); $table->smallInteger('smallInteger_default')->default(1080); $table->string('string'); @@ -130,6 +158,20 @@ public function up() $table->decimal('unsignedDecimal')->unsigned(); $table->double('unsignedDouble')->unsigned(); $table->float('unsignedFloat')->unsigned(); + + if (method_exists(Blueprint::class, 'unsignedDecimal')) { + // https://github.com/laravel/framework/pull/48861 + $table->double('double_82', 8, 2); // @phpstan-ignore-line + $table->double('double_83', 8, 3); // @phpstan-ignore-line + $table->double('double_92', 9, 2); // @phpstan-ignore-line + $table->double('double_53', 5, 3); // @phpstan-ignore-line + $table->float('float_82', 8, 2); // @phpstan-ignore-line + $table->float('float_83', 8, 3); // @phpstan-ignore-line + $table->float('float_92', 9, 2); // @phpstan-ignore-line + $table->float('float_53', 5, 3); // @phpstan-ignore-line + $table->float('float_56', 50); + } + $table->unsignedInteger('unsignedInteger'); $table->unsignedMediumInteger('unsignedMediumInteger'); $table->unsignedSmallInteger('unsignedSmallInteger'); diff --git a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_test_index_db_table.php b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_test_index_db_table.php index 8f0a694f..d19f755e 100644 --- a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_test_index_db_table.php +++ b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_test_index_db_table.php @@ -43,9 +43,16 @@ public function up() // SQLite does not support spatial index. if (DB::getDriverName() !== Driver::SQLITE()->getValue()) { - $table->lineString('spatial_index')->spatialIndex(); - $table->lineString('spatial_index_custom'); - $table->spatialIndex('spatial_index_custom', 'spatial_index_custom'); + if ($this->hasGeography()) { + $table->geography('spatial_index', null, 0)->spatialIndex(); + $table->geography('spatial_index_custom', null, 0); + $table->spatialIndex('spatial_index_custom', 'spatial_index_custom'); + } + if (!$this->hasGeography()) { + $table->geometry('spatial_index')->spatialIndex(); + $table->geometry('spatial_index_custom'); + $table->spatialIndex('spatial_index_custom', 'spatial_index_custom'); + } } if ( From 31b4b4410cfa7f89a6fed1fe88368075410c9135 Mon Sep 17 00:00:00 2001 From: Kit Loong Date: Wed, 7 Feb 2024 20:55:20 +0800 Subject: [PATCH 02/20] Update code comments --- src/DBAL/Connection.php | 4 +--- src/DBAL/Models/DBALCustomColumn.php | 6 +++--- src/DBAL/Models/PgSQL/PgSQLColumn.php | 3 +++ src/Migration/Generator/Columns/SpatialColumn.php | 4 ++++ src/Repositories/MySQLRepository.php | 3 +++ 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/DBAL/Connection.php b/src/DBAL/Connection.php index ea9b134e..e852ce07 100644 --- a/src/DBAL/Connection.php +++ b/src/DBAL/Connection.php @@ -69,10 +69,8 @@ public function getDoctrineSchemaManager(): AbstractSchemaManager /** * Get the Doctrine DBAL driver. - * - * @return \KitLoong\MigrationsGenerator\DBAL\PDO\MySqlDriver|\KitLoong\MigrationsGenerator\DBAL\PDO\PostgresDriver|\KitLoong\MigrationsGenerator\DBAL\PDO\SQLiteDriver|\KitLoong\MigrationsGenerator\DBAL\PDO\SqlServerDriver */ - protected function getDoctrineDriver() + protected function getDoctrineDriver(): SQLiteDriver|SqlServerDriver|MySqlDriver|PostgresDriver { switch (true) { case DB::connection() instanceof MySqlConnection: diff --git a/src/DBAL/Models/DBALCustomColumn.php b/src/DBAL/Models/DBALCustomColumn.php index 3ba320ab..79795c17 100644 --- a/src/DBAL/Models/DBALCustomColumn.php +++ b/src/DBAL/Models/DBALCustomColumn.php @@ -72,9 +72,9 @@ public function getSqls(): array } /** - * Init TableDiff by table name. - * This method compare Laravel version to determine which TableDiff constructor to use. - * To be precise, it uses Laravel version to determine which constructor to use because Laravel 11 uses Doctrine DBAL 4. + * Initialize a TableDiff instance based on the table name. + * The \Doctrine\DBAL\Schema\TableDiff constructor has been updated from Doctrine DBAL 3 to DBAL 4. + * This method utilizes the Laravel version to determine which TableDiff constructor to use, as Laravel 11 requires Doctrine DBAL 4. * * @see https://github.com/doctrine/dbal/pull/5683 */ diff --git a/src/DBAL/Models/PgSQL/PgSQLColumn.php b/src/DBAL/Models/PgSQL/PgSQLColumn.php index 2daff3ce..639d3947 100644 --- a/src/DBAL/Models/PgSQL/PgSQLColumn.php +++ b/src/DBAL/Models/PgSQL/PgSQLColumn.php @@ -220,6 +220,9 @@ private function setStoredDefinition(): void $this->default = null; } + /** + * Override parent method to handle autoincrement with default value. + */ protected function setTypeToIncrements(bool $supportUnsigned): void { // https://www.postgresqltutorial.com/postgresql-tutorial/postgresql-identity-column/ diff --git a/src/Migration/Generator/Columns/SpatialColumn.php b/src/Migration/Generator/Columns/SpatialColumn.php index 16d3e933..2ea34d65 100644 --- a/src/Migration/Generator/Columns/SpatialColumn.php +++ b/src/Migration/Generator/Columns/SpatialColumn.php @@ -48,6 +48,10 @@ public function generate(Table $table, Column $column): Method return new Method($column->getType(), ...$methodValues); } + /** + * Get the SRID argument for spatial column. + * Return null if the SRID is null or it matches the default SRID. + */ private function getSrIDArg(Column $column): ?int { if ($column->getSpatialSrID() === null) { diff --git a/src/Repositories/MySQLRepository.php b/src/Repositories/MySQLRepository.php index dcb43886..c269f9c0 100644 --- a/src/Repositories/MySQLRepository.php +++ b/src/Repositories/MySQLRepository.php @@ -189,6 +189,9 @@ private function getGenerationExpression(string $table, string $column, string $ return $definitionArr['generation_expression'] !== '' ? $definitionArr['generation_expression'] : null; } + /** + * Get the SRID by table and column name. + */ public function getSrID(string $table, string $column): ?int { try { From c6d986286557d37801ca178aa12a66f29adb9f3e Mon Sep 17 00:00:00 2001 From: Kit Loong Date: Wed, 7 Feb 2024 21:17:28 +0800 Subject: [PATCH 03/20] Lint fix --- phpcs.xml | 88 +++------------ src/DBAL/Connection.php | 4 +- src/DBAL/DBALSchema.php | 3 +- src/DBAL/Models/DBALColumn.php | 102 ++++-------------- src/DBAL/Models/DBALCustomColumn.php | 14 +-- src/DBAL/Models/DBALForeignKey.php | 29 ++--- src/DBAL/Models/DBALIndex.php | 19 +--- src/DBAL/Models/DBALProcedure.php | 19 +--- src/DBAL/Models/DBALTable.php | 25 ++--- src/DBAL/Models/DBALView.php | 20 +--- src/DBAL/Models/MySQL/MySQLColumn.php | 14 +-- src/DBAL/Models/PgSQL/PgSQLColumn.php | 5 +- src/DBAL/Models/PgSQL/PgSQLIndex.php | 9 +- src/DBAL/Models/PgSQL/PgSQLTable.php | 15 ++- src/DBAL/Models/SQLSrv/SQLSrvColumn.php | 7 +- src/DBAL/Models/SQLSrv/SQLSrvIndex.php | 5 +- src/DBAL/Models/SQLite/SQLiteColumn.php | 5 +- src/DBAL/MySQLSchema.php | 27 ++--- src/DBAL/PgSQLSchema.php | 31 ++---- src/DBAL/RegisterColumnType.php | 19 +--- src/DBAL/SQLSrvSchema.php | 32 ++---- src/DBAL/SQLiteSchema.php | 14 +-- src/DBAL/Types/Types.php | 2 +- src/MigrateGenerateCommand.php | 98 +++++------------ .../Blueprint/DBStatementBlueprint.php | 8 +- .../Blueprint/DBUnpreparedBlueprint.php | 8 +- src/Migration/Blueprint/Method.php | 12 +-- src/Migration/Blueprint/Property.php | 17 +-- src/Migration/Blueprint/SchemaBlueprint.php | 19 +--- .../Blueprint/Support/MergeTimestamps.php | 2 +- .../Blueprint/Support/Stringable.php | 8 +- src/Migration/Blueprint/TableBlueprint.php | 20 ++-- src/Migration/ForeignKeyMigration.php | 48 ++------- src/Migration/Generator/ColumnGenerator.php | 64 ++--------- .../Generator/ForeignKeyGenerator.php | 2 +- src/Migration/Generator/IndexGenerator.php | 16 +-- .../Generator/Modifiers/CharsetModifier.php | 10 +- .../Generator/Modifiers/CollationModifier.php | 10 +- .../Generator/Modifiers/CommentModifier.php | 2 +- .../Generator/Modifiers/DefaultModifier.php | 20 ++-- .../Generator/Modifiers/IndexModifier.php | 10 +- .../Generator/Modifiers/Modifier.php | 4 +- .../Generator/Modifiers/NullableModifier.php | 6 +- .../Generator/Modifiers/StoredAsModifier.php | 2 +- .../Generator/Modifiers/VirtualAsModifier.php | 2 +- src/Migration/Migrator/Migrator.php | 6 +- src/Migration/ProcedureMigration.php | 38 ++----- src/Migration/Squash.php | 24 +---- src/Migration/TableMigration.php | 58 ++-------- src/Migration/ViewMigration.php | 38 ++----- src/Migration/Writer/MigrationStub.php | 2 +- src/Migration/Writer/MigrationWriter.php | 18 +--- src/Migration/Writer/SquashWriter.php | 28 ++--- src/MigrationsGeneratorServiceProvider.php | 8 +- .../Entities/MariaDB/CheckConstraint.php | 22 ++-- .../Entities/MySQL/ShowColumn.php | 22 ++-- .../Entities/PgSQL/IndexDefinition.php | 20 +--- .../Entities/ProcedureDefinition.php | 10 +- .../Entities/SQLSrv/ColumnDefinition.php | 34 ++---- .../Entities/SQLSrv/ViewDefinition.php | 14 +-- src/Repositories/MariaDBRepository.php | 4 +- src/Repositories/MySQLRepository.php | 17 ++- src/Repositories/PgSQLRepository.php | 30 +++--- src/Repositories/SQLSrvRepository.php | 10 +- src/Setting.php | 40 +++---- src/Support/IndexNameHelper.php | 8 +- src/Support/MigrationNameHelper.php | 6 +- tests/Feature/FeatureTestCase.php | 16 ++- tests/Feature/MariaDB/CommandTest.php | 2 +- tests/Feature/MariaDB/MariaDBTestCase.php | 4 +- tests/Feature/MySQL57/CommandTest.php | 36 +++---- tests/Feature/MySQL57/DBConnectionTest.php | 10 +- tests/Feature/MySQL57/MySQL57TestCase.php | 4 +- tests/Feature/MySQL57/StackedCommandTest.php | 8 +- tests/Feature/MySQL57/TablePrefixTest.php | 2 +- tests/Feature/MySQL8/CommandTest.php | 6 +- tests/Feature/MySQL8/MySQL8TestCase.php | 4 +- tests/Feature/PgSQL/CommandTest.php | 30 +++--- tests/Feature/PgSQL/PgSQLTestCase.php | 4 +- tests/Feature/PgSQL/TablePrefixTest.php | 4 +- tests/Feature/SQLSrv/CommandTest.php | 16 ++- tests/Feature/SQLSrv/SQLSrvTestCase.php | 6 +- tests/Feature/SQLite/CommandTest.php | 6 +- tests/Feature/SQLite/SQLiteTestCase.php | 2 +- tests/MigrationWriterTest.php | 4 +- tests/Support/CheckLaravelVersionTest.php | 5 +- tests/TestCase.php | 4 +- 87 files changed, 396 insertions(+), 1130 deletions(-) diff --git a/phpcs.xml b/phpcs.xml index 06ab786c..ba7395c3 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -39,7 +39,7 @@ - + @@ -48,17 +48,12 @@ - + - - - - - - + @@ -92,10 +87,10 @@ - + - + @@ -106,12 +101,7 @@ - - - - - - + @@ -121,12 +111,7 @@ - - - - - - + @@ -146,23 +131,13 @@ - + - - - - - - - - - - - - - - + + + + @@ -184,8 +159,8 @@ - - + + @@ -210,39 +185,10 @@ - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - + + diff --git a/src/DBAL/Connection.php b/src/DBAL/Connection.php index e852ce07..2db5fa41 100644 --- a/src/DBAL/Connection.php +++ b/src/DBAL/Connection.php @@ -20,10 +20,8 @@ class Connection { /** * The instance of Doctrine connection. - * - * @var \Doctrine\DBAL\Connection */ - protected $doctrineConnection; + protected ?DoctrineConnection $doctrineConnection; /** * Get the Doctrine DBAL database connection instance. diff --git a/src/DBAL/DBALSchema.php b/src/DBAL/DBALSchema.php index 6e62bf9c..46143943 100644 --- a/src/DBAL/DBALSchema.php +++ b/src/DBAL/DBALSchema.php @@ -2,6 +2,7 @@ namespace KitLoong\MigrationsGenerator\DBAL; +use Doctrine\DBAL\Schema\AbstractSchemaManager; use Doctrine\DBAL\Schema\Table; use Illuminate\Support\Collection; use KitLoong\MigrationsGenerator\Schema\Schema; @@ -17,7 +18,7 @@ abstract class DBALSchema implements Schema /** * @var \Doctrine\DBAL\Schema\AbstractSchemaManager */ - protected $dbalSchema; + protected AbstractSchemaManager $dbalSchema; /** * @throws \Doctrine\DBAL\Exception diff --git a/src/DBAL/Models/DBALColumn.php b/src/DBAL/Models/DBALColumn.php index b3fad579..4abb408e 100644 --- a/src/DBAL/Models/DBALColumn.php +++ b/src/DBAL/Models/DBALColumn.php @@ -21,110 +21,50 @@ abstract class DBALColumn implements Column { use CheckLaravelVersion; - /** - * @var bool - */ - protected $autoincrement; + protected bool $autoincrement; - /** - * @var string|null - */ - protected $charset; + protected ?string $charset = null; - /** - * @var string|null - */ - protected $collation; + protected ?string $collation = null; - /** - * @var string|null - */ - protected $comment; + protected ?string $comment = null; - /** - * @var string|null - */ - protected $default; + protected ?string $default = null; - /** - * @var bool - */ - protected $fixed; + protected bool $fixed; - /** - * @var int|null - */ - protected $length; + protected ?int $length = null; - /** - * @var string - */ - protected $name; + protected string $name; - /** - * @var bool - */ - protected $notNull; + protected bool $notNull; - /** - * @var bool - */ - protected $onUpdateCurrentTimestamp; + protected bool $onUpdateCurrentTimestamp; - /** - * @var int|null - */ - protected $precision; + protected ?int $precision = null; /** * @var string[] */ - protected $presetValues; + protected array $presetValues; - /** - * @var bool - */ - protected $rawDefault; + protected bool $rawDefault; - /** - * @var int - */ - protected $scale; + protected int $scale; - /** - * @var string - */ - protected $tableName; + protected string $tableName; - /** - * @var \KitLoong\MigrationsGenerator\Enum\Migrations\Method\ColumnType - */ - protected $type; + protected ColumnType $type; - /** - * @var bool - */ - protected $unsigned; + protected bool $unsigned; - /** - * @var string|null - */ - protected $virtualDefinition; + protected ?string $virtualDefinition = null; - /** - * @var string|null - */ - protected $storedDefinition; + protected ?string $storedDefinition = null; - /** - * @var string|null - */ - protected $spatialSubType; + protected ?string $spatialSubType = null; - /** - * @var int|null - */ - protected $spatialSrID; + protected ?int $spatialSrID = null; private const REMEMBER_TOKEN_LENGTH = 100; diff --git a/src/DBAL/Models/DBALCustomColumn.php b/src/DBAL/Models/DBALCustomColumn.php index 79795c17..c2d0ce3e 100644 --- a/src/DBAL/Models/DBALCustomColumn.php +++ b/src/DBAL/Models/DBALCustomColumn.php @@ -13,20 +13,14 @@ abstract class DBALCustomColumn implements CustomColumn { use CheckLaravelVersion; - /** - * @var string - */ - private $name; + private string $name; - /** - * @var string - */ - private $tableName; + private string $tableName; /** * @var string[] */ - private $sqls; + private array $sqls; /** * @throws \Doctrine\DBAL\Exception @@ -93,7 +87,7 @@ private function getTableDiff(DoctrineDBALColumn $column): TableDiff [], [], [], - [] + [], ); } diff --git a/src/DBAL/Models/DBALForeignKey.php b/src/DBAL/Models/DBALForeignKey.php index 6b467916..0af9c7c5 100644 --- a/src/DBAL/Models/DBALForeignKey.php +++ b/src/DBAL/Models/DBALForeignKey.php @@ -7,40 +7,25 @@ abstract class DBALForeignKey implements ForeignKey { - /** - * @var string - */ - protected $name; + protected string $name; - /** - * @var string - */ - protected $tableName; + protected string $tableName; /** * @var string[] */ - protected $localColumns; + protected array $localColumns; /** * @var string[] */ - protected $foreignColumns; + protected array $foreignColumns; - /** - * @var string - */ - protected $foreignTableName; + protected string $foreignTableName; - /** - * @var string|null - */ - protected $onUpdate; + protected ?string $onUpdate = null; - /** - * @var string|null - */ - protected $onDelete; + protected ?string $onDelete = null; public function __construct(string $table, ForeignKeyConstraint $foreignKeyConstraint) { diff --git a/src/DBAL/Models/DBALIndex.php b/src/DBAL/Models/DBALIndex.php index ee526bc7..af28a653 100644 --- a/src/DBAL/Models/DBALIndex.php +++ b/src/DBAL/Models/DBALIndex.php @@ -14,27 +14,18 @@ abstract class DBALIndex implements Index /** * @var string[] */ - protected $columns; + protected array $columns; /** * @var array */ - protected $lengths; + protected array $lengths; - /** - * @var string - */ - protected $name; + protected string $name; - /** - * @var string - */ - protected $tableName; + protected string $tableName; - /** - * @var \KitLoong\MigrationsGenerator\Enum\Migrations\Method\IndexType - */ - protected $type; + protected IndexType $type; /** * Create an index instance. diff --git a/src/DBAL/Models/DBALProcedure.php b/src/DBAL/Models/DBALProcedure.php index 7609be9c..33a06e5c 100644 --- a/src/DBAL/Models/DBALProcedure.php +++ b/src/DBAL/Models/DBALProcedure.php @@ -6,25 +6,10 @@ abstract class DBALProcedure implements Procedure { - /** - * @var string - */ - protected $name; - - /** - * @var string - */ - protected $definition; - - /** - * @var string - */ - protected $dropDefinition; + protected string $dropDefinition; - public function __construct(string $name, string $definition) + public function __construct(protected string $name, protected string $definition) { - $this->name = $name; - $this->definition = $definition; $this->dropDefinition = "DROP PROCEDURE IF EXISTS $name"; } diff --git a/src/DBAL/Models/DBALTable.php b/src/DBAL/Models/DBALTable.php index 64780d61..682c3b4c 100644 --- a/src/DBAL/Models/DBALTable.php +++ b/src/DBAL/Models/DBALTable.php @@ -14,35 +14,26 @@ abstract class DBALTable implements Table { - /** - * @var string|null - */ - protected $collation; + protected ?string $collation = null; /** * @var \Illuminate\Support\Collection */ - protected $columns; + protected Collection $columns; /** * @var \Illuminate\Support\Collection */ - protected $customColumns; + protected Collection $customColumns; - /** - * @var string - */ - protected $name; + protected string $name; - /** - * @var string|null - */ - protected $comment; + protected ?string $comment = null; /** * @var \Illuminate\Support\Collection */ - protected $indexes; + protected Collection $indexes; /** * Create a new instance. @@ -72,9 +63,7 @@ public function __construct(DoctrineDBALTable $table, array $columns, array $ind return $columns; }, new Collection())->values(); - $this->indexes = (new Collection($indexes))->map(function (DoctrineDBALIndex $index) use ($table) { - return $this->makeIndex($table->getName(), $index); - })->values(); + $this->indexes = (new Collection($indexes))->map(fn (DoctrineDBALIndex $index) => $this->makeIndex($table->getName(), $index))->values(); $this->handle(); } diff --git a/src/DBAL/Models/DBALView.php b/src/DBAL/Models/DBALView.php index ff805af8..cd9e6eb6 100644 --- a/src/DBAL/Models/DBALView.php +++ b/src/DBAL/Models/DBALView.php @@ -11,25 +11,13 @@ abstract class DBALView implements View { use AssetNameQuote; - /** - * @var string - */ - protected $name; + protected string $name; - /** - * @var string - */ - protected $quotedName; + protected string $quotedName; - /** - * @var string - */ - protected $definition; + protected string $definition; - /** - * @var string - */ - protected $dropDefinition; + protected string $dropDefinition; public function __construct(DoctrineDBALView $view) { diff --git a/src/DBAL/Models/MySQL/MySQLColumn.php b/src/DBAL/Models/MySQL/MySQLColumn.php index 4c68a838..b66485b0 100644 --- a/src/DBAL/Models/MySQL/MySQLColumn.php +++ b/src/DBAL/Models/MySQL/MySQLColumn.php @@ -16,15 +16,9 @@ class MySQLColumn extends DBALColumn { use CheckMigrationMethod; - /** - * @var \KitLoong\MigrationsGenerator\Repositories\MySQLRepository - */ - private $mysqlRepository; + private MySQLRepository $mysqlRepository; - /** - * @var \KitLoong\MigrationsGenerator\Repositories\MariaDBRepository - */ - private $mariaDBRepository; + private MariaDBRepository $mariaDBRepository; protected function handle(): void { @@ -132,7 +126,7 @@ private function getEnumPresetValues(): array { return $this->mysqlRepository->getEnumPresetValues( $this->tableName, - $this->name + $this->name, )->toArray(); } @@ -145,7 +139,7 @@ private function getSetPresetValues(): array { return $this->mysqlRepository->getSetPresetValues( $this->tableName, - $this->name + $this->name, )->toArray(); } diff --git a/src/DBAL/Models/PgSQL/PgSQLColumn.php b/src/DBAL/Models/PgSQL/PgSQLColumn.php index 639d3947..06f6e4dc 100644 --- a/src/DBAL/Models/PgSQL/PgSQLColumn.php +++ b/src/DBAL/Models/PgSQL/PgSQLColumn.php @@ -10,10 +10,7 @@ class PgSQLColumn extends DBALColumn { - /** - * @var \KitLoong\MigrationsGenerator\Repositories\PgSQLRepository - */ - private $repository; + private PgSQLRepository $repository; protected function handle(): void { diff --git a/src/DBAL/Models/PgSQL/PgSQLIndex.php b/src/DBAL/Models/PgSQL/PgSQLIndex.php index bd37e4bc..7a1a1a4a 100644 --- a/src/DBAL/Models/PgSQL/PgSQLIndex.php +++ b/src/DBAL/Models/PgSQL/PgSQLIndex.php @@ -12,10 +12,7 @@ class PgSQLIndex extends DBALIndex { use CheckMigrationMethod; - /** - * @var \KitLoong\MigrationsGenerator\Repositories\PgSQLRepository - */ - private $repository; + private PgSQLRepository $repository; protected function handle(): void { @@ -36,9 +33,7 @@ protected function handle(): void private function setTypeToSpatial(): void { $spatialNames = $this->repository->getSpatialIndexes($this->tableName) - ->map(function (IndexDefinition $indexDefinition) { - return $indexDefinition->getIndexName(); - }); + ->map(static fn (IndexDefinition $indexDefinition) => $indexDefinition->getIndexName()); if (!$spatialNames->contains($this->name)) { return; diff --git a/src/DBAL/Models/PgSQL/PgSQLTable.php b/src/DBAL/Models/PgSQL/PgSQLTable.php index 57cb788e..da962d22 100644 --- a/src/DBAL/Models/PgSQL/PgSQLTable.php +++ b/src/DBAL/Models/PgSQL/PgSQLTable.php @@ -13,8 +13,7 @@ class PgSQLTable extends DBALTable { - /** @var \KitLoong\MigrationsGenerator\Repositories\PgSQLRepository */ - private $repository; + private PgSQLRepository $repository; /** * @inheritDoc @@ -25,9 +24,7 @@ protected function handle(): void $this->pushFulltextIndexes(); - $this->indexes = $this->indexes->sortBy(function (Index $index) { - return $index->getName(); - })->values(); + $this->indexes = $this->indexes->sortBy(static fn (Index $index) => $index->getName())->values(); } /** @@ -65,7 +62,7 @@ private function pushFulltextIndexes(): void // Get "fulltext_custom" preg_match_all('/to_tsvector\((.*), \((.*)\)::text/U', $indexDefinition->getIndexDef(), $matches); - if (empty($matches[2])) { + if (!isset($matches[2])) { return; } @@ -80,9 +77,9 @@ private function pushFulltextIndexes(): void false, false, ['fulltext'], - [] - ) - ) + [], + ), + ), ); }); } diff --git a/src/DBAL/Models/SQLSrv/SQLSrvColumn.php b/src/DBAL/Models/SQLSrv/SQLSrvColumn.php index 7d0b53a3..d4054cec 100644 --- a/src/DBAL/Models/SQLSrv/SQLSrvColumn.php +++ b/src/DBAL/Models/SQLSrv/SQLSrvColumn.php @@ -19,10 +19,7 @@ class SQLSrvColumn extends DBALColumn private const TEXT_TYPE = 'nvarchar'; private const TEXT_LENGTH = -1; - /** - * @var \KitLoong\MigrationsGenerator\Repositories\SQLSrvRepository - */ - private $repository; + private SQLSrvRepository $repository; /** * @inheritDoc @@ -145,7 +142,7 @@ private function getEnumPresetValues(): array { return $this->repository->getEnumPresetValues( $this->tableName, - $this->name + $this->name, )->toArray(); } } diff --git a/src/DBAL/Models/SQLSrv/SQLSrvIndex.php b/src/DBAL/Models/SQLSrv/SQLSrvIndex.php index 92651e42..0d84d8f4 100644 --- a/src/DBAL/Models/SQLSrv/SQLSrvIndex.php +++ b/src/DBAL/Models/SQLSrv/SQLSrvIndex.php @@ -10,10 +10,7 @@ class SQLSrvIndex extends DBALIndex { - /** - * @var \KitLoong\MigrationsGenerator\Repositories\SQLSrvRepository - */ - private $repository; + private SQLSrvRepository $repository; protected function handle(): void { diff --git a/src/DBAL/Models/SQLite/SQLiteColumn.php b/src/DBAL/Models/SQLite/SQLiteColumn.php index 670bb2d9..7033c1c8 100644 --- a/src/DBAL/Models/SQLite/SQLiteColumn.php +++ b/src/DBAL/Models/SQLite/SQLiteColumn.php @@ -13,10 +13,7 @@ class SQLiteColumn extends DBALColumn { use CheckMigrationMethod; - /** - * @var \KitLoong\MigrationsGenerator\Repositories\SQLiteRepository - */ - private $repository; + private SQLiteRepository $repository; /** * @inheritDoc diff --git a/src/DBAL/MySQLSchema.php b/src/DBAL/MySQLSchema.php index 67369a11..aa9790b0 100644 --- a/src/DBAL/MySQLSchema.php +++ b/src/DBAL/MySQLSchema.php @@ -20,16 +20,9 @@ */ class MySQLSchema extends DBALSchema implements MySQLSchemaInterface { - /** - * @var \KitLoong\MigrationsGenerator\Repositories\MySQLRepository - */ - private $mySQLRepository; - - public function __construct(RegisterColumnType $registerColumnType, MySQLRepository $mySQLRepository) + public function __construct(RegisterColumnType $registerColumnType, private MySQLRepository $mySQLRepository) { parent::__construct($registerColumnType); - - $this->mySQLRepository = $mySQLRepository; } /** @@ -41,7 +34,7 @@ public function getTable(string $name): Table return new MySQLTable( $this->introspectTable($name), $this->dbalSchema->listTableColumns($name), - $this->dbalSchema->listTableIndexes($name) + $this->dbalSchema->listTableIndexes($name), ); } @@ -51,9 +44,7 @@ public function getTable(string $name): Table */ public function getViewNames(): Collection { - return $this->getViews()->map(function (View $view) { - return $view->getName(); - }); + return $this->getViews()->map(static fn (View $view) => $view->getName()); } /** @@ -63,9 +54,7 @@ public function getViewNames(): Collection public function getViews(): Collection { return (new Collection($this->dbalSchema->listViews())) - ->map(function (DoctrineDBALView $view) { - return new MySQLView($view); - }); + ->map(static fn (DoctrineDBALView $view) => new MySQLView($view)); } /** @@ -74,9 +63,7 @@ public function getViews(): Collection public function getProcedures(): Collection { return (new Collection($this->mySQLRepository->getProcedures())) - ->map(function (ProcedureDefinition $procedureDefinition) { - return new MySQLProcedure($procedureDefinition->getName(), $procedureDefinition->getDefinition()); - }); + ->map(static fn (ProcedureDefinition $procedureDefinition) => new MySQLProcedure($procedureDefinition->getName(), $procedureDefinition->getDefinition())); } /** @@ -87,8 +74,6 @@ public function getTableForeignKeys(string $table): Collection { // @phpstan-ignore-next-line return (new Collection($this->dbalSchema->listTableForeignKeys($table))) - ->map(function (ForeignKeyConstraint $foreignKeyConstraint) use ($table) { - return new MySQLForeignKey($table, $foreignKeyConstraint); - }); + ->map(static fn (ForeignKeyConstraint $foreignKeyConstraint) => new MySQLForeignKey($table, $foreignKeyConstraint)); } } diff --git a/src/DBAL/PgSQLSchema.php b/src/DBAL/PgSQLSchema.php index 61db4e73..477a7a32 100644 --- a/src/DBAL/PgSQLSchema.php +++ b/src/DBAL/PgSQLSchema.php @@ -20,16 +20,9 @@ */ class PgSQLSchema extends DBALSchema { - /** - * @var \KitLoong\MigrationsGenerator\Repositories\PgSQLRepository - */ - private $pgSQLRepository; - - public function __construct(RegisterColumnType $registerColumnType, PgSQLRepository $pgSQLRepository) + public function __construct(RegisterColumnType $registerColumnType, private PgSQLRepository $pgSQLRepository) { parent::__construct($registerColumnType); - - $this->pgSQLRepository = $pgSQLRepository; } /** @@ -38,7 +31,7 @@ public function __construct(RegisterColumnType $registerColumnType, PgSQLReposit public function getTableNames(): Collection { return parent::getTableNames() - ->filter(function (string $table): bool { + ->filter(static function (string $table): bool { // Checks if the table is from user defined "schema". // If table name do not have namespace, it is using the default namespace. if (strpos($table, '.') === false) { @@ -65,7 +58,7 @@ public function getTable(string $name): Table return new PgSQLTable( $this->introspectTable($name), $this->dbalSchema->listTableColumns($name), - $this->dbalSchema->listTableIndexes($name) + $this->dbalSchema->listTableIndexes($name), ); } @@ -76,9 +69,7 @@ public function getTable(string $name): Table public function getViewNames(): Collection { return $this->getViews() - ->map(function (View $view) { - return $view->getName(); - }); + ->map(static fn (View $view) => $view->getName()); } /** @@ -88,7 +79,7 @@ public function getViewNames(): Collection public function getViews(): Collection { return (new Collection($this->dbalSchema->listViews())) - ->filter(function (DoctrineDBALView $view) { + ->filter(static function (DoctrineDBALView $view) { if (in_array($view->getName(), ['public.geography_columns', 'public.geometry_columns'])) { return false; } @@ -99,9 +90,7 @@ public function getViews(): Collection return $view->getNamespaceName() === $searchPath; }) - ->map(function (DoctrineDBALView $view) { - return new PgSQLView($view); - }) + ->map(static fn (DoctrineDBALView $view) => new PgSQLView($view)) ->values(); } @@ -111,9 +100,7 @@ public function getViews(): Collection public function getProcedures(): Collection { return (new Collection($this->pgSQLRepository->getProcedures())) - ->map(function (ProcedureDefinition $procedureDefinition) { - return new PgSQLProcedure($procedureDefinition->getName(), $procedureDefinition->getDefinition()); - }); + ->map(static fn (ProcedureDefinition $procedureDefinition) => new PgSQLProcedure($procedureDefinition->getName(), $procedureDefinition->getDefinition())); } /** @@ -124,8 +111,6 @@ public function getTableForeignKeys(string $table): Collection { // @phpstan-ignore-next-line return (new Collection($this->dbalSchema->listTableForeignKeys($table))) - ->map(function (ForeignKeyConstraint $foreignKeyConstraint) use ($table) { - return new PgSQLForeignKey($table, $foreignKeyConstraint); - }); + ->map(static fn (ForeignKeyConstraint $foreignKeyConstraint) => new PgSQLForeignKey($table, $foreignKeyConstraint)); } } diff --git a/src/DBAL/RegisterColumnType.php b/src/DBAL/RegisterColumnType.php index 7a8bfff7..639e3507 100644 --- a/src/DBAL/RegisterColumnType.php +++ b/src/DBAL/RegisterColumnType.php @@ -16,20 +16,8 @@ class RegisterColumnType { - /** - * @var \KitLoong\MigrationsGenerator\Repositories\PgSQLRepository - */ - private $pgSQLRepository; - - /** - * @var \KitLoong\MigrationsGenerator\Repositories\SQLSrvRepository - */ - private $sqlSrvRepository; - - public function __construct(PgSQLRepository $pgSQLRepository, SQLSrvRepository $sqlSrvRepository) + public function __construct(private PgSQLRepository $pgSQLRepository, private SQLSrvRepository $sqlSrvRepository) { - $this->pgSQLRepository = $pgSQLRepository; - $this->sqlSrvRepository = $sqlSrvRepository; } /** @@ -106,10 +94,7 @@ private function registerLaravelCustomColumnType(): void { foreach ($this->getCustomTypes() as $type) { $customType = new class () extends CustomType { - /** - * @var string - */ - public $type = ''; + public string $type = ''; /** * @inheritDoc diff --git a/src/DBAL/SQLSrvSchema.php b/src/DBAL/SQLSrvSchema.php index a9df01b4..296c03d0 100644 --- a/src/DBAL/SQLSrvSchema.php +++ b/src/DBAL/SQLSrvSchema.php @@ -19,16 +19,9 @@ */ class SQLSrvSchema extends DBALSchema { - /** - * @var \KitLoong\MigrationsGenerator\Repositories\SQLSrvRepository - */ - private $sqlSrvRepository; - - public function __construct(RegisterColumnType $registerColumnType, SQLSrvRepository $sqlSrvRepository) + public function __construct(RegisterColumnType $registerColumnType, private SQLSrvRepository $sqlSrvRepository) { parent::__construct($registerColumnType); - - $this->sqlSrvRepository = $sqlSrvRepository; } /** @@ -40,7 +33,7 @@ public function getTable(string $name): Table return new SQLSrvTable( $this->introspectTable($name), $this->dbalSchema->listTableColumns($name), - $this->dbalSchema->listTableIndexes($name) + $this->dbalSchema->listTableIndexes($name), ); } @@ -50,9 +43,7 @@ public function getTable(string $name): Table */ public function getViewNames(): Collection { - return $this->getViews()->map(function (View $view) { - return $view->getName(); - }); + return $this->getViews()->map(static fn (View $view) => $view->getName()); } /** @@ -62,13 +53,8 @@ public function getViewNames(): Collection public function getViews(): Collection { return (new Collection($this->dbalSchema->listViews())) - ->map(function (DoctrineDBALView $view) { - return new SQLSrvView($view); - }) - ->filter(function (SQLSrvView $view) { - // `$view->getDefinition()` is empty string if the view definition is encrypted. - return $view->getDefinition() !== ''; - }); + ->map(static fn (DoctrineDBALView $view) => new SQLSrvView($view)) + ->filter(static fn (SQLSrvView $view) => $view->getDefinition() !== ''); } /** @@ -77,9 +63,7 @@ public function getViews(): Collection public function getProcedures(): Collection { return (new Collection($this->sqlSrvRepository->getProcedures())) - ->map(function (ProcedureDefinition $procedureDefinition) { - return new PgSQLProcedure($procedureDefinition->getName(), $procedureDefinition->getDefinition()); - }); + ->map(static fn (ProcedureDefinition $procedureDefinition) => new PgSQLProcedure($procedureDefinition->getName(), $procedureDefinition->getDefinition())); } /** @@ -90,8 +74,6 @@ public function getTableForeignKeys(string $table): Collection { // @phpstan-ignore-next-line return (new Collection($this->dbalSchema->listTableForeignKeys($table))) - ->map(function (ForeignKeyConstraint $foreignKeyConstraint) use ($table) { - return new SQLSrvForeignKey($table, $foreignKeyConstraint); - }); + ->map(static fn (ForeignKeyConstraint $foreignKeyConstraint) => new SQLSrvForeignKey($table, $foreignKeyConstraint)); } } diff --git a/src/DBAL/SQLiteSchema.php b/src/DBAL/SQLiteSchema.php index e9d534d6..4c2654ea 100644 --- a/src/DBAL/SQLiteSchema.php +++ b/src/DBAL/SQLiteSchema.php @@ -25,7 +25,7 @@ public function getTable(string $name): Table return new SQLiteTable( $this->introspectTable($name), $this->dbalSchema->listTableColumns($name), - $this->dbalSchema->listTableIndexes($name) + $this->dbalSchema->listTableIndexes($name), ); } @@ -35,9 +35,7 @@ public function getTable(string $name): Table */ public function getViewNames(): Collection { - return $this->getViews()->map(function (View $view) { - return $view->getName(); - }); + return $this->getViews()->map(static fn (View $view) => $view->getName()); } /** @@ -47,9 +45,7 @@ public function getViewNames(): Collection public function getViews(): Collection { return (new Collection($this->dbalSchema->listViews())) - ->map(function (DoctrineDBALView $view) { - return new SQLiteView($view); - }); + ->map(static fn (DoctrineDBALView $view) => new SQLiteView($view)); } /** @@ -70,8 +66,6 @@ public function getTableForeignKeys(string $table): Collection { // @phpstan-ignore-next-line return (new Collection($this->dbalSchema->listTableForeignKeys($table))) - ->map(function (ForeignKeyConstraint $foreignKeyConstraint) use ($table) { - return new SQLiteForeignKey($table, $foreignKeyConstraint); - }); + ->map(static fn (ForeignKeyConstraint $foreignKeyConstraint) => new SQLiteForeignKey($table, $foreignKeyConstraint)); } } diff --git a/src/DBAL/Types/Types.php b/src/DBAL/Types/Types.php index d4f21f6b..43a9a23a 100644 --- a/src/DBAL/Types/Types.php +++ b/src/DBAL/Types/Types.php @@ -93,6 +93,6 @@ final class Types public static function toColumnType(Type $dbalType): ColumnType { $map = self::BUILTIN_TYPES_MAP + self::ADDITIONAL_TYPES_MAP; - return ColumnType::fromValue($map[get_class($dbalType)]); + return ColumnType::fromValue($map[$dbalType::class]); } } diff --git a/src/MigrateGenerateCommand.php b/src/MigrateGenerateCommand.php index 577cd2e1..ef1cddc1 100644 --- a/src/MigrateGenerateCommand.php +++ b/src/MigrateGenerateCommand.php @@ -31,9 +31,8 @@ class MigrateGenerateCommand extends Command /** * The name and signature of the console command. - * - * @var string */ + // phpcs:ignore protected $signature = 'migrate:generate {tables? : A list of tables or views you wish to generate migrations for separated by a comma: users,posts,comments} {--c|connection= : The database connection to use} @@ -59,72 +58,25 @@ class MigrateGenerateCommand extends Command /** * The console command description. - * - * @var string */ + // phpcs:ignore protected $description = 'Generate migrations from an existing table structure.'; - /** - * @var \KitLoong\MigrationsGenerator\Schema\Schema - */ - protected $schema; - - /** - * @var bool - */ - protected $shouldLog = false; - - /** - * @var int - */ - protected $nextBatchNumber = 0; + protected Schema $schema; - /** - * @var \Illuminate\Database\Migrations\MigrationRepositoryInterface - */ - protected $repository; + protected bool $shouldLog = false; - /** - * @var \KitLoong\MigrationsGenerator\Migration\Squash - */ - protected $squash; - - /** - * @var \KitLoong\MigrationsGenerator\Migration\ForeignKeyMigration - */ - protected $foreignKeyMigration; - - /** - * @var \KitLoong\MigrationsGenerator\Migration\ProcedureMigration - */ - protected $procedureMigration; - - /** - * @var \KitLoong\MigrationsGenerator\Migration\TableMigration - */ - protected $tableMigration; - - /** - * @var \KitLoong\MigrationsGenerator\Migration\ViewMigration - */ - protected $viewMigration; + protected int $nextBatchNumber = 0; public function __construct( - MigrationRepositoryInterface $repository, - Squash $squash, - ForeignKeyMigration $foreignKeyMigration, - ProcedureMigration $procedureMigration, - TableMigration $tableMigration, - ViewMigration $viewMigration + protected MigrationRepositoryInterface $repository, + protected Squash $squash, + protected ForeignKeyMigration $foreignKeyMigration, + protected ProcedureMigration $procedureMigration, + protected TableMigration $tableMigration, + protected ViewMigration $viewMigration, ) { parent::__construct(); - - $this->squash = $squash; - $this->repository = $repository; - $this->foreignKeyMigration = $foreignKeyMigration; - $this->procedureMigration = $procedureMigration; - $this->tableMigration = $tableMigration; - $this->viewMigration = $viewMigration; } /** @@ -187,29 +139,29 @@ protected function setup(string $connection): void $setting->setWithHasTable((bool) $this->option('with-has-table')); $setting->setPath( - $this->option('path') ?? Config::get('migrations-generator.migration_target_path') + $this->option('path') ?? Config::get('migrations-generator.migration_target_path'), ); $this->setStubPath($setting); $setting->setDate( - $this->option('date') ? Carbon::parse($this->option('date')) : Carbon::now() + $this->option('date') ? Carbon::parse($this->option('date')) : Carbon::now(), ); $setting->setTableFilename( - $this->option('table-filename') ?? Config::get('migrations-generator.filename_pattern.table') + $this->option('table-filename') ?? Config::get('migrations-generator.filename_pattern.table'), ); $setting->setViewFilename( - $this->option('view-filename') ?? Config::get('migrations-generator.filename_pattern.view') + $this->option('view-filename') ?? Config::get('migrations-generator.filename_pattern.view'), ); $setting->setProcedureFilename( - $this->option('proc-filename') ?? Config::get('migrations-generator.filename_pattern.procedure') + $this->option('proc-filename') ?? Config::get('migrations-generator.filename_pattern.procedure'), ); $setting->setFkFilename( - $this->option('fk-filename') ?? Config::get('migrations-generator.filename_pattern.foreign_key') + $this->option('fk-filename') ?? Config::get('migrations-generator.filename_pattern.foreign_key'), ); } @@ -225,7 +177,7 @@ protected function setStubPath(Setting $setting): void } $setting->setStubPath( - $this->option('template-path') ?? $defaultStub + $this->option('template-path') ?? $defaultStub, ); } @@ -303,7 +255,7 @@ protected function getExcludedTables(): array $excludes = [$migrationTable]; $ignore = (string) $this->option('ignore'); - if (!empty($ignore)) { + if ($ignore !== '') { $excludes = array_merge($excludes, explode(',', $ignore)); } @@ -338,7 +290,7 @@ protected function askIfLogMigrationTable(string $defaultConnection): void if ( !$this->confirm( 'Log into current connection: ' . DB::getName() . '? [Y = ' . DB::getName() . ', n = ' . $defaultConnection . ' (default connection)]', - true + true, ) ) { $this->repository->setSource($defaultConnection); @@ -351,7 +303,7 @@ protected function askIfLogMigrationTable(string $defaultConnection): void $this->nextBatchNumber = $this->askInt( 'Next Batch Number is: ' . $this->repository->getNextBatchNumber() . '. We recommend using Batch Number 0 so that it becomes the "first" migration.', - 0 + 0, ); } @@ -502,7 +454,7 @@ protected function generateTables(Collection $tables): void { $tables->each(function (string $table): void { $path = $this->tableMigration->write( - $this->schema->getTable($table) + $this->schema->getTable($table), ); $this->info("Created: $path"); @@ -524,7 +476,7 @@ protected function generateTablesToTemp(Collection $tables): void { $tables->each(function (string $table): void { $this->tableMigration->writeToTemp( - $this->schema->getTable($table) + $this->schema->getTable($table), ); $this->info("Prepared: $table"); @@ -623,7 +575,7 @@ protected function generateForeignKeys(Collection $tables): void $path = $this->foreignKeyMigration->write( $table, - $foreignKeys + $foreignKeys, ); $this->info("Created: $path"); @@ -652,7 +604,7 @@ protected function generateForeignKeysToTemp(Collection $tables): void $this->foreignKeyMigration->writeToTemp( $table, - $foreignKeys + $foreignKeys, ); $this->info('Prepared: ' . $table); diff --git a/src/Migration/Blueprint/DBStatementBlueprint.php b/src/Migration/Blueprint/DBStatementBlueprint.php index 41dda22f..30e6a4da 100644 --- a/src/Migration/Blueprint/DBStatementBlueprint.php +++ b/src/Migration/Blueprint/DBStatementBlueprint.php @@ -23,19 +23,13 @@ class DBStatementBlueprint implements WritableBlueprint use Stringable; use MethodStringHelper; - /** - * @var string - */ - private $sql; - /** * DBStatementBlueprint constructor. * * @param string $sql The SQL statement. */ - public function __construct(string $sql) + public function __construct(private string $sql) { - $this->sql = $sql; } /** diff --git a/src/Migration/Blueprint/DBUnpreparedBlueprint.php b/src/Migration/Blueprint/DBUnpreparedBlueprint.php index 5b60cfdb..fdce7c2b 100644 --- a/src/Migration/Blueprint/DBUnpreparedBlueprint.php +++ b/src/Migration/Blueprint/DBUnpreparedBlueprint.php @@ -23,19 +23,13 @@ class DBUnpreparedBlueprint implements WritableBlueprint use Stringable; use MethodStringHelper; - /** - * @var string - */ - private $sql; - /** * DBStatementBlueprint constructor. * * @param string $sql The SQL statement. */ - public function __construct(string $sql) + public function __construct(private string $sql) { - $this->sql = $sql; } /** diff --git a/src/Migration/Blueprint/Method.php b/src/Migration/Blueprint/Method.php index df3d0837..727105e0 100644 --- a/src/Migration/Blueprint/Method.php +++ b/src/Migration/Blueprint/Method.php @@ -4,14 +4,11 @@ class Method { - /** @var string */ - private $name; - /** @var mixed[] */ - private $values; + private array $values; /** @var \KitLoong\MigrationsGenerator\Migration\Blueprint\Method[] */ - private $chains; + private array $chains; /** * Method constructor. @@ -19,9 +16,8 @@ class Method * @param string $name Method name. * @param mixed ...$values Method arguments. */ - public function __construct(string $name, ...$values) + public function __construct(private string $name, mixed ...$values) { - $this->name = $name; $this->values = $values; $this->chains = []; } @@ -46,7 +42,7 @@ public function getValues(): array * @param mixed ...$values Method arguments. * @return $this */ - public function chain(string $name, ...$values): self + public function chain(string $name, mixed ...$values): self { $this->chains[] = new self($name, ...$values); return $this; diff --git a/src/Migration/Blueprint/Property.php b/src/Migration/Blueprint/Property.php index bbd26ba2..f213accf 100644 --- a/src/Migration/Blueprint/Property.php +++ b/src/Migration/Blueprint/Property.php @@ -4,21 +4,11 @@ class Property { - /** @var string */ - private $name; - - /** @var mixed */ - private $value; - /** * Property constructor. - * - * @param mixed $value */ - public function __construct(string $name, $value) + public function __construct(private string $name, private mixed $value) { - $this->name = $name; - $this->value = $value; } public function getName(): string @@ -26,10 +16,7 @@ public function getName(): string return $this->name; } - /** - * @return mixed - */ - public function getValue() + public function getValue(): mixed { return $this->value; } diff --git a/src/Migration/Blueprint/SchemaBlueprint.php b/src/Migration/Blueprint/SchemaBlueprint.php index ae623d5b..d915658b 100644 --- a/src/Migration/Blueprint/SchemaBlueprint.php +++ b/src/Migration/Blueprint/SchemaBlueprint.php @@ -39,18 +39,10 @@ class SchemaBlueprint implements WritableBlueprint /** * The table name without prefix. {@see \Illuminate\Support\Facades\DB::getTablePrefix()} - * - * @var string - */ - private $table; - - /** - * @var \KitLoong\MigrationsGenerator\Enum\Migrations\Method\SchemaBuilder */ - private $schemaBuilder; + private string $table; - /** @var \KitLoong\MigrationsGenerator\Migration\Blueprint\TableBlueprint|null */ - private $blueprint; + private ?TableBlueprint $blueprint = null; /** * SchemaBlueprint constructor. @@ -58,11 +50,10 @@ class SchemaBlueprint implements WritableBlueprint * @param string $table Table name. * @param \KitLoong\MigrationsGenerator\Enum\Migrations\Method\SchemaBuilder $schemaBuilder SchemaBuilder name. */ - public function __construct(string $table, SchemaBuilder $schemaBuilder) + public function __construct(string $table, private SchemaBuilder $schemaBuilder) { - $this->table = $this->stripTablePrefix($table); - $this->schemaBuilder = $schemaBuilder; - $this->blueprint = null; + $this->table = $this->stripTablePrefix($table); + $this->blueprint = null; } public function setBlueprint(TableBlueprint $blueprint): void diff --git a/src/Migration/Blueprint/Support/MergeTimestamps.php b/src/Migration/Blueprint/Support/MergeTimestamps.php index 4e18b4dc..a8e0106f 100644 --- a/src/Migration/Blueprint/Support/MergeTimestamps.php +++ b/src/Migration/Blueprint/Support/MergeTimestamps.php @@ -85,7 +85,7 @@ private function checkTimestamps(ColumnName $columnName, Method $method, bool $t } return $method->getChains()[0]->getName() === ColumnModifier::NULLABLE()->getValue() - && empty($method->getChains()[0]->getValues()); + && count($method->getChains()[0]->getValues()) === 0; } /** diff --git a/src/Migration/Blueprint/Support/Stringable.php b/src/Migration/Blueprint/Support/Stringable.php index ca6cccdd..7bdbe5ef 100644 --- a/src/Migration/Blueprint/Support/Stringable.php +++ b/src/Migration/Blueprint/Support/Stringable.php @@ -34,10 +34,8 @@ public function flattenLines(array $lines, int $numberOfPrefixTab): string /** * Convert $value to printable string. - * - * @param mixed $value */ - public function convertFromAnyTypeToString($value): string + public function convertFromAnyTypeToString(mixed $value): string { switch (gettype($value)) { case 'string': @@ -90,8 +88,6 @@ public function escapeDoubleQuote(string $string): string */ public function mapArrayItemsToString(array $list): array { - return (new Collection($list))->map(function ($v) { - return $this->convertFromAnyTypeToString($v); - })->toArray(); + return (new Collection($list))->map(fn ($v) => $this->convertFromAnyTypeToString($v))->toArray(); } } diff --git a/src/Migration/Blueprint/TableBlueprint.php b/src/Migration/Blueprint/TableBlueprint.php index 71e0d062..6352bbc5 100644 --- a/src/Migration/Blueprint/TableBlueprint.php +++ b/src/Migration/Blueprint/TableBlueprint.php @@ -34,14 +34,12 @@ class TableBlueprint implements WritableBlueprint use Stringable; /** @var \KitLoong\MigrationsGenerator\Migration\Blueprint\Property[]|\KitLoong\MigrationsGenerator\Migration\Blueprint\Method[]|string[] */ - private $lines; + private array $lines; /** * By default, generate 3 tabs for each line. - * - * @var int */ - private $numberOfPrefixTab = 3; + private int $numberOfPrefixTab = 3; public function __construct() { @@ -50,9 +48,8 @@ public function __construct() /** * @param string $name Property name. - * @param mixed $value */ - public function setProperty(string $name, $value): Property + public function setProperty(string $name, mixed $value): Property { $property = new Property($name, $value); $this->lines[] = $property; @@ -63,7 +60,7 @@ public function setProperty(string $name, $value): Property * @param string $name Method name. * @param mixed ...$values Method arguments. */ - public function setMethodByName(string $name, ...$values): Method + public function setMethodByName(string $name, mixed ...$values): Method { $method = new Method($name, ...$values); $this->lines[] = $method; @@ -81,10 +78,7 @@ public function setLineBreak(): void $this->lines[] = Space::LINE_BREAK(); } - /** - * @return \KitLoong\MigrationsGenerator\Migration\Blueprint\Method|\KitLoong\MigrationsGenerator\Migration\Blueprint\Property|string|null - */ - public function removeLastLine() + public function removeLastLine(): Method|Property|string|null { return array_pop($this->lines); } @@ -181,9 +175,7 @@ private function methodToString(Method $method): string */ private function flattenMethod(Method $method): string { - $v = (new Collection($method->getValues()))->map(function ($v) { - return $this->convertFromAnyTypeToString($v); - })->implode(', '); + $v = (new Collection($method->getValues()))->map(fn ($v) => $this->convertFromAnyTypeToString($v))->implode(', '); return $method->getName() . "($v)"; } } diff --git a/src/Migration/ForeignKeyMigration.php b/src/Migration/ForeignKeyMigration.php index e421f0d9..a892d8df 100644 --- a/src/Migration/ForeignKeyMigration.php +++ b/src/Migration/ForeignKeyMigration.php @@ -18,43 +18,13 @@ class ForeignKeyMigration { use TableName; - /** - * @var \KitLoong\MigrationsGenerator\Migration\Generator\ForeignKeyGenerator - */ - private $foreignKeyGenerator; - - /** - * @var \KitLoong\MigrationsGenerator\Support\MigrationNameHelper - */ - private $migrationNameHelper; - - /** - * @var \KitLoong\MigrationsGenerator\Migration\Writer\MigrationWriter - */ - private $migrationWriter; - - /** - * @var \KitLoong\MigrationsGenerator\Setting - */ - private $setting; - - /** - * @var \KitLoong\MigrationsGenerator\Migration\Writer\SquashWriter - */ - private $squashWriter; - public function __construct( - ForeignKeyGenerator $foreignKeyGenerator, - MigrationNameHelper $migrationNameHelper, - MigrationWriter $migrationWriter, - Setting $setting, - SquashWriter $squashWriter + private ForeignKeyGenerator $foreignKeyGenerator, + private MigrationNameHelper $migrationNameHelper, + private MigrationWriter $migrationWriter, + private Setting $setting, + private SquashWriter $squashWriter, ) { - $this->foreignKeyGenerator = $foreignKeyGenerator; - $this->migrationNameHelper = $migrationNameHelper; - $this->migrationWriter = $migrationWriter; - $this->setting = $setting; - $this->squashWriter = $squashWriter; } /** @@ -74,7 +44,7 @@ public function write(string $table, Collection $foreignKeys): string $this->makeMigrationClassName($table), new Collection([$up]), new Collection([$down]), - MigrationFileType::FOREIGN_KEY() + MigrationFileType::FOREIGN_KEY(), ); return $path; @@ -143,7 +113,7 @@ private function makeMigrationClassName(string $table): string $withoutPrefix = $this->stripTablePrefix($table); return $this->migrationNameHelper->makeClassName( $this->setting->getFkFilename(), - $withoutPrefix + $withoutPrefix, ); } @@ -158,7 +128,7 @@ private function makeMigrationPath(string $table): string return $this->migrationNameHelper->makeFilename( $this->setting->getFkFilename(), $this->setting->getDateForMigrationFilename(), - $withoutPrefix + $withoutPrefix, ); } @@ -166,7 +136,7 @@ private function getSchemaBlueprint(string $table): SchemaBlueprint { return new SchemaBlueprint( $table, - SchemaBuilder::TABLE() + SchemaBuilder::TABLE(), ); } } diff --git a/src/Migration/Generator/ColumnGenerator.php b/src/Migration/Generator/ColumnGenerator.php index 254cd438..9122750c 100644 --- a/src/Migration/Generator/ColumnGenerator.php +++ b/src/Migration/Generator/ColumnGenerator.php @@ -18,64 +18,16 @@ class ColumnGenerator { - /** - * @var \KitLoong\MigrationsGenerator\Migration\Generator\Modifiers\CharsetModifier - */ - private $charsetModifier; - - /** - * @var \KitLoong\MigrationsGenerator\Migration\Generator\Modifiers\CollationModifier - */ - private $collationModifier; - - /** - * @var \KitLoong\MigrationsGenerator\Migration\Generator\Modifiers\CommentModifier - */ - private $commentModifier; - - /** - * @var \KitLoong\MigrationsGenerator\Migration\Generator\Modifiers\DefaultModifier - */ - private $defaultModifier; - - /** - * @var \KitLoong\MigrationsGenerator\Migration\Generator\Modifiers\IndexModifier - */ - private $indexModifier; - - /** - * @var \KitLoong\MigrationsGenerator\Migration\Generator\Modifiers\NullableModifier - */ - private $nullableModifier; - - /** - * @var \KitLoong\MigrationsGenerator\Migration\Generator\Modifiers\StoredAsModifier - */ - private $storedAsModifier; - - /** - * @var \KitLoong\MigrationsGenerator\Migration\Generator\Modifiers\VirtualAsModifier - */ - private $virtualAsModifier; - public function __construct( - CharsetModifier $charsetModifier, - CollationModifier $collationModifier, - CommentModifier $commentModifier, - DefaultModifier $defaultModifier, - IndexModifier $indexModifier, - NullableModifier $nullableModifier, - StoredAsModifier $storedAsModifier, - VirtualAsModifier $virtualAsModifier + private CharsetModifier $charsetModifier, + private CollationModifier $collationModifier, + private CommentModifier $commentModifier, + private DefaultModifier $defaultModifier, + private IndexModifier $indexModifier, + private NullableModifier $nullableModifier, + private StoredAsModifier $storedAsModifier, + private VirtualAsModifier $virtualAsModifier, ) { - $this->charsetModifier = $charsetModifier; - $this->collationModifier = $collationModifier; - $this->commentModifier = $commentModifier; - $this->defaultModifier = $defaultModifier; - $this->indexModifier = $indexModifier; - $this->nullableModifier = $nullableModifier; - $this->storedAsModifier = $storedAsModifier; - $this->virtualAsModifier = $virtualAsModifier; } /** diff --git a/src/Migration/Generator/ForeignKeyGenerator.php b/src/Migration/Generator/ForeignKeyGenerator.php index 6f7db098..fe01dc0b 100644 --- a/src/Migration/Generator/ForeignKeyGenerator.php +++ b/src/Migration/Generator/ForeignKeyGenerator.php @@ -63,7 +63,7 @@ private function shouldSkipName(ForeignKey $foreignKey): bool private function makeLaravelForeignKeyName(ForeignKey $foreignKey): string { $name = strtolower( - $foreignKey->getTableName() . '_' . implode('_', $foreignKey->getLocalColumns()) . '_foreign' + $foreignKey->getTableName() . '_' . implode('_', $foreignKey->getLocalColumns()) . '_foreign', ); return str_replace(['-', '.'], '_', $name); } diff --git a/src/Migration/Generator/IndexGenerator.php b/src/Migration/Generator/IndexGenerator.php index 63873ac9..c93dae42 100644 --- a/src/Migration/Generator/IndexGenerator.php +++ b/src/Migration/Generator/IndexGenerator.php @@ -11,14 +11,8 @@ class IndexGenerator { - /** - * @var \KitLoong\MigrationsGenerator\Support\IndexNameHelper - */ - private $indexNameHelper; - - public function __construct(IndexNameHelper $indexNameHelper) + public function __construct(private IndexNameHelper $indexNameHelper) { - $this->indexNameHelper = $indexNameHelper; } public function generate(Table $table, Index $index): Method @@ -99,13 +93,9 @@ public function getChainableIndexes(string $name, Collection $indexes): Collecti */ public function getNotChainableIndexes(Collection $indexes, Collection $chainableIndexes): Collection { - $chainableNames = $chainableIndexes->map(function (Index $index) { - return $index->getName(); - }); + $chainableNames = $chainableIndexes->map(static fn (Index $index) => $index->getName()); - return $indexes->filter(function (Index $index) use ($chainableNames) { - return !$chainableNames->contains($index->getName()); - }); + return $indexes->filter(static fn (Index $index) => !$chainableNames->contains($index->getName())); } /** diff --git a/src/Migration/Generator/Modifiers/CharsetModifier.php b/src/Migration/Generator/Modifiers/CharsetModifier.php index bd8961e3..c4912b1e 100644 --- a/src/Migration/Generator/Modifiers/CharsetModifier.php +++ b/src/Migration/Generator/Modifiers/CharsetModifier.php @@ -11,20 +11,14 @@ class CharsetModifier implements Modifier { - /** - * @var \KitLoong\MigrationsGenerator\Setting - */ - private $setting; - - public function __construct(Setting $setting) + public function __construct(private Setting $setting) { - $this->setting = $setting; } /** * @inheritDoc */ - public function chain(Method $method, Table $table, Column $column, ...$args): Method + public function chain(Method $method, Table $table, Column $column, mixed ...$args): Method { if (!$this->setting->isUseDBCollation()) { return $method; diff --git a/src/Migration/Generator/Modifiers/CollationModifier.php b/src/Migration/Generator/Modifiers/CollationModifier.php index 6d39a35e..9d1cc871 100644 --- a/src/Migration/Generator/Modifiers/CollationModifier.php +++ b/src/Migration/Generator/Modifiers/CollationModifier.php @@ -10,20 +10,14 @@ class CollationModifier implements Modifier { - /** - * @var \KitLoong\MigrationsGenerator\Setting - */ - private $setting; - - public function __construct(Setting $setting) + public function __construct(private Setting $setting) { - $this->setting = $setting; } /** * @inheritDoc */ - public function chain(Method $method, Table $table, Column $column, ...$args): Method + public function chain(Method $method, Table $table, Column $column, mixed ...$args): Method { if (!$this->setting->isUseDBCollation()) { return $method; diff --git a/src/Migration/Generator/Modifiers/CommentModifier.php b/src/Migration/Generator/Modifiers/CommentModifier.php index 33cec84b..e1b0e17e 100644 --- a/src/Migration/Generator/Modifiers/CommentModifier.php +++ b/src/Migration/Generator/Modifiers/CommentModifier.php @@ -12,7 +12,7 @@ class CommentModifier implements Modifier /** * @inheritDoc */ - public function chain(Method $method, Table $table, Column $column, ...$args): Method + public function chain(Method $method, Table $table, Column $column, mixed ...$args): Method { if ($column->getComment() !== null) { $method->chain(ColumnModifier::COMMENT(), $column->getComment()); diff --git a/src/Migration/Generator/Modifiers/DefaultModifier.php b/src/Migration/Generator/Modifiers/DefaultModifier.php index e749c4b0..5d713385 100644 --- a/src/Migration/Generator/Modifiers/DefaultModifier.php +++ b/src/Migration/Generator/Modifiers/DefaultModifier.php @@ -17,7 +17,7 @@ class DefaultModifier implements Modifier /** * @var array */ - private $chainerMap = []; + private array $chainerMap = []; public function __construct() { @@ -35,9 +35,7 @@ public function __construct() ColumnType::UNSIGNED_TINY_INTEGER(), ] as $columnType ) { - $this->chainerMap[$columnType->getValue()] = function (Method $method, Column $column): Method { - return call_user_func([$this, 'chainDefaultForInteger'], $method, $column); - }; + $this->chainerMap[$columnType->getValue()] = fn (Method $method, Column $column): Method => call_user_func([$this, 'chainDefaultForInteger'], $method, $column); } foreach ( @@ -47,14 +45,10 @@ public function __construct() ColumnType::DOUBLE(), ] as $columnType ) { - $this->chainerMap[$columnType->getValue()] = function (Method $method, Column $column): Method { - return call_user_func([$this, 'chainDefaultForDecimal'], $method, $column); - }; + $this->chainerMap[$columnType->getValue()] = fn (Method $method, Column $column): Method => call_user_func([$this, 'chainDefaultForDecimal'], $method, $column); } - $this->chainerMap[ColumnType::BOOLEAN()->getValue()] = function (Method $method, Column $column): Method { - return call_user_func([$this, 'chainDefaultForBoolean'], $method, $column); - }; + $this->chainerMap[ColumnType::BOOLEAN()->getValue()] = fn (Method $method, Column $column): Method => call_user_func([$this, 'chainDefaultForBoolean'], $method, $column); foreach ( [ @@ -69,16 +63,14 @@ public function __construct() ColumnType::TIMESTAMP_TZ(), ] as $columnType ) { - $this->chainerMap[$columnType->getValue()] = function (Method $method, Column $column): Method { - return call_user_func([$this, 'chainDefaultForDatetime'], $method, $column); - }; + $this->chainerMap[$columnType->getValue()] = fn (Method $method, Column $column): Method => call_user_func([$this, 'chainDefaultForDatetime'], $method, $column); } } /** * @inheritDoc */ - public function chain(Method $method, Table $table, Column $column, ...$args): Method + public function chain(Method $method, Table $table, Column $column, mixed ...$args): Method { if ($column->getDefault() === null) { return $method; diff --git a/src/Migration/Generator/Modifiers/IndexModifier.php b/src/Migration/Generator/Modifiers/IndexModifier.php index b6ebab76..105f75a8 100644 --- a/src/Migration/Generator/Modifiers/IndexModifier.php +++ b/src/Migration/Generator/Modifiers/IndexModifier.php @@ -10,20 +10,14 @@ class IndexModifier implements Modifier { - /** - * @var \KitLoong\MigrationsGenerator\Support\IndexNameHelper - */ - private $indexNameHelper; - - public function __construct(IndexNameHelper $indexNameHelper) + public function __construct(private IndexNameHelper $indexNameHelper) { - $this->indexNameHelper = $indexNameHelper; } /** * @inheritDoc */ - public function chain(Method $method, Table $table, Column $column, ...$args): Method + public function chain(Method $method, Table $table, Column $column, mixed ...$args): Method { /** @var \Illuminate\Support\Collection $chainableIndexes Key is column name. */ $chainableIndexes = $args[0]; diff --git a/src/Migration/Generator/Modifiers/Modifier.php b/src/Migration/Generator/Modifiers/Modifier.php index 2302a368..7b332919 100644 --- a/src/Migration/Generator/Modifiers/Modifier.php +++ b/src/Migration/Generator/Modifiers/Modifier.php @@ -10,8 +10,6 @@ interface Modifier { /** * Chain column modifier. - * - * @param mixed ...$args */ - public function chain(Method $method, Table $table, Column $column, ...$args): Method; + public function chain(Method $method, Table $table, Column $column, mixed ...$args): Method; } diff --git a/src/Migration/Generator/Modifiers/NullableModifier.php b/src/Migration/Generator/Modifiers/NullableModifier.php index 676b6c73..570c3403 100644 --- a/src/Migration/Generator/Modifiers/NullableModifier.php +++ b/src/Migration/Generator/Modifiers/NullableModifier.php @@ -13,7 +13,7 @@ class NullableModifier implements Modifier /** * @inheritDoc */ - public function chain(Method $method, Table $table, Column $column, ...$args): Method + public function chain(Method $method, Table $table, Column $column, mixed ...$args): Method { if ($column->isNotNull()) { if ($this->shouldAddNotNullModifier($column->getType())) { @@ -43,7 +43,7 @@ private function shouldAddNullableModifier(ColumnType $columnType): bool ColumnType::SOFT_DELETES_TZ(), ColumnType::REMEMBER_TOKEN(), ColumnType::TIMESTAMPS(), - ] + ], ); } @@ -59,7 +59,7 @@ private function shouldAddNotNullModifier(ColumnType $columnType): bool ColumnType::SOFT_DELETES(), ColumnType::SOFT_DELETES_TZ(), ColumnType::REMEMBER_TOKEN(), - ] + ], ); } } diff --git a/src/Migration/Generator/Modifiers/StoredAsModifier.php b/src/Migration/Generator/Modifiers/StoredAsModifier.php index 62138227..0111df75 100644 --- a/src/Migration/Generator/Modifiers/StoredAsModifier.php +++ b/src/Migration/Generator/Modifiers/StoredAsModifier.php @@ -12,7 +12,7 @@ class StoredAsModifier implements Modifier /** * @inheritDoc */ - public function chain(Method $method, Table $table, Column $column, ...$args): Method + public function chain(Method $method, Table $table, Column $column, mixed ...$args): Method { if ($column->getStoredDefinition() !== null) { $method->chain(ColumnModifier::STORED_AS(), $column->getStoredDefinition()); diff --git a/src/Migration/Generator/Modifiers/VirtualAsModifier.php b/src/Migration/Generator/Modifiers/VirtualAsModifier.php index 51b9b267..449d278e 100644 --- a/src/Migration/Generator/Modifiers/VirtualAsModifier.php +++ b/src/Migration/Generator/Modifiers/VirtualAsModifier.php @@ -12,7 +12,7 @@ class VirtualAsModifier implements Modifier /** * @inheritDoc */ - public function chain(Method $method, Table $table, Column $column, ...$args): Method + public function chain(Method $method, Table $table, Column $column, mixed ...$args): Method { if ($column->getVirtualDefinition() !== null) { $method->chain(ColumnModifier::VIRTUAL_AS(), $column->getVirtualDefinition()); diff --git a/src/Migration/Migrator/Migrator.php b/src/Migration/Migrator/Migrator.php index 1e82a4b2..5fc2fd70 100644 --- a/src/Migration/Migrator/Migrator.php +++ b/src/Migration/Migrator/Migrator.php @@ -73,10 +73,8 @@ protected function getMigrationQueries(string $path): array /** * Resolve migration instance with backward compatibility. - * - * @return object */ - protected function resolveMigration(string $path) + protected function resolveMigration(string $path): object { if (method_exists(DefaultMigrator::class, 'resolvePath')) { return $this->resolvePath($path); @@ -84,7 +82,7 @@ protected function resolveMigration(string $path) // @codeCoverageIgnoreStart return $this->resolve( - $this->getMigrationName($path) + $this->getMigrationName($path), ); // @codeCoverageIgnoreEnd } diff --git a/src/Migration/ProcedureMigration.php b/src/Migration/ProcedureMigration.php index fc46a84a..7c73fff3 100644 --- a/src/Migration/ProcedureMigration.php +++ b/src/Migration/ProcedureMigration.php @@ -13,36 +13,12 @@ class ProcedureMigration { - /** - * @var \KitLoong\MigrationsGenerator\Support\MigrationNameHelper - */ - private $migrationNameHelper; - - /** - * @var \KitLoong\MigrationsGenerator\Migration\Writer\MigrationWriter - */ - private $migrationWriter; - - /** - * @var \KitLoong\MigrationsGenerator\Setting - */ - private $setting; - - /** - * @var \KitLoong\MigrationsGenerator\Migration\Writer\SquashWriter - */ - private $squashWriter; - public function __construct( - MigrationNameHelper $migrationNameHelper, - MigrationWriter $migrationWriter, - Setting $setting, - SquashWriter $squashWriter + private MigrationNameHelper $migrationNameHelper, + private MigrationWriter $migrationWriter, + private Setting $setting, + private SquashWriter $squashWriter, ) { - $this->migrationNameHelper = $migrationNameHelper; - $this->migrationWriter = $migrationWriter; - $this->setting = $setting; - $this->squashWriter = $squashWriter; } /** @@ -61,7 +37,7 @@ public function write(Procedure $procedure): string $this->makeMigrationClassName($procedure->getName()), new Collection([$up]), new Collection([$down]), - MigrationFileType::PROCEDURE() + MigrationFileType::PROCEDURE(), ); return $path; @@ -103,7 +79,7 @@ private function makeMigrationClassName(string $procedure): string { return $this->migrationNameHelper->makeClassName( $this->setting->getProcedureFilename(), - $procedure + $procedure, ); } @@ -117,7 +93,7 @@ private function makeMigrationPath(string $procedure): string return $this->migrationNameHelper->makeFilename( $this->setting->getProcedureFilename(), $this->setting->getDateForMigrationFilename(), - $procedure + $procedure, ); } } diff --git a/src/Migration/Squash.php b/src/Migration/Squash.php index 1504dc91..d8dc55bd 100644 --- a/src/Migration/Squash.php +++ b/src/Migration/Squash.php @@ -9,26 +9,8 @@ class Squash { - /** - * @var \KitLoong\MigrationsGenerator\Migration\Writer\SquashWriter - */ - private $squashWriter; - - /** - * @var \KitLoong\MigrationsGenerator\Support\MigrationNameHelper - */ - private $migrationNameHelper; - - /** - * @var \KitLoong\MigrationsGenerator\Setting - */ - private $setting; - - public function __construct(SquashWriter $squashWriter, MigrationNameHelper $migrationNameHelper, Setting $setting) + public function __construct(private SquashWriter $squashWriter, private MigrationNameHelper $migrationNameHelper, private Setting $setting) { - $this->squashWriter = $squashWriter; - $this->migrationNameHelper = $migrationNameHelper; - $this->setting = $setting; } /** @@ -50,12 +32,12 @@ public function squashMigrations(): string $path = $this->migrationNameHelper->makeFilename( $this->setting->getTableFilename(), $this->setting->getDateForMigrationFilename(), - DB::getDatabaseName() + DB::getDatabaseName(), ); $className = $this->migrationNameHelper->makeClassName( $this->setting->getTableFilename(), - DB::getDatabaseName() + DB::getDatabaseName(), ); $this->squashWriter->squashMigrations($path, $this->setting->getStubPath(), $className); return $path; diff --git a/src/Migration/TableMigration.php b/src/Migration/TableMigration.php index 79bad50e..76042438 100644 --- a/src/Migration/TableMigration.php +++ b/src/Migration/TableMigration.php @@ -29,50 +29,14 @@ class TableMigration use CheckMigrationMethod; use TableName; - /** - * @var \KitLoong\MigrationsGenerator\Migration\Generator\ColumnGenerator - */ - private $columnGenerator; - - /** - * @var \KitLoong\MigrationsGenerator\Support\MigrationNameHelper - */ - private $migrationNameHelper; - - /** - * @var \KitLoong\MigrationsGenerator\Migration\Generator\IndexGenerator - */ - private $indexGenerator; - - /** - * @var \KitLoong\MigrationsGenerator\Migration\Writer\MigrationWriter - */ - private $migrationWriter; - - /** - * @var \KitLoong\MigrationsGenerator\Setting - */ - private $setting; - - /** - * @var \KitLoong\MigrationsGenerator\Migration\Writer\SquashWriter - */ - private $squashWriter; - public function __construct( - ColumnGenerator $columnGenerator, - MigrationNameHelper $migrationNameHelper, - IndexGenerator $indexGenerator, - MigrationWriter $migrationWriter, - Setting $setting, - SquashWriter $squashWriter + private ColumnGenerator $columnGenerator, + private MigrationNameHelper $migrationNameHelper, + private IndexGenerator $indexGenerator, + private MigrationWriter $migrationWriter, + private Setting $setting, + private SquashWriter $squashWriter, ) { - $this->columnGenerator = $columnGenerator; - $this->migrationNameHelper = $migrationNameHelper; - $this->indexGenerator = $indexGenerator; - $this->migrationWriter = $migrationWriter; - $this->setting = $setting; - $this->squashWriter = $squashWriter; } /** @@ -99,7 +63,7 @@ public function write(Table $table): string $this->makeMigrationClassName($table->getName()), $upList, new Collection([$down]), - MigrationFileType::TABLE() + MigrationFileType::TABLE(), ); return $path; @@ -202,7 +166,7 @@ private function makeMigrationClassName(string $table): string $withoutPrefix = $this->stripTablePrefix($table); return $this->migrationNameHelper->makeClassName( $this->setting->getTableFilename(), - $withoutPrefix + $withoutPrefix, ); } @@ -217,7 +181,7 @@ private function makeMigrationPath(string $table): string return $this->migrationNameHelper->makeFilename( $this->setting->getTableFilename(), $this->setting->getDateForMigrationFilename(), - $withoutPrefix + $withoutPrefix, ); } @@ -237,7 +201,7 @@ private function setTableCharset(TableBlueprint $blueprint, Table $table): Table { $blueprint->setProperty( TableProperty::COLLATION(), - $collation = $table->getCollation() + $collation = $table->getCollation(), ); if ($collation === null) { @@ -254,7 +218,7 @@ private function getSchemaBlueprint(Table $table, SchemaBuilder $schemaBuilder): { return new SchemaBlueprint( $table->getName(), - $schemaBuilder + $schemaBuilder, ); } } diff --git a/src/Migration/ViewMigration.php b/src/Migration/ViewMigration.php index 0176cfee..d237666e 100644 --- a/src/Migration/ViewMigration.php +++ b/src/Migration/ViewMigration.php @@ -16,36 +16,12 @@ class ViewMigration { use TableName; - /** - * @var \KitLoong\MigrationsGenerator\Support\MigrationNameHelper - */ - private $migrationNameHelper; - - /** - * @var \KitLoong\MigrationsGenerator\Migration\Writer\MigrationWriter - */ - private $migrationWriter; - - /** - * @var \KitLoong\MigrationsGenerator\Setting - */ - private $setting; - - /** - * @var \KitLoong\MigrationsGenerator\Migration\Writer\SquashWriter - */ - private $squashWriter; - public function __construct( - MigrationNameHelper $migrationNameHelper, - MigrationWriter $migrationWriter, - Setting $setting, - SquashWriter $squashWriter + private MigrationNameHelper $migrationNameHelper, + private MigrationWriter $migrationWriter, + private Setting $setting, + private SquashWriter $squashWriter, ) { - $this->migrationNameHelper = $migrationNameHelper; - $this->migrationWriter = $migrationWriter; - $this->setting = $setting; - $this->squashWriter = $squashWriter; } /** @@ -64,7 +40,7 @@ public function write(View $view): string $this->makeMigrationClassName($view->getName()), new Collection([$up]), new Collection([$down]), - MigrationFileType::VIEW() + MigrationFileType::VIEW(), ); return $path; @@ -107,7 +83,7 @@ private function makeMigrationClassName(string $view): string $withoutPrefix = $this->stripTablePrefix($view); return $this->migrationNameHelper->makeClassName( $this->setting->getViewFilename(), - $withoutPrefix + $withoutPrefix, ); } @@ -122,7 +98,7 @@ private function makeMigrationPath(string $view): string return $this->migrationNameHelper->makeFilename( $this->setting->getViewFilename(), $this->setting->getDateForMigrationFilename(), - $withoutPrefix + $withoutPrefix, ); } } diff --git a/src/Migration/Writer/MigrationStub.php b/src/Migration/Writer/MigrationStub.php index 66aefb59..aa0b949b 100644 --- a/src/Migration/Writer/MigrationStub.php +++ b/src/Migration/Writer/MigrationStub.php @@ -30,7 +30,7 @@ public function populateStub( string $use, string $className, string $upContent, - string $downContent + string $downContent, ): string { $content = $stub; $replace = [ diff --git a/src/Migration/Writer/MigrationWriter.php b/src/Migration/Writer/MigrationWriter.php index e113f243..73aaab50 100644 --- a/src/Migration/Writer/MigrationWriter.php +++ b/src/Migration/Writer/MigrationWriter.php @@ -12,14 +12,8 @@ class MigrationWriter { - /** - * @var \KitLoong\MigrationsGenerator\Migration\Writer\MigrationStub - */ - private $migrationStub; - - public function __construct(MigrationStub $migrationStub) + public function __construct(private MigrationStub $migrationStub) { - $this->migrationStub = $migrationStub; } /** @@ -36,7 +30,7 @@ public function writeTo( string $className, Collection $up, Collection $down, - MigrationFileType $migrationFileType + MigrationFileType $migrationFileType, ): void { try { $stub = $this->migrationStub->getStub($stubPath); @@ -61,9 +55,9 @@ public function writeTo( File::put( $path, - $this->migrationStub->populateStub($stub, $use, $className, $upString, $downString) + $this->migrationStub->populateStub($stub, $use, $className, $upString, $downString), ); - } catch (FileNotFoundException $e) { + } catch (FileNotFoundException) { // Do nothing. } } @@ -105,8 +99,6 @@ private function getNamespaces(MigrationFileType $migrationFileType, bool $useDB */ private function prettifyToString(Collection $blueprints): string { - return $blueprints->map(function (WritableBlueprint $blueprint) { - return $blueprint->toString(); - })->implode(Space::LINE_BREAK() . Space::TAB() . Space::TAB()); // Add tab to prettify + return $blueprints->map(static fn (WritableBlueprint $blueprint) => $blueprint->toString())->implode(Space::LINE_BREAK() . Space::TAB() . Space::TAB()); // Add tab to prettify } } diff --git a/src/Migration/Writer/SquashWriter.php b/src/Migration/Writer/SquashWriter.php index b0fe90cd..6d36268e 100644 --- a/src/Migration/Writer/SquashWriter.php +++ b/src/Migration/Writer/SquashWriter.php @@ -11,20 +11,8 @@ class SquashWriter { - /** - * @var \KitLoong\MigrationsGenerator\Support\MigrationNameHelper - */ - private $migrationNameHelper; - - /** - * @var \KitLoong\MigrationsGenerator\Migration\Writer\MigrationStub - */ - private $migrationStub; - - public function __construct(MigrationNameHelper $migrationNameHelper, MigrationStub $migrationStub) + public function __construct(private MigrationNameHelper $migrationNameHelper, private MigrationStub $migrationStub) { - $this->migrationNameHelper = $migrationNameHelper; - $this->migrationStub = $migrationStub; } /** @@ -39,16 +27,12 @@ public function writeToTemp(Collection $upBlueprints, Collection $downBlueprints { $upTempPath = $this->migrationNameHelper->makeUpTempPath(); $prettySpace = $this->getSpaceIfFileExists($upTempPath); - $upString = $upBlueprints->map(function (WritableBlueprint $up) { - return $up->toString(); - })->implode(Space::LINE_BREAK() . Space::TAB() . Space::TAB()); // Add tab to prettify + $upString = $upBlueprints->map(static fn (WritableBlueprint $up) => $up->toString())->implode(Space::LINE_BREAK() . Space::TAB() . Space::TAB()); // Add tab to prettify File::append($upTempPath, $prettySpace . $upString); $downTempPath = $this->migrationNameHelper->makeDownTempPath(); $prettySpace = $this->getSpaceIfFileExists($downTempPath); - $downString = $downBlueprints->map(function (WritableBlueprint $down) { - return $down->toString(); - })->implode(Space::LINE_BREAK() . Space::TAB() . Space::TAB()); // Add tab to prettify + $downString = $downBlueprints->map(static fn (WritableBlueprint $down) => $down->toString())->implode(Space::LINE_BREAK() . Space::TAB() . Space::TAB()); // Add tab to prettify File::prepend($downTempPath, $downString . $prettySpace); } @@ -87,10 +71,10 @@ public function squashMigrations(string $path, string $stubPath, string $classNa $use, $className, File::get($upTempPath), - File::get($downTempPath) - ) + File::get($downTempPath), + ), ); - } catch (FileNotFoundException $e) { + } catch (FileNotFoundException) { // Do nothing. } finally { File::delete($upTempPath); diff --git a/src/MigrationsGeneratorServiceProvider.php b/src/MigrationsGeneratorServiceProvider.php index a9b72c77..63892002 100644 --- a/src/MigrationsGeneratorServiceProvider.php +++ b/src/MigrationsGeneratorServiceProvider.php @@ -72,19 +72,17 @@ public function register(): void // Bind the Repository Interface to $app['migrations.repository'] $this->app->singleton( MigrationRepositoryInterface::class, - function ($app) { - return $app['migration.repository']; - } + static fn ($app) => $app['migration.repository'], ); // Backward compatible for older Laravel version which failed to resolve Illuminate\Database\ConnectionResolverInterface. $this->app->singleton( Migrator::class, - function ($app) { + static function ($app) { $repository = $app['migration.repository']; return new Migrator($repository, $app['db'], $app['files'], $app['events']); - } + }, ); $this->registerColumnTypeGenerator(); diff --git a/src/Repositories/Entities/MariaDB/CheckConstraint.php b/src/Repositories/Entities/MariaDB/CheckConstraint.php index f8378eec..ab8822a1 100644 --- a/src/Repositories/Entities/MariaDB/CheckConstraint.php +++ b/src/Repositories/Entities/MariaDB/CheckConstraint.php @@ -14,31 +14,23 @@ */ class CheckConstraint { - /** @var string */ - private $constraintCatalog; + private string $constraintCatalog; - /** @var string */ - private $constraintSchema; + private string $constraintSchema; - /** @var string */ - private $tableName; + private string $tableName; - /** @var string */ - private $constraintName; + private string $constraintName; - /** @var string|null */ - private $level; + private ?string $level = null; - /** @var string */ - private $checkClause; + private string $checkClause; public function __construct(stdClass $column) { // Convert column property to case-insensitive // Issue https://github.com/kitloong/laravel-migrations-generator/issues/34 - $lowerKey = (new Collection((array) $column))->mapWithKeys(function ($item, $key) { - return [strtolower($key) => $item]; - }); + $lowerKey = (new Collection((array) $column))->mapWithKeys(static fn ($item, $key) => [strtolower($key) => $item]); $this->constraintCatalog = $lowerKey['constraint_catalog']; $this->constraintSchema = $lowerKey['constraint_schema']; diff --git a/src/Repositories/Entities/MySQL/ShowColumn.php b/src/Repositories/Entities/MySQL/ShowColumn.php index 1ae44178..9d21e85d 100644 --- a/src/Repositories/Entities/MySQL/ShowColumn.php +++ b/src/Repositories/Entities/MySQL/ShowColumn.php @@ -15,31 +15,23 @@ */ class ShowColumn { - /** @var string */ - private $field; + private string $field; - /** @var string */ - private $type; + private string $type; - /** @var string */ - private $null; + private string $null; - /** @var string */ - private $key; + private string $key; - /** @var string|null */ - private $default; + private ?string $default = null; - /** @var string */ - private $extra; + private string $extra; public function __construct(stdClass $column) { // Convert column property to case-insensitive // Issue https://github.com/kitloong/laravel-migrations-generator/issues/34 - $lowerKey = (new Collection((array) $column))->mapWithKeys(function ($item, $key) { - return [strtolower($key) => $item]; - }); + $lowerKey = (new Collection((array) $column))->mapWithKeys(static fn ($item, $key) => [strtolower($key) => $item]); $this->field = $lowerKey['field']; $this->type = $lowerKey['type']; diff --git a/src/Repositories/Entities/PgSQL/IndexDefinition.php b/src/Repositories/Entities/PgSQL/IndexDefinition.php index 9bc2a520..82b6867e 100644 --- a/src/Repositories/Entities/PgSQL/IndexDefinition.php +++ b/src/Repositories/Entities/PgSQL/IndexDefinition.php @@ -4,26 +4,8 @@ class IndexDefinition { - /** - * @var string - */ - private $tableName; - - /** - * @var string - */ - private $indexName; - - /** - * @var string - */ - private $indexDef; - - public function __construct(string $tableName, string $indexName, string $indexDef) + public function __construct(private string $tableName, private string $indexName, private string $indexDef) { - $this->tableName = $tableName; - $this->indexName = $indexName; - $this->indexDef = $indexDef; } public function getTableName(): string diff --git a/src/Repositories/Entities/ProcedureDefinition.php b/src/Repositories/Entities/ProcedureDefinition.php index 9e34193c..867e9adb 100644 --- a/src/Repositories/Entities/ProcedureDefinition.php +++ b/src/Repositories/Entities/ProcedureDefinition.php @@ -4,16 +4,8 @@ class ProcedureDefinition { - /** @var string */ - private $name; - - /** @var string */ - private $definition; - - public function __construct(string $name, string $definition) + public function __construct(private string $name, private string $definition) { - $this->name = $name; - $this->definition = $definition; } public function getName(): string diff --git a/src/Repositories/Entities/SQLSrv/ColumnDefinition.php b/src/Repositories/Entities/SQLSrv/ColumnDefinition.php index a45a8aab..96236c00 100644 --- a/src/Repositories/Entities/SQLSrv/ColumnDefinition.php +++ b/src/Repositories/Entities/SQLSrv/ColumnDefinition.php @@ -7,42 +7,30 @@ class ColumnDefinition { - /** @var string */ - private $name; + private string $name; - /** @var string */ - private $type; + private string $type; - /** @var int */ - private $length; + private int $length; - /** @var bool */ - private $notnull; + private bool $notnull; - /** @var string|null */ - private $default; + private ?string $default = null; - /** @var int */ - private $scale; + private int $scale; - /** @var int */ - private $precision; + private int $precision; - /** @var bool */ - private $autoincrement; + private bool $autoincrement; - /** @var string|null */ - private $collation; + private ?string $collation = null; - /** @var string|null */ - private $comment; + private ?string $comment = null; public function __construct(stdClass $column) { // Convert column property to case-insensitive - $lowerKey = (new Collection((array) $column))->mapWithKeys(function ($item, $key) { - return [strtolower($key) => $item]; - }); + $lowerKey = (new Collection((array) $column))->mapWithKeys(static fn ($item, $key) => [strtolower($key) => $item]); $this->name = $lowerKey['name']; $this->type = $lowerKey['type']; diff --git a/src/Repositories/Entities/SQLSrv/ViewDefinition.php b/src/Repositories/Entities/SQLSrv/ViewDefinition.php index a1298874..d1a7deb9 100644 --- a/src/Repositories/Entities/SQLSrv/ViewDefinition.php +++ b/src/Repositories/Entities/SQLSrv/ViewDefinition.php @@ -4,20 +4,8 @@ class ViewDefinition { - /** - * @var string - */ - private $name; - - /** - * @var string - */ - private $definition; - - public function __construct(string $name, string $definition) + public function __construct(private string $name, private string $definition) { - $this->name = $name; - $this->definition = $definition; } public function getName(): string diff --git a/src/Repositories/MariaDBRepository.php b/src/Repositories/MariaDBRepository.php index 568b6542..44a4486f 100644 --- a/src/Repositories/MariaDBRepository.php +++ b/src/Repositories/MariaDBRepository.php @@ -23,10 +23,10 @@ public function getCheckConstraintForJson(string $table, string $column): ?Check "SELECT * FROM information_schema.CHECK_CONSTRAINTS WHERE TABLE_NAME = '$table' AND CONSTRAINT_SCHEMA = '" . DB::getDatabaseName() . "' - AND CHECK_CLAUSE LIKE '%json_valid(`$column`)%'" + AND CHECK_CLAUSE LIKE '%json_valid(`$column`)%'", ); return $column === null ? null : new CheckConstraint($column); - } catch (QueryException $exception) { + } catch (QueryException) { return null; } } diff --git a/src/Repositories/MySQLRepository.php b/src/Repositories/MySQLRepository.php index c269f9c0..29a17512 100644 --- a/src/Repositories/MySQLRepository.php +++ b/src/Repositories/MySQLRepository.php @@ -42,7 +42,7 @@ public function getEnumPresetValues(string $table, string $column): Collection $value = substr( str_replace('enum(\'', '', $showColumn->getType()), 0, - -2 + -2, ); return new Collection(explode("','", $value)); } @@ -66,7 +66,7 @@ public function getSetPresetValues(string $table, string $column): Collection $value = substr( str_replace('set(\'', '', $showColumn->getType()), 0, - -2 + -2, ); return new Collection(explode("','", $value)); } @@ -85,7 +85,7 @@ public function isOnUpdateCurrentTimestamp(string $table, string $column): bool "SHOW COLUMNS FROM `$table` WHERE Field = '$column' AND Type = 'timestamp' - AND Extra LIKE '%on update CURRENT_TIMESTAMP%'" + AND Extra LIKE '%on update CURRENT_TIMESTAMP%'", ); return !($result === null); } @@ -141,9 +141,8 @@ public function getProcedures(): Collection * Get single stored procedure by name. * * @param string $procedure Procedure name. - * @return mixed */ - private function getProcedure(string $procedure) + private function getProcedure(string $procedure): mixed { return DB::selectOne("SHOW CREATE PROCEDURE $procedure"); } @@ -161,7 +160,7 @@ private function getGenerationExpression(string $table, string $column, string $ FROM information_schema.COLUMNS WHERE TABLE_NAME = '$table' AND COLUMN_NAME = '$column' - AND EXTRA = '$extra'" + AND EXTRA = '$extra'", ); } catch (QueryException $exception) { // Check if error caused by missing column 'GENERATION_EXPRESSION'. @@ -172,7 +171,7 @@ private function getGenerationExpression(string $table, string $column, string $ Str::contains( $exception->getMessage(), "SQLSTATE[42S22]: Column not found: 1054 Unknown column 'GENERATION_EXPRESSION'", - true + true, ) ) { return null; @@ -200,14 +199,14 @@ public function getSrID(string $table, string $column): ?int FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = '" . DB::getDatabaseName() . "' AND TABLE_NAME = '" . $table . "' - AND COLUMN_NAME = '" . $column . "'" + AND COLUMN_NAME = '" . $column . "'", ); } catch (QueryException $exception) { if ( Str::contains( $exception->getMessage(), "SQLSTATE[42S22]: Column not found: 1054 Unknown column 'SRS_ID'", - true + true, ) ) { return null; diff --git a/src/Repositories/PgSQLRepository.php b/src/Repositories/PgSQLRepository.php index 687117b5..7e0bf49d 100644 --- a/src/Repositories/PgSQLRepository.php +++ b/src/Repositories/PgSQLRepository.php @@ -31,9 +31,9 @@ public function getTypeByColumnName(string $table, string $column): ?string WHERE c.relname ~ '^($table)$' AND pg_catalog.pg_table_is_visible(c.oid) ) - AND a.attname='$column'" + AND a.attname='$column'", ); - return $result === null ? null : $result->datatype; + return $result?->datatype; } /** @@ -60,9 +60,9 @@ public function getDefaultByColumnName(string $table, string $column): ?string WHERE c.relname ~ '^($table)$' AND pg_catalog.pg_table_is_visible(c.oid) ) - AND a.attname='$column'" + AND a.attname='$column'", ); - return $result === null ? null : $result->default_value; + return $result?->default_value; } /** @@ -88,9 +88,9 @@ public function getCheckConstraintDefinition(string $table, string $column): ?st AND nsp.nspname = ccu.constraint_schema WHERE contype ='c' AND ccu.table_name='$table' - AND ccu.column_name='$column'" + AND ccu.column_name='$column'", ); - return $result === null ? null : $result->definition; + return $result?->definition; } /** @@ -107,7 +107,7 @@ public function getSpatialIndexes(string $table): Collection indexdef FROM pg_indexes WHERE tablename = '$table' - AND indexdef LIKE '% USING gist %'" + AND indexdef LIKE '% USING gist %'", ); $definitions = new Collection(); @@ -117,8 +117,8 @@ public function getSpatialIndexes(string $table): Collection new IndexDefinition( $column->tablename, $column->indexname, - $column->indexdef - ) + $column->indexdef, + ), ); } } @@ -141,7 +141,7 @@ public function getFulltextIndexes(string $table): Collection FROM pg_indexes WHERE tablename = '$table' AND indexdef LIKE '%to_tsvector(%' - ORDER BY indexname" + ORDER BY indexname", ); $definitions = new Collection(); @@ -151,8 +151,8 @@ public function getFulltextIndexes(string $table): Collection new IndexDefinition( $column->tablename, $column->indexname, - $column->indexdef - ) + $column->indexdef, + ), ); } } @@ -176,7 +176,7 @@ public function getCustomDataTypes(): Collection LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace WHERE (t.typrelid = 0 OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)) AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid) - AND n.nspname IN ('$searchPath');" + AND n.nspname IN ('$searchPath');", ); $types = new Collection(); @@ -205,7 +205,7 @@ public function getProcedures(): Collection FROM pg_catalog.pg_proc JOIN pg_namespace ON pg_catalog.pg_proc.pronamespace = pg_namespace.oid WHERE prokind = 'p' - AND pg_namespace.nspname = '$searchPath'" + AND pg_namespace.nspname = '$searchPath'", ); foreach ($procedures as $procedure) { @@ -230,7 +230,7 @@ public function getStoredDefinition(string $table, string $column): ?string FROM information_schema.columns WHERE table_name = '$table' AND column_name = '$column' - AND is_generated = 'ALWAYS'" + AND is_generated = 'ALWAYS'", ); if ($definition === null) { diff --git a/src/Repositories/SQLSrvRepository.php b/src/Repositories/SQLSrvRepository.php index 16df5c25..1b4a7ea2 100644 --- a/src/Repositories/SQLSrvRepository.php +++ b/src/Repositories/SQLSrvRepository.php @@ -34,7 +34,7 @@ public function getSpatialIndexNames(string $table): Collection JOIN sys.index_columns AS idxcol ON idx.object_id = idxcol.object_id AND idx.index_id = idxcol.index_id JOIN sys.columns AS col ON idxcol.object_id = col.object_id AND idxcol.column_id = col.column_id WHERE " . $this->getTableWhereClause($table, 'scm.name', 'tbl.name') . " - AND idx.type = " . self::SPATIAL_INDEX_ID + AND idx.type = " . self::SPATIAL_INDEX_ID, ); $definitions = new Collection(); @@ -82,7 +82,7 @@ public function getColumnDefinition(string $table, string $column): ?ColumnDefin AND prop.name = 'MS_Description' WHERE obj.type = 'U' AND " . $this->getTableWhereClause($table, 'scm.name', 'obj.name') . " - AND col.name = " . $this->quoteStringLiteral($column) + AND col.name = " . $this->quoteStringLiteral($column), ); return $result === null ? null : new ColumnDefinition($result); } @@ -106,7 +106,7 @@ public function getView(string $name): ?ViewDefinition '$name' ) AND definition IS NOT NULL - ORDER BY name" + ORDER BY name", ); return $view === null ? null : new ViewDefinition($view->name, $view->definition); } @@ -147,7 +147,7 @@ public function getProcedures(): Collection INNER JOIN sys.sql_modules ON (sys.sysobjects.id = sys.sql_modules.object_id) WHERE type = 'P' AND definition IS NOT NULL - ORDER BY name" + ORDER BY name", ); foreach ($procedures as $procedure) { @@ -176,7 +176,7 @@ public function getEnumPresetValues(string $table, string $column): Collection AND con.parent_object_id = col.object_id WHERE t.name = '$table' AND col.name = '$column' - AND con.definition IS NOT NULL" + AND con.definition IS NOT NULL", ); if ($result === null) { diff --git a/src/Setting.php b/src/Setting.php index d5b0f5d8..15c585cc 100644 --- a/src/Setting.php +++ b/src/Setting.php @@ -9,46 +9,32 @@ class Setting /** * The default DB connection name, also known as "previous" connection name if migration is called * with `--connection=other` option. - * - * @var string */ - private $defaultConnection; + private string $defaultConnection; - /** @var bool */ - private $useDBCollation; + private bool $useDBCollation; - /** @var bool */ - private $ignoreIndexNames; + private bool $ignoreIndexNames; - /** @var bool */ - private $ignoreForeignKeyNames; + private bool $ignoreForeignKeyNames; - /** @var bool */ - private $squash; + private bool $squash; - /** @var string */ - private $path; + private string $path; - /** @var string */ - private $stubPath; + private string $stubPath; - /** @var \Carbon\Carbon */ - private $date; + private Carbon $date; - /** @var string */ - private $tableFilename; + private string $tableFilename; - /** @var string */ - private $viewFilename; + private string $viewFilename; - /** @var string */ - private $procedureFilename; + private string $procedureFilename; - /** @var string */ - private $fkFilename; + private string $fkFilename; - /** @var bool */ - private $withHasTable; + private bool $withHasTable; public function getDefaultConnection(): string { diff --git a/src/Support/IndexNameHelper.php b/src/Support/IndexNameHelper.php index 1026dac4..27233293 100644 --- a/src/Support/IndexNameHelper.php +++ b/src/Support/IndexNameHelper.php @@ -8,14 +8,8 @@ class IndexNameHelper { - /** - * @var \KitLoong\MigrationsGenerator\Setting - */ - private $setting; - - public function __construct(Setting $setting) + public function __construct(private Setting $setting) { - $this->setting = $setting; } /** diff --git a/src/Support/MigrationNameHelper.php b/src/Support/MigrationNameHelper.php index c6e3fecb..3293ebcc 100644 --- a/src/Support/MigrationNameHelper.php +++ b/src/Support/MigrationNameHelper.php @@ -9,12 +9,8 @@ class MigrationNameHelper { use TableName; - /** @var \KitLoong\MigrationsGenerator\Setting */ - private $setting; - - public function __construct(Setting $setting) + public function __construct(private Setting $setting) { - $this->setting = $setting; } /** diff --git a/tests/Feature/FeatureTestCase.php b/tests/Feature/FeatureTestCase.php index 33244e8b..ad0fbe3c 100644 --- a/tests/Feature/FeatureTestCase.php +++ b/tests/Feature/FeatureTestCase.php @@ -25,7 +25,7 @@ protected function getEnvironmentSetUp($app): void try { $this->loadDotenv(); - } catch (InvalidPathException $exception) { + } catch (InvalidPathException) { $this->markTestSkipped('Skipped feature tests.'); } } @@ -123,7 +123,7 @@ protected function migrateFromTemplate(string $connection, string $templatePath) File::put($this->getStorageFromPath($file->getBasename()), $content); File::move( $this->getStorageFromPath($file->getBasename()), - $this->getStorageFromPath(str_replace('_db_', "_{$connection}_", $file->getBasename())) + $this->getStorageFromPath(str_replace('_db_', "_{$connection}_", $file->getBasename())), ); } @@ -146,7 +146,7 @@ protected function migrateFromVendorsTemplate(string $connection, string $templa File::put($this->getStorageFromVendorsPath($file->getBasename()), $content); File::move( $this->getStorageFromVendorsPath($file->getBasename()), - $this->getStorageFromVendorsPath(str_replace('_db_', "_{$connection}_", $file->getBasename())) + $this->getStorageFromVendorsPath(str_replace('_db_', "_{$connection}_", $file->getBasename())), ); } @@ -192,20 +192,20 @@ protected function generateMigrations(array $options = []): void 'migrate:generate', array_merge([ '--path' => $this->getStorageMigrationsPath(), - ], $options) + ], $options), ); $command->expectsQuestion('Do you want to log these migrations in the migrations table?', true); if ($expectConnectionQuestion) { $command->expectsQuestion( 'Log into current connection: ' . $options['--connection'] . '? [Y = ' . $options['--connection'] . ', n = ' . config('database.default') . ' (default connection)]', - true + true, ); } $command->expectsQuestion( 'Next Batch Number is: 1. We recommend using Batch Number 0 so that it becomes the "first" migration. [Default: 0]', - '0' + '0', ); } @@ -260,9 +260,7 @@ protected function getTableNames(): array protected function getViewNames(): array { return collect(app(Connection::class)->getDoctrineSchemaManager()->listViews()) - ->map(function (View $view) { - return $view->getName(); - }) + ->map(static fn (View $view) => $view->getName()) ->toArray(); } diff --git a/tests/Feature/MariaDB/CommandTest.php b/tests/Feature/MariaDB/CommandTest.php index a62b95de..1923b2f3 100644 --- a/tests/Feature/MariaDB/CommandTest.php +++ b/tests/Feature/MariaDB/CommandTest.php @@ -77,7 +77,7 @@ private function verify(callable $migrateTemplates, callable $generateMigrations $this->assertFileEqualsIgnoringOrder( $this->getStorageSqlPath('expected.sql'), - $this->getStorageSqlPath('actual.sql') + $this->getStorageSqlPath('actual.sql'), ); } } diff --git a/tests/Feature/MariaDB/MariaDBTestCase.php b/tests/Feature/MariaDB/MariaDBTestCase.php index 6b86d3a0..d4f50ea4 100644 --- a/tests/Feature/MariaDB/MariaDBTestCase.php +++ b/tests/Feature/MariaDB/MariaDBTestCase.php @@ -40,7 +40,7 @@ protected function getEnvironmentSetUp($app): void protected function dumpSchemaAs(string $destination): void { - $password = (!empty(config('database.connections.mariadb.password')) ? + $password = (config('database.connections.mariadb.password') !== '' ? '-p\'' . config('database.connections.mariadb.password') . '\'' : ''); @@ -56,7 +56,7 @@ protected function dumpSchemaAs(string $destination): void config('database.connections.mariadb.port'), config('database.connections.mariadb.username'), config('database.connections.mariadb.database'), - $destination + $destination, ); exec($command); } diff --git a/tests/Feature/MySQL57/CommandTest.php b/tests/Feature/MySQL57/CommandTest.php index 033e2882..9adad644 100644 --- a/tests/Feature/MySQL57/CommandTest.php +++ b/tests/Feature/MySQL57/CommandTest.php @@ -177,9 +177,7 @@ public function testDefaultIndexNames(): void ->getTable('test_index_mysql57') ->getIndexes(); - $actualIndexes = $indexes->map(function (Index $index) { - return $index->getName(); - })->toArray(); + $actualIndexes = $indexes->map(static fn (Index $index) => $index->getName())->toArray(); $expectedIndexes = [ '', // PRIMARY @@ -215,7 +213,7 @@ public function testDefaultIndexNames(): void $this->assertSame( $expectedIndexes, - $actualIndexes + $actualIndexes, ); } @@ -232,9 +230,7 @@ public function testDefaultFKNames(): void $this->runMigrationsFrom('mysql57', $this->getStorageMigrationsPath()); $foreignKeys = app(MySQLSchema::class)->getTableForeignKeys('user_profile_mysql57'); - $foreignKeyNames = $foreignKeys->map(function (ForeignKey $foreignKey) { - return $foreignKey->getName(); - }) + $foreignKeyNames = $foreignKeys->map(static fn (ForeignKey $foreignKey) => $foreignKey->getName()) ->sort() ->values() ->toArray(); @@ -247,7 +243,7 @@ public function testDefaultFKNames(): void 'user_profile_mysql57_user_id_user_sub_id_fk_custom_foreign', 'user_profile_mysql57_user_id_user_sub_id_foreign', ], - $foreignKeyNames + $foreignKeyNames, ); $this->rollbackMigrationsFrom('mysql57', $this->getStorageMigrationsPath()); @@ -406,7 +402,7 @@ public function testNoInteraction(): void [ '--path' => $this->getStorageMigrationsPath(), '--no-interaction' => true, - ] + ], ); $this->assertSame(0, DB::table('migrations')->count()); @@ -414,7 +410,7 @@ public function testNoInteraction(): void $this->assertFileEqualsIgnoringOrder( $this->getStorageSqlPath('expected.sql'), - $this->getStorageSqlPath('actual.sql') + $this->getStorageSqlPath('actual.sql'), ); } @@ -429,7 +425,7 @@ public function testSkipLog(): void [ '--path' => $this->getStorageMigrationsPath(), '--skip-log' => true, - ] + ], ); $this->assertSame(0, DB::table('migrations')->count()); @@ -437,7 +433,7 @@ public function testSkipLog(): void $this->assertFileEqualsIgnoringOrder( $this->getStorageSqlPath('expected.sql'), - $this->getStorageSqlPath('actual.sql') + $this->getStorageSqlPath('actual.sql'), ); } @@ -453,7 +449,7 @@ public function testLogWithBatch0(): void [ '--path' => $this->getStorageMigrationsPath(), '--log-with-batch' => '0', - ] + ], ); $this->assertMigrations(); @@ -463,7 +459,7 @@ public function testLogWithBatch0(): void $this->assertFileEqualsIgnoringOrder( $this->getStorageSqlPath('expected.sql'), - $this->getStorageSqlPath('actual.sql') + $this->getStorageSqlPath('actual.sql'), ); } @@ -479,7 +475,7 @@ public function testLogWithBatch99(): void [ '--path' => $this->getStorageMigrationsPath(), '--log-with-batch' => '99', - ] + ], ); $this->assertMigrations(); @@ -491,7 +487,7 @@ public function testLogWithBatch99(): void $this->assertFileEqualsIgnoringOrder( $this->getStorageSqlPath('expected.sql'), - $this->getStorageSqlPath('actual.sql') + $this->getStorageSqlPath('actual.sql'), ); } @@ -505,7 +501,7 @@ public function testLogWithBatchNaN(): void [ '--path' => $this->getStorageMigrationsPath(), '--log-with-batch' => 'Not a number', - ] + ], ); } @@ -532,9 +528,7 @@ public function testSkipVendor(): void $this->assertContains($vendor, $tables); } - $tablesWithoutVendors = (new Collection($tables))->filter(function ($table) use ($vendors) { - return !in_array($table, $vendors); - }) + $tablesWithoutVendors = (new Collection($tables))->filter(static fn ($table) => !in_array($table, $vendors)) ->values() ->all(); @@ -571,7 +565,7 @@ private function verify(callable $migrateTemplates, callable $generateMigrations $this->assertFileEqualsIgnoringOrder( $this->getStorageSqlPath('expected.sql'), - $this->getStorageSqlPath('actual.sql') + $this->getStorageSqlPath('actual.sql'), ); } } diff --git a/tests/Feature/MySQL57/DBConnectionTest.php b/tests/Feature/MySQL57/DBConnectionTest.php index 217bec8b..807337d3 100644 --- a/tests/Feature/MySQL57/DBConnectionTest.php +++ b/tests/Feature/MySQL57/DBConnectionTest.php @@ -74,7 +74,7 @@ public function testDBConnection(): void $this->assertStringContainsString( 'Schema::connection', - File::files($this->getStorageMigrationsPath())[0]->getContents() + File::files($this->getStorageMigrationsPath())[0]->getContents(), ); } @@ -90,16 +90,16 @@ public function testLogMigrationToAnotherSource(): void [ '--connection' => 'mysql57', '--path' => $this->getStorageMigrationsPath(), - ] + ], ) ->expectsQuestion('Do you want to log these migrations in the migrations table?', true) ->expectsQuestion( 'Log into current connection: mysql57? [Y = mysql57, n = mysql8 (default connection)]', - false + false, ) ->expectsQuestion( 'Next Batch Number is: 1. We recommend using Batch Number 0 so that it becomes the "first" migration. [Default: 0]', - '0' + '0', ); $totalMigrations = count(File::allFiles($this->getStorageMigrationsPath())); @@ -127,7 +127,7 @@ private function verify(callable $migrateTemplates, callable $generateMigrations $this->assertFileEqualsIgnoringOrder( $this->getStorageSqlPath('expected.sql'), - $this->getStorageSqlPath('actual.sql') + $this->getStorageSqlPath('actual.sql'), ); } } diff --git a/tests/Feature/MySQL57/MySQL57TestCase.php b/tests/Feature/MySQL57/MySQL57TestCase.php index 3d8dcdfb..6d154df9 100644 --- a/tests/Feature/MySQL57/MySQL57TestCase.php +++ b/tests/Feature/MySQL57/MySQL57TestCase.php @@ -40,7 +40,7 @@ protected function getEnvironmentSetUp($app): void protected function dumpSchemaAs(string $destination): void { - $password = (!empty(config('database.connections.mysql57.password')) ? + $password = (config('database.connections.mysql57.password') !== '' ? '-p\'' . config('database.connections.mysql57.password') . '\'' : ''); @@ -57,7 +57,7 @@ protected function dumpSchemaAs(string $destination): void config('database.connections.mysql57.port'), config('database.connections.mysql57.username'), config('database.connections.mysql57.database'), - $destination + $destination, ); exec($command); } diff --git a/tests/Feature/MySQL57/StackedCommandTest.php b/tests/Feature/MySQL57/StackedCommandTest.php index 5ae3f905..bd400743 100644 --- a/tests/Feature/MySQL57/StackedCommandTest.php +++ b/tests/Feature/MySQL57/StackedCommandTest.php @@ -63,11 +63,11 @@ protected function tearDown(): void public function testRunAsCall(): void { - Schema::create('migration_table', function (Blueprint $table): void { + Schema::create('migration_table', static function (Blueprint $table): void { $table->increments('id'); }); - Schema::connection('migration2')->create('migration2_table', function (Blueprint $table): void { + Schema::connection('migration2')->create('migration2_table', static function (Blueprint $table): void { $table->increments('id'); }); @@ -88,14 +88,14 @@ public function testRunAsCall(): void if (Str::contains($file->getBasename(), 'create_migration_table')) { $this->assertStringContainsString( 'migration_table', - $file->getContents() + $file->getContents(), ); continue; } $this->assertStringContainsString( 'migration2_table', - $file->getContents() + $file->getContents(), ); } } diff --git a/tests/Feature/MySQL57/TablePrefixTest.php b/tests/Feature/MySQL57/TablePrefixTest.php index af32a27f..322aa9e0 100644 --- a/tests/Feature/MySQL57/TablePrefixTest.php +++ b/tests/Feature/MySQL57/TablePrefixTest.php @@ -47,7 +47,7 @@ private function verify(callable $migrateTemplates, callable $generateMigrations $this->assertFileEqualsIgnoringOrder( $this->getStorageSqlPath('expected.sql'), - $this->getStorageSqlPath('actual.sql') + $this->getStorageSqlPath('actual.sql'), ); } } diff --git a/tests/Feature/MySQL8/CommandTest.php b/tests/Feature/MySQL8/CommandTest.php index c877d0e3..f006fa92 100644 --- a/tests/Feature/MySQL8/CommandTest.php +++ b/tests/Feature/MySQL8/CommandTest.php @@ -78,9 +78,7 @@ public function testSkipVendor(): void $this->assertContains($vendor, $tables); } - $tablesWithoutVendors = (new Collection($tables))->filter(function ($table) use ($vendors) { - return !in_array($table, $vendors); - }) + $tablesWithoutVendors = (new Collection($tables))->filter(static fn ($table) => !in_array($table, $vendors)) ->values() ->all(); @@ -117,7 +115,7 @@ private function verify(callable $migrateTemplates, callable $generateMigrations $this->assertFileEqualsIgnoringOrder( $this->getStorageSqlPath('expected.sql'), - $this->getStorageSqlPath('actual.sql') + $this->getStorageSqlPath('actual.sql'), ); } } diff --git a/tests/Feature/MySQL8/MySQL8TestCase.php b/tests/Feature/MySQL8/MySQL8TestCase.php index adddb883..90a7666a 100644 --- a/tests/Feature/MySQL8/MySQL8TestCase.php +++ b/tests/Feature/MySQL8/MySQL8TestCase.php @@ -40,7 +40,7 @@ protected function getEnvironmentSetUp($app): void protected function dumpSchemaAs(string $destination): void { - $password = (!empty(config('database.connections.mysql8.password')) ? + $password = (config('database.connections.mysql8.password') !== '' ? '-p\'' . config('database.connections.mysql8.password') . '\'' : ''); @@ -56,7 +56,7 @@ protected function dumpSchemaAs(string $destination): void config('database.connections.mysql8.port'), config('database.connections.mysql8.username'), config('database.connections.mysql8.database'), - $destination + $destination, ); exec($command); } diff --git a/tests/Feature/PgSQL/CommandTest.php b/tests/Feature/PgSQL/CommandTest.php index 816a7386..f8bdb16f 100644 --- a/tests/Feature/PgSQL/CommandTest.php +++ b/tests/Feature/PgSQL/CommandTest.php @@ -23,15 +23,15 @@ public function testRun(): void // Test timestamp default now() DB::statement( - "ALTER TABLE all_columns_pgsql ADD COLUMN timestamp_defaultnow timestamp(0) without time zone DEFAULT now() NOT NULL" + "ALTER TABLE all_columns_pgsql ADD COLUMN timestamp_defaultnow timestamp(0) without time zone DEFAULT now() NOT NULL", ); DB::statement( - "ALTER TABLE all_columns_pgsql ADD COLUMN status my_status NOT NULL" + "ALTER TABLE all_columns_pgsql ADD COLUMN status my_status NOT NULL", ); DB::statement( - "ALTER TABLE all_columns_pgsql ADD COLUMN timestamp_default_timezone_now timestamp(0) without time zone DEFAULT timezone('Europe/Rome'::text, now()) NOT NULL" + "ALTER TABLE all_columns_pgsql ADD COLUMN timestamp_default_timezone_now timestamp(0) without time zone DEFAULT timezone('Europe/Rome'::text, now()) NOT NULL", ); }; @@ -42,12 +42,12 @@ public function testRun(): void $beforeVerify = function (): void { $this->assertLineExistsThenReplace( $this->getStorageSqlPath('actual.sql'), - 'timestamp_defaultnow timestamp(0) without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL' + 'timestamp_defaultnow timestamp(0) without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL', ); $this->assertLineExistsThenReplace( $this->getStorageSqlPath('expected.sql'), - 'timestamp_defaultnow timestamp(0) without time zone DEFAULT now() NOT NULL' + 'timestamp_defaultnow timestamp(0) without time zone DEFAULT now() NOT NULL', ); }; @@ -60,7 +60,7 @@ public function testSquashUp(): void $this->migrateGeneral('pgsql'); DB::statement( - "ALTER TABLE all_columns_pgsql ADD COLUMN status my_status NOT NULL" + "ALTER TABLE all_columns_pgsql ADD COLUMN status my_status NOT NULL", ); }; @@ -143,7 +143,7 @@ public function testWithHasTable(): void $this->migrateGeneral('pgsql'); DB::statement( - "ALTER TABLE all_columns_pgsql ADD COLUMN status my_status NOT NULL" + "ALTER TABLE all_columns_pgsql ADD COLUMN status my_status NOT NULL", ); }; @@ -160,7 +160,7 @@ public function testWithHasTableSquash(): void $this->migrateGeneral('pgsql'); DB::statement( - "ALTER TABLE all_columns_pgsql ADD COLUMN status my_status NOT NULL" + "ALTER TABLE all_columns_pgsql ADD COLUMN status my_status NOT NULL", ); }; @@ -194,9 +194,7 @@ public function testSkipVendor(): void $this->assertContains($vendor, $tables); } - $tablesWithoutVendors = (new Collection($tables))->filter(function ($table) use ($vendors) { - return !in_array($table, $vendors); - }) + $tablesWithoutVendors = (new Collection($tables))->filter(static fn ($table) => !in_array($table, $vendors)) ->values() ->all(); @@ -238,7 +236,7 @@ private function verify(callable $migrateTemplates, callable $generateMigrations $this->assertFileEqualsIgnoringOrder( $this->getStorageSqlPath('expected.sql'), - $this->getStorageSqlPath('actual.sql') + $this->getStorageSqlPath('actual.sql'), ); } @@ -247,8 +245,8 @@ private function assertLineExistsThenReplace(string $file, string $line): void $this->assertTrue( str_contains( File::get($file), - $line - ) + $line, + ), ); File::put( @@ -256,8 +254,8 @@ private function assertLineExistsThenReplace(string $file, string $line): void str_replace( $line, 'replaced', - File::get($file) - ) + File::get($file), + ), ); } } diff --git a/tests/Feature/PgSQL/PgSQLTestCase.php b/tests/Feature/PgSQL/PgSQLTestCase.php index 968bfa8b..8e21a9c7 100644 --- a/tests/Feature/PgSQL/PgSQLTestCase.php +++ b/tests/Feature/PgSQL/PgSQLTestCase.php @@ -57,7 +57,7 @@ protected function dumpSchemaAs(string $destination): void config('database.connections.pgsql.port'), config('database.connections.pgsql.username'), config('database.connections.pgsql.database'), - $destination + $destination, ); exec($command); } @@ -96,7 +96,7 @@ protected function dropAllProcedures(): void FROM pg_catalog.pg_proc JOIN pg_namespace ON pg_catalog.pg_proc.pronamespace = pg_namespace.oid WHERE prokind = 'p' - AND pg_namespace.nspname = '" . $searchPath . "'" + AND pg_namespace.nspname = '" . $searchPath . "'", ); foreach ($procedures as $procedure) { diff --git a/tests/Feature/PgSQL/TablePrefixTest.php b/tests/Feature/PgSQL/TablePrefixTest.php index 0aef6b48..624be7bd 100644 --- a/tests/Feature/PgSQL/TablePrefixTest.php +++ b/tests/Feature/PgSQL/TablePrefixTest.php @@ -22,7 +22,7 @@ public function testTablePrefix(): void $this->migrateGeneral('pgsql'); DB::statement( - "ALTER TABLE kit_all_columns_pgsql ADD COLUMN status my_status NOT NULL" + "ALTER TABLE kit_all_columns_pgsql ADD COLUMN status my_status NOT NULL", ); }; @@ -53,7 +53,7 @@ private function verify(callable $migrateTemplates, callable $generateMigrations $this->assertFileEqualsIgnoringOrder( $this->getStorageSqlPath('expected.sql'), - $this->getStorageSqlPath('actual.sql') + $this->getStorageSqlPath('actual.sql'), ); } } diff --git a/tests/Feature/SQLSrv/CommandTest.php b/tests/Feature/SQLSrv/CommandTest.php index c5e03b92..ca9a1672 100644 --- a/tests/Feature/SQLSrv/CommandTest.php +++ b/tests/Feature/SQLSrv/CommandTest.php @@ -37,7 +37,7 @@ public function testRun(): void $this->migrateGeneral('sqlsrv'); DB::statement( - "ALTER TABLE all_columns_sqlsrv ADD accountnumber accountnumber NOT NULL" + "ALTER TABLE all_columns_sqlsrv ADD accountnumber accountnumber NOT NULL", ); }; @@ -55,7 +55,7 @@ public function testUnsupportedColumns(): void money money, smallmoney smallmoney, [name.dot] varchar(255) - )" + )", ); $this->generateMigrations(); @@ -65,17 +65,17 @@ public function testUnsupportedColumns(): void $this->assertStringContainsString( '$table->decimal(\'money\', 19, 4)->nullable();', - $migration->getContents() + $migration->getContents(), ); $this->assertStringContainsString( '$table->decimal(\'smallmoney\', 10, 4)->nullable();', - $migration->getContents() + $migration->getContents(), ); $this->assertStringContainsString( '$table->string(\'name.dot\')->nullable()', - $migration->getContents() + $migration->getContents(), ); } @@ -150,9 +150,7 @@ public function testSkipVendor(): void $this->assertContains($vendor, $tables); } - $tablesWithoutVendors = (new Collection($tables))->filter(function ($table) use ($vendors) { - return !in_array($table, $vendors); - }) + $tablesWithoutVendors = (new Collection($tables))->filter(static fn ($table) => !in_array($table, $vendors)) ->values() ->all(); @@ -192,7 +190,7 @@ private function verify(callable $migrateTemplates, callable $generateMigrations $this->assertFileEqualsIgnoringOrder( $this->getStorageSqlPath('expected.sql'), - $this->getStorageSqlPath('actual.sql') + $this->getStorageSqlPath('actual.sql'), ); } } diff --git a/tests/Feature/SQLSrv/SQLSrvTestCase.php b/tests/Feature/SQLSrv/SQLSrvTestCase.php index 72bfcc40..40feaf92 100644 --- a/tests/Feature/SQLSrv/SQLSrvTestCase.php +++ b/tests/Feature/SQLSrv/SQLSrvTestCase.php @@ -75,7 +75,7 @@ protected function dumpSchemaAs(string $destination): void config('database.connections.sqlsrv.password'), config('database.connections.sqlsrv.database'), implode('', $sqls), - $this->getStorageSqlPath('temp.sql') + $this->getStorageSqlPath('temp.sql'), ); exec($command); @@ -103,7 +103,7 @@ protected function dropAllViews(): void SELECT @sql += 'DROP VIEW ' + QUOTENAME(OBJECT_SCHEMA_NAME(object_id)) + '.' + QUOTENAME(name) + ';' FROM sys.views; - EXEC sp_executesql @sql;" + EXEC sp_executesql @sql;", ); } @@ -127,7 +127,7 @@ protected function getAllProcedures(): array INNER JOIN sys.sql_modules ON (sys.sysobjects.id = sys.sql_modules.object_id) WHERE type = 'P' AND definition IS NOT NULL - ORDER BY name" + ORDER BY name", ); } diff --git a/tests/Feature/SQLite/CommandTest.php b/tests/Feature/SQLite/CommandTest.php index d78771d4..fe72b7ec 100644 --- a/tests/Feature/SQLite/CommandTest.php +++ b/tests/Feature/SQLite/CommandTest.php @@ -81,9 +81,7 @@ public function testSkipVendor(): void $this->assertContains($vendor, $tables); } - $tablesWithoutVendors = (new Collection($tables))->filter(function ($table) use ($vendors) { - return !in_array($table, $vendors); - }) + $tablesWithoutVendors = (new Collection($tables))->filter(static fn ($table) => !in_array($table, $vendors)) ->values() ->all(); @@ -120,7 +118,7 @@ private function verify(callable $migrateTemplates, callable $generateMigrations $this->assertFileEqualsIgnoringOrder( $this->getStorageSqlPath('expected.sql'), - $this->getStorageSqlPath('actual.sql') + $this->getStorageSqlPath('actual.sql'), ); } } diff --git a/tests/Feature/SQLite/SQLiteTestCase.php b/tests/Feature/SQLite/SQLiteTestCase.php index 2591282c..599dee5a 100644 --- a/tests/Feature/SQLite/SQLiteTestCase.php +++ b/tests/Feature/SQLite/SQLiteTestCase.php @@ -31,7 +31,7 @@ protected function dumpSchemaAs(string $destination): void $command = sprintf( 'sqlite3 %s .dump > %s', config('database.connections.sqlite.database'), - $destination + $destination, ); exec($command); } diff --git a/tests/MigrationWriterTest.php b/tests/MigrationWriterTest.php index 631a3669..67c88ef9 100644 --- a/tests/MigrationWriterTest.php +++ b/tests/MigrationWriterTest.php @@ -21,7 +21,7 @@ public function testWrite(): void $setting->setDefaultConnection(DB::getDefaultConnection()); $setting->setWithHasTable(false); - $this->mock(TableName::class, function (MockInterface $mock): void { + $this->mock(TableName::class, static function (MockInterface $mock): void { $mock->shouldReceive('stripPrefix') ->andReturn('test'); }); @@ -49,7 +49,7 @@ public function testWrite(): void 'Tester', new Collection([$up]), new Collection([$down]), - MigrationFileType::TABLE() + MigrationFileType::TABLE(), ); $this->assertFileExists(storage_path('migration.php')); diff --git a/tests/Support/CheckLaravelVersionTest.php b/tests/Support/CheckLaravelVersionTest.php index 99a113ae..d77687b8 100644 --- a/tests/Support/CheckLaravelVersionTest.php +++ b/tests/Support/CheckLaravelVersionTest.php @@ -68,10 +68,7 @@ public function testAtLeastLaravel8(): void $this->assertTrue($this->stubInstance()->atLeastLaravel8()); } - /** - * @return object - */ - private function stubInstance() + private function stubInstance(): object { return new class () { use CheckLaravelVersion; diff --git a/tests/TestCase.php b/tests/TestCase.php index a460ed79..c7adf102 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -43,11 +43,9 @@ public static function assertFileEqualsIgnoringOrder(string $expected, string $a static::assertFileExists($expected, $message); static::assertFileExists($actual, $message); - $removeLastComma = function (string $line): string { - return Str::endsWith($line, ',' . PHP_EOL) + $removeLastComma = static fn (string $line): string => Str::endsWith($line, ',' . PHP_EOL) ? Str::replaceLast(',' . PHP_EOL, PHP_EOL, $line) : $line; - }; $expectedFiles = file($expected) ?: []; $expectedContent = new Collection($expectedFiles); From 061542aac3fed6e3df275238992b723a6ebfb660 Mon Sep 17 00:00:00 2001 From: Kit Loong Date: Wed, 7 Feb 2024 21:34:15 +0800 Subject: [PATCH 04/20] Set default to null --- src/DBAL/Connection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DBAL/Connection.php b/src/DBAL/Connection.php index 2db5fa41..508a09f3 100644 --- a/src/DBAL/Connection.php +++ b/src/DBAL/Connection.php @@ -21,7 +21,7 @@ class Connection /** * The instance of Doctrine connection. */ - protected ?DoctrineConnection $doctrineConnection; + protected ?DoctrineConnection $doctrineConnection = null; /** * Get the Doctrine DBAL database connection instance. From ae72cd82ab75ae2694ee6fa13b4e0a3bcc75f6d4 Mon Sep 17 00:00:00 2001 From: Kit Loong Date: Wed, 7 Feb 2024 22:35:23 +0800 Subject: [PATCH 05/20] Update exclude --- phpunit.xml.dist | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index b18123a7..95d47657 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -17,7 +17,8 @@ src - src/KitLoong/MigrationsGenerator/Types + src/DBAL/Types + src/DBAL/PDO From 16871caa914e1320117a790f711325f5ea4e1295 Mon Sep 17 00:00:00 2001 From: Kit Loong Date: Thu, 8 Feb 2024 19:22:06 +0800 Subject: [PATCH 06/20] Tidy test --- tests/Feature/FeatureTestCase.php | 57 ++---- tests/Feature/MariaDB/CommandTest.php | 12 +- tests/Feature/MySQL57/CommandTest.php | 162 +++++++++--------- tests/Feature/MySQL57/DBConnectionTest.php | 19 +- tests/Feature/MySQL57/TablePrefixTest.php | 4 +- tests/Feature/MySQL8/CommandTest.php | 26 ++- tests/Feature/PgSQL/CommandTest.php | 56 +++--- tests/Feature/PgSQL/TablePrefixTest.php | 6 +- tests/Feature/SQLSrv/CommandTest.php | 34 ++-- tests/Feature/SQLite/CommandTest.php | 26 ++- tests/TestCase.php | 4 - ...0000_expected_create_collations_table.php} | 8 +- ...expected_create_user_collations_table.php} | 8 +- ...000_expected_create_all_columns_table.php} | 8 +- ...0000_expected_create_increments_table.php} | 30 ++-- ..._000000_expected_create_primary_table.php} | 24 +-- ...000_expected_create_quoted_name_table.php} | 8 +- ...d_create_reserved_name_modifier_table.php} | 12 +- ...te_reserved_name_with_precision_table.php} | 8 +- ...0000_expected_create_test_index_table.php} | 8 +- ...0000_expected_create_timestamps_table.php} | 44 ++--- ...21_000000_expected_create_users_table.php} | 8 +- ...cted_create_quoted_name_foreign_table.php} | 10 +- ...0001_expected_create_quoted_name_proc.php} | 18 +- ...0001_expected_create_quoted_name_view.php} | 10 +- ...01_expected_create_user_profile_table.php} | 22 +-- ..._21_000001_expected_create_users_view.php} | 8 +- ...8_08_08_100000_create_telescope_table.php} | 18 +- ...1_create_personal_access_tokens_table.php} | 8 +- 29 files changed, 300 insertions(+), 366 deletions(-) rename tests/resources/database/migrations/collation/{2020_03_21_000000_expected_create_collations_db_table.php => 2020_03_21_000000_expected_create_collations_table.php} (94%) rename tests/resources/database/migrations/collation/{2020_03_21_000000_expected_create_user_collations_db_table.php => 2020_03_21_000000_expected_create_user_collations_table.php} (84%) rename tests/resources/database/migrations/general/{2020_03_21_000000_expected_create_all_columns_db_table.php => 2020_03_21_000000_expected_create_all_columns_table.php} (98%) rename tests/resources/database/migrations/general/{2020_03_21_000000_expected_create_increments_db_table.php => 2020_03_21_000000_expected_create_increments_table.php} (53%) rename tests/resources/database/migrations/general/{2020_03_21_000000_expected_create_primary_db_table.php => 2020_03_21_000000_expected_create_primary_table.php} (59%) rename tests/resources/database/migrations/general/{2020_03_21_000000_expected_create_quoted_name_db_table.php => 2020_03_21_000000_expected_create_quoted_name_table.php} (74%) rename tests/resources/database/migrations/general/{2020_03_21_000000_expected_create_reserved_name_modifier_db_table.php => 2020_03_21_000000_expected_create_reserved_name_modifier_table.php} (70%) rename tests/resources/database/migrations/general/{2020_03_21_000000_expected_create_reserved_name_with_precision_db_table.php => 2020_03_21_000000_expected_create_reserved_name_with_precision_table.php} (74%) rename tests/resources/database/migrations/general/{2020_03_21_000000_expected_create_test_index_db_table.php => 2020_03_21_000000_expected_create_test_index_table.php} (94%) rename tests/resources/database/migrations/general/{2020_03_21_000000_expected_create_timestamps_db_table.php => 2020_03_21_000000_expected_create_timestamps_table.php} (63%) rename tests/resources/database/migrations/general/{2020_03_21_000000_expected_create_users_db_table.php => 2020_03_21_000000_expected_create_users_table.php} (84%) rename tests/resources/database/migrations/general/{2020_03_21_000001_expected_create_quoted_name_foreign_db_table.php => 2020_03_21_000001_expected_create_quoted_name_foreign_table.php} (79%) rename tests/resources/database/migrations/general/{2020_03_21_000001_expected_create_quoted_name_db_proc.php => 2020_03_21_000001_expected_create_quoted_name_proc.php} (78%) rename tests/resources/database/migrations/general/{2020_03_21_000001_expected_create_quoted_name_db_view.php => 2020_03_21_000001_expected_create_quoted_name_view.php} (78%) rename tests/resources/database/migrations/general/{2020_03_21_000001_expected_create_user_profile_db_table.php => 2020_03_21_000001_expected_create_user_profile_table.php} (75%) rename tests/resources/database/migrations/general/{2020_03_21_000001_expected_create_users_db_view.php => 2020_03_21_000001_expected_create_users_view.php} (63%) rename tests/resources/database/migrations/vendors/{2018_08_08_100000_create_telescope_db_table.php => 2018_08_08_100000_create_telescope_table.php} (76%) rename tests/resources/database/migrations/vendors/{2019_12_14_000001_create_personal_access_tokens_db_table.php => 2019_12_14_000001_create_personal_access_tokens_table.php} (78%) diff --git a/tests/Feature/FeatureTestCase.php b/tests/Feature/FeatureTestCase.php index ad0fbe3c..d9cd0b99 100644 --- a/tests/Feature/FeatureTestCase.php +++ b/tests/Feature/FeatureTestCase.php @@ -92,71 +92,36 @@ protected function getStorageSqlPath(string $path = ''): string return storage_path('sql') . ($path ? DIRECTORY_SEPARATOR . $path : $path); } - protected function migrateGeneral(string $connection): void + protected function migrateGeneral(): void { - $this->migrateFromTemplate($connection, base_path('tests/resources/database/migrations/general')); + $this->migrateFromTemplate(base_path('tests/resources/database/migrations/general')); } - protected function migrateCollation(string $connection): void + protected function migrateCollation(): void { - $this->migrateFromTemplate($connection, base_path('tests/resources/database/migrations/collation')); + $this->migrateFromTemplate(base_path('tests/resources/database/migrations/collation')); } - protected function migrateVendors(string $connection): void + protected function migrateVendors(): void { - $this->migrateFromVendorsTemplate($connection, base_path('tests/resources/database/migrations/vendors')); + $this->migrateFromVendorsTemplate(base_path('tests/resources/database/migrations/vendors')); } - protected function migrateFromTemplate(string $connection, string $templatePath): void + protected function migrateFromTemplate(string $templatePath): void { File::copyDirectory($templatePath, $this->getStorageFromPath()); - - foreach (File::files($this->getStorageFromPath()) as $file) { - $content = str_replace([ - '[db]', - '_DB_', - ], [ - $connection, - ucfirst("$connection"), - ], $file->getContents()); - - File::put($this->getStorageFromPath($file->getBasename()), $content); - File::move( - $this->getStorageFromPath($file->getBasename()), - $this->getStorageFromPath(str_replace('_db_', "_{$connection}_", $file->getBasename())), - ); - } - - $this->runMigrationsFrom($connection, $this->getStorageFromPath()); + $this->runMigrationsFrom($this->getStorageFromPath()); } - protected function migrateFromVendorsTemplate(string $connection, string $templatePath): void + protected function migrateFromVendorsTemplate(string $templatePath): void { File::copyDirectory($templatePath, $this->getStorageFromVendorsPath()); - - foreach (File::files($this->getStorageFromVendorsPath()) as $file) { - $content = str_replace([ - '[db]', - '_DB_', - ], [ - $connection, - ucfirst("$connection"), - ], $file->getContents()); - - File::put($this->getStorageFromVendorsPath($file->getBasename()), $content); - File::move( - $this->getStorageFromVendorsPath($file->getBasename()), - $this->getStorageFromVendorsPath(str_replace('_db_', "_{$connection}_", $file->getBasename())), - ); - } - - $this->runMigrationsFrom($connection, $this->getStorageFromVendorsPath()); + $this->runMigrationsFrom($this->getStorageFromVendorsPath()); } - protected function runMigrationsFrom(string $connection, string $path): void + protected function runMigrationsFrom(string $path): void { $this->artisan('migrate', [ - '--database' => $connection, '--realpath' => true, '--path' => $path, ]); diff --git a/tests/Feature/MariaDB/CommandTest.php b/tests/Feature/MariaDB/CommandTest.php index 1923b2f3..188c7353 100644 --- a/tests/Feature/MariaDB/CommandTest.php +++ b/tests/Feature/MariaDB/CommandTest.php @@ -5,10 +5,6 @@ use Illuminate\Support\Facades\DB; use KitLoong\MigrationsGenerator\Support\CheckMigrationMethod; -/** - * @runTestsInSeparateProcesses - * @preserveGlobalState disabled - */ class CommandTest extends MariaDBTestCase { use CheckMigrationMethod; @@ -16,7 +12,7 @@ class CommandTest extends MariaDBTestCase public function testRun(): void { $migrateTemplates = function (): void { - $this->migrateGeneral('mariadb'); + $this->migrateGeneral(); }; $generateMigrations = function (): void { @@ -28,7 +24,7 @@ public function testRun(): void public function testDown(): void { - $this->migrateGeneral('mariadb'); + $this->migrateGeneral(); $this->truncateMigrationsTable(); @@ -47,7 +43,7 @@ public function testDown(): void public function testCollation(): void { $migrateTemplates = function (): void { - $this->migrateCollation('mariadb'); + $this->migrateCollation(); }; $generateMigrations = function (): void { @@ -70,7 +66,7 @@ private function verify(callable $migrateTemplates, callable $generateMigrations $this->refreshDatabase(); - $this->runMigrationsFrom('mariadb', $this->getStorageMigrationsPath()); + $this->runMigrationsFrom($this->getStorageMigrationsPath()); $this->truncateMigrationsTable(); $this->dumpSchemaAs($this->getStorageSqlPath('actual.sql')); diff --git a/tests/Feature/MySQL57/CommandTest.php b/tests/Feature/MySQL57/CommandTest.php index 9adad644..1bd2b218 100644 --- a/tests/Feature/MySQL57/CommandTest.php +++ b/tests/Feature/MySQL57/CommandTest.php @@ -13,10 +13,6 @@ use KitLoong\MigrationsGenerator\Support\CheckMigrationMethod; use Throwable; -/** - * @runTestsInSeparateProcesses - * @preserveGlobalState disabled - */ class CommandTest extends MySQL57TestCase { use CheckMigrationMethod; @@ -24,7 +20,7 @@ class CommandTest extends MySQL57TestCase public function testRun(): void { $migrateTemplates = function (): void { - $this->migrateGeneral('mysql57'); + $this->migrateGeneral(); }; $generateMigrations = function (): void { @@ -36,7 +32,7 @@ public function testRun(): void public function testDown(): void { - $this->migrateGeneral('mysql57'); + $this->migrateGeneral(); $this->truncateMigrationsTable(); @@ -55,7 +51,7 @@ public function testDown(): void public function testCollation(): void { $migrateTemplates = function (): void { - $this->migrateCollation('mysql57'); + $this->migrateCollation(); }; $generateMigrations = function (): void { @@ -68,7 +64,7 @@ public function testCollation(): void public function testSquashUp(): void { $migrateTemplates = function (): void { - $this->migrateGeneral('mysql57'); + $this->migrateGeneral(); }; $generateMigrations = function (): void { @@ -80,7 +76,7 @@ public function testSquashUp(): void public function testSquashDown(): void { - $this->migrateGeneral('mysql57'); + $this->migrateGeneral(); $this->truncateMigrationsTable(); @@ -98,21 +94,21 @@ public function testSquashDown(): void public function testTables(): void { - $this->migrateGeneral('mysql57'); + $this->migrateGeneral(); $this->truncateMigrationsTable(); $this->generateMigrations([ '--tables' => implode(',', [ - 'all_columns_mysql57', - 'users_mysql57', - 'users_mysql57_view', + 'all_columns', + 'users', + 'users_view', ]), ]); $this->refreshDatabase(); - $this->runMigrationsFrom('mysql57', $this->getStorageMigrationsPath()); + $this->runMigrationsFrom($this->getStorageMigrationsPath()); $tables = $this->getTableNames(); $views = $this->getViewNames(); @@ -120,25 +116,25 @@ public function testTables(): void $this->assertCount(3, $tables); $this->assertCount(1, $views); - $this->assertContains('all_columns_mysql57', $tables); + $this->assertContains('all_columns', $tables); $this->assertContains('migrations', $tables); - $this->assertContains('users_mysql57', $tables); - $this->assertContains('users_mysql57_view', $views); + $this->assertContains('users', $tables); + $this->assertContains('users_view', $views); } public function testIgnore(): void { - $this->migrateGeneral('mysql57'); + $this->migrateGeneral(); $this->truncateMigrationsTable(); $allAssets = count($this->getTableNames()) + count($this->getViewNames()); $ignores = [ - 'quoted-name-foreign-mysql57', - 'increments_mysql57', - 'timestamps_mysql57', - 'users_mysql57_view', + 'quoted-name-foreign', + 'increments', + 'timestamps', + 'users_view', ]; $ignoreNotExists = ['not_exists']; @@ -149,7 +145,7 @@ public function testIgnore(): void $this->refreshDatabase(); - $this->runMigrationsFrom('mysql57', $this->getStorageMigrationsPath()); + $this->runMigrationsFrom($this->getStorageMigrationsPath()); $tables = $this->getTableNames(); $views = $this->getViewNames(); @@ -160,51 +156,51 @@ public function testIgnore(): void public function testDefaultIndexNames(): void { - $this->migrateGeneral('mysql57'); + $this->migrateGeneral(); $this->truncateMigrationsTable(); $this->generateMigrations([ - '--tables' => 'test_index_mysql57', + '--tables' => 'test_index', '--default-index-names' => true, ]); $this->refreshDatabase(); - $this->runMigrationsFrom('mysql57', $this->getStorageMigrationsPath()); + $this->runMigrationsFrom($this->getStorageMigrationsPath()); $indexes = app(MySQLSchema::class) - ->getTable('test_index_mysql57') + ->getTable('test_index') ->getIndexes(); $actualIndexes = $indexes->map(static fn (Index $index) => $index->getName())->toArray(); $expectedIndexes = [ '', // PRIMARY - 'test_index_mysql57_chain_index', - 'test_index_mysql57_chain_unique', - 'test_index_mysql57_col_multi1_col_multi2_index', -// 'test_index_mysql57_col_multi1_col_multi2(16)_index', - 'test_index_mysql57_col_multi1_col_multi2_unique', - 'test_index_mysql57_col_multi_custom1_col_multi_custom2_index', - 'test_index_mysql57_col_multi_custom1_col_multi_custom2_unique', - 'test_index_mysql57_column_hyphen_index', - 'test_index_mysql57_index_custom_index', - 'test_index_mysql57_index_index', - 'test_index_mysql57_spatial_index_custom_spatialindex', - 'test_index_mysql57_spatial_index_spatialindex', - 'test_index_mysql57_unique_custom_unique', - 'test_index_mysql57_unique_unique', -// 'test_index_mysql57_with_length(16)_index', -// 'test_index_mysql57_with_length_custom(16)_index', + 'test_index_chain_index', + 'test_index_chain_unique', + 'test_index_col_multi1_col_multi2_index', +// 'test_index_col_multi1_col_multi2(16)_index', + 'test_index_col_multi1_col_multi2_unique', + 'test_index_col_multi_custom1_col_multi_custom2_index', + 'test_index_col_multi_custom1_col_multi_custom2_unique', + 'test_index_column_hyphen_index', + 'test_index_index_custom_index', + 'test_index_index_index', + 'test_index_spatial_index_custom_spatialindex', + 'test_index_spatial_index_spatialindex', + 'test_index_unique_custom_unique', + 'test_index_unique_unique', +// 'test_index_with_length(16)_index', +// 'test_index_with_length_custom(16)_index', ]; if ($this->hasFullText()) { $expectedIndexes = array_merge($expectedIndexes, [ - 'test_index_mysql57_chain_fulltext', - 'test_index_mysql57_col_multi1_col_multi2_fulltext', - 'test_index_mysql57_fulltext_custom_fulltext', - 'test_index_mysql57_fulltext_fulltext', + 'test_index_chain_fulltext', + 'test_index_col_multi1_col_multi2_fulltext', + 'test_index_fulltext_custom_fulltext', + 'test_index_fulltext_fulltext', ]); } @@ -219,7 +215,7 @@ public function testDefaultIndexNames(): void public function testDefaultFKNames(): void { - $this->migrateGeneral('mysql57'); + $this->migrateGeneral(); $this->truncateMigrationsTable(); @@ -227,9 +223,9 @@ public function testDefaultFKNames(): void $this->refreshDatabase(); - $this->runMigrationsFrom('mysql57', $this->getStorageMigrationsPath()); + $this->runMigrationsFrom($this->getStorageMigrationsPath()); - $foreignKeys = app(MySQLSchema::class)->getTableForeignKeys('user_profile_mysql57'); + $foreignKeys = app(MySQLSchema::class)->getTableForeignKeys('user_profile'); $foreignKeyNames = $foreignKeys->map(static fn (ForeignKey $foreignKey) => $foreignKey->getName()) ->sort() ->values() @@ -237,11 +233,11 @@ public function testDefaultFKNames(): void $this->assertSame( [ - 'user_profile_mysql57_user_id_fk_constraint_foreign', - 'user_profile_mysql57_user_id_fk_custom_foreign', - 'user_profile_mysql57_user_id_foreign', - 'user_profile_mysql57_user_id_user_sub_id_fk_custom_foreign', - 'user_profile_mysql57_user_id_user_sub_id_foreign', + 'user_profile_user_id_fk_constraint_foreign', + 'user_profile_user_id_fk_custom_foreign', + 'user_profile_user_id_foreign', + 'user_profile_user_id_user_sub_id_fk_custom_foreign', + 'user_profile_user_id_user_sub_id_foreign', ], $foreignKeyNames, ); @@ -252,7 +248,7 @@ public function testDefaultFKNames(): void public function testDate(): void { $migrateTemplates = function (): void { - $this->migrateGeneral('mysql57'); + $this->migrateGeneral(); }; $generateMigrations = function (): void { @@ -264,7 +260,7 @@ public function testDate(): void public function testTableFilenameAndViewFilename(): void { - $this->migrateGeneral('mysql57'); + $this->migrateGeneral(); $this->truncateMigrationsTable(); @@ -279,13 +275,13 @@ public function testTableFilenameAndViewFilename(): void $migrations[] = substr($migration->getFilenameWithoutExtension(), 18); } - $this->assertContains('custom_all_columns_mysql57_table', $migrations); - $this->assertContains('custom_users_mysql57_view_view', $migrations); + $this->assertContains('custom_all_columns_table', $migrations); + $this->assertContains('custom_users_view_view', $migrations); } public function testProcedureFilename(): void { - $this->migrateGeneral('mysql57'); + $this->migrateGeneral(); $this->truncateMigrationsTable(); @@ -297,12 +293,12 @@ public function testProcedureFilename(): void $migrations[] = substr($migration->getFilenameWithoutExtension(), 18); } - $this->assertContains('custom_findNameWithHyphenmysql57_proc', $migrations); + $this->assertContains('custom_findNameWithHyphen_proc', $migrations); } public function testFKFilename(): void { - $this->migrateGeneral('mysql57'); + $this->migrateGeneral(); $this->truncateMigrationsTable(); @@ -314,12 +310,12 @@ public function testFKFilename(): void $migrations[] = substr($migration->getFilenameWithoutExtension(), 18); } - $this->assertContains('custom_user_profile_mysql57_table', $migrations); + $this->assertContains('custom_user_profile_table', $migrations); } public function testSkipView(): void { - $this->migrateGeneral('mysql57'); + $this->migrateGeneral(); $this->truncateMigrationsTable(); @@ -332,13 +328,13 @@ public function testSkipView(): void $migrations[] = substr($migration->getFilenameWithoutExtension(), $prefixLength); } - $this->assertContains('create_all_columns_mysql57_table', $migrations); - $this->assertNotContains('create_users_mysql57_view_view', $migrations); + $this->assertContains('create_all_columns_table', $migrations); + $this->assertNotContains('create_users_view_view', $migrations); } public function testSkipProcedure(): void { - $this->migrateGeneral('mysql57'); + $this->migrateGeneral(); $this->truncateMigrationsTable(); @@ -351,14 +347,14 @@ public function testSkipProcedure(): void $migrations[] = substr($migration->getFilenameWithoutExtension(), $prefixLength); } - $this->assertContains('create_all_columns_mysql57_table', $migrations); + $this->assertContains('create_all_columns_table', $migrations); $this->assertNotContains('create_getNameWithHyphen_proc', $migrations); } public function testWithHasTable(): void { $migrateTemplates = function (): void { - $this->migrateGeneral('mysql57'); + $this->migrateGeneral(); }; $generateMigrations = function (): void { @@ -371,7 +367,7 @@ public function testWithHasTable(): void public function testWithHasTableSquash(): void { $migrateTemplates = function (): void { - $this->migrateGeneral('mysql57'); + $this->migrateGeneral(); }; $generateMigrations = function (): void { @@ -383,7 +379,7 @@ public function testWithHasTableSquash(): void public function testWillCreateMigrationTable(): void { - $this->migrateGeneral('mysql57'); + $this->migrateGeneral(); Schema::dropIfExists('migrations'); $this->generateMigrations(); @@ -393,7 +389,7 @@ public function testWillCreateMigrationTable(): void public function testNoInteraction(): void { - $this->migrateGeneral('mysql57'); + $this->migrateGeneral(); $this->truncateMigrationsTable(); $this->dumpSchemaAs($this->getStorageSqlPath('expected.sql')); @@ -416,7 +412,7 @@ public function testNoInteraction(): void public function testSkipLog(): void { - $this->migrateGeneral('mysql57'); + $this->migrateGeneral(); $this->truncateMigrationsTable(); $this->dumpSchemaAs($this->getStorageSqlPath('expected.sql')); @@ -439,7 +435,7 @@ public function testSkipLog(): void public function testLogWithBatch0(): void { - $this->migrateGeneral('mysql57'); + $this->migrateGeneral(); $this->truncateMigrationsTable(); $this->dumpSchemaAs($this->getStorageSqlPath('expected.sql')); @@ -465,7 +461,7 @@ public function testLogWithBatch0(): void public function testLogWithBatch99(): void { - $this->migrateGeneral('mysql57'); + $this->migrateGeneral(); $this->truncateMigrationsTable(); $this->dumpSchemaAs($this->getStorageSqlPath('expected.sql')); @@ -507,9 +503,9 @@ public function testLogWithBatchNaN(): void public function testSkipVendor(): void { - $this->migrateGeneral('mysql57'); + $this->migrateGeneral(); - $this->migrateVendors('mysql57'); + $this->migrateVendors(); // Load migrations from vendors path to mock vendors migration. // Loaded migrations should not be generated. @@ -518,10 +514,10 @@ public function testSkipVendor(): void $tables = $this->getTableNames(); $vendors = [ - 'personal_access_tokens_mysql57', - 'telescope_entries_mysql57', - 'telescope_entries_tags_mysql57', - 'telescope_monitoring_mysql57', + 'personal_access_tokens', + 'telescope_entries', + 'telescope_entries_tags', + 'telescope_monitoring', ]; foreach ($vendors as $vendor) { @@ -538,7 +534,7 @@ public function testSkipVendor(): void $this->refreshDatabase(); - $this->runMigrationsFrom('mysql57', $this->getStorageMigrationsPath()); + $this->runMigrationsFrom($this->getStorageMigrationsPath()); $generatedTables = $this->getTableNames(); @@ -558,7 +554,7 @@ private function verify(callable $migrateTemplates, callable $generateMigrations $this->refreshDatabase(); - $this->runMigrationsFrom('mysql57', $this->getStorageMigrationsPath()); + $this->runMigrationsFrom($this->getStorageMigrationsPath()); $this->truncateMigrationsTable(); $this->dumpSchemaAs($this->getStorageSqlPath('actual.sql')); diff --git a/tests/Feature/MySQL57/DBConnectionTest.php b/tests/Feature/MySQL57/DBConnectionTest.php index 807337d3..dbce951b 100644 --- a/tests/Feature/MySQL57/DBConnectionTest.php +++ b/tests/Feature/MySQL57/DBConnectionTest.php @@ -7,10 +7,6 @@ use Illuminate\Support\Facades\Schema; use PDO; -/** - * @runTestsInSeparateProcesses - * @preserveGlobalState disabled - */ class DBConnectionTest extends MySQL57TestCase { /** @@ -56,13 +52,10 @@ public function tearDown(): void public function testDBConnection(): void { $migrateTemplates = function (): void { - $this->migrateGeneral('mysql57'); + $this->migrateGeneral(); }; $generateMigrations = function (): void { - // Needed for Laravel 6 and below. - DB::setDefaultConnection('mysql8'); - $this->generateMigrations(['--connection' => 'mysql57']); $totalMigrations = count(File::allFiles($this->getStorageMigrationsPath())); @@ -80,9 +73,9 @@ public function testDBConnection(): void public function testLogMigrationToAnotherSource(): void { - $this->migrateGeneral('mysql57'); + DB::setDefaultConnection('mysql57'); + $this->migrateGeneral(); - // Needed for Laravel 6 and below. DB::setDefaultConnection('mysql8'); $this->artisan( @@ -109,19 +102,23 @@ public function testLogMigrationToAnotherSource(): void private function verify(callable $migrateTemplates, callable $generateMigrations): void { + DB::setDefaultConnection('mysql57'); $migrateTemplates(); DB::connection('mysql57')->table('migrations')->truncate(); $this->dumpSchemaAs($this->getStorageSqlPath('expected.sql')); + DB::setDefaultConnection('mysql8'); $generateMigrations(); $this->assertMigrations(); + DB::setDefaultConnection('mysql57'); $this->refreshDatabase(); - $this->runMigrationsFrom('mysql57', $this->getStorageMigrationsPath()); + $this->runMigrationsFrom($this->getStorageMigrationsPath()); + DB::setDefaultConnection('mysql57'); DB::connection('mysql57')->table('migrations')->truncate(); $this->dumpSchemaAs($this->getStorageSqlPath('actual.sql')); diff --git a/tests/Feature/MySQL57/TablePrefixTest.php b/tests/Feature/MySQL57/TablePrefixTest.php index 322aa9e0..2954cd3f 100644 --- a/tests/Feature/MySQL57/TablePrefixTest.php +++ b/tests/Feature/MySQL57/TablePrefixTest.php @@ -17,7 +17,7 @@ protected function getEnvironmentSetUp($app): void public function testTablePrefix(): void { $migrateTemplates = function (): void { - $this->migrateGeneral('mysql57'); + $this->migrateGeneral(); }; $generateMigrations = function (): void { @@ -40,7 +40,7 @@ private function verify(callable $migrateTemplates, callable $generateMigrations $this->refreshDatabase(); - $this->runMigrationsFrom('mysql57', $this->getStorageMigrationsPath()); + $this->runMigrationsFrom($this->getStorageMigrationsPath()); $this->truncateMigrationsTable(); $this->dumpSchemaAs($this->getStorageSqlPath('actual.sql')); diff --git a/tests/Feature/MySQL8/CommandTest.php b/tests/Feature/MySQL8/CommandTest.php index f006fa92..cd84211e 100644 --- a/tests/Feature/MySQL8/CommandTest.php +++ b/tests/Feature/MySQL8/CommandTest.php @@ -5,16 +5,12 @@ use Illuminate\Support\Collection; use Illuminate\Support\Facades\DB; -/** - * @runTestsInSeparateProcesses - * @preserveGlobalState disabled - */ class CommandTest extends MySQL8TestCase { public function testRun(): void { $migrateTemplates = function (): void { - $this->migrateGeneral('mysql8'); + $this->migrateGeneral(); }; $generateMigrations = function (): void { @@ -26,7 +22,7 @@ public function testRun(): void public function testDown(): void { - $this->migrateGeneral('mysql8'); + $this->migrateGeneral(); $this->truncateMigrationsTable(); @@ -45,7 +41,7 @@ public function testDown(): void public function testCollation(): void { $migrateTemplates = function (): void { - $this->migrateCollation('mysql8'); + $this->migrateCollation(); }; $generateMigrations = function (): void { @@ -57,9 +53,9 @@ public function testCollation(): void public function testSkipVendor(): void { - $this->migrateGeneral('mysql8'); + $this->migrateGeneral(); - $this->migrateVendors('mysql8'); + $this->migrateVendors(); // Load migrations from vendors path to mock vendors migration. // Loaded migrations should not be generated. @@ -68,10 +64,10 @@ public function testSkipVendor(): void $tables = $this->getTableNames(); $vendors = [ - 'personal_access_tokens_mysql8', - 'telescope_entries_mysql8', - 'telescope_entries_tags_mysql8', - 'telescope_monitoring_mysql8', + 'personal_access_tokens', + 'telescope_entries', + 'telescope_entries_tags', + 'telescope_monitoring', ]; foreach ($vendors as $vendor) { @@ -88,7 +84,7 @@ public function testSkipVendor(): void $this->refreshDatabase(); - $this->runMigrationsFrom('mysql8', $this->getStorageMigrationsPath()); + $this->runMigrationsFrom($this->getStorageMigrationsPath()); $generatedTables = $this->getTableNames(); @@ -108,7 +104,7 @@ private function verify(callable $migrateTemplates, callable $generateMigrations $this->refreshDatabase(); - $this->runMigrationsFrom('mysql8', $this->getStorageMigrationsPath()); + $this->runMigrationsFrom($this->getStorageMigrationsPath()); $this->truncateMigrationsTable(); $this->dumpSchemaAs($this->getStorageSqlPath('actual.sql')); diff --git a/tests/Feature/PgSQL/CommandTest.php b/tests/Feature/PgSQL/CommandTest.php index f8bdb16f..ccbcb272 100644 --- a/tests/Feature/PgSQL/CommandTest.php +++ b/tests/Feature/PgSQL/CommandTest.php @@ -8,10 +8,6 @@ use Illuminate\Support\Facades\File; use KitLoong\MigrationsGenerator\Support\CheckLaravelVersion; -/** - * @runTestsInSeparateProcesses - * @preserveGlobalState disabled - */ class CommandTest extends PgSQLTestCase { use CheckLaravelVersion; @@ -19,19 +15,19 @@ class CommandTest extends PgSQLTestCase public function testRun(): void { $migrateTemplates = function (): void { - $this->migrateGeneral('pgsql'); + $this->migrateGeneral(); // Test timestamp default now() DB::statement( - "ALTER TABLE all_columns_pgsql ADD COLUMN timestamp_defaultnow timestamp(0) without time zone DEFAULT now() NOT NULL", + "ALTER TABLE all_columns ADD COLUMN timestamp_defaultnow timestamp(0) without time zone DEFAULT now() NOT NULL", ); DB::statement( - "ALTER TABLE all_columns_pgsql ADD COLUMN status my_status NOT NULL", + "ALTER TABLE all_columns ADD COLUMN status my_status NOT NULL", ); DB::statement( - "ALTER TABLE all_columns_pgsql ADD COLUMN timestamp_default_timezone_now timestamp(0) without time zone DEFAULT timezone('Europe/Rome'::text, now()) NOT NULL", + "ALTER TABLE all_columns ADD COLUMN timestamp_default_timezone_now timestamp(0) without time zone DEFAULT timezone('Europe/Rome'::text, now()) NOT NULL", ); }; @@ -57,10 +53,10 @@ public function testRun(): void public function testSquashUp(): void { $migrateTemplates = function (): void { - $this->migrateGeneral('pgsql'); + $this->migrateGeneral(); DB::statement( - "ALTER TABLE all_columns_pgsql ADD COLUMN status my_status NOT NULL", + "ALTER TABLE all_columns ADD COLUMN status my_status NOT NULL", ); }; @@ -74,7 +70,7 @@ public function testSquashUp(): void public function testCollation(): void { $migrateTemplates = function (): void { - $this->migrateCollation('pgsql'); + $this->migrateCollation(); }; $generateMigrations = function (): void { @@ -86,26 +82,26 @@ public function testCollation(): void public function testIgnore(): void { - $this->migrateGeneral('pgsql'); + $this->migrateGeneral(); $this->truncateMigrationsTable(); $this->generateMigrations([ '--ignore' => implode(',', [ - 'name-with-hyphen-pgsql', - 'name-with-hyphen-pgsql_view', + 'name-with-hyphen', + 'name-with-hyphen_view', ]), ]); $this->refreshDatabase(); - $this->runMigrationsFrom('pgsql', $this->getStorageMigrationsPath()); + $this->runMigrationsFrom($this->getStorageMigrationsPath()); $tables = $this->getTableNames(); $views = $this->getViewNames(); - $this->assertNotContains('name-with-hyphen-pgsql', $tables); - $this->assertNotContains('public."name-with-hyphen-pgsql_view"', $views); + $this->assertNotContains('name-with-hyphen', $tables); + $this->assertNotContains('public."name-with-hyphen_view"', $views); } /** @@ -127,7 +123,7 @@ public function testRunWithSearchPath(): void Config::set('database.connections.pgsql.search_path', 'public'); $migrateTemplates = function (): void { - $this->migrateGeneral('pgsql'); + $this->migrateGeneral(); }; $generateMigrations = function (): void { @@ -140,10 +136,10 @@ public function testRunWithSearchPath(): void public function testWithHasTable(): void { $migrateTemplates = function (): void { - $this->migrateGeneral('pgsql'); + $this->migrateGeneral(); DB::statement( - "ALTER TABLE all_columns_pgsql ADD COLUMN status my_status NOT NULL", + "ALTER TABLE all_columns ADD COLUMN status my_status NOT NULL", ); }; @@ -157,10 +153,10 @@ public function testWithHasTable(): void public function testWithHasTableSquash(): void { $migrateTemplates = function (): void { - $this->migrateGeneral('pgsql'); + $this->migrateGeneral(); DB::statement( - "ALTER TABLE all_columns_pgsql ADD COLUMN status my_status NOT NULL", + "ALTER TABLE all_columns ADD COLUMN status my_status NOT NULL", ); }; @@ -173,9 +169,9 @@ public function testWithHasTableSquash(): void public function testSkipVendor(): void { - $this->migrateGeneral('pgsql'); + $this->migrateGeneral(); - $this->migrateVendors('pgsql'); + $this->migrateVendors(); // Load migrations from vendors path to mock vendors migration. // Loaded migrations should not be generated. @@ -184,10 +180,10 @@ public function testSkipVendor(): void $tables = $this->getTableNames(); $vendors = [ - 'personal_access_tokens_pgsql', - 'telescope_entries_pgsql', - 'telescope_entries_tags_pgsql', - 'telescope_monitoring_pgsql', + 'personal_access_tokens', + 'telescope_entries', + 'telescope_entries_tags', + 'telescope_monitoring', ]; foreach ($vendors as $vendor) { @@ -204,7 +200,7 @@ public function testSkipVendor(): void $this->refreshDatabase(); - $this->runMigrationsFrom('pgsql', $this->getStorageMigrationsPath()); + $this->runMigrationsFrom($this->getStorageMigrationsPath()); $generatedTables = $this->getTableNames(); @@ -227,7 +223,7 @@ private function verify(callable $migrateTemplates, callable $generateMigrations $this->refreshDatabase(); - $this->runMigrationsFrom('pgsql', $this->getStorageMigrationsPath()); + $this->runMigrationsFrom($this->getStorageMigrationsPath()); $this->truncateMigrationsTable(); $this->dumpSchemaAs($this->getStorageSqlPath('actual.sql')); diff --git a/tests/Feature/PgSQL/TablePrefixTest.php b/tests/Feature/PgSQL/TablePrefixTest.php index 624be7bd..0d1c317e 100644 --- a/tests/Feature/PgSQL/TablePrefixTest.php +++ b/tests/Feature/PgSQL/TablePrefixTest.php @@ -19,10 +19,10 @@ protected function getEnvironmentSetUp($app): void public function testTablePrefix(): void { $migrateTemplates = function (): void { - $this->migrateGeneral('pgsql'); + $this->migrateGeneral(); DB::statement( - "ALTER TABLE kit_all_columns_pgsql ADD COLUMN status my_status NOT NULL", + "ALTER TABLE kit_all_columns ADD COLUMN status my_status NOT NULL", ); }; @@ -46,7 +46,7 @@ private function verify(callable $migrateTemplates, callable $generateMigrations $this->refreshDatabase(); - $this->runMigrationsFrom('pgsql', $this->getStorageMigrationsPath()); + $this->runMigrationsFrom($this->getStorageMigrationsPath()); $this->truncateMigrationsTable(); $this->dumpSchemaAs($this->getStorageSqlPath('actual.sql')); diff --git a/tests/Feature/SQLSrv/CommandTest.php b/tests/Feature/SQLSrv/CommandTest.php index ca9a1672..f6f55a4f 100644 --- a/tests/Feature/SQLSrv/CommandTest.php +++ b/tests/Feature/SQLSrv/CommandTest.php @@ -6,10 +6,6 @@ use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\File; -/** - * @runTestsInSeparateProcesses - * @preserveGlobalState disabled - */ class CommandTest extends SQLSrvTestCase { protected function setUp(): void @@ -34,10 +30,10 @@ protected function setUp(): void public function testRun(): void { $migrateTemplates = function (): void { - $this->migrateGeneral('sqlsrv'); + $this->migrateGeneral(); DB::statement( - "ALTER TABLE all_columns_sqlsrv ADD accountnumber accountnumber NOT NULL", + "ALTER TABLE all_columns ADD accountnumber accountnumber NOT NULL", ); }; @@ -51,7 +47,7 @@ public function testRun(): void public function testUnsupportedColumns(): void { DB::statement( - "CREATE TABLE custom_sqlsrv ( + "CREATE TABLE custom ( money money, smallmoney smallmoney, [name.dot] varchar(255) @@ -81,7 +77,7 @@ public function testUnsupportedColumns(): void public function testDown(): void { - $this->migrateGeneral('sqlsrv'); + $this->migrateGeneral(); $this->truncateMigrationsTable(); @@ -103,7 +99,7 @@ public function testDown(): void public function testCollation(): void { $migrateTemplates = function (): void { - $this->migrateCollation('sqlsrv'); + $this->migrateCollation(); }; $generateMigrations = function (): void { @@ -115,10 +111,10 @@ public function testCollation(): void public function testGenerateXml(): void { - $this->migrateGeneral('sqlsrv'); + $this->migrateGeneral(); // Test xml column - DB::statement("alter table all_columns_sqlsrv add xml xml"); + DB::statement("alter table all_columns add xml xml"); $this->truncateMigrationsTable(); @@ -129,9 +125,9 @@ public function testGenerateXml(): void public function testSkipVendor(): void { - $this->migrateGeneral('sqlsrv'); + $this->migrateGeneral(); - $this->migrateVendors('sqlsrv'); + $this->migrateVendors(); // Load migrations from vendors path to mock vendors migration. // Loaded migrations should not be generated. @@ -140,10 +136,10 @@ public function testSkipVendor(): void $tables = $this->getTableNames(); $vendors = [ - 'personal_access_tokens_sqlsrv', - 'telescope_entries_sqlsrv', - 'telescope_entries_tags_sqlsrv', - 'telescope_monitoring_sqlsrv', + 'personal_access_tokens', + 'telescope_entries', + 'telescope_entries_tags', + 'telescope_monitoring', ]; foreach ($vendors as $vendor) { @@ -160,7 +156,7 @@ public function testSkipVendor(): void $this->refreshDatabase(); - $this->runMigrationsFrom('sqlsrv', $this->getStorageMigrationsPath()); + $this->runMigrationsFrom($this->getStorageMigrationsPath()); $generatedTables = $this->getTableNames(); @@ -183,7 +179,7 @@ private function verify(callable $migrateTemplates, callable $generateMigrations $this->refreshDatabase(); - $this->runMigrationsFrom('sqlsrv', $this->getStorageMigrationsPath()); + $this->runMigrationsFrom($this->getStorageMigrationsPath()); $this->truncateMigrationsTable(); $this->dumpSchemaAs($this->getStorageSqlPath('actual.sql')); diff --git a/tests/Feature/SQLite/CommandTest.php b/tests/Feature/SQLite/CommandTest.php index fe72b7ec..94df4bed 100644 --- a/tests/Feature/SQLite/CommandTest.php +++ b/tests/Feature/SQLite/CommandTest.php @@ -6,10 +6,6 @@ use Illuminate\Support\Facades\DB; use KitLoong\MigrationsGenerator\Support\CheckMigrationMethod; -/** - * @runTestsInSeparateProcesses - * @preserveGlobalState disabled - */ class CommandTest extends SQLiteTestCase { use CheckMigrationMethod; @@ -17,7 +13,7 @@ class CommandTest extends SQLiteTestCase public function testRun(): void { $migrateTemplates = function (): void { - $this->migrateGeneral('sqlite'); + $this->migrateGeneral(); }; $generateMigrations = function (): void { @@ -29,7 +25,7 @@ public function testRun(): void public function testDown(): void { - $this->migrateGeneral('sqlite'); + $this->migrateGeneral(); $this->truncateMigrationsTable(); @@ -48,7 +44,7 @@ public function testDown(): void // public function testCollation(): void // { // $migrateTemplates = function (): void { -// $this->migrateCollation('sqlite'); +// $this->migrateCollation(); // }; // // $generateMigrations = function (): void { @@ -60,9 +56,9 @@ public function testDown(): void public function testSkipVendor(): void { - $this->migrateGeneral('sqlite'); + $this->migrateGeneral(); - $this->migrateVendors('sqlite'); + $this->migrateVendors(); // Load migrations from vendors path to mock vendors migration. // Loaded migrations should not be generated. @@ -71,10 +67,10 @@ public function testSkipVendor(): void $tables = $this->getTableNames(); $vendors = [ - 'personal_access_tokens_sqlite', - 'telescope_entries_sqlite', - 'telescope_entries_tags_sqlite', - 'telescope_monitoring_sqlite', + 'personal_access_tokens', + 'telescope_entries', + 'telescope_entries_tags', + 'telescope_monitoring', ]; foreach ($vendors as $vendor) { @@ -91,7 +87,7 @@ public function testSkipVendor(): void $this->refreshDatabase(); - $this->runMigrationsFrom('sqlite', $this->getStorageMigrationsPath()); + $this->runMigrationsFrom($this->getStorageMigrationsPath()); $generatedTables = $this->getTableNames(); @@ -111,7 +107,7 @@ private function verify(callable $migrateTemplates, callable $generateMigrations $this->refreshDatabase(); - $this->runMigrationsFrom('sqlite', $this->getStorageMigrationsPath()); + $this->runMigrationsFrom($this->getStorageMigrationsPath()); $this->truncateMigrationsTable(); $this->dumpSchemaAs($this->getStorageSqlPath('actual.sql')); diff --git a/tests/TestCase.php b/tests/TestCase.php index c7adf102..4f6c311e 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -27,10 +27,6 @@ protected function getEnvironmentSetUp($app): void { parent::getEnvironmentSetUp($app); - // Tests run with @runTestsInSeparateProcesses failed since https://github.com/sebastianbergmann/phpunit/commit/3291172e198f044a922af8036378719f71267a51 and https://github.com/php/php-src/pull/11169. - // The root caused is not determined yet, however, by revert `set_error_handler` (https://github.com/laravel/framework/blob/2967d89906708cc7d619fc130e835c8002b7d3e3/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php#L45C20-L45C20) to default seems fix the failed test for now. - restore_error_handler(); - app()->setBasePath(__DIR__ . '/../'); } diff --git a/tests/resources/database/migrations/collation/2020_03_21_000000_expected_create_collations_db_table.php b/tests/resources/database/migrations/collation/2020_03_21_000000_expected_create_collations_table.php similarity index 94% rename from tests/resources/database/migrations/collation/2020_03_21_000000_expected_create_collations_db_table.php rename to tests/resources/database/migrations/collation/2020_03_21_000000_expected_create_collations_table.php index 69de0e6b..07cbc6d4 100644 --- a/tests/resources/database/migrations/collation/2020_03_21_000000_expected_create_collations_db_table.php +++ b/tests/resources/database/migrations/collation/2020_03_21_000000_expected_create_collations_table.php @@ -11,7 +11,7 @@ use KitLoong\MigrationsGenerator\Support\CheckLaravelVersion; use KitLoong\MigrationsGenerator\Tests\TestMigration; -class ExpectedCreateCollations_DB_Table extends TestMigration +return new class extends TestMigration { use CheckLaravelVersion; @@ -22,7 +22,7 @@ class ExpectedCreateCollations_DB_Table extends TestMigration */ public function up() { - Schema::create('collations_[db]', function (Blueprint $table) { + Schema::create('collations', function (Blueprint $table) { $table->charset = 'utf8mb4'; $table->collation = 'utf8mb4_general_ci'; @@ -86,6 +86,6 @@ public function up() */ public function down() { - Schema::dropIfExists('all_columns_[db]'); + Schema::dropIfExists('all_columns'); } -} +}; diff --git a/tests/resources/database/migrations/collation/2020_03_21_000000_expected_create_user_collations_db_table.php b/tests/resources/database/migrations/collation/2020_03_21_000000_expected_create_user_collations_table.php similarity index 84% rename from tests/resources/database/migrations/collation/2020_03_21_000000_expected_create_user_collations_db_table.php rename to tests/resources/database/migrations/collation/2020_03_21_000000_expected_create_user_collations_table.php index 8540b390..496d8196 100644 --- a/tests/resources/database/migrations/collation/2020_03_21_000000_expected_create_user_collations_db_table.php +++ b/tests/resources/database/migrations/collation/2020_03_21_000000_expected_create_user_collations_table.php @@ -8,7 +8,7 @@ use Illuminate\Support\Facades\Schema; use KitLoong\MigrationsGenerator\Tests\TestMigration; -class ExpectedCreateUserCollations_DB_Table extends TestMigration +return new class extends TestMigration { /** * Run the migrations. @@ -17,7 +17,7 @@ class ExpectedCreateUserCollations_DB_Table extends TestMigration */ public function up() { - Schema::create('user_collations_[db]', function (Blueprint $table) { + Schema::create('user_collations', function (Blueprint $table) { $table->unsignedBigInteger('id'); $table->unsignedInteger('sub_id'); $table->string('name'); @@ -40,6 +40,6 @@ public function up() */ public function down() { - Schema::dropIfExists('users_[db]'); + Schema::dropIfExists('users'); } -} +}; diff --git a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_db_table.php b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_table.php similarity index 98% rename from tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_db_table.php rename to tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_table.php index 68a7a9ba..5b5a942e 100644 --- a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_db_table.php +++ b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_table.php @@ -11,7 +11,7 @@ use KitLoong\MigrationsGenerator\Support\CheckMigrationMethod; use KitLoong\MigrationsGenerator\Tests\TestMigration; -class ExpectedCreateAllColumns_DB_Table extends TestMigration +return new class extends TestMigration { use CheckMigrationMethod; @@ -22,7 +22,7 @@ class ExpectedCreateAllColumns_DB_Table extends TestMigration */ public function up() { - Schema::create('all_columns_[db]', function (Blueprint $table) { + Schema::create('all_columns', function (Blueprint $table) { if ($this->hasTableComment()) { $table->comment('A table comment.'); } @@ -223,6 +223,6 @@ public function up() */ public function down() { - Schema::dropIfExists('all_columns_[db]'); + Schema::dropIfExists('all_columns'); } -} +}; diff --git a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_increments_db_table.php b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_increments_table.php similarity index 53% rename from tests/resources/database/migrations/general/2020_03_21_000000_expected_create_increments_db_table.php rename to tests/resources/database/migrations/general/2020_03_21_000000_expected_create_increments_table.php index 70c76dc2..0b421749 100644 --- a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_increments_db_table.php +++ b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_increments_table.php @@ -8,7 +8,7 @@ use Illuminate\Support\Facades\Schema; use KitLoong\MigrationsGenerator\Tests\TestMigration; -class ExpectedCreateIncrements_DB_Table extends TestMigration +return new class extends TestMigration { /** * Run the migrations. @@ -17,31 +17,31 @@ class ExpectedCreateIncrements_DB_Table extends TestMigration */ public function up() { - Schema::create('big_increments_[db]', function (Blueprint $table) { + Schema::create('big_increments', function (Blueprint $table) { $table->bigIncrements('id')->comment('Increments'); }); - Schema::create('increments_[db]', function (Blueprint $table) { + Schema::create('increments', function (Blueprint $table) { $table->increments('id')->comment('Increments'); }); - Schema::create('medium_increments_[db]', function (Blueprint $table) { + Schema::create('medium_increments', function (Blueprint $table) { $table->mediumIncrements('id')->comment('Increments'); }); - Schema::create('small_increments_[db]', function (Blueprint $table) { + Schema::create('small_increments', function (Blueprint $table) { $table->smallIncrements('id')->comment('Increments'); }); - Schema::create('tiny_increments_[db]', function (Blueprint $table) { + Schema::create('tiny_increments', function (Blueprint $table) { $table->tinyIncrements('id')->comment('Increments'); }); - Schema::create('signed_increments_[db]', function (Blueprint $table) { + Schema::create('signed_increments', function (Blueprint $table) { $table->integer('id', true)->comment('Increments'); }); -// Schema::create('increments_not_primary_[db]', function (Blueprint $table) { +// Schema::create('increments_not_primary', function (Blueprint $table) { // $table->increments('id'); // $table->unique('id'); // $table->dropPrimary(); @@ -55,11 +55,11 @@ public function up() */ public function down() { - Schema::dropIfExists('big_increments_[db]'); - Schema::dropIfExists('increments_[db]'); - Schema::dropIfExists('medium_increments_[db]'); - Schema::dropIfExists('small_increments_[db]'); - Schema::dropIfExists('tiny_increments_[db]'); - Schema::dropIfExists('signed_increments_[db]'); + Schema::dropIfExists('big_increments'); + Schema::dropIfExists('increments'); + Schema::dropIfExists('medium_increments'); + Schema::dropIfExists('small_increments'); + Schema::dropIfExists('tiny_increments'); + Schema::dropIfExists('signed_increments'); } -} +}; diff --git a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_primary_db_table.php b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_primary_table.php similarity index 59% rename from tests/resources/database/migrations/general/2020_03_21_000000_expected_create_primary_db_table.php rename to tests/resources/database/migrations/general/2020_03_21_000000_expected_create_primary_table.php index 59b9e5a3..ef903ad0 100644 --- a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_primary_db_table.php +++ b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_primary_table.php @@ -8,7 +8,7 @@ use Illuminate\Support\Facades\Schema; use KitLoong\MigrationsGenerator\Tests\TestMigration; -class ExpectedCreatePrimary_DB_Table extends TestMigration +return new class extends TestMigration { /** * Run the migrations. @@ -17,29 +17,29 @@ class ExpectedCreatePrimary_DB_Table extends TestMigration */ public function up() { - Schema::create('primary_id_[db]', function (Blueprint $table) { + Schema::create('primary_id', function (Blueprint $table) { $table->unsignedInteger('id'); $table->primary('id'); }); - Schema::create('primary_name_[db]', function (Blueprint $table) { + Schema::create('primary_name', function (Blueprint $table) { $table->string('name'); $table->primary('name', 'primary_custom'); }); - Schema::create('signed_primary_id_[db]', function (Blueprint $table) { + Schema::create('signed_primary_id', function (Blueprint $table) { $table->integer('id'); $table->primary('id'); }); - Schema::create('composite_primary_[db]', function (Blueprint $table) { + Schema::create('composite_primary', function (Blueprint $table) { $table->unsignedInteger('id'); $table->unsignedInteger('sub_id'); $table->primary(['id', 'sub_id']); }); // Test short table name - Schema::create('s_[db]', function (Blueprint $table) { + Schema::create('s', function (Blueprint $table) { $table->bigIncrements('id'); }); } @@ -51,10 +51,10 @@ public function up() */ public function down() { - Schema::dropIfExists('primary_id_[db]'); - Schema::dropIfExists('primary_name_[db]'); - Schema::dropIfExists('signed_primary_id_[db]'); - Schema::dropIfExists('composite_primary_[db]'); - Schema::dropIfExists('s_[db]'); + Schema::dropIfExists('primary_id'); + Schema::dropIfExists('primary_name'); + Schema::dropIfExists('signed_primary_id'); + Schema::dropIfExists('composite_primary'); + Schema::dropIfExists('s'); } -} +}; diff --git a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_quoted_name_db_table.php b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_quoted_name_table.php similarity index 74% rename from tests/resources/database/migrations/general/2020_03_21_000000_expected_create_quoted_name_db_table.php rename to tests/resources/database/migrations/general/2020_03_21_000000_expected_create_quoted_name_table.php index 2eecaaaf..cacf00bc 100644 --- a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_quoted_name_db_table.php +++ b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_quoted_name_table.php @@ -8,7 +8,7 @@ use Illuminate\Support\Facades\Schema; use KitLoong\MigrationsGenerator\Tests\TestMigration; -class ExpectedCreateQuotedName_DB_Table extends TestMigration +return new class extends TestMigration { /** * Run the migrations. @@ -17,7 +17,7 @@ class ExpectedCreateQuotedName_DB_Table extends TestMigration */ public function up() { - Schema::create('quoted-name-[db]', function (Blueprint $table) { + Schema::create('quoted-name', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('quoted-column'); }); @@ -30,6 +30,6 @@ public function up() */ public function down() { - Schema::dropIfExists('quoted-name-[db]'); + Schema::dropIfExists('quoted-name'); } -} +}; diff --git a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_reserved_name_modifier_db_table.php b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_reserved_name_modifier_table.php similarity index 70% rename from tests/resources/database/migrations/general/2020_03_21_000000_expected_create_reserved_name_modifier_db_table.php rename to tests/resources/database/migrations/general/2020_03_21_000000_expected_create_reserved_name_modifier_table.php index cc34efc2..aa6bbb1e 100644 --- a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_reserved_name_modifier_db_table.php +++ b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_reserved_name_modifier_table.php @@ -8,7 +8,7 @@ use Illuminate\Support\Facades\Schema; use KitLoong\MigrationsGenerator\Tests\TestMigration; -class ExpectedCreateReservedNameModifier_DB_Table extends TestMigration +return new class extends TestMigration { /** * Run the migrations. @@ -17,13 +17,13 @@ class ExpectedCreateReservedNameModifier_DB_Table extends TestMigration */ public function up() { - Schema::create('reserved_name_modifier_[db]', function (Blueprint $table) { + Schema::create('reserved_name_modifier', function (Blueprint $table) { $table->increments('id'); $table->softDeletes()->nullable(false)->comment('Soft deletes')->default('2020-10-08'); $table->rememberToken()->nullable(false)->comment('Remember token')->default('default'); }); - Schema::create('reserved_name_modifier2_[db]', function (Blueprint $table) { + Schema::create('reserved_name_modifier2', function (Blueprint $table) { $table->increments('id'); $table->softDeletesTz()->nullable(false)->comment('Soft deletes tz')->default('2020-10-08'); }); @@ -36,7 +36,7 @@ public function up() */ public function down() { - Schema::dropIfExists('reserved_name_modifier_[db]'); - Schema::dropIfExists('reserved_name_modifier2_[db]'); + Schema::dropIfExists('reserved_name_modifier'); + Schema::dropIfExists('reserved_name_modifier2'); } -} +}; diff --git a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_reserved_name_with_precision_db_table.php b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_reserved_name_with_precision_table.php similarity index 74% rename from tests/resources/database/migrations/general/2020_03_21_000000_expected_create_reserved_name_with_precision_db_table.php rename to tests/resources/database/migrations/general/2020_03_21_000000_expected_create_reserved_name_with_precision_table.php index 14040059..732f9439 100644 --- a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_reserved_name_with_precision_db_table.php +++ b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_reserved_name_with_precision_table.php @@ -8,7 +8,7 @@ use Illuminate\Support\Facades\Schema; use KitLoong\MigrationsGenerator\Tests\TestMigration; -class ExpectedCreateReservedNameWithPrecision_DB_Table extends TestMigration +return new class extends TestMigration { /** * Run the migrations. @@ -17,7 +17,7 @@ class ExpectedCreateReservedNameWithPrecision_DB_Table extends TestMigration */ public function up() { - Schema::create('reserved_name_with_precision_[db]', function (Blueprint $table) { + Schema::create('reserved_name_with_precision', function (Blueprint $table) { $table->increments('id'); $table->softDeletes('deleted_at', 2); $table->softDeletesTz('deleted_at_tz', 2); @@ -33,6 +33,6 @@ public function up() */ public function down() { - Schema::dropIfExists('reserved_name_with_precision_[db]'); + Schema::dropIfExists('reserved_name_with_precision'); } -} +}; diff --git a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_test_index_db_table.php b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_test_index_table.php similarity index 94% rename from tests/resources/database/migrations/general/2020_03_21_000000_expected_create_test_index_db_table.php rename to tests/resources/database/migrations/general/2020_03_21_000000_expected_create_test_index_table.php index d19f755e..9137142f 100644 --- a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_test_index_db_table.php +++ b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_test_index_table.php @@ -11,7 +11,7 @@ use KitLoong\MigrationsGenerator\Support\CheckMigrationMethod; use KitLoong\MigrationsGenerator\Tests\TestMigration; -class ExpectedCreateTestIndex_DB_Table extends TestMigration +return new class extends TestMigration { use CheckMigrationMethod; @@ -22,7 +22,7 @@ class ExpectedCreateTestIndex_DB_Table extends TestMigration */ public function up() { - Schema::create('test_index_[db]', function (Blueprint $table) { + Schema::create('test_index', function (Blueprint $table) { $table->increments('id'); $table->string('index')->index(); $table->string('index_custom')->index('index_custom'); @@ -83,6 +83,6 @@ public function up() */ public function down() { - Schema::dropIfExists('test_index_[db]'); + Schema::dropIfExists('test_index'); } -} +}; diff --git a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_timestamps_db_table.php b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_timestamps_table.php similarity index 63% rename from tests/resources/database/migrations/general/2020_03_21_000000_expected_create_timestamps_db_table.php rename to tests/resources/database/migrations/general/2020_03_21_000000_expected_create_timestamps_table.php index 6e586b16..347c47d7 100644 --- a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_timestamps_db_table.php +++ b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_timestamps_table.php @@ -8,7 +8,7 @@ use Illuminate\Support\Facades\Schema; use KitLoong\MigrationsGenerator\Tests\TestMigration; -class ExpectedCreateTimestamps_DB_Table extends TestMigration +return new class extends TestMigration { /** * Run the migrations. @@ -17,71 +17,71 @@ class ExpectedCreateTimestamps_DB_Table extends TestMigration */ public function up() { - Schema::create('timestamps_[db]', function (Blueprint $table) { + Schema::create('timestamps', function (Blueprint $table) { $table->increments('id'); $table->timestamps(); }); - Schema::create('timestamps_precision_[db]', function (Blueprint $table) { + Schema::create('timestamps_precision', function (Blueprint $table) { $table->increments('id'); $table->timestamps(2); }); - Schema::create('timestamps_tz_[db]', function (Blueprint $table) { + Schema::create('timestamps_tz', function (Blueprint $table) { $table->increments('id'); $table->timestampsTz(); }); - Schema::create('timestamps_tz_precision_[db]', function (Blueprint $table) { + Schema::create('timestamps_tz_precision', function (Blueprint $table) { $table->increments('id'); $table->timestampsTz(2); }); - Schema::create('not_timestamps_[db]', function (Blueprint $table) { + Schema::create('not_timestamps', function (Blueprint $table) { $table->increments('id'); $table->timestamp('created_at')->nullable(); $table->timestamp('deleted_at')->nullable(); $table->timestamp('update_at')->nullable(); }); - Schema::create('not_timestamps2_[db]', function (Blueprint $table) { + Schema::create('not_timestamps2', function (Blueprint $table) { $table->increments('id'); $table->timestamp('created_at'); $table->timestamp('update_at')->nullable(); }); - Schema::create('not_timestamps3_[db]', function (Blueprint $table) { + Schema::create('not_timestamps3', function (Blueprint $table) { $table->increments('id'); $table->timestamp('created_at')->nullable()->comment('Created at'); $table->timestamp('update_at')->nullable(); }); - Schema::create('not_timestamps4_[db]', function (Blueprint $table) { + Schema::create('not_timestamps4', function (Blueprint $table) { $table->increments('id'); $table->timestamp('created_at')->nullable(); $table->timestamp('update_at')->nullable()->useCurrent()->useCurrentOnUpdate(); }); - Schema::create('not_timestamps_tz_[db]', function (Blueprint $table) { + Schema::create('not_timestamps_tz', function (Blueprint $table) { $table->increments('id'); $table->timestampTz('created_at')->nullable(); $table->timestampTz('deleted_at')->nullable(); $table->timestampTz('update_at')->nullable(); }); - Schema::create('not_timestamps_tz2_[db]', function (Blueprint $table) { + Schema::create('not_timestamps_tz2', function (Blueprint $table) { $table->increments('id'); $table->timestampTz('created_at'); $table->timestampTz('update_at')->nullable(); }); - Schema::create('not_timestamps_tz3_[db]', function (Blueprint $table) { + Schema::create('not_timestamps_tz3', function (Blueprint $table) { $table->increments('id'); $table->timestampTz('created_at')->nullable()->comment('Created at'); $table->timestampTz('update_at')->nullable(); }); - Schema::create('not_timestamps_tz4_[db]', function (Blueprint $table) { + Schema::create('not_timestamps_tz4', function (Blueprint $table) { $table->increments('id'); $table->timestampTz('created_at')->nullable(); $table->timestampTz('update_at')->nullable()->useCurrent()->useCurrentOnUpdate(); @@ -95,13 +95,13 @@ public function up() */ public function down() { - Schema::dropIfExists('timestamps_[db]'); - Schema::dropIfExists('timestamps_precision_[db]'); - Schema::dropIfExists('timestamps_tz_[db]'); - Schema::dropIfExists('timestamps_tz_precision_[db]'); - Schema::dropIfExists('not_timestamps_[db]'); - Schema::dropIfExists('not_timestamps2_[db]'); - Schema::dropIfExists('not_timestamps3_[db]'); - Schema::dropIfExists('not_timestamps4_[db]'); + Schema::dropIfExists('timestamps'); + Schema::dropIfExists('timestamps_precision'); + Schema::dropIfExists('timestamps_tz'); + Schema::dropIfExists('timestamps_tz_precision'); + Schema::dropIfExists('not_timestamps'); + Schema::dropIfExists('not_timestamps2'); + Schema::dropIfExists('not_timestamps3'); + Schema::dropIfExists('not_timestamps4'); } -} +}; diff --git a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_users_db_table.php b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_users_table.php similarity index 84% rename from tests/resources/database/migrations/general/2020_03_21_000000_expected_create_users_db_table.php rename to tests/resources/database/migrations/general/2020_03_21_000000_expected_create_users_table.php index 35d54fc3..e5627b6a 100644 --- a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_users_db_table.php +++ b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_users_table.php @@ -8,7 +8,7 @@ use Illuminate\Support\Facades\Schema; use KitLoong\MigrationsGenerator\Tests\TestMigration; -class ExpectedCreateUsers_DB_Table extends TestMigration +return new class extends TestMigration { /** * Run the migrations. @@ -17,7 +17,7 @@ class ExpectedCreateUsers_DB_Table extends TestMigration */ public function up() { - Schema::create('users_[db]', function (Blueprint $table) { + Schema::create('users', function (Blueprint $table) { $table->bigIncrements('id'); $table->unsignedBigInteger('sub_id'); $table->string('name'); @@ -39,6 +39,6 @@ public function up() */ public function down() { - Schema::dropIfExists('users_[db]'); + Schema::dropIfExists('users'); } -} +}; diff --git a/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_foreign_db_table.php b/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_foreign_table.php similarity index 79% rename from tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_foreign_db_table.php rename to tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_foreign_table.php index aaa3c1fc..645d6312 100644 --- a/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_foreign_db_table.php +++ b/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_foreign_table.php @@ -10,7 +10,7 @@ use KitLoong\MigrationsGenerator\Enum\Driver; use KitLoong\MigrationsGenerator\Tests\TestMigration; -class ExpectedCreateQuotedNameForeign_DB_Table extends TestMigration +return new class extends TestMigration { /** * Run the migrations. @@ -19,14 +19,14 @@ class ExpectedCreateQuotedNameForeign_DB_Table extends TestMigration */ public function up() { - Schema::create('quoted-name-foreign-[db]', function (Blueprint $table) { + Schema::create('quoted-name-foreign', function (Blueprint $table) { $table->bigIncrements('id'); $table->unsignedBigInteger('quoted-name-id'); // SQLite does not support alter add foreign key. // https://www.sqlite.org/omitted.html if (DB::getDriverName() !== Driver::SQLITE()->getValue()) { - $table->foreign('quoted-name-id')->references('id')->on('quoted-name-[db]'); + $table->foreign('quoted-name-id')->references('id')->on('quoted-name'); } }); } @@ -38,6 +38,6 @@ public function up() */ public function down() { - Schema::dropIfExists('quoted-name-foreign-[db]'); + Schema::dropIfExists('quoted-name-foreign'); } -} +}; diff --git a/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_db_proc.php b/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_proc.php similarity index 78% rename from tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_db_proc.php rename to tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_proc.php index c5d394a8..aca4efbd 100644 --- a/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_db_proc.php +++ b/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_proc.php @@ -8,7 +8,7 @@ use KitLoong\MigrationsGenerator\Enum\Driver; use KitLoong\MigrationsGenerator\Tests\TestMigration; -class ExpectedCreateQuotedName_DB_Proc extends TestMigration +return new class extends TestMigration { /** * Run the migrations. @@ -20,27 +20,27 @@ public function up() switch (DB::getDriverName()) { case Driver::MYSQL(): DB::unprepared( - "CREATE PROCEDURE findNameWithHyphen[db]() + "CREATE PROCEDURE findNameWithHyphen() BEGIN - SELECT * from " . $this->quoteIdentifier('name-with-hyphen-[db]') . "; + SELECT * from " . $this->quoteIdentifier('name-with-hyphen') . "; END" ); break; case Driver::PGSQL(): DB::unprepared( - "CREATE PROCEDURE findNameWithHyphen[db]() + "CREATE PROCEDURE findNameWithHyphen() language plpgsql as $$ BEGIN - SELECT * from " . $this->quoteIdentifier('name-with-hyphen-[db]') . "; + SELECT * from " . $this->quoteIdentifier('name-with-hyphen') . "; END;$$" ); break; case Driver::SQLSRV(): DB::unprepared( - "CREATE PROCEDURE findNameWithHyphen[db] + "CREATE PROCEDURE findNameWithHyphen AS - SELECT * from " . $this->quoteIdentifier('name-with-hyphen-[db]') . ";" + SELECT * from " . $this->quoteIdentifier('name-with-hyphen') . ";" ); break; default: @@ -54,6 +54,6 @@ public function up() */ public function down() { - DB::unprepared("DROP PROCEDURE IF EXISTS findNameWithHyphen[db]"); + DB::unprepared("DROP PROCEDURE IF EXISTS findNameWithHyphen"); } -} +}; diff --git a/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_db_view.php b/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_view.php similarity index 78% rename from tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_db_view.php rename to tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_view.php index 201eaf03..e16ae6f8 100644 --- a/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_db_view.php +++ b/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_view.php @@ -7,7 +7,7 @@ use Illuminate\Support\Facades\DB; use KitLoong\MigrationsGenerator\Tests\TestMigration; -class ExpectedCreateQuotedName_DB_View extends TestMigration +return new class extends TestMigration { /** * Run the migrations. @@ -17,8 +17,8 @@ class ExpectedCreateQuotedName_DB_View extends TestMigration public function up() { DB::statement( - "CREATE VIEW " . $this->quoteIdentifier(DB::getTablePrefix() . 'quoted-name-[db]-view') - . " AS SELECT * from " . $this->quoteIdentifier(DB::getTablePrefix() . 'quoted-name-[db]') + "CREATE VIEW " . $this->quoteIdentifier(DB::getTablePrefix() . 'quoted-name-view') + . " AS SELECT * from " . $this->quoteIdentifier(DB::getTablePrefix() . 'quoted-name') ); } @@ -29,6 +29,6 @@ public function up() */ public function down() { - DB::statement("DROP VIEW IF EXISTS " . $this->quoteIdentifier('quoted-name-[db]-view')); + DB::statement("DROP VIEW IF EXISTS " . $this->quoteIdentifier('quoted-name-view')); } -} +}; diff --git a/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_user_profile_db_table.php b/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_user_profile_table.php similarity index 75% rename from tests/resources/database/migrations/general/2020_03_21_000001_expected_create_user_profile_db_table.php rename to tests/resources/database/migrations/general/2020_03_21_000001_expected_create_user_profile_table.php index 8425b9d2..269eda01 100644 --- a/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_user_profile_db_table.php +++ b/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_user_profile_table.php @@ -10,7 +10,7 @@ use KitLoong\MigrationsGenerator\Enum\Driver; use KitLoong\MigrationsGenerator\Tests\TestMigration; -class ExpectedCreateUserProfile_DB_Table extends TestMigration +return new class extends TestMigration { /** * Run the migrations. @@ -19,7 +19,7 @@ class ExpectedCreateUserProfile_DB_Table extends TestMigration */ public function up() { - Schema::create('user_profile_[db]', function (Blueprint $table) { + Schema::create('user_profile', function (Blueprint $table) { $table->increments('id'); $table->bigInteger('user_id')->unsigned(); $table->bigInteger('user_id_fk_custom')->unsigned(); @@ -34,15 +34,15 @@ public function up() // SQLite does not support alter add foreign key. // https://www.sqlite.org/omitted.html if (DB::getDriverName() !== Driver::SQLITE()->getValue()) { - $table->foreign('user_id')->references('id')->on('users_[db]'); - $table->foreign('user_id_fk_custom', 'users_[db]_foreign_custom')->references('id')->on('users_[db]'); - $table->foreign('user_id_fk_constraint', 'users_[db]_foreign_constraint')->references('id')->on( - 'users_[db]' + $table->foreign('user_id')->references('id')->on('users'); + $table->foreign('user_id_fk_custom', 'users_foreign_custom')->references('id')->on('users'); + $table->foreign('user_id_fk_constraint', 'users_foreign_constraint')->references('id')->on( + 'users' )->onDelete('cascade')->onUpdate('cascade'); - $table->foreign(['user_id', 'user_sub_id'])->references(['id', 'sub_id'])->on('users_[db]'); - $table->foreign(['user_id', 'user_sub_id_fk_custom'], 'users_[db]_composite_foreign_custom') + $table->foreign(['user_id', 'user_sub_id'])->references(['id', 'sub_id'])->on('users'); + $table->foreign(['user_id', 'user_sub_id_fk_custom'], 'users_composite_foreign_custom') ->references(['id', 'sub_id']) - ->on('users_[db]'); + ->on('users'); } }); } @@ -54,6 +54,6 @@ public function up() */ public function down() { - Schema::dropIfExists('user_profile_[db]'); + Schema::dropIfExists('user_profile'); } -} +}; diff --git a/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_users_db_view.php b/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_users_view.php similarity index 63% rename from tests/resources/database/migrations/general/2020_03_21_000001_expected_create_users_db_view.php rename to tests/resources/database/migrations/general/2020_03_21_000001_expected_create_users_view.php index 6b98da7d..3c4017a4 100644 --- a/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_users_db_view.php +++ b/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_users_view.php @@ -7,7 +7,7 @@ use Illuminate\Support\Facades\DB; use KitLoong\MigrationsGenerator\Tests\TestMigration; -class ExpectedCreateUsers_DB_View extends TestMigration +return new class extends TestMigration { /** * Run the migrations. @@ -16,7 +16,7 @@ class ExpectedCreateUsers_DB_View extends TestMigration */ public function up() { - DB::statement("CREATE VIEW users_[db]_view AS SELECT * from " . DB::getTablePrefix() . "users_[db]"); + DB::statement("CREATE VIEW users_view AS SELECT * from " . DB::getTablePrefix() . "users"); } /** @@ -26,6 +26,6 @@ public function up() */ public function down() { - DB::statement("DROP VIEW IF EXISTS users_[db]_view"); + DB::statement("DROP VIEW IF EXISTS users_view"); } -} +}; diff --git a/tests/resources/database/migrations/vendors/2018_08_08_100000_create_telescope_db_table.php b/tests/resources/database/migrations/vendors/2018_08_08_100000_create_telescope_table.php similarity index 76% rename from tests/resources/database/migrations/vendors/2018_08_08_100000_create_telescope_db_table.php rename to tests/resources/database/migrations/vendors/2018_08_08_100000_create_telescope_table.php index e59a0fe5..20838107 100644 --- a/tests/resources/database/migrations/vendors/2018_08_08_100000_create_telescope_db_table.php +++ b/tests/resources/database/migrations/vendors/2018_08_08_100000_create_telescope_table.php @@ -8,7 +8,7 @@ use Illuminate\Support\Facades\Schema; use KitLoong\MigrationsGenerator\Tests\TestMigration; -class CreateTelescope_DB_Table extends TestMigration +return new class extends TestMigration { /** * Get the migration connection name. @@ -25,7 +25,7 @@ public function up(): void { $schema = Schema::connection($this->getConnection()); - $schema->create('telescope_entries_[db]', function (Blueprint $table) { + $schema->create('telescope_entries', function (Blueprint $table) { $table->bigIncrements('sequence'); $table->uuid('uuid'); $table->uuid('batch_id'); @@ -42,7 +42,7 @@ public function up(): void $table->index(['type', 'should_display_on_index']); }); - $schema->create('telescope_entries_tags_[db]', function (Blueprint $table) { + $schema->create('telescope_entries_tags', function (Blueprint $table) { $table->uuid('entry_uuid'); $table->string('tag'); @@ -51,11 +51,11 @@ public function up(): void $table->foreign('entry_uuid') ->references('uuid') - ->on('telescope_entries_[db]') + ->on('telescope_entries') ->onDelete('cascade'); }); - $schema->create('telescope_monitoring_[db]', function (Blueprint $table) { + $schema->create('telescope_monitoring', function (Blueprint $table) { $table->string('tag'); }); } @@ -67,8 +67,8 @@ public function down(): void { $schema = Schema::connection($this->getConnection()); - $schema->dropIfExists('telescope_entries_tags_[db]'); - $schema->dropIfExists('telescope_entries_[db]'); - $schema->dropIfExists('telescope_monitoring_[db]'); + $schema->dropIfExists('telescope_entries_tags'); + $schema->dropIfExists('telescope_entries'); + $schema->dropIfExists('telescope_monitoring'); } -} +}; diff --git a/tests/resources/database/migrations/vendors/2019_12_14_000001_create_personal_access_tokens_db_table.php b/tests/resources/database/migrations/vendors/2019_12_14_000001_create_personal_access_tokens_table.php similarity index 78% rename from tests/resources/database/migrations/vendors/2019_12_14_000001_create_personal_access_tokens_db_table.php rename to tests/resources/database/migrations/vendors/2019_12_14_000001_create_personal_access_tokens_table.php index 5e1d9010..233c289e 100644 --- a/tests/resources/database/migrations/vendors/2019_12_14_000001_create_personal_access_tokens_db_table.php +++ b/tests/resources/database/migrations/vendors/2019_12_14_000001_create_personal_access_tokens_table.php @@ -8,14 +8,14 @@ use Illuminate\Support\Facades\Schema; use KitLoong\MigrationsGenerator\Tests\TestMigration; -class CreatePersonalAccessTokens_DB_Table extends TestMigration +return new class extends TestMigration { /** * Run the migrations. */ public function up(): void { - Schema::create('personal_access_tokens_[db]', function (Blueprint $table) { + Schema::create('personal_access_tokens', function (Blueprint $table) { $table->bigIncrements('id'); $table->morphs('tokenable'); $table->string('name'); @@ -32,6 +32,6 @@ public function up(): void */ public function down(): void { - Schema::dropIfExists('personal_access_tokens_[db]'); + Schema::dropIfExists('personal_access_tokens'); } -} +}; From e4805aaf89733391c04bc2b0e2af5e1fd60cd25b Mon Sep 17 00:00:00 2001 From: Kit Loong Date: Thu, 8 Feb 2024 19:47:40 +0800 Subject: [PATCH 07/20] Remove old Laravel version check --- src/DBAL/Models/DBALIndex.php | 5 +- src/DBAL/Models/MySQL/MySQLColumn.php | 26 +------ .../Generator/Columns/DatetimeColumn.php | 5 +- .../Generator/Modifiers/DefaultModifier.php | 17 ---- src/Support/CheckLaravelVersion.php | 25 ------ src/Support/CheckMigrationMethod.php | 35 --------- tests/Feature/MySQL57/CommandTest.php | 16 +--- tests/Feature/MySQL57/StackedCommandTest.php | 8 -- tests/Feature/SQLSrv/CommandTest.php | 16 ---- tests/Feature/SQLSrv/SQLSrvTestCase.php | 23 +----- tests/Support/CheckLaravelVersionTest.php | 77 ------------------- ...00000_expected_create_collations_table.php | 13 +--- ...0000_expected_create_all_columns_table.php | 10 +-- ...00000_expected_create_test_index_table.php | 5 +- 14 files changed, 18 insertions(+), 263 deletions(-) delete mode 100644 tests/Support/CheckLaravelVersionTest.php diff --git a/src/DBAL/Models/DBALIndex.php b/src/DBAL/Models/DBALIndex.php index af28a653..42a176ce 100644 --- a/src/DBAL/Models/DBALIndex.php +++ b/src/DBAL/Models/DBALIndex.php @@ -5,12 +5,9 @@ use Doctrine\DBAL\Schema\Index as DoctrineDBALIndex; use KitLoong\MigrationsGenerator\Enum\Migrations\Method\IndexType; use KitLoong\MigrationsGenerator\Schema\Models\Index; -use KitLoong\MigrationsGenerator\Support\CheckMigrationMethod; abstract class DBALIndex implements Index { - use CheckMigrationMethod; - /** * @var string[] */ @@ -103,7 +100,7 @@ private function getIndexType(DoctrineDBALIndex $index): IndexType return IndexType::SPATIAL_INDEX(); } - if ($this->hasFullText() && $index->hasFlag('fulltext')) { + if ($index->hasFlag('fulltext')) { return IndexType::FULLTEXT(); } diff --git a/src/DBAL/Models/MySQL/MySQLColumn.php b/src/DBAL/Models/MySQL/MySQLColumn.php index b66485b0..6f81116e 100644 --- a/src/DBAL/Models/MySQL/MySQLColumn.php +++ b/src/DBAL/Models/MySQL/MySQLColumn.php @@ -9,13 +9,10 @@ use KitLoong\MigrationsGenerator\Enum\Migrations\Method\ColumnType; use KitLoong\MigrationsGenerator\Repositories\MariaDBRepository; use KitLoong\MigrationsGenerator\Repositories\MySQLRepository; -use KitLoong\MigrationsGenerator\Support\CheckMigrationMethod; use PDO; class MySQLColumn extends DBALColumn { - use CheckMigrationMethod; - private MySQLRepository $mysqlRepository; private MariaDBRepository $mariaDBRepository; @@ -46,7 +43,7 @@ protected function handle(): void break; case ColumnType::SET(): - $this->useSetOrString(); + $this->presetValues = $this->getSetPresetValues(); break; case ColumnType::SOFT_DELETES(): @@ -143,21 +140,6 @@ private function getSetPresetValues(): array )->toArray(); } - /** - * Check if "set" method is available, then get "set" preset values. - * If not available, change type to string with 255 length. - */ - private function useSetOrString(): void - { - if ($this->hasSet()) { - $this->presetValues = $this->getSetPresetValues(); - return; - } - - $this->type = ColumnType::STRING(); - $this->length = 255; // Framework default string length. - } - /** * Check if the column uses "on update CURRENT_TIMESTAMP". */ @@ -181,11 +163,7 @@ private function getTextTypeByLength(): ColumnType { switch ($this->length) { case MySQLPlatform::LENGTH_LIMIT_TINYTEXT: - if ($this->hasTinyText()) { - return ColumnType::TINY_TEXT(); - } - - return ColumnType::TEXT(); + return ColumnType::TINY_TEXT(); case MySQLPlatform::LENGTH_LIMIT_TEXT: return ColumnType::TEXT(); diff --git a/src/Migration/Generator/Columns/DatetimeColumn.php b/src/Migration/Generator/Columns/DatetimeColumn.php index 59ea17dc..9b22f467 100644 --- a/src/Migration/Generator/Columns/DatetimeColumn.php +++ b/src/Migration/Generator/Columns/DatetimeColumn.php @@ -6,12 +6,9 @@ use KitLoong\MigrationsGenerator\Migration\Blueprint\Method; use KitLoong\MigrationsGenerator\Schema\Models\Column; use KitLoong\MigrationsGenerator\Schema\Models\Table; -use KitLoong\MigrationsGenerator\Support\CheckMigrationMethod; class DatetimeColumn implements ColumnTypeGenerator { - use CheckMigrationMethod; - private const DEFAULT_PRECISION = 0; /** @@ -21,7 +18,7 @@ public function generate(Table $table, Column $column): Method { $method = $this->makeMethod($column); - if ($column->isOnUpdateCurrentTimestamp() && $this->hasUseCurrentOnUpdate()) { + if ($column->isOnUpdateCurrentTimestamp()) { $method->chain(ColumnModifier::USE_CURRENT_ON_UPDATE()); } diff --git a/src/Migration/Generator/Modifiers/DefaultModifier.php b/src/Migration/Generator/Modifiers/DefaultModifier.php index 5d713385..cb6135b9 100644 --- a/src/Migration/Generator/Modifiers/DefaultModifier.php +++ b/src/Migration/Generator/Modifiers/DefaultModifier.php @@ -8,12 +8,9 @@ use KitLoong\MigrationsGenerator\Migration\Blueprint\Method; use KitLoong\MigrationsGenerator\Schema\Models\Column; use KitLoong\MigrationsGenerator\Schema\Models\Table; -use KitLoong\MigrationsGenerator\Support\CheckMigrationMethod; class DefaultModifier implements Modifier { - use CheckMigrationMethod; - /** * @var array */ @@ -118,20 +115,6 @@ protected function chainDefaultForDatetime(Method $method, Column $column): Meth switch ($column->getDefault()) { case 'now()': case 'CURRENT_TIMESTAMP': - // By default, `timestamp()` and `timestampTz()` will generate column as: - // `DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP`, migration translated to `useCurrent()` and `useCurrentOnUpdate()`. - // Due to old Laravel version does not have `useCurrentOnUpdate()`, - // if column has both `DEFAULT CURRENT_TIMESTAMP` and `ON UPDATE CURRENT_TIMESTAMP`, - // we need to generate column without chain. - // New laravel is okay to chain `useCurrent()` and `useCurrentOnUpdate()`. - if (!$this->hasUseCurrentOnUpdate()) { - if (!$column->isOnUpdateCurrentTimestamp()) { - $method->chain(ColumnModifier::USE_CURRENT()); - } - - break; - } - $method->chain(ColumnModifier::USE_CURRENT()); break; diff --git a/src/Support/CheckLaravelVersion.php b/src/Support/CheckLaravelVersion.php index 812f0351..18494ab4 100644 --- a/src/Support/CheckLaravelVersion.php +++ b/src/Support/CheckLaravelVersion.php @@ -6,31 +6,6 @@ trait CheckLaravelVersion { - public function atLeastLaravel5Dot7(): bool - { - return $this->atLeastLaravelVersion('5.7.0'); - } - - public function atLeastLaravel5Dot8(): bool - { - return $this->atLeastLaravelVersion('5.8.0'); - } - - public function atLeastLaravel6(): bool - { - return $this->atLeastLaravelVersion('6.0'); - } - - public function atLeastLaravel7(): bool - { - return $this->atLeastLaravelVersion('7.0'); - } - - public function atLeastLaravel8(): bool - { - return $this->atLeastLaravelVersion('8.0'); - } - public function atLeastLaravel9(): bool { return $this->atLeastLaravelVersion('9.0'); diff --git a/src/Support/CheckMigrationMethod.php b/src/Support/CheckMigrationMethod.php index 4f60da22..4313587a 100644 --- a/src/Support/CheckMigrationMethod.php +++ b/src/Support/CheckMigrationMethod.php @@ -4,44 +4,9 @@ use Illuminate\Database\Migrations\Migrator; use Illuminate\Database\Schema\Blueprint; -use Illuminate\Database\Schema\Grammars\Grammar; trait CheckMigrationMethod { - use CheckLaravelVersion; - - /** - * `useCurrentOnUpdate` added since Laravel 8. - */ - public function hasUseCurrentOnUpdate(): bool - { - return $this->atLeastLaravel8(); - } - - /** - * `set` added since Laravel 5.8. - */ - public function hasSet(): bool - { - return method_exists(Blueprint::class, 'set'); - } - - /** - * `fulltext` added since Laravel 8. - */ - public function hasFullText(): bool - { - return method_exists(Grammar::class, 'compileFulltext'); - } - - /** - * `tinyText` added since Laravel 8. - */ - public function hasTinyText(): bool - { - return method_exists(Blueprint::class, 'tinyText'); - } - /** * `tinyText` added since Laravel 9. */ diff --git a/tests/Feature/MySQL57/CommandTest.php b/tests/Feature/MySQL57/CommandTest.php index 1bd2b218..1e0719be 100644 --- a/tests/Feature/MySQL57/CommandTest.php +++ b/tests/Feature/MySQL57/CommandTest.php @@ -10,13 +10,10 @@ use KitLoong\MigrationsGenerator\Schema\Models\ForeignKey; use KitLoong\MigrationsGenerator\Schema\Models\Index; use KitLoong\MigrationsGenerator\Schema\MySQLSchema; -use KitLoong\MigrationsGenerator\Support\CheckMigrationMethod; use Throwable; class CommandTest extends MySQL57TestCase { - use CheckMigrationMethod; - public function testRun(): void { $migrateTemplates = function (): void { @@ -193,17 +190,12 @@ public function testDefaultIndexNames(): void 'test_index_unique_unique', // 'test_index_with_length(16)_index', // 'test_index_with_length_custom(16)_index', + 'test_index_chain_fulltext', + 'test_index_col_multi1_col_multi2_fulltext', + 'test_index_fulltext_custom_fulltext', + 'test_index_fulltext_fulltext', ]; - if ($this->hasFullText()) { - $expectedIndexes = array_merge($expectedIndexes, [ - 'test_index_chain_fulltext', - 'test_index_col_multi1_col_multi2_fulltext', - 'test_index_fulltext_custom_fulltext', - 'test_index_fulltext_fulltext', - ]); - } - sort($actualIndexes); sort($expectedIndexes); diff --git a/tests/Feature/MySQL57/StackedCommandTest.php b/tests/Feature/MySQL57/StackedCommandTest.php index bd400743..2176e37c 100644 --- a/tests/Feature/MySQL57/StackedCommandTest.php +++ b/tests/Feature/MySQL57/StackedCommandTest.php @@ -7,13 +7,10 @@ use Illuminate\Support\Facades\Schema; use Illuminate\Support\Str; use KitLoong\MigrationsGenerator\Setting; -use KitLoong\MigrationsGenerator\Support\CheckLaravelVersion; use PDO; class StackedCommandTest extends MySQL57TestCase { - use CheckLaravelVersion; - /** * @inheritDoc */ @@ -46,11 +43,6 @@ protected function setUp(): void { parent::setUp(); - // `Schema::createDatabase` available since Laravel 8. - if (!$this->atLeastLaravel8()) { - $this->markTestSkipped(); - } - Schema::createDatabase('migration2'); } diff --git a/tests/Feature/SQLSrv/CommandTest.php b/tests/Feature/SQLSrv/CommandTest.php index f6f55a4f..4d7c76e0 100644 --- a/tests/Feature/SQLSrv/CommandTest.php +++ b/tests/Feature/SQLSrv/CommandTest.php @@ -8,22 +8,6 @@ class CommandTest extends SQLSrvTestCase { - protected function setUp(): void - { - parent::setUp(); - - // Method `typeDateTime` is using different implementation since v5.8 - // It is hard to create unified UT across Laravel <= v5.7 and >= v5.8 - // To simplify, dropping UT check for version <= 5.7. - // https://github.com/laravel/framework/blob/5.7/src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php#L523 - // https://github.com/laravel/framework/blob/5.8/src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php#L538 - if ($this->atLeastLaravel5Dot8()) { - return; - } - - $this->markTestSkipped(); - } - /** * @throws \Doctrine\DBAL\Exception */ diff --git a/tests/Feature/SQLSrv/SQLSrvTestCase.php b/tests/Feature/SQLSrv/SQLSrvTestCase.php index 40feaf92..3fe88856 100644 --- a/tests/Feature/SQLSrv/SQLSrvTestCase.php +++ b/tests/Feature/SQLSrv/SQLSrvTestCase.php @@ -6,13 +6,10 @@ use Illuminate\Support\Facades\File; use Illuminate\Support\Facades\Schema; use KitLoong\MigrationsGenerator\DBAL\Connection; -use KitLoong\MigrationsGenerator\Support\CheckLaravelVersion; use KitLoong\MigrationsGenerator\Tests\Feature\FeatureTestCase; abstract class SQLSrvTestCase extends FeatureTestCase { - use CheckLaravelVersion; - /** * @inheritDoc */ @@ -84,29 +81,11 @@ protected function dumpSchemaAs(string $destination): void protected function refreshDatabase(): void { - $this->dropAllViews(); + Schema::dropAllViews(); Schema::dropAllTables(); $this->dropAllProcedures(); } - protected function dropAllViews(): void - { - // `dropAllViews` available in Laravel >= 6.x - if ($this->atLeastLaravel6()) { - Schema::dropAllViews(); - return; - } - - // See https://github.com/laravel/framework/blob/6.x/src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php#L360 - DB::statement( - "DECLARE @sql NVARCHAR(MAX) = N''; - SELECT @sql += 'DROP VIEW ' + QUOTENAME(OBJECT_SCHEMA_NAME(object_id)) + '.' + QUOTENAME(name) + ';' - FROM sys.views; - - EXEC sp_executesql @sql;", - ); - } - protected function dropAllProcedures(): void { $procedures = $this->getAllProcedures(); diff --git a/tests/Support/CheckLaravelVersionTest.php b/tests/Support/CheckLaravelVersionTest.php deleted file mode 100644 index d77687b8..00000000 --- a/tests/Support/CheckLaravelVersionTest.php +++ /dev/null @@ -1,77 +0,0 @@ -andReturn('5.6.0')->once(); - $this->assertFalse($this->stubInstance()->atLeastLaravel5Dot7()); - - App::shouldReceive('version')->andReturn('5.7.0')->once(); - $this->assertTrue($this->stubInstance()->atLeastLaravel5Dot7()); - - App::shouldReceive('version')->andReturn('5.8.0')->once(); - $this->assertTrue($this->stubInstance()->atLeastLaravel5Dot7()); - } - - public function testAtLeastLaravel5Dot8(): void - { - App::shouldReceive('version')->andReturn('5.7.0')->once(); - $this->assertFalse($this->stubInstance()->atLeastLaravel5Dot8()); - - App::shouldReceive('version')->andReturn('5.8.0')->once(); - $this->assertTrue($this->stubInstance()->atLeastLaravel5Dot8()); - - App::shouldReceive('version')->andReturn('6.0.0')->once(); - $this->assertTrue($this->stubInstance()->atLeastLaravel5Dot8()); - } - - public function testAtLeastLaravel6(): void - { - App::shouldReceive('version')->andReturn('5.8.0')->once(); - $this->assertFalse($this->stubInstance()->atLeastLaravel6()); - - App::shouldReceive('version')->andReturn('6.0.0')->once(); - $this->assertTrue($this->stubInstance()->atLeastLaravel6()); - - App::shouldReceive('version')->andReturn('7.0.0')->once(); - $this->assertTrue($this->stubInstance()->atLeastLaravel6()); - } - - public function testAtLeastLaravel7(): void - { - App::shouldReceive('version')->andReturn('6.0.0')->once(); - $this->assertFalse($this->stubInstance()->atLeastLaravel7()); - - App::shouldReceive('version')->andReturn('7.0.0')->once(); - $this->assertTrue($this->stubInstance()->atLeastLaravel7()); - - App::shouldReceive('version')->andReturn('8.0.0')->once(); - $this->assertTrue($this->stubInstance()->atLeastLaravel7()); - } - - public function testAtLeastLaravel8(): void - { - App::shouldReceive('version')->andReturn('7.0.0')->once(); - $this->assertFalse($this->stubInstance()->atLeastLaravel8()); - - App::shouldReceive('version')->andReturn('8.0.0')->once(); - $this->assertTrue($this->stubInstance()->atLeastLaravel8()); - - App::shouldReceive('version')->andReturn('9.0.0')->once(); - $this->assertTrue($this->stubInstance()->atLeastLaravel8()); - } - - private function stubInstance(): object - { - return new class () { - use CheckLaravelVersion; - }; - } -} diff --git a/tests/resources/database/migrations/collation/2020_03_21_000000_expected_create_collations_table.php b/tests/resources/database/migrations/collation/2020_03_21_000000_expected_create_collations_table.php index 07cbc6d4..4493a207 100644 --- a/tests/resources/database/migrations/collation/2020_03_21_000000_expected_create_collations_table.php +++ b/tests/resources/database/migrations/collation/2020_03_21_000000_expected_create_collations_table.php @@ -8,13 +8,10 @@ use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Schema; use KitLoong\MigrationsGenerator\Enum\Driver; -use KitLoong\MigrationsGenerator\Support\CheckLaravelVersion; use KitLoong\MigrationsGenerator\Tests\TestMigration; return new class extends TestMigration { - use CheckLaravelVersion; - /** * Run the migrations. * @@ -65,12 +62,10 @@ public function up() $table->text('text_collation')->collation($collation); if (DB::getDriverName() === Driver::MYSQL()->getValue()) { - if ($this->atLeastLaravel5Dot8()) { - $table->set('set', ['strawberry', 'vanilla']); - $table->set('set_default', ['strawberry', 'vanilla'])->default('strawberry'); - $table->set('set_charset', ['strawberry', 'vanilla'])->charset('utf8'); - $table->set('set_collation', ['strawberry', 'vanilla'])->collation($collation); - } + $table->set('set', ['strawberry', 'vanilla']); + $table->set('set_default', ['strawberry', 'vanilla'])->default('strawberry'); + $table->set('set_charset', ['strawberry', 'vanilla'])->charset('utf8'); + $table->set('set_collation', ['strawberry', 'vanilla'])->collation($collation); } $table->string('string'); diff --git a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_table.php b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_table.php index 5b5a942e..07bc9add 100644 --- a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_table.php +++ b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_table.php @@ -8,11 +8,13 @@ use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Schema; use KitLoong\MigrationsGenerator\Enum\Driver; +use KitLoong\MigrationsGenerator\Support\CheckLaravelVersion; use KitLoong\MigrationsGenerator\Support\CheckMigrationMethod; use KitLoong\MigrationsGenerator\Tests\TestMigration; return new class extends TestMigration { + use CheckLaravelVersion; use CheckMigrationMethod; /** @@ -186,9 +188,7 @@ public function up() ->default('string !@#$%^^&*()_+-=[]{};:,./<>?~`| \ \\ \\\ \\\\ \'\' \\\\\'\' " \" \\" \\\" \\\\" quotes') ->comment('string !@#$%^^&*()_+-=[]{};:,./<>?~`| \ \\ \\\ \\\\ \'\' \\\\\'\' " \" \\" \\\" \\\\" quotes'); - if ($this->hasTinyText()) { - $table->tinyText('tinyText'); - } + $table->tinyText('tinyText'); if ($this->hasULID()) { $table->ulid('ulid'); @@ -196,9 +196,7 @@ public function up() switch (DB::getDriverName()) { case Driver::MYSQL(): - if ($this->hasSet()) { - $table->set('set', ['strawberry', 'vanilla']); - } + $table->set('set', ['strawberry', 'vanilla']); break; default: } diff --git a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_test_index_table.php b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_test_index_table.php index 9137142f..750669eb 100644 --- a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_test_index_table.php +++ b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_test_index_table.php @@ -55,10 +55,7 @@ public function up() } } - if ( - in_array(DB::getDriverName(), [Driver::MYSQL()->getValue(), Driver::PGSQL()->getValue()]) - && $this->hasFullText() - ) { + if (in_array(DB::getDriverName(), [Driver::MYSQL()->getValue(), Driver::PGSQL()->getValue()])) { $table->string('fulltext')->fulltext(); $table->string('fulltext_custom')->fulltext('fulltext_custom'); $table->fullText(['col_multi1', 'col_multi2']); From 323cba2ac6540f82f0ba388c7570af48e48c811f Mon Sep 17 00:00:00 2001 From: Kit Loong Date: Thu, 8 Feb 2024 20:57:00 +0800 Subject: [PATCH 08/20] Use doctrine dbal connection --- phpcs.xml | 1 - phpstan.neon | 1 - phpunit.xml.dist | 1 - src/DBAL/PDO/Concerns/ConnectsToDatabase.php | 27 --- src/DBAL/PDO/Connection.php | 186 ------------------- src/DBAL/PDO/ConnectsToDatabase.php | 19 ++ src/DBAL/PDO/MySqlDriver.php | 1 - src/DBAL/PDO/PostgresDriver.php | 1 - src/DBAL/PDO/SQLiteDriver.php | 1 - src/DBAL/PDO/SqlServerConnection.php | 152 --------------- src/DBAL/PDO/SqlServerDriver.php | 14 +- 11 files changed, 20 insertions(+), 384 deletions(-) delete mode 100644 src/DBAL/PDO/Concerns/ConnectsToDatabase.php delete mode 100644 src/DBAL/PDO/Connection.php create mode 100644 src/DBAL/PDO/ConnectsToDatabase.php delete mode 100644 src/DBAL/PDO/SqlServerConnection.php diff --git a/phpcs.xml b/phpcs.xml index ba7395c3..720e719b 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -6,7 +6,6 @@ tests tests/resources/database/migrations/*.php - src/DBAL/PDO/* diff --git a/phpstan.neon b/phpstan.neon index b8377ceb..940ede59 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -20,6 +20,5 @@ parameters: excludePaths: - ./*/*/FileToBeExcluded.php - - ./src/DBAL/PDO/* checkMissingIterableValueType: true diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 95d47657..51a734d4 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -18,7 +18,6 @@ src/DBAL/Types - src/DBAL/PDO diff --git a/src/DBAL/PDO/Concerns/ConnectsToDatabase.php b/src/DBAL/PDO/Concerns/ConnectsToDatabase.php deleted file mode 100644 index fc75596c..00000000 --- a/src/DBAL/PDO/Concerns/ConnectsToDatabase.php +++ /dev/null @@ -1,27 +0,0 @@ -connection = $connection; - } - - /** - * Execute an SQL statement. - * - * @param string $statement - * @return int - */ - public function exec(string $statement): int - { - try { - $result = $this->connection->exec($statement); - - \assert($result !== false); - - return $result; - } catch (PDOException $exception) { - throw Exception::new($exception); - } - } - - /** - * Prepare a new SQL statement. - * - * @param string $sql - * @return \Doctrine\DBAL\Driver\Statement - * - * @throws \Doctrine\DBAL\Driver\PDO\Exception - */ - public function prepare(string $sql): StatementInterface - { - try { - return $this->createStatement( - $this->connection->prepare($sql) - ); - } catch (PDOException $exception) { - throw Exception::new($exception); - } - } - - /** - * Execute a new query against the connection. - * - * @param string $sql - * @return \Doctrine\DBAL\Driver\Result - */ - public function query(string $sql): ResultInterface - { - try { - $stmt = $this->connection->query($sql); - - \assert($stmt instanceof PDOStatement); - - return new Result($stmt); - } catch (PDOException $exception) { - throw Exception::new($exception); - } - } - - /** - * Get the last insert ID. - * - * @param string|null $name - * @return string|int - * - * @throws \Doctrine\DBAL\Driver\PDO\Exception - */ - public function lastInsertId($name = null): int|string - { - try { - if ($name === null) { - return $this->connection->lastInsertId(); - } - - return $this->connection->lastInsertId($name); - } catch (PDOException $exception) { - throw Exception::new($exception); - } - } - - /** - * Create a new statement instance. - * - * @param \PDOStatement $stmt - * @return \Doctrine\DBAL\Driver\PDO\Statement - */ - protected function createStatement(PDOStatement $stmt): Statement - { - return new Statement($stmt); - } - - /** - * Begin a new database transaction. - * - * @return void - */ - public function beginTransaction(): void - { - $this->connection->beginTransaction(); - } - - /** - * Commit a database transaction. - * - * @return void - */ - public function commit(): void - { - $this->connection->commit(); - } - - /** - * Rollback a database transaction. - * - * @return void - */ - public function rollBack(): void - { - $this->connection->rollBack(); - } - - /** - * Wrap quotes around the given input. - * - * @param string $input - * @param string $type - * @return string - */ - public function quote($input, $type = ParameterType::STRING): string - { - return $this->connection->quote($input, $type); - } - - /** - * Get the server version for the connection. - * - * @return string - */ - public function getServerVersion(): string - { - return $this->connection->getAttribute(PDO::ATTR_SERVER_VERSION); - } - - /** - * Get the native PDO connection. - * - * @return \PDO - */ - public function getNativeConnection(): PDO - { - return $this->connection; - } -} diff --git a/src/DBAL/PDO/ConnectsToDatabase.php b/src/DBAL/PDO/ConnectsToDatabase.php new file mode 100644 index 00000000..2372815e --- /dev/null +++ b/src/DBAL/PDO/ConnectsToDatabase.php @@ -0,0 +1,19 @@ +connection = $connection; - } - - /** - * Prepare a new SQL statement. - * - * @param string $sql - * @return \Doctrine\DBAL\Driver\Statement - */ - public function prepare(string $sql): StatementInterface - { - return new Statement( - $this->connection->prepare($sql) - ); - } - - /** - * Execute a new query against the connection. - * - * @param string $sql - * @return \Doctrine\DBAL\Driver\Result - */ - public function query(string $sql): Result - { - return $this->connection->query($sql); - } - - /** - * Execute an SQL statement. - * - * @param string $statement - * @return int - */ - public function exec(string $statement): int - { - return $this->connection->exec($statement); - } - - /** - * Get the last insert ID. - * - * @param string|null $name - * @return string|int - */ - public function lastInsertId($name = null): string|int - { - if ($name === null) { - return $this->connection->lastInsertId($name); - } - - return $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?') - ->execute([$name]) - ->fetchOne(); - } - - /** - * Begin a new database transaction. - * - * @return void - */ - public function beginTransaction(): void - { - $this->connection->beginTransaction(); - } - - /** - * Commit a database transaction. - * - * @return void - */ - public function commit(): void - { - $this->connection->commit(); - } - - /** - * Rollback a database transaction. - * - * @return void - */ - public function rollBack(): void - { - $this->connection->rollBack(); - } - - /** - * Wrap quotes around the given input. - * - * @param string $value - * @param int $type - * @return string - */ - public function quote($value, $type = ParameterType::STRING): string - { - $val = $this->connection->quote($value, $type); - - // Fix for a driver version terminating all values with null byte... - if (\is_string($val) && str_contains($val, "\0")) { - $val = \substr($val, 0, -1); - } - - return $val; - } - - /** - * Get the server version for the connection. - * - * @return string - */ - public function getServerVersion(): string - { - return $this->connection->getServerVersion(); - } - - /** - * Get the native PDO connection. - * - * @return \PDO - */ - public function getNativeConnection(): PDO - { - return $this->connection->getWrappedConnection(); - } -} diff --git a/src/DBAL/PDO/SqlServerDriver.php b/src/DBAL/PDO/SqlServerDriver.php index 442dbfa1..561d501e 100644 --- a/src/DBAL/PDO/SqlServerDriver.php +++ b/src/DBAL/PDO/SqlServerDriver.php @@ -3,22 +3,10 @@ namespace KitLoong\MigrationsGenerator\DBAL\PDO; use Doctrine\DBAL\Driver\AbstractSQLServerDriver; -use Doctrine\DBAL\Driver\Connection as ConnectionContract; class SqlServerDriver extends AbstractSQLServerDriver { - /** - * Create a new database connection. - * - * @param mixed[] $params - * @return \KitLoong\MigrationsGenerator\DBAL\PDO\SqlServerConnection - */ - public function connect(array $params): ConnectionContract - { - return new SqlServerConnection( - new Connection($params['pdo']) - ); - } + use ConnectsToDatabase; public function getName(): string { From c02f9c06906e3f147544fed0c065d78a6f3833bb Mon Sep 17 00:00:00 2001 From: Kit Loong Date: Thu, 8 Feb 2024 21:37:33 +0800 Subject: [PATCH 09/20] Remove old code --- src/Enum/Migrations/Method/ColumnType.php | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/Enum/Migrations/Method/ColumnType.php b/src/Enum/Migrations/Method/ColumnType.php index 0a64ca5d..59f16bfd 100644 --- a/src/Enum/Migrations/Method/ColumnType.php +++ b/src/Enum/Migrations/Method/ColumnType.php @@ -3,7 +3,6 @@ namespace KitLoong\MigrationsGenerator\Enum\Migrations\Method; use MyCLabs\Enum\Enum; -use UnexpectedValueException; /** * Define column types of the framework. @@ -134,16 +133,6 @@ final class ColumnType extends Enum */ public static function fromValue(string $value): self { - if (method_exists(Enum::class, 'from')) { - return parent::from($value); - } - - $key = self::search($value); - - if ($key === false) { - throw new UnexpectedValueException("Value '$value' is not part of the enum " . self::class); - } - - return self::__callStatic($key, []); + return parent::from($value); } } From d9b066b95543185584b93cace94d10d2f65cfefc Mon Sep 17 00:00:00 2001 From: Kit Loong Date: Tue, 27 Feb 2024 23:01:23 +0800 Subject: [PATCH 10/20] Remove Doctrine DBAL * Support minimum Laravel v10.38 * Support minimum PHP 8.1 * Lint fix --- .github/workflows/{check.yml => lint.yml} | 0 .github/workflows/tests.yml | 20 +- composer.json | 7 +- phpcs.xml | 4 +- phpstan.neon | 5 +- src/DBAL/Connection.php | 87 ------ src/DBAL/DBALSchema.php | 67 ----- src/DBAL/Models/DBALCustomColumn.php | 97 ------- src/DBAL/Models/MySQL/MySQLCustomColumn.php | 9 - src/DBAL/Models/MySQL/MySQLForeignKey.php | 9 - src/DBAL/Models/MySQL/MySQLProcedure.php | 9 - src/DBAL/Models/MySQL/MySQLTable.php | 46 ---- src/DBAL/Models/MySQL/MySQLView.php | 21 -- src/DBAL/Models/PgSQL/PgSQLCustomColumn.php | 9 - src/DBAL/Models/PgSQL/PgSQLForeignKey.php | 9 - src/DBAL/Models/PgSQL/PgSQLIndex.php | 44 --- src/DBAL/Models/PgSQL/PgSQLProcedure.php | 9 - src/DBAL/Models/PgSQL/PgSQLTable.php | 86 ------ src/DBAL/Models/PgSQL/PgSQLView.php | 36 --- src/DBAL/Models/SQLSrv/SQLSrvCustomColumn.php | 9 - src/DBAL/Models/SQLSrv/SQLSrvForeignKey.php | 9 - src/DBAL/Models/SQLSrv/SQLSrvProcedure.php | 9 - src/DBAL/Models/SQLSrv/SQLSrvTable.php | 46 ---- src/DBAL/Models/SQLSrv/SQLSrvView.php | 36 --- src/DBAL/Models/SQLite/SQLiteCustomColumn.php | 9 - src/DBAL/Models/SQLite/SQLiteForeignKey.php | 9 - src/DBAL/Models/SQLite/SQLiteTable.php | 46 ---- src/DBAL/Models/SQLite/SQLiteView.php | 17 -- src/DBAL/MySQLSchema.php | 79 ------ src/DBAL/PDO/ConnectsToDatabase.php | 19 -- src/DBAL/PDO/MySqlDriver.php | 15 -- src/DBAL/PDO/PostgresDriver.php | 15 -- src/DBAL/PDO/SQLiteDriver.php | 15 -- src/DBAL/PDO/SqlServerDriver.php | 15 -- src/DBAL/PgSQLSchema.php | 116 -------- src/DBAL/RegisterColumnType.php | 172 ------------ src/DBAL/SQLSrvSchema.php | 79 ------ src/DBAL/SQLiteSchema.php | 71 ----- src/DBAL/Types/CustomType.php | 9 - src/DBAL/Types/DoubleType.php | 29 -- src/DBAL/Types/EnumType.php | 29 -- src/DBAL/Types/GeographyType.php | 29 -- src/DBAL/Types/GeometryCollectionType.php | 29 -- src/DBAL/Types/GeometryType.php | 29 -- src/DBAL/Types/IpAddressType.php | 29 -- src/DBAL/Types/JsonbType.php | 29 -- src/DBAL/Types/LineStringType.php | 29 -- src/DBAL/Types/MacAddressType.php | 29 -- src/DBAL/Types/MediumIntegerType.php | 29 -- src/DBAL/Types/MultiLineStringType.php | 29 -- src/DBAL/Types/MultiPointType.php | 29 -- src/DBAL/Types/MultiPolygonType.php | 29 -- src/DBAL/Types/PointType.php | 29 -- src/DBAL/Types/PolygonType.php | 29 -- src/DBAL/Types/SetType.php | 29 -- src/DBAL/Types/TimeTzType.php | 29 -- src/DBAL/Types/TimestampType.php | 29 -- src/DBAL/Types/TimestampTzType.php | 29 -- src/DBAL/Types/TinyIntegerType.php | 29 -- src/DBAL/Types/Types.php | 98 ------- src/DBAL/Types/UUIDType.php | 29 -- src/DBAL/Types/YearType.php | 29 -- src/Database/DatabaseColumnType.php | 22 ++ src/Database/DatabaseSchema.php | 130 +++++++++ .../Models/DatabaseColumn.php} | 252 ++++++------------ src/Database/Models/DatabaseCustomColumn.php | 56 ++++ .../Models/DatabaseForeignKey.php} | 25 +- .../Models/DatabaseIndex.php} | 51 ++-- .../Models/DatabaseProcedure.php} | 4 +- .../Models/DatabaseTable.php} | 84 +++--- .../Models/DatabaseView.php} | 25 +- .../Models/MySQL/MySQLColumn.php | 197 +++++++++++--- src/Database/Models/MySQL/MySQLColumnType.php | 70 +++++ .../Models/MySQL/MySQLCustomColumn.php | 9 + src/Database/Models/MySQL/MySQLForeignKey.php | 9 + .../Models/MySQL/MySQLIndex.php | 13 +- src/Database/Models/MySQL/MySQLProcedure.php | 9 + src/Database/Models/MySQL/MySQLTable.php | 35 +++ src/Database/Models/MySQL/MySQLView.php | 18 ++ .../Models/PgSQL/PgSQLColumn.php | 117 +++----- src/Database/Models/PgSQL/PgSQLColumnType.php | 68 +++++ .../Models/PgSQL/PgSQLCustomColumn.php | 40 +++ src/Database/Models/PgSQL/PgSQLForeignKey.php | 9 + .../Models/PgSQL/PgSQLIndex.php} | 13 +- src/Database/Models/PgSQL/PgSQLParser.php | 32 +++ src/Database/Models/PgSQL/PgSQLProcedure.php | 9 + src/Database/Models/PgSQL/PgSQLTable.php | 93 +++++++ src/Database/Models/PgSQL/PgSQLView.php | 18 ++ .../Models/SQLSrv/SQLSrvColumn.php | 113 +++++--- .../Models/SQLSrv/SQLSrvColumnType.php | 56 ++++ .../Models/SQLSrv/SQLSrvCustomColumn.php | 37 +++ .../Models/SQLSrv/SQLSrvForeignKey.php | 9 + .../Models/SQLSrv/SQLSrvIndex.php | 33 +-- src/Database/Models/SQLSrv/SQLSrvParser.php | 34 +++ .../Models/SQLSrv/SQLSrvProcedure.php | 9 + src/Database/Models/SQLSrv/SQLSrvTable.php | 35 +++ src/Database/Models/SQLSrv/SQLSrvView.php | 18 ++ .../Models/SQLite/SQLiteColumn.php | 70 +++-- .../Models/SQLite/SQLiteColumnType.php | 57 ++++ .../Models/SQLite/SQLiteCustomColumn.php | 9 + .../Models/SQLite/SQLiteForeignKey.php | 9 + src/Database/Models/SQLite/SQLiteIndex.php | 26 ++ src/Database/Models/SQLite/SQLiteTable.php | 35 +++ src/Database/Models/SQLite/SQLiteView.php | 18 ++ src/Database/MySQLSchema.php | 69 +++++ src/Database/PgSQLSchema.php | 126 +++++++++ src/Database/SQLSrvSchema.php | 92 +++++++ src/Database/SQLiteSchema.php | 62 +++++ src/Enum/Migrations/Method/ColumnType.php | 3 - src/MigrateGenerateCommand.php | 4 +- src/Migration/Blueprint/Method.php | 8 +- src/Migration/Blueprint/TableBlueprint.php | 4 +- src/Migration/ForeignKeyMigration.php | 8 +- .../Generator/Columns/DecimalColumn.php | 4 + .../Generator/Columns/FloatColumn.php | 4 +- .../Generator/ForeignKeyGenerator.php | 21 +- .../Generator/Modifiers/DefaultModifier.php | 8 +- src/MigrationsGeneratorServiceProvider.php | 10 +- src/Repositories/MySQLRepository.php | 118 +++----- src/Repositories/PgSQLRepository.php | 29 -- src/Repositories/Repository.php | 3 - src/Repositories/SQLSrvRepository.php | 43 ++- src/Schema/Models/Column.php | 5 - src/Schema/Models/Index.php | 7 - src/Schema/Schema.php | 4 +- src/Support/AssetNameQuote.php | 28 +- tests/Feature/FeatureTestCase.php | 23 +- tests/Feature/MariaDB/TablePrefixTest.php | 53 ++++ tests/Feature/MySQL57/CommandTest.php | 2 +- tests/Feature/MySQL57/DBConnectionTest.php | 58 ++-- tests/Feature/MySQL57/StackedCommandTest.php | 78 +++--- tests/Feature/MySQL57/TablePrefixTest.php | 20 +- tests/Feature/MySQL8/TablePrefixTest.php | 53 ++++ tests/Feature/PgSQL/CommandTest.php | 66 +---- tests/Feature/PgSQL/PgSQLTestCase.php | 36 +-- tests/Feature/PgSQL/TablePrefixTest.php | 26 +- tests/Feature/SQLSrv/CommandTest.php | 13 - tests/Feature/SQLSrv/SQLSrvTestCase.php | 7 +- tests/Feature/SQLSrv/TablePrefixTest.php | 53 ++++ tests/Feature/SQLite/TablePrefixTest.php | 58 ++++ tests/TestCase.php | 40 +-- tests/TestMigration.php | 7 +- ...0000_expected_create_all_columns_table.php | 27 ++ 143 files changed, 2369 insertions(+), 2992 deletions(-) rename .github/workflows/{check.yml => lint.yml} (100%) delete mode 100644 src/DBAL/Connection.php delete mode 100644 src/DBAL/DBALSchema.php delete mode 100644 src/DBAL/Models/DBALCustomColumn.php delete mode 100644 src/DBAL/Models/MySQL/MySQLCustomColumn.php delete mode 100644 src/DBAL/Models/MySQL/MySQLForeignKey.php delete mode 100644 src/DBAL/Models/MySQL/MySQLProcedure.php delete mode 100644 src/DBAL/Models/MySQL/MySQLTable.php delete mode 100644 src/DBAL/Models/MySQL/MySQLView.php delete mode 100644 src/DBAL/Models/PgSQL/PgSQLCustomColumn.php delete mode 100644 src/DBAL/Models/PgSQL/PgSQLForeignKey.php delete mode 100644 src/DBAL/Models/PgSQL/PgSQLIndex.php delete mode 100644 src/DBAL/Models/PgSQL/PgSQLProcedure.php delete mode 100644 src/DBAL/Models/PgSQL/PgSQLTable.php delete mode 100644 src/DBAL/Models/PgSQL/PgSQLView.php delete mode 100644 src/DBAL/Models/SQLSrv/SQLSrvCustomColumn.php delete mode 100644 src/DBAL/Models/SQLSrv/SQLSrvForeignKey.php delete mode 100644 src/DBAL/Models/SQLSrv/SQLSrvProcedure.php delete mode 100644 src/DBAL/Models/SQLSrv/SQLSrvTable.php delete mode 100644 src/DBAL/Models/SQLSrv/SQLSrvView.php delete mode 100644 src/DBAL/Models/SQLite/SQLiteCustomColumn.php delete mode 100644 src/DBAL/Models/SQLite/SQLiteForeignKey.php delete mode 100644 src/DBAL/Models/SQLite/SQLiteTable.php delete mode 100644 src/DBAL/Models/SQLite/SQLiteView.php delete mode 100644 src/DBAL/MySQLSchema.php delete mode 100644 src/DBAL/PDO/ConnectsToDatabase.php delete mode 100644 src/DBAL/PDO/MySqlDriver.php delete mode 100644 src/DBAL/PDO/PostgresDriver.php delete mode 100644 src/DBAL/PDO/SQLiteDriver.php delete mode 100644 src/DBAL/PDO/SqlServerDriver.php delete mode 100644 src/DBAL/PgSQLSchema.php delete mode 100644 src/DBAL/RegisterColumnType.php delete mode 100644 src/DBAL/SQLSrvSchema.php delete mode 100644 src/DBAL/SQLiteSchema.php delete mode 100644 src/DBAL/Types/CustomType.php delete mode 100644 src/DBAL/Types/DoubleType.php delete mode 100644 src/DBAL/Types/EnumType.php delete mode 100644 src/DBAL/Types/GeographyType.php delete mode 100644 src/DBAL/Types/GeometryCollectionType.php delete mode 100644 src/DBAL/Types/GeometryType.php delete mode 100644 src/DBAL/Types/IpAddressType.php delete mode 100644 src/DBAL/Types/JsonbType.php delete mode 100644 src/DBAL/Types/LineStringType.php delete mode 100644 src/DBAL/Types/MacAddressType.php delete mode 100644 src/DBAL/Types/MediumIntegerType.php delete mode 100644 src/DBAL/Types/MultiLineStringType.php delete mode 100644 src/DBAL/Types/MultiPointType.php delete mode 100644 src/DBAL/Types/MultiPolygonType.php delete mode 100644 src/DBAL/Types/PointType.php delete mode 100644 src/DBAL/Types/PolygonType.php delete mode 100644 src/DBAL/Types/SetType.php delete mode 100644 src/DBAL/Types/TimeTzType.php delete mode 100644 src/DBAL/Types/TimestampType.php delete mode 100644 src/DBAL/Types/TimestampTzType.php delete mode 100644 src/DBAL/Types/TinyIntegerType.php delete mode 100644 src/DBAL/Types/Types.php delete mode 100644 src/DBAL/Types/UUIDType.php delete mode 100644 src/DBAL/Types/YearType.php create mode 100644 src/Database/DatabaseColumnType.php create mode 100644 src/Database/DatabaseSchema.php rename src/{DBAL/Models/DBALColumn.php => Database/Models/DatabaseColumn.php} (55%) create mode 100644 src/Database/Models/DatabaseCustomColumn.php rename src/{DBAL/Models/DBALForeignKey.php => Database/Models/DatabaseForeignKey.php} (65%) rename src/{DBAL/Models/DBALIndex.php => Database/Models/DatabaseIndex.php} (55%) rename src/{DBAL/Models/DBALProcedure.php => Database/Models/DatabaseProcedure.php} (85%) rename src/{DBAL/Models/DBALTable.php => Database/Models/DatabaseTable.php} (51%) rename src/{DBAL/Models/DBALView.php => Database/Models/DatabaseView.php} (57%) rename src/{DBAL => Database}/Models/MySQL/MySQLColumn.php (54%) create mode 100644 src/Database/Models/MySQL/MySQLColumnType.php create mode 100644 src/Database/Models/MySQL/MySQLCustomColumn.php create mode 100644 src/Database/Models/MySQL/MySQLForeignKey.php rename src/{DBAL => Database}/Models/MySQL/MySQLIndex.php (52%) create mode 100644 src/Database/Models/MySQL/MySQLProcedure.php create mode 100644 src/Database/Models/MySQL/MySQLTable.php create mode 100644 src/Database/Models/MySQL/MySQLView.php rename src/{DBAL => Database}/Models/PgSQL/PgSQLColumn.php (61%) create mode 100644 src/Database/Models/PgSQL/PgSQLColumnType.php create mode 100644 src/Database/Models/PgSQL/PgSQLCustomColumn.php create mode 100644 src/Database/Models/PgSQL/PgSQLForeignKey.php rename src/{DBAL/Models/SQLite/SQLiteIndex.php => Database/Models/PgSQL/PgSQLIndex.php} (52%) create mode 100644 src/Database/Models/PgSQL/PgSQLParser.php create mode 100644 src/Database/Models/PgSQL/PgSQLProcedure.php create mode 100644 src/Database/Models/PgSQL/PgSQLTable.php create mode 100644 src/Database/Models/PgSQL/PgSQLView.php rename src/{DBAL => Database}/Models/SQLSrv/SQLSrvColumn.php (53%) create mode 100644 src/Database/Models/SQLSrv/SQLSrvColumnType.php create mode 100644 src/Database/Models/SQLSrv/SQLSrvCustomColumn.php create mode 100644 src/Database/Models/SQLSrv/SQLSrvForeignKey.php rename src/{DBAL => Database}/Models/SQLSrv/SQLSrvIndex.php (54%) create mode 100644 src/Database/Models/SQLSrv/SQLSrvParser.php create mode 100644 src/Database/Models/SQLSrv/SQLSrvProcedure.php create mode 100644 src/Database/Models/SQLSrv/SQLSrvTable.php create mode 100644 src/Database/Models/SQLSrv/SQLSrvView.php rename src/{DBAL => Database}/Models/SQLite/SQLiteColumn.php (65%) create mode 100644 src/Database/Models/SQLite/SQLiteColumnType.php create mode 100644 src/Database/Models/SQLite/SQLiteCustomColumn.php create mode 100644 src/Database/Models/SQLite/SQLiteForeignKey.php create mode 100644 src/Database/Models/SQLite/SQLiteIndex.php create mode 100644 src/Database/Models/SQLite/SQLiteTable.php create mode 100644 src/Database/Models/SQLite/SQLiteView.php create mode 100644 src/Database/MySQLSchema.php create mode 100644 src/Database/PgSQLSchema.php create mode 100644 src/Database/SQLSrvSchema.php create mode 100644 src/Database/SQLiteSchema.php create mode 100644 tests/Feature/MariaDB/TablePrefixTest.php create mode 100644 tests/Feature/MySQL8/TablePrefixTest.php create mode 100644 tests/Feature/SQLSrv/TablePrefixTest.php create mode 100644 tests/Feature/SQLite/TablePrefixTest.php diff --git a/.github/workflows/check.yml b/.github/workflows/lint.yml similarity index 100% rename from .github/workflows/check.yml rename to .github/workflows/lint.yml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 77d69258..2e7c9682 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -77,20 +77,14 @@ jobs: strategy: matrix: - php: [ 8.1, 8.2, 8.3 ] - laravel: [ 9.*, 10.* ] - dbal: [ 3.* ] + php: [ 8.2, 8.3 ] + laravel: [ 11.* ] sqlsrv_extension: [ pdo_sqlsrv ] include: - - php: 8.0 - laravel: 8.* - dbal: 3.* - - php: 8.2 - laravel: 11.* - dbal: 4.* - - php: 8.3 - laravel: 11.* - dbal: 4.* + - php: 8.1 + laravel: 10.38 + - php: 8.1 + laravel: 10.* name: PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }} @@ -119,7 +113,7 @@ jobs: - name: Install dependencies run: | composer config --no-plugins allow-plugins.kylekatarnls/update-helper true - composer require "laravel/framework:${{ matrix.laravel }}" "doctrine/dbal:${{ matrix.dbal }}" --no-interaction --no-update + composer require "laravel/framework:${{ matrix.laravel }}" --no-interaction --no-update composer update --prefer-stable --prefer-dist --no-interaction --no-progress - name: Setup .env diff --git a/composer.json b/composer.json index 2d972eb4..67ead7ab 100644 --- a/composer.json +++ b/composer.json @@ -17,14 +17,13 @@ } ], "require": { - "php": "^8.0", - "illuminate/support": "^8.0|^9.0|^10.0|^11.0", - "doctrine/dbal": "^3.0|^4.0", + "php": "^8.1", + "illuminate/support": "^10.38|^11.0", "myclabs/php-enum": "^1.8", "ext-pdo": "*" }, "require-dev": { - "orchestra/testbench": "^6.0|^7.0|^8.0|^9.0", + "orchestra/testbench": "^8.0|^9.0", "squizlabs/php_codesniffer": "^3.5", "mockery/mockery": "^1.0", "friendsofphp/php-cs-fixer": "^3.1", diff --git a/phpcs.xml b/phpcs.xml index 720e719b..314de429 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -36,7 +36,7 @@ - + @@ -67,7 +67,7 @@ - + diff --git a/phpstan.neon b/phpstan.neon index 940ede59..e6a04458 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -14,8 +14,9 @@ parameters: - '#Class Dotenv\\Dotenv constructor invoked with 1 parameter, 4 required.#' - '#Parameter \#1 \$store of class Dotenv\\Dotenv constructor expects Dotenv\\Store\\StoreInterface, string given.#' - '#Constant (.*)\\Enum\\(.*) is unused#' - - '#Method KitLoong\\MigrationsGenerator\\DBAL\\(.*)Schema::getViews\(\) should return Illuminate\\Support\\Collection but returns Illuminate\\Support\\Collection<(int|\(int\|string\)), KitLoong\\MigrationsGenerator\\DBAL\\Models\\(.*)\\(.*)View>.#' - - '#Method KitLoong\\MigrationsGenerator\\DBAL\\(.*)Schema::getProcedures\(\) should return Illuminate\\Support\\Collection but returns Illuminate\\Support\\Collection<(int|\(int\|string\)), KitLoong\\MigrationsGenerator\\DBAL\\Models\\(.*)\\(.*)Procedure>.#' + - '#Method KitLoong\\MigrationsGenerator\\Database\\(.*)Schema::getViews\(\) should return Illuminate\\Support\\Collection but returns Illuminate\\Support\\Collection<(int|\(int\|string\)), KitLoong\\MigrationsGenerator\\Database\\Models\\(.*)\\(.*)View>.#' + - '#Method KitLoong\\MigrationsGenerator\\Database\\(.*)Schema::getProcedures\(\) should return Illuminate\\Support\\Collection but returns Illuminate\\Support\\Collection<(int|\(int\|string\)), KitLoong\\MigrationsGenerator\\Database\\Models\\(.*)\\(.*)Procedure>.#' + - '#Method KitLoong\\MigrationsGenerator\\Database\\(.*)Schema::getForeignKeys\(\) should return Illuminate\\Support\\Collection but returns Illuminate\\Support\\Collection<(int|\(int\|string\)), KitLoong\\MigrationsGenerator\\Database\\Models\\(.*)\\(.*)ForeignKey>.#' - '#(.*)expects Illuminate\\Support\\Collection, Illuminate\\Support\\Collection given.#' excludePaths: diff --git a/src/DBAL/Connection.php b/src/DBAL/Connection.php deleted file mode 100644 index 508a09f3..00000000 --- a/src/DBAL/Connection.php +++ /dev/null @@ -1,87 +0,0 @@ -doctrineConnection === null) { - $driver = $this->getDoctrineDriver(); - - $this->doctrineConnection = new DoctrineConnection(array_filter([ - 'pdo' => DB::connection()->getPdo(), - 'dbname' => DB::connection()->getDatabaseName(), - 'driver' => $driver->getName(), - 'serverVersion' => DB::connection()->getConfig('server_version'), - ]), $driver); - } - - return $this->doctrineConnection; - } - - /** - * Get the Doctrine DBAL schema manager for the connection. - * - * @return \Doctrine\DBAL\Schema\AbstractSchemaManager - * @throws \Doctrine\DBAL\Exception - */ - public function getDoctrineSchemaManager(): AbstractSchemaManager - { - if (method_exists($this->getDoctrineConnection(), 'createSchemaManager')) { - return $this->getDoctrineConnection()->createSchemaManager(); - } - - // @codeCoverageIgnoreStart - // @phpstan-ignore-next-line - return $this->getDoctrineConnection()->getSchemaManager(); - // @codeCoverageIgnoreEnd - } - - /** - * Get the Doctrine DBAL driver. - */ - protected function getDoctrineDriver(): SQLiteDriver|SqlServerDriver|MySqlDriver|PostgresDriver - { - switch (true) { - case DB::connection() instanceof MySqlConnection: - return new MySqlDriver(); - - case DB::connection() instanceof SqlServerConnection: - return new SqlServerDriver(); - - case DB::connection() instanceof PostgresConnection: - return new PostgresDriver(); - - default: - return new SQLiteDriver(); - } - } -} diff --git a/src/DBAL/DBALSchema.php b/src/DBAL/DBALSchema.php deleted file mode 100644 index 46143943..00000000 --- a/src/DBAL/DBALSchema.php +++ /dev/null @@ -1,67 +0,0 @@ - - */ - protected AbstractSchemaManager $dbalSchema; - - /** - * @throws \Doctrine\DBAL\Exception - */ - public function __construct(RegisterColumnType $registerColumnType) - { - // @phpstan-ignore-next-line - $this->dbalSchema = app(Connection::class)->getDoctrineSchemaManager(); - $registerColumnType->handle(); - } - - /** - * @inheritDoc - * @throws \Doctrine\DBAL\Exception - */ - public function getTableNames(): Collection - { - return (new Collection($this->dbalSchema->listTableNames())) - ->map(function ($table) { - // The table name may contain quotes. - // Always trim quotes before set into list. - if ($this->isIdentifierQuoted($table)) { - return $this->trimQuotes($table); - } - - return $table; - }); - } - - /** - * Introspects the table with the given name. - * `listTableDetails` is deprecated since `doctrine/dbal` v3.5 and will be removed from v4. - * This method will try to call `introspectTable` and fallback to `listTableDetails`. - * - * @throws \Doctrine\DBAL\Exception - */ - protected function introspectTable(string $name): Table - { - if (method_exists($this->dbalSchema, 'introspectTable')) { - return $this->dbalSchema->introspectTable($name); - } - - // @phpstan-ignore-next-line - return $this->dbalSchema->listTableDetails($name); - } -} diff --git a/src/DBAL/Models/DBALCustomColumn.php b/src/DBAL/Models/DBALCustomColumn.php deleted file mode 100644 index c2d0ce3e..00000000 --- a/src/DBAL/Models/DBALCustomColumn.php +++ /dev/null @@ -1,97 +0,0 @@ -name = $column->getName(); - $this->tableName = $table; - - // COLLATE clause cannot be used on user-defined data types. - // Unset collation here. - $platformOptions = $column->getPlatformOptions(); - unset($platformOptions['collation']); - $column->setPlatformOptions($platformOptions); - - $tableDiff = $this->getTableDiff($column); - - $this->sqls = app(Connection::class)->getDoctrineConnection()->getDatabasePlatform()->getAlterTableSQL($tableDiff); - } - - /** - * @inheritDoc - */ - public function getName(): string - { - return $this->name; - } - - /** - * @inheritDoc - */ - public function getTableName(): string - { - return $this->tableName; - } - - /** - * @inheritDoc - */ - public function getSqls(): array - { - return $this->sqls; - } - - /** - * Initialize a TableDiff instance based on the table name. - * The \Doctrine\DBAL\Schema\TableDiff constructor has been updated from Doctrine DBAL 3 to DBAL 4. - * This method utilizes the Laravel version to determine which TableDiff constructor to use, as Laravel 11 requires Doctrine DBAL 4. - * - * @see https://github.com/doctrine/dbal/pull/5683 - */ - private function getTableDiff(DoctrineDBALColumn $column): TableDiff - { - if ($this->atLeastLaravel11()) { - return new TableDiff( - new Table($this->tableName), - [$column], - [], - [], - [], - [], - [], - [], - [], - [], - [], - [], - ); - } - - // @phpstan-ignore-next-line - return new TableDiff($this->tableName, [$column]); - } -} diff --git a/src/DBAL/Models/MySQL/MySQLCustomColumn.php b/src/DBAL/Models/MySQL/MySQLCustomColumn.php deleted file mode 100644 index 29a6f9f9..00000000 --- a/src/DBAL/Models/MySQL/MySQLCustomColumn.php +++ /dev/null @@ -1,9 +0,0 @@ -definition = app(Connection::class)->getDoctrineConnection() - ->getDatabasePlatform() - ->getCreateViewSQL($this->quotedName, $view->getSql()); - } -} diff --git a/src/DBAL/Models/PgSQL/PgSQLCustomColumn.php b/src/DBAL/Models/PgSQL/PgSQLCustomColumn.php deleted file mode 100644 index 567ccbfc..00000000 --- a/src/DBAL/Models/PgSQL/PgSQLCustomColumn.php +++ /dev/null @@ -1,9 +0,0 @@ -repository = app(PgSQLRepository::class); - - $this->setTypeToSpatial(); - - switch ($this->type) { - case IndexType::PRIMARY(): - // Reset name to empty to indicate use the database platform naming. - $this->name = ''; - break; - - default: - } - } - - private function setTypeToSpatial(): void - { - $spatialNames = $this->repository->getSpatialIndexes($this->tableName) - ->map(static fn (IndexDefinition $indexDefinition) => $indexDefinition->getIndexName()); - - if (!$spatialNames->contains($this->name)) { - return; - } - - $this->type = IndexType::SPATIAL_INDEX(); - } -} diff --git a/src/DBAL/Models/PgSQL/PgSQLProcedure.php b/src/DBAL/Models/PgSQL/PgSQLProcedure.php deleted file mode 100644 index 410b0066..00000000 --- a/src/DBAL/Models/PgSQL/PgSQLProcedure.php +++ /dev/null @@ -1,9 +0,0 @@ -repository = app(PgSQLRepository::class); - - $this->pushFulltextIndexes(); - - $this->indexes = $this->indexes->sortBy(static fn (Index $index) => $index->getName())->values(); - } - - /** - * @inheritDoc - */ - protected function makeColumn(string $table, DoctrineDBALColumn $column): Column - { - return new PgSQLColumn($table, $column); - } - - /** - * @inheritDoc - * @throws \Doctrine\DBAL\Exception - */ - protected function makeCustomColumn(string $table, DoctrineDBALColumn $column): CustomColumn - { - return new PgSQLCustomColumn($table, $column); - } - - /** - * @inheritDoc - */ - protected function makeIndex(string $table, DoctrineDBALIndex $index): Index - { - return new PgSQLIndex($table, $index); - } - - private function pushFulltextIndexes(): void - { - // Get fulltext indexes. - $fulltextIndexes = $this->repository->getFulltextIndexes($this->name); - $fulltextIndexes->each(function (IndexDefinition $indexDefinition): void { - // Get column names in array - // eg: CREATE INDEX fulltext_custom ON public.test_index_pgsql USING gin (to_tsvector('english'::regconfig, (fulltext_custom)::text)) - // Get "fulltext_custom" - preg_match_all('/to_tsvector\((.*), \((.*)\)::text/U', $indexDefinition->getIndexDef(), $matches); - - if (!isset($matches[2])) { - return; - } - - $columns = $matches[2]; - - $this->indexes->push( - new PgSQLIndex( - $this->name, - new DoctrineDBALIndex( - $indexDefinition->getIndexName(), - $columns, - false, - false, - ['fulltext'], - [], - ), - ), - ); - }); - } -} diff --git a/src/DBAL/Models/PgSQL/PgSQLView.php b/src/DBAL/Models/PgSQL/PgSQLView.php deleted file mode 100644 index 78e8b124..00000000 --- a/src/DBAL/Models/PgSQL/PgSQLView.php +++ /dev/null @@ -1,36 +0,0 @@ -getConfig('search_path') ?: DB::connection()->getConfig('schema'); - - if ($view->getNamespaceName() !== $searchPath) { - $this->definition = app(Connection::class)->getDoctrineConnection() - ->getDatabasePlatform() - ->getCreateViewSQL($this->quotedName, $view->getSql()); - return; - } - - // Strip namespace from name. - $name = $view->getShortestName($view->getNamespaceName()); - $this->name = $this->trimQuotes($name); - $this->quotedName = app(Connection::class)->getDoctrineConnection()->quoteIdentifier($this->name); - $this->definition = app(Connection::class)->getDoctrineConnection() - ->getDatabasePlatform() - ->getCreateViewSQL($this->quotedName, $view->getSql()); - $this->dropDefinition = "DROP VIEW IF EXISTS $this->quotedName"; - } -} diff --git a/src/DBAL/Models/SQLSrv/SQLSrvCustomColumn.php b/src/DBAL/Models/SQLSrv/SQLSrvCustomColumn.php deleted file mode 100644 index ab653e49..00000000 --- a/src/DBAL/Models/SQLSrv/SQLSrvCustomColumn.php +++ /dev/null @@ -1,9 +0,0 @@ -getSql() !== null && $view->getSql() !== '') { - // $view->getSql() contains full view definition. - $this->definition = $view->getSql(); - - return; - } - - // Use repository to get view definition. - $viewDefinition = $repository->getView($view->getName()); - - if ($viewDefinition === null) { - return; - } - - $this->definition = $viewDefinition->getDefinition(); - } -} diff --git a/src/DBAL/Models/SQLite/SQLiteCustomColumn.php b/src/DBAL/Models/SQLite/SQLiteCustomColumn.php deleted file mode 100644 index f49e10e9..00000000 --- a/src/DBAL/Models/SQLite/SQLiteCustomColumn.php +++ /dev/null @@ -1,9 +0,0 @@ -definition = $view->getSql(); - } -} diff --git a/src/DBAL/MySQLSchema.php b/src/DBAL/MySQLSchema.php deleted file mode 100644 index aa9790b0..00000000 --- a/src/DBAL/MySQLSchema.php +++ /dev/null @@ -1,79 +0,0 @@ - - */ -class MySQLSchema extends DBALSchema implements MySQLSchemaInterface -{ - public function __construct(RegisterColumnType $registerColumnType, private MySQLRepository $mySQLRepository) - { - parent::__construct($registerColumnType); - } - - /** - * @inheritDoc - * @throws \Doctrine\DBAL\Exception - */ - public function getTable(string $name): Table - { - return new MySQLTable( - $this->introspectTable($name), - $this->dbalSchema->listTableColumns($name), - $this->dbalSchema->listTableIndexes($name), - ); - } - - /** - * @inheritDoc - * @throws \Doctrine\DBAL\Exception - */ - public function getViewNames(): Collection - { - return $this->getViews()->map(static fn (View $view) => $view->getName()); - } - - /** - * @inheritDoc - * @throws \Doctrine\DBAL\Exception - */ - public function getViews(): Collection - { - return (new Collection($this->dbalSchema->listViews())) - ->map(static fn (DoctrineDBALView $view) => new MySQLView($view)); - } - - /** - * @inheritDoc - */ - public function getProcedures(): Collection - { - return (new Collection($this->mySQLRepository->getProcedures())) - ->map(static fn (ProcedureDefinition $procedureDefinition) => new MySQLProcedure($procedureDefinition->getName(), $procedureDefinition->getDefinition())); - } - - /** - * @inheritDoc - * @throws \Doctrine\DBAL\Exception - */ - public function getTableForeignKeys(string $table): Collection - { - // @phpstan-ignore-next-line - return (new Collection($this->dbalSchema->listTableForeignKeys($table))) - ->map(static fn (ForeignKeyConstraint $foreignKeyConstraint) => new MySQLForeignKey($table, $foreignKeyConstraint)); - } -} diff --git a/src/DBAL/PDO/ConnectsToDatabase.php b/src/DBAL/PDO/ConnectsToDatabase.php deleted file mode 100644 index 2372815e..00000000 --- a/src/DBAL/PDO/ConnectsToDatabase.php +++ /dev/null @@ -1,19 +0,0 @@ - - */ -class PgSQLSchema extends DBALSchema -{ - public function __construct(RegisterColumnType $registerColumnType, private PgSQLRepository $pgSQLRepository) - { - parent::__construct($registerColumnType); - } - - /** - * @inheritDoc - */ - public function getTableNames(): Collection - { - return parent::getTableNames() - ->filter(static function (string $table): bool { - // Checks if the table is from user defined "schema". - // If table name do not have namespace, it is using the default namespace. - if (strpos($table, '.') === false) { - return true; - } - - // Schema name defined in the framework configuration. - $searchPath = DB::connection()->getConfig('search_path') ?: DB::connection()->getConfig('schema'); - - $parts = explode('.', $table); - $namespace = $parts[0]; - - return $namespace === $searchPath; - }) - ->values(); - } - - /** - * @inheritDoc - * @throws \Doctrine\DBAL\Exception - */ - public function getTable(string $name): Table - { - return new PgSQLTable( - $this->introspectTable($name), - $this->dbalSchema->listTableColumns($name), - $this->dbalSchema->listTableIndexes($name), - ); - } - - /** - * @inheritDoc - * @throws \Doctrine\DBAL\Exception - */ - public function getViewNames(): Collection - { - return $this->getViews() - ->map(static fn (View $view) => $view->getName()); - } - - /** - * @inheritDoc - * @throws \Doctrine\DBAL\Exception - */ - public function getViews(): Collection - { - return (new Collection($this->dbalSchema->listViews())) - ->filter(static function (DoctrineDBALView $view) { - if (in_array($view->getName(), ['public.geography_columns', 'public.geometry_columns'])) { - return false; - } - - // Start from Laravel 9, the `schema` configuration option used to configure Postgres connection search paths renamed to `search_path`. - // Fallback to `schema` if Laravel version is older than 9. - $searchPath = DB::connection()->getConfig('search_path') ?: DB::connection()->getConfig('schema'); - - return $view->getNamespaceName() === $searchPath; - }) - ->map(static fn (DoctrineDBALView $view) => new PgSQLView($view)) - ->values(); - } - - /** - * @inheritDoc - */ - public function getProcedures(): Collection - { - return (new Collection($this->pgSQLRepository->getProcedures())) - ->map(static fn (ProcedureDefinition $procedureDefinition) => new PgSQLProcedure($procedureDefinition->getName(), $procedureDefinition->getDefinition())); - } - - /** - * @inheritDoc - * @throws \Doctrine\DBAL\Exception - */ - public function getTableForeignKeys(string $table): Collection - { - // @phpstan-ignore-next-line - return (new Collection($this->dbalSchema->listTableForeignKeys($table))) - ->map(static fn (ForeignKeyConstraint $foreignKeyConstraint) => new PgSQLForeignKey($table, $foreignKeyConstraint)); - } -} diff --git a/src/DBAL/RegisterColumnType.php b/src/DBAL/RegisterColumnType.php deleted file mode 100644 index 639e3507..00000000 --- a/src/DBAL/RegisterColumnType.php +++ /dev/null @@ -1,172 +0,0 @@ -registerLaravelColumnType(); - $this->registerLaravelCustomColumnType(); - - $doctrineTypes = [ - Driver::MYSQL()->getValue() => [ - 'bit' => DoctrineDBALTypes::BOOLEAN, - 'geomcollection' => ColumnType::GEOMETRY_COLLECTION, - 'mediumint' => ColumnType::MEDIUM_INTEGER, - 'tinyint' => ColumnType::TINY_INTEGER, - ], - Driver::PGSQL()->getValue() => [ - '_int4' => DoctrineDBALTypes::TEXT, - '_int8' => DoctrineDBALTypes::TEXT, - '_numeric' => DoctrineDBALTypes::FLOAT, - '_text' => DoctrineDBALTypes::TEXT, - 'cidr' => DoctrineDBALTypes::STRING, - 'inet' => ColumnType::IP_ADDRESS, - 'macaddr' => ColumnType::MAC_ADDRESS, - 'oid' => DoctrineDBALTypes::STRING, - ], - Driver::SQLITE()->getValue() => [], - Driver::SQLSRV()->getValue() => [ - 'sysname' => DoctrineDBALTypes::STRING, - 'hierarchyid' => DoctrineDBALTypes::STRING, - 'money' => DoctrineDBALTypes::DECIMAL, - 'smallmoney' => DoctrineDBALTypes::DECIMAL, - 'tinyint' => ColumnType::TINY_INTEGER, - 'xml' => DoctrineDBALTypes::TEXT, - ], - ]; - - // Register DB specific type, and fallback to Laravel column types. - foreach ($doctrineTypes[DB::getDriverName()] as $dbType => $doctrineType) { - $this->registerDoctrineTypeMapping($dbType, $doctrineType); - } - } - - /** - * Register additional column types which are supported by the framework. - * - * @throws \Doctrine\DBAL\Exception - */ - private function registerLaravelColumnType(): void - { - $typesMap = array_flip(Types::ADDITIONAL_TYPES_MAP); - - foreach ($typesMap as $type => $doctrineTypeClassName) { - // Add a new type by providing a `type` name and a `\Doctrine\DBAL\Types\Type` class name. - // eg: `$type = double`, `$doctrineTypeClassName = \KitLoong\MigrationsGenerator\DBAL\Types\DoubleType` - $this->addOrOverrideType($type, $doctrineTypeClassName); - - // Register type mapping so that Doctrine DBAL can recognize the DB column type. - // eg: `$type = double` - // Now Doctrine DBAL can recognize `column double NOT NULL` and create a column instance with type `\KitLoong\MigrationsGenerator\DBAL\Types\DoubleType`. - $this->registerDoctrineTypeMapping($type, $type); - } - } - - /** - * Register additional column types which are not supported by the framework. - * - * @note Uses {@see \Doctrine\DBAL\Types\Type::__construct} instead of {@see \Doctrine\DBAL\Types\Type::addType} here as workaround. - * @throws \Doctrine\DBAL\Exception - * @SuppressWarnings(PHPMD.UnusedFormalParameter) to suppress `getSQLDeclaration` warning. - */ - private function registerLaravelCustomColumnType(): void - { - foreach ($this->getCustomTypes() as $type) { - $customType = new class () extends CustomType { - public string $type = ''; - - /** - * @inheritDoc - */ - public function getSQLDeclaration(array $column, AbstractPlatform $platform): string - { - return $this->type; - } - - /** - * @inheritDoc - */ - public function getName(): string - { - return $this->type; - } - }; - - $customType->type = $type; - - if (!Type::hasType($type)) { - Type::getTypeRegistry()->register($type, $customType); - } - - $this->registerDoctrineTypeMapping($type, $type); - } - } - - /** - * Get a list of custom type names from DB. - * - * @return \Illuminate\Support\Collection - */ - private function getCustomTypes(): Collection - { - switch (DB::getDriverName()) { - case Driver::PGSQL(): - return $this->pgSQLRepository->getCustomDataTypes(); - - case Driver::SQLSRV(): - return $this->sqlSrvRepository->getCustomDataTypes(); - - default: - return new Collection(); - } - } - - /** - * Add or override doctrine type. - * - * @param class-string<\Doctrine\DBAL\Types\Type> $class The class name which is extends {@see \Doctrine\DBAL\Types\Type}. - * @throws \Doctrine\DBAL\Exception - */ - private function addOrOverrideType(string $type, string $class): void - { - if (!Type::hasType($type)) { - Type::addType($type, $class); - return; - } - - Type::overrideType($type, $class); - } - - /** - * Registers a doctrine type to be used in conjunction with a column type of this platform. - * - * @throws \Doctrine\DBAL\Exception - */ - private function registerDoctrineTypeMapping(string $dbType, string $doctrineType): void - { - app(Connection::class)->getDoctrineConnection() - ->getDatabasePlatform() - ->registerDoctrineTypeMapping($dbType, $doctrineType); - } -} diff --git a/src/DBAL/SQLSrvSchema.php b/src/DBAL/SQLSrvSchema.php deleted file mode 100644 index 296c03d0..00000000 --- a/src/DBAL/SQLSrvSchema.php +++ /dev/null @@ -1,79 +0,0 @@ - - */ -class SQLSrvSchema extends DBALSchema -{ - public function __construct(RegisterColumnType $registerColumnType, private SQLSrvRepository $sqlSrvRepository) - { - parent::__construct($registerColumnType); - } - - /** - * @inheritDoc - * @throws \Doctrine\DBAL\Exception - */ - public function getTable(string $name): Table - { - return new SQLSrvTable( - $this->introspectTable($name), - $this->dbalSchema->listTableColumns($name), - $this->dbalSchema->listTableIndexes($name), - ); - } - - /** - * @inheritDoc - * @throws \Doctrine\DBAL\Exception - */ - public function getViewNames(): Collection - { - return $this->getViews()->map(static fn (View $view) => $view->getName()); - } - - /** - * @inheritDoc - * @throws \Doctrine\DBAL\Exception - */ - public function getViews(): Collection - { - return (new Collection($this->dbalSchema->listViews())) - ->map(static fn (DoctrineDBALView $view) => new SQLSrvView($view)) - ->filter(static fn (SQLSrvView $view) => $view->getDefinition() !== ''); - } - - /** - * @inheritDoc - */ - public function getProcedures(): Collection - { - return (new Collection($this->sqlSrvRepository->getProcedures())) - ->map(static fn (ProcedureDefinition $procedureDefinition) => new PgSQLProcedure($procedureDefinition->getName(), $procedureDefinition->getDefinition())); - } - - /** - * @inheritDoc - * @throws \Doctrine\DBAL\Exception - */ - public function getTableForeignKeys(string $table): Collection - { - // @phpstan-ignore-next-line - return (new Collection($this->dbalSchema->listTableForeignKeys($table))) - ->map(static fn (ForeignKeyConstraint $foreignKeyConstraint) => new SQLSrvForeignKey($table, $foreignKeyConstraint)); - } -} diff --git a/src/DBAL/SQLiteSchema.php b/src/DBAL/SQLiteSchema.php deleted file mode 100644 index 4c2654ea..00000000 --- a/src/DBAL/SQLiteSchema.php +++ /dev/null @@ -1,71 +0,0 @@ - - */ -class SQLiteSchema extends DBALSchema -{ - /** - * @inheritDoc - * @throws \Doctrine\DBAL\Exception - */ - public function getTable(string $name): Table - { - return new SQLiteTable( - $this->introspectTable($name), - $this->dbalSchema->listTableColumns($name), - $this->dbalSchema->listTableIndexes($name), - ); - } - - /** - * @inheritDoc - * @throws \Doctrine\DBAL\Exception - */ - public function getViewNames(): Collection - { - return $this->getViews()->map(static fn (View $view) => $view->getName()); - } - - /** - * @inheritDoc - * @throws \Doctrine\DBAL\Exception - */ - public function getViews(): Collection - { - return (new Collection($this->dbalSchema->listViews())) - ->map(static fn (DoctrineDBALView $view) => new SQLiteView($view)); - } - - /** - * @inheritDoc - */ - public function getProcedures(): Collection - { - // Stored procedure is not available. - // https://sqlite.org/forum/info/78a60bdeec7c1ee9 - return new Collection(); - } - - /** - * @inheritDoc - * @throws \Doctrine\DBAL\Exception - */ - public function getTableForeignKeys(string $table): Collection - { - // @phpstan-ignore-next-line - return (new Collection($this->dbalSchema->listTableForeignKeys($table))) - ->map(static fn (ForeignKeyConstraint $foreignKeyConstraint) => new SQLiteForeignKey($table, $foreignKeyConstraint)); - } -} diff --git a/src/DBAL/Types/CustomType.php b/src/DBAL/Types/CustomType.php deleted file mode 100644 index de14bc76..00000000 --- a/src/DBAL/Types/CustomType.php +++ /dev/null @@ -1,9 +0,0 @@ - ColumnType::STRING, - BigIntType::class => ColumnType::BIG_INTEGER, - BinaryType::class => ColumnType::BINARY, - BlobType::class => ColumnType::BINARY, - BooleanType::class => ColumnType::BOOLEAN, - DateType::class => ColumnType::DATE, - DateImmutableType::class => ColumnType::DATE, - DateIntervalType::class => ColumnType::DATE, - DateTimeType::class => ColumnType::DATETIME, - DateTimeImmutableType::class => ColumnType::DATETIME, - DateTimeTzType::class => ColumnType::DATETIME_TZ, - DateTimeTzImmutableType::class => ColumnType::DATETIME_TZ, - DecimalType::class => ColumnType::DECIMAL, - FloatType::class => ColumnType::FLOAT, - GuidType::class => ColumnType::UUID, - IntegerType::class => ColumnType::INTEGER, - JsonType::class => ColumnType::JSON, - SimpleArrayType::class => ColumnType::STRING, - SmallIntType::class => ColumnType::SMALL_INTEGER, - StringType::class => ColumnType::STRING, - TextType::class => ColumnType::TEXT, - TimeType::class => ColumnType::TIME, - TimeImmutableType::class => ColumnType::TIME, - ]; - - /** - * Additional types provided by Migration Generator. - */ - public const ADDITIONAL_TYPES_MAP = [ - DoubleType::class => ColumnType::DOUBLE, - EnumType::class => ColumnType::ENUM, - GeographyType::class => ColumnType::GEOGRAPHY, - GeometryType::class => ColumnType::GEOMETRY, - GeometryCollectionType::class => ColumnType::GEOMETRY_COLLECTION, - IpAddressType::class => ColumnType::IP_ADDRESS, - JsonbType::class => ColumnType::JSONB, - LineStringType::class => ColumnType::LINE_STRING, - MacAddressType::class => ColumnType::MAC_ADDRESS, - MediumIntegerType::class => ColumnType::MEDIUM_INTEGER, - MultiLineStringType::class => ColumnType::MULTI_LINE_STRING, - MultiPointType::class => ColumnType::MULTI_POINT, - MultiPolygonType::class => ColumnType::MULTI_POLYGON, - PointType::class => ColumnType::POINT, - PolygonType::class => ColumnType::POLYGON, - SetType::class => ColumnType::SET, - TimestampType::class => ColumnType::TIMESTAMP, - TimestampTzType::class => ColumnType::TIMESTAMP_TZ, - TimeTzType::class => ColumnType::TIME_TZ, - TinyIntegerType::class => ColumnType::TINY_INTEGER, - UUIDType::class => ColumnType::UUID, - YearType::class => ColumnType::YEAR, - ]; - - /** - * Create instance from {@see \Doctrine\DBAL\Types\Type}. - */ - public static function toColumnType(Type $dbalType): ColumnType - { - $map = self::BUILTIN_TYPES_MAP + self::ADDITIONAL_TYPES_MAP; - return ColumnType::fromValue($map[$dbalType::class]); - } -} diff --git a/src/DBAL/Types/UUIDType.php b/src/DBAL/Types/UUIDType.php deleted file mode 100644 index 35437437..00000000 --- a/src/DBAL/Types/UUIDType.php +++ /dev/null @@ -1,29 +0,0 @@ - $map + */ + protected static function mapToColumnType(array $map, string $dbType): ColumnType + { + $columnType = $map[strtolower($dbType)] ?? ColumnType::STRING(); + return ColumnType::fromValue($columnType); + } +} diff --git a/src/Database/DatabaseSchema.php b/src/Database/DatabaseSchema.php new file mode 100644 index 00000000..11efed5b --- /dev/null +++ b/src/Database/DatabaseSchema.php @@ -0,0 +1,130 @@ + + */ + protected array $tables = []; + + /** + * @inheritDoc + */ + public function getTableNames(): Collection + { + return new Collection(SchemaFacade::getTableListing()); + } + + /** + * Get a table from the schema by name. + * + * @return SchemaTable + */ + protected function getSchemaTable(string $name): array + { + if ($this->tables === []) { + foreach (SchemaFacade::getTables() as $table) { + $this->tables[$table['name']] = $table; + } + } + + return $this->tables[$name]; + } + + /** + * Get columns from the schema by table name. + * + * @return \Illuminate\Support\Collection + */ + protected function getSchemaColumns(string $table): Collection + { + return new Collection(SchemaFacade::getColumns($this->stripTablePrefix($table))); + } + + /** + * Get indexes from the schema by table name. + * + * @return \Illuminate\Support\Collection + */ + protected function getSchemaIndexes(string $table): Collection + { + return new Collection(SchemaFacade::getIndexes($this->stripTablePrefix($table))); + } + + /** + * Get views from the schema. + * + * @return \Illuminate\Support\Collection + */ + protected function getSchemaViews(): Collection + { + return new Collection(SchemaFacade::getViews()); + } + + /** + * Get foreign keys from the schema by table name. + * + * @return \Illuminate\Support\Collection + */ + protected function getSchemaForeignKeys(string $table): Collection + { + return new Collection(SchemaFacade::getForeignKeys($this->stripTablePrefix($table))); + } +} diff --git a/src/DBAL/Models/DBALColumn.php b/src/Database/Models/DatabaseColumn.php similarity index 55% rename from src/DBAL/Models/DBALColumn.php rename to src/Database/Models/DatabaseColumn.php index 4abb408e..b4aef284 100644 --- a/src/DBAL/Models/DBALColumn.php +++ b/src/Database/Models/DatabaseColumn.php @@ -1,26 +1,21 @@ tableName = $table; - $this->name = $column->getName(); - $this->length = $column->getLength(); - $this->type = Types::toColumnType($column->getType()); - $this->scale = $column->getScale(); - $this->precision = $column->getPrecision(); - $this->comment = $this->escapeComment($column->getComment()); - $this->fixed = $column->getFixed(); - $this->unsigned = $column->getUnsigned(); - $this->notNull = $column->getNotnull(); - $this->default = $this->escapeDefault($column->getDefault()); - $this->collation = $column->getPlatformOptions()['collation'] ?? null; - $this->charset = $column->getPlatformOptions()['charset'] ?? null; - $this->autoincrement = $column->getAutoincrement(); - $this->presetValues = []; - $this->onUpdateCurrentTimestamp = false; - $this->rawDefault = false; - $this->virtualDefinition = null; - $this->storedDefinition = null; - $this->spatialSubType = null; - $this->spatialSrID = null; + $this->tableName = $table; + $this->name = $column['name']; + $this->type = $this->getColumnType($column['type_name']); + $this->length = $this->parseLength($column['type']); + [$this->precision, $this->scale] = $this->parsePrecisionAndScale($column['type']); + $this->comment = $this->escapeComment($column['comment']); + $this->notNull = !$column['nullable']; + $this->collation = $column['collation'] !== null && $column['collation'] !== '' ? $column['collation'] : null; + $this->charset = null; + $this->autoincrement = $column['auto_increment']; + $this->presetValues = []; + $this->onUpdateCurrentTimestamp = false; + $this->rawDefault = false; + $this->virtualDefinition = null; + $this->storedDefinition = null; + $this->spatialSubType = null; + $this->spatialSrID = null; $this->setTypeToSoftDeletes(); $this->setTypeToRememberToken(); - $this->setTypeToChar(); - $this->setSpatialSubType($column->getType()); - $this->fixDoubleLength(); - - $this->handle(); } - /** - * Instance extend this abstract may run special handling. - */ - abstract protected function handle(): void; - /** * @inheritDoc */ @@ -162,14 +147,6 @@ public function getComment(): ?string return $this->comment; } - /** - * @inheritDoc - */ - public function isFixed(): bool - { - return $this->fixed; - } - /** * @inheritDoc */ @@ -311,157 +288,104 @@ protected function setTypeToIncrements(bool $supportUnsigned): void } /** - * Set the column type to "unsigned*" if the column is unsigned. + * Escape `'` with `''`. */ - protected function setTypeToUnsigned(): void + protected function escapeDefault(?string $default): ?string { - if ( - !in_array($this->type, [ - ColumnType::BIG_INTEGER(), - ColumnType::INTEGER(), - ColumnType::MEDIUM_INTEGER(), - ColumnType::SMALL_INTEGER(), - ColumnType::TINY_INTEGER(), - ]) - || !$this->unsigned - ) { - return; + if ($default === null) { + return null; } - $this->type = ColumnType::fromValue('unsigned' . ucfirst($this->type)); + $default = str_replace("'", "''", $default); + return addcslashes($default, '\\'); } /** - * Set the column type to "softDeletes" or "softDeletesTz". + * Escape `\` with `\\`. */ - private function setTypeToSoftDeletes(): void + protected function escapeComment(?string $comment): ?string { - if ($this->name !== ColumnName::DELETED_AT()->getValue()) { - return; + if ($comment === null || $comment === '') { + return null; } - switch ($this->type) { - case ColumnType::TIMESTAMP(): - $this->type = ColumnType::SOFT_DELETES(); - return; - - case ColumnType::TIMESTAMP_TZ(): - $this->type = ColumnType::SOFT_DELETES_TZ(); - return; - } + return addcslashes($comment, '\\'); } /** - * Set the column type to "rememberToken". + * Parse the length from the full definition type. */ - private function setTypeToRememberToken(): void + protected function parseLength(string $fullDefinitionType): ?int { - if ( - ColumnName::REMEMBER_TOKEN()->getValue() !== $this->name - || $this->length !== self::REMEMBER_TOKEN_LENGTH - || $this->fixed - ) { - return; + switch ($this->type) { + case ColumnType::CHAR(): + case ColumnType::STRING(): + case ColumnType::DATE(): + case ColumnType::DATETIME(): + case ColumnType::DATETIME_TZ(): + case ColumnType::TIME(): + case ColumnType::TIME_TZ(): + case ColumnType::TIMESTAMP(): + case ColumnType::TIMESTAMP_TZ(): + if (preg_match('/\((\d*)\)/', $fullDefinitionType, $matches) === 1) { + return (int) $matches[1]; + } } - $this->type = ColumnType::REMEMBER_TOKEN(); + return null; } /** - * Set the column type to "char". + * Parse the precision and scale from the full definition type. + * + * @return array{0: int|null, 1: int} */ - private function setTypeToChar(): void + protected function parsePrecisionAndScale(string $fullDefinitionType): array { - if (!$this->fixed) { - return; + switch ($this->type) { + case ColumnType::DECIMAL(): + case ColumnType::DOUBLE(): + case ColumnType::FLOAT(): + if (preg_match('/\((\d+)(?:,\s*(\d+))?\)?/', $fullDefinitionType, $matches) === 1) { + return [(int) $matches[1], isset($matches[2]) ? (int) $matches[2] : 0]; + } } - $this->type = ColumnType::CHAR(); + return [null, 0]; } /** - * Set the column spatial subtype. + * Set the column type to "softDeletes" or "softDeletesTz". */ - private function setSpatialSubType(Type $dbalColumnType): void + private function setTypeToSoftDeletes(): void { - if (!$this->atLeastLaravel11()) { + if ($this->name !== ColumnName::DELETED_AT()->getValue()) { return; } - switch (true) { - case $dbalColumnType instanceof GeometryCollectionType: - $this->spatialSubType = 'geometryCollection'; - break; - - case $dbalColumnType instanceof LineStringType: - $this->spatialSubType = 'lineString'; - break; - - case $dbalColumnType instanceof MultiLineStringType: - $this->spatialSubType = 'multiLineString'; - break; - - case $dbalColumnType instanceof PointType: - $this->spatialSubType = 'point'; - break; - - case $dbalColumnType instanceof MultiPointType: - $this->spatialSubType = 'multiPoint'; - break; - - case $dbalColumnType instanceof PolygonType: - $this->spatialSubType = 'polygon'; - break; - - case $dbalColumnType instanceof MultiPolygonType: - $this->spatialSubType = 'multiPolygon'; - break; + switch ($this->type) { + case ColumnType::TIMESTAMP(): + $this->type = ColumnType::SOFT_DELETES(); + return; - default: + case ColumnType::TIMESTAMP_TZ(): + $this->type = ColumnType::SOFT_DELETES_TZ(); + return; } } /** - * When double is created without total and places, $table->double('double'); - * Doctrine DBAL return precisions 10 and scale 0. - * Reset precisions and scale to 0 here. + * Set the column type to "rememberToken". */ - private function fixDoubleLength(): void + private function setTypeToRememberToken(): void { if ( - !$this->type->equals(ColumnType::DOUBLE()) - || $this->getPrecision() !== 10 - || $this->getScale() !== 0 + ColumnName::REMEMBER_TOKEN()->getValue() !== $this->name + || $this->length !== self::REMEMBER_TOKEN_LENGTH ) { return; } - $this->precision = 0; - $this->scale = 0; - } - - /** - * Escape `'` with `''`. - */ - protected function escapeDefault(?string $default): ?string - { - if ($default === null) { - return null; - } - - $default = str_replace("'", "''", $default); - return addcslashes($default, '\\'); - } - - /** - * Escape `\` with `\\`. - */ - protected function escapeComment(?string $comment): ?string - { - if ($comment === null || $comment === '') { - return null; - } - - return addcslashes($comment, '\\'); + $this->type = ColumnType::REMEMBER_TOKEN(); } } diff --git a/src/Database/Models/DatabaseCustomColumn.php b/src/Database/Models/DatabaseCustomColumn.php new file mode 100644 index 00000000..534c0cfc --- /dev/null +++ b/src/Database/Models/DatabaseCustomColumn.php @@ -0,0 +1,56 @@ +name = $column['name']; + $this->tableName = $table; + } + + /** + * @inheritDoc + */ + public function getName(): string + { + return $this->name; + } + + /** + * @inheritDoc + */ + public function getTableName(): string + { + return $this->tableName; + } + + /** + * @inheritDoc + */ + public function getSqls(): array + { + return $this->sqls; + } +} diff --git a/src/DBAL/Models/DBALForeignKey.php b/src/Database/Models/DatabaseForeignKey.php similarity index 65% rename from src/DBAL/Models/DBALForeignKey.php rename to src/Database/Models/DatabaseForeignKey.php index 0af9c7c5..5976099e 100644 --- a/src/DBAL/Models/DBALForeignKey.php +++ b/src/Database/Models/DatabaseForeignKey.php @@ -1,11 +1,13 @@ tableName = $table; - $this->name = $foreignKeyConstraint->getName(); - $this->localColumns = $foreignKeyConstraint->getUnquotedLocalColumns(); - $this->foreignColumns = $foreignKeyConstraint->getUnquotedForeignColumns(); - $this->foreignTableName = $foreignKeyConstraint->getForeignTableName(); - $this->onUpdate = $foreignKeyConstraint->getOption('onUpdate'); - $this->onDelete = $foreignKeyConstraint->getOption('onDelete'); + $this->name = $foreignKey['name']; + $this->localColumns = $foreignKey['columns']; + $this->foreignColumns = $foreignKey['foreign_columns']; + $this->foreignTableName = $foreignKey['foreign_table']; + $this->onUpdate = $foreignKey['on_update']; + $this->onDelete = $foreignKey['on_delete']; } /** diff --git a/src/DBAL/Models/DBALIndex.php b/src/Database/Models/DatabaseIndex.php similarity index 55% rename from src/DBAL/Models/DBALIndex.php rename to src/Database/Models/DatabaseIndex.php index 42a176ce..7980dff4 100644 --- a/src/DBAL/Models/DBALIndex.php +++ b/src/Database/Models/DatabaseIndex.php @@ -1,23 +1,20 @@ - */ - protected array $lengths; - protected string $name; protected string $tableName; @@ -26,23 +23,17 @@ abstract class DBALIndex implements Index /** * Create an index instance. + * + * @param SchemaIndex $index */ - public function __construct(string $table, DoctrineDBALIndex $index) + public function __construct(string $table, array $index) { $this->tableName = $table; - $this->name = $index->getName(); - $this->columns = $index->getUnquotedColumns(); + $this->name = $index['name']; + $this->columns = $index['columns']; $this->type = $this->getIndexType($index); - $this->lengths = $index->getOptions()['lengths'] ?? array_fill(0, count($this->columns), null); - - $this->handle(); } - /** - * Instance extend this abstract may run special handling. - */ - abstract protected function handle(): void; - /** * @inheritDoc */ @@ -67,14 +58,6 @@ public function getColumns(): array return $this->columns; } - /** - * @inheritDoc - */ - public function getLengths(): array - { - return $this->lengths; - } - /** * @inheritDoc */ @@ -85,22 +68,26 @@ public function getType(): IndexType /** * Get the index type. + * + * @param SchemaIndex $index */ - private function getIndexType(DoctrineDBALIndex $index): IndexType + private function getIndexType(array $index): IndexType { - if ($index->isPrimary()) { + if ($index['primary'] === true) { return IndexType::PRIMARY(); } - if ($index->isUnique()) { + if ($index['unique'] === true) { return IndexType::UNIQUE(); } - if ($index->hasFlag('spatial')) { + // pgsql uses gist + if ($index['type'] === 'spatial' || $index['type'] === 'gist') { return IndexType::SPATIAL_INDEX(); } - if ($index->hasFlag('fulltext')) { + // pgsql uses gin + if ($index['type'] === 'fulltext' || $index['type'] === 'gin') { return IndexType::FULLTEXT(); } diff --git a/src/DBAL/Models/DBALProcedure.php b/src/Database/Models/DatabaseProcedure.php similarity index 85% rename from src/DBAL/Models/DBALProcedure.php rename to src/Database/Models/DatabaseProcedure.php index 33a06e5c..6f83ba0d 100644 --- a/src/DBAL/Models/DBALProcedure.php +++ b/src/Database/Models/DatabaseProcedure.php @@ -1,10 +1,10 @@ $columns Key is quoted name. - * @param array $indexes Key is name. + * @param SchemaTable $table + * @param \Illuminate\Support\Collection $columns Key is quoted name. + * @param \Illuminate\Support\Collection $indexes Key is name. + * @param \Illuminate\Support\Collection $userDefinedTypes */ - public function __construct(DoctrineDBALTable $table, array $columns, array $indexes) + public function __construct(array $table, Collection $columns, Collection $indexes, Collection $userDefinedTypes) { - $this->name = $table->getName(); - $this->comment = $table->getComment(); - $this->collation = $table->getOptions()['collation'] ?? null; + $this->name = $table['name']; + $this->comment = $table['comment']; + $this->collation = $table['collation']; - $this->columns = (new Collection($columns))->reduce(function (Collection $columns, DoctrineDBALColumn $column) use ($table) { - if (!$column->getType() instanceof CustomType) { - $columns->push($this->makeColumn($table->getName(), $column)); + $this->columns = $columns->reduce(function (Collection $columns, array $column) use ($userDefinedTypes) { + if (!$userDefinedTypes->contains($column['type_name'])) { + $columns->push($this->makeColumn($this->name, $column)); } return $columns; }, new Collection())->values(); - $this->customColumns = (new Collection($columns))->reduce(function (Collection $columns, DoctrineDBALColumn $column) use ($table) { - if ($column->getType() instanceof CustomType) { - $columns->push($this->makeCustomColumn($table->getName(), $column)); + $this->customColumns = $columns->reduce(function (Collection $columns, array $column) use ($userDefinedTypes) { + if ($userDefinedTypes->contains($column['type_name'])) { + $columns->push($this->makeCustomColumn($this->name, $column)); } return $columns; }, new Collection())->values(); - $this->indexes = (new Collection($indexes))->map(fn (DoctrineDBALIndex $index) => $this->makeIndex($table->getName(), $index))->values(); - - $this->handle(); + $this->indexes = $indexes->map(fn (array $index) => $this->makeIndex($this->name, $index))->values(); } - /** - * Instance extend this abstract may run special handling. - */ - abstract protected function handle(): void; - - /** - * Make a Column instance. - */ - abstract protected function makeColumn(string $table, DoctrineDBALColumn $column): Column; - - /** - * Make a CustomColumn instance. - */ - abstract protected function makeCustomColumn(string $table, DoctrineDBALColumn $column): CustomColumn; - - /** - * Make an Index instance. - */ - abstract protected function makeIndex(string $table, DoctrineDBALIndex $index): Index; - /** * @inheritDoc */ diff --git a/src/DBAL/Models/DBALView.php b/src/Database/Models/DatabaseView.php similarity index 57% rename from src/DBAL/Models/DBALView.php rename to src/Database/Models/DatabaseView.php index cd9e6eb6..92463275 100644 --- a/src/DBAL/Models/DBALView.php +++ b/src/Database/Models/DatabaseView.php @@ -1,13 +1,14 @@ name = $this->trimQuotes($view->getName()); - $this->quotedName = app(Connection::class)->getDoctrineConnection()->quoteIdentifier($this->name); + $this->name = $view['name']; + $this->quotedName = $this->quoteIdentifier($view['name']); $this->definition = ''; $this->dropDefinition = "DROP VIEW IF EXISTS $this->quotedName"; - - $this->handle($view); } - /** - * Instance extend this abstract may run special handling. - */ - abstract protected function handle(DoctrineDBALView $view): void; - /** * @inheritDoc */ diff --git a/src/DBAL/Models/MySQL/MySQLColumn.php b/src/Database/Models/MySQL/MySQLColumn.php similarity index 54% rename from src/DBAL/Models/MySQL/MySQLColumn.php rename to src/Database/Models/MySQL/MySQLColumn.php index 6f81116e..b3382ffd 100644 --- a/src/DBAL/Models/MySQL/MySQLColumn.php +++ b/src/Database/Models/MySQL/MySQLColumn.php @@ -1,24 +1,56 @@ "\0", + "\\'" => "'", + '\\"' => '"', + '\\b' => "\b", + '\\n' => "\n", + '\\r' => "\r", + '\\t' => "\t", + '\\Z' => "\x1a", + '\\\\' => '\\', + '\\%' => '%', + '\\_' => '_', + + // Internally, MariaDB escapes single quotes using the standard syntax + "''" => "'", + ]; + private MySQLRepository $mysqlRepository; private MariaDBRepository $mariaDBRepository; - protected function handle(): void + /** + * @inheritDoc + */ + public function __construct(string $table, array $column) { + parent::__construct($table, $column); + + $this->default = $this->escapeDefault($column['default']); + $this->unsigned = str_contains($column['type'], 'unsigned'); + + if ($this->isMaria()) { + $this->default = $this->getMariaDBColumnDefault($column['default']); + $this->default = $this->escapeDefault($this->default); + } + $this->mysqlRepository = app(MySQLRepository::class); $this->mariaDBRepository = app(MariaDBRepository::class); @@ -35,15 +67,11 @@ protected function handle(): void break; case ColumnType::ENUM(): - $this->presetValues = $this->getEnumPresetValues(); - break; - - case ColumnType::TEXT(): - $this->type = $this->getTextTypeByLength(); + $this->presetValues = $this->getEnumPresetValues($column['type']); break; case ColumnType::SET(): - $this->presetValues = $this->getSetPresetValues(); + $this->presetValues = $this->getSetPresetValues($column['type']); break; case ColumnType::SOFT_DELETES(): @@ -88,6 +116,28 @@ protected function handle(): void } } + /** + * @inheritDoc + */ + protected function getColumnType(string $type): ColumnType + { + return MySQLColumnType::toColumnType($type); + } + + /** + * @inheritDoc + */ + protected function escapeDefault(?string $default): ?string + { + $default = parent::escapeDefault($default); + + if ($default === null) { + return null; + } + + return addcslashes($default, '\\'); + } + /** * Determine if the connected database is a MariaDB database. */ @@ -97,7 +147,7 @@ private function isMaria(): bool } /** - * Check if the column is "tinyint(1)", if yes then generate as boolean. + * Check if the column is "tinyint(1)". */ private function isBoolean(): bool { @@ -119,12 +169,14 @@ private function isBoolean(): bool * * @return string[] */ - private function getEnumPresetValues(): array + private function getEnumPresetValues(string $fullDefinition): array { - return $this->mysqlRepository->getEnumPresetValues( - $this->tableName, - $this->name, - )->toArray(); + $value = substr( + $fullDefinition, + strlen("enum('"), + -strlen("')"), + ); + return explode("','", $value); } /** @@ -132,12 +184,14 @@ private function getEnumPresetValues(): array * * @return string[] */ - private function getSetPresetValues(): array + private function getSetPresetValues(string $fullDefinition): array { - return $this->mysqlRepository->getSetPresetValues( - $this->tableName, - $this->name, - )->toArray(); + $value = substr( + $fullDefinition, + strlen("set('"), + -strlen("')"), + ); + return explode("','", $value); } /** @@ -159,23 +213,6 @@ private function isJson(): bool return $checkConstraint !== null; } - private function getTextTypeByLength(): ColumnType - { - switch ($this->length) { - case MySQLPlatform::LENGTH_LIMIT_TINYTEXT: - return ColumnType::TINY_TEXT(); - - case MySQLPlatform::LENGTH_LIMIT_TEXT: - return ColumnType::TEXT(); - - case MySQLPlatform::LENGTH_LIMIT_MEDIUMTEXT: - return ColumnType::MEDIUM_TEXT(); - - default: - return ColumnType::LONG_TEXT(); - } - } - /** * Set virtual definition if the column is virtual. */ @@ -217,6 +254,38 @@ private function setRealSpatialColumn(): void return; } + switch ($this->type) { + case ColumnType::GEOMETRY_COLLECTION(): + $this->spatialSubType = 'geometryCollection'; + break; + + case ColumnType::LINE_STRING(): + $this->spatialSubType = 'lineString'; + break; + + case ColumnType::MULTI_LINE_STRING(): + $this->spatialSubType = 'multiLineString'; + break; + + case ColumnType::POINT(): + $this->spatialSubType = 'point'; + break; + + case ColumnType::MULTI_POINT(): + $this->spatialSubType = 'multiPoint'; + break; + + case ColumnType::POLYGON(): + $this->spatialSubType = 'polygon'; + break; + + case ColumnType::MULTI_POLYGON(): + $this->spatialSubType = 'multiPolygon'; + break; + + default: + } + $this->type = ColumnType::GEOMETRY(); $this->spatialSrID = $this->mysqlRepository->getSrID($this->tableName, $this->name); @@ -229,16 +298,56 @@ private function setRealSpatialColumn(): void } /** - * @inheritDoc + * Set the column type to "unsigned*" if the column is unsigned. */ - protected function escapeDefault(?string $default): ?string + private function setTypeToUnsigned(): void { - $default = parent::escapeDefault($default); + if ( + !in_array($this->type, [ + ColumnType::BIG_INTEGER(), + ColumnType::INTEGER(), + ColumnType::MEDIUM_INTEGER(), + ColumnType::SMALL_INTEGER(), + ColumnType::TINY_INTEGER(), + ]) + || !$this->unsigned + ) { + return; + } - if ($default === null) { + $this->type = ColumnType::fromValue('unsigned' . ucfirst($this->type)); + } + + /** + * Return Mysql column default values for MariaDB 10.2.7+ servers. + * + * - Since MariaDb 10.2.7 column defaults stored in information_schema are now quoted + * to distinguish them from expressions (see MDEV-10134). + * - CURRENT_TIMESTAMP, CURRENT_TIME, CURRENT_DATE are stored in information_schema + * as current_timestamp(), currdate(), currtime() + * - Quoted 'NULL' is not enforced by Maria, it is technically possible to have + * null in some circumstances (see https://jira.mariadb.org/browse/MDEV-14053) + * - \' is always stored as '' in information_schema (normalized) + * + * @link https://mariadb.com/kb/en/library/information-schema-columns-table/ + * @link https://jira.mariadb.org/browse/MDEV-13132 + * @param string|null $columnDefault default value as stored in information_schema for MariaDB >= 10.2.7 + */ + private function getMariaDBColumnDefault(?string $columnDefault): ?string + { + if ($columnDefault === 'NULL' || $columnDefault === null) { return null; } - return addcslashes($default, '\\'); + if (preg_match('/^\'(.*)\'$/', $columnDefault, $matches) === 1) { + return strtr($matches[1], self::MARIADB_ESCAPE_SEQUENCES); + } + + return match ($columnDefault) { + 'current_timestamp()' => 'CURRENT_TIMESTAMP', + 'curdate()' => 'CURRENT_DATE', + 'curtime()' => 'CURRENT_TIME', + default => $columnDefault, + }; } } diff --git a/src/Database/Models/MySQL/MySQLColumnType.php b/src/Database/Models/MySQL/MySQLColumnType.php new file mode 100644 index 00000000..653c2c72 --- /dev/null +++ b/src/Database/Models/MySQL/MySQLColumnType.php @@ -0,0 +1,70 @@ + + */ + protected static array $map = [ + 'bigint' => ColumnType::BIG_INTEGER, + 'binary' => ColumnType::BINARY, + 'bit' => ColumnType::BOOLEAN, + 'blob' => ColumnType::BINARY, + 'char' => ColumnType::CHAR, + 'date' => ColumnType::DATE, + 'datetime' => ColumnType::DATETIME, + 'decimal' => ColumnType::DECIMAL, + 'double' => ColumnType::DOUBLE, + 'enum' => ColumnType::ENUM, + 'float' => ColumnType::FLOAT, + 'geography' => ColumnType::GEOGRAPHY, + 'geometry' => ColumnType::GEOMETRY, + 'int' => ColumnType::INTEGER, + 'integer' => ColumnType::INTEGER, + 'json' => ColumnType::JSON, + 'longblob' => ColumnType::BINARY, + 'longtext' => ColumnType::LONG_TEXT, + 'mediumblob' => ColumnType::BINARY, + 'mediumint' => ColumnType::MEDIUM_INTEGER, + 'mediumtext' => ColumnType::MEDIUM_TEXT, + 'numeric' => ColumnType::DECIMAL, + 'real' => ColumnType::FLOAT, + 'set' => ColumnType::SET, + 'smallint' => ColumnType::SMALL_INTEGER, + 'string' => ColumnType::STRING, + 'text' => ColumnType::TEXT, + 'time' => ColumnType::TIME, + 'timestamp' => ColumnType::TIMESTAMP, + 'tinyblob' => ColumnType::BINARY, + 'tinyint' => ColumnType::TINY_INTEGER, + 'tinytext' => ColumnType::TINY_TEXT, + 'varbinary' => ColumnType::BINARY, + 'varchar' => ColumnType::STRING, + 'year' => ColumnType::YEAR, + + // Removed from Laravel v11 + 'geomcollection' => ColumnType::GEOMETRY_COLLECTION, + 'linestring' => ColumnType::LINE_STRING, + 'multilinestring' => ColumnType::MULTI_LINE_STRING, + 'point' => ColumnType::POINT, + 'multipoint' => ColumnType::MULTI_POINT, + 'polygon' => ColumnType::POLYGON, + 'multipolygon' => ColumnType::MULTI_POLYGON, + + // For MariaDB + 'geometrycollection' => ColumnType::GEOMETRY_COLLECTION, + ]; + + /** + * @inheritDoc + */ + public static function toColumnType(string $dbType): ColumnType + { + return self::mapToColumnType(self::$map, $dbType); + } +} diff --git a/src/Database/Models/MySQL/MySQLCustomColumn.php b/src/Database/Models/MySQL/MySQLCustomColumn.php new file mode 100644 index 00000000..d73f0bfa --- /dev/null +++ b/src/Database/Models/MySQL/MySQLCustomColumn.php @@ -0,0 +1,9 @@ +type) { case IndexType::PRIMARY(): // Reset name to empty to indicate use the database platform naming. diff --git a/src/Database/Models/MySQL/MySQLProcedure.php b/src/Database/Models/MySQL/MySQLProcedure.php new file mode 100644 index 00000000..58576aee --- /dev/null +++ b/src/Database/Models/MySQL/MySQLProcedure.php @@ -0,0 +1,9 @@ +definition = 'CREATE VIEW ' . $this->quotedName . ' AS ' . $view['definition']; + } +} diff --git a/src/DBAL/Models/PgSQL/PgSQLColumn.php b/src/Database/Models/PgSQL/PgSQLColumn.php similarity index 61% rename from src/DBAL/Models/PgSQL/PgSQLColumn.php rename to src/Database/Models/PgSQL/PgSQLColumn.php index 06f6e4dc..42c2dbcb 100644 --- a/src/DBAL/Models/PgSQL/PgSQLColumn.php +++ b/src/Database/Models/PgSQL/PgSQLColumn.php @@ -1,19 +1,28 @@ default = $this->parseDefault($column['default'], $this->type); + $this->default = $this->escapeDefault($this->default); + $this->repository = app(PgSQLRepository::class); $this->setTypeToIncrements(false); @@ -28,17 +37,12 @@ protected function handle(): void case ColumnType::TIMESTAMP_TZ(): case ColumnType::SOFT_DELETES(): case ColumnType::SOFT_DELETES_TZ(): - $this->length = $this->getDataTypeLength(); $this->setRawDefault(); break; - case ColumnType::FLOAT(): - $this->fixFloatLength(); - break; - case ColumnType::GEOGRAPHY(): case ColumnType::GEOMETRY(): - $this->setRealSpatialColumn(); + $this->setRealSpatialColumn($column['type']); break; case ColumnType::STRING(): @@ -57,23 +61,23 @@ protected function handle(): void } /** - * Get the column length from DB. + * @inheritDoc */ - private function getDataTypeLength(): ?int + protected function getColumnType(string $type): ColumnType { - $dataType = $this->repository->getTypeByColumnName($this->tableName, $this->name); - - if ($dataType === null) { - return null; - } - - $length = Regex::getTextBetweenFirst($dataType); + return PgSQLColumnType::toColumnType($type); + } - if ($length === null) { - return null; + /** + * @inheritDoc + */ + protected function escapeDefault(?string $default): ?string + { + if (preg_match('/\((.?)\)\)/', $default)) { + return $default; } - return (int) $length; + return parent::escapeDefault($default); } /** @@ -82,23 +86,16 @@ private function getDataTypeLength(): ?int */ private function setRawDefault(): void { - // Reserve now() to generate as `useCurrent`. if ($this->default === 'now()') { - return; - } - - $default = $this->repository->getDefaultByColumnName($this->tableName, $this->name); - - if ($default === null) { + $this->rawDefault = true; return; } // If default value is expression, eg: timezone('Europe/Rome'::text, now()) - if (!preg_match('/\((.?)\)/', $default)) { + if (!preg_match('/\((.?)\)/', $this->default)) { return; } - $this->default = $default; $this->rawDefault = true; } @@ -124,15 +121,9 @@ private function getGeometryMap(): array /** * Set to geometry type base on geography map. */ - private function setRealSpatialColumn(): void + private function setRealSpatialColumn(string $fullDefinitionType): void { - $dataType = $this->repository->getTypeByColumnName($this->tableName, $this->name); - - if ($dataType === null) { - return; - } - - $dataType = strtolower($dataType); + $dataType = strtolower($fullDefinitionType); $dataType = preg_replace('/\s+/', '', $dataType); if ($dataType === 'geography' || $dataType === 'geometry') { @@ -187,21 +178,6 @@ private function getEnumPresetValues(): array return $presetValues; } - /** - * The framework always create float without precision. - * However, Doctrine DBAL always return precisions 10 and scale 0. - * Reset precisions and scale to 0 here. - */ - private function fixFloatLength(): void - { - if ($this->precision !== 10 || $this->scale !== 0) { - return; - } - - $this->precision = 0; - $this->scale = 0; - } - /** * Set stored definition if the column is stored. */ @@ -216,35 +192,4 @@ private function setStoredDefinition(): void $this->default = null; } - - /** - * Override parent method to handle autoincrement with default value. - */ - protected function setTypeToIncrements(bool $supportUnsigned): void - { - // https://www.postgresqltutorial.com/postgresql-tutorial/postgresql-identity-column/ - // https://github.com/doctrine/dbal/pull/5396 - if ( - !in_array($this->type, [ - ColumnType::BIG_INTEGER(), - ColumnType::INTEGER(), - ColumnType::MEDIUM_INTEGER(), - ColumnType::SMALL_INTEGER(), - ColumnType::TINY_INTEGER(), - ]) - ) { - return; - } - - if ( - $this->default !== null && ( - Str::endsWith($this->default, '_seq') || Str::endsWith($this->default, '_seq"') - ) - ) { - $this->default = null; - $this->autoincrement = true; - } - - parent::setTypeToIncrements($supportUnsigned); - } } diff --git a/src/Database/Models/PgSQL/PgSQLColumnType.php b/src/Database/Models/PgSQL/PgSQLColumnType.php new file mode 100644 index 00000000..5128b479 --- /dev/null +++ b/src/Database/Models/PgSQL/PgSQLColumnType.php @@ -0,0 +1,68 @@ + + */ + protected static array $map = [ + '_text' => ColumnType::TEXT, + '_varchar' => ColumnType::STRING, + 'bigint' => ColumnType::BIG_INTEGER, + 'bigserial' => ColumnType::BIG_INTEGER, + 'bool' => ColumnType::BOOLEAN, + 'boolean' => ColumnType::BOOLEAN, + 'bpchar' => ColumnType::CHAR, + 'bytea' => ColumnType::BINARY, + 'char' => ColumnType::CHAR, + 'date' => ColumnType::DATE, + 'datetime' => ColumnType::DATETIME, + 'decimal' => ColumnType::DECIMAL, + 'double precision' => ColumnType::FLOAT, + 'double' => ColumnType::FLOAT, + 'float' => ColumnType::FLOAT, + 'float4' => ColumnType::FLOAT, + 'float8' => ColumnType::FLOAT, + 'geography' => ColumnType::GEOGRAPHY, + 'geometry' => ColumnType::GEOMETRY, + 'inet' => ColumnType::IP_ADDRESS, + 'int' => ColumnType::INTEGER, + 'int2' => ColumnType::SMALL_INTEGER, + 'int4' => ColumnType::INTEGER, + 'int8' => ColumnType::BIG_INTEGER, + 'integer' => ColumnType::INTEGER, + 'interval' => ColumnType::STRING, + 'json' => ColumnType::JSON, + 'jsonb' => ColumnType::JSONB, + 'macaddr' => ColumnType::MAC_ADDRESS, + 'money' => ColumnType::DECIMAL, + 'numeric' => ColumnType::DECIMAL, + 'real' => ColumnType::FLOAT, + 'serial' => ColumnType::INTEGER, + 'serial4' => ColumnType::INTEGER, + 'serial8' => ColumnType::BIG_INTEGER, + 'smallint' => ColumnType::SMALL_INTEGER, + 'text' => ColumnType::TEXT, + 'time' => ColumnType::TIME, + 'timestamp' => ColumnType::TIMESTAMP, + 'timestamptz' => ColumnType::TIMESTAMP_TZ, + 'timetz' => ColumnType::TIME_TZ, + 'tsvector' => ColumnType::TEXT, + 'uuid' => ColumnType::UUID, + 'varchar' => ColumnType::STRING, + 'year' => ColumnType::INTEGER, + ]; + + /** + * @inheritDoc + */ + public static function toColumnType(string $dbType): ColumnType + { + return self::mapToColumnType(self::$map, $dbType); + } +} diff --git a/src/Database/Models/PgSQL/PgSQLCustomColumn.php b/src/Database/Models/PgSQL/PgSQLCustomColumn.php new file mode 100644 index 00000000..00e8566d --- /dev/null +++ b/src/Database/Models/PgSQL/PgSQLCustomColumn.php @@ -0,0 +1,40 @@ +stripTablePrefix($table)); + $blueprint->addColumn('string', $column['name'], [ + 'autoIncrement' => $column['auto_increment'], + 'collation' => $column['collation'], + 'comment' => $column['comment'], + 'default' => $this->parseDefault($column['default'], ColumnType::STRING()), // Assume is string + 'nullable' => $column['nullable'], + // 'after' => "id", + ]); + + $sqls = $blueprint->toSql(Schema::getConnection(), Schema::getConnection()->getSchemaGrammar()); + $sqls[0] = Str::replaceFirst(' varchar ', ' ' . $column['type'] . ' ', $sqls[0]); + + $this->sqls = $sqls; + } +} diff --git a/src/Database/Models/PgSQL/PgSQLForeignKey.php b/src/Database/Models/PgSQL/PgSQLForeignKey.php new file mode 100644 index 00000000..eaea5a3d --- /dev/null +++ b/src/Database/Models/PgSQL/PgSQLForeignKey.php @@ -0,0 +1,9 @@ +type) { case IndexType::PRIMARY(): // Reset name to empty to indicate use the database platform naming. diff --git a/src/Database/Models/PgSQL/PgSQLParser.php b/src/Database/Models/PgSQL/PgSQLParser.php new file mode 100644 index 00000000..51f3b227 --- /dev/null +++ b/src/Database/Models/PgSQL/PgSQLParser.php @@ -0,0 +1,32 @@ +equals(ColumnType::STRING()) || $columnType->equals(ColumnType::TEXT())) { + $default = str_replace("''", "'", $default); + } + + return $default; + } +} diff --git a/src/Database/Models/PgSQL/PgSQLProcedure.php b/src/Database/Models/PgSQL/PgSQLProcedure.php new file mode 100644 index 00000000..4405a430 --- /dev/null +++ b/src/Database/Models/PgSQL/PgSQLProcedure.php @@ -0,0 +1,9 @@ +repository = app(PgSQLRepository::class); + + $this->updateFulltextIndexes(); + + $this->indexes = $this->indexes->sortBy(static fn (Index $index) => $index->getName())->values(); + } + + /** + * @inheritDoc + */ + protected function makeColumn(string $table, array $column): Column + { + return new PgSQLColumn($table, $column); + } + + /** + * @inheritDoc + */ + protected function makeCustomColumn(string $table, array $column): CustomColumn + { + return new PgSQLCustomColumn($table, $column); + } + + /** + * @inheritDoc + */ + protected function makeIndex(string $table, array $index): Index + { + return new PgSQLIndex($table, $index); + } + + /** + * The fulltext index column is empty by default. + * This method query the DB to get the fulltext index columns and update the indexes collection. + */ + private function updateFulltextIndexes(): void + { + $tableName = $this->name; + + // Get fulltext indexes. + $fulltextIndexes = $this->repository->getFulltextIndexes($tableName) + ->keyBy(static fn (IndexDefinition $indexDefinition) => $indexDefinition->getIndexName()); + + $this->indexes = $this->indexes->map(static function (Index $index) use ($fulltextIndexes, $tableName) { + if (!$index->getType()->equals(IndexType::FULLTEXT())) { + return $index; + } + + if (!$fulltextIndexes->has($index->getName())) { + return $index; + } + + preg_match_all('/to_tsvector\((.*), \((.*)\)::text/U', $fulltextIndexes->get($index->getName())->getIndexDef(), $matches); + + $columns = $matches[2]; + + return new PgSQLIndex( + $tableName, + [ + 'name' => $index->getName(), + 'columns' => $columns, + 'type' => 'gin', + 'unique' => $index->getType()->equals(IndexType::UNIQUE()), + 'primary' => $index->getType()->equals(IndexType::PRIMARY()), + ], + ); + }); + } +} diff --git a/src/Database/Models/PgSQL/PgSQLView.php b/src/Database/Models/PgSQL/PgSQLView.php new file mode 100644 index 00000000..9ab70240 --- /dev/null +++ b/src/Database/Models/PgSQL/PgSQLView.php @@ -0,0 +1,18 @@ +definition = 'CREATE VIEW ' . $this->quotedName . ' AS ' . trim($view['definition']); + } +} diff --git a/src/DBAL/Models/SQLSrv/SQLSrvColumn.php b/src/Database/Models/SQLSrv/SQLSrvColumn.php similarity index 53% rename from src/DBAL/Models/SQLSrv/SQLSrvColumn.php rename to src/Database/Models/SQLSrv/SQLSrvColumn.php index d4054cec..86c35fd1 100644 --- a/src/DBAL/Models/SQLSrv/SQLSrvColumn.php +++ b/src/Database/Models/SQLSrv/SQLSrvColumn.php @@ -1,34 +1,39 @@ default = $this->parseDefault($column['default']); + $this->default = $this->escapeDefault($this->default); + $this->repository = app(SQLSrvRepository::class); $this->setTypeToIncrements(false); + $this->fixMoneyPrecision($column['type_name']); switch ($this->type) { case ColumnType::DATE(): @@ -40,37 +45,44 @@ protected function handle(): void case ColumnType::TIMESTAMP_TZ(): case ColumnType::SOFT_DELETES(): case ColumnType::SOFT_DELETES_TZ(): - $this->length = $this->getDataTypeLength(); - break; - - case ColumnType::FLOAT(): - $this->fixFloatLength(); + $this->length = $this->getDateTimeLength(); break; + case ColumnType::CHAR(): case ColumnType::STRING(): - if ($this->isText()) { - $this->type = ColumnType::TEXT(); - break; - } - + case ColumnType::TEXT(): $this->presetValues = $this->getEnumPresetValues(); if (count($this->presetValues) > 0) { $this->type = ColumnType::ENUM(); + break; } + if ($this->isText($column['type'])) { + $this->type = ColumnType::TEXT(); + $this->length = null; + } + + $this->fixLength($column['type_name']); + break; default: } } + /** + * @inheritDoc + */ + protected function getColumnType(string $type): ColumnType + { + return SQLSrvColumnType::toColumnType($type); + } + /** * Get the datetime column length. - * MySQL and PgSQL use "length" for precision while SQLSrv uses "scale". - * Return "scale" as "length". */ - private function getDataTypeLength(): ?int + private function getDateTimeLength(): ?int { $columnDef = $this->repository->getColumnDefinition($this->tableName, $this->name); @@ -87,7 +99,7 @@ private function getDataTypeLength(): ?int return null; } - return $this->scale; + return $columnDef->getScale(); case ColumnType::DATETIME_TZ(): if ( @@ -97,40 +109,38 @@ private function getDataTypeLength(): ?int return null; } - return $this->scale; + return $columnDef->getScale(); default: - return $this->scale; + return $columnDef->getScale(); } } /** - * Check if the column type is "text". + * Set precision to 19 and scale to 4. */ - private function isText(): bool + private function fixMoneyPrecision(string $dbType): void { - $columnDef = $this->repository->getColumnDefinition($this->tableName, $this->name); + if ($dbType === 'money') { + $this->precision = 19; + $this->scale = 4; + return; + } - if ($columnDef === null) { - return false; + if ($dbType !== 'smallmoney') { + return; } - return $columnDef->getType() === self::TEXT_TYPE && $columnDef->getLength() === self::TEXT_LENGTH; + $this->precision = 10; + $this->scale = 4; } /** - * The framework always create float without precision. - * However, Doctrine DBAL always return precisions 53 and scale 0. - * Reset precisions and scale to 0 here. + * Check if the column type is "text". */ - private function fixFloatLength(): void + private function isText(string $fullDefinitionType): bool { - if ($this->precision !== 53 || $this->scale !== 0) { - return; - } - - $this->precision = 0; - $this->scale = 0; + return $fullDefinitionType === 'nvarchar(max)' || $fullDefinitionType === 'varchar(max)'; } /** @@ -145,4 +155,25 @@ private function getEnumPresetValues(): array $this->name, )->toArray(); } + + /** + * Fix the unicode string length. + */ + private function fixLength(string $dbType): void + { + if ($this->length === null) { + return; + } + + switch ($dbType) { + case 'nchar': + case 'ntext': + case 'nvarchar': + // Unicode data requires 2 bytes per character + $this->length /= 2; + return; + + default: + } + } } diff --git a/src/Database/Models/SQLSrv/SQLSrvColumnType.php b/src/Database/Models/SQLSrv/SQLSrvColumnType.php new file mode 100644 index 00000000..e67a3cec --- /dev/null +++ b/src/Database/Models/SQLSrv/SQLSrvColumnType.php @@ -0,0 +1,56 @@ + + */ + protected static array $map = [ + 'bigint' => ColumnType::BIG_INTEGER, + 'binary' => ColumnType::BINARY, + 'bit' => ColumnType::BOOLEAN, + 'blob' => ColumnType::BINARY, + 'char' => ColumnType::STRING, + 'date' => ColumnType::DATE, + 'datetime' => ColumnType::DATETIME, + 'datetime2' => ColumnType::DATETIME, + 'datetimeoffset' => ColumnType::DATETIME_TZ, + 'decimal' => ColumnType::DECIMAL, + 'double precision' => ColumnType::FLOAT, + 'double' => ColumnType::FLOAT, + 'float' => ColumnType::FLOAT, + 'geography' => ColumnType::GEOGRAPHY, + 'geometry' => ColumnType::GEOMETRY, + 'image' => ColumnType::BINARY, + 'int' => ColumnType::INTEGER, + 'money' => ColumnType::DECIMAL, + 'nchar' => ColumnType::CHAR, + 'ntext' => ColumnType::TEXT, + 'numeric' => ColumnType::DECIMAL, + 'nvarchar' => ColumnType::STRING, + 'real' => ColumnType::FLOAT, + 'smalldatetime' => ColumnType::DATETIME, + 'smallint' => ColumnType::SMALL_INTEGER, + 'smallmoney' => ColumnType::DECIMAL, + 'text' => ColumnType::TEXT, + 'time' => ColumnType::TIME, + 'tinyint' => ColumnType::TINY_INTEGER, + 'uniqueidentifier' => ColumnType::UUID, + 'varbinary' => ColumnType::BINARY, + 'varchar' => ColumnType::STRING, + 'xml' => ColumnType::TEXT, + ]; + + /** + * @inheritDoc + */ + public static function toColumnType(string $dbType): ColumnType + { + return self::mapToColumnType(self::$map, $dbType); + } +} diff --git a/src/Database/Models/SQLSrv/SQLSrvCustomColumn.php b/src/Database/Models/SQLSrv/SQLSrvCustomColumn.php new file mode 100644 index 00000000..517d9b51 --- /dev/null +++ b/src/Database/Models/SQLSrv/SQLSrvCustomColumn.php @@ -0,0 +1,37 @@ +stripTablePrefix($table)); + $blueprint->addColumn('string', $column['name'], [ + 'autoIncrement' => $column['auto_increment'], + 'default' => $this->parseDefault($column['default']), + 'nullable' => $column['nullable'], + // 'after' => "id", + ]); + + $sqls = $blueprint->toSql(Schema::getConnection(), Schema::getConnection()->getSchemaGrammar()); + $sqls[0] = Str::replaceFirst(' nvarchar() ', ' ' . $column['type'] . ' ', $sqls[0]); + + $this->sqls = $sqls; + } +} diff --git a/src/Database/Models/SQLSrv/SQLSrvForeignKey.php b/src/Database/Models/SQLSrv/SQLSrvForeignKey.php new file mode 100644 index 00000000..3888c6c1 --- /dev/null +++ b/src/Database/Models/SQLSrv/SQLSrvForeignKey.php @@ -0,0 +1,9 @@ +repository = app(SQLSrvRepository::class); + parent::__construct($table, $index); switch ($this->type) { case IndexType::PRIMARY(): @@ -22,22 +22,7 @@ protected function handle(): void break; default: - $this->changeTypeToSpatial(); - } - } - - /** - * Change the index type to `spatial` if the name is in the spatial index name list. - */ - private function changeTypeToSpatial(): void - { - $spatialNames = $this->repository->getSpatialIndexNames($this->tableName); - - if (!$spatialNames->contains($this->name)) { - return; } - - $this->type = IndexType::SPATIAL_INDEX(); } /** @@ -47,7 +32,7 @@ private function changeTypeToSpatial(): void */ private function resetPrimaryNameToEmptyIfIsDefaultName(): void { - $prefix = 'PK__' . Str::substr($this->tableName, 0, 8) . '__'; + $prefix = 'pk__' . Str::substr($this->tableName, 0, 8) . '__'; // Can be improved by generate exact 16 characters of sequence number instead of `\w{16}` // if the rules of sequence number generation is known. diff --git a/src/Database/Models/SQLSrv/SQLSrvParser.php b/src/Database/Models/SQLSrv/SQLSrvParser.php new file mode 100644 index 00000000..45070ae7 --- /dev/null +++ b/src/Database/Models/SQLSrv/SQLSrvParser.php @@ -0,0 +1,34 @@ +definition = $view['definition']; + } +} diff --git a/src/DBAL/Models/SQLite/SQLiteColumn.php b/src/Database/Models/SQLite/SQLiteColumn.php similarity index 65% rename from src/DBAL/Models/SQLite/SQLiteColumn.php rename to src/Database/Models/SQLite/SQLiteColumn.php index 7033c1c8..69a07928 100644 --- a/src/DBAL/Models/SQLite/SQLiteColumn.php +++ b/src/Database/Models/SQLite/SQLiteColumn.php @@ -1,31 +1,40 @@ default = $this->parseDefault($column['default']); + $this->default = $this->escapeDefault($this->default); + $this->repository = app(SQLiteRepository::class); $this->setAutoincrement(); $this->setTypeToIncrements(false); switch ($this->type) { + case ColumnType::INTEGER(): + if ($this->isBoolean($column['type'])) { + $this->type = ColumnType::BOOLEAN(); + } + + break; + case ColumnType::STRING(): $this->presetValues = $this->getEnumPresetValues(); @@ -42,21 +51,22 @@ protected function handle(): void break; - case ColumnType::DATETIME_TZ(): - if ($this->default === 'CURRENT_TIMESTAMP') { - $this->type = ColumnType::TIMESTAMP_TZ(); - } - - break; - default: } } + /** + * @inheritDoc + */ + protected function getColumnType(string $type): ColumnType + { + return SQLiteColumnType::toColumnType($type); + } + /** * If column is integer and primary key, - * doctrine/dbal assume the column is autoincrement, but it could be wrong. - * Should check full sql statement from sqlite_master to ensure autoincrement is written corretly. + * The column is autoincrement, but it could be wrong. + * Should check full sql statement from sqlite_master to ensure autoincrement is written correctly. */ private function setAutoincrement(): void { @@ -96,6 +106,18 @@ private function setAutoincrement(): void } } + /** + * Check if the column is "tinyint(1)". + */ + private function isBoolean(string $fullDefinitionType): bool + { + if ($this->autoincrement) { + return false; + } + + return $fullDefinitionType === 'tinyint(1)'; + } + /** * Get the preset values if the column is "enum". * @@ -119,4 +141,20 @@ private function getEnumPresetValues(): array return $values; } + + /** + * Parse the default value. + */ + private function parseDefault(?string $default): ?string + { + if ($default === null) { + return null; + } + + while (preg_match('/^\'(.*)\'$/s', $default, $matches)) { + $default = str_replace("''", "'", $matches[1]); + } + + return $default; + } } diff --git a/src/Database/Models/SQLite/SQLiteColumnType.php b/src/Database/Models/SQLite/SQLiteColumnType.php new file mode 100644 index 00000000..988f1fb1 --- /dev/null +++ b/src/Database/Models/SQLite/SQLiteColumnType.php @@ -0,0 +1,57 @@ + + */ + protected static array $map = [ + 'bigint' => ColumnType::BIG_INTEGER, + 'bigserial' => ColumnType::BIG_INTEGER, + 'blob' => ColumnType::BINARY, + 'boolean' => ColumnType::BOOLEAN, + 'char' => ColumnType::STRING, + 'clob' => ColumnType::TEXT, + 'date' => ColumnType::DATE, + 'datetime' => ColumnType::DATETIME, + 'decimal' => ColumnType::DECIMAL, + 'double' => ColumnType::DOUBLE, + 'double precision' => ColumnType::DOUBLE, + 'float' => ColumnType::FLOAT, + 'image' => ColumnType::STRING, + 'int' => ColumnType::INTEGER, + 'integer' => ColumnType::INTEGER, + 'geometry' => ColumnType::GEOMETRY, + 'longtext' => ColumnType::TEXT, + 'longvarchar' => ColumnType::STRING, + 'mediumint' => ColumnType::INTEGER, + 'mediumtext' => ColumnType::TEXT, + 'ntext' => ColumnType::STRING, + 'numeric' => ColumnType::DECIMAL, + 'nvarchar' => ColumnType::STRING, + 'real' => ColumnType::FLOAT, + 'serial' => ColumnType::INTEGER, + 'smallint' => ColumnType::INTEGER, + 'string' => ColumnType::STRING, + 'text' => ColumnType::TEXT, + 'time' => ColumnType::TIME, + 'timestamp' => ColumnType::DATETIME, + 'tinyint' => ColumnType::INTEGER, + 'tinytext' => ColumnType::TEXT, + 'varchar' => ColumnType::STRING, + 'varchar2' => ColumnType::STRING, + ]; + + /** + * @inheritDoc + */ + public static function toColumnType(string $dbType): ColumnType + { + return self::mapToColumnType(self::$map, $dbType); + } +} diff --git a/src/Database/Models/SQLite/SQLiteCustomColumn.php b/src/Database/Models/SQLite/SQLiteCustomColumn.php new file mode 100644 index 00000000..fd4cb416 --- /dev/null +++ b/src/Database/Models/SQLite/SQLiteCustomColumn.php @@ -0,0 +1,9 @@ +type) { + case IndexType::PRIMARY(): + // Reset name to empty to indicate use the database platform naming. + $this->name = ''; + break; + + default: + } + } +} diff --git a/src/Database/Models/SQLite/SQLiteTable.php b/src/Database/Models/SQLite/SQLiteTable.php new file mode 100644 index 00000000..209c018c --- /dev/null +++ b/src/Database/Models/SQLite/SQLiteTable.php @@ -0,0 +1,35 @@ +definition = $view['definition']; + } +} diff --git a/src/Database/MySQLSchema.php b/src/Database/MySQLSchema.php new file mode 100644 index 00000000..1501b540 --- /dev/null +++ b/src/Database/MySQLSchema.php @@ -0,0 +1,69 @@ +getSchemaTable($name), + $this->getSchemaColumns($name), + $this->getSchemaIndexes($name), + new Collection(), + ); + } + + /** + * @inheritDoc + */ + public function getViewNames(): Collection + { + return $this->getViews()->map(static fn (View $view) => $view->getName()); + } + + /** + * @inheritDoc + */ + public function getViews(): Collection + { + return $this->getSchemaViews() + ->map(static fn (array $view) => new MySQLView($view)); + } + + /** + * @inheritDoc + */ + public function getProcedures(): Collection + { + return $this->mySQLRepository->getProcedures() + ->map(static fn (ProcedureDefinition $procedureDefinition) => new MySQLProcedure($procedureDefinition->getName(), $procedureDefinition->getDefinition())); + } + + /** + * @inheritDoc + */ + public function getForeignKeys(string $table): Collection + { + return $this->getSchemaForeignKeys($table) + ->map(static fn (array $foreignKey) => new MySQLForeignKey($table, $foreignKey)); + } +} diff --git a/src/Database/PgSQLSchema.php b/src/Database/PgSQLSchema.php new file mode 100644 index 00000000..889a7e1f --- /dev/null +++ b/src/Database/PgSQLSchema.php @@ -0,0 +1,126 @@ + + */ + private Collection $userDefinedTypes; + + private bool $ranGetUserDefinedTypes = false; + + public function __construct(private readonly PgSQLRepository $pgSQLRepository) + { + $this->userDefinedTypes = new Collection(); + } + + /** + * @inheritDoc + */ + public function getTableNames(): Collection + { + return (new Collection(Schema::getTables())) + ->filter(static function (array $table): bool { + if ($table['name'] === 'spatial_ref_sys') { + return false; + } + + // Schema name defined in the framework configuration. + $searchPath = DB::connection()->getConfig('search_path') ?: DB::connection()->getConfig('schema'); + + return $table['schema'] === $searchPath; + }) + ->pluck('name') + ->values(); + } + + /** + * @inheritDoc + */ + public function getTable(string $name): Table + { + return new PgSQLTable( + $this->getSchemaTable($name), + $this->getSchemaColumns($name), + $this->getSchemaIndexes($name), + $this->getUserDefinedTypes(), + ); + } + + /** + * @inheritDoc + */ + public function getViewNames(): Collection + { + return $this->getViews() + ->map(static fn (View $view) => $view->getName()); + } + + /** + * @inheritDoc + */ + public function getViews(): Collection + { + return $this->getSchemaViews() + ->filter(static function (array $view) { + if (in_array($view['name'], ['geography_columns', 'geometry_columns'])) { + return false; + } + + // Start from Laravel 9, the `schema` configuration option used to configure Postgres connection search paths renamed to `search_path`. + // Fallback to `schema` if Laravel version is older than 9. + $searchPath = DB::connection()->getConfig('search_path') ?: DB::connection()->getConfig('schema'); + + return $view['schema'] === $searchPath; + }) + ->map(static fn (array $view) => new PgSQLView($view)) + ->values(); + } + + /** + * @inheritDoc + */ + public function getProcedures(): Collection + { + return $this->pgSQLRepository->getProcedures() + ->map(static fn (ProcedureDefinition $procedureDefinition) => new PgSQLProcedure($procedureDefinition->getName(), $procedureDefinition->getDefinition())); + } + + /** + * @inheritDoc + */ + public function getForeignKeys(string $table): Collection + { + return $this->getSchemaForeignKeys($table) + ->map(static fn (array $foreignKey) => new PgSQLForeignKey($table, $foreignKey)); + } + + /** + * Get user defined types from the schema. + * + * @return \Illuminate\Support\Collection + */ + private function getUserDefinedTypes(): Collection + { + if (!$this->ranGetUserDefinedTypes) { + $this->userDefinedTypes = new Collection(array_column(Schema::getTypes(), 'name')); + $this->ranGetUserDefinedTypes = true; + } + + return $this->userDefinedTypes; + } +} diff --git a/src/Database/SQLSrvSchema.php b/src/Database/SQLSrvSchema.php new file mode 100644 index 00000000..17bf17d0 --- /dev/null +++ b/src/Database/SQLSrvSchema.php @@ -0,0 +1,92 @@ + + */ + private Collection $userDefinedTypes; + + private bool $ranGetUserDefinedTypes = false; + + public function __construct(private readonly SQLSrvRepository $sqlSrvRepository) + { + $this->userDefinedTypes = new Collection(); + } + + /** + * @inheritDoc + */ + public function getTable(string $name): Table + { + return new SQLSrvTable( + $this->getSchemaTable($name), + $this->getSchemaColumns($name), + $this->getSchemaIndexes($name), + $this->getUserDefinedTypes(), + ); + } + + /** + * @inheritDoc + */ + public function getViewNames(): Collection + { + return $this->getViews()->map(static fn (View $view) => $view->getName()); + } + + /** + * @inheritDoc + */ + public function getViews(): Collection + { + return $this->getSchemaViews() + ->map(static fn (array $view) => new SQLSrvView($view)) + ->filter(static fn (SQLSrvView $view) => $view->getDefinition() !== ''); + } + + /** + * @inheritDoc + */ + public function getProcedures(): Collection + { + return $this->sqlSrvRepository->getProcedures() + ->map(static fn (ProcedureDefinition $procedureDefinition) => new PgSQLProcedure($procedureDefinition->getName(), $procedureDefinition->getDefinition())); + } + + /** + * @inheritDoc + */ + public function getForeignKeys(string $table): Collection + { + return $this->getSchemaForeignKeys($table) + ->map(static fn (array $foreignKey) => new SQLSrvForeignKey($table, $foreignKey)); + } + + /** + * Get user defined types from the database. + * + * @return \Illuminate\Support\Collection + */ + private function getUserDefinedTypes(): Collection + { + if (!$this->ranGetUserDefinedTypes) { + $this->userDefinedTypes = $this->sqlSrvRepository->getCustomDataTypes(); + $this->ranGetUserDefinedTypes = true; + } + + return $this->userDefinedTypes; + } +} diff --git a/src/Database/SQLiteSchema.php b/src/Database/SQLiteSchema.php new file mode 100644 index 00000000..938ff3dc --- /dev/null +++ b/src/Database/SQLiteSchema.php @@ -0,0 +1,62 @@ +getSchemaTable($name), + $this->getSchemaColumns($name), + $this->getSchemaIndexes($name), + new Collection(), + ); + } + + /** + * @inheritDoc + */ + public function getViewNames(): Collection + { + return $this->getViews()->map(static fn (View $view) => $view->getName()); + } + + /** + * @inheritDoc + */ + public function getViews(): Collection + { + return $this->getSchemaViews() + ->map(static fn (array $view) => new SQLiteView($view)); + } + + /** + * @inheritDoc + */ + public function getProcedures(): Collection + { + // Stored procedure does not available. + // https://sqlite.org/forum/info/78a60bdeec7c1ee9 + return new Collection(); + } + + /** + * @inheritDoc + */ + public function getForeignKeys(string $table): Collection + { + return $this->getSchemaForeignKeys($table) + ->map(static fn (array $foreignKey) => new SQLiteForeignKey($table, $foreignKey)); + } +} diff --git a/src/Enum/Migrations/Method/ColumnType.php b/src/Enum/Migrations/Method/ColumnType.php index 59f16bfd..f291e584 100644 --- a/src/Enum/Migrations/Method/ColumnType.php +++ b/src/Enum/Migrations/Method/ColumnType.php @@ -6,9 +6,6 @@ /** * Define column types of the framework. - * Keep const as public to allow used by: - * {@see \KitLoong\MigrationsGenerator\DBAL\RegisterColumnType::registerLaravelColumnType()} - * {@see \KitLoong\MigrationsGenerator\DBAL\Types\Types} * * @link https://laravel.com/docs/master/migrations#available-column-types * @method static self BIG_INTEGER() diff --git a/src/MigrateGenerateCommand.php b/src/MigrateGenerateCommand.php index ef1cddc1..b158e983 100644 --- a/src/MigrateGenerateCommand.php +++ b/src/MigrateGenerateCommand.php @@ -567,7 +567,7 @@ protected function generateProceduresToTemp(): void protected function generateForeignKeys(Collection $tables): void { $tables->each(function (string $table): void { - $foreignKeys = $this->schema->getTableForeignKeys($table); + $foreignKeys = $this->schema->getForeignKeys($table); if (!$foreignKeys->isNotEmpty()) { return; @@ -596,7 +596,7 @@ protected function generateForeignKeys(Collection $tables): void protected function generateForeignKeysToTemp(Collection $tables): void { $tables->each(function (string $table): void { - $foreignKeys = $this->schema->getTableForeignKeys($table); + $foreignKeys = $this->schema->getForeignKeys($table); if (!$foreignKeys->isNotEmpty()) { return; diff --git a/src/Migration/Blueprint/Method.php b/src/Migration/Blueprint/Method.php index 727105e0..cbf71022 100644 --- a/src/Migration/Blueprint/Method.php +++ b/src/Migration/Blueprint/Method.php @@ -4,10 +4,14 @@ class Method { - /** @var mixed[] */ + /** + * @var mixed[] + */ private array $values; - /** @var \KitLoong\MigrationsGenerator\Migration\Blueprint\Method[] */ + /** + * @var \KitLoong\MigrationsGenerator\Migration\Blueprint\Method[] + */ private array $chains; /** diff --git a/src/Migration/Blueprint/TableBlueprint.php b/src/Migration/Blueprint/TableBlueprint.php index 6352bbc5..d8be85da 100644 --- a/src/Migration/Blueprint/TableBlueprint.php +++ b/src/Migration/Blueprint/TableBlueprint.php @@ -33,7 +33,9 @@ class TableBlueprint implements WritableBlueprint use MergeTimestamps; use Stringable; - /** @var \KitLoong\MigrationsGenerator\Migration\Blueprint\Property[]|\KitLoong\MigrationsGenerator\Migration\Blueprint\Method[]|string[] */ + /** + * @var \KitLoong\MigrationsGenerator\Migration\Blueprint\Property[]|\KitLoong\MigrationsGenerator\Migration\Blueprint\Method[]|string[] + */ private array $lines; /** diff --git a/src/Migration/ForeignKeyMigration.php b/src/Migration/ForeignKeyMigration.php index a892d8df..ec280a54 100644 --- a/src/Migration/ForeignKeyMigration.php +++ b/src/Migration/ForeignKeyMigration.php @@ -30,7 +30,7 @@ public function __construct( /** * Create foreign key migration. * - * @param \Illuminate\Support\Collection $foreignKeys + * @param \Illuminate\Support\Collection $foreignKeys * @return string The migration file path. */ public function write(string $table, Collection $foreignKeys): string @@ -53,7 +53,7 @@ public function write(string $table, Collection $foreignKeys): string /** * Write foreign key migration into temporary file. * - * @param \Illuminate\Support\Collection $foreignKeys + * @param \Illuminate\Support\Collection $foreignKeys */ public function writeToTemp(string $table, Collection $foreignKeys): void { @@ -66,7 +66,7 @@ public function writeToTemp(string $table, Collection $foreignKeys): void /** * Generates `up` schema for foreign key. * - * @param \Illuminate\Support\Collection $foreignKeys + * @param \Illuminate\Support\Collection $foreignKeys */ private function up(string $table, Collection $foreignKeys): SchemaBlueprint { @@ -86,7 +86,7 @@ private function up(string $table, Collection $foreignKeys): SchemaBlueprint /** * Generates `down` schema for foreign key. * - * @param \Illuminate\Support\Collection $foreignKeys + * @param \Illuminate\Support\Collection $foreignKeys */ private function down(string $table, Collection $foreignKeys): SchemaBlueprint { diff --git a/src/Migration/Generator/Columns/DecimalColumn.php b/src/Migration/Generator/Columns/DecimalColumn.php index 8acf1880..f13500de 100644 --- a/src/Migration/Generator/Columns/DecimalColumn.php +++ b/src/Migration/Generator/Columns/DecimalColumn.php @@ -37,6 +37,10 @@ public function generate(Table $table, Column $column): Method */ private function getDecimalPrecisions(?int $precision, int $scale): array { + if ($precision === null) { + return []; + } + if ($precision === self::DEFAULT_PRECISION && $scale === self::DEFAULT_SCALE) { return []; } diff --git a/src/Migration/Generator/Columns/FloatColumn.php b/src/Migration/Generator/Columns/FloatColumn.php index 92d941c6..6d2b1d18 100644 --- a/src/Migration/Generator/Columns/FloatColumn.php +++ b/src/Migration/Generator/Columns/FloatColumn.php @@ -16,6 +16,8 @@ class FloatColumn implements ColumnTypeGenerator private const DEFAULT_PRECISION = 8; private const DEFAULT_SCALE = 2; + private const DEFAULT_PRECISION_V11 = 53; + /** * @inheritDoc */ @@ -41,7 +43,7 @@ public function generate(Table $table, Column $column): Method private function getPrecisions(Column $column): array { if ($this->atLeastLaravel11()) { - if ($column->getPrecision() === null) { + if ($column->getPrecision() === null || $column->getPrecision() === self::DEFAULT_PRECISION_V11) { return []; } diff --git a/src/Migration/Generator/ForeignKeyGenerator.php b/src/Migration/Generator/ForeignKeyGenerator.php index fe01dc0b..c1c2cc44 100644 --- a/src/Migration/Generator/ForeignKeyGenerator.php +++ b/src/Migration/Generator/ForeignKeyGenerator.php @@ -45,6 +45,18 @@ public function generateDrop(ForeignKey $foreignKey): Method return new Method(Foreign::DROP_FOREIGN(), $foreignKey->getName()); } + /** + * Create a new Method with foreignKey and columns. + */ + public function makeMethod(ForeignKey $foreignKey): Method + { + if ($this->shouldSkipName($foreignKey)) { + return new Method(Foreign::FOREIGN(), $foreignKey->getLocalColumns()); + } + + return new Method(Foreign::FOREIGN(), $foreignKey->getLocalColumns(), $foreignKey->getName()); + } + /** * Checks should skip current foreign key name from DB. */ @@ -67,13 +79,4 @@ private function makeLaravelForeignKeyName(ForeignKey $foreignKey): string ); return str_replace(['-', '.'], '_', $name); } - - public function makeMethod(ForeignKey $foreignKey): Method - { - if ($this->shouldSkipName($foreignKey)) { - return new Method(Foreign::FOREIGN(), $foreignKey->getLocalColumns()); - } - - return new Method(Foreign::FOREIGN(), $foreignKey->getLocalColumns(), $foreignKey->getName()); - } } diff --git a/src/Migration/Generator/Modifiers/DefaultModifier.php b/src/Migration/Generator/Modifiers/DefaultModifier.php index cb6135b9..a1e43d3f 100644 --- a/src/Migration/Generator/Modifiers/DefaultModifier.php +++ b/src/Migration/Generator/Modifiers/DefaultModifier.php @@ -103,7 +103,12 @@ protected function chainDefaultForDecimal(Method $method, Column $column): Metho */ protected function chainDefaultForBoolean(Method $method, Column $column): Method { - $method->chain(ColumnModifier::DEFAULT(), (int) $column->getDefault() === 1); + $default = match ($column->getDefault()) { + 'true', '1' => true, + default => false, + }; + + $method->chain(ColumnModifier::DEFAULT(), $default); return $method; } @@ -113,7 +118,6 @@ protected function chainDefaultForBoolean(Method $method, Column $column): Metho protected function chainDefaultForDatetime(Method $method, Column $column): Method { switch ($column->getDefault()) { - case 'now()': case 'CURRENT_TIMESTAMP': $method->chain(ColumnModifier::USE_CURRENT()); break; diff --git a/src/MigrationsGeneratorServiceProvider.php b/src/MigrationsGeneratorServiceProvider.php index 63892002..37eb5dca 100644 --- a/src/MigrationsGeneratorServiceProvider.php +++ b/src/MigrationsGeneratorServiceProvider.php @@ -4,11 +4,10 @@ use Illuminate\Database\Migrations\MigrationRepositoryInterface; use Illuminate\Support\ServiceProvider; -use KitLoong\MigrationsGenerator\DBAL\Connection; -use KitLoong\MigrationsGenerator\DBAL\MySQLSchema as DBALMySQLSchema; -use KitLoong\MigrationsGenerator\DBAL\PgSQLSchema as DBALPgSQLSchema; -use KitLoong\MigrationsGenerator\DBAL\SQLiteSchema as DBALSQLiteSchema; -use KitLoong\MigrationsGenerator\DBAL\SQLSrvSchema as DBALSQLSrvSchema; +use KitLoong\MigrationsGenerator\Database\MySQLSchema as DBALMySQLSchema; +use KitLoong\MigrationsGenerator\Database\PgSQLSchema as DBALPgSQLSchema; +use KitLoong\MigrationsGenerator\Database\SQLiteSchema as DBALSQLiteSchema; +use KitLoong\MigrationsGenerator\Database\SQLSrvSchema as DBALSQLSrvSchema; use KitLoong\MigrationsGenerator\Enum\Migrations\Method\ColumnType; use KitLoong\MigrationsGenerator\Migration\Generator\Columns\BooleanColumn; use KitLoong\MigrationsGenerator\Migration\Generator\Columns\DatetimeColumn; @@ -52,7 +51,6 @@ public function register(): void SQLiteRepository::class => SQLiteRepository::class, SQLSrvRepository::class => SQLSrvRepository::class, MariaDBRepository::class => MariaDBRepository::class, - Connection::class => Connection::class, ] as $abstract => $concrete ) { $this->app->singleton($abstract, $concrete); diff --git a/src/Repositories/MySQLRepository.php b/src/Repositories/MySQLRepository.php index 29a17512..c4f4ce54 100644 --- a/src/Repositories/MySQLRepository.php +++ b/src/Repositories/MySQLRepository.php @@ -23,54 +23,6 @@ public function showColumn(string $table, string $column): ?ShowColumn return $result === null ? null : new ShowColumn($result); } - /** - * Get enum values. - * - * @param string $table Table name. - * @param string $column Column name. - * @return \Illuminate\Support\Collection - */ - public function getEnumPresetValues(string $table, string $column): Collection - { - $result = DB::selectOne("SHOW COLUMNS FROM `$table` WHERE Field = '$column' AND Type LIKE 'enum(%'"); - - if ($result === null) { - return new Collection(); - } - - $showColumn = new ShowColumn($result); - $value = substr( - str_replace('enum(\'', '', $showColumn->getType()), - 0, - -2, - ); - return new Collection(explode("','", $value)); - } - - /** - * Get set values. - * - * @param string $table Table name. - * @param string $column Column name. - * @return \Illuminate\Support\Collection - */ - public function getSetPresetValues(string $table, string $column): Collection - { - $result = DB::selectOne("SHOW COLUMNS FROM `$table` WHERE Field = '$column' AND Type LIKE 'set(%'"); - - if ($result === null) { - return new Collection(); - } - - $showColumn = new ShowColumn($result); - $value = substr( - str_replace('set(\'', '', $showColumn->getType()), - 0, - -2, - ); - return new Collection(explode("','", $value)); - } - /** * Checks if column has `on update CURRENT_TIMESTAMP` * @@ -137,6 +89,41 @@ public function getProcedures(): Collection return $list; } + /** + * Get the SRID by table and column name. + */ + public function getSrID(string $table, string $column): ?int + { + try { + $srsID = DB::selectOne( + "SELECT SRS_ID + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = '" . DB::getDatabaseName() . "' + AND TABLE_NAME = '" . $table . "' + AND COLUMN_NAME = '" . $column . "'", + ); + } catch (QueryException $exception) { + if ( + Str::contains( + $exception->getMessage(), + "SQLSTATE[42S22]: Column not found: 1054 Unknown column 'SRS_ID'", + true, + ) + ) { + return null; + } + + throw $exception; + } + + if ($srsID === null) { + return null; + } + + $srsIDArr = array_change_key_case((array) $srsID); + return $srsIDArr['srs_id'] ?? null; + } + /** * Get single stored procedure by name. * @@ -187,39 +174,4 @@ private function getGenerationExpression(string $table, string $column, string $ $definitionArr = array_change_key_case((array) $definition); return $definitionArr['generation_expression'] !== '' ? $definitionArr['generation_expression'] : null; } - - /** - * Get the SRID by table and column name. - */ - public function getSrID(string $table, string $column): ?int - { - try { - $srsID = DB::selectOne( - "SELECT SRS_ID - FROM information_schema.COLUMNS - WHERE TABLE_SCHEMA = '" . DB::getDatabaseName() . "' - AND TABLE_NAME = '" . $table . "' - AND COLUMN_NAME = '" . $column . "'", - ); - } catch (QueryException $exception) { - if ( - Str::contains( - $exception->getMessage(), - "SQLSTATE[42S22]: Column not found: 1054 Unknown column 'SRS_ID'", - true, - ) - ) { - return null; - } - - throw $exception; - } - - if ($srsID === null) { - return null; - } - - $srsIDArr = array_change_key_case((array) $srsID); - return $srsIDArr['srs_id'] ?? null; - } } diff --git a/src/Repositories/PgSQLRepository.php b/src/Repositories/PgSQLRepository.php index 7e0bf49d..d456d11b 100644 --- a/src/Repositories/PgSQLRepository.php +++ b/src/Repositories/PgSQLRepository.php @@ -160,35 +160,6 @@ public function getFulltextIndexes(string $table): Collection return $definitions; } - /** - * Get a list of custom data types. - * - * @source https://stackoverflow.com/questions/3660787/how-to-list-custom-types-using-postgres-information-schema - * @return \Illuminate\Support\Collection - */ - public function getCustomDataTypes(): Collection - { - $searchPath = DB::connection()->getConfig('search_path') ?: DB::connection()->getConfig('schema'); - - $rows = DB::select( - "SELECT n.nspname AS schema, t.typname AS type - FROM pg_type t - LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace - WHERE (t.typrelid = 0 OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)) - AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid) - AND n.nspname IN ('$searchPath');", - ); - $types = new Collection(); - - if (count($rows) > 0) { - foreach ($rows as $row) { - $types->push($row->type); - } - } - - return $types; - } - /** * Get a list of stored procedures. * diff --git a/src/Repositories/Repository.php b/src/Repositories/Repository.php index 1111efc5..426d6b2d 100644 --- a/src/Repositories/Repository.php +++ b/src/Repositories/Repository.php @@ -12,7 +12,6 @@ abstract class Repository * * @param string $str The literal string to be quoted. * @return string The quoted literal string. - * @see https://github.com/doctrine/dbal/blob/3.1.x/src/Platforms/AbstractPlatform.php#L3560 */ protected function quoteStringLiteral(string $str): string { @@ -23,8 +22,6 @@ protected function quoteStringLiteral(string $str): string /** * Gets the character used for string literal quoting. - * - * @see https://github.com/doctrine/dbal/blob/3.1.x/src/Platforms/AbstractPlatform.php#L3572 */ protected function getStringLiteralQuoteCharacter(): string { diff --git a/src/Repositories/SQLSrvRepository.php b/src/Repositories/SQLSrvRepository.php index 1b4a7ea2..df343f36 100644 --- a/src/Repositories/SQLSrvRepository.php +++ b/src/Repositories/SQLSrvRepository.php @@ -111,28 +111,6 @@ public function getView(string $name): ?ViewDefinition return $view === null ? null : new ViewDefinition($view->name, $view->definition); } - /** - * Returns the where clause to filter schema and table name in a query. - * - * @param string $table The full qualified name of the table. - * @param string $schemaColumn The name of the column to compare the schema to in the where clause. - * @param string $tableColumn The name of the column to compare the table to in the where clause. - * @see https://github.com/doctrine/dbal/blob/3.1.x/src/Platforms/SQLServer2012Platform.php#L1064 - */ - private function getTableWhereClause(string $table, string $schemaColumn, string $tableColumn): string - { - $schema = 'SCHEMA_NAME()'; - - if (strpos($table, '.') !== false) { - [$schema, $table] = explode('.', $table); - $schema = $this->quoteStringLiteral($schema); - } - - $table = $this->quoteStringLiteral($table); - - return sprintf('(%s = %s AND %s = %s)', $tableColumn, $table, $schemaColumn, $schema); - } - /** * Get a list of stored procedures. * @@ -210,4 +188,25 @@ public function getCustomDataTypes(): Collection return $types; } + + /** + * Returns the where clause to filter schema and table name in a query. + * + * @param string $table The full qualified name of the table. + * @param string $schemaColumn The name of the column to compare the schema to in the where clause. + * @param string $tableColumn The name of the column to compare the table to in the where clause. + */ + private function getTableWhereClause(string $table, string $schemaColumn, string $tableColumn): string + { + $schema = 'SCHEMA_NAME()'; + + if (strpos($table, '.') !== false) { + [$schema, $table] = explode('.', $table); + $schema = $this->quoteStringLiteral($schema); + } + + $table = $this->quoteStringLiteral($table); + + return sprintf('(%s = %s AND %s = %s)', $tableColumn, $table, $schemaColumn, $schema); + } } diff --git a/src/Schema/Models/Column.php b/src/Schema/Models/Column.php index f37fc09e..7139a3a1 100644 --- a/src/Schema/Models/Column.php +++ b/src/Schema/Models/Column.php @@ -40,11 +40,6 @@ public function getScale(): int; */ public function isUnsigned(): bool; - /** - * Check if the column is fixed. - */ - public function isFixed(): bool; - /** * Check if the column is not null. */ diff --git a/src/Schema/Models/Index.php b/src/Schema/Models/Index.php index 3a21f2eb..2c7ace36 100644 --- a/src/Schema/Models/Index.php +++ b/src/Schema/Models/Index.php @@ -24,13 +24,6 @@ public function getTableName(): string; */ public function getColumns(): array; - /** - * Get the index column lengths, always same size with {@see self::getColumns()}. - * - * @return array - */ - public function getLengths(): array; - /** * Get the index type. */ diff --git a/src/Schema/Schema.php b/src/Schema/Schema.php index 2fb79500..a4edaccc 100644 --- a/src/Schema/Schema.php +++ b/src/Schema/Schema.php @@ -38,9 +38,9 @@ public function getViews(): Collection; /** * Get a list of foreign keys. * - * @return \Illuminate\Support\Collection + * @return \Illuminate\Support\Collection */ - public function getTableForeignKeys(string $table): Collection; + public function getForeignKeys(string $table): Collection; /** * Get a list of store procedures. diff --git a/src/Support/AssetNameQuote.php b/src/Support/AssetNameQuote.php index cf11f8bc..0e1ad87b 100644 --- a/src/Support/AssetNameQuote.php +++ b/src/Support/AssetNameQuote.php @@ -2,12 +2,13 @@ namespace KitLoong\MigrationsGenerator\Support; +use Illuminate\Support\Facades\DB; +use KitLoong\MigrationsGenerator\Enum\Driver; + trait AssetNameQuote { /** * Checks if this identifier is quoted. - * - * @see \Doctrine\DBAL\Schema\AbstractAsset::isIdentifierQuoted() */ public function isIdentifierQuoted(string $identifier): bool { @@ -16,11 +17,30 @@ public function isIdentifierQuoted(string $identifier): bool /** * Trim quotes from the identifier. - * - * @see \Doctrine\DBAL\Schema\AbstractAsset::trimQuotes() */ public function trimQuotes(string $identifier): string { return str_replace(['`', '"', '[', ']'], '', $identifier); } + + /** + * Wrap a single string in keyword identifiers. + */ + public function quoteIdentifier(string $value): string + { + switch (DB::getDriverName()) { + case Driver::SQLSRV(): + return $value === '*' ? $value : '[' . str_replace(']', ']]', $value) . ']'; + + case Driver::MYSQL(): + return $value === '*' ? $value : '`' . str_replace('`', '``', $value) . '`'; + + default: + if ($value !== '*') { + return '"' . str_replace('"', '""', $value) . '"'; + } + + return $value; + } + } } diff --git a/tests/Feature/FeatureTestCase.php b/tests/Feature/FeatureTestCase.php index d9cd0b99..566515e2 100644 --- a/tests/Feature/FeatureTestCase.php +++ b/tests/Feature/FeatureTestCase.php @@ -2,13 +2,12 @@ namespace KitLoong\MigrationsGenerator\Tests\Feature; -use Doctrine\DBAL\Schema\View; use Dotenv\Dotenv; use Dotenv\Exception\InvalidPathException; use Illuminate\Database\Migrations\MigrationRepositoryInterface; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\File; -use KitLoong\MigrationsGenerator\DBAL\Connection; +use Illuminate\Support\Facades\Schema; use KitLoong\MigrationsGenerator\Support\AssetNameQuote; use KitLoong\MigrationsGenerator\Tests\TestCase; @@ -16,6 +15,8 @@ abstract class FeatureTestCase extends TestCase { use AssetNameQuote; + abstract protected function refreshDatabase(): void; + /** * @inheritDoc */ @@ -204,17 +205,7 @@ protected function truncateMigrationsTable(): void */ protected function getTableNames(): array { - return collect(app(Connection::class)->getDoctrineSchemaManager()->listTableNames()) - ->map(function ($table) { - // The table name may contain quotes. - // Always trim quotes before set into list. - if ($this->isIdentifierQuoted($table)) { - return $this->trimQuotes($table); - } - - return $table; - }) - ->toArray(); + return Schema::getTableListing(); } /** @@ -224,10 +215,6 @@ protected function getTableNames(): array */ protected function getViewNames(): array { - return collect(app(Connection::class)->getDoctrineSchemaManager()->listViews()) - ->map(static fn (View $view) => $view->getName()) - ->toArray(); + return array_column(Schema::getViews(), 'name'); } - - abstract protected function refreshDatabase(): void; } diff --git a/tests/Feature/MariaDB/TablePrefixTest.php b/tests/Feature/MariaDB/TablePrefixTest.php new file mode 100644 index 00000000..107a1e02 --- /dev/null +++ b/tests/Feature/MariaDB/TablePrefixTest.php @@ -0,0 +1,53 @@ +migrateGeneral(); + }; + + $generateMigrations = function (): void { + $this->generateMigrations(); + }; + + $this->verify($migrateTemplates, $generateMigrations); + } + + /** + * @inheritDoc + */ + protected function getEnvironmentSetUp($app): void + { + parent::getEnvironmentSetUp($app); + + $app['config']->set('database.connections.mariadb.prefix', 'prefix_'); + } + + private function verify(callable $migrateTemplates, callable $generateMigrations): void + { + $migrateTemplates(); + + $this->truncateMigrationsTable(); + $this->dumpSchemaAs($this->getStorageSqlPath('expected.sql')); + + $generateMigrations(); + + $this->assertMigrations(); + + $this->refreshDatabase(); + + $this->runMigrationsFrom($this->getStorageMigrationsPath()); + + $this->truncateMigrationsTable(); + $this->dumpSchemaAs($this->getStorageSqlPath('actual.sql')); + + $this->assertFileEqualsIgnoringOrder( + $this->getStorageSqlPath('expected.sql'), + $this->getStorageSqlPath('actual.sql'), + ); + } +} diff --git a/tests/Feature/MySQL57/CommandTest.php b/tests/Feature/MySQL57/CommandTest.php index 1e0719be..ccfed9ad 100644 --- a/tests/Feature/MySQL57/CommandTest.php +++ b/tests/Feature/MySQL57/CommandTest.php @@ -217,7 +217,7 @@ public function testDefaultFKNames(): void $this->runMigrationsFrom($this->getStorageMigrationsPath()); - $foreignKeys = app(MySQLSchema::class)->getTableForeignKeys('user_profile'); + $foreignKeys = app(MySQLSchema::class)->getForeignKeys('user_profile'); $foreignKeyNames = $foreignKeys->map(static fn (ForeignKey $foreignKey) => $foreignKey->getName()) ->sort() ->values() diff --git a/tests/Feature/MySQL57/DBConnectionTest.php b/tests/Feature/MySQL57/DBConnectionTest.php index dbce951b..d8b7a1bb 100644 --- a/tests/Feature/MySQL57/DBConnectionTest.php +++ b/tests/Feature/MySQL57/DBConnectionTest.php @@ -9,35 +9,6 @@ class DBConnectionTest extends MySQL57TestCase { - /** - * @inheritDoc - */ - protected function getEnvironmentSetUp($app): void - { - parent::getEnvironmentSetUp($app); - - $app['config']->set('database.default', 'mysql8'); - $app['config']->set('database.connections.mysql8', [ - 'driver' => 'mysql', - 'url' => null, - 'host' => env('MYSQL8_HOST'), - 'port' => env('MYSQL8_PORT'), - 'database' => env('MYSQL8_DATABASE'), - 'username' => env('MYSQL8_USERNAME'), - 'password' => env('MYSQL8_PASSWORD'), - 'unix_socket' => env('DB_SOCKET', ''), - 'charset' => 'utf8mb4', - 'collation' => 'utf8mb4_general_ci', - 'prefix' => '', - 'prefix_indexes' => true, - 'strict' => true, - 'engine' => null, - 'options' => extension_loaded('pdo_mysql') ? array_filter([ - PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), - ]) : [], - ]); - } - public function tearDown(): void { // Clean "migrations" table after test. @@ -100,6 +71,35 @@ public function testLogMigrationToAnotherSource(): void $this->assertSame($totalMigrations, DB::connection('mysql8')->table('migrations')->count()); } + /** + * @inheritDoc + */ + protected function getEnvironmentSetUp($app): void + { + parent::getEnvironmentSetUp($app); + + $app['config']->set('database.default', 'mysql8'); + $app['config']->set('database.connections.mysql8', [ + 'driver' => 'mysql', + 'url' => null, + 'host' => env('MYSQL8_HOST'), + 'port' => env('MYSQL8_PORT'), + 'database' => env('MYSQL8_DATABASE'), + 'username' => env('MYSQL8_USERNAME'), + 'password' => env('MYSQL8_PASSWORD'), + 'unix_socket' => env('DB_SOCKET', ''), + 'charset' => 'utf8mb4', + 'collation' => 'utf8mb4_general_ci', + 'prefix' => '', + 'prefix_indexes' => true, + 'strict' => true, + 'engine' => null, + 'options' => extension_loaded('pdo_mysql') ? array_filter([ + PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), + ]) : [], + ]); + } + private function verify(callable $migrateTemplates, callable $generateMigrations): void { DB::setDefaultConnection('mysql57'); diff --git a/tests/Feature/MySQL57/StackedCommandTest.php b/tests/Feature/MySQL57/StackedCommandTest.php index 2176e37c..8530f8e4 100644 --- a/tests/Feature/MySQL57/StackedCommandTest.php +++ b/tests/Feature/MySQL57/StackedCommandTest.php @@ -11,6 +11,45 @@ class StackedCommandTest extends MySQL57TestCase { + public function testRunAsCall(): void + { + Schema::create('migration_table', static function (Blueprint $table): void { + $table->increments('id'); + }); + + Schema::connection('migration2')->create('migration2_table', static function (Blueprint $table): void { + $table->increments('id'); + }); + + $this->assertTrue(Schema::hasTable('migration_table')); + $this->assertTrue(Schema::connection('migration2')->hasTable('migration2_table')); + + $this->generateMigrations(); + + // Setting should reset. + $this->assertEquals(app(Setting::class), new Setting()); + + $this->generateMigrations(['--connection' => 'migration2']); + + $files = File::files($this->getStorageMigrationsPath()); + $this->assertCount(2, $files); + + foreach ($files as $file) { + if (Str::contains($file->getBasename(), 'create_migration_table')) { + $this->assertStringContainsString( + 'migration_table', + $file->getContents(), + ); + continue; + } + + $this->assertStringContainsString( + 'migration2_table', + $file->getContents(), + ); + } + } + /** * @inheritDoc */ @@ -52,43 +91,4 @@ protected function tearDown(): void parent::tearDown(); } - - public function testRunAsCall(): void - { - Schema::create('migration_table', static function (Blueprint $table): void { - $table->increments('id'); - }); - - Schema::connection('migration2')->create('migration2_table', static function (Blueprint $table): void { - $table->increments('id'); - }); - - $this->assertTrue(Schema::hasTable('migration_table')); - $this->assertTrue(Schema::connection('migration2')->hasTable('migration2_table')); - - $this->generateMigrations(); - - // Setting should reset. - $this->assertEquals(app(Setting::class), new Setting()); - - $this->generateMigrations(['--connection' => 'migration2']); - - $files = File::files($this->getStorageMigrationsPath()); - $this->assertCount(2, $files); - - foreach ($files as $file) { - if (Str::contains($file->getBasename(), 'create_migration_table')) { - $this->assertStringContainsString( - 'migration_table', - $file->getContents(), - ); - continue; - } - - $this->assertStringContainsString( - 'migration2_table', - $file->getContents(), - ); - } - } } diff --git a/tests/Feature/MySQL57/TablePrefixTest.php b/tests/Feature/MySQL57/TablePrefixTest.php index 2954cd3f..a72a8d66 100644 --- a/tests/Feature/MySQL57/TablePrefixTest.php +++ b/tests/Feature/MySQL57/TablePrefixTest.php @@ -4,16 +4,6 @@ class TablePrefixTest extends MySQL57TestCase { - /** - * @inheritDoc - */ - protected function getEnvironmentSetUp($app): void - { - parent::getEnvironmentSetUp($app); - - $app['config']->set('database.connections.mysql57.prefix', 'kit_'); - } - public function testTablePrefix(): void { $migrateTemplates = function (): void { @@ -27,6 +17,16 @@ public function testTablePrefix(): void $this->verify($migrateTemplates, $generateMigrations); } + /** + * @inheritDoc + */ + protected function getEnvironmentSetUp($app): void + { + parent::getEnvironmentSetUp($app); + + $app['config']->set('database.connections.mysql57.prefix', 'prefix_'); + } + private function verify(callable $migrateTemplates, callable $generateMigrations): void { $migrateTemplates(); diff --git a/tests/Feature/MySQL8/TablePrefixTest.php b/tests/Feature/MySQL8/TablePrefixTest.php new file mode 100644 index 00000000..2b13639b --- /dev/null +++ b/tests/Feature/MySQL8/TablePrefixTest.php @@ -0,0 +1,53 @@ +migrateGeneral(); + }; + + $generateMigrations = function (): void { + $this->generateMigrations(); + }; + + $this->verify($migrateTemplates, $generateMigrations); + } + + /** + * @inheritDoc + */ + protected function getEnvironmentSetUp($app): void + { + parent::getEnvironmentSetUp($app); + + $app['config']->set('database.connections.mysql8.prefix', 'prefix_'); + } + + private function verify(callable $migrateTemplates, callable $generateMigrations): void + { + $migrateTemplates(); + + $this->truncateMigrationsTable(); + $this->dumpSchemaAs($this->getStorageSqlPath('expected.sql')); + + $generateMigrations(); + + $this->assertMigrations(); + + $this->refreshDatabase(); + + $this->runMigrationsFrom($this->getStorageMigrationsPath()); + + $this->truncateMigrationsTable(); + $this->dumpSchemaAs($this->getStorageSqlPath('actual.sql')); + + $this->assertFileEqualsIgnoringOrder( + $this->getStorageSqlPath('expected.sql'), + $this->getStorageSqlPath('actual.sql'), + ); + } +} diff --git a/tests/Feature/PgSQL/CommandTest.php b/tests/Feature/PgSQL/CommandTest.php index ccbcb272..78c2ad4c 100644 --- a/tests/Feature/PgSQL/CommandTest.php +++ b/tests/Feature/PgSQL/CommandTest.php @@ -4,8 +4,6 @@ use Illuminate\Support\Collection; use Illuminate\Support\Facades\Config; -use Illuminate\Support\Facades\DB; -use Illuminate\Support\Facades\File; use KitLoong\MigrationsGenerator\Support\CheckLaravelVersion; class CommandTest extends PgSQLTestCase @@ -16,48 +14,19 @@ public function testRun(): void { $migrateTemplates = function (): void { $this->migrateGeneral(); - - // Test timestamp default now() - DB::statement( - "ALTER TABLE all_columns ADD COLUMN timestamp_defaultnow timestamp(0) without time zone DEFAULT now() NOT NULL", - ); - - DB::statement( - "ALTER TABLE all_columns ADD COLUMN status my_status NOT NULL", - ); - - DB::statement( - "ALTER TABLE all_columns ADD COLUMN timestamp_default_timezone_now timestamp(0) without time zone DEFAULT timezone('Europe/Rome'::text, now()) NOT NULL", - ); }; $generateMigrations = function (): void { $this->generateMigrations(); }; - $beforeVerify = function (): void { - $this->assertLineExistsThenReplace( - $this->getStorageSqlPath('actual.sql'), - 'timestamp_defaultnow timestamp(0) without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL', - ); - - $this->assertLineExistsThenReplace( - $this->getStorageSqlPath('expected.sql'), - 'timestamp_defaultnow timestamp(0) without time zone DEFAULT now() NOT NULL', - ); - }; - - $this->verify($migrateTemplates, $generateMigrations, $beforeVerify); + $this->verify($migrateTemplates, $generateMigrations); } public function testSquashUp(): void { $migrateTemplates = function (): void { $this->migrateGeneral(); - - DB::statement( - "ALTER TABLE all_columns ADD COLUMN status my_status NOT NULL", - ); }; $generateMigrations = function (): void { @@ -109,7 +78,7 @@ public function testIgnore(): void * * @see https://laravel.com/docs/9.x/upgrade#postgres-schema-configuration */ - public function testRunWithSearchPath(): void + public function testWithSearchPath(): void { if (!$this->atLeastLaravel9()) { $this->markTestSkipped(); @@ -137,10 +106,6 @@ public function testWithHasTable(): void { $migrateTemplates = function (): void { $this->migrateGeneral(); - - DB::statement( - "ALTER TABLE all_columns ADD COLUMN status my_status NOT NULL", - ); }; $generateMigrations = function (): void { @@ -154,10 +119,6 @@ public function testWithHasTableSquash(): void { $migrateTemplates = function (): void { $this->migrateGeneral(); - - DB::statement( - "ALTER TABLE all_columns ADD COLUMN status my_status NOT NULL", - ); }; $generateMigrations = function (): void { @@ -210,7 +171,7 @@ public function testSkipVendor(): void $this->assertSame($tablesWithoutVendors, $generatedTables); } - private function verify(callable $migrateTemplates, callable $generateMigrations, ?callable $beforeVerify = null): void + private function verify(callable $migrateTemplates, callable $generateMigrations): void { $migrateTemplates(); @@ -228,30 +189,9 @@ private function verify(callable $migrateTemplates, callable $generateMigrations $this->truncateMigrationsTable(); $this->dumpSchemaAs($this->getStorageSqlPath('actual.sql')); - $beforeVerify === null ?: $beforeVerify(); - $this->assertFileEqualsIgnoringOrder( $this->getStorageSqlPath('expected.sql'), $this->getStorageSqlPath('actual.sql'), ); } - - private function assertLineExistsThenReplace(string $file, string $line): void - { - $this->assertTrue( - str_contains( - File::get($file), - $line, - ), - ); - - File::put( - $file, - str_replace( - $line, - 'replaced', - File::get($file), - ), - ); - } } diff --git a/tests/Feature/PgSQL/PgSQLTestCase.php b/tests/Feature/PgSQL/PgSQLTestCase.php index 8e21a9c7..380005fa 100644 --- a/tests/Feature/PgSQL/PgSQLTestCase.php +++ b/tests/Feature/PgSQL/PgSQLTestCase.php @@ -2,9 +2,9 @@ namespace KitLoong\MigrationsGenerator\Tests\Feature\PgSQL; +use Illuminate\Support\Collection; use Illuminate\Support\Facades\DB; -use Illuminate\Support\Str; -use KitLoong\MigrationsGenerator\DBAL\Connection; +use Illuminate\Support\Facades\Schema; use KitLoong\MigrationsGenerator\Tests\Feature\FeatureTestCase; abstract class PgSQLTestCase extends FeatureTestCase @@ -70,21 +70,23 @@ protected function refreshDatabase(): void protected function dropAllTablesAndViews(): void { - $tables = app(Connection::class)->getDoctrineSchemaManager()->listTableNames(); - - foreach ($tables as $table) { - if (Str::startsWith($table, 'tiger.')) { - continue; - } - - if (Str::startsWith($table, 'topology.')) { - continue; - } - - // CASCADE, automatically drop objects that depend on the table. - // This statement will drop views which depend on the table. - DB::statement("DROP TABLE IF EXISTS $table cascade"); - } + (new Collection(Schema::getTables())) + ->each(static function (array $table): void { + if ($table['name'] === 'spatial_ref_sys') { + return; + } + + // Schema name defined in the framework configuration. + $searchPath = DB::connection()->getConfig('search_path') ?: DB::connection()->getConfig('schema'); + + if ($table['schema'] !== $searchPath) { + return; + } + + // CASCADE, automatically drop objects that depend on the table. + // This statement will drop views which depend on the table. + DB::statement("DROP TABLE IF EXISTS \"" . $table['name'] . "\" cascade"); + }); } protected function dropAllProcedures(): void diff --git a/tests/Feature/PgSQL/TablePrefixTest.php b/tests/Feature/PgSQL/TablePrefixTest.php index 0d1c317e..83f529aa 100644 --- a/tests/Feature/PgSQL/TablePrefixTest.php +++ b/tests/Feature/PgSQL/TablePrefixTest.php @@ -2,28 +2,12 @@ namespace KitLoong\MigrationsGenerator\Tests\Feature\PgSQL; -use Illuminate\Support\Facades\DB; - class TablePrefixTest extends PgSQLTestCase { - /** - * @inheritDoc - */ - protected function getEnvironmentSetUp($app): void - { - parent::getEnvironmentSetUp($app); - - $app['config']->set('database.connections.pgsql.prefix', 'kit_'); - } - public function testTablePrefix(): void { $migrateTemplates = function (): void { $this->migrateGeneral(); - - DB::statement( - "ALTER TABLE kit_all_columns ADD COLUMN status my_status NOT NULL", - ); }; $generateMigrations = function (): void { @@ -33,6 +17,16 @@ public function testTablePrefix(): void $this->verify($migrateTemplates, $generateMigrations); } + /** + * @inheritDoc + */ + protected function getEnvironmentSetUp($app): void + { + parent::getEnvironmentSetUp($app); + + $app['config']->set('database.connections.pgsql.prefix', 'prefix_'); + } + private function verify(callable $migrateTemplates, callable $generateMigrations): void { $migrateTemplates(); diff --git a/tests/Feature/SQLSrv/CommandTest.php b/tests/Feature/SQLSrv/CommandTest.php index 4d7c76e0..6e850271 100644 --- a/tests/Feature/SQLSrv/CommandTest.php +++ b/tests/Feature/SQLSrv/CommandTest.php @@ -8,17 +8,10 @@ class CommandTest extends SQLSrvTestCase { - /** - * @throws \Doctrine\DBAL\Exception - */ public function testRun(): void { $migrateTemplates = function (): void { $this->migrateGeneral(); - - DB::statement( - "ALTER TABLE all_columns ADD accountnumber accountnumber NOT NULL", - ); }; $generateMigrations = function (): void { @@ -77,9 +70,6 @@ public function testDown(): void $this->assertSame(0, DB::table('migrations')->count()); } - /** - * @throws \Doctrine\DBAL\Exception - */ public function testCollation(): void { $migrateTemplates = function (): void { @@ -147,9 +137,6 @@ public function testSkipVendor(): void $this->assertSame($tablesWithoutVendors, $generatedTables); } - /** - * @throws \Doctrine\DBAL\Exception - */ private function verify(callable $migrateTemplates, callable $generateMigrations): void { $migrateTemplates(); diff --git a/tests/Feature/SQLSrv/SQLSrvTestCase.php b/tests/Feature/SQLSrv/SQLSrvTestCase.php index 3fe88856..4abdcb22 100644 --- a/tests/Feature/SQLSrv/SQLSrvTestCase.php +++ b/tests/Feature/SQLSrv/SQLSrvTestCase.php @@ -5,7 +5,6 @@ use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\File; use Illuminate\Support\Facades\Schema; -use KitLoong\MigrationsGenerator\DBAL\Connection; use KitLoong\MigrationsGenerator\Tests\Feature\FeatureTestCase; abstract class SQLSrvTestCase extends FeatureTestCase @@ -45,17 +44,17 @@ protected function setUp(): void protected function dumpSchemaAs(string $destination): void { - $tables = app(Connection::class)->getDoctrineSchemaManager()->listTableNames(); + $tables = Schema::getTableListing(); $sqls = []; foreach ($tables as $table) { $sqls[] = "EXEC sp_help '" . $table . "';"; } - $views = app(Connection::class)->getDoctrineSchemaManager()->listViews(); + $views = array_column(Schema::getViews(), 'name'); foreach ($views as $view) { - $sqls[] = "EXEC sp_helptext '" . $view->getName() . "';"; + $sqls[] = "EXEC sp_helptext '" . $view . "';"; } $procedures = $this->getAllProcedures(); diff --git a/tests/Feature/SQLSrv/TablePrefixTest.php b/tests/Feature/SQLSrv/TablePrefixTest.php new file mode 100644 index 00000000..1b8489fc --- /dev/null +++ b/tests/Feature/SQLSrv/TablePrefixTest.php @@ -0,0 +1,53 @@ +migrateGeneral(); + }; + + $generateMigrations = function (): void { + $this->generateMigrations(); + }; + + $this->verify($migrateTemplates, $generateMigrations); + } + + /** + * @inheritDoc + */ + protected function getEnvironmentSetUp($app): void + { + parent::getEnvironmentSetUp($app); + + $app['config']->set('database.connections.sqlsrv.prefix', 'prefix_'); + } + + private function verify(callable $migrateTemplates, callable $generateMigrations): void + { + $migrateTemplates(); + + $this->truncateMigrationsTable(); + $this->dumpSchemaAs($this->getStorageSqlPath('expected.sql')); + + $generateMigrations(); + + $this->assertMigrations(); + + $this->refreshDatabase(); + + $this->runMigrationsFrom($this->getStorageMigrationsPath()); + + $this->truncateMigrationsTable(); + $this->dumpSchemaAs($this->getStorageSqlPath('actual.sql')); + + $this->assertFileEqualsIgnoringOrder( + $this->getStorageSqlPath('expected.sql'), + $this->getStorageSqlPath('actual.sql'), + ); + } +} diff --git a/tests/Feature/SQLite/TablePrefixTest.php b/tests/Feature/SQLite/TablePrefixTest.php new file mode 100644 index 00000000..57230ba4 --- /dev/null +++ b/tests/Feature/SQLite/TablePrefixTest.php @@ -0,0 +1,58 @@ +migrateGeneral(); + }; + + $generateMigrations = function (): void { + $this->generateMigrations(); + }; + + $this->verify($migrateTemplates, $generateMigrations); + } + + /** + * @inheritDoc + */ + protected function getEnvironmentSetUp($app): void + { + parent::getEnvironmentSetUp($app); + + $app['config']->set('database.connections.sqlite.prefix', 'prefix_'); + } + + private function verify(callable $migrateTemplates, callable $generateMigrations): void + { + $migrateTemplates(); + + $this->truncateMigrationsTable(); + DB::statement("delete from sqlite_sequence where name = 'prefix_migrations'"); + + $this->dumpSchemaAs($this->getStorageSqlPath('expected.sql')); + $generateMigrations(); + + $this->assertMigrations(); + + $this->refreshDatabase(); + + $this->runMigrationsFrom($this->getStorageMigrationsPath()); + + $this->truncateMigrationsTable(); + DB::statement("delete from sqlite_sequence where name = 'prefix_migrations'"); + + $this->dumpSchemaAs($this->getStorageSqlPath('actual.sql')); + + $this->assertFileEqualsIgnoringOrder( + $this->getStorageSqlPath('expected.sql'), + $this->getStorageSqlPath('actual.sql'), + ); + } +} diff --git a/tests/TestCase.php b/tests/TestCase.php index 4f6c311e..cdb5697c 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -10,26 +10,6 @@ abstract class TestCase extends Testbench { - /** - * @inheritDoc - */ - protected function getPackageProviders($app) - { - return [ - MigrationsGeneratorServiceProvider::class, - ]; - } - - /** - * @inheritDoc - */ - protected function getEnvironmentSetUp($app): void - { - parent::getEnvironmentSetUp($app); - - app()->setBasePath(__DIR__ . '/../'); - } - /** * Asserts that the contents of one file is equal to the contents of another file, ignore the ordering. * Also, strip all end of line commas. @@ -55,4 +35,24 @@ public static function assertFileEqualsIgnoringOrder(string $expected, string $a static::assertThat($actualContent->values(), $constraint, $message); } + + /** + * @inheritDoc + */ + protected function getPackageProviders($app) + { + return [ + MigrationsGeneratorServiceProvider::class, + ]; + } + + /** + * @inheritDoc + */ + protected function getEnvironmentSetUp($app): void + { + parent::getEnvironmentSetUp($app); + + app()->setBasePath(__DIR__ . '/../'); + } } diff --git a/tests/TestMigration.php b/tests/TestMigration.php index 77663a33..eb23dede 100644 --- a/tests/TestMigration.php +++ b/tests/TestMigration.php @@ -3,12 +3,9 @@ namespace KitLoong\MigrationsGenerator\Tests; use Illuminate\Database\Migrations\Migration; -use KitLoong\MigrationsGenerator\DBAL\Connection; +use KitLoong\MigrationsGenerator\Support\AssetNameQuote; abstract class TestMigration extends Migration { - protected function quoteIdentifier(string $string): string - { - return app(Connection::class)->getDoctrineConnection()->quoteIdentifier($string); - } + use AssetNameQuote; } diff --git a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_table.php b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_table.php index 07bc9add..181c04f0 100644 --- a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_table.php +++ b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_table.php @@ -212,6 +212,33 @@ public function up() default: } }); + + switch (DB::getDriverName()) { + case Driver::PGSQL(): + // Test timestamp default now() + DB::statement( + "ALTER TABLE ".DB::getTablePrefix()."all_columns ADD COLUMN timestamp_defaultnow timestamp(0) without time zone DEFAULT now() NOT NULL", + ); + + DB::statement( + "ALTER TABLE ".DB::getTablePrefix()."all_columns ADD COLUMN status my_status NOT NULL DEFAULT 'PENDING'", + ); + + DB::statement( + "COMMENT ON column ".DB::getTablePrefix()."all_columns.status IS 'comment a'", + ); + + DB::statement( + "ALTER TABLE ".DB::getTablePrefix()."all_columns ADD COLUMN timestamp_default_timezone_now timestamp(0) without time zone DEFAULT timezone('Europe/Rome'::text, now()) NOT NULL", + ); + break; + + case Driver::SQLSRV(): + DB::statement( + "ALTER TABLE ".DB::getTablePrefix()."all_columns ADD accountnumber accountnumber NOT NULL DEFAULT '1008'", + ); + break; + } } /** From e49019d55b5817d1da8722c33c082ffe218d4b8d Mon Sep 17 00:00:00 2001 From: Kit Loong Date: Wed, 28 Feb 2024 01:10:14 +0800 Subject: [PATCH 11/20] Support minimum Laravel v10.43 --- .github/workflows/tests.yml | 2 +- composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2e7c9682..0f12a292 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -82,7 +82,7 @@ jobs: sqlsrv_extension: [ pdo_sqlsrv ] include: - php: 8.1 - laravel: 10.38 + laravel: 10.43.* - php: 8.1 laravel: 10.* diff --git a/composer.json b/composer.json index 67ead7ab..b1557229 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ ], "require": { "php": "^8.1", - "illuminate/support": "^10.38|^11.0", + "illuminate/support": "^10.43|^11.0", "myclabs/php-enum": "^1.8", "ext-pdo": "*" }, From 32763772cd121488acc2fce547f6aa70d265a41c Mon Sep 17 00:00:00 2001 From: Kit Loong Date: Wed, 28 Feb 2024 22:04:26 +0800 Subject: [PATCH 12/20] Use native enum --- composer.json | 1 - phpstan.neon | 1 - src/Database/DatabaseColumnType.php | 5 +- src/Database/Models/DatabaseColumn.php | 54 +++--- src/Database/Models/DatabaseIndex.php | 10 +- src/Database/Models/MySQL/MySQLColumn.php | 70 +++---- src/Database/Models/MySQL/MySQLColumnType.php | 2 +- src/Database/Models/MySQL/MySQLIndex.php | 2 +- src/Database/Models/PgSQL/PgSQLColumn.php | 42 ++-- src/Database/Models/PgSQL/PgSQLColumnType.php | 2 +- .../Models/PgSQL/PgSQLCustomColumn.php | 2 +- src/Database/Models/PgSQL/PgSQLIndex.php | 2 +- src/Database/Models/PgSQL/PgSQLParser.php | 2 +- src/Database/Models/PgSQL/PgSQLTable.php | 6 +- src/Database/Models/SQLSrv/SQLSrvColumn.php | 32 ++-- .../Models/SQLSrv/SQLSrvColumnType.php | 2 +- src/Database/Models/SQLSrv/SQLSrvIndex.php | 2 +- src/Database/Models/SQLite/SQLiteColumn.php | 12 +- .../Models/SQLite/SQLiteColumnType.php | 2 +- src/Database/Models/SQLite/SQLiteIndex.php | 2 +- src/Enum/Driver.php | 18 +- src/Enum/Migrations/ColumnName.php | 17 +- src/Enum/Migrations/Method/ColumnModifier.php | 44 ++--- src/Enum/Migrations/Method/ColumnType.php | 180 ++++++------------ src/Enum/Migrations/Method/DBBuilder.php | 9 + src/Enum/Migrations/Method/Foreign.php | 23 +-- src/Enum/Migrations/Method/IndexType.php | 23 +-- src/Enum/Migrations/Method/MethodName.php | 9 + src/Enum/Migrations/Method/SchemaBuilder.php | 20 +- src/Enum/Migrations/Method/TableMethod.php | 8 +- src/Enum/Migrations/Property/PropertyName.php | 9 + .../Migrations/Property/TableProperty.php | 14 +- src/MigrateGenerateCommand.php | 10 +- .../Blueprint/DBStatementBlueprint.php | 3 +- .../Blueprint/DBUnpreparedBlueprint.php | 3 +- src/Migration/Blueprint/Method.php | 16 +- src/Migration/Blueprint/Property.php | 6 +- src/Migration/Blueprint/SchemaBlueprint.php | 10 +- .../Blueprint/Support/MergeTimestamps.php | 24 +-- .../Blueprint/Support/MethodStringHelper.php | 7 +- .../Blueprint/Support/Stringable.php | 8 +- src/Migration/Blueprint/TableBlueprint.php | 25 ++- src/Migration/Blueprint/WritableBlueprint.php | 3 + src/Migration/Enum/MigrationFileType.php | 19 +- src/Migration/Enum/Space.php | 13 +- src/Migration/ForeignKeyMigration.php | 4 +- src/Migration/Generator/ColumnGenerator.php | 2 +- .../Generator/Columns/BooleanColumn.php | 2 +- .../Generator/Columns/DatetimeColumn.php | 2 +- .../Generator/Columns/DecimalColumn.php | 2 +- .../Generator/Columns/DoubleColumn.php | 2 +- .../Generator/Columns/FloatColumn.php | 2 +- .../Generator/Columns/SoftDeleteColumn.php | 2 +- .../Generator/Columns/SpatialColumn.php | 6 +- .../Generator/ForeignKeyGenerator.php | 16 +- src/Migration/Generator/IndexGenerator.php | 4 +- .../Generator/Modifiers/CharsetModifier.php | 2 +- .../Generator/Modifiers/CollationModifier.php | 2 +- .../Generator/Modifiers/CommentModifier.php | 2 +- .../Generator/Modifiers/DefaultModifier.php | 68 +++---- .../Generator/Modifiers/IndexModifier.php | 6 +- .../Generator/Modifiers/NullableModifier.php | 18 +- .../Generator/Modifiers/StoredAsModifier.php | 2 +- .../Generator/Modifiers/VirtualAsModifier.php | 2 +- src/Migration/ProcedureMigration.php | 2 +- src/Migration/TableMigration.php | 14 +- src/Migration/ViewMigration.php | 2 +- src/Migration/Writer/MigrationWriter.php | 8 +- src/Migration/Writer/SquashWriter.php | 8 +- src/MigrationsGeneratorServiceProvider.php | 68 +++---- src/Support/AssetNameQuote.php | 4 +- src/Support/IndexNameHelper.php | 4 +- tests/MigrationWriterTest.php | 27 +-- ...00000_expected_create_collations_table.php | 12 +- ...0000_expected_create_all_columns_table.php | 18 +- ...00000_expected_create_test_index_table.php | 6 +- ...ected_create_quoted_name_foreign_table.php | 2 +- ...00001_expected_create_quoted_name_proc.php | 6 +- ...001_expected_create_user_profile_table.php | 2 +- 79 files changed, 495 insertions(+), 608 deletions(-) create mode 100644 src/Enum/Migrations/Method/DBBuilder.php create mode 100644 src/Enum/Migrations/Method/MethodName.php create mode 100644 src/Enum/Migrations/Property/PropertyName.php diff --git a/composer.json b/composer.json index b1557229..6d48303b 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,6 @@ "require": { "php": "^8.1", "illuminate/support": "^10.43|^11.0", - "myclabs/php-enum": "^1.8", "ext-pdo": "*" }, "require-dev": { diff --git a/phpstan.neon b/phpstan.neon index e6a04458..a8bc8484 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -13,7 +13,6 @@ parameters: ignoreErrors: - '#Class Dotenv\\Dotenv constructor invoked with 1 parameter, 4 required.#' - '#Parameter \#1 \$store of class Dotenv\\Dotenv constructor expects Dotenv\\Store\\StoreInterface, string given.#' - - '#Constant (.*)\\Enum\\(.*) is unused#' - '#Method KitLoong\\MigrationsGenerator\\Database\\(.*)Schema::getViews\(\) should return Illuminate\\Support\\Collection but returns Illuminate\\Support\\Collection<(int|\(int\|string\)), KitLoong\\MigrationsGenerator\\Database\\Models\\(.*)\\(.*)View>.#' - '#Method KitLoong\\MigrationsGenerator\\Database\\(.*)Schema::getProcedures\(\) should return Illuminate\\Support\\Collection but returns Illuminate\\Support\\Collection<(int|\(int\|string\)), KitLoong\\MigrationsGenerator\\Database\\Models\\(.*)\\(.*)Procedure>.#' - '#Method KitLoong\\MigrationsGenerator\\Database\\(.*)Schema::getForeignKeys\(\) should return Illuminate\\Support\\Collection but returns Illuminate\\Support\\Collection<(int|\(int\|string\)), KitLoong\\MigrationsGenerator\\Database\\Models\\(.*)\\(.*)ForeignKey>.#' diff --git a/src/Database/DatabaseColumnType.php b/src/Database/DatabaseColumnType.php index a5496a97..4e8be47b 100644 --- a/src/Database/DatabaseColumnType.php +++ b/src/Database/DatabaseColumnType.php @@ -12,11 +12,10 @@ abstract class DatabaseColumnType abstract public static function toColumnType(string $dbType): ColumnType; /** - * @param array $map + * @param array $map */ protected static function mapToColumnType(array $map, string $dbType): ColumnType { - $columnType = $map[strtolower($dbType)] ?? ColumnType::STRING(); - return ColumnType::fromValue($columnType); + return $map[strtolower($dbType)] ?? ColumnType::STRING; } } diff --git a/src/Database/Models/DatabaseColumn.php b/src/Database/Models/DatabaseColumn.php index b4aef284..c609dc1b 100644 --- a/src/Database/Models/DatabaseColumn.php +++ b/src/Database/Models/DatabaseColumn.php @@ -261,11 +261,11 @@ protected function setTypeToIncrements(bool $supportUnsigned): void { if ( !in_array($this->type, [ - ColumnType::BIG_INTEGER(), - ColumnType::INTEGER(), - ColumnType::MEDIUM_INTEGER(), - ColumnType::SMALL_INTEGER(), - ColumnType::TINY_INTEGER(), + ColumnType::BIG_INTEGER, + ColumnType::INTEGER, + ColumnType::MEDIUM_INTEGER, + ColumnType::SMALL_INTEGER, + ColumnType::TINY_INTEGER, ]) ) { return; @@ -279,12 +279,12 @@ protected function setTypeToIncrements(bool $supportUnsigned): void return; } - if ($this->type->equals(ColumnType::INTEGER())) { - $this->type = ColumnType::INCREMENTS(); + if ($this->type === ColumnType::INTEGER) { + $this->type = ColumnType::INCREMENTS; return; } - $this->type = ColumnType::fromValue(str_replace('Integer', 'Increments', $this->type)); + $this->type = ColumnType::from(str_replace('Integer', 'Increments', $this->type->value)); } /** @@ -318,15 +318,15 @@ protected function escapeComment(?string $comment): ?string protected function parseLength(string $fullDefinitionType): ?int { switch ($this->type) { - case ColumnType::CHAR(): - case ColumnType::STRING(): - case ColumnType::DATE(): - case ColumnType::DATETIME(): - case ColumnType::DATETIME_TZ(): - case ColumnType::TIME(): - case ColumnType::TIME_TZ(): - case ColumnType::TIMESTAMP(): - case ColumnType::TIMESTAMP_TZ(): + case ColumnType::CHAR: + case ColumnType::STRING: + case ColumnType::DATE: + case ColumnType::DATETIME: + case ColumnType::DATETIME_TZ: + case ColumnType::TIME: + case ColumnType::TIME_TZ: + case ColumnType::TIMESTAMP: + case ColumnType::TIMESTAMP_TZ: if (preg_match('/\((\d*)\)/', $fullDefinitionType, $matches) === 1) { return (int) $matches[1]; } @@ -343,9 +343,9 @@ protected function parseLength(string $fullDefinitionType): ?int protected function parsePrecisionAndScale(string $fullDefinitionType): array { switch ($this->type) { - case ColumnType::DECIMAL(): - case ColumnType::DOUBLE(): - case ColumnType::FLOAT(): + case ColumnType::DECIMAL: + case ColumnType::DOUBLE: + case ColumnType::FLOAT: if (preg_match('/\((\d+)(?:,\s*(\d+))?\)?/', $fullDefinitionType, $matches) === 1) { return [(int) $matches[1], isset($matches[2]) ? (int) $matches[2] : 0]; } @@ -359,17 +359,17 @@ protected function parsePrecisionAndScale(string $fullDefinitionType): array */ private function setTypeToSoftDeletes(): void { - if ($this->name !== ColumnName::DELETED_AT()->getValue()) { + if ($this->name !== ColumnName::DELETED_AT->value) { return; } switch ($this->type) { - case ColumnType::TIMESTAMP(): - $this->type = ColumnType::SOFT_DELETES(); + case ColumnType::TIMESTAMP: + $this->type = ColumnType::SOFT_DELETES; return; - case ColumnType::TIMESTAMP_TZ(): - $this->type = ColumnType::SOFT_DELETES_TZ(); + case ColumnType::TIMESTAMP_TZ: + $this->type = ColumnType::SOFT_DELETES_TZ; return; } } @@ -380,12 +380,12 @@ private function setTypeToSoftDeletes(): void private function setTypeToRememberToken(): void { if ( - ColumnName::REMEMBER_TOKEN()->getValue() !== $this->name + ColumnName::REMEMBER_TOKEN->value !== $this->name || $this->length !== self::REMEMBER_TOKEN_LENGTH ) { return; } - $this->type = ColumnType::REMEMBER_TOKEN(); + $this->type = ColumnType::REMEMBER_TOKEN; } } diff --git a/src/Database/Models/DatabaseIndex.php b/src/Database/Models/DatabaseIndex.php index 7980dff4..c73eb743 100644 --- a/src/Database/Models/DatabaseIndex.php +++ b/src/Database/Models/DatabaseIndex.php @@ -74,23 +74,23 @@ public function getType(): IndexType private function getIndexType(array $index): IndexType { if ($index['primary'] === true) { - return IndexType::PRIMARY(); + return IndexType::PRIMARY; } if ($index['unique'] === true) { - return IndexType::UNIQUE(); + return IndexType::UNIQUE; } // pgsql uses gist if ($index['type'] === 'spatial' || $index['type'] === 'gist') { - return IndexType::SPATIAL_INDEX(); + return IndexType::SPATIAL_INDEX; } // pgsql uses gin if ($index['type'] === 'fulltext' || $index['type'] === 'gin') { - return IndexType::FULLTEXT(); + return IndexType::FULLTEXT; } - return IndexType::INDEX(); + return IndexType::INDEX; } } diff --git a/src/Database/Models/MySQL/MySQLColumn.php b/src/Database/Models/MySQL/MySQLColumn.php index b3382ffd..64fa13f1 100644 --- a/src/Database/Models/MySQL/MySQLColumn.php +++ b/src/Database/Models/MySQL/MySQLColumn.php @@ -58,38 +58,38 @@ public function __construct(string $table, array $column) $this->setTypeToUnsigned(); switch ($this->type) { - case ColumnType::UNSIGNED_TINY_INTEGER(): - case ColumnType::TINY_INTEGER(): + case ColumnType::UNSIGNED_TINY_INTEGER: + case ColumnType::TINY_INTEGER: if ($this->isBoolean()) { - $this->type = ColumnType::BOOLEAN(); + $this->type = ColumnType::BOOLEAN; } break; - case ColumnType::ENUM(): + case ColumnType::ENUM: $this->presetValues = $this->getEnumPresetValues($column['type']); break; - case ColumnType::SET(): + case ColumnType::SET: $this->presetValues = $this->getSetPresetValues($column['type']); break; - case ColumnType::SOFT_DELETES(): - case ColumnType::SOFT_DELETES_TZ(): - case ColumnType::TIMESTAMP(): - case ColumnType::TIMESTAMP_TZ(): + case ColumnType::SOFT_DELETES: + case ColumnType::SOFT_DELETES_TZ: + case ColumnType::TIMESTAMP: + case ColumnType::TIMESTAMP_TZ: $this->onUpdateCurrentTimestamp = $this->hasOnUpdateCurrentTimestamp(); break; - case ColumnType::GEOGRAPHY(): - case ColumnType::GEOMETRY(): - case ColumnType::GEOMETRY_COLLECTION(): - case ColumnType::LINE_STRING(): - case ColumnType::MULTI_LINE_STRING(): - case ColumnType::POINT(): - case ColumnType::MULTI_POINT(): - case ColumnType::POLYGON(): - case ColumnType::MULTI_POLYGON(): + case ColumnType::GEOGRAPHY: + case ColumnType::GEOMETRY: + case ColumnType::GEOMETRY_COLLECTION: + case ColumnType::LINE_STRING: + case ColumnType::MULTI_LINE_STRING: + case ColumnType::POINT: + case ColumnType::MULTI_POINT: + case ColumnType::POLYGON: + case ColumnType::MULTI_POLYGON: $this->setRealSpatialColumn(); break; @@ -105,9 +105,9 @@ public function __construct(string $table, array $column) // Extra logic for MariaDB switch ($this->type) { - case ColumnType::LONG_TEXT(): + case ColumnType::LONG_TEXT: if ($this->isJson()) { - $this->type = ColumnType::JSON(); + $this->type = ColumnType::JSON; } break; @@ -255,38 +255,38 @@ private function setRealSpatialColumn(): void } switch ($this->type) { - case ColumnType::GEOMETRY_COLLECTION(): + case ColumnType::GEOMETRY_COLLECTION: $this->spatialSubType = 'geometryCollection'; break; - case ColumnType::LINE_STRING(): + case ColumnType::LINE_STRING: $this->spatialSubType = 'lineString'; break; - case ColumnType::MULTI_LINE_STRING(): + case ColumnType::MULTI_LINE_STRING: $this->spatialSubType = 'multiLineString'; break; - case ColumnType::POINT(): + case ColumnType::POINT: $this->spatialSubType = 'point'; break; - case ColumnType::MULTI_POINT(): + case ColumnType::MULTI_POINT: $this->spatialSubType = 'multiPoint'; break; - case ColumnType::POLYGON(): + case ColumnType::POLYGON: $this->spatialSubType = 'polygon'; break; - case ColumnType::MULTI_POLYGON(): + case ColumnType::MULTI_POLYGON: $this->spatialSubType = 'multiPolygon'; break; default: } - $this->type = ColumnType::GEOMETRY(); + $this->type = ColumnType::GEOMETRY; $this->spatialSrID = $this->mysqlRepository->getSrID($this->tableName, $this->name); @@ -294,7 +294,7 @@ private function setRealSpatialColumn(): void return; } - $this->type = ColumnType::GEOGRAPHY(); + $this->type = ColumnType::GEOGRAPHY; } /** @@ -304,18 +304,18 @@ private function setTypeToUnsigned(): void { if ( !in_array($this->type, [ - ColumnType::BIG_INTEGER(), - ColumnType::INTEGER(), - ColumnType::MEDIUM_INTEGER(), - ColumnType::SMALL_INTEGER(), - ColumnType::TINY_INTEGER(), + ColumnType::BIG_INTEGER, + ColumnType::INTEGER, + ColumnType::MEDIUM_INTEGER, + ColumnType::SMALL_INTEGER, + ColumnType::TINY_INTEGER, ]) || !$this->unsigned ) { return; } - $this->type = ColumnType::fromValue('unsigned' . ucfirst($this->type)); + $this->type = ColumnType::from('unsigned' . ucfirst($this->type->value)); } /** diff --git a/src/Database/Models/MySQL/MySQLColumnType.php b/src/Database/Models/MySQL/MySQLColumnType.php index 653c2c72..570762d4 100644 --- a/src/Database/Models/MySQL/MySQLColumnType.php +++ b/src/Database/Models/MySQL/MySQLColumnType.php @@ -8,7 +8,7 @@ class MySQLColumnType extends DatabaseColumnType { /** - * @var array + * @var array */ protected static array $map = [ 'bigint' => ColumnType::BIG_INTEGER, diff --git a/src/Database/Models/MySQL/MySQLIndex.php b/src/Database/Models/MySQL/MySQLIndex.php index c8dabb74..604c444a 100644 --- a/src/Database/Models/MySQL/MySQLIndex.php +++ b/src/Database/Models/MySQL/MySQLIndex.php @@ -15,7 +15,7 @@ public function __construct(string $table, array $index) parent::__construct($table, $index); switch ($this->type) { - case IndexType::PRIMARY(): + case IndexType::PRIMARY: // Reset name to empty to indicate use the database platform naming. $this->name = ''; break; diff --git a/src/Database/Models/PgSQL/PgSQLColumn.php b/src/Database/Models/PgSQL/PgSQLColumn.php index 42c2dbcb..e261e42a 100644 --- a/src/Database/Models/PgSQL/PgSQLColumn.php +++ b/src/Database/Models/PgSQL/PgSQLColumn.php @@ -28,28 +28,28 @@ public function __construct(string $table, array $column) $this->setTypeToIncrements(false); switch ($this->type) { - case ColumnType::DATE(): - case ColumnType::DATETIME(): - case ColumnType::DATETIME_TZ(): - case ColumnType::TIME(): - case ColumnType::TIME_TZ(): - case ColumnType::TIMESTAMP(): - case ColumnType::TIMESTAMP_TZ(): - case ColumnType::SOFT_DELETES(): - case ColumnType::SOFT_DELETES_TZ(): + case ColumnType::DATE: + case ColumnType::DATETIME: + case ColumnType::DATETIME_TZ: + case ColumnType::TIME: + case ColumnType::TIME_TZ: + case ColumnType::TIMESTAMP: + case ColumnType::TIMESTAMP_TZ: + case ColumnType::SOFT_DELETES: + case ColumnType::SOFT_DELETES_TZ: $this->setRawDefault(); break; - case ColumnType::GEOGRAPHY(): - case ColumnType::GEOMETRY(): + case ColumnType::GEOGRAPHY: + case ColumnType::GEOMETRY: $this->setRealSpatialColumn($column['type']); break; - case ColumnType::STRING(): + case ColumnType::STRING: $this->presetValues = $this->getEnumPresetValues(); if (count($this->presetValues) > 0) { - $this->type = ColumnType::ENUM(); + $this->type = ColumnType::ENUM; } break; @@ -107,14 +107,14 @@ private function setRawDefault(): void private function getGeometryMap(): array { return [ - 'geometry' => ColumnType::GEOMETRY(), - 'geometrycollection' => ColumnType::GEOMETRY_COLLECTION(), - 'linestring' => ColumnType::LINE_STRING(), - 'multilinestring' => ColumnType::MULTI_LINE_STRING(), - 'multipoint' => ColumnType::MULTI_POINT(), - 'multipolygon' => ColumnType::MULTI_POLYGON(), - 'point' => ColumnType::POINT(), - 'polygon' => ColumnType::POLYGON(), + 'geometry' => ColumnType::GEOMETRY, + 'geometrycollection' => ColumnType::GEOMETRY_COLLECTION, + 'linestring' => ColumnType::LINE_STRING, + 'multilinestring' => ColumnType::MULTI_LINE_STRING, + 'multipoint' => ColumnType::MULTI_POINT, + 'multipolygon' => ColumnType::MULTI_POLYGON, + 'point' => ColumnType::POINT, + 'polygon' => ColumnType::POLYGON, ]; } diff --git a/src/Database/Models/PgSQL/PgSQLColumnType.php b/src/Database/Models/PgSQL/PgSQLColumnType.php index 5128b479..d09b413e 100644 --- a/src/Database/Models/PgSQL/PgSQLColumnType.php +++ b/src/Database/Models/PgSQL/PgSQLColumnType.php @@ -8,7 +8,7 @@ class PgSQLColumnType extends DatabaseColumnType { /** - * @var array + * @var array */ protected static array $map = [ '_text' => ColumnType::TEXT, diff --git a/src/Database/Models/PgSQL/PgSQLCustomColumn.php b/src/Database/Models/PgSQL/PgSQLCustomColumn.php index 00e8566d..4fef3db1 100644 --- a/src/Database/Models/PgSQL/PgSQLCustomColumn.php +++ b/src/Database/Models/PgSQL/PgSQLCustomColumn.php @@ -27,7 +27,7 @@ public function __construct(string $table, array $column) 'autoIncrement' => $column['auto_increment'], 'collation' => $column['collation'], 'comment' => $column['comment'], - 'default' => $this->parseDefault($column['default'], ColumnType::STRING()), // Assume is string + 'default' => $this->parseDefault($column['default'], ColumnType::STRING), // Assume is string 'nullable' => $column['nullable'], // 'after' => "id", ]); diff --git a/src/Database/Models/PgSQL/PgSQLIndex.php b/src/Database/Models/PgSQL/PgSQLIndex.php index 7f1fcb17..f7f64e97 100644 --- a/src/Database/Models/PgSQL/PgSQLIndex.php +++ b/src/Database/Models/PgSQL/PgSQLIndex.php @@ -15,7 +15,7 @@ public function __construct(string $table, array $index) parent::__construct($table, $index); switch ($this->type) { - case IndexType::PRIMARY(): + case IndexType::PRIMARY: // Reset name to empty to indicate use the database platform naming. $this->name = ''; break; diff --git a/src/Database/Models/PgSQL/PgSQLParser.php b/src/Database/Models/PgSQL/PgSQLParser.php index 51f3b227..a34a0fa1 100644 --- a/src/Database/Models/PgSQL/PgSQLParser.php +++ b/src/Database/Models/PgSQL/PgSQLParser.php @@ -23,7 +23,7 @@ public function parseDefault(?string $default, ColumnType $columnType): ?string $default = $matches[1]; } - if ($columnType->equals(ColumnType::STRING()) || $columnType->equals(ColumnType::TEXT())) { + if ($columnType === ColumnType::STRING || $columnType === ColumnType::TEXT) { $default = str_replace("''", "'", $default); } diff --git a/src/Database/Models/PgSQL/PgSQLTable.php b/src/Database/Models/PgSQL/PgSQLTable.php index 9373a3ff..b38ef6f2 100644 --- a/src/Database/Models/PgSQL/PgSQLTable.php +++ b/src/Database/Models/PgSQL/PgSQLTable.php @@ -66,7 +66,7 @@ private function updateFulltextIndexes(): void ->keyBy(static fn (IndexDefinition $indexDefinition) => $indexDefinition->getIndexName()); $this->indexes = $this->indexes->map(static function (Index $index) use ($fulltextIndexes, $tableName) { - if (!$index->getType()->equals(IndexType::FULLTEXT())) { + if (!($index->getType() === IndexType::FULLTEXT)) { return $index; } @@ -84,8 +84,8 @@ private function updateFulltextIndexes(): void 'name' => $index->getName(), 'columns' => $columns, 'type' => 'gin', - 'unique' => $index->getType()->equals(IndexType::UNIQUE()), - 'primary' => $index->getType()->equals(IndexType::PRIMARY()), + 'unique' => false, + 'primary' => false, ], ); }); diff --git a/src/Database/Models/SQLSrv/SQLSrvColumn.php b/src/Database/Models/SQLSrv/SQLSrvColumn.php index 86c35fd1..e25fab74 100644 --- a/src/Database/Models/SQLSrv/SQLSrvColumn.php +++ b/src/Database/Models/SQLSrv/SQLSrvColumn.php @@ -36,30 +36,30 @@ public function __construct(string $table, array $column) $this->fixMoneyPrecision($column['type_name']); switch ($this->type) { - case ColumnType::DATE(): - case ColumnType::DATETIME(): - case ColumnType::DATETIME_TZ(): - case ColumnType::TIME(): - case ColumnType::TIME_TZ(): - case ColumnType::TIMESTAMP(): - case ColumnType::TIMESTAMP_TZ(): - case ColumnType::SOFT_DELETES(): - case ColumnType::SOFT_DELETES_TZ(): + case ColumnType::DATE: + case ColumnType::DATETIME: + case ColumnType::DATETIME_TZ: + case ColumnType::TIME: + case ColumnType::TIME_TZ: + case ColumnType::TIMESTAMP: + case ColumnType::TIMESTAMP_TZ: + case ColumnType::SOFT_DELETES: + case ColumnType::SOFT_DELETES_TZ: $this->length = $this->getDateTimeLength(); break; - case ColumnType::CHAR(): - case ColumnType::STRING(): - case ColumnType::TEXT(): + case ColumnType::CHAR: + case ColumnType::STRING: + case ColumnType::TEXT: $this->presetValues = $this->getEnumPresetValues(); if (count($this->presetValues) > 0) { - $this->type = ColumnType::ENUM(); + $this->type = ColumnType::ENUM; break; } if ($this->isText($column['type'])) { - $this->type = ColumnType::TEXT(); + $this->type = ColumnType::TEXT; $this->length = null; } @@ -91,7 +91,7 @@ private function getDateTimeLength(): ?int } switch ($this->type) { - case ColumnType::DATETIME(): + case ColumnType::DATETIME: if ( $columnDef->getScale() === self::DATETIME_EMPTY_SCALE && $columnDef->getLength() === self::DATETIME_EMPTY_LENGTH @@ -101,7 +101,7 @@ private function getDateTimeLength(): ?int return $columnDef->getScale(); - case ColumnType::DATETIME_TZ(): + case ColumnType::DATETIME_TZ: if ( $columnDef->getScale() === self::DATETIME_TZ_EMPTY_SCALE && $columnDef->getLength() === self::DATETIME_TZ_EMPTY_LENGTH diff --git a/src/Database/Models/SQLSrv/SQLSrvColumnType.php b/src/Database/Models/SQLSrv/SQLSrvColumnType.php index e67a3cec..0b6e91fc 100644 --- a/src/Database/Models/SQLSrv/SQLSrvColumnType.php +++ b/src/Database/Models/SQLSrv/SQLSrvColumnType.php @@ -8,7 +8,7 @@ class SQLSrvColumnType extends DatabaseColumnType { /** - * @var array + * @var array */ protected static array $map = [ 'bigint' => ColumnType::BIG_INTEGER, diff --git a/src/Database/Models/SQLSrv/SQLSrvIndex.php b/src/Database/Models/SQLSrv/SQLSrvIndex.php index 81f77020..782ad8a2 100644 --- a/src/Database/Models/SQLSrv/SQLSrvIndex.php +++ b/src/Database/Models/SQLSrv/SQLSrvIndex.php @@ -17,7 +17,7 @@ public function __construct(string $table, array $index) parent::__construct($table, $index); switch ($this->type) { - case IndexType::PRIMARY(): + case IndexType::PRIMARY: $this->resetPrimaryNameToEmptyIfIsDefaultName(); break; diff --git a/src/Database/Models/SQLite/SQLiteColumn.php b/src/Database/Models/SQLite/SQLiteColumn.php index 69a07928..88637485 100644 --- a/src/Database/Models/SQLite/SQLiteColumn.php +++ b/src/Database/Models/SQLite/SQLiteColumn.php @@ -28,25 +28,25 @@ public function __construct(string $table, array $column) $this->setTypeToIncrements(false); switch ($this->type) { - case ColumnType::INTEGER(): + case ColumnType::INTEGER: if ($this->isBoolean($column['type'])) { - $this->type = ColumnType::BOOLEAN(); + $this->type = ColumnType::BOOLEAN; } break; - case ColumnType::STRING(): + case ColumnType::STRING: $this->presetValues = $this->getEnumPresetValues(); if (count($this->presetValues) > 0) { - $this->type = ColumnType::ENUM(); + $this->type = ColumnType::ENUM; } break; - case ColumnType::DATETIME(): + case ColumnType::DATETIME: if ($this->default === 'CURRENT_TIMESTAMP') { - $this->type = ColumnType::TIMESTAMP(); + $this->type = ColumnType::TIMESTAMP; } break; diff --git a/src/Database/Models/SQLite/SQLiteColumnType.php b/src/Database/Models/SQLite/SQLiteColumnType.php index 988f1fb1..d0293665 100644 --- a/src/Database/Models/SQLite/SQLiteColumnType.php +++ b/src/Database/Models/SQLite/SQLiteColumnType.php @@ -8,7 +8,7 @@ class SQLiteColumnType extends DatabaseColumnType { /** - * @var array + * @var array */ protected static array $map = [ 'bigint' => ColumnType::BIG_INTEGER, diff --git a/src/Database/Models/SQLite/SQLiteIndex.php b/src/Database/Models/SQLite/SQLiteIndex.php index 79c4b8ec..23bd0da1 100644 --- a/src/Database/Models/SQLite/SQLiteIndex.php +++ b/src/Database/Models/SQLite/SQLiteIndex.php @@ -15,7 +15,7 @@ public function __construct(string $table, array $index) parent::__construct($table, $index); switch ($this->type) { - case IndexType::PRIMARY(): + case IndexType::PRIMARY: // Reset name to empty to indicate use the database platform naming. $this->name = ''; break; diff --git a/src/Enum/Driver.php b/src/Enum/Driver.php index f5f472d6..42704927 100644 --- a/src/Enum/Driver.php +++ b/src/Enum/Driver.php @@ -2,21 +2,13 @@ namespace KitLoong\MigrationsGenerator\Enum; -use MyCLabs\Enum\Enum; - /** * Framework DB connection driver name. - * - * @method static self MYSQL() - * @method static self PGSQL() - * @method static self SQLITE() - * @method static self SQLSRV() - * @extends \MyCLabs\Enum\Enum */ -final class Driver extends Enum +enum Driver: string { - private const MYSQL = 'mysql'; - private const PGSQL = 'pgsql'; - private const SQLITE = 'sqlite'; - private const SQLSRV = 'sqlsrv'; + case MYSQL = 'mysql'; + case PGSQL = 'pgsql'; + case SQLITE = 'sqlite'; + case SQLSRV = 'sqlsrv'; } diff --git a/src/Enum/Migrations/ColumnName.php b/src/Enum/Migrations/ColumnName.php index 944da132..26a72bd1 100644 --- a/src/Enum/Migrations/ColumnName.php +++ b/src/Enum/Migrations/ColumnName.php @@ -2,22 +2,15 @@ namespace KitLoong\MigrationsGenerator\Enum\Migrations; -use MyCLabs\Enum\Enum; - /** * Preserved column names used by the framework. * * @see https://laravel.com/docs/master/migrations#available-column-types - * @method static self CREATED_AT() - * @method static self DELETED_AT() - * @method static self REMEMBER_TOKEN() - * @method static self UPDATED_AT() - * @extends \MyCLabs\Enum\Enum */ -final class ColumnName extends Enum +enum ColumnName: string { - private const CREATED_AT = 'created_at'; - private const DELETED_AT = 'deleted_at'; - private const REMEMBER_TOKEN = 'remember_token'; - private const UPDATED_AT = 'updated_at'; + case CREATED_AT = 'created_at'; + case DELETED_AT = 'deleted_at'; + case REMEMBER_TOKEN = 'remember_token'; + case UPDATED_AT = 'updated_at'; } diff --git a/src/Enum/Migrations/Method/ColumnModifier.php b/src/Enum/Migrations/Method/ColumnModifier.php index 51526d5b..150fa2a2 100644 --- a/src/Enum/Migrations/Method/ColumnModifier.php +++ b/src/Enum/Migrations/Method/ColumnModifier.php @@ -2,40 +2,24 @@ namespace KitLoong\MigrationsGenerator\Enum\Migrations\Method; -use MyCLabs\Enum\Enum; - /** * Preserved column modifier of the framework. * * @see https://laravel.com/docs/master/migrations#column-modifiers - * @method static self ALWAYS() - * @method static self AUTO_INCREMENT() - * @method static self CHARSET() - * @method static self COLLATION() - * @method static self COMMENT() - * @method static self DEFAULT() - * @method static self GENERATED_AS() - * @method static self NULLABLE() - * @method static self STORED_AS() - * @method static self UNSIGNED() - * @method static self USE_CURRENT() - * @method static self USE_CURRENT_ON_UPDATE() - * @method static self VIRTUAL_AS() - * @extends \MyCLabs\Enum\Enum */ -final class ColumnModifier extends Enum +enum ColumnModifier: string implements MethodName { - private const ALWAYS = 'always'; - private const AUTO_INCREMENT = 'autoIncrement'; - private const CHARSET = 'charset'; - private const COLLATION = 'collation'; - private const COMMENT = 'comment'; - private const DEFAULT = 'default'; - private const GENERATED_AS = 'generatedAs'; - private const NULLABLE = 'nullable'; - private const STORED_AS = 'storedAs'; - private const UNSIGNED = 'unsigned'; - private const USE_CURRENT = 'useCurrent'; - private const USE_CURRENT_ON_UPDATE = 'useCurrentOnUpdate'; - private const VIRTUAL_AS = 'virtualAs'; + case ALWAYS = 'always'; + case AUTO_INCREMENT = 'autoIncrement'; + case CHARSET = 'charset'; + case COLLATION = 'collation'; + case COMMENT = 'comment'; + case DEFAULT = 'default'; + case GENERATED_AS = 'generatedAs'; + case NULLABLE = 'nullable'; + case STORED_AS = 'storedAs'; + case UNSIGNED = 'unsigned'; + case USE_CURRENT = 'useCurrent'; + case USE_CURRENT_ON_UPDATE = 'useCurrentOnUpdate'; + case VIRTUAL_AS = 'virtualAs'; } diff --git a/src/Enum/Migrations/Method/ColumnType.php b/src/Enum/Migrations/Method/ColumnType.php index f291e584..a1f6b1e2 100644 --- a/src/Enum/Migrations/Method/ColumnType.php +++ b/src/Enum/Migrations/Method/ColumnType.php @@ -2,134 +2,66 @@ namespace KitLoong\MigrationsGenerator\Enum\Migrations\Method; -use MyCLabs\Enum\Enum; - /** * Define column types of the framework. * * @link https://laravel.com/docs/master/migrations#available-column-types - * @method static self BIG_INTEGER() - * @method static self BIG_INCREMENTS() - * @method static self BINARY() - * @method static self BOOLEAN() - * @method static self CHAR() - * @method static self DATE() - * @method static self DATETIME() - * @method static self DATETIME_TZ() - * @method static self DECIMAL() - * @method static self DOUBLE() - * @method static self ENUM() - * @method static self FLOAT() - * @method static self GEOGRAPHY() - * @method static self GEOMETRY() - * @method static self GEOMETRY_COLLECTION() - * @method static self INCREMENTS() - * @method static self INTEGER() - * @method static self IP_ADDRESS() - * @method static self JSON() - * @method static self JSONB() - * @method static self LINE_STRING() - * @method static self LONG_TEXT() - * @method static self MAC_ADDRESS() - * @method static self MEDIUM_INCREMENTS() - * @method static self MEDIUM_INTEGER() - * @method static self MEDIUM_TEXT() - * @method static self MULTI_LINE_STRING() - * @method static self MULTI_POINT() - * @method static self MULTI_POLYGON() - * @method static self POINT() - * @method static self POLYGON() - * @method static self REMEMBER_TOKEN() - * @method static self SET() - * @method static self SMALL_INCREMENTS() - * @method static self SMALL_INTEGER() - * @method static self SOFT_DELETES() - * @method static self SOFT_DELETES_TZ() - * @method static self STRING() - * @method static self TEXT() - * @method static self TIME() - * @method static self TIME_TZ() - * @method static self TIMESTAMP() - * @method static self TIMESTAMPS() - * @method static self TIMESTAMP_TZ() - * @method static self TIMESTAMPS_TZ() - * @method static self TINY_INCREMENTS() - * @method static self TINY_INTEGER() - * @method static self TINY_TEXT() - * @method static self UNSIGNED_BIG_INTEGER() - * @method static self UNSIGNED_INTEGER() - * @method static self UNSIGNED_MEDIUM_INTEGER() - * @method static self UNSIGNED_SMALL_INTEGER() - * @method static self UNSIGNED_TINY_INTEGER() - * @method static self UUID() - * @method static self YEAR() - * @extends \MyCLabs\Enum\Enum */ -final class ColumnType extends Enum +enum ColumnType: string implements MethodName { - public const BIG_INTEGER = 'bigInteger'; - public const BIG_INCREMENTS = 'bigIncrements'; - public const BINARY = 'binary'; - public const BOOLEAN = 'boolean'; - public const CHAR = 'char'; - public const DATE = 'date'; - public const DATETIME = 'dateTime'; - public const DATETIME_TZ = 'dateTimeTz'; - public const DECIMAL = 'decimal'; - public const DOUBLE = 'double'; - public const ENUM = 'enum'; - public const FLOAT = 'float'; - public const GEOGRAPHY = 'geography'; - public const GEOMETRY = 'geometry'; - public const GEOMETRY_COLLECTION = 'geometryCollection'; - public const INCREMENTS = 'increments'; - public const INTEGER = 'integer'; - public const IP_ADDRESS = 'ipAddress'; - public const JSON = 'json'; - public const JSONB = 'jsonb'; - public const LINE_STRING = 'lineString'; - public const LONG_TEXT = 'longText'; - public const MAC_ADDRESS = 'macAddress'; - public const MEDIUM_INCREMENTS = 'mediumIncrements'; - public const MEDIUM_INTEGER = 'mediumInteger'; - public const MEDIUM_TEXT = 'mediumText'; - public const MULTI_LINE_STRING = 'multiLineString'; - public const MULTI_POINT = 'multiPoint'; - public const MULTI_POLYGON = 'multiPolygon'; - public const POINT = 'point'; - public const POLYGON = 'polygon'; - public const REMEMBER_TOKEN = 'rememberToken'; - public const SET = 'set'; - public const SMALL_INCREMENTS = 'smallIncrements'; - public const SMALL_INTEGER = 'smallInteger'; - public const SOFT_DELETES = 'softDeletes'; - public const SOFT_DELETES_TZ = 'softDeletesTz'; - public const STRING = 'string'; - public const TEXT = 'text'; - public const TIME = 'time'; - public const TIME_TZ = 'timeTz'; - public const TIMESTAMP = 'timestamp'; - public const TIMESTAMPS = 'timestamps'; - public const TIMESTAMP_TZ = 'timestampTz'; - public const TIMESTAMPS_TZ = 'timestampsTz'; - public const TINY_INCREMENTS = 'tinyIncrements'; - public const TINY_INTEGER = 'tinyInteger'; - public const TINY_TEXT = 'tinyText'; - public const UNSIGNED_BIG_INTEGER = 'unsignedBigInteger'; - public const UNSIGNED_INTEGER = 'unsignedInteger'; - public const UNSIGNED_MEDIUM_INTEGER = 'unsignedMediumInteger'; - public const UNSIGNED_SMALL_INTEGER = 'unsignedSmallInteger'; - public const UNSIGNED_TINY_INTEGER = 'unsignedTinyInteger'; - public const UUID = 'uuid'; - public const YEAR = 'year'; - - /** - * Initiate an instance from value. - * - * @return static - */ - public static function fromValue(string $value): self - { - return parent::from($value); - } + case BIG_INTEGER = 'bigInteger'; + case BIG_INCREMENTS = 'bigIncrements'; + case BINARY = 'binary'; + case BOOLEAN = 'boolean'; + case CHAR = 'char'; + case DATE = 'date'; + case DATETIME = 'dateTime'; + case DATETIME_TZ = 'dateTimeTz'; + case DECIMAL = 'decimal'; + case DOUBLE = 'double'; + case ENUM = 'enum'; + case FLOAT = 'float'; + case GEOGRAPHY = 'geography'; + case GEOMETRY = 'geometry'; + case GEOMETRY_COLLECTION = 'geometryCollection'; + case INCREMENTS = 'increments'; + case INTEGER = 'integer'; + case IP_ADDRESS = 'ipAddress'; + case JSON = 'json'; + case JSONB = 'jsonb'; + case LINE_STRING = 'lineString'; + case LONG_TEXT = 'longText'; + case MAC_ADDRESS = 'macAddress'; + case MEDIUM_INCREMENTS = 'mediumIncrements'; + case MEDIUM_INTEGER = 'mediumInteger'; + case MEDIUM_TEXT = 'mediumText'; + case MULTI_LINE_STRING = 'multiLineString'; + case MULTI_POINT = 'multiPoint'; + case MULTI_POLYGON = 'multiPolygon'; + case POINT = 'point'; + case POLYGON = 'polygon'; + case REMEMBER_TOKEN = 'rememberToken'; + case SET = 'set'; + case SMALL_INCREMENTS = 'smallIncrements'; + case SMALL_INTEGER = 'smallInteger'; + case SOFT_DELETES = 'softDeletes'; + case SOFT_DELETES_TZ = 'softDeletesTz'; + case STRING = 'string'; + case TEXT = 'text'; + case TIME = 'time'; + case TIME_TZ = 'timeTz'; + case TIMESTAMP = 'timestamp'; + case TIMESTAMPS = 'timestamps'; + case TIMESTAMP_TZ = 'timestampTz'; + case TIMESTAMPS_TZ = 'timestampsTz'; + case TINY_INCREMENTS = 'tinyIncrements'; + case TINY_INTEGER = 'tinyInteger'; + case TINY_TEXT = 'tinyText'; + case UNSIGNED_BIG_INTEGER = 'unsignedBigInteger'; + case UNSIGNED_INTEGER = 'unsignedInteger'; + case UNSIGNED_MEDIUM_INTEGER = 'unsignedMediumInteger'; + case UNSIGNED_SMALL_INTEGER = 'unsignedSmallInteger'; + case UNSIGNED_TINY_INTEGER = 'unsignedTinyInteger'; + case UUID = 'uuid'; + case YEAR = 'year'; } diff --git a/src/Enum/Migrations/Method/DBBuilder.php b/src/Enum/Migrations/Method/DBBuilder.php new file mode 100644 index 00000000..0b93bffe --- /dev/null +++ b/src/Enum/Migrations/Method/DBBuilder.php @@ -0,0 +1,9 @@ + */ -class Foreign extends Enum +enum Foreign: string implements MethodName { - private const DROP_FOREIGN = 'dropForeign'; - private const FOREIGN = 'foreign'; - private const ON = 'on'; - private const ON_DELETE = 'onDelete'; - private const ON_UPDATE = 'onUpdate'; - private const REFERENCES = 'references'; + case DROP_FOREIGN = 'dropForeign'; + case FOREIGN = 'foreign'; + case ON = 'on'; + case ON_DELETE = 'onDelete'; + case ON_UPDATE = 'onUpdate'; + case REFERENCES = 'references'; } diff --git a/src/Enum/Migrations/Method/IndexType.php b/src/Enum/Migrations/Method/IndexType.php index 98913be8..3fe6b224 100644 --- a/src/Enum/Migrations/Method/IndexType.php +++ b/src/Enum/Migrations/Method/IndexType.php @@ -2,26 +2,17 @@ namespace KitLoong\MigrationsGenerator\Enum\Migrations\Method; -use MyCLabs\Enum\Enum; - /** * Predefined index types of the framework. * * @see https://laravel.com/docs/master/migrations#available-index-types - * @method static self FULLTEXT() - * @method static self FULLTEXT_CHAIN() - * @method static self INDEX() - * @method static self PRIMARY() - * @method static self SPATIAL_INDEX() - * @method static self UNIQUE() - * @extends \MyCLabs\Enum\Enum */ -final class IndexType extends Enum +enum IndexType: string implements MethodName { - private const FULLTEXT = 'fullText'; - private const FULLTEXT_CHAIN = 'fulltext'; // Use lowercase. - private const INDEX = 'index'; - private const PRIMARY = 'primary'; - private const SPATIAL_INDEX = 'spatialIndex'; - private const UNIQUE = 'unique'; + case FULLTEXT = 'fullText'; + case FULLTEXT_CHAIN = 'fulltext'; // Use lowercase. + case INDEX = 'index'; + case PRIMARY = 'primary'; + case SPATIAL_INDEX = 'spatialIndex'; + case UNIQUE = 'unique'; } diff --git a/src/Enum/Migrations/Method/MethodName.php b/src/Enum/Migrations/Method/MethodName.php new file mode 100644 index 00000000..0320c84a --- /dev/null +++ b/src/Enum/Migrations/Method/MethodName.php @@ -0,0 +1,9 @@ + */ -final class SchemaBuilder extends Enum +enum SchemaBuilder: string implements MethodName { - private const CONNECTION = 'connection'; - private const CREATE = 'create'; - private const DROP_IF_EXISTS = 'dropIfExists'; - private const HAS_TABLE = 'hasTable'; - private const TABLE = 'table'; + case CONNECTION = 'connection'; + case CREATE = 'create'; + case DROP_IF_EXISTS = 'dropIfExists'; + case HAS_TABLE = 'hasTable'; + case TABLE = 'table'; } diff --git a/src/Enum/Migrations/Method/TableMethod.php b/src/Enum/Migrations/Method/TableMethod.php index 6f123e40..ef86ed2d 100644 --- a/src/Enum/Migrations/Method/TableMethod.php +++ b/src/Enum/Migrations/Method/TableMethod.php @@ -2,16 +2,12 @@ namespace KitLoong\MigrationsGenerator\Enum\Migrations\Method; -use MyCLabs\Enum\Enum; - /** * Preserved table methods of the framework. * * @see https://laravel.com/docs/master/migrations#tables - * @method static self COMMENT() - * @extends \MyCLabs\Enum\Enum */ -final class TableMethod extends Enum +enum TableMethod: string implements MethodName { - private const COMMENT = 'comment'; + case COMMENT = 'comment'; } diff --git a/src/Enum/Migrations/Property/PropertyName.php b/src/Enum/Migrations/Property/PropertyName.php new file mode 100644 index 00000000..1c7d510f --- /dev/null +++ b/src/Enum/Migrations/Property/PropertyName.php @@ -0,0 +1,9 @@ + */ -final class TableProperty extends Enum +enum TableProperty: string implements PropertyName { - private const CHARSET = 'charset'; - private const COLLATION = 'collation'; - private const ENGINE = 'engine'; + case CHARSET = 'charset'; + case COLLATION = 'collation'; + case ENGINE = 'engine'; } diff --git a/src/MigrateGenerateCommand.php b/src/MigrateGenerateCommand.php index b158e983..9f26d7f8 100644 --- a/src/MigrateGenerateCommand.php +++ b/src/MigrateGenerateCommand.php @@ -111,7 +111,7 @@ public function handle(): void $this->info("\nFinished!\n"); - if (DB::getDriverName() === Driver::SQLITE()->getValue()) { + if (DB::getDriverName() === Driver::SQLITE->value) { $this->warn('SQLite only supports foreign keys upon creation of the table and not when tables are altered.'); $this->warn('See https://www.sqlite.org/omitted.html'); $this->warn('*_add_foreign_keys_* migrations were generated, however will get omitted if migrate to SQLite type database.'); @@ -634,16 +634,16 @@ protected function makeSchema(): Schema } switch ($driver) { - case Driver::MYSQL(): + case Driver::MYSQL->value: return $this->schema = app(MySQLSchema::class); - case Driver::PGSQL(): + case Driver::PGSQL->value: return $this->schema = app(PgSQLSchema::class); - case Driver::SQLITE(): + case Driver::SQLITE->value: return $this->schema = app(SQLiteSchema::class); - case Driver::SQLSRV(): + case Driver::SQLSRV->value: return $this->schema = app(SQLSrvSchema::class); default: diff --git a/src/Migration/Blueprint/DBStatementBlueprint.php b/src/Migration/Blueprint/DBStatementBlueprint.php index 30e6a4da..7156f0c6 100644 --- a/src/Migration/Blueprint/DBStatementBlueprint.php +++ b/src/Migration/Blueprint/DBStatementBlueprint.php @@ -2,6 +2,7 @@ namespace KitLoong\MigrationsGenerator\Migration\Blueprint; +use KitLoong\MigrationsGenerator\Enum\Migrations\Method\DBBuilder; use KitLoong\MigrationsGenerator\Migration\Blueprint\Support\MethodStringHelper; use KitLoong\MigrationsGenerator\Migration\Blueprint\Support\Stringable; @@ -37,7 +38,7 @@ public function __construct(private string $sql) */ public function toString(): string { - $method = $this->connection('DB', 'statement'); + $method = $this->connection('DB', DBBuilder::STATEMENT); $query = $this->escapeDoubleQuote($this->sql); return "$method(\"$query\");"; } diff --git a/src/Migration/Blueprint/DBUnpreparedBlueprint.php b/src/Migration/Blueprint/DBUnpreparedBlueprint.php index fdce7c2b..a6b68020 100644 --- a/src/Migration/Blueprint/DBUnpreparedBlueprint.php +++ b/src/Migration/Blueprint/DBUnpreparedBlueprint.php @@ -2,6 +2,7 @@ namespace KitLoong\MigrationsGenerator\Migration\Blueprint; +use KitLoong\MigrationsGenerator\Enum\Migrations\Method\DBBuilder; use KitLoong\MigrationsGenerator\Migration\Blueprint\Support\MethodStringHelper; use KitLoong\MigrationsGenerator\Migration\Blueprint\Support\Stringable; @@ -37,7 +38,7 @@ public function __construct(private string $sql) */ public function toString(): string { - $method = $this->connection('DB', 'unprepared'); + $method = $this->connection('DB', DBBuilder::UNPREPARED); $query = $this->escapeDoubleQuote($this->sql); return "$method(\"$query\");"; } diff --git a/src/Migration/Blueprint/Method.php b/src/Migration/Blueprint/Method.php index cbf71022..99d9fded 100644 --- a/src/Migration/Blueprint/Method.php +++ b/src/Migration/Blueprint/Method.php @@ -2,6 +2,8 @@ namespace KitLoong\MigrationsGenerator\Migration\Blueprint; +use KitLoong\MigrationsGenerator\Enum\Migrations\Method\MethodName; + class Method { /** @@ -17,16 +19,16 @@ class Method /** * Method constructor. * - * @param string $name Method name. + * @param \KitLoong\MigrationsGenerator\Enum\Migrations\Method\MethodName $name Method name. * @param mixed ...$values Method arguments. */ - public function __construct(private string $name, mixed ...$values) + public function __construct(private MethodName $name, mixed ...$values) { $this->values = $values; $this->chains = []; } - public function getName(): string + public function getName(): MethodName { return $this->name; } @@ -42,11 +44,11 @@ public function getValues(): array /** * Chain method. * - * @param string $name Method name. + * @param \KitLoong\MigrationsGenerator\Enum\Migrations\Method\MethodName $name Method name. * @param mixed ...$values Method arguments. * @return $this */ - public function chain(string $name, mixed ...$values): self + public function chain(MethodName $name, mixed ...$values): self { $this->chains[] = new self($name, ...$values); return $this; @@ -55,9 +57,9 @@ public function chain(string $name, mixed ...$values): self /** * Checks if chain name exists. * - * @param string $name Method name. + * @param \KitLoong\MigrationsGenerator\Enum\Migrations\Method\MethodName $name Method name. */ - public function hasChain(string $name): bool + public function hasChain(MethodName $name): bool { foreach ($this->chains as $chain) { if ($chain->getName() === $name) { diff --git a/src/Migration/Blueprint/Property.php b/src/Migration/Blueprint/Property.php index f213accf..d1512878 100644 --- a/src/Migration/Blueprint/Property.php +++ b/src/Migration/Blueprint/Property.php @@ -2,16 +2,18 @@ namespace KitLoong\MigrationsGenerator\Migration\Blueprint; +use KitLoong\MigrationsGenerator\Enum\Migrations\Property\PropertyName; + class Property { /** * Property constructor. */ - public function __construct(private string $name, private mixed $value) + public function __construct(private PropertyName $name, private mixed $value) { } - public function getName(): string + public function getName(): PropertyName { return $this->name; } diff --git a/src/Migration/Blueprint/SchemaBlueprint.php b/src/Migration/Blueprint/SchemaBlueprint.php index d915658b..b4345f42 100644 --- a/src/Migration/Blueprint/SchemaBlueprint.php +++ b/src/Migration/Blueprint/SchemaBlueprint.php @@ -77,7 +77,7 @@ private function getLines(): array { $schema = $this->connection('Schema', $this->schemaBuilder); - if ($this->schemaBuilder->equals(SchemaBuilder::DROP_IF_EXISTS())) { + if ($this->schemaBuilder === SchemaBuilder::DROP_IF_EXISTS) { return $this->getDropLines($schema); } @@ -87,7 +87,7 @@ private function getLines(): array return $tableLines; } - $schemaHasTable = $this->connection('Schema', SchemaBuilder::HAS_TABLE()); + $schemaHasTable = $this->connection('Schema', SchemaBuilder::HAS_TABLE); $lines = []; @@ -95,7 +95,7 @@ private function getLines(): array foreach ($tableLines as $tableLine) { // Add another tabulation to indent(prettify) blueprint definition. - $lines[] = Space::TAB() . $tableLine; + $lines[] = Space::TAB->value . $tableLine; } $lines[] = "}"; @@ -132,7 +132,7 @@ private function getTableLines(string $schema): array } // Add 1 tabulation to indent(prettify) blueprint definition. - $lines[] = Space::TAB() . $this->blueprint->toString(); + $lines[] = Space::TAB->value . $this->blueprint->toString(); $lines[] = "});"; return $lines; @@ -145,7 +145,7 @@ private function getTableLines(string $schema): array */ private function getIfCondition(string $schemaHasTable, string $tableWithoutPrefix): string { - if ($this->schemaBuilder->equals(SchemaBuilder::TABLE())) { + if ($this->schemaBuilder === SchemaBuilder::TABLE) { return "if ($schemaHasTable('$tableWithoutPrefix')) {"; } diff --git a/src/Migration/Blueprint/Support/MergeTimestamps.php b/src/Migration/Blueprint/Support/MergeTimestamps.php index a8e0106f..aca5f272 100644 --- a/src/Migration/Blueprint/Support/MergeTimestamps.php +++ b/src/Migration/Blueprint/Support/MergeTimestamps.php @@ -30,7 +30,7 @@ public function merge(array $lines, bool $tz): array continue; } - if (!$this->checkTimestamps(ColumnName::CREATED_AT(), $line, $tz)) { + if (!$this->checkTimestamps(ColumnName::CREATED_AT, $line, $tz)) { continue; } @@ -46,7 +46,7 @@ public function merge(array $lines, bool $tz): array return $lines; } - if (!$this->checkTimestamps(ColumnName::UPDATED_AT(), $updatedAt, $tz)) { + if (!$this->checkTimestamps(ColumnName::UPDATED_AT, $updatedAt, $tz)) { return $lines; } @@ -76,7 +76,7 @@ private function checkTimestamps(ColumnName $columnName, Method $method, bool $t return false; } - if ($method->getValues()[0] !== $columnName->getValue()) { + if ($method->getValues()[0] !== $columnName->value) { return false; } @@ -84,7 +84,7 @@ private function checkTimestamps(ColumnName $columnName, Method $method, bool $t return false; } - return $method->getChains()[0]->getName() === ColumnModifier::NULLABLE()->getValue() + return $method->getChains()[0]->getName() === ColumnModifier::NULLABLE && count($method->getChains()[0]->getValues()) === 0; } @@ -95,11 +95,11 @@ private function checkTimestamps(ColumnName $columnName, Method $method, bool $t */ private function isPossibleTimestampsColumn(Method $method, bool $tz): bool { - if (Driver::SQLSRV()->getValue() === DB::getDriverName()) { - return $method->getName() === $this->sqlSrvTimestampsColumnType($tz)->getValue(); + if (Driver::SQLSRV->value === DB::getDriverName()) { + return $method->getName() === $this->sqlSrvTimestampsColumnType($tz); } - return $method->getName() === $this->timestampsColumnType($tz)->getValue(); + return $method->getName() === $this->timestampsColumnType($tz); } /** @@ -112,10 +112,10 @@ private function isPossibleTimestampsColumn(Method $method, bool $tz): bool private function sqlSrvTimestampsColumnType(bool $tz): ColumnType { if ($tz) { - return ColumnType::DATETIME_TZ(); + return ColumnType::DATETIME_TZ; } - return ColumnType::DATETIME(); + return ColumnType::DATETIME; } /** @@ -127,10 +127,10 @@ private function sqlSrvTimestampsColumnType(bool $tz): ColumnType private function timestampsColumnType(bool $tz): ColumnType { if ($tz) { - return ColumnType::TIMESTAMP_TZ(); + return ColumnType::TIMESTAMP_TZ; } - return ColumnType::TIMESTAMP(); + return ColumnType::TIMESTAMP; } /** @@ -138,7 +138,7 @@ private function timestampsColumnType(bool $tz): ColumnType * * @param bool $tz Is timezone. */ - private function timestamps(bool $tz): string + private function timestamps(bool $tz): ColumnType { if ($tz) { return ColumnType::TIMESTAMPS_TZ; diff --git a/src/Migration/Blueprint/Support/MethodStringHelper.php b/src/Migration/Blueprint/Support/MethodStringHelper.php index 63bf4f9b..50e9c395 100644 --- a/src/Migration/Blueprint/Support/MethodStringHelper.php +++ b/src/Migration/Blueprint/Support/MethodStringHelper.php @@ -3,6 +3,7 @@ namespace KitLoong\MigrationsGenerator\Migration\Blueprint\Support; use Illuminate\Support\Facades\DB; +use KitLoong\MigrationsGenerator\Enum\Migrations\Method\DBBuilder; use KitLoong\MigrationsGenerator\Enum\Migrations\Method\SchemaBuilder; use KitLoong\MigrationsGenerator\Setting; @@ -11,12 +12,12 @@ trait MethodStringHelper /** * Generates method string with `connection` if `--connection=other` option is used. */ - public function connection(string $class, string $method): string + public function connection(string $class, SchemaBuilder|DBBuilder $method): string { if (DB::getName() === app(Setting::class)->getDefaultConnection()) { - return "$class::$method"; + return "$class::$method->value"; } - return "$class::" . SchemaBuilder::CONNECTION() . "('" . DB::getName() . "')->$method"; + return "$class::" . SchemaBuilder::CONNECTION->value . "('" . DB::getName() . "')->$method->value"; } } diff --git a/src/Migration/Blueprint/Support/Stringable.php b/src/Migration/Blueprint/Support/Stringable.php index 7bdbe5ef..9cfee0c7 100644 --- a/src/Migration/Blueprint/Support/Stringable.php +++ b/src/Migration/Blueprint/Support/Stringable.php @@ -21,12 +21,12 @@ public function flattenLines(array $lines, int $numberOfPrefixTab): string foreach ($lines as $i => $line) { // Skip tab if the line is first line or line break. - if ($i === 0 || $line === Space::LINE_BREAK()->getValue()) { + if ($i === 0 || $line === Space::LINE_BREAK->value) { $content .= $line; continue; } - $content .= Space::LINE_BREAK() . str_repeat(Space::TAB(), $numberOfPrefixTab) . $line; + $content .= Space::LINE_BREAK->value . str_repeat(Space::TAB->value, $numberOfPrefixTab) . $line; } return $content; @@ -60,6 +60,10 @@ public function convertFromAnyTypeToString(mixed $value): string return 'DB::raw("' . $this->escapeDoubleQuote((string) DB::getQueryGrammar()->getValue($value)) . '")'; } + if ($value instanceof Space) { + return $value->value; + } + return (string) $value; } } diff --git a/src/Migration/Blueprint/TableBlueprint.php b/src/Migration/Blueprint/TableBlueprint.php index d8be85da..5cb0e95f 100644 --- a/src/Migration/Blueprint/TableBlueprint.php +++ b/src/Migration/Blueprint/TableBlueprint.php @@ -3,6 +3,8 @@ namespace KitLoong\MigrationsGenerator\Migration\Blueprint; use Illuminate\Support\Collection; +use KitLoong\MigrationsGenerator\Enum\Migrations\Method\MethodName; +use KitLoong\MigrationsGenerator\Enum\Migrations\Property\PropertyName; use KitLoong\MigrationsGenerator\Migration\Blueprint\Support\MergeTimestamps; use KitLoong\MigrationsGenerator\Migration\Blueprint\Support\Stringable; use KitLoong\MigrationsGenerator\Migration\Enum\Space; @@ -34,7 +36,7 @@ class TableBlueprint implements WritableBlueprint use Stringable; /** - * @var \KitLoong\MigrationsGenerator\Migration\Blueprint\Property[]|\KitLoong\MigrationsGenerator\Migration\Blueprint\Method[]|string[] + * @var array */ private array $lines; @@ -49,9 +51,9 @@ public function __construct() } /** - * @param string $name Property name. + * @param \KitLoong\MigrationsGenerator\Enum\Migrations\Property\PropertyName $name Property name. */ - public function setProperty(string $name, mixed $value): Property + public function setProperty(PropertyName $name, mixed $value): Property { $property = new Property($name, $value); $this->lines[] = $property; @@ -59,10 +61,10 @@ public function setProperty(string $name, mixed $value): Property } /** - * @param string $name Method name. + * @param \KitLoong\MigrationsGenerator\Enum\Migrations\Method\MethodName $name Method name. * @param mixed ...$values Method arguments. */ - public function setMethodByName(string $name, mixed ...$values): Method + public function setMethodByName(MethodName $name, mixed ...$values): Method { $method = new Method($name, ...$values); $this->lines[] = $method; @@ -77,16 +79,11 @@ public function setMethod(Method $method): Method public function setLineBreak(): void { - $this->lines[] = Space::LINE_BREAK(); - } - - public function removeLastLine(): Method|Property|string|null - { - return array_pop($this->lines); + $this->lines[] = Space::LINE_BREAK; } /** - * @return \KitLoong\MigrationsGenerator\Migration\Blueprint\Property[]|\KitLoong\MigrationsGenerator\Migration\Blueprint\Method[]|string[] + * @return array */ public function getLines(): array { @@ -147,7 +144,7 @@ public function toString(): string private function propertyToString(Property $property): string { $v = $this->convertFromAnyTypeToString($property->getValue()); - return '$table->' . $property->getName() . " = $v;"; + return '$table->' . $property->getName()->value . " = $v;"; } /** @@ -178,6 +175,6 @@ private function methodToString(Method $method): string private function flattenMethod(Method $method): string { $v = (new Collection($method->getValues()))->map(fn ($v) => $this->convertFromAnyTypeToString($v))->implode(', '); - return $method->getName() . "($v)"; + return $method->getName()->value . "($v)"; } } diff --git a/src/Migration/Blueprint/WritableBlueprint.php b/src/Migration/Blueprint/WritableBlueprint.php index 92a8f5c3..21b2624e 100644 --- a/src/Migration/Blueprint/WritableBlueprint.php +++ b/src/Migration/Blueprint/WritableBlueprint.php @@ -4,5 +4,8 @@ interface WritableBlueprint { + /** + * Convert the object to its string representation. + */ public function toString(): string; } diff --git a/src/Migration/Enum/MigrationFileType.php b/src/Migration/Enum/MigrationFileType.php index 50bec1aa..bd579d13 100644 --- a/src/Migration/Enum/MigrationFileType.php +++ b/src/Migration/Enum/MigrationFileType.php @@ -2,19 +2,10 @@ namespace KitLoong\MigrationsGenerator\Migration\Enum; -use MyCLabs\Enum\Enum; - -/** - * @method static self FOREIGN_KEY() - * @method static self TABLE() - * @method static self VIEW() - * @method static self PROCEDURE() - * @extends \MyCLabs\Enum\Enum - */ -final class MigrationFileType extends Enum +enum MigrationFileType: string { - private const FOREIGN_KEY = 'foreign_key'; - private const TABLE = 'table'; - private const VIEW = 'view'; - private const PROCEDURE = 'procedure'; + case FOREIGN_KEY = 'foreign_key'; + case TABLE = 'table'; + case VIEW = 'view'; + case PROCEDURE = 'procedure'; } diff --git a/src/Migration/Enum/Space.php b/src/Migration/Enum/Space.php index c7d87088..acf4e713 100644 --- a/src/Migration/Enum/Space.php +++ b/src/Migration/Enum/Space.php @@ -2,15 +2,8 @@ namespace KitLoong\MigrationsGenerator\Migration\Enum; -use MyCLabs\Enum\Enum; - -/** - * @method static self LINE_BREAK() - * @method static self TAB() - * @extends \MyCLabs\Enum\Enum - */ -final class Space extends Enum +enum Space: string { - private const LINE_BREAK = PHP_EOL; - private const TAB = ' '; // 4 spaces tab + case LINE_BREAK = "\n"; + case TAB = ' '; // 4 spaces tab } diff --git a/src/Migration/ForeignKeyMigration.php b/src/Migration/ForeignKeyMigration.php index ec280a54..95d86843 100644 --- a/src/Migration/ForeignKeyMigration.php +++ b/src/Migration/ForeignKeyMigration.php @@ -44,7 +44,7 @@ public function write(string $table, Collection $foreignKeys): string $this->makeMigrationClassName($table), new Collection([$up]), new Collection([$down]), - MigrationFileType::FOREIGN_KEY(), + MigrationFileType::FOREIGN_KEY, ); return $path; @@ -136,7 +136,7 @@ private function getSchemaBlueprint(string $table): SchemaBlueprint { return new SchemaBlueprint( $table, - SchemaBuilder::TABLE(), + SchemaBuilder::TABLE, ); } } diff --git a/src/Migration/Generator/ColumnGenerator.php b/src/Migration/Generator/ColumnGenerator.php index 9122750c..518fcb44 100644 --- a/src/Migration/Generator/ColumnGenerator.php +++ b/src/Migration/Generator/ColumnGenerator.php @@ -52,7 +52,7 @@ public function generate(Table $table, Column $column, Collection $chainableInde private function createMethodFromColumn(Table $table, Column $column): Method { /** @var \KitLoong\MigrationsGenerator\Migration\Generator\Columns\ColumnTypeGenerator $generator */ - $generator = app(ColumnType::class . '\\' . $column->getType()->getKey()); + $generator = app(ColumnType::class . '\\' . $column->getType()->name); return $generator->generate($table, $column); } } diff --git a/src/Migration/Generator/Columns/BooleanColumn.php b/src/Migration/Generator/Columns/BooleanColumn.php index 91293b1f..2dc7ef9e 100644 --- a/src/Migration/Generator/Columns/BooleanColumn.php +++ b/src/Migration/Generator/Columns/BooleanColumn.php @@ -17,7 +17,7 @@ public function generate(Table $table, Column $column): Method $method = new Method($column->getType(), $column->getName()); if ($column->isUnsigned()) { - $method->chain(ColumnModifier::UNSIGNED()); + $method->chain(ColumnModifier::UNSIGNED); } return $method; diff --git a/src/Migration/Generator/Columns/DatetimeColumn.php b/src/Migration/Generator/Columns/DatetimeColumn.php index 9b22f467..275ace1a 100644 --- a/src/Migration/Generator/Columns/DatetimeColumn.php +++ b/src/Migration/Generator/Columns/DatetimeColumn.php @@ -19,7 +19,7 @@ public function generate(Table $table, Column $column): Method $method = $this->makeMethod($column); if ($column->isOnUpdateCurrentTimestamp()) { - $method->chain(ColumnModifier::USE_CURRENT_ON_UPDATE()); + $method->chain(ColumnModifier::USE_CURRENT_ON_UPDATE); } return $method; diff --git a/src/Migration/Generator/Columns/DecimalColumn.php b/src/Migration/Generator/Columns/DecimalColumn.php index f13500de..aa4de31c 100644 --- a/src/Migration/Generator/Columns/DecimalColumn.php +++ b/src/Migration/Generator/Columns/DecimalColumn.php @@ -23,7 +23,7 @@ public function generate(Table $table, Column $column): Method $method = new Method($column->getType(), $column->getName(), ...$precisions); if ($column->isUnsigned()) { - $method->chain(ColumnModifier::UNSIGNED()); + $method->chain(ColumnModifier::UNSIGNED); } return $method; diff --git a/src/Migration/Generator/Columns/DoubleColumn.php b/src/Migration/Generator/Columns/DoubleColumn.php index 368ed386..9ec49110 100644 --- a/src/Migration/Generator/Columns/DoubleColumn.php +++ b/src/Migration/Generator/Columns/DoubleColumn.php @@ -25,7 +25,7 @@ public function generate(Table $table, Column $column): Method $method = new Method($column->getType(), $column->getName(), ...$precisions); if ($column->isUnsigned()) { - $method->chain(ColumnModifier::UNSIGNED()); + $method->chain(ColumnModifier::UNSIGNED); } return $method; diff --git a/src/Migration/Generator/Columns/FloatColumn.php b/src/Migration/Generator/Columns/FloatColumn.php index 6d2b1d18..592505ff 100644 --- a/src/Migration/Generator/Columns/FloatColumn.php +++ b/src/Migration/Generator/Columns/FloatColumn.php @@ -28,7 +28,7 @@ public function generate(Table $table, Column $column): Method $method = new Method($column->getType(), $column->getName(), ...$precisions); if ($column->isUnsigned()) { - $method->chain(ColumnModifier::UNSIGNED()); + $method->chain(ColumnModifier::UNSIGNED); } return $method; diff --git a/src/Migration/Generator/Columns/SoftDeleteColumn.php b/src/Migration/Generator/Columns/SoftDeleteColumn.php index edc963b1..95121ae4 100644 --- a/src/Migration/Generator/Columns/SoftDeleteColumn.php +++ b/src/Migration/Generator/Columns/SoftDeleteColumn.php @@ -19,7 +19,7 @@ public function generate(Table $table, Column $column): Method $method = $this->makeMethod($column); if ($column->isOnUpdateCurrentTimestamp()) { - $method->chain(ColumnModifier::USE_CURRENT_ON_UPDATE()); + $method->chain(ColumnModifier::USE_CURRENT_ON_UPDATE); } return $method; diff --git a/src/Migration/Generator/Columns/SpatialColumn.php b/src/Migration/Generator/Columns/SpatialColumn.php index 2ea34d65..beec1fb2 100644 --- a/src/Migration/Generator/Columns/SpatialColumn.php +++ b/src/Migration/Generator/Columns/SpatialColumn.php @@ -22,8 +22,8 @@ class SpatialColumn implements ColumnTypeGenerator public function generate(Table $table, Column $column): Method { if (!$this->hasGeography()) { - if ($column->getType()->equals(ColumnType::GEOGRAPHY())) { - return new Method(ColumnType::GEOMETRY(), $column->getName()); + if ($column->getType() === ColumnType::GEOGRAPHY) { + return new Method(ColumnType::GEOMETRY, $column->getName()); } return new Method($column->getType(), $column->getName()); @@ -59,7 +59,7 @@ private function getSrIDArg(Column $column): ?int } switch ($column->getType()) { - case ColumnType::GEOMETRY(): + case ColumnType::GEOMETRY: if ($column->getSpatialSrID() !== self::GEOMETRY_DEFAULT_SRID) { return $column->getSpatialSrID(); } diff --git a/src/Migration/Generator/ForeignKeyGenerator.php b/src/Migration/Generator/ForeignKeyGenerator.php index c1c2cc44..d83b78e8 100644 --- a/src/Migration/Generator/ForeignKeyGenerator.php +++ b/src/Migration/Generator/ForeignKeyGenerator.php @@ -19,15 +19,15 @@ public function generate(ForeignKey $foreignKey): Method { $method = $this->makeMethod($foreignKey); - $method->chain(Foreign::REFERENCES(), $foreignKey->getForeignColumns()) - ->chain(Foreign::ON(), $this->stripTablePrefix($foreignKey->getForeignTableName())); + $method->chain(Foreign::REFERENCES, $foreignKey->getForeignColumns()) + ->chain(Foreign::ON, $this->stripTablePrefix($foreignKey->getForeignTableName())); if ($foreignKey->getOnUpdate() !== null) { - $method->chain(Foreign::ON_UPDATE(), $foreignKey->getOnUpdate()); + $method->chain(Foreign::ON_UPDATE, $foreignKey->getOnUpdate()); } if ($foreignKey->getOnDelete() !== null) { - $method->chain(Foreign::ON_DELETE(), $foreignKey->getOnDelete()); + $method->chain(Foreign::ON_DELETE, $foreignKey->getOnDelete()); } return $method; @@ -39,10 +39,10 @@ public function generate(ForeignKey $foreignKey): Method public function generateDrop(ForeignKey $foreignKey): Method { if ($this->shouldSkipName($foreignKey)) { - return new Method(Foreign::DROP_FOREIGN(), $this->makeLaravelForeignKeyName($foreignKey)); + return new Method(Foreign::DROP_FOREIGN, $this->makeLaravelForeignKeyName($foreignKey)); } - return new Method(Foreign::DROP_FOREIGN(), $foreignKey->getName()); + return new Method(Foreign::DROP_FOREIGN, $foreignKey->getName()); } /** @@ -51,10 +51,10 @@ public function generateDrop(ForeignKey $foreignKey): Method public function makeMethod(ForeignKey $foreignKey): Method { if ($this->shouldSkipName($foreignKey)) { - return new Method(Foreign::FOREIGN(), $foreignKey->getLocalColumns()); + return new Method(Foreign::FOREIGN, $foreignKey->getLocalColumns()); } - return new Method(Foreign::FOREIGN(), $foreignKey->getLocalColumns(), $foreignKey->getName()); + return new Method(Foreign::FOREIGN, $foreignKey->getLocalColumns(), $foreignKey->getName()); } /** diff --git a/src/Migration/Generator/IndexGenerator.php b/src/Migration/Generator/IndexGenerator.php index c93dae42..2504dc3b 100644 --- a/src/Migration/Generator/IndexGenerator.php +++ b/src/Migration/Generator/IndexGenerator.php @@ -55,7 +55,7 @@ public function getChainableIndexes(string $name, Collection $indexes): Collecti // Check if index is using framework default naming. // The older version "spatialIndex" modifier does not accept index name as argument. if ( - $index->getType()->equals(IndexType::SPATIAL_INDEX()) + $index->getType() === IndexType::SPATIAL_INDEX && !$this->indexNameHelper->shouldSkipName($name, $index) ) { return $carry; @@ -63,7 +63,7 @@ public function getChainableIndexes(string $name, Collection $indexes): Collecti // If name is not empty, primary name should be set explicitly. if ( - $index->getType()->equals(IndexType::PRIMARY()) + $index->getType() === IndexType::PRIMARY && $index->getName() !== '' ) { return $carry; diff --git a/src/Migration/Generator/Modifiers/CharsetModifier.php b/src/Migration/Generator/Modifiers/CharsetModifier.php index c4912b1e..e008d2f8 100644 --- a/src/Migration/Generator/Modifiers/CharsetModifier.php +++ b/src/Migration/Generator/Modifiers/CharsetModifier.php @@ -31,7 +31,7 @@ public function chain(Method $method, Table $table, Column $column, mixed ...$ar $charset = $column->getCharset(); if ($charset !== null && $charset !== $tableCharset) { - $method->chain(ColumnModifier::CHARSET(), $charset); + $method->chain(ColumnModifier::CHARSET, $charset); } return $method; diff --git a/src/Migration/Generator/Modifiers/CollationModifier.php b/src/Migration/Generator/Modifiers/CollationModifier.php index 9d1cc871..b7b5bf50 100644 --- a/src/Migration/Generator/Modifiers/CollationModifier.php +++ b/src/Migration/Generator/Modifiers/CollationModifier.php @@ -29,7 +29,7 @@ public function chain(Method $method, Table $table, Column $column, mixed ...$ar $collation = $column->getCollation(); if ($collation !== null && $collation !== $tableCollation) { - $method->chain(ColumnModifier::COLLATION(), $collation); + $method->chain(ColumnModifier::COLLATION, $collation); } return $method; diff --git a/src/Migration/Generator/Modifiers/CommentModifier.php b/src/Migration/Generator/Modifiers/CommentModifier.php index e1b0e17e..65a393d2 100644 --- a/src/Migration/Generator/Modifiers/CommentModifier.php +++ b/src/Migration/Generator/Modifiers/CommentModifier.php @@ -15,7 +15,7 @@ class CommentModifier implements Modifier public function chain(Method $method, Table $table, Column $column, mixed ...$args): Method { if ($column->getComment() !== null) { - $method->chain(ColumnModifier::COMMENT(), $column->getComment()); + $method->chain(ColumnModifier::COMMENT, $column->getComment()); } return $method; diff --git a/src/Migration/Generator/Modifiers/DefaultModifier.php b/src/Migration/Generator/Modifiers/DefaultModifier.php index a1e43d3f..22c48ad4 100644 --- a/src/Migration/Generator/Modifiers/DefaultModifier.php +++ b/src/Migration/Generator/Modifiers/DefaultModifier.php @@ -20,47 +20,47 @@ public function __construct() { foreach ( [ - ColumnType::BIG_INTEGER(), - ColumnType::INTEGER(), - ColumnType::MEDIUM_INTEGER(), - ColumnType::SMALL_INTEGER(), - ColumnType::TINY_INTEGER(), - ColumnType::UNSIGNED_BIG_INTEGER(), - ColumnType::UNSIGNED_INTEGER(), - ColumnType::UNSIGNED_MEDIUM_INTEGER(), - ColumnType::UNSIGNED_SMALL_INTEGER(), - ColumnType::UNSIGNED_TINY_INTEGER(), + ColumnType::BIG_INTEGER, + ColumnType::INTEGER, + ColumnType::MEDIUM_INTEGER, + ColumnType::SMALL_INTEGER, + ColumnType::TINY_INTEGER, + ColumnType::UNSIGNED_BIG_INTEGER, + ColumnType::UNSIGNED_INTEGER, + ColumnType::UNSIGNED_MEDIUM_INTEGER, + ColumnType::UNSIGNED_SMALL_INTEGER, + ColumnType::UNSIGNED_TINY_INTEGER, ] as $columnType ) { - $this->chainerMap[$columnType->getValue()] = fn (Method $method, Column $column): Method => call_user_func([$this, 'chainDefaultForInteger'], $method, $column); + $this->chainerMap[$columnType->value] = fn (Method $method, Column $column): Method => call_user_func([$this, 'chainDefaultForInteger'], $method, $column); } foreach ( [ - ColumnType::DECIMAL(), - ColumnType::FLOAT(), - ColumnType::DOUBLE(), + ColumnType::DECIMAL, + ColumnType::FLOAT, + ColumnType::DOUBLE, ] as $columnType ) { - $this->chainerMap[$columnType->getValue()] = fn (Method $method, Column $column): Method => call_user_func([$this, 'chainDefaultForDecimal'], $method, $column); + $this->chainerMap[$columnType->value] = fn (Method $method, Column $column): Method => call_user_func([$this, 'chainDefaultForDecimal'], $method, $column); } - $this->chainerMap[ColumnType::BOOLEAN()->getValue()] = fn (Method $method, Column $column): Method => call_user_func([$this, 'chainDefaultForBoolean'], $method, $column); + $this->chainerMap[ColumnType::BOOLEAN->value] = fn (Method $method, Column $column): Method => call_user_func([$this, 'chainDefaultForBoolean'], $method, $column); foreach ( [ - ColumnType::SOFT_DELETES(), - ColumnType::SOFT_DELETES_TZ(), - ColumnType::DATE(), - ColumnType::DATETIME(), - ColumnType::DATETIME_TZ(), - ColumnType::TIME(), - ColumnType::TIME_TZ(), - ColumnType::TIMESTAMP(), - ColumnType::TIMESTAMP_TZ(), + ColumnType::SOFT_DELETES, + ColumnType::SOFT_DELETES_TZ, + ColumnType::DATE, + ColumnType::DATETIME, + ColumnType::DATETIME_TZ, + ColumnType::TIME, + ColumnType::TIME_TZ, + ColumnType::TIMESTAMP, + ColumnType::TIMESTAMP_TZ, ] as $columnType ) { - $this->chainerMap[$columnType->getValue()] = fn (Method $method, Column $column): Method => call_user_func([$this, 'chainDefaultForDatetime'], $method, $column); + $this->chainerMap[$columnType->value] = fn (Method $method, Column $column): Method => call_user_func([$this, 'chainDefaultForDatetime'], $method, $column); } } @@ -73,8 +73,8 @@ public function chain(Method $method, Table $table, Column $column, mixed ...$ar return $method; } - if (isset($this->chainerMap[$column->getType()->getValue()])) { - return $this->chainerMap[$column->getType()->getValue()]($method, $column); + if (isset($this->chainerMap[$column->getType()->value])) { + return $this->chainerMap[$column->getType()->value]($method, $column); } return $this->chainDefaultForString($method, $column); @@ -85,7 +85,7 @@ public function chain(Method $method, Table $table, Column $column, mixed ...$ar */ protected function chainDefaultForInteger(Method $method, Column $column): Method { - $method->chain(ColumnModifier::DEFAULT(), (int) $column->getDefault()); + $method->chain(ColumnModifier::DEFAULT, (int) $column->getDefault()); return $method; } @@ -94,7 +94,7 @@ protected function chainDefaultForInteger(Method $method, Column $column): Metho */ protected function chainDefaultForDecimal(Method $method, Column $column): Method { - $method->chain(ColumnModifier::DEFAULT(), (float) $column->getDefault()); + $method->chain(ColumnModifier::DEFAULT, (float) $column->getDefault()); return $method; } @@ -108,7 +108,7 @@ protected function chainDefaultForBoolean(Method $method, Column $column): Metho default => false, }; - $method->chain(ColumnModifier::DEFAULT(), $default); + $method->chain(ColumnModifier::DEFAULT, $default); return $method; } @@ -119,7 +119,7 @@ protected function chainDefaultForDatetime(Method $method, Column $column): Meth { switch ($column->getDefault()) { case 'CURRENT_TIMESTAMP': - $method->chain(ColumnModifier::USE_CURRENT()); + $method->chain(ColumnModifier::USE_CURRENT); break; default: @@ -131,7 +131,7 @@ protected function chainDefaultForDatetime(Method $method, Column $column): Meth $default = DB::raw($default); } - $method->chain(ColumnModifier::DEFAULT(), $default); + $method->chain(ColumnModifier::DEFAULT, $default); } return $method; @@ -142,7 +142,7 @@ protected function chainDefaultForDatetime(Method $method, Column $column): Meth */ protected function chainDefaultForString(Method $method, Column $column): Method { - $method->chain(ColumnModifier::DEFAULT(), $column->getDefault()); + $method->chain(ColumnModifier::DEFAULT, $column->getDefault()); return $method; } diff --git a/src/Migration/Generator/Modifiers/IndexModifier.php b/src/Migration/Generator/Modifiers/IndexModifier.php index 105f75a8..e0074159 100644 --- a/src/Migration/Generator/Modifiers/IndexModifier.php +++ b/src/Migration/Generator/Modifiers/IndexModifier.php @@ -30,7 +30,7 @@ public function chain(Method $method, Table $table, Column $column, mixed ...$ar $index = $chainableIndexes->get($column->getName()); // "increment" will add primary key by default. No need explicitly declare "primary" index here. - if ($column->isAutoincrement() && $index->getType()->equals(IndexType::PRIMARY())) { + if ($column->isAutoincrement() && $index->getType() === IndexType::PRIMARY) { return $method; } @@ -51,8 +51,8 @@ public function chain(Method $method, Table $table, Column $column, mixed ...$ar */ private function adjustIndexType(IndexType $indexType): IndexType { - if ($indexType->equals(IndexType::FULLTEXT())) { - return IndexType::FULLTEXT_CHAIN(); + if ($indexType === IndexType::FULLTEXT) { + return IndexType::FULLTEXT_CHAIN; } return $indexType; diff --git a/src/Migration/Generator/Modifiers/NullableModifier.php b/src/Migration/Generator/Modifiers/NullableModifier.php index 570c3403..75cf70c1 100644 --- a/src/Migration/Generator/Modifiers/NullableModifier.php +++ b/src/Migration/Generator/Modifiers/NullableModifier.php @@ -17,14 +17,14 @@ public function chain(Method $method, Table $table, Column $column, mixed ...$ar { if ($column->isNotNull()) { if ($this->shouldAddNotNullModifier($column->getType())) { - $method->chain(ColumnModifier::NULLABLE(), false); + $method->chain(ColumnModifier::NULLABLE, false); } return $method; } if ($this->shouldAddNullableModifier($column->getType())) { - $method->chain(ColumnModifier::NULLABLE()); + $method->chain(ColumnModifier::NULLABLE); } return $method; @@ -39,10 +39,10 @@ private function shouldAddNullableModifier(ColumnType $columnType): bool return !in_array( $columnType, [ - ColumnType::SOFT_DELETES(), - ColumnType::SOFT_DELETES_TZ(), - ColumnType::REMEMBER_TOKEN(), - ColumnType::TIMESTAMPS(), + ColumnType::SOFT_DELETES, + ColumnType::SOFT_DELETES_TZ, + ColumnType::REMEMBER_TOKEN, + ColumnType::TIMESTAMPS, ], ); } @@ -56,9 +56,9 @@ private function shouldAddNotNullModifier(ColumnType $columnType): bool return in_array( $columnType, [ - ColumnType::SOFT_DELETES(), - ColumnType::SOFT_DELETES_TZ(), - ColumnType::REMEMBER_TOKEN(), + ColumnType::SOFT_DELETES, + ColumnType::SOFT_DELETES_TZ, + ColumnType::REMEMBER_TOKEN, ], ); } diff --git a/src/Migration/Generator/Modifiers/StoredAsModifier.php b/src/Migration/Generator/Modifiers/StoredAsModifier.php index 0111df75..d469e7b3 100644 --- a/src/Migration/Generator/Modifiers/StoredAsModifier.php +++ b/src/Migration/Generator/Modifiers/StoredAsModifier.php @@ -15,7 +15,7 @@ class StoredAsModifier implements Modifier public function chain(Method $method, Table $table, Column $column, mixed ...$args): Method { if ($column->getStoredDefinition() !== null) { - $method->chain(ColumnModifier::STORED_AS(), $column->getStoredDefinition()); + $method->chain(ColumnModifier::STORED_AS, $column->getStoredDefinition()); } return $method; diff --git a/src/Migration/Generator/Modifiers/VirtualAsModifier.php b/src/Migration/Generator/Modifiers/VirtualAsModifier.php index 449d278e..5d306ec9 100644 --- a/src/Migration/Generator/Modifiers/VirtualAsModifier.php +++ b/src/Migration/Generator/Modifiers/VirtualAsModifier.php @@ -15,7 +15,7 @@ class VirtualAsModifier implements Modifier public function chain(Method $method, Table $table, Column $column, mixed ...$args): Method { if ($column->getVirtualDefinition() !== null) { - $method->chain(ColumnModifier::VIRTUAL_AS(), $column->getVirtualDefinition()); + $method->chain(ColumnModifier::VIRTUAL_AS, $column->getVirtualDefinition()); } return $method; diff --git a/src/Migration/ProcedureMigration.php b/src/Migration/ProcedureMigration.php index 7c73fff3..b229ec5c 100644 --- a/src/Migration/ProcedureMigration.php +++ b/src/Migration/ProcedureMigration.php @@ -37,7 +37,7 @@ public function write(Procedure $procedure): string $this->makeMigrationClassName($procedure->getName()), new Collection([$up]), new Collection([$down]), - MigrationFileType::PROCEDURE(), + MigrationFileType::PROCEDURE, ); return $path; diff --git a/src/Migration/TableMigration.php b/src/Migration/TableMigration.php index 76042438..a1a141c7 100644 --- a/src/Migration/TableMigration.php +++ b/src/Migration/TableMigration.php @@ -63,7 +63,7 @@ public function write(Table $table): string $this->makeMigrationClassName($table->getName()), $upList, new Collection([$down]), - MigrationFileType::TABLE(), + MigrationFileType::TABLE, ); return $path; @@ -93,7 +93,7 @@ public function writeToTemp(Table $table): void */ private function up(Table $table): SchemaBlueprint { - $up = $this->getSchemaBlueprint($table, SchemaBuilder::CREATE()); + $up = $this->getSchemaBlueprint($table, SchemaBuilder::CREATE); $blueprint = new TableBlueprint(); @@ -103,7 +103,7 @@ private function up(Table $table): SchemaBlueprint } if ($this->hasTableComment() && $table->getComment() !== null && $table->getComment() !== '') { - $blueprint->setMethod(new Method(TableMethod::COMMENT(), $table->getComment())); + $blueprint->setMethod(new Method(TableMethod::COMMENT, $table->getComment())); } $chainableIndexes = $this->indexGenerator->getChainableIndexes($table->getName(), $table->getIndexes()); @@ -153,7 +153,7 @@ private function upAdditionalStatements(Table $table): array */ private function down(Table $table): SchemaBlueprint { - return $this->getSchemaBlueprint($table, SchemaBuilder::DROP_IF_EXISTS()); + return $this->getSchemaBlueprint($table, SchemaBuilder::DROP_IF_EXISTS); } /** @@ -190,7 +190,7 @@ private function makeMigrationPath(string $table): string */ private function shouldSetCharset(): bool { - if (DB::getDriverName() !== Driver::MYSQL()->getValue()) { + if (DB::getDriverName() !== Driver::MYSQL->value) { return false; } @@ -200,7 +200,7 @@ private function shouldSetCharset(): bool private function setTableCharset(TableBlueprint $blueprint, Table $table): TableBlueprint { $blueprint->setProperty( - TableProperty::COLLATION(), + TableProperty::COLLATION, $collation = $table->getCollation(), ); @@ -209,7 +209,7 @@ private function setTableCharset(TableBlueprint $blueprint, Table $table): Table } $charset = Str::before($collation, '_'); - $blueprint->setProperty(TableProperty::CHARSET(), $charset); + $blueprint->setProperty(TableProperty::CHARSET, $charset); return $blueprint; } diff --git a/src/Migration/ViewMigration.php b/src/Migration/ViewMigration.php index d237666e..214cab2c 100644 --- a/src/Migration/ViewMigration.php +++ b/src/Migration/ViewMigration.php @@ -40,7 +40,7 @@ public function write(View $view): string $this->makeMigrationClassName($view->getName()), new Collection([$up]), new Collection([$down]), - MigrationFileType::VIEW(), + MigrationFileType::VIEW, ); return $path; diff --git a/src/Migration/Writer/MigrationWriter.php b/src/Migration/Writer/MigrationWriter.php index 73aaab50..77235903 100644 --- a/src/Migration/Writer/MigrationWriter.php +++ b/src/Migration/Writer/MigrationWriter.php @@ -44,7 +44,7 @@ public function writeTo( $useDBFacade = true; } - $use = implode(Space::LINE_BREAK(), $this->getNamespaces($migrationFileType, $useDBFacade)); + $use = implode(Space::LINE_BREAK->value, $this->getNamespaces($migrationFileType, $useDBFacade)); // Create directory if it doesn't exist $directory = dirname($path); @@ -68,8 +68,8 @@ public function writeTo( private function getNamespaces(MigrationFileType $migrationFileType, bool $useDBFacade): array { if ( - $migrationFileType->equals(MigrationFileType::VIEW()) - || $migrationFileType->equals(MigrationFileType::PROCEDURE()) + $migrationFileType === MigrationFileType::VIEW + || $migrationFileType === MigrationFileType::PROCEDURE ) { return [ 'use Illuminate\Database\Migrations\Migration;', @@ -99,6 +99,6 @@ private function getNamespaces(MigrationFileType $migrationFileType, bool $useDB */ private function prettifyToString(Collection $blueprints): string { - return $blueprints->map(static fn (WritableBlueprint $blueprint) => $blueprint->toString())->implode(Space::LINE_BREAK() . Space::TAB() . Space::TAB()); // Add tab to prettify + return $blueprints->map(static fn (WritableBlueprint $blueprint) => $blueprint->toString())->implode(Space::LINE_BREAK->value . Space::TAB->value . Space::TAB->value); // Add tab to prettify } } diff --git a/src/Migration/Writer/SquashWriter.php b/src/Migration/Writer/SquashWriter.php index 6d36268e..f5b93764 100644 --- a/src/Migration/Writer/SquashWriter.php +++ b/src/Migration/Writer/SquashWriter.php @@ -27,12 +27,12 @@ public function writeToTemp(Collection $upBlueprints, Collection $downBlueprints { $upTempPath = $this->migrationNameHelper->makeUpTempPath(); $prettySpace = $this->getSpaceIfFileExists($upTempPath); - $upString = $upBlueprints->map(static fn (WritableBlueprint $up) => $up->toString())->implode(Space::LINE_BREAK() . Space::TAB() . Space::TAB()); // Add tab to prettify + $upString = $upBlueprints->map(static fn (WritableBlueprint $up) => $up->toString())->implode(Space::LINE_BREAK->value . Space::TAB->value . Space::TAB->value); // Add tab to prettify File::append($upTempPath, $prettySpace . $upString); $downTempPath = $this->migrationNameHelper->makeDownTempPath(); $prettySpace = $this->getSpaceIfFileExists($downTempPath); - $downString = $downBlueprints->map(static fn (WritableBlueprint $down) => $down->toString())->implode(Space::LINE_BREAK() . Space::TAB() . Space::TAB()); // Add tab to prettify + $downString = $downBlueprints->map(static fn (WritableBlueprint $down) => $down->toString())->implode(Space::LINE_BREAK->value . Space::TAB->value . Space::TAB->value); // Add tab to prettify File::prepend($downTempPath, $downString . $prettySpace); } @@ -53,7 +53,7 @@ public function cleanTemps(): void */ public function squashMigrations(string $path, string $stubPath, string $className): void { - $use = implode(Space::LINE_BREAK(), [ + $use = implode(Space::LINE_BREAK->value, [ 'use Illuminate\Database\Migrations\Migration;', 'use Illuminate\Database\Schema\Blueprint;', 'use Illuminate\Support\Facades\DB;', @@ -88,6 +88,6 @@ private function getSpaceIfFileExists(string $path): string return ''; } - return Space::LINE_BREAK() . Space::LINE_BREAK() . Space::TAB() . Space::TAB(); + return Space::LINE_BREAK->value . Space::LINE_BREAK->value . Space::TAB->value . Space::TAB->value; } } diff --git a/src/MigrationsGeneratorServiceProvider.php b/src/MigrationsGeneratorServiceProvider.php index 37eb5dca..881c779e 100644 --- a/src/MigrationsGeneratorServiceProvider.php +++ b/src/MigrationsGeneratorServiceProvider.php @@ -112,7 +112,7 @@ protected function registerConfig(): void */ protected function columnTypeSingleton(ColumnType $type, string $columnTypeGenerator): void { - $this->app->singleton(ColumnType::class . '\\' . $type->getKey(), $columnTypeGenerator); + $this->app->singleton(ColumnType::class . '\\' . $type->name, $columnTypeGenerator); } /** @@ -120,17 +120,17 @@ protected function columnTypeSingleton(ColumnType $type, string $columnTypeGener */ protected function registerColumnTypeGenerator(): void { - foreach (ColumnType::values() as $columnType) { + foreach (ColumnType::cases() as $columnType) { $this->columnTypeSingleton($columnType, MiscColumn::class); } foreach ( [ - ColumnType::BIG_INTEGER(), - ColumnType::INTEGER(), - ColumnType::MEDIUM_INTEGER(), - ColumnType::SMALL_INTEGER(), - ColumnType::TINY_INTEGER(), + ColumnType::BIG_INTEGER, + ColumnType::INTEGER, + ColumnType::MEDIUM_INTEGER, + ColumnType::SMALL_INTEGER, + ColumnType::TINY_INTEGER, ] as $columnType ) { $this->columnTypeSingleton($columnType, IntegerColumn::class); @@ -138,13 +138,13 @@ protected function registerColumnTypeGenerator(): void foreach ( [ - ColumnType::DATE(), - ColumnType::DATETIME(), - ColumnType::DATETIME_TZ(), - ColumnType::TIME(), - ColumnType::TIME_TZ(), - ColumnType::TIMESTAMP(), - ColumnType::TIMESTAMP_TZ(), + ColumnType::DATE, + ColumnType::DATETIME, + ColumnType::DATETIME_TZ, + ColumnType::TIME, + ColumnType::TIME_TZ, + ColumnType::TIMESTAMP, + ColumnType::TIMESTAMP_TZ, ] as $columnType ) { $this->columnTypeSingleton($columnType, DatetimeColumn::class); @@ -152,8 +152,8 @@ protected function registerColumnTypeGenerator(): void foreach ( [ - ColumnType::SOFT_DELETES(), - ColumnType::SOFT_DELETES_TZ(), + ColumnType::SOFT_DELETES, + ColumnType::SOFT_DELETES_TZ, ] as $columnType ) { $this->columnTypeSingleton($columnType, SoftDeleteColumn::class); @@ -161,7 +161,7 @@ protected function registerColumnTypeGenerator(): void foreach ( [ - ColumnType::DECIMAL(), + ColumnType::DECIMAL, ] as $columnType ) { $this->columnTypeSingleton($columnType, DecimalColumn::class); @@ -169,8 +169,8 @@ protected function registerColumnTypeGenerator(): void foreach ( [ - ColumnType::ENUM(), - ColumnType::SET(), + ColumnType::ENUM, + ColumnType::SET, ] as $columnType ) { $this->columnTypeSingleton($columnType, PresetValuesColumn::class); @@ -178,8 +178,8 @@ protected function registerColumnTypeGenerator(): void foreach ( [ - ColumnType::CHAR(), - ColumnType::STRING(), + ColumnType::CHAR, + ColumnType::STRING, ] as $columnType ) { $this->columnTypeSingleton($columnType, StringColumn::class); @@ -187,23 +187,23 @@ protected function registerColumnTypeGenerator(): void foreach ( [ - ColumnType::GEOGRAPHY(), - ColumnType::GEOMETRY(), - ColumnType::GEOMETRY_COLLECTION(), - ColumnType::LINE_STRING(), - ColumnType::MULTI_LINE_STRING(), - ColumnType::POINT(), - ColumnType::MULTI_POINT(), - ColumnType::MULTI_POLYGON(), - ColumnType::POLYGON(), + ColumnType::GEOGRAPHY, + ColumnType::GEOMETRY, + ColumnType::GEOMETRY_COLLECTION, + ColumnType::LINE_STRING, + ColumnType::MULTI_LINE_STRING, + ColumnType::POINT, + ColumnType::MULTI_POINT, + ColumnType::MULTI_POLYGON, + ColumnType::POLYGON, ] as $columnType ) { $this->columnTypeSingleton($columnType, SpatialColumn::class); } - $this->columnTypeSingleton(ColumnType::BOOLEAN(), BooleanColumn::class); - $this->columnTypeSingleton(ColumnType::DOUBLE(), DoubleColumn::class); - $this->columnTypeSingleton(ColumnType::FLOAT(), FloatColumn::class); - $this->columnTypeSingleton(ColumnType::REMEMBER_TOKEN(), OmitNameColumn::class); + $this->columnTypeSingleton(ColumnType::BOOLEAN, BooleanColumn::class); + $this->columnTypeSingleton(ColumnType::DOUBLE, DoubleColumn::class); + $this->columnTypeSingleton(ColumnType::FLOAT, FloatColumn::class); + $this->columnTypeSingleton(ColumnType::REMEMBER_TOKEN, OmitNameColumn::class); } } diff --git a/src/Support/AssetNameQuote.php b/src/Support/AssetNameQuote.php index 0e1ad87b..6c09d797 100644 --- a/src/Support/AssetNameQuote.php +++ b/src/Support/AssetNameQuote.php @@ -29,10 +29,10 @@ public function trimQuotes(string $identifier): string public function quoteIdentifier(string $value): string { switch (DB::getDriverName()) { - case Driver::SQLSRV(): + case Driver::SQLSRV->value: return $value === '*' ? $value : '[' . str_replace(']', ']]', $value) . ']'; - case Driver::MYSQL(): + case Driver::MYSQL->value: return $value === '*' ? $value : '`' . str_replace('`', '``', $value) . '`'; default: diff --git a/src/Support/IndexNameHelper.php b/src/Support/IndexNameHelper.php index 27233293..34a05695 100644 --- a/src/Support/IndexNameHelper.php +++ b/src/Support/IndexNameHelper.php @@ -25,13 +25,13 @@ public function shouldSkipName(string $table, Index $index): bool } if ( - $index->getType()->equals(IndexType::PRIMARY()) + $index->getType() === IndexType::PRIMARY && $index->getName() === '' ) { return true; } - $indexName = strtolower($table . '_' . implode('_', $index->getColumns()) . '_' . $index->getType()); + $indexName = strtolower($table . '_' . implode('_', $index->getColumns()) . '_' . $index->getType()->value); $indexName = (string) str_replace(['-', '.'], '_', $indexName); return $indexName === $index->getName(); } diff --git a/tests/MigrationWriterTest.php b/tests/MigrationWriterTest.php index 67c88ef9..1fdd338d 100644 --- a/tests/MigrationWriterTest.php +++ b/tests/MigrationWriterTest.php @@ -4,7 +4,10 @@ use Illuminate\Support\Collection; use Illuminate\Support\Facades\DB; +use KitLoong\MigrationsGenerator\Enum\Migrations\Method\ColumnModifier; +use KitLoong\MigrationsGenerator\Enum\Migrations\Method\ColumnType; use KitLoong\MigrationsGenerator\Enum\Migrations\Method\SchemaBuilder; +use KitLoong\MigrationsGenerator\Enum\Migrations\Property\TableProperty; use KitLoong\MigrationsGenerator\Migration\Blueprint\SchemaBlueprint; use KitLoong\MigrationsGenerator\Migration\Blueprint\TableBlueprint; use KitLoong\MigrationsGenerator\Migration\Enum\MigrationFileType; @@ -26,21 +29,21 @@ public function testWrite(): void ->andReturn('test'); }); - $up = new SchemaBlueprint('users', SchemaBuilder::CREATE()); + $up = new SchemaBlueprint('users', SchemaBuilder::CREATE); $blueprint = new TableBlueprint(); - $blueprint->setProperty('collation', 'utf-8'); - $blueprint->setProperty('something', 1); - $blueprint->setProperty('something', true); - $blueprint->setProperty('something', false); - $blueprint->setProperty('something', null); - $blueprint->setProperty('something', [1, 2, 3, 'abc', null, true, false, ['a', 2, 'c']]); + $blueprint->setProperty(TableProperty::COLLATION, 'utf-8'); + $blueprint->setProperty(TableProperty::CHARSET, 1); + $blueprint->setProperty(TableProperty::CHARSET, true); + $blueprint->setProperty(TableProperty::CHARSET, false); + $blueprint->setProperty(TableProperty::CHARSET, null); + $blueprint->setProperty(TableProperty::CHARSET, [1, 2, 3, 'abc', null, true, false, ['a', 2, 'c']]); $blueprint->setLineBreak(); - $blueprint->setMethodByName('string', 'name', 100) - ->chain('comment', 'Hello') - ->chain('default', 'Test'); + $blueprint->setMethodByName(ColumnType::STRING, 'name', 100) + ->chain(ColumnModifier::COMMENT, 'Hello') + ->chain(ColumnModifier::DEFAULT, 'Test'); $up->setBlueprint($blueprint); - $down = new SchemaBlueprint('users', SchemaBuilder::DROP_IF_EXISTS()); + $down = new SchemaBlueprint('users', SchemaBuilder::DROP_IF_EXISTS); $migration = app(MigrationWriter::class); $migration->writeTo( @@ -49,7 +52,7 @@ public function testWrite(): void 'Tester', new Collection([$up]), new Collection([$down]), - MigrationFileType::TABLE(), + MigrationFileType::TABLE, ); $this->assertFileExists(storage_path('migration.php')); diff --git a/tests/resources/database/migrations/collation/2020_03_21_000000_expected_create_collations_table.php b/tests/resources/database/migrations/collation/2020_03_21_000000_expected_create_collations_table.php index 4493a207..2904e922 100644 --- a/tests/resources/database/migrations/collation/2020_03_21_000000_expected_create_collations_table.php +++ b/tests/resources/database/migrations/collation/2020_03_21_000000_expected_create_collations_table.php @@ -24,13 +24,13 @@ public function up() $table->collation = 'utf8mb4_general_ci'; switch (DB::getDriverName()) { - case Driver::PGSQL(): + case Driver::PGSQL->value: $collation = 'en_US.utf8'; break; - case Driver::SQLSRV(): + case Driver::SQLSRV->value: $collation = 'Latin1_General_100_CI_AI_SC_UTF8'; break; - case Driver::MYSQL(): + case Driver::MYSQL->value: $collation = 'utf8_unicode_ci'; break; default: @@ -42,8 +42,8 @@ public function up() // sqlsrv does not support collation with enum switch (DB::getDriverName()) { - case Driver::MYSQL(): - case Driver::PGSQL(): + case Driver::MYSQL->value: + case Driver::PGSQL->value: $table->enum('enum', ['easy', 'hard']); $table->enum('enum_charset', ['easy', 'hard'])->charset('utf8'); $table->enum('enum_collation', ['easy', 'hard'])->collation($collation); @@ -61,7 +61,7 @@ public function up() $table->text('text_charset')->charset('utf8'); $table->text('text_collation')->collation($collation); - if (DB::getDriverName() === Driver::MYSQL()->getValue()) { + if (DB::getDriverName() === Driver::MYSQL->value) { $table->set('set', ['strawberry', 'vanilla']); $table->set('set_default', ['strawberry', 'vanilla'])->default('strawberry'); $table->set('set_charset', ['strawberry', 'vanilla'])->charset('utf8'); diff --git a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_table.php b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_table.php index 181c04f0..cbca8029 100644 --- a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_table.php +++ b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_table.php @@ -84,8 +84,8 @@ public function up() // https://github.com/laravel/framework/pull/49634 if ($this->atLeastLaravel11()) { if ( - DB::getDriverName() !== Driver::MYSQL()->getValue() || - version_compare(DB::getServerVersion(), '5.8', '>') + DB::getDriverName() !== Driver::MYSQL->value || + version_compare(DB::getPdo()->getAttribute(PDO::ATTR_SERVER_VERSION), '5.8', '>') ) { $table->geography('geography'); $table->geography('geographyGeometryCollection', 'geometryCollection'); @@ -97,7 +97,7 @@ public function up() $table->geography('geographyPolygon', 'polygon'); $table->geography('geography1', null, 3857); - if (DB::getDriverName() !== Driver::PGSQL()->getValue()) { + if (DB::getDriverName() !== Driver::PGSQL->value) { $table->geography('geography2', 'geometryCollection', 3857); } @@ -161,7 +161,7 @@ public function up() $table->double('unsignedDouble')->unsigned(); $table->float('unsignedFloat')->unsigned(); - if (method_exists(Blueprint::class, 'unsignedDecimal')) { + if (!$this->atLeastLaravel11()) { // https://github.com/laravel/framework/pull/48861 $table->double('double_82', 8, 2); // @phpstan-ignore-line $table->double('double_83', 8, 3); // @phpstan-ignore-line @@ -195,18 +195,18 @@ public function up() } switch (DB::getDriverName()) { - case Driver::MYSQL(): + case Driver::MYSQL->value: $table->set('set', ['strawberry', 'vanilla']); break; default: } switch (DB::getDriverName()) { - case Driver::MYSQL(): + case Driver::MYSQL->value: $table->string('virtual')->nullable()->virtualAs('CONCAT(string, " ", string_255)'); $table->string('stored')->nullable()->storedAs("CONCAT(string_255, ' ', string)"); break; - case Driver::PGSQL(): + case Driver::PGSQL->value: $table->string('stored')->nullable()->storedAs("string_255 || ' ' || string"); break; default: @@ -214,7 +214,7 @@ public function up() }); switch (DB::getDriverName()) { - case Driver::PGSQL(): + case Driver::PGSQL->value: // Test timestamp default now() DB::statement( "ALTER TABLE ".DB::getTablePrefix()."all_columns ADD COLUMN timestamp_defaultnow timestamp(0) without time zone DEFAULT now() NOT NULL", @@ -233,7 +233,7 @@ public function up() ); break; - case Driver::SQLSRV(): + case Driver::SQLSRV->value: DB::statement( "ALTER TABLE ".DB::getTablePrefix()."all_columns ADD accountnumber accountnumber NOT NULL DEFAULT '1008'", ); diff --git a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_test_index_table.php b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_test_index_table.php index 750669eb..7e372171 100644 --- a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_test_index_table.php +++ b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_test_index_table.php @@ -42,7 +42,7 @@ public function up() $table->unique('chain'); // SQLite does not support spatial index. - if (DB::getDriverName() !== Driver::SQLITE()->getValue()) { + if (DB::getDriverName() !== Driver::SQLITE->value) { if ($this->hasGeography()) { $table->geography('spatial_index', null, 0)->spatialIndex(); $table->geography('spatial_index_custom', null, 0); @@ -55,7 +55,7 @@ public function up() } } - if (in_array(DB::getDriverName(), [Driver::MYSQL()->getValue(), Driver::PGSQL()->getValue()])) { + if (in_array(DB::getDriverName(), [Driver::MYSQL->value, Driver::PGSQL->value])) { $table->string('fulltext')->fulltext(); $table->string('fulltext_custom')->fulltext('fulltext_custom'); $table->fullText(['col_multi1', 'col_multi2']); @@ -63,7 +63,7 @@ public function up() } // TODO Laravel 10 does not support `$table->index(DB::raw("with_length(16)"))` -// if (DB::getDriverName() === Driver::MYSQL()->getValue()) { +// if (DB::getDriverName() === Driver::MYSQL->value) { // $table->index(['col_multi1', DB::raw('col_multi2(16)')], 'with_length_multi_custom'); // $table->string('with_length'); // $table->string('with_length_custom'); diff --git a/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_foreign_table.php b/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_foreign_table.php index 645d6312..1c091627 100644 --- a/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_foreign_table.php +++ b/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_foreign_table.php @@ -25,7 +25,7 @@ public function up() // SQLite does not support alter add foreign key. // https://www.sqlite.org/omitted.html - if (DB::getDriverName() !== Driver::SQLITE()->getValue()) { + if (DB::getDriverName() !== Driver::SQLITE->value) { $table->foreign('quoted-name-id')->references('id')->on('quoted-name'); } }); diff --git a/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_proc.php b/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_proc.php index aca4efbd..50d4e4c9 100644 --- a/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_proc.php +++ b/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_quoted_name_proc.php @@ -18,7 +18,7 @@ public function up() { switch (DB::getDriverName()) { - case Driver::MYSQL(): + case Driver::MYSQL->value: DB::unprepared( "CREATE PROCEDURE findNameWithHyphen() BEGIN @@ -26,7 +26,7 @@ public function up() END" ); break; - case Driver::PGSQL(): + case Driver::PGSQL->value: DB::unprepared( "CREATE PROCEDURE findNameWithHyphen() language plpgsql @@ -36,7 +36,7 @@ public function up() END;$$" ); break; - case Driver::SQLSRV(): + case Driver::SQLSRV->value: DB::unprepared( "CREATE PROCEDURE findNameWithHyphen AS diff --git a/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_user_profile_table.php b/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_user_profile_table.php index 269eda01..20d3758b 100644 --- a/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_user_profile_table.php +++ b/tests/resources/database/migrations/general/2020_03_21_000001_expected_create_user_profile_table.php @@ -33,7 +33,7 @@ public function up() // SQLite does not support alter add foreign key. // https://www.sqlite.org/omitted.html - if (DB::getDriverName() !== Driver::SQLITE()->getValue()) { + if (DB::getDriverName() !== Driver::SQLITE->value) { $table->foreign('user_id')->references('id')->on('users'); $table->foreign('user_id_fk_custom', 'users_foreign_custom')->references('id')->on('users'); $table->foreign('user_id_fk_constraint', 'users_foreign_constraint')->references('id')->on( From e3c6a1e79915c01d9cb621e142093d83eb08beca Mon Sep 17 00:00:00 2001 From: Kit Loong Date: Wed, 28 Feb 2024 22:11:14 +0800 Subject: [PATCH 13/20] Fix test --- .../2020_03_21_000000_expected_create_all_columns_table.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_table.php b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_table.php index cbca8029..10014247 100644 --- a/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_table.php +++ b/tests/resources/database/migrations/general/2020_03_21_000000_expected_create_all_columns_table.php @@ -113,7 +113,7 @@ public function up() } } - if (!$this->atLeastLaravel11()) { + if (!$this->atLeastLaravel11() && DB::getDriverName() !== Driver::SQLITE->value) { $table->geometryCollection('geometryCollection'); // @phpstan-ignore-line $table->lineString('lineString'); // @phpstan-ignore-line $table->multiLineString('multiLineString'); // @phpstan-ignore-line From 1bf763a514ad30f68de865428b5244fdc53d5562 Mon Sep 17 00:00:00 2001 From: Kit Loong Date: Wed, 28 Feb 2024 22:48:04 +0800 Subject: [PATCH 14/20] Remove test --- tests/Feature/SQLite/TablePrefixTest.php | 58 ------------------------ 1 file changed, 58 deletions(-) delete mode 100644 tests/Feature/SQLite/TablePrefixTest.php diff --git a/tests/Feature/SQLite/TablePrefixTest.php b/tests/Feature/SQLite/TablePrefixTest.php deleted file mode 100644 index 57230ba4..00000000 --- a/tests/Feature/SQLite/TablePrefixTest.php +++ /dev/null @@ -1,58 +0,0 @@ -migrateGeneral(); - }; - - $generateMigrations = function (): void { - $this->generateMigrations(); - }; - - $this->verify($migrateTemplates, $generateMigrations); - } - - /** - * @inheritDoc - */ - protected function getEnvironmentSetUp($app): void - { - parent::getEnvironmentSetUp($app); - - $app['config']->set('database.connections.sqlite.prefix', 'prefix_'); - } - - private function verify(callable $migrateTemplates, callable $generateMigrations): void - { - $migrateTemplates(); - - $this->truncateMigrationsTable(); - DB::statement("delete from sqlite_sequence where name = 'prefix_migrations'"); - - $this->dumpSchemaAs($this->getStorageSqlPath('expected.sql')); - $generateMigrations(); - - $this->assertMigrations(); - - $this->refreshDatabase(); - - $this->runMigrationsFrom($this->getStorageMigrationsPath()); - - $this->truncateMigrationsTable(); - DB::statement("delete from sqlite_sequence where name = 'prefix_migrations'"); - - $this->dumpSchemaAs($this->getStorageSqlPath('actual.sql')); - - $this->assertFileEqualsIgnoringOrder( - $this->getStorageSqlPath('expected.sql'), - $this->getStorageSqlPath('actual.sql'), - ); - } -} From 6e0264b8fbfa4998bb9e9d2cb539e82e2fd66072 Mon Sep 17 00:00:00 2001 From: Kit Loong Date: Wed, 28 Feb 2024 23:06:31 +0800 Subject: [PATCH 15/20] Remove old code --- src/Database/Models/DatabaseCustomColumn.php | 3 --- src/Support/CheckLaravelVersion.php | 5 ----- tests/Feature/PgSQL/CommandTest.php | 4 ---- 3 files changed, 12 deletions(-) diff --git a/src/Database/Models/DatabaseCustomColumn.php b/src/Database/Models/DatabaseCustomColumn.php index 534c0cfc..e0013fb5 100644 --- a/src/Database/Models/DatabaseCustomColumn.php +++ b/src/Database/Models/DatabaseCustomColumn.php @@ -3,15 +3,12 @@ namespace KitLoong\MigrationsGenerator\Database\Models; use KitLoong\MigrationsGenerator\Schema\Models\CustomColumn; -use KitLoong\MigrationsGenerator\Support\CheckLaravelVersion; /** * @phpstan-import-type SchemaColumn from \KitLoong\MigrationsGenerator\Database\DatabaseSchema */ abstract class DatabaseCustomColumn implements CustomColumn { - use CheckLaravelVersion; - protected string $name; protected string $tableName; diff --git a/src/Support/CheckLaravelVersion.php b/src/Support/CheckLaravelVersion.php index 18494ab4..90110c47 100644 --- a/src/Support/CheckLaravelVersion.php +++ b/src/Support/CheckLaravelVersion.php @@ -6,11 +6,6 @@ trait CheckLaravelVersion { - public function atLeastLaravel9(): bool - { - return $this->atLeastLaravelVersion('9.0'); - } - public function atLeastLaravel11(): bool { if (App::version() === '11.x-dev') { diff --git a/tests/Feature/PgSQL/CommandTest.php b/tests/Feature/PgSQL/CommandTest.php index 78c2ad4c..a237565c 100644 --- a/tests/Feature/PgSQL/CommandTest.php +++ b/tests/Feature/PgSQL/CommandTest.php @@ -80,10 +80,6 @@ public function testIgnore(): void */ public function testWithSearchPath(): void { - if (!$this->atLeastLaravel9()) { - $this->markTestSkipped(); - } - // Unset `schema` Config::set('database.connections.pgsql.schema'); $this->assertNull(Config::get('database.connections.pgsql.schema')); From c186e123e85e70e7e650deb3139f6ac1e0730999 Mon Sep 17 00:00:00 2001 From: Kit Loong Date: Wed, 28 Feb 2024 23:14:45 +0800 Subject: [PATCH 16/20] Rename to user-define type column --- src/Database/Models/DatabaseTable.php | 18 +++++++++--------- ...eCustomColumn.php => DatabaseUDTColumn.php} | 4 ++-- .../Models/MySQL/MySQLCustomColumn.php | 9 --------- src/Database/Models/MySQL/MySQLTable.php | 6 +++--- src/Database/Models/MySQL/MySQLUDTColumn.php | 9 +++++++++ src/Database/Models/PgSQL/PgSQLTable.php | 6 +++--- ...gSQLCustomColumn.php => PgSQLUDTColumn.php} | 4 ++-- src/Database/Models/SQLSrv/SQLSrvTable.php | 6 +++--- ...SrvCustomColumn.php => SQLSrvUDTColumn.php} | 4 ++-- .../Models/SQLite/SQLiteCustomColumn.php | 9 --------- src/Database/Models/SQLite/SQLiteTable.php | 6 +++--- src/Database/Models/SQLite/SQLiteUDTColumn.php | 9 +++++++++ src/Database/SQLSrvSchema.php | 2 +- src/Migration/TableMigration.php | 6 +++--- src/Repositories/SQLSrvRepository.php | 4 ++-- src/Schema/Models/Table.php | 6 +++--- .../Models/{CustomColumn.php => UDTColumn.php} | 4 ++-- tests/Feature/PgSQL/PgSQLTestCase.php | 2 +- tests/Feature/SQLSrv/SQLSrvTestCase.php | 2 +- 19 files changed, 58 insertions(+), 58 deletions(-) rename src/Database/Models/{DatabaseCustomColumn.php => DatabaseUDTColumn.php} (87%) delete mode 100644 src/Database/Models/MySQL/MySQLCustomColumn.php create mode 100644 src/Database/Models/MySQL/MySQLUDTColumn.php rename src/Database/Models/PgSQL/{PgSQLCustomColumn.php => PgSQLUDTColumn.php} (90%) rename src/Database/Models/SQLSrv/{SQLSrvCustomColumn.php => SQLSrvUDTColumn.php} (89%) delete mode 100644 src/Database/Models/SQLite/SQLiteCustomColumn.php create mode 100644 src/Database/Models/SQLite/SQLiteUDTColumn.php rename src/Schema/Models/{CustomColumn.php => UDTColumn.php} (76%) diff --git a/src/Database/Models/DatabaseTable.php b/src/Database/Models/DatabaseTable.php index 825ab0fc..f56198fe 100644 --- a/src/Database/Models/DatabaseTable.php +++ b/src/Database/Models/DatabaseTable.php @@ -4,9 +4,9 @@ use Illuminate\Support\Collection; use KitLoong\MigrationsGenerator\Schema\Models\Column; -use KitLoong\MigrationsGenerator\Schema\Models\CustomColumn; use KitLoong\MigrationsGenerator\Schema\Models\Index; use KitLoong\MigrationsGenerator\Schema\Models\Table; +use KitLoong\MigrationsGenerator\Schema\Models\UDTColumn; /** * @phpstan-import-type SchemaColumn from \KitLoong\MigrationsGenerator\Database\DatabaseSchema @@ -23,9 +23,9 @@ abstract class DatabaseTable implements Table protected Collection $columns; /** - * @var \Illuminate\Support\Collection + * @var \Illuminate\Support\Collection */ - protected Collection $customColumns; + protected Collection $udtColumns; protected string $name; @@ -44,11 +44,11 @@ abstract class DatabaseTable implements Table abstract protected function makeColumn(string $table, array $column): Column; /** - * Make a CustomColumn instance. + * Make a UDTColumn instance. * * @param SchemaColumn $column */ - abstract protected function makeCustomColumn(string $table, array $column): CustomColumn; + abstract protected function makeUDTColumn(string $table, array $column): UDTColumn; /** * Make an Index instance. @@ -79,9 +79,9 @@ public function __construct(array $table, Collection $columns, Collection $index return $columns; }, new Collection())->values(); - $this->customColumns = $columns->reduce(function (Collection $columns, array $column) use ($userDefinedTypes) { + $this->udtColumns = $columns->reduce(function (Collection $columns, array $column) use ($userDefinedTypes) { if ($userDefinedTypes->contains($column['type_name'])) { - $columns->push($this->makeCustomColumn($this->name, $column)); + $columns->push($this->makeUDTColumn($this->name, $column)); } return $columns; @@ -117,9 +117,9 @@ public function getColumns(): Collection /** * @inheritDoc */ - public function getCustomColumns(): Collection + public function getUdtColumns(): Collection { - return $this->customColumns; + return $this->udtColumns; } /** diff --git a/src/Database/Models/DatabaseCustomColumn.php b/src/Database/Models/DatabaseUDTColumn.php similarity index 87% rename from src/Database/Models/DatabaseCustomColumn.php rename to src/Database/Models/DatabaseUDTColumn.php index e0013fb5..dea246f8 100644 --- a/src/Database/Models/DatabaseCustomColumn.php +++ b/src/Database/Models/DatabaseUDTColumn.php @@ -2,12 +2,12 @@ namespace KitLoong\MigrationsGenerator\Database\Models; -use KitLoong\MigrationsGenerator\Schema\Models\CustomColumn; +use KitLoong\MigrationsGenerator\Schema\Models\UDTColumn; /** * @phpstan-import-type SchemaColumn from \KitLoong\MigrationsGenerator\Database\DatabaseSchema */ -abstract class DatabaseCustomColumn implements CustomColumn +abstract class DatabaseUDTColumn implements UDTColumn { protected string $name; diff --git a/src/Database/Models/MySQL/MySQLCustomColumn.php b/src/Database/Models/MySQL/MySQLCustomColumn.php deleted file mode 100644 index d73f0bfa..00000000 --- a/src/Database/Models/MySQL/MySQLCustomColumn.php +++ /dev/null @@ -1,9 +0,0 @@ -ranGetUserDefinedTypes) { - $this->userDefinedTypes = $this->sqlSrvRepository->getCustomDataTypes(); + $this->userDefinedTypes = $this->sqlSrvRepository->getUserDefinedTypes(); $this->ranGetUserDefinedTypes = true; } diff --git a/src/Migration/TableMigration.php b/src/Migration/TableMigration.php index a1a141c7..0aaa7c4f 100644 --- a/src/Migration/TableMigration.php +++ b/src/Migration/TableMigration.php @@ -49,7 +49,7 @@ public function write(Table $table): string $upList = new Collection(); $upList->push($this->up($table)); - if ($table->getCustomColumns()->isNotEmpty()) { + if ($table->getUdtColumns()->isNotEmpty()) { foreach ($this->upAdditionalStatements($table) as $statement) { $upList->push($statement); } @@ -77,7 +77,7 @@ public function writeToTemp(Table $table): void $upList = new Collection(); $upList->push($this->up($table)); - if ($table->getCustomColumns()->isNotEmpty()) { + if ($table->getUdtColumns()->isNotEmpty()) { foreach ($this->upAdditionalStatements($table) as $statement) { $upList->push($statement); } @@ -139,7 +139,7 @@ private function upAdditionalStatements(Table $table): array { $statements = []; - foreach ($table->getCustomColumns() as $column) { + foreach ($table->getUdtColumns() as $column) { foreach ($column->getSqls() as $sql) { $statements[] = new DBStatementBlueprint($sql); } diff --git a/src/Repositories/SQLSrvRepository.php b/src/Repositories/SQLSrvRepository.php index df343f36..254dab06 100644 --- a/src/Repositories/SQLSrvRepository.php +++ b/src/Repositories/SQLSrvRepository.php @@ -171,11 +171,11 @@ public function getEnumPresetValues(string $table, string $column): Collection } /** - * Get a list of custom data types. + * Get a list of user-defined types. * * @return \Illuminate\Support\Collection */ - public function getCustomDataTypes(): Collection + public function getUserDefinedTypes(): Collection { $rows = DB::select("SELECT * FROM sys.types WHERE is_user_defined = 1"); $types = new Collection(); diff --git a/src/Schema/Models/Table.php b/src/Schema/Models/Table.php index c44e219b..37181186 100644 --- a/src/Schema/Models/Table.php +++ b/src/Schema/Models/Table.php @@ -24,11 +24,11 @@ public function getComment(): ?string; public function getColumns(): Collection; /** - * Get a list of custom columns. + * Get a list of user-defined type columns. * - * @return \Illuminate\Support\Collection + * @return \Illuminate\Support\Collection */ - public function getCustomColumns(): Collection; + public function getUdtColumns(): Collection; /** * Get a list of indexes. diff --git a/src/Schema/Models/CustomColumn.php b/src/Schema/Models/UDTColumn.php similarity index 76% rename from src/Schema/Models/CustomColumn.php rename to src/Schema/Models/UDTColumn.php index 4a030e52..43291b52 100644 --- a/src/Schema/Models/CustomColumn.php +++ b/src/Schema/Models/UDTColumn.php @@ -3,9 +3,9 @@ namespace KitLoong\MigrationsGenerator\Schema\Models; /** - * Table column. Column type which is not supported by the framework. + * Table column. User-defined type column which is not supported by the framework. */ -interface CustomColumn extends Model +interface UDTColumn extends Model { /** * Get the column name. diff --git a/tests/Feature/PgSQL/PgSQLTestCase.php b/tests/Feature/PgSQL/PgSQLTestCase.php index 380005fa..f4419b81 100644 --- a/tests/Feature/PgSQL/PgSQLTestCase.php +++ b/tests/Feature/PgSQL/PgSQLTestCase.php @@ -37,7 +37,7 @@ protected function setUp(): void { parent::setUp(); - // Create for custom column type test. + // Create for user defined type column test. DB::statement("CREATE TYPE my_status AS enum ('PENDING', 'ACTIVE', 'SUSPENDED')"); } diff --git a/tests/Feature/SQLSrv/SQLSrvTestCase.php b/tests/Feature/SQLSrv/SQLSrvTestCase.php index 4abdcb22..0b43a6e3 100644 --- a/tests/Feature/SQLSrv/SQLSrvTestCase.php +++ b/tests/Feature/SQLSrv/SQLSrvTestCase.php @@ -38,7 +38,7 @@ protected function setUp(): void // Drop first. DB::statement("DROP TYPE IF EXISTS accountnumber"); - // Create for custom column type test. + // Create for user defined type column test. DB::statement("CREATE TYPE accountnumber FROM [nvarchar](15) NULL"); } From f7884abd2e4b658575938414a74d9d43a05735e7 Mon Sep 17 00:00:00 2001 From: Kit Loong Date: Sun, 3 Mar 2024 22:38:55 +0800 Subject: [PATCH 17/20] Remove old codes --- config/migrations-generator.php | 7 +++-- src/Database/DatabaseSchema.php | 3 --- src/Database/Models/DatabaseColumn.php | 10 +++++++ src/MigrateGenerateCommand.php | 9 +------ src/Migration/TableMigration.php | 4 +-- src/Support/CheckMigrationMethod.php | 27 ------------------- stubs/migration.generate.anonymous.stub | 26 ------------------ stubs/migration.generate.stub | 4 +-- tests/Feature/FeatureTestCase.php | 3 --- tests/Feature/MariaDB/CommandTest.php | 3 --- tests/Feature/SQLite/CommandTest.php | 3 --- ...0000_expected_create_all_columns_table.php | 10 ++----- 12 files changed, 19 insertions(+), 90 deletions(-) delete mode 100644 stubs/migration.generate.anonymous.stub diff --git a/config/migrations-generator.php b/config/migrations-generator.php index 43dedee0..a84924c3 100644 --- a/config/migrations-generator.php +++ b/config/migrations-generator.php @@ -2,14 +2,13 @@ return [ // Where the templates for the generators are stored. - 'migration_template_path' => __DIR__ . '/../stubs/migration.generate.stub', - 'migration_anonymous_template_path' => __DIR__ . '/../stubs/migration.generate.anonymous.stub', + 'migration_template_path' => __DIR__ . '/../stubs/migration.generate.stub', // Where the generated files will be saved. - 'migration_target_path' => base_path('database/migrations'), + 'migration_target_path' => base_path('database/migrations'), // Migration filename pattern. - 'filename_pattern' => [ + 'filename_pattern' => [ 'table' => '[datetime]_create_[name]_table.php', 'view' => '[datetime]_create_[name]_view.php', 'procedure' => '[datetime]_create_[name]_proc.php', diff --git a/src/Database/DatabaseSchema.php b/src/Database/DatabaseSchema.php index 11efed5b..5ee67f35 100644 --- a/src/Database/DatabaseSchema.php +++ b/src/Database/DatabaseSchema.php @@ -5,7 +5,6 @@ use Illuminate\Support\Collection; use Illuminate\Support\Facades\Schema as SchemaFacade; use KitLoong\MigrationsGenerator\Schema\Schema; -use KitLoong\MigrationsGenerator\Support\AssetNameQuote; use KitLoong\MigrationsGenerator\Support\TableName; /** @@ -55,8 +54,6 @@ */ abstract class DatabaseSchema implements Schema { - use AssetNameQuote; - use TableName; /** diff --git a/src/Database/Models/DatabaseColumn.php b/src/Database/Models/DatabaseColumn.php index c609dc1b..a9004743 100644 --- a/src/Database/Models/DatabaseColumn.php +++ b/src/Database/Models/DatabaseColumn.php @@ -330,6 +330,10 @@ protected function parseLength(string $fullDefinitionType): ?int if (preg_match('/\((\d*)\)/', $fullDefinitionType, $matches) === 1) { return (int) $matches[1]; } + + break; + + default: } return null; @@ -349,6 +353,10 @@ protected function parsePrecisionAndScale(string $fullDefinitionType): array if (preg_match('/\((\d+)(?:,\s*(\d+))?\)?/', $fullDefinitionType, $matches) === 1) { return [(int) $matches[1], isset($matches[2]) ? (int) $matches[2] : 0]; } + + break; + + default: } return [null, 0]; @@ -371,6 +379,8 @@ private function setTypeToSoftDeletes(): void case ColumnType::TIMESTAMP_TZ: $this->type = ColumnType::SOFT_DELETES_TZ; return; + + default: } } diff --git a/src/MigrateGenerateCommand.php b/src/MigrateGenerateCommand.php index 9f26d7f8..059c756e 100644 --- a/src/MigrateGenerateCommand.php +++ b/src/MigrateGenerateCommand.php @@ -23,12 +23,9 @@ use KitLoong\MigrationsGenerator\Schema\Schema; use KitLoong\MigrationsGenerator\Schema\SQLiteSchema; use KitLoong\MigrationsGenerator\Schema\SQLSrvSchema; -use KitLoong\MigrationsGenerator\Support\CheckMigrationMethod; class MigrateGenerateCommand extends Command { - use CheckMigrationMethod; - /** * The name and signature of the console command. */ @@ -170,11 +167,7 @@ protected function setup(string $connection): void */ protected function setStubPath(Setting $setting): void { - $defaultStub = Config::get('migrations-generator.migration_anonymous_template_path'); - - if (!$this->hasAnonymousMigration()) { - $defaultStub = Config::get('migrations-generator.migration_template_path'); - } + $defaultStub = Config::get('migrations-generator.migration_template_path'); $setting->setStubPath( $this->option('template-path') ?? $defaultStub, diff --git a/src/Migration/TableMigration.php b/src/Migration/TableMigration.php index 0aaa7c4f..2b14ea97 100644 --- a/src/Migration/TableMigration.php +++ b/src/Migration/TableMigration.php @@ -20,13 +20,11 @@ use KitLoong\MigrationsGenerator\Migration\Writer\SquashWriter; use KitLoong\MigrationsGenerator\Schema\Models\Table; use KitLoong\MigrationsGenerator\Setting; -use KitLoong\MigrationsGenerator\Support\CheckMigrationMethod; use KitLoong\MigrationsGenerator\Support\MigrationNameHelper; use KitLoong\MigrationsGenerator\Support\TableName; class TableMigration { - use CheckMigrationMethod; use TableName; public function __construct( @@ -102,7 +100,7 @@ private function up(Table $table): SchemaBlueprint $blueprint->setLineBreak(); } - if ($this->hasTableComment() && $table->getComment() !== null && $table->getComment() !== '') { + if ($table->getComment() !== null && $table->getComment() !== '') { $blueprint->setMethod(new Method(TableMethod::COMMENT, $table->getComment())); } diff --git a/src/Support/CheckMigrationMethod.php b/src/Support/CheckMigrationMethod.php index 4313587a..9c29c182 100644 --- a/src/Support/CheckMigrationMethod.php +++ b/src/Support/CheckMigrationMethod.php @@ -2,37 +2,10 @@ namespace KitLoong\MigrationsGenerator\Support; -use Illuminate\Database\Migrations\Migrator; use Illuminate\Database\Schema\Blueprint; trait CheckMigrationMethod { - /** - * `tinyText` added since Laravel 9. - */ - public function hasULID(): bool - { - return method_exists(Blueprint::class, 'ulid'); - } - - /** - * Check if support anonymous migration. - * This feature is added in late Laravel v8 and above. - */ - public function hasAnonymousMigration(): bool - { - return method_exists(Migrator::class, 'getMigrationClass'); - } - - /** - * Check if support add comment to a table. - * This feature is added since Laravel v9. - */ - public function hasTableComment(): bool - { - return method_exists(Blueprint::class, 'comment'); - } - /** * `geography` added since Laravel 11. */ diff --git a/stubs/migration.generate.anonymous.stub b/stubs/migration.generate.anonymous.stub deleted file mode 100644 index 82673456..00000000 --- a/stubs/migration.generate.anonymous.stub +++ /dev/null @@ -1,26 +0,0 @@ -hasTableComment()) { - $table->comment('A table comment.'); - } + $table->comment('A table comment.'); $table->bigInteger('bigInteger'); $table->bigInteger('bigInteger_default')->default(1080); @@ -190,9 +186,7 @@ public function up() $table->tinyText('tinyText'); - if ($this->hasULID()) { - $table->ulid('ulid'); - } + $table->ulid('ulid'); switch (DB::getDriverName()) { case Driver::MYSQL->value: From acf1f0fbf16261764b40ed7f8ae30a2c124ac493 Mon Sep 17 00:00:00 2001 From: Kit Loong Date: Sun, 3 Mar 2024 23:06:26 +0800 Subject: [PATCH 18/20] Add ide-helper v3 --- composer.json | 3 ++- testbench.yaml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 6d48303b..e0276021 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,8 @@ "friendsofphp/php-cs-fixer": "^3.1", "larastan/larastan": "^1.0|^2.0", "slevomat/coding-standard": "^8.0", - "phpmd/phpmd": "^2.10" + "phpmd/phpmd": "^2.10", + "barryvdh/laravel-ide-helper": "^2.0|^3.0" }, "autoload": { "psr-4": { diff --git a/testbench.yaml b/testbench.yaml index d5ab53bd..df049c3a 100644 --- a/testbench.yaml +++ b/testbench.yaml @@ -1,3 +1,3 @@ providers: - # - Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider + - Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider - KitLoong\MigrationsGenerator\MigrationsGeneratorServiceProvider From 898841654fa05d9e3e60a3077e2aa8ff2f03e776 Mon Sep 17 00:00:00 2001 From: Kit Loong Date: Sun, 3 Mar 2024 23:07:18 +0800 Subject: [PATCH 19/20] Clean --- .gitattributes | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index a34f6d88..3c0e2138 100644 --- a/.gitattributes +++ b/.gitattributes @@ -13,5 +13,4 @@ /phpcs.xml export-ignore /phpstan.neon export-ignore /phpunit.xml.dist export-ignore -/phpunit8.xml export-ignore /testbench.yaml export-ignore From 5bbe6c1cec3a2b3dac9421c37e640c6da426fd40 Mon Sep 17 00:00:00 2001 From: Kit Loong Date: Sun, 3 Mar 2024 23:14:20 +0800 Subject: [PATCH 20/20] Update README.md --- README.md | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 22321f04..a41c9532 100644 --- a/README.md +++ b/README.md @@ -23,17 +23,19 @@ Laravel Migrations Generator supports all five Laravel first-party support datab ## Version Compatibility -| Laravel | Version | -|---------------|-------------------------------------------------| -| 10.x | 6.x | -| 9.x | 6.x | -| 8.x | 6.x | -| 7.x | 6.x | -| 6.x | 6.x | -| 5.8.x | 6.x | -| 5.7.x | 6.x | -| 5.6.x | 6.x | -| 5.5 and below | https://github.com/Xethron/migrations-generator | +| Laravel | Version | +|--------------------|-------------------------------------------------| +| 11.x | 7.x | +| \>= 10.43.x | 7.x | +| 10.x \| <= 10.42.x | 6.x | +| 9.x | 6.x | +| 8.x | 6.x | +| 7.x | 6.x | +| 6.x | 6.x | +| 5.8.x | 6.x | +| 5.7.x | 6.x | +| 5.6.x | 6.x | +| <= 5.5.x | https://github.com/Xethron/migrations-generator | ## Install @@ -148,9 +150,9 @@ The generator first generates all tables and then adds foreign keys to existing However, SQLite only supports foreign keys upon creation of the table and not when tables are altered. *_add_foreign_keys_* migrations will still be generated, however will get omitted if migrate to SQLite type database. -## User Defined Custom Column Type +## User-Defined Type Columns -The generator will register custom data type from the schema, then generate migration as +The generator will recognize user-defined type from the schema, and then generate migration as ```php public function up() @@ -164,7 +166,7 @@ public function up() Note that the new `column` is always added at the end of the created `table` which means the ordering of the column generated in migration will differ from what we have from the schema. -Supported database with custom types: +Supported database with user-defined types: - [x] PostgreSQL - [x] SQL Server