├── database └── migrations │ └── transform_pk_int_to_bigint.php.stub ├── src ├── Console │ └── TransformCommand.php ├── ServiceProvider.php └── Transformer.php ├── composer.json ├── LICENSE ├── CHANGELOG.md ├── db_test.sql ├── README.md └── CLAUDE.md /database/migrations/transform_pk_int_to_bigint.php.stub: -------------------------------------------------------------------------------- 1 | setConsoleCommand($this); 18 | 19 | if ($database = $this->option('database')) { 20 | $transformer->setSchema($database); 21 | } 22 | 23 | $transformer->transform(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "axn/laravel-pk-int-to-bigint", 3 | "description": "Convert DB primary keys and related foreign keys type from INT to BIGINT in a Laravel project", 4 | "homepage": "https://github.com/AXN-Informatique/laravel-pk-int-to-bigint", 5 | "support": { 6 | "issues": "https://github.com/AXN-Informatique/laravel-pk-int-to-bigint/issues" 7 | }, 8 | "authors": [{ 9 | "name": "AXN Informatique", 10 | "email": "developpement@axn.fr" 11 | } 12 | ], 13 | "license": "MIT", 14 | "require": { 15 | "php": "^8.4", 16 | "illuminate/support": "^12.0", 17 | "illuminate/database": "^12.0" 18 | }, 19 | "autoload": { 20 | "psr-4": { 21 | "Axn\\PkIntToBigint\\": "src/" 22 | } 23 | }, 24 | "extra" : { 25 | "laravel" : { 26 | "providers" : [ 27 | "Axn\\PkIntToBigint\\ServiceProvider" 28 | ] 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/ServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->runningInConsole()) { 14 | return; 15 | } 16 | 17 | $this->app->singleton('command.pk-int-to-bigint.transform', function($app) { 18 | $transformer = new Transformer($app['db.connection']); 19 | 20 | return new TransformCommand($transformer); 21 | }); 22 | 23 | $this->commands([ 24 | 'command.pk-int-to-bigint.transform', 25 | ]); 26 | 27 | $this->publishes([ 28 | __DIR__.'/../database/migrations/transform_pk_int_to_bigint.php.stub' => 29 | database_path('migrations/'.now()->format('Y_m_d_His').'_transform_pk_int_to_bigint.php'), 30 | ], 'pk-int-to-bigint-migration'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 AXN Informatique 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Changelog 2 | ========= 3 | 4 | 4.0.0 (2025-12-03) 5 | ------------------ 6 | 7 | Breaking changes: 8 | - Drop Laravel 11 support 9 | - Drop PHP 8.2 support 10 | - Require PHP 8.4+ 11 | - Require Laravel 12+ 12 | 13 | New features: 14 | - Add `--database` option to specify the database/schema to use 15 | 16 | Fixes: 17 | - Handle Laravel 12 multi-schema database inspection changes 18 | 19 | 20 | 3.0.0 (2025-11-04) 21 | ------------------ 22 | 23 | Add Laravel 11 & 12 support 24 | - Support PHP 8.2 and 8.4 25 | - Add illuminate/support ^11.0 || ^12.0 26 | - Add illuminate/database ^11.0 || ^12.0 27 | 28 | Breaking changes: 29 | - Drop Laravel 8, 9, 10 support 30 | - Drop PHP 8.1 support" 31 | - Remove doctrine/dbal dependency completely 32 | - Use native Laravel database introspection 33 | 34 | 35 | 2.1.1 (2023-07-03) 36 | ------------------ 37 | 38 | - Prevent running migration if package is uninstalled 39 | - Removed unsigned constraint for keys 40 | - Prevent errors in the presence of enum type columns (close #2) 41 | 42 | 43 | 2.1.0 (2023-04-12) 44 | ------------------ 45 | 46 | - Added support for Laravel 10 47 | - Uppercase README and CHANGELOG fielnames 48 | 49 | 50 | 2.0.0 (2022-12-19) 51 | ------------------ 52 | 53 | - PHP < 8.1 support removed 54 | - doctrine/dbal < 3.5 support 55 | 56 | 57 | 1.3.2 (2022-12-01) 58 | ------------------ 59 | 60 | - Typo in changelog : doctrine/dbal >= 3.5 (instead of >= 3.1) 61 | 62 | 63 | 1.3.1 (2022-11-09) 64 | ------------------ 65 | 66 | - Fixed support for doctrine/dbal >= 3.5 67 | - Dropped Transformer injection from command constructor 68 | 69 | 70 | 1.3.0 (2022-08-05) 71 | ------------------ 72 | 73 | - Added support for Laravel 9 74 | 75 | 76 | 1.2.0 (2022-01-11) 77 | ------------------ 78 | 79 | - Possibility of generating a migration in order to simplify the implementation 80 | 81 | 82 | 1.1.0 (2022-01-10) 83 | ------------------ 84 | 85 | - Uses doctrine/dbal instead of custom driver for getting DB schema information 86 | 87 | 88 | 1.0.0 (2021-10-27) 89 | ------------------ 90 | 91 | - First release. 92 | -------------------------------------------------------------------------------- /db_test.sql: -------------------------------------------------------------------------------- 1 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 2 | /*!40101 SET NAMES utf8 */; 3 | /*!50503 SET NAMES utf8mb4 */; 4 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 5 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 6 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; 7 | 8 | CREATE TABLE IF NOT EXISTS `table1` ( 9 | `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'commentaire 1', 10 | `col1` int(10) unsigned DEFAULT NULL, 11 | `col2` varchar(50) DEFAULT NULL, 12 | PRIMARY KEY (`id`) 13 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 14 | 15 | /*!40000 ALTER TABLE `table1` DISABLE KEYS */; 16 | /*!40000 ALTER TABLE `table1` ENABLE KEYS */; 17 | 18 | CREATE TABLE IF NOT EXISTS `table2` ( 19 | `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 20 | `table1_id` int(10) unsigned NOT NULL COMMENT 'commentaire 2', 21 | PRIMARY KEY (`id`), 22 | KEY `FK_table2_table1` (`table1_id`) USING BTREE, 23 | CONSTRAINT `FK_table2_table1` FOREIGN KEY (`table1_id`) REFERENCES `table1` (`id`) 24 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 25 | 26 | /*!40000 ALTER TABLE `table2` DISABLE KEYS */; 27 | /*!40000 ALTER TABLE `table2` ENABLE KEYS */; 28 | 29 | CREATE TABLE IF NOT EXISTS `table3` ( 30 | `id1` int(10) unsigned NOT NULL COMMENT 'commentaire 3', 31 | `id2` int(10) unsigned NOT NULL, 32 | `table1_id` int(10) unsigned NOT NULL DEFAULT '1' COMMENT 'commentaire 4', 33 | `table2_id` int(10) unsigned DEFAULT NULL, 34 | PRIMARY KEY (`id1`,`id2`), 35 | KEY `FK_table3_table1` (`table1_id`) USING BTREE, 36 | KEY `FK_table3_table2` (`table2_id`) USING BTREE, 37 | CONSTRAINT `FK_table3_table1` FOREIGN KEY (`table1_id`) REFERENCES `table1` (`id`), 38 | CONSTRAINT `FK_table3_table2` FOREIGN KEY (`table2_id`) REFERENCES `table2` (`id`) 39 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 40 | 41 | /*!40000 ALTER TABLE `table3` DISABLE KEYS */; 42 | /*!40000 ALTER TABLE `table3` ENABLE KEYS */; 43 | 44 | /*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; 45 | /*!40014 SET FOREIGN_KEY_CHECKS=IFNULL(@OLD_FOREIGN_KEY_CHECKS, 1) */; 46 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 47 | /*!40111 SET SQL_NOTES=IFNULL(@OLD_SQL_NOTES, 1) */; 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Laravel convert primary keys INT to BIGINT 2 | ========================================== 3 | 4 | This package convert DB primary keys and related foreign keys type from INT to BIGINT in a Laravel project. 5 | 6 | This is especially useful for old projects that need to be updated. 7 | 8 | Indeed, since Laravel 5.8 the ID columns are by default of type BIGINT. If you install new packages that use this new "standard" you will have trouble creating the foreign keys. 9 | 10 | As a result, this package will be of great help to you to modernize an old application. 11 | 12 | ## Version Compatibility 13 | 14 | - **Version 4.x**: Laravel 12+ / PHP 8.4+ (uses native Laravel schema methods) 15 | - **Version 3.x**: Laravel 11 / PHP 8.2+ (uses native Laravel schema methods) ⚠️ **Not compatible with Laravel 12** 16 | - **Version 2.x**: Laravel 8-10 / PHP 8.1+ (uses Doctrine DBAL) 17 | 18 | ## How it works 19 | 20 | It proceeds in 4 steps: 21 | 22 | 1. **Introspection**: Scans the database and verifies the integrity of foreign keys (if an integrity is not respected it stops and indicates it to you) 23 | 2. **Drop constraints**: Temporarily drops all foreign key constraints on each table 24 | 3. **Convert columns**: Converts INT to BIGINT on primary and foreign key columns on each table (preserving nullable, default values, and auto-increment settings) 25 | 4. **Restore constraints**: Restores all foreign key constraints on each table with their original ON DELETE/ON UPDATE actions 26 | 27 | ## Installation 28 | 29 | Install the package with Composer: 30 | 31 | ```sh 32 | composer require axn/laravel-pk-int-to-bigint 33 | ``` 34 | 35 | For Laravel 11 (version 3.x): 36 | 37 | ```sh 38 | composer require axn/laravel-pk-int-to-bigint:^3.0 39 | ``` 40 | 41 | For Laravel 8-10 (version 2.x): 42 | 43 | ```sh 44 | composer require axn/laravel-pk-int-to-bigint:^2.0 45 | ``` 46 | 47 | ## Usage 48 | 49 | **⚠️ Important**: First create a dump of your database in case there is a problem. 50 | 51 | ### Option 1: Run manually 52 | 53 | If you want to run the command directly: 54 | 55 | ```sh 56 | php artisan pk-int-to-bigint:transform 57 | ``` 58 | 59 | You can specify a specific database/schema: 60 | 61 | ```sh 62 | php artisan pk-int-to-bigint:transform --database=my_database 63 | ``` 64 | 65 | ### Option 2: With migration 66 | 67 | Publish the migration: 68 | 69 | ```sh 70 | php artisan vendor:publish --tag="pk-int-to-bigint-migration" 71 | ``` 72 | 73 | So you can incorporate it into your deployment workflow with: 74 | 75 | ```sh 76 | php artisan migrate 77 | ``` 78 | 79 | ## What gets converted 80 | 81 | The package will convert: 82 | - All primary key columns of type INT, TINYINT, SMALLINT, MEDIUMINT to BIGINT 83 | - All foreign key columns of type INT, TINYINT, SMALLINT, MEDIUMINT to BIGINT 84 | - Preserves all column attributes (nullable, default values, auto-increment) 85 | - Preserves all foreign key constraints (ON DELETE, ON UPDATE actions) 86 | 87 | -------------------------------------------------------------------------------- /CLAUDE.md: -------------------------------------------------------------------------------- 1 | # CLAUDE.md 2 | 3 | This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. 4 | 5 | ## Project Overview 6 | 7 | This is a Laravel package that converts database primary keys and related foreign keys from INT to BIGINT. It's designed to help modernize older Laravel projects (pre-5.8) where INT was the default ID type, enabling compatibility with newer packages that use BIGINT. 8 | 9 | **Version 4.0** requires Laravel 12+ and PHP 8.4+, using native Laravel schema methods. 10 | 11 | ## Package Architecture 12 | 13 | ### Core Components 14 | 15 | - **ServiceProvider** (`src/ServiceProvider.php`): Registers the Artisan command and publishes the migration stub 16 | - **Transformer** (`src/Transformer.php`): Contains the core transformation logic 17 | - **TransformCommand** (`src/Console/TransformCommand.php`): Artisan command entry point 18 | 19 | ### Transformation Process 20 | 21 | The Transformer class performs a 4-step process (see `Transformer::transform()`): 22 | 23 | 1. **Introspection**: `extractSchemaInfos()` scans all tables using Laravel's native schema methods: 24 | - `Schema::getTables()` - Get all database tables 25 | - `Schema::getColumns($table)` - Get column information including type, nullable, default, auto_increment 26 | - `Schema::getIndexes($table)` - Identify primary key columns 27 | - `Schema::getForeignKeys($table)` - Get foreign key constraints 28 | - Identifies integer columns (int, tinyint, smallint, mediumint, bigint) that are primary or foreign keys 29 | 30 | 2. **Validation**: Checks referential integrity before making changes via `hasConstraintAnomaly()`. If any foreign key constraint would be violated, the process stops and reports the anomaly. 31 | 32 | 3. **Drop constraints**: Temporarily drops all foreign key constraints to allow column type changes 33 | 34 | 4. **Transform columns**: Changes INT to BIGINT for all identified key columns, preserving: 35 | - Nullable/NOT NULL status 36 | - Default values 37 | - Auto-increment settings 38 | 39 | 5. **Restore constraints**: Re-creates all foreign key constraints with their original: 40 | - ON DELETE actions 41 | - ON UPDATE actions 42 | 43 | ### Important Technical Details 44 | 45 | - **v3.0+**: Uses Laravel 11+ native schema methods (`getTables()`, `getColumns()`, `getIndexes()`, `getForeignKeys()`) 46 | - **Pre-v3.0**: Used Doctrine DBAL (no longer supported in v3.0) 47 | - Column type detection via `isIntegerType()` method supports all MySQL integer types (int, tinyint, smallint, mediumint, bigint) 48 | - Column type name retrieved from `$column['type_name']` or `$column['type']` depending on database driver 49 | - Handles all integer columns that are keys (primary or foreign) 50 | - Foreign keys are assumed to be single-column (accesses `[0]` index) 51 | - Migration stub includes safety check: won't run if package is uninstalled 52 | 53 | ## Usage Commands 54 | 55 | ### Run transformation directly: 56 | ```bash 57 | php artisan pk-int-to-bigint:transform 58 | ``` 59 | 60 | ### Publish migration for deployment workflow: 61 | ```bash 62 | php artisan vendor:publish --tag="pk-int-to-bigint-migration" 63 | php artisan migrate 64 | ``` 65 | 66 | ## Development Requirements 67 | 68 | **Version 4.0+:** 69 | - PHP ^8.4 70 | - Laravel ^12.0 71 | - No Doctrine DBAL dependency (uses native Laravel schema methods) 72 | 73 | **Version 3.x:** 74 | - PHP ^8.2 || ^8.4 75 | - Laravel ^11.0 || ^12.0 76 | 77 | **Version 2.x (legacy):** 78 | - PHP ^8.1 79 | - Laravel ^8.0 || ^9.0 || ^10.0 80 | - Doctrine DBAL ^3.5 || ^3.6 81 | 82 | ## Testing Considerations 83 | 84 | When making changes: 85 | - Test with various foreign key configurations (CASCADE, RESTRICT, SET NULL, etc.) 86 | - Verify behavior with composite keys (though current implementation assumes single-column FKs) 87 | - Check handling of nullable columns vs NOT NULL columns 88 | - Test with different integer types (tinyint, smallint, mediumint, int, bigint) 89 | - Test referential integrity validation catches actual constraint violations 90 | - Verify compatibility with MySQL, PostgreSQL, and SQLite databases 91 | - Test that column attributes (auto_increment, default values) are preserved correctly 92 | -------------------------------------------------------------------------------- /src/Transformer.php: -------------------------------------------------------------------------------- 1 | connection = $connection; 30 | $this->schemaBuilder = $connection->getSchemaBuilder(); 31 | $this->connection->getDatabaseName(); 32 | $this->setSchema(); 33 | } 34 | 35 | /** 36 | * Set console command instance for printing message to the console. 37 | * 38 | * @param Command $command 39 | * @return void 40 | */ 41 | public function setConsoleCommand(Command $command): void 42 | { 43 | $this->command = $command; 44 | } 45 | 46 | public function setSchema(?string $schema = null): void 47 | { 48 | $this->schema = $schema ?? $this->connection->getDatabaseName(); 49 | } 50 | 51 | /** 52 | * 1) Drop all foreign key constraints on each table 53 | * 2) Change INT to BIGINT on primary and foreign key columns on each table 54 | * 3) Restore all foreign key constraints on each table 55 | * 56 | * @return void 57 | */ 58 | public function transform(): void 59 | { 60 | $this->extractSchemaInfos(); 61 | 62 | $hasConstraintAnomaly = false; 63 | 64 | foreach ($this->foreignKeysConstraintsInfo as $constraint) { 65 | // If there are data that do not respect a foreign key constraint, 66 | // it will be impossible to restore the constraint after deleting it. 67 | // So, we check this before doing any action. 68 | if ($this->hasConstraintAnomaly($constraint)) { 69 | $this->message( 70 | "Foreign key constraint anomaly: [{$constraint['name']}] " 71 | ."{$constraint['table']}.{$constraint['column']} references " 72 | ."{$constraint['relatedTable']}.{$constraint['relatedColumn']}", 73 | 'error' 74 | ); 75 | 76 | $hasConstraintAnomaly = true; 77 | } 78 | } 79 | 80 | if ($hasConstraintAnomaly) { 81 | return; 82 | } 83 | 84 | // DROP FOREIGN KEY CONSTRAINTS 85 | 86 | foreach ($this->foreignKeysConstraintsInfo as $constraint) { 87 | $this->message("Drop foreign on {$constraint['table']}.{$constraint['column']}"); 88 | 89 | $this->schemaBuilder->table($constraint['table'], function (Blueprint $blueprint) use ($constraint) { 90 | $blueprint->dropForeign($constraint['name']); 91 | }); 92 | } 93 | 94 | // CHANGE INT TO BIGINT 95 | 96 | foreach ($this->intColumnsInfo as $column) { 97 | $this->message("Change INT to BIGINT for {$column['table']}.{$column['column']}"); 98 | 99 | $this->schemaBuilder->table($column['table'], function (Blueprint $blueprint) use ($column) { 100 | $blueprint 101 | ->unsignedBigInteger($column['column'], $column['autoIncrement']) 102 | ->nullable($column['nullable']) 103 | ->default($column['default']) 104 | ->change(); 105 | }); 106 | } 107 | 108 | // RESTORE FOREIGN KEY CONSTRAINTS 109 | 110 | foreach ($this->foreignKeysConstraintsInfo as $constraint) { 111 | $this->message("Restore foreign on {$constraint['table']}.{$constraint['column']}"); 112 | 113 | $this->schemaBuilder->table($constraint['table'], function (Blueprint $blueprint) use ($constraint) { 114 | $blueprint 115 | ->foreign($constraint['column'], $constraint['name']) 116 | ->references($constraint['relatedColumn']) 117 | ->on($constraint['relatedTable']) 118 | ->onDelete($constraint['onDelete']) 119 | ->onUpdate($constraint['onUpdate']); 120 | }); 121 | } 122 | } 123 | 124 | /** 125 | * On each table : 126 | * 1) Extract information on unsigned integer columns that are primary or foreign key. 127 | * 2) Extract information on foreign keys constraints concerning unsigned integer columns. 128 | * 129 | * @return void 130 | */ 131 | private function extractSchemaInfos(): void 132 | { 133 | $this->intColumnsInfo = []; 134 | $this->foreignKeysConstraintsInfo = []; 135 | 136 | foreach ($this->schemaBuilder->getTables($this->schema) as $table) { 137 | $tableName = $table['name']; 138 | $tableIntColumnsNames = []; 139 | 140 | // GET TABLE KEYS COLUMNS NAMES 141 | 142 | $tableKeysColumnsNames = []; 143 | 144 | // Get all columns for this table 145 | $columns = $this->schemaBuilder->getColumns($tableName); 146 | 147 | // Get primary keys 148 | $indexes = $this->schemaBuilder->getIndexes($tableName); 149 | foreach ($indexes as $index) { 150 | if ($index['primary']) { 151 | $tableKeysColumnsNames = array_merge($tableKeysColumnsNames, $index['columns']); 152 | } 153 | } 154 | 155 | // Get foreign keys 156 | $foreignKeys = $this->schemaBuilder->getForeignKeys($tableName); 157 | foreach ($foreignKeys as $foreignKey) { 158 | $tableKeysColumnsNames = array_merge($tableKeysColumnsNames, $foreignKey['columns']); 159 | } 160 | 161 | // GET UNSIGNED INTEGER COLUMNS NAMES AND INFOS 162 | 163 | foreach ($columns as $column) { 164 | $columnName = $column['name']; 165 | $columnType = strtolower($column['type_name'] ?? $column['type'] ?? ''); 166 | 167 | // keep only integer columns that are a key 168 | if (! $this->isIntegerType($columnType) 169 | || ! in_array($columnName, $tableKeysColumnsNames)) { 170 | continue; 171 | } 172 | 173 | $tableIntColumnsNames[] = $columnName; 174 | 175 | $this->intColumnsInfo[] = [ 176 | 'table' => $tableName, 177 | 'column' => $columnName, 178 | 'nullable' => $column['nullable'], 179 | 'default' => $column['default'], 180 | 'autoIncrement' => $column['auto_increment'], 181 | ]; 182 | } 183 | 184 | // GET FOREIGN KEYS CONSTRAINTS INFOS 185 | 186 | foreach ($foreignKeys as $foreignKey) { 187 | // keep only foreign keys that are unsigned integer 188 | if (! in_array($foreignKey['columns'][0], $tableIntColumnsNames)) { 189 | continue; 190 | } 191 | 192 | $this->foreignKeysConstraintsInfo[] = [ 193 | 'name' => $foreignKey['name'], 194 | 'table' => $tableName, 195 | 'column' => $foreignKey['columns'][0], 196 | 'relatedTable' => $foreignKey['foreign_table'], 197 | 'relatedColumn' => $foreignKey['foreign_columns'][0], 198 | 'onUpdate' => $foreignKey['on_update'], 199 | 'onDelete' => $foreignKey['on_delete'], 200 | ]; 201 | } 202 | } 203 | } 204 | 205 | /** 206 | * Check if a column type is an integer type. 207 | * 208 | * @param string $columnType 209 | * @return bool 210 | */ 211 | private function isIntegerType(string $columnType): bool 212 | { 213 | $integerTypes = [ 214 | 'int', 215 | 'integer', 216 | 'tinyint', 217 | 'smallint', 218 | 'mediumint', 219 | 'bigint', 220 | ]; 221 | 222 | foreach ($integerTypes as $type) { 223 | if (str_contains($columnType, $type)) { 224 | return true; 225 | } 226 | } 227 | 228 | return false; 229 | } 230 | 231 | /** 232 | * Says if there are data that do not respect a foreign key constraint. 233 | * 234 | * @param array $constraint 235 | * @return bool 236 | */ 237 | private function hasConstraintAnomaly(array $constraint): bool 238 | { 239 | return $this->connection 240 | ->table($constraint['table']) 241 | ->whereNotNull($constraint['column']) 242 | ->whereNotIn($constraint['column'], function ($query) use ($constraint) { 243 | $query 244 | ->from($constraint['relatedTable']) 245 | ->select($constraint['relatedColumn']); 246 | }) 247 | ->exists(); 248 | } 249 | 250 | /** 251 | * Print message to the console if set, or do an echo. 252 | * 253 | * @param string $message 254 | * @param string $style 255 | * @return void 256 | */ 257 | protected function message(string $message, string $style = 'info'): void 258 | { 259 | if ($this->command !== null) { 260 | $this->command->line($message, $style); 261 | } else { 262 | echo $message."\n"; 263 | } 264 | } 265 | } 266 | --------------------------------------------------------------------------------