Giter VIP home page Giter VIP logo

laravel-migration-generator's Introduction

Laravel Migration Generator

Latest Version on Packagist

Generate migrations from existing database structures, an alternative to the schema dump provided by Laravel. A primary use case for this package would be a project that has many migrations that alter tables using ->change() from doctrine/dbal that SQLite doesn't support and need a way to get table structures updated for SQLite to use in tests. Another use case would be taking a project with a database and no migrations and turning that database into base migrations.

Installation

composer require --dev bennett-treptow/laravel-migration-generator
php artisan vendor:publish --provider="LaravelMigrationGenerator\LaravelMigrationGeneratorProvider"

Lumen Installation

composer require --dev bennett-treptow/laravel-migration-generator

Copy config file from vendor/bennett-treptow/laravel-migration-generator/config to your Lumen config folder

Register service provider in bootstrap/app.php

$app->register(\LaravelMigrationGenerator\LaravelMigrationGeneratorProvider::class);  

Usage

Whenever you have database changes or are ready to squash your database structure down to migrations, run:

php artisan generate:migrations

By default, the migrations will be created in tests/database/migrations. You can specify a different path with the --path option:

php artisan generate:migrations --path=database/migrations

You can specify the connection to use as the database with the --connection option:

php artisan generate:migrations --connection=mysql2

You can also clear the directory with the --empty-path option:

php artisan generate:migrations --empty-path

This command can also be run by setting the LMG_RUN_AFTER_MIGRATIONS environment variable to true and running your migrations as normal. This will latch into the MigrationsEnded event and run this command using the default options specified via your environment variables. Note: it will only run when your app environment is set to local.

Configuration

Want to customize the migration stubs? Make sure you've published the vendor assets with the artisan command to publish vendor files above.

Environment Variables

Key Default Value Allowed Values Description
LMG_RUN_AFTER_MIGRATIONS false boolean Whether or not the migration generator should run after migrations have completed.
LMG_CLEAR_OUTPUT_PATH false boolean Whether or not to clear out the output path before creating new files. Same as specifying --empty-path on the command
LMG_TABLE_NAMING_SCHEME [Timestamp]_create_[TableName]_table.php string The string to be used to name table migration files
LMG_VIEW_NAMING_SCHEME [Timestamp]_create_[ViewName]_view.php string The string to be used to name view migration files
LMG_OUTPUT_PATH tests/database/migrations string The path (relative to the root of your project) to where the files will be output to. Same as specifying --path= on the command
LMG_SKIPPABLE_TABLES migrations comma delimited string The tables to be skipped
LMG_SKIP_VIEWS false boolean When true, skip all views
LMG_SKIPPABLE_VIEWS '' comma delimited string The views to be skipped
LMG_SORT_MODE 'foreign_key' string The sorting mode to be used. Options: foreign_key
LMG_PREFER_UNSIGNED_PREFIX true boolean When true, uses unsigned variant methods instead of the ->unsigned() modifier.
LMG_USE_DEFINED_INDEX_NAMES true boolean When true, uses index names defined by the database as the name parameter for index methods
LMG_USE_DEFINED_FOREIGN_KEY_INDEX_NAMES true boolean When true, uses foreign key index names defined by the database as the name parameter for foreign key methods
LMG_USE_DEFINED_UNIQUE_KEY_INDEX_NAMES true boolean When true, uses unique key index names defined by the database as the name parameter for the unique methods
LMG_USE_DEFINED_PRIMARY_KEY_INDEX_NAMES true boolean When true, uses primary key index name defined by the database as the name parameter for the primary method
LMG_WITH_COMMENTS true boolean When true, export comment using ->comment() method.
LMG_USE_DEFINED_DATATYPE_ON_TIMESTAMP false boolean When false, uses ->timestamps() by mashing up created_at and updated_at regardless of datatype defined by the database
LMG_MYSQL_TABLE_NAMING_SCHEME null ?boolean When not null, this setting will override LMG_TABLE_NAMING_SCHEME when the database driver is mysql.
LMG_MYSQL_VIEW_NAMING_SCHEME null ?boolean When not null, this setting will override LMG_VIEW_NAMING_SCHEME when the database driver is mysql.
LMG_MYSQL_OUTPUT_PATH null ?boolean When not null, this setting will override LMG_OUTPUT_PATH when the database driver is mysql.
LMG_MYSQL_SKIPPABLE_TABLES null ?boolean When not null, this setting will override LMG_SKIPPABLE_TABLES when the database driver is mysql.
LMG_MYSQL_SKIPPABLE_VIEWS null comma delimited string The views to be skipped when driver is mysql
LMG_SQLITE_TABLE_NAMING_SCHEME null ?boolean When not null, this setting will override LMG_TABLE_NAMING_SCHEME when the database driver is sqlite.
LMG_SQLITE_VIEW_NAMING_SCHEME null ?boolean When not null, this setting will override LMG_VIEW_NAMING_SCHEME when the database driver is sqlite.
LMG_SQLITE_OUTPUT_PATH null ?boolean When not null, this setting will override LMG_OUTPUT_PATH when the database driver is sqlite.
LMG_SQLITE_SKIPPABLE_TABLES null ?boolean When not null, this setting will override LMG_SKIPPABLE_TABLES when the database driver is sqlite.
LMG_SQLITE_SKIPPABLE_VIEWS null comma delimited string The views to be skipped when driver is sqlite
LMG_PGSQL_TABLE_NAMING_SCHEME null ?boolean When not null, this setting will override LMG_TABLE_NAMING_SCHEME when the database driver is pgsql.
LMG_PGSQL_VIEW_NAMING_SCHEME null ?boolean When not null, this setting will override LMG_VIEW_NAMING_SCHEME when the database driver is pgsql.
LMG_PGSQL_OUTPUT_PATH null ?boolean When not null, this setting will override LMG_OUTPUT_PATH when the database driver is pgsql.
LMG_PGSQL_SKIPPABLE_TABLES null ?boolean When not null, this setting will override LMG_SKIPPABLE_TABLES when the database driver is pgsql.
LMG_PGSQL_SKIPPABLE_VIEWS null comma delimited string The views to be skipped when driver is pgsql
LMG_SQLSRV_TABLE_NAMING_SCHEME null ?boolean When not null, this setting will override LMG_TABLE_NAMING_SCHEME when the database driver is sqlsrc.
LMG_SQLSRV_VIEW_NAMING_SCHEME null ?boolean When not null, this setting will override LMG_VIEW_NAMING_SCHEME when the database driver is sqlsrv.
LMG_SQLSRV_OUTPUT_PATH null ?boolean When not null, this setting will override LMG_OUTPUT_PATH when the database driver is sqlsrv.
LMG_SQLSRV_SKIPPABLE_TABLES null ?boolean When not null, this setting will override LMG_SKIPPABLE_TABLES when the database driver is sqlsrv.
LMG_SQLSRV_SKIPPABLE_VIEWS null comma delimited string The views to be skipped when driver is sqlsrv

Stubs

There is a default stub for tables and views, found in resources/stubs/vendor/laravel-migration-generator/. Each database driver can be assigned a specific migration stub by creating a new stub file in resources/stubs/vendor/laravel-migration-generator/ with a driver-prefix, e.g. mysql-table.stub for a MySQL specific table stub.

Stub Naming

Table and view stubs can be named using the LMG_(TABLE|VIEW)_NAMING_SCHEME environment variables. Optionally, driver-specific naming schemes can be used as well by specifying LMG_{driver}_TABLE_NAMING_SCHEME environment vars using the same tokens. See below for available tokens that can be replaced.

Table Name Stub Tokens

Table stubs have the following tokens available for the naming scheme:

Token Example Description
[TableName] users Table's name, same as what is defined in the database
[TableName:Studly] Users Table's name with Str::studly() applied to it (useful for standardizing table names if they are inconsistent)
[TableName:Lowercase] users Table's name with strtolower applied to it (useful for standardizing table names if they are inconsistent)
[Timestamp] 2021_04_25_110000 The standard migration timestamp format, at the time of calling the command: Y_m_d_His
[Index] 0 The key of the migration in the sorted order, for use with enforcing a sort order
[IndexedEmptyTimestamp] 0000_00_00_000041 The standard migration timestamp format, but filled with 0s and incremented by [Index] seconds
[IndexedTimestamp] 2021_04_25_110003 The standard migration timestamp format, at the time of calling the command: Y_m_d_His incremented by [Index] seconds

Table Schema Stub Tokens

Table schema stubs have the following tokens available:

Token Description
[TableName] Table's name, same as what is defined in the database
[TableName:Studly] Table's name with Str::studly() applied to it, for use with the class name
[TableUp] Table's up() function
[TableDown] Table's down() function
[Schema] The table's generated schema

View Name Stub Tokens

View stubs have the following tokens available for the naming scheme:

Token Example Description
[ViewName] user_earnings View's name, same as what is defined in the database
[ViewName:Studly] UserEarnings View's name with Str::studly() applied to it (useful for standardizing view names if they are inconsistent)
[ViewName:Lowercase] user_earnings View's name with strtolower applied to it (useful for standardizing view names if they are inconsistent)
[Timestamp] 2021_04_25_110000 The standard migration timestamp format, at the time of calling the command: Y_m_d_His
[Index] 0 The key of the migration in the sorted order, for use with enforcing a sort order
[IndexedEmptyTimestamp] 0000_00_00_000041 The standard migration timestamp format, but filled with 0s and incremented by [Index] seconds
[IndexedTimestamp] 2021_04_25_110003 The standard migration timestamp format, at the time of calling the command: Y_m_d_His incremented by [Index] seconds

View Schema Stub Tokens

View schema stubs have the following tokens available:

Token Description
[ViewName] View's name, same as what is defined in the database
[ViewName:Studly] View's name with Str::studly() applied to it, for use with the class name
[Schema] The view's schema

Example Usage

Given a database structure for a users table of:

CREATE TABLE `users` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `username` varchar(128) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `first_name` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `last_name` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `timezone` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'America/New_York',
  `location_id` int(10) unsigned NOT NULL,
  `deleted_at` timestamp NULL DEFAULT NULL,
  `remember_token` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `users_username_index` (`username`),
  KEY `users_first_name_index` (`first_name`),
  KEY `users_last_name_index` (`last_name`),
  KEY `users_email_index` (`email`),
  KEY `fk_users_location_id_index` (`location_id`)
  CONSTRAINT `users_location_id_foreign` FOREIGN KEY (`location_id`) REFERENCES `locations` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

A tests/database/migrations/[TIMESTAMP]_create_users_table.php with the following Blueprint would be created:

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('username', 128)->nullable()->index();
            $table->string('email', 255)->index();
            $table->string('password', 255);
            $table->string('first_name', 45)->nullable()->index();
            $table->string('last_name', 45)->index();
            $table->string('timezone', 45)->default('America/New_York');
            $table->unsignedInteger('location_id');
            $table->softDeletes();
            $table->string('remember_token', 255)->nullable();
            $table->timestamps();
            $table->foreign('location_id', 'users_location_id_foreign')->references('id')->on('locations')->onUpdate('cascade')->onDelete('cascade');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
}

Currently Supported DBMS's

These DBMS's are what are currently supported for creating migrations from. Migrations created will, as usual, follow what database drivers Laravel migrations allow for

  • MySQL
  • Postgres
  • SQLite
  • SQL Server

laravel-migration-generator's People

Contributors

bennett-treptow avatar christhompsontldr avatar hellerbenjamin avatar jimbolino avatar kevinb1989 avatar laravel-shift avatar nacl30d avatar ordago avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

laravel-migration-generator's Issues

Undefined offset: 1 in ColumnTokenizer.php:76

 165/206 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░]  80%
   ErrorException 

  Undefined offset: 1

  at vendor/bennett-treptow/laravel-migration-generator/src/Tokenizers/MySQL/ColumnTokenizer.php:76
     72▕ 
     73▕         $this->resolveColumnMethod();
     74▕         if ($hasConstraints) {
     75▕             preg_match("/\((.+?)\)/", $originalColumnType, $constraintMatches);
  ➜  76▕             $matches = explode(',', $constraintMatches[1]);
     77▕             $this->resolveColumnConstraints($matches);
     78▕         }
     79▕     }
     80▕ 

it crashes on the enum "calculate":

CREATE TABLE `pr_feature` (
  `feature_id` int unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL,
  `description` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
  `sysname` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL,
  `sysvalue` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL,
  `pos` int unsigned DEFAULT '1',
  `status` tinyint(1) DEFAULT '1' COMMENT '0: disabled; 1:enabled',
  `cl_publication_type_publication_type_id` tinyint DEFAULT NULL,
  `editable_user_rights` tinyint NOT NULL COMMENT '0: feature is not editable by users; 1: show in overview user features editable',
  `category` enum('module','setting','special','publication_type','option','admin_option','admin_feature','admin_limit','admin_preset','deprecated') COLLATE utf8mb4_general_ci DEFAULT NULL,
  `feature_type` tinyint NOT NULL COMMENT '0: view(analytics); 1:property(500 mb)',
  `calculate` enum('one','and','highest or','lowest or','sum','highest position or','lowest position or') COLLATE utf8mb4_general_ci NOT NULL COMMENT 'set the way we calculate a feature value. with high or low or the sort is by position',
  PRIMARY KEY (`feature_id`),
  KEY `status` (`status`),
  KEY `sysname` (`sysname`),
  KEY `editable_user_rights` (`editable_user_rights`) USING BTREE,
  KEY `feature_type` (`feature_type`) USING BTREE,
  KEY `cl_publication_type_publication_type_id` (`cl_publication_type_publication_type_id`)
) ENGINE=InnoDB AUTO_INCREMENT=133 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;

[BUG]

Package Version
What version are you running? 4.3

Database Version
MariaDB 10.6.7

Describe the bug
Error is thrown when running php artisan migrate for the portion of generated migration ex. $table->timestamp('created_at')->default('current_timestamp()');

To Reproduce
CREATE TABLE test(idINT NOT NULL AUTO_INCREMENT ,created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP , PRIMARY KEY (id)) ENGINE = InnoDB;

Expected behavior
Above should be translated to:
$table->timestamp('created_at')->useCurrent();

Screenshots

Additional context

[BUG] ErrorException Required parameter $output follows optional parameter $tableNames

Package Version
"laravel/sail": "^1.0.1",
"php": "^8.0",
"laravel/framework": "^8.12",

Database Version
Mysql 5.7.19

Describe the bug
When trying to run the command, I receive a Exception described below.
ErrorException
Required parameter $output follows optional parameter $tableNames

To Reproduce
command: sail php artisan generate:migrations --connection=mysql2

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
image

Additional context
Maybe the style of function declaration is deprecated on PHP 8.

PHP 8.0.2 (cli) (built: Feb 14 2021 14:21:37) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.2, Copyright (c) Zend Technologies
with Zend OPcache v8.0.2, Copyright (c), by Zend Technologies
with Xdebug v3.0.2, Copyright (c) 2002-2021, by Derick Rethans

How to use the LMG_OUTPUT_PATH for actual testing

This is a wonderful solution and perfect for my testing needs since it created all the migrations from my long default migrations list. I was wondering if its actually possible to use those migrations located at the specific folder, just for testing while leaving the default migrations path for the application .

As I understand we can enable LMG_RUN_AFTER_MIGRATIONS so that whenever you do php artisan migrate after that php artisan generate:migrations gets executed .

My issue is, how can i set php artisan test to point to another migrations path and use testing\database\migrations for speeding up the tests.

Is this possible?

[BUG] TypeError after update to 3.1.4

Package Version

3.1.4

Database Version

MySQL 8.0.23

PHP Version

7.4.16

Describe the bug

TypeError 

Argument 2 passed to LaravelMigrationGenerator\GeneratorManagers\MySQLGeneratorManager::handle() must be an instance of Illuminate\Console\OutputStyle, array given, called in /../vendor/bennett-treptow/laravel-migration-generator/src/Commands/GenerateMigrationsCommand.php on line 80

To Reproduce

php artisan generate:migrations --path=database/migrations/test

Generate Migration that would insert newly created migration files into migrate table

Would be neat if I could add an additional flag to to the command such that an Additional migration file would be created with dates and timestamps set so it would run first. The migration would insert into the migrations table, all the files generated by the run. This way you could squash the migration files but these would NOT run in production causing a bigger problem.

[BUG]Return value of LaravelMigrationGenerator\Generators\BaseTableGenerator::getStubFileName() must be of the type string, null returned

Package Version
What version are you running? 2.2., 3.

Database Version
Driver: PDO
Database: MySQL 8.0.25

Describe the bug

Using connection mysql
Using [laravel path] as the output path..



   TypeError

  Return value of LaravelMigrationGenerator\Generators\BaseTableGenerator::getStubFileName() must be of the type string, null returned

  at [laravel path]\vendor\bennett-treptow\laravel-migration-generator\src\Generators\Concerns\WritesTablesToFile.php:41
     37▕                 $baseStubFileName = preg_replace("/\[" . $variable . "\]/i", $replacement, $baseStubFileName);
     38▕             }
     39▕         }
     40▕
  ➜  41▕         return $baseStubFileName;
     42▕     }
     43▕
     44▕     protected function getStubPath(): string
     45▕     {

  1   [laravel path]\vendor\bennett-treptow\laravel-migration-generator\src\Generators\Concerns\WritesToFile.php:16
      LaravelMigrationGenerator\Generators\BaseTableGenerator::getStubFileName()

  2   [laravel path]\vendor\bennett-treptow\laravel-migration-generator\src\GeneratorManagers\MySQLGeneratorManager.php:52
      LaravelMigrationGenerator\Generators\BaseTableGenerator::write()`

To Reproduce
php artisan generate:migrations

What could be the issue?

Option to define/add the named indexes

Suggestion

This is just a suggestion.

In one of my original migrations, I set up a unique named index.

$table->string('name_base', 50)->default('')->unique('UniqueBaseName');

MySQL (SHOW CREATE TABLE tablename;):

UNIQUE KEY `UniqueBaseName` (`name_base`)

In the migration created by this package, the existing name of the unique index was not defined.

$table->string('name_base', 50)->default('')->unique();

This may also be an option in the config, as some indexes can be automatically named by the database.

[BUG] Call to a member function `useCurrent()` on null

Package Version: 3.1.5

Database Version: mysql Ver 8.0.23-0ubuntu0.20.04.1 for Linux on x86_64 ((Ubuntu))

Describe the bug

Generating some tables with timestamps creates this syntax:

$table->timestamps()->useCurrent();

which is not valid syntax because the timestamps function does not return a ColumnDefinition

To Reproduce

create table test_table
(
    id              int auto_increment
        primary key,
    created_at      timestamp       default CURRENT_TIMESTAMP not null,
    updated_at      timestamp                                 null on update CURRENT_TIMESTAMP
)

Expected behavior

Expected generation to create:

$table->timestamp('created_at')->nullable()->useCurrent();
$table->timestamp('updated_at')->nullable()->useCurrentOnUpdate();

P.S. Your package is a huge time saver! Thank you so much.

Ordering migration by foreign key requirement

The package doesn't order migration based on foreign key relation, assuming i have a table consisting of admins, roles, admin_roles, the package first create migration for admin_roles before that of admins and roles thereby causing incorrect foreign key as admin is supposed to have been migrated before the admin_roles

COMMENT is not handled properly.

When generating a migration with a default value and a comment for a column, it creates this line
$table->string('Value', 45)->default('0 COMMENT 'action');
when it should be this:
$table->string('Value', 45)->default(0)->comment('action');

SQLSTATE[42000]: on generate:migration

1/27 [▓░░░░░░░░░░░░░░░░░░░░░░░░░░░] 3%
Illuminate\Database\QueryException

SQLSTATE[42000]: Syntax error or access violation: 1055 'be_f.o.user_id' isn't in GROUP BY (SQL: SHOW CREATE VIEW view_operation_sum_all)

add option to skip views

I would really like an option to skip all views.
Or alternatively, add an "skippable_views" option or extend the "skippable_tables" config so that it is possible to skip views too :)

Suggested Enhancement: Connection feature

Love the existing functionality. I ran the 4.0 version and everything worked great! Had to alter all my migrations to accommodate my use case. In my use case, I'm converting an existing MySQL database to an SQLite database.

Changed Schema::create() to Schema::connection('sqlite_foo')->create()

If we had a flag to use the connection name or the connection's database name that would be super helpful. As an extra having a template variable name for the database and/or connection so it could be used when creating and naming the migration files would be nice too.

Again very thankful for what you brought to the community. Thank you!!!

[BUG] Apostrophes in column comment value not escaped

Package Version
What version are you running? 2.2., 3.
4.1.2

Database Version
What database driver are you using? And what version is that database?
MySQL

Describe the bug
A clear and concise description of what the bug is.
When generating migrations, if the table has a comment that contains an apostrophe, the apostrophe isn't escaped in the migration.

To Reproduce
Please include any stack traces and applicable .env / config changes you've made
Create a table with a comment that contains an apostrophe, then generate a migration.

Expected behavior
A clear and concise description of what you expected to happen.
The apostrophes in comments should be escaped.

Screenshots
If applicable, add screenshots to help explain your problem.
image

Additional context
Add any other context about the problem here.

[BUG] Creates multiple foreign key migrations that should be in the original file

Package Version
4.4.0

Database Version
MySQL 8.0.19

Describe the bug
When running the generate command the package creates duplicate foreign key entry files.

To Reproduce
No changes to the default config other than clearing the output directory.

Expected behavior
Package should implement the foreign key inside the original table creation migration file, or at the very least, if it must create a separate file, it should not make duplicates of it.

Screenshots
Screenshot 2024-04-03 at 1 13 42 PM

Thanks

Migration does not generator properly if field has empty default value and apostrophe in comment

Package Version
4.3.1

Database Version
MySQL 8.0.27

Describe the bug
I have quite a few varchar fields that have a default value of '' and a comment that contains an apostrophe, when this occurs the migration that generates looks like the following:

->default(')->comment("Code to identify the part's manufacturer.")

To Reproduce
I was able to add a test to ColumnTokenizerTest that recreates the issue

public function test_it_tokenizes_varchar_with_default_empty_string_and_comment_with_apostrophe()
{
    $columnTokenizer = ColumnTokenizer::parse("`testing` varchar(255) DEFAULT '' COMMENT 'test with an apostrophe ('')'");
    $columnDefinition = $columnTokenizer->definition();
    $this->assertEquals('', $columnDefinition->getDefaultValue());
    $this->assertEquals('test with an apostrophe (\')', $columnDefinition->getComment());
}

I was able to "fix" the issue locally by adding the following code to the BaseTokenizer class. This obviously isn't a valid fix, but was good enough to get around the issue for myself.

$value = str_replace("DEFAULT ''", '----------', $value);

//first get rid of any single quoted stuff with '' around it
if (preg_match_all('/\'\'(.+?)\'\'/', $value, $matches)) {
    ray($matches);
    foreach ($matches[0] as $key => $singleQuoted) {
        $toReplace = $singleQuoted;
        $value = str_replace($toReplace, self::SINGLE_QUOTE_REPLACER . $matches[1][$key] . self::SINGLE_QUOTE_REPLACER, $value);
        $pruneSingleQuotes = true;
    }
}

$value = str_replace('----------', "DEFAULT ''", $value);

Expected behavior
I would expect a migration to be generated like below:

->default('')->comment("Code to identify the part's manufacturer.")

Additional context
I was going to create a pull request to fix the issue, but I'm not great with regex and wasn't sure of the best way to fix the issue correctly.

[BUG] "The `pgsql` driver is not supported at this time."

Package Version
3.1.5

Database Version
PostgreSQL

Describe the bug

▶ php artisan generate:migrations --connection=pgsql
Using connection pgsql
The `pgsql` driver is not supported at this time.

To Reproduce
Use postgresql

Expected behavior
A migration dump of the postgresql database

Undefined offset: 0 in WritesTablesToFile.php:38

When I run php artisan generate:migrations with the default configs, I got this error:

Using connection mysql
Using /var/www/network/tests/database/migrations as the output path..

   1/103 [░░░░░░░░░░░░░░░░░░░░░░░░░░░░]   0% < 1 sec/< 1 sec 26.0 MiB
   ErrorException 

  Undefined offset: 0

  at vendor/bennett-treptow/laravel-migration-generator/src/Generators/Concerns/WritesTablesToFile.php:38
     34▕         $baseStubFileName = ConfigResolver::tableNamingScheme($driver);
     35▕         foreach ($this->stubNameVariables() as $variable => $replacement) {
     36▕             if (is_callable($replacement)) {
     37▕                 //replacement is a closure
  ➜  38▕                 [$variable, $replacement] = $replacement($baseStubFileName);
     39▕             }
     40▕             if ($variable === null) {
     41▕                 continue;
     42▕             }

[BUG]

Package Version
What version are you running? 4.2.1

Database Version
Mysql 5.7.37

Describe the bug
I encountered an error while testing:

ParseError: syntax error, unexpected '0' (T_LNUMBER), expecting ')'

Debugging revealed that it's because of the migration file.

We've b'0' as a default value for the one of fields.
It seems "Laravel migration generator" doesn't check ' (single quote). default('b'0'')->

To Reproduce

  • Add b'0' as a default value for a field
  • php artisan generate:migrations
  • Check the migration file.

Expected behavior
Can we replace single quotes with double?

[BUG]

Package Version
3.2

Database Version
MariaDB 10.3 (XAMPP 3.2.4)

Describe the bug
Migration files are successfully generated. I then do the following

  1. move them from the test/database/migrations folder to database/migrations folder
  2. create a blank database and set the .env file to point to this
  3. run php artisan migrate

It gives this error on the very first table it attempts to create (i.e. nothing is successfully created):

`PHP Fatal error:  Cannot declare class CreateAllActivitiesHistoryTable, because the name is already in use in 
C:\Users\user1\dev\laravel\migratetest\database\migrations\create_all_activities_istory_table.php on line 7

   Symfony\Component\ErrorHandler\Error\FatalError

  Cannot declare class CreateAllActivitiesHistoryTable, because the name is already in use

  at C:\Users\user1\dev\laravel\migratetest\database\migrations\create_all_activities_history_table.php:7
      3▕ use Illuminate\Support\Facades\Schema;
      4▕ use Illuminate\Database\Schema\Blueprint;
      5▕ use Illuminate\Database\Migrations\Migration;
      6▕
      7▕ class CreateAllActivitiesHistoryTable extends Migration
      8▕ {
      9▕     /**
     10▕      * Run the migrations.
     11▕      *


   Whoops\Exception\ErrorException`

To Reproduce
As described above

Expected behavior
I expect the database structure to be created into this new blank database

Screenshot
image

Additional context
I have tried to fix with all suggestions here but they do not work (except the grep commands since this is Windows 10 environment).

However I have checked the migrations folder and there is only one file for each migration so it's unclear to me where this class is being redeclared and throwing the error.

PHP version is 7.4.3

Auto-incrementing in `id` field that should not have auto-incrementing.

First of all, I want to thank you for this package. It saved me a lot of work.

The primary key that I set up in my original migration.

$table->unsignedInteger('id')->nullable(false)->primary();

The field generated by this package. In addition, the definition as a primary key is missing.

$table->increments('id');

In this table, specifically, there cannot be auto-increment in the id field since the ids are pre-established.

Suggestion

Instead of using:

$table->integer(xx)->unsigned()

Use

$table->unsignedInteger(xx)

According to the field types of laravel 8.

[BUG] Cannot migrate the Default Time Stamp value

The solution, if you use ''CURRENT_TIMESTAMP' as a default value, the generation need to create this schema:
$table->timestamp('date')->default(DB::raw('CURRENT_TIMESTAMP'));
and need to add this: use Illuminate\Support\Facades\DB;

[BUG] cannot generate migrations for multiple tables

Package Version
What version are you running? 4.3.1

Database Version
MariaDB 10.6.7

Describe the bug
I cannot generate the migration for multiple tables tried many commands it simply generates the empty folder

To Reproduce

php artisan generate:migrations --table="countries,states"

Expected behavior
It should generate migrations for countries and states table

Screenshots
If applicable, add screenshots to help explain your problem.
Screenshot 2023-07-02 at 3 25 01 PM

Screenshot 2023-07-02 at 3 25 14 PM

Additional context
When i run this command php artisan generate:migrations it generates the migration for all the tables successfully. I want to generate migration only for specific tables

BadMethodCallException Method LaravelMigrationGenerator\Commands\GenerateMigrationsCommand::newLine does not exist.

Got the following exception

# php artisan generate:migrations
Using connection mysql
Using /var/www/html/tests/database/migrations as the output path..

   BadMethodCallException 

  Method LaravelMigrationGenerator\Commands\GenerateMigrationsCommand::newLine does not exist.

  at vendor/laravel/framework/src/Illuminate/Support/Traits/Macroable.php:103
     99|      */
    100|     public function __call($method, $parameters)
    101|     {
    102|         if (! static::hasMacro($method)) {
  > 103|             throw new BadMethodCallException(sprintf(
    104|                 'Method %s::%s does not exist.', static::class, $method
    105|             ));
    106|         }
    107| 

  • Bad Method Call: Did you mean LaravelMigrationGenerator\Commands\GenerateMigrationsCommand::line() ? 

      +14 vendor frames 
  15  artisan:37
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

[BUG] sort_mode foreign_key -> Dependency `REFERENCES` not found

Package Version
4.0.1

Database Version
mysql 8.0.26-0ubuntu0.20.04.3

Describe the bug

$ php artisan generate:migrations --verbose
Using connection mysql
Using /home/jim/projects/maglr/dashboard/tests/database/migrations as the output path..

   MJS\TopSort\ElementNotFoundException 

  Dependency `REFERENCES` not found, required by `js_spread_text`

  at vendor/marcj/topsort/src/ElementNotFoundException.php:40
    36|      */
    37|     public static function create($source, $target)
    38|     {
    39|         $message = sprintf('Dependency `%s` not found, required by `%s`', $target, $source);
  > 40|         $exception = new static($message, 0, null, $source, $target);
    41| 
    42|         return $exception;
    43|     }
    44| 

  1   vendor/marcj/topsort/src/Implementations/ArraySort.php:77
      MJS\TopSort\ElementNotFoundException::create()

  2   vendor/marcj/topsort/src/Implementations/FixedArraySort.php:50
      MJS\TopSort\Implementations\ArraySort::visit()

  3   vendor/marcj/topsort/src/Implementations/FixedArraySort.php:33
      MJS\TopSort\Implementations\FixedArraySort::doSort()

  4   vendor/bennett-treptow/laravel-migration-generator/src/Helpers/DependencyResolver.php:51
      MJS\TopSort\Implementations\FixedArraySort::sort()

  5   vendor/bennett-treptow/laravel-migration-generator/src/Helpers/DependencyResolver.php:21
      LaravelMigrationGenerator\Helpers\DependencyResolver::build()

  6   vendor/bennett-treptow/laravel-migration-generator/src/GeneratorManagers/BaseGeneratorManager.php:105
      LaravelMigrationGenerator\Helpers\DependencyResolver::__construct()

  7   vendor/bennett-treptow/laravel-migration-generator/src/GeneratorManagers/BaseGeneratorManager.php:87
      LaravelMigrationGenerator\GeneratorManagers\BaseGeneratorManager::sortTables()

  8   vendor/bennett-treptow/laravel-migration-generator/src/Commands/GenerateMigrationsCommand.php:80
      LaravelMigrationGenerator\GeneratorManagers\BaseGeneratorManager::handle()

  9   vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:36
      LaravelMigrationGenerator\Commands\GenerateMigrationsCommand::handle()

Screenshots
image
image

Additional context
A bit of an uncommon many to many relation from our end. Where we want the records to be deleted, if any of the references gets deleted. I think it is this "composite foreign key" that is causing the crash.

File malformatted when comments are present

Package Version
What version are you running? 4.2.2

Database Version
Mysql 8.0.27

Describe the bug

There seem to be an error from time to time (it doesn't seem consistent) when generating migrations.

There's a syntax error.

public function up()
{
Schema::create('warehouses', function (Blueprint $table) {
$table->smallIncrements('warehouse_id')->unsigned()->primary();
$table->string('warehouse_name', 120)->default(' COMMENT 'The');
$table->dateTime('warehouse_created_utc', 6)->nullable();
$table->dateTime('warehouse_modified_utc', 6)->nullable();
$table->dateTime('warehouse_deleted_utc', 6)->nullable();
});
}

image

Thanks

[BUG] Typed propert $foreignReferencedTable must not be accessed before initialization

Package Version
What version are you running?
4.1.0

Database Version
What database driver are you using? And what version is that database?
MySQL. mariadb:10.2 image

Describe the bug
A clear and concise description of what the bug is.
I'm running php 7.4. After requiring and publishing this package according to the package docs, I run it via php artisan generate:migrations. From there, I get the following error:
Typed property LaravelMigrationGenerator\Definitions\IndexDefinition::$foreignReferencedTable must not be accessed before initialization

php artisan generate:migrations
Using connection mysql
Using /app/tests/database/migrations as the output path..

   Error 

  Typed property LaravelMigrationGenerator\Definitions\IndexDefinition::$foreignReferencedTable must not be accessed before initialization

  at vendor/bennett-treptow/laravel-migration-generator/src/Definitions/IndexDefinition.php:74
     70▕      * @return string
     71▕      */
     72▕     public function getForeignReferencedTable(): string
     73▕     {
  ➜  74▕         return $this->foreignReferencedTable;
     75▕     }
     76▕
     77▕     /**
     78▕      * @return array

      +18 vendor frames
  19  artisan:37
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

To Reproduce
Please include any stack traces and applicable .env / config changes you've made
Stack trace:

[2022-01-24 19:29:21] local.ERROR: Typed property LaravelMigrationGenerator\Definitions\IndexDefinition::$foreignReferencedTable must not be accessed before initialization {"exception":"[object] (Error(code: 0): Typed property LaravelMigrationGenerator\\Definitions\\IndexDefinition::$foreignReferencedTable must not be accessed before initialization at /app/vendor/bennett-treptow/laravel-migration-generator/src/Definitions/IndexDefinition.php:74)
[stacktrace]
#0 /app/vendor/bennett-treptow/laravel-migration-generator/src/Helpers/DependencyResolver.php(37): LaravelMigrationGenerator\\Definitions\\IndexDefinition->getForeignReferencedTable()
#1 /app/vendor/bennett-treptow/laravel-migration-generator/src/Helpers/DependencyResolver.php(21): LaravelMigrationGenerator\\Helpers\\DependencyResolver->build()
#2 /app/vendor/bennett-treptow/laravel-migration-generator/src/GeneratorManagers/BaseGeneratorManager.php(105): LaravelMigrationGenerator\\Helpers\\DependencyResolver->__construct(Array)
#3 /app/vendor/bennett-treptow/laravel-migration-generator/src/GeneratorManagers/BaseGeneratorManager.php(87): LaravelMigrationGenerator\\GeneratorManagers\\BaseGeneratorManager->sortTables(Array)
#4 /app/vendor/bennett-treptow/laravel-migration-generator/src/Commands/GenerateMigrationsCommand.php(80): LaravelMigrationGenerator\\GeneratorManagers\\BaseGeneratorManager->handle('/app/tests/data...', Array, Array)
#5 /app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): LaravelMigrationGenerator\\Commands\\GenerateMigrationsCommand->handle()
#6 /app/vendor/laravel/framework/src/Illuminate/Container/Util.php(40): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#7 /app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(93): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#8 /app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(37): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#9 /app/vendor/laravel/framework/src/Illuminate/Container/Container.php(653): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#10 /app/vendor/laravel/framework/src/Illuminate/Console/Command.php(136): Illuminate\\Container\\Container->call(Array)
#11 /app/vendor/symfony/console/Command/Command.php(298): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#12 /app/vendor/laravel/framework/src/Illuminate/Console/Command.php(121): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#13 /app/vendor/symfony/console/Application.php(1005): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#14 /app/vendor/symfony/console/Application.php(299): Symfony\\Component\\Console\\Application->doRunCommand(Object(LaravelMigrationGenerator\\Commands\\GenerateMigrationsCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#15 /app/vendor/symfony/console/Application.php(171): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#16 /app/vendor/laravel/framework/src/Illuminate/Console/Application.php(94): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 /app/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(129): Illuminate\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /app/artisan(37): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#19 {main}
"} 

Expected behavior
A clear and concise description of what you expected to happen.
I expect migrations to be generated.

Screenshots
If applicable, add screenshots to help explain your problem.

Additional context
I upgraded from php 7.3.7 to php 7.4 to use this package. Is there a better php version to use? Some google searches show that "Typed properties" were added into php 7.4

Create the `seed` from the data

Suggestion

This package for Laravel does an exceptional job and has saved a lot of development time on creating the new migrations from the existing tables.

A feature that would be nice to have implemented in this package is creating the seed from the data.

Command example:

php artisan generate:migrations --seed=model --transaction
php artisan generate:migrations --seed=table // no transaction

Seeder example:

class UserSeeder extends Seeder
{
    public function run()
    {
        // With or without closure transaction
        DB::transaction(function () {

            // Multiple insertions
            DB::table('users')->insert(['name1..' => 'Name', 'email' => 'email1...', 'password' => 'hash1...']);
            DB::table('users')->insert(['name2..' => 'Name', 'email' => 'email2...', 'password' => 'hash2...']);
            DB::table('users')->insert(['name3..' => 'Name', 'email' => 'email3...', 'password' => 'hash3...']);

            // Or multiple creations
            User::create(['name1..' => 'Name', 'email' => 'email1...', 'password' => 'hash1...']);
            User::create(['name2..' => 'Name', 'email' => 'email2...', 'password' => 'hash3...']);
            User::create(['name3..' => 'Name', 'email' => 'email3...', 'password' => 'hash3...']);
        });


        // or data in array
        $data = [
            ['name1..' => 'Name', 'email' => 'email1...', 'password' => 'hash1...'],
            ['name2..' => 'Name', 'email' => 'email2...', 'password' => 'hash2...'],
            ['name3..' => 'Name', 'email' => 'email3...', 'password' => 'hash3...'],
        ];

        // Transaction in another way
        try {
            DB::beginTransaction();
            foreach ($data as $item) {
                // table
                DB::table('users')->insert($item);
                // model
                User::create($item);
            }
            DB::commit();
        } catch (Throwable $e) {
            DB::rollback();
        }
    }
}

There is a package that does this, but it is out of date.
https://github.com/orangehill/iseed

[BUG] Call to a member function filter() on array

Package Version
4.1

Database Version
MySQL 5.7.12

Describe the bug
Getting this error when running "php artisan generate:migrations --env local --table article"

 Error

  Call to a member function filter() on array

  at vendor/bennett-treptow/laravel-migration-generator/src/GeneratorManagers/BaseGeneratorManager.php:79
     75▕                 return in_array($viewGenerator->getViewName(), $viewNames);
     76▕             })->toArray();
     77▕         }
     78▕
  ➜  79▕         $tableDefinitions = $tableDefinitions->filter(function ($tableDefinition) {
     80▕             return ! $this->skipTable($tableDefinition->getTableName());
     81▕         });
     82▕
     83▕         $viewDefinitions = $viewDefinitions->filter(function ($viewDefinition) {

      +14 vendor frames
  15  artisan:37
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.