Quantcast
Channel: Live News for Yii Framework
Viewing all articles
Browse latest Browse all 3375

[extension] sam-it/yii2-mariadb

$
0
0

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

yii2-mariadb

  1. Override the schema class used for MySQL
  2. Add schema class to schemaMap
  3. Use the provided behavior

While Yii2 supports MariaDB through its MySQL driver, the differences between MariaDB and MySQL are increasing. At this time the driver included in Yii2 will not properly detect JSON columns in MariaDB and will not properly store data in them.

The goal of this library is to implement the MariaDB specific changes required to get all features working in MariaDB that are supported in the Yii2 core library for other DBMSes.

Tests

  1. Override the schema class used for MySQL
  2. Add schema class to schemaMap
  3. Use the provided behavior

The tests coverage is really high due to 2 reasons:

  • All code extends their MySQL counter parts in the framework, only very little is added.
  • We run the core tests for Yii2 (with some minor changes) to guarantee interoperability with the framework.

Usage

  1. Override the schema class used for MySQL
  2. Add schema class to schemaMap
  3. Use the provided behavior

To use the MariaDB Schema implementation there are several approaches.

Override the schema class used for MySQL

Update the schemaMap property in your Connection config (the drivername is still mysql since we use the MySQL PDO driver) (RECOMMENDED)

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

Add schema class to schemaMap

Append the new Schema class to the schemaMap property and set the driverName property manually.

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

Use the provided behavior

Add the MariaDbBehavior to your Connection. `php 'db' => [

'class' => Connection::class',
'as mariadb' => \SamIT\Yii2\MariaDb\MariaDbBehavior::class

] `

The behavior will register a handler for the EVENT_AFTER_OPEN on the connection. When a connection opens it will check the PDO attribute(s) to see if it's a MariaDB connection. If that's the case then it will update the $schemaMap property on the connection.

While the behavior method in theory allows you to use the connection without knowing the database type in advance, it has some disadvantages. Specifically the Connection class might instantiate a the Schema before opening the connection. This happens when a query builder is requested before the database connection is opened. If you run into issues related to SQL syntax please try the first approach to see if that resolves the issue.

JSON Column detection

  1. Override the schema class used for MySQL
  2. Add schema class to schemaMap
  3. Use the provided behavior

Since MariaDB has no built-in JSON data type we need to do some extra work to detect JSON columns. We do this by parsing the SQL obtained when using SHOW CREATE TABLE. Since MariaDB supports CHECK constraints these are used to ensure a column can only contain valid JSON. Any constraint that of the form: `json_valid(column1) will identify the column as JSON. Note that this could lead to problems if you have weird constraints, consider this: `sql column1 longtext CHECK(not json_valid(column1)); ` Will mark column1` as a JSON column.

Column creation

  1. Override the schema class used for MySQL
  2. Add schema class to schemaMap
  3. Use the provided behavior

When creating JSON columns the ColumnSchemaBuilder requires the name of the column to add the table constraint. Since this is not the case for all other column types Yii does not pass the name of the column to the builder. Consider this code, for example in a migration:

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

Here there is no way for the ColumnSchemaBuilder to know what the name of the column is going to be. Since the schema builder is ultimately passed to QueryBuilder::alterColumn(), we can intercept it there and replace the column name in the constraint.

If you coerce the ColumnSchemaBuilder to string early, or use it without the QueryBuilder you will end up with SQL like this: `php ALTER COLUMN field JSON CHECK(json_valid({name})); That will clearly not work. For those cases we have added a `toString(string $columnName)` method to the builder.php // 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'); `


Viewing all articles
Browse latest Browse all 3375

Trending Articles