有没有办法使用Laravel 5 Migrations创建一个citext字段?

CJ *_*son 2 php postgresql laravel laravel-5 laravel-migrations

具体来说,由于MySQL没有该字段类型,原始数据库查询似乎是一个坏主意.由于默认情况下pgsql缺少不区分大小写的文本字段,因此我们不得不使用此扩展(当然,它完美地运行),但现在面临着迁移的两难困境.

pat*_*cus 6

更新

我创建了一个实现此功能的包.它passthru()为迁移添加了一种方法,以便您可以创建任何您想要的字段类型.在此示例中,在安装软件包并添加服务提供程序之后,您只需执行$table->passthru('citext', 'name');迁移文件.该包被称为"laravel-nomad",可以在githubpackagist上找到.


是的,这可以做到.它需要扩展一些核心文件,但它是可行的.具体来说,您将需要新的连接,模式语法和蓝图.

首先,在目录下创建一个新目录app以保存自定义文件.例如,app/Extension.放在此目录中的文件将扩展核心Illuminate文件,因此您将复制此新目录下的Illuminate文件夹结构.

蓝图

要添加可用于迁移的新方法,您需要更新蓝图.您将创建一个扩展核心Blueprint类的自定义Blueprint类.这个自定义Blueprint类将包含新方法(例如ciText()).

应用/扩展/数据库/模式/ PostgresCustomBlueprint.php

<?php namespace App\Extension\Database\Schema;

use Illuminate\Database\Schema\Blueprint;

class PostgresCustomBlueprint extends Blueprint {

    /**
     * Create a new case-insensitive text column on the table.
     *
     * @param  string  $column
     * @return \Illuminate\Support\Fluent
     */
    public function ciText($column)
    {
        return $this->addColumn('ciText', $column);
    }

}
Run Code Online (Sandbox Code Playgroud)

架构语法

更新Blueprint以允许该ciText()方法后,您需要更新模式语法以便能够处理该ciText字段.您将创建一个自定义模式语法类,该类扩展了核心PostgresGrammar模式语法类.此自定义架构语法将具有将Blueprint ciText列转换为citext字段的方法.

应用/扩展/数据库/模式/文法/ PostgresCustomGrammar.php

<?php namespace App\Extension\Database\Schema\Grammars;

use Illuminate\Database\Schema\Grammars\PostgresGrammar;
use Illuminate\Support\Fluent;

class PostgresCustomGrammar extends PostgresGrammar {

    /**
     * Create the column definition for a citext type.
     *
     * @param  \Illuminate\Support\Fluent  $column
     * @return string
     */
    protected function typeCiText(Fluent $column)
    {
        return 'citext';
    }

}
Run Code Online (Sandbox Code Playgroud)

连接

既然您有自定义蓝图和允许使用该citext字段的自定义模式语法,您需要创建将使用这些新自定义类的自定义连接.此自定义Connection类将扩展核心PostgresConnection类,以覆盖使用自定义模式语法和自定义蓝图所需的方法.

应用/扩展/数据库/ PostgresCustomConnection.php

<?php namespace App\Extension\Database;

use Illuminate\Database\PostgresConnection;
use App\Extension\Database\Schema\Grammars\PostgresCustomGrammar as SchemaGrammar;
use App\Extension\Database\Schema\PostgresCustomBlueprint;

class PostgresCustomConnection extends PostgresConnection {

    /**
     * Get the default schema grammar instance.
     *
     * @return \App\Extension\Database\Schema\Grammars\PostgresCustomGrammar
     */
    protected function getDefaultSchemaGrammar()
    {
        return $this->withTablePrefix(new SchemaGrammar);
    }

    /**
     * Get a schema builder instance for the connection.
     *
     * @return \Illuminate\Database\Schema\Builder
     */
    public function getSchemaBuilder()
    {
        $parentBuilder = parent::getSchemaBuilder();

        // add a blueprint resolver closure that returns the custom blueprint
        $parentBuilder->blueprintResolver(function($table, $callback) {
            return new PostgresCustomBlueprint($table, $callback);
        });

        return $parentBuilder;
    }

}
Run Code Online (Sandbox Code Playgroud)

服务提供者

现在已经设置了自定义连接,您需要告诉Laravel使用它.您可以覆盖内置pgsql驱动程序以使用PostgresCustomConnection该类,也可以pgsql-custom为新连接创建新的驱动程序名称(例如).

如果您只想覆盖内置pgsql驱动程序,则需要register()将以下行添加到app/Providers/AppServiceProvider.php文件中的方法:

$this->app->bind('db.connection.pgsql', 'App\Extension\Database\PostgresCustomConnection');
Run Code Online (Sandbox Code Playgroud)

如果要创建新的驱动程序名称(例如pgsql-custom),则需要register()app/Providers/AppServiceProvider.php文件中的方法中添加以下两行:

$this->app->bind('db.connector.pgsql-custom', 'Illuminate\Database\Connectors\PostgresConnector');
$this->app->bind('db.connection.pgsql-custom', 'App\Extension\Database\PostgresCustomConnection');
Run Code Online (Sandbox Code Playgroud)

数据库配置

如果您创建新的驱动程序名称,请确保更新您的config/database.php文件以设置driver连接上的密钥值pgsql-custom(或您为驱动程序命名的任何内容).

工匠

最后,运行artisan命令以确保可以找到所有类并更新任何缓存(编译)版本app/Providers/AppServiceProvider:

composer dump-autoload
php artisan clear-compiled
php artisan optimize
Run Code Online (Sandbox Code Playgroud)

移民

现在,您可以ciText()在迁移中使用该方法,它将创建一个citext字段.

<?php

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->engine = 'InnoDB';

            $table->increments('id');
            $table->timestamps();
            $table->ciText('name');
            $table->ciText('email')->unique();
            $table->string('password', 60);
            $table->rememberToken();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('users');
    }
}
Run Code Online (Sandbox Code Playgroud)