sam-it/yii2-mariadb

MariaDB 驱动程序 for Yii2

安装次数: 70,631

依赖项: 5

建议者: 0

安全: 0

星标: 29

关注者: 3

分支: 6

开放问题: 2

类型:yii2-extension

v3.1.1 2022-06-13 15:29 UTC

This package is auto-updated.

Last update: 2024-09-13 11:32:17 UTC


README

Latest Stable Version Total Downloads Scrutinizer Code Quality Code Coverage Continous integration

yii2-mariadb

虽然 Yii2 通过其 MySQL 驱动程序支持 MariaDB,但 MariaDB 与 MySQL 之间的差异正在增加。此时,Yii2 中包含的驱动程序无法正确检测 MariaDB 中的 JSON 列,也无法正确存储其中的数据。

此库的目标是实现 MariaDB 特定的更改,以便在 MariaDB 中实现所有功能,这些功能在其他 DBMS 中由 Yii2 核心库支持。

测试

测试覆盖率很高,原因有两个

  • 所有代码都扩展了框架中的 MySQL 对应部分,新增内容很少。
  • 我们运行了 Yii2 的核心测试(进行了一些小的修改),以保证与框架的互操作性。

使用方法

要使用 MariaDB 的 Schema 实现,有几种方法。

覆盖用于 MySQL 的 schema 类

更新你的 Connection 配置中的 schemaMap 属性(驱动名仍然是 mysql,因为我们使用 MySQL PDO 驱动)(推荐)

'db' => [
    'class' => Connection::class,
    'schemaMap' => [
        'mysql' => SamIT\Yii2\MariaDb\Schema::class
    ]
]

将 schema 类添加到 schemaMap

将新的 Schema 类追加到 schemaMap 属性中,并手动设置 driverName 属性。

'db' => [
    'class' => Connection::class,
    'driverName' => 'mariadb',
    'schemaMap' => [
        'mariadb' => SamIT\Yii2\MariaDb\Schema::class
    ]
]

JSON 列检测

由于 MariaDB 没有内置的 JSON 数据类型,我们需要做一些额外的工作来检测 JSON 列。我们通过解析使用 SHOW CREATE TABLE 获得的 SQL 来完成此操作。由于 MariaDB 支持 CHECK 约束,因此使用这些约束来确保列只能包含有效的 JSON。任何形式为:json_valid(`column1`) 的约束都将识别该列作为 JSON。请注意,这可能会引起问题,如果你有奇怪的约束,请考虑这一点

`column1` longtext CHECK(not json_valid(`column1`));

column1 标记为 JSON 列。

列创建

在创建 JSON 列时,ColumnSchemaBuilder 需要添加表约束的列名。由于并非所有其他列类型都如此,Yii 不会将列名传递给构建器。考虑以下代码,例如在迁移中

$this->alterColumn('{{test}}', 'field1', $this->json());

在这里,ColumnSchemaBuilder 没有办法知道将要使用的列名。由于最终将架构构建器传递给 QueryBuilder::alterColumn(),我们可以在那里拦截它,并替换约束中的列名。

如果你提前将 ColumnSchemaBuilder 强制转换为字符串,或者在没有 QueryBuilder 的情况下使用它,最终会得到这样的 SQL

ALTER COLUMN `field` JSON CHECK(json_valid({name}));

这显然是不可行的。对于这些情况,我们在构建器中添加了 toString(string $columnName) 方法。

// Will result in broken SQL.
$this->alterColumn('{{test}}', 'field1', $this->json() . ' --APPEND SOMETHING');
// Will result in working SQL.
$this->alterColumn('{{test}}', 'field1', $this->json()->toString('field1') . ' --APPEND SOMETHING');