umbrellio/laravel-pg-extensions

Postgres Laravel 扩展

7.0.1 2024-05-02 17:48 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 umbrellio/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::dropView('active_users')

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

获取 foreign key

示例

// Facade methods:
/** @var ForeignKeyDefinition[] $fks */
$fks = Schema::getForeignKeys('some_table');

foreach ($fks as $fk) {
    // $fk->source_column_name
    // $fk->target_table_name
    // $fk->target_column_name
}

扩展唯一索引创建

示例

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_start')
        ->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);
    }
}

待办功能

  • 通过 inheritspartition by 扩展 CreateCommand
  • 扩展分区的工作方式
  • 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