agpopov/laravel-pg-extensions

Postgres Laravel 扩展

6.0.0 2022-02-28 09:19 UTC

README

Github Status Coverage Status Latest Stable Version Total Downloads Code Intelligence Status Build Status Code Coverage Scrutinizer Code Quality

此项目扩展了 Laravel 的数据库层,允许在不使用原始查询的情况下使用特定的 Postgres 功能。

安装

运行以下命令进行安装

composer require agpopov/laravel-pg-extensions

功能

扩展表创建

示例

Schema::create('table', function (Blueprint $table) {
    $table->like('other_table')->includingAll(); 
    $table->ifNotExists();
});

扩展 Schema USING

示例

Schema::create('table', function (Blueprint $table) {
    $table->integer('number');
});

//modifications with data...

Schema::table('table', function (Blueprint $table) {
    $table
        ->string('number')
        ->using("('[' || number || ']')::character varying")
        ->change();
});

创建视图

示例

// Facade methods:
Schema::createView('active_users', "SELECT * FROM users WHERE active = 1");
Schema::createRecursiveView('active_users', ['id', 'name'], "SELECT id, name FROM users WHERE active = 1");
Schema::dropView('active_users');

// Schema methods:
Schema::create('users', function (Blueprint $table) {
    $table
        ->createView('active_users', "SELECT * FROM users WHERE active = 1")
        ->materialize();
});

扩展索引创建

示例

Schema::create('table', function (Blueprint $table) {
    $table->string('code'); 
    $table->softDeletes();
    $table->indexPartial('code')->whereNull('deleted_at');
});

扩展唯一索引创建

示例

Schema::create('table', function (Blueprint $table) {
    $table->string('code'); 
    $table->softDeletes();
    $table->uniquePartial('code')->whereNull('deleted_at');
});

如果你要删除部分唯一索引,请使用此方法

Schema::create('table', function (Blueprint $table) {
    $table->dropUniquePartial(['code']);
});

$table->dropUnique() 对部分唯一索引不起作用,因为 PostgreSQL 没有定义部分(即条件)唯一约束。如果你尝试删除这样的部分唯一索引,你会得到一个错误。

CREATE UNIQUE INDEX CONCURRENTLY examples_new_col_idx ON examples (new_col);
ALTER TABLE examples
    ADD CONSTRAINT examples_unique_constraint USING INDEX examples_new_col_idx;

当你创建一个没有条件的唯一索引时,PostgreSQL 会自动为你创建唯一约束,当你尝试删除这样的索引时,约束会先被删除,然后是唯一索引。

创建 EXCLUDE 约束

使用以下示例

Schema::create('table', function (Blueprint $table) {
    $table->integer('type_id'); 
    $table->date('date_start'); 
    $table->date('date_end'); 
    $table->softDeletes();
    $table
        ->exclude(['date_start', 'date_end'])
        ->using('type_id', '=')
        ->using('daterange(date_start, date_end)', '&&')
        ->method('gist')
        ->with('some_arg', 1)
        ->with('any_arg', 'some_value')
        ->whereNull('deleted_at');
});

将为你的表生成一个 EXCLUDE 约束

ALTER TABLE test_table
    ADD CONSTRAINT test_table_date_start_date_end_excl
        EXCLUDE USING gist (type_id WITH =, daterange(date_start, date_end) WITH &&)
        WITH (some_arg = 1, any_arg = 'some_value')
        WHERE ("deleted_at" is null)

创建 CHECK 约束

使用以下示例

Schema::create('table', function (Blueprint $table) {
    $table->integer('type_id'); 
    $table->date('date_start'); 
    $table->date('date_end'); 
    $table
        ->check(['date_start', 'date_end'])
        ->whereColumn('date_end', '>', 'date_end')
        ->whereIn('type_id', [1, 2, 3]);
});

将为你的表生成一个 CHECK 约束

ALTER TABLE test_table
    ADD CONSTRAINT test_table_date_start_date_end_chk
        CHECK ("date_end" > "date_start" AND "type_id" IN [1, 2, 3])

分区

支持挂载和卸载分区。

示例

Schema::table('table', function (Blueprint $table) {
    $table->attachPartition('partition')->range([
        'from' => now()->startOfDay(), // Carbon will be converted to date time string
        'to' => now()->tomorrow(),
    ]);
});

检查现有索引

Schema::table('some_table', function (Blueprint $table) {
   // check unique index exists on column
   if ($table->hasIndex(['column'], true)) {
      $table->dropUnique(['column']);
   }
   $table->uniquePartial('column')->whereNull('deleted_at');
});

数字列类型

与标准的 Laravel decimal 类型不同,此类型可以是 可变精度

Schema::table('some_table', function (Blueprint $table) {
   $table->numeric('column_with_variable_precision');
   $table->numeric('column_with_defined_precision', 8);
   $table->numeric('column_with_defined_precision_and_scale', 8, 2);
});

自定义扩展

1). 为你的扩展创建一个仓库。

2). 在 composer 中将此包添加为依赖项。

3). 从具有命名空间 namespace Umbrellio\Postgres\Extensions 的抽象类继承你打算扩展的类

4). 在闭包中实现扩展方法,例如

use Umbrellio\Postgres\Extensions\Schema\AbstractBlueprint;
class SomeBlueprint extends AbstractBlueprint
{
   public function someMethod()
   {
       return function (string $column): Fluent {
           return $this->addColumn('someColumn', $column);
       };
   }
}

5). 创建扩展类并使用以下语法混合这些方法,例如

use Umbrellio\Postgres\PostgresConnection;
use Umbrellio\Postgres\Schema\Blueprint;
use Umbrellio\Postgres\Schema\Grammars\PostgresGrammar;
use Umbrellio\Postgres\Extensions\AbstractExtension;

class SomeExtension extends AbstractExtension
{
    public static function getMixins(): array
    {
        return [
            SomeBlueprint::class => Blueprint::class,
            SomeConnection::class => PostgresConnection::class,
            SomeSchemaGrammar::class => PostgresGrammar::class,
            ...
        ];
    }
    
    public static function getTypes(): string
    {
        // where SomeType extends Doctrine\DBAL\Types\Type
        return [
            'some' => SomeType::class,
        ];
    }

    public static function getName(): string
    {
        return 'some';
    }
}

6). 在 ServiceProvider 中注册你的扩展并将配置放入 config/app.php 中,例如

use Illuminate\Support\ServiceProvider;
use Umbrellio\Postgres\PostgresConnection;

class SomeServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        PostgresConnection::registerExtension(SomeExtension::class);
    }
}

待办事项功能

  • 扩展 CreateCommand 以包含 inheritspartition by
  • 扩展分区处理
  • COPY 支持
  • 特定列上的 DISTINCT 支持
  • INSERT ON CONFLICT 支持
  • ...

许可证

在 MIT 许可证下发布。

作者

由 Vitaliy Lazeev & Korben Dallas 创建。

贡献

  • 分支它 ( https://github.com/umbrellio/laravel-pg-extensions )
  • 创建你的功能分支 (git checkout -b feature/my-new-feature)
  • 提交你的更改 (git commit -am 'Add some feature')
  • 推送到分支 (git push origin feature/my-new-feature)
  • 创建新的 Pull Request
Supported by Umbrellio