Есть ли способ создать поле citext, используя Laravel 5 Migrations?

В частности, поскольку MySQL не имеет такого типа поля, необработанные запросы к БД кажутся плохой идеей. Поскольку в pgsql по умолчанию отсутствует текстовое поле без учета регистра, нам пришлось использовать это расширение (которое, разумеется, работает отлично), но теперь перед миграцией стоит дилемма.

2

Решение

Я создал пакет, который реализует эту функциональность. Добавляет passthru() метод миграции, так что вы можете создать любой тип поля, который вы хотите. В этом примере, после установки пакета и добавления поставщика услуг, вы просто $table->passthru('citext', 'name'); в файле миграции. Пакет называется «laravel-nomad», и его можно найти на GitHub а также packagist.


Да, это можно сделать. Это требует расширения нескольких основных файлов, но это выполнимо. В частности, вам понадобится новое соединение, грамматика схемы и план.

Сначала создайте новый каталог под вашим app каталог для хранения ваших пользовательских файлов. Например, app/Extension, Файлы, размещенные в этом каталоге, будут расширять основные файлы Illuminate, поэтому вы будете реплицировать структуру папок Illuminate в этом новом каталоге.

светокопия

Чтобы добавить новый метод, доступный для миграции, необходимо обновить Blueprint. Вы создадите собственный класс 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);
}

}

Схема Грамматика

С обновленным планом, чтобы позволить ciText() метод, вам нужно обновить грамматику схемы, чтобы иметь возможность обрабатывать ciText поле. Вы создадите собственный класс грамматики схемы, который расширяет базовый класс грамматики схемы PostgresGrammar. Эта пользовательская схема грамматики будет иметь метод, который преобразует план 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';
}

}

соединение

Теперь, когда у вас есть пользовательский Blueprint и грамматика пользовательской схемы, которая позволит использовать citext поле, вам нужно создать пользовательское соединение, которое будет использовать эти новые пользовательские классы. Этот пользовательский класс Connection расширит базовый класс PostgresConnection, чтобы переопределить методы, необходимые для использования пользовательской грамматики схемы и пользовательского Blueprint.

приложение / Extension / База данных / 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;
}

}

Поставщик услуг

Теперь, когда настраиваемое соединение настроено, вам нужно указать Laravel использовать его. Вы можете переопределить встроенный pgsql Водитель использовать PostgresCustomConnection класс, или вы можете создать новое имя драйвера (например, pgsql-custom) для нового подключения.

Если вы просто хотите переопределить встроенный pgsql водитель, вам нужно добавить следующую строку в register() метод в вашем app/Providers/AppServiceProvider.php файл:

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

Если вы хотите создать новое имя драйвера (например, 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');

Конфигурация базы данных

Если вы создаете новое имя драйвера, обязательно обновите config/database.php файл для установки значения для driver ключ к вашей связи с pgsql-custom (или как вы называете свой драйвер).

ремесленник

Наконец, запустите команды ремесленника, чтобы убедиться, что все ваши классы могут быть найдены, и обновите любую кэшированную (скомпилированную) версию app/Providers/AppServiceProvider:

composer dump-autoload
php artisan clear-compiled
php artisan optimize

миграция

Теперь вы можете использовать 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');
}
}
5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]