В частности, поскольку MySQL не имеет такого типа поля, необработанные запросы к БД кажутся плохой идеей. Поскольку в pgsql по умолчанию отсутствует текстовое поле без учета регистра, нам пришлось использовать это расширение (которое, разумеется, работает отлично), но теперь перед миграцией стоит дилемма.
Я создал пакет, который реализует эту функциональность. Добавляет 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');
}
}
Других решений пока нет …