laravel / framework

The Laravel Framework.
https://laravel.com
MIT License
32.66k stars 11.04k forks source link

[11.x] Introduce method `Blueprint::rawColumn()` #53496

Closed Jacobs63 closed 1 week ago

Jacobs63 commented 1 week ago

This PR introduces a new column method when creating/updating table schema.

Currently, when trying to create columns which are not natively supported by any of the grammars, we have to instead use database statements. This creates a rather big inconvenience as we cannot use a single table creation callback, because database statements are fired immediately and therefore cannot be used in Schema::create(<table>, <callback>).

Imagine a scenario, where we would like to create a:

  1. Table named posts
  2. Containing auto-increment column id
  3. Containing an integer column of display width 1 named legacy_boolean with a default value of 0
  4. Containing a composite index for these two columns

The example code to solve this would likely be as follows:

new class extends Migration {
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
        });

        DB::statement('alter table `posts` add `legacy_boolean` int(1) default 0 not null');

        Schema::table('posts', function (Blueprint $table) {
            $table->index(['id', 'legacy_boolean']);
        });
    }
};

This PR introduces a new column creation method which supports directly specifiying the column type definition used for creating a column:

new class extends Migration {
    public function up()
    {
        Schema::create('table', function (Blueprint $table) {
            $table->id();
            $table->rawColumn('legacy_boolean', 'int(1)')->default(0);
            $table->index(['id', 'legacy_boolean']);
        });
    }
};

This however has one possible drawback - this is not grammar-agnostic and therefore would be specific to the database driver used, even though, by-default, working with columns is grammar-agnostic as the underlying column definitions are compiled by the grammar implementation used by the driver. On the other hand, the previous solution using database statements is also not grammar-agnostic and therefore we're just moving the drawback from one place to another, meaning, this should not be an issue after all, as we were already facing it elsewhere.

taylorotwell commented 1 week ago

I think rawColumn would be a more fitting name as @morloderex notes. Please mark as ready for review when the requested changes have been made.

Jacobs63 commented 1 week ago

Not sure that I'm a fan of using the callback as I feel like it doesn't really have added value. The connection is already accessible via DB::connection().

Requested changes have been applied, feel free to re-check.