ditscheri / laravel-check-constraints

为您的Laravel模式添加检查约束。

v0.0.7 2023-04-07 19:35 UTC

README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

此包允许您向数据库表添加本机检查约束。

您可以在MySQLPostgreSQLSQLiteSQL Server 的官方文档中了解更多有关检查约束的信息。

目前,此包不会向SQLite驱动器添加检查约束,但如果您只使用SQLite进行测试,应该没有问题(见下文)。

安装

您可以通过composer安装此包

composer require ditscheri/laravel-check-constraints

用法

Schema::create('events', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->datetime('starts_at');
    $table->datetime('ends_at');

    // This is the new part:
    $table->check('starts_at < ends_at');
});

最后一条语句将生成以下SQL语句

alter table `events` add constraint `events_starts_at_ends_at_check` check (starts_at < ends_at);

现在您的数据库只允许插入和更新具有有效日期范围的行。

如果您尝试插入或更新违反检查的行,将抛出 \Illuminate\Database\QueryException

Event::first()->update([
    'starts_at' => '2022-02-19 20:00:00',
    'end_at'    => '2022-02-19 18:00:00', // this one would be over before it even started?!
]); 
 
// Illuminate\Database\QueryException with message
// SQLSTATE[HY000]: General error: 3819 
// Check constraint 'events_starts_at_ends_at_check' is violated.

另一个简单但典型的用例是与价格和折扣一起使用

Schema::create('products', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->unsignedInteger('price');
    $table->unsignedInteger('discounted_price');

    // Ensure that discounts are lower than the regular price:
    $table->check('discounted_price <= price');
});

当然,您仍然需要在应用程序代码中验证您的数据,并在触及数据库之前检测此类问题。但有时在数据库本身中添加一层完整性检查也是有用的。

尤其是在您从数据库中读取数据时,您的代码现在可以安全地假设所有定义的检查都得到了保证。

您还可以向现有表添加检查

Schema::table('users', function (Blueprint $table) {
    $table->check('age > 18');
});

使用第二个参数为可选的自定义约束名称

Schema::table('users', function (Blueprint $table) {
    $table->check('age > 18', 'require_min_age');
    $table->check('is_admin=1 OR company_id IS NOT NULL', 'non_admins_require_company');
});

您可以通过名称删除检查约束

Schema::table('users', function (Blueprint $table) {
    $table->dropCheck('require_min_age');
});

关于SQLite的说明

尽管SQLite支持在 create table 语句中使用检查约束,但有一些限制

  • SQLite无法向现有表添加检查约束。
  • SQLite无法删除检查约束。

由于此包仅依赖于宏,因此目前不支持SQLite驱动器。

您可以使用配置 check-constraints.sqlite.throw 来定义在使用SQLite时是否抛出 RuntimeException 或静默失败。

如果您仅在测试中使用SQLite,您可以将此选项设置为 false。这将为您的生产环境提供检查约束的所有好处,而您的测试仍然可以使用SQLite运行,其中对 $table->check() 的调用将被忽略。

配置

您可以使用以下命令发布配置文件

php artisan vendor:publish --tag="check-constraints-config"

这是发布配置文件的内容

return [
    'sqlite' => [
        'throw' => true,
    ],
];

测试

composer test

变更日志

有关最近更改的更多信息,请参阅CHANGELOG

贡献

有关详细信息,请参阅CONTRIBUTING

安全漏洞

有关如何报告安全漏洞的详细信息,请参阅我们的安全策略

版权信息

许可协议

MIT 许可协议(MIT)。请参阅许可文件获取更多信息。