Fixes #13019: Support JSON in SchemaBuilderTrait

This commit is contained in:
Zhukov Roman
2018-02-06 16:35:49 +03:00
committed by Alexander Makarov
parent 46848f0051
commit 40b038379f
15 changed files with 107 additions and 15 deletions

View File

@ -49,6 +49,11 @@ cache:
# try running against postgres 9.6 # try running against postgres 9.6
addons: addons:
postgresql: "9.6" postgresql: "9.6"
apt:
sources:
- mysql-5.7-trusty
packages:
- mysql-server
code_climate: code_climate:
repo_token: 2935307212620b0e2228ab67eadd92c9f5501ddb60549d0d86007a354d56915b repo_token: 2935307212620b0e2228ab67eadd92c9f5501ddb60549d0d86007a354d56915b
@ -76,10 +81,10 @@ matrix:
code_climate: code_climate:
repo_token: 2935307212620b0e2228ab67eadd92c9f5501ddb60549d0d86007a354d56915b repo_token: 2935307212620b0e2228ab67eadd92c9f5501ddb60549d0d86007a354d56915b
apt: apt:
sources:
- mysql-5.7-trusty
packages: packages:
- mysql-server-5.6 - mysql-server
- mysql-client-core-5.6
- mysql-client-5.6
services: services:
- mysql - mysql
@ -91,10 +96,10 @@ matrix:
repo_token: 2935307212620b0e2228ab67eadd92c9f5501ddb60549d0d86007a354d56915b repo_token: 2935307212620b0e2228ab67eadd92c9f5501ddb60549d0d86007a354d56915b
postgresql: "9.6" postgresql: "9.6"
apt: apt:
sources:
- mysql-5.7-trusty
packages: packages:
- mysql-server-5.6 - mysql-server
- mysql-client-core-5.6
- mysql-client-5.6
services: services:
- mysql - mysql
- postgresql - postgresql
@ -166,6 +171,7 @@ before_script:
- | - |
if [ $TASK_TESTS_PHP == 1 ]; then if [ $TASK_TESTS_PHP == 1 ]; then
travis_retry mysql -e 'CREATE DATABASE `yiitest`;'; travis_retry mysql -e 'CREATE DATABASE `yiitest`;';
mysql -e "SET GLOBAL sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';";
mysql -e "CREATE USER 'travis'@'localhost' IDENTIFIED WITH mysql_native_password;"; mysql -e "CREATE USER 'travis'@'localhost' IDENTIFIED WITH mysql_native_password;";
mysql -e "GRANT ALL PRIVILEGES ON *.* TO 'travis'@'localhost' WITH GRANT OPTION;"; mysql -e "GRANT ALL PRIVILEGES ON *.* TO 'travis'@'localhost' WITH GRANT OPTION;";
psql -U postgres -c 'CREATE DATABASE yiitest;'; psql -U postgres -c 'CREATE DATABASE yiitest;';

View File

@ -4,6 +4,7 @@ Yii Framework 2 Change Log
2.0.14 under development 2.0.14 under development
------------------------ ------------------------
- Enh #13019: Support JSON in SchemaBuilderTrait (zhukovra, undefinedor)
- Enh #15047: `yii\db\Query::select()` and `yii\db\Query::addSelect()` now check for duplicate column names (wapmorgan) - Enh #15047: `yii\db\Query::select()` and `yii\db\Query::addSelect()` now check for duplicate column names (wapmorgan)
- Enh #14643: Added `yii\web\ErrorAction::$layout` property to conveniently set layout from error action config (swods, cebe, samdark) - Enh #14643: Added `yii\web\ErrorAction::$layout` property to conveniently set layout from error action config (swods, cebe, samdark)
- Enh #13465: Added `yii\helpers\FileHelper::findDirectory()` method (ArsSirek, developeruz) - Enh #13465: Added `yii\helpers\FileHelper::findDirectory()` method (ArsSirek, developeruz)

View File

@ -114,13 +114,33 @@ class ColumnSchema extends BaseObject
*/ */
protected function typecast($value) protected function typecast($value)
{ {
if ($value === '' && !in_array($this->type, [Schema::TYPE_TEXT, Schema::TYPE_STRING, Schema::TYPE_BINARY, Schema::TYPE_CHAR], true)) { if ($value === ''
&& !in_array(
$this->type,
[
Schema::TYPE_TEXT,
Schema::TYPE_STRING,
Schema::TYPE_BINARY,
Schema::TYPE_CHAR
],
true)
) {
return null; return null;
} }
if ($value === null || gettype($value) === $this->phpType || $value instanceof ExpressionInterface || $value instanceof Query) {
if ($value === null
|| gettype($value) === $this->phpType
|| $value instanceof ExpressionInterface
|| $value instanceof Query
) {
return $value; return $value;
} }
if (is_array($value) && count($value) === 2 && isset($value[1]) && in_array($value[1], $this->getPdoParamTypes(), true)) {
if (is_array($value)
&& count($value) === 2
&& isset($value[1])
&& in_array($value[1], $this->getPdoParamTypes(), true)
) {
return new PdoValue($value[0], $value[1]); return new PdoValue($value[0], $value[1]);
} }

View File

@ -272,4 +272,25 @@ trait SchemaBuilderTrait
return $this->getDb()->getSchema()->createColumnSchemaBuilder(Schema::TYPE_MONEY, $length); return $this->getDb()->getSchema()->createColumnSchemaBuilder(Schema::TYPE_MONEY, $length);
} }
/**
* Creates a JSON column.
* @return ColumnSchemaBuilder the column instance which can be further customized.
* @since 2.0.14
* @throws \yii\base\Exception
*/
public function json()
{
/*
* TODO Remove in Yii 2.1
*
* Disabled due to bug in MySQL extension
* @link https://bugs.php.net/bug.php?id=70384
*/
if (version_compare(PHP_VERSION, '5.6', '<') && $this->getDb()->getDriverName() === 'mysql') {
throw new \yii\base\Exception('JSON column type is not supported in PHP < 5.6');
}
return $this->getDb()->getSchema()->createColumnSchemaBuilder(Schema::TYPE_JSON);
}
} }

View File

@ -44,6 +44,7 @@ class QueryBuilder extends \yii\db\QueryBuilder
Schema::TYPE_BINARY => 'blob', Schema::TYPE_BINARY => 'blob',
Schema::TYPE_BOOLEAN => 'tinyint(1)', Schema::TYPE_BOOLEAN => 'tinyint(1)',
Schema::TYPE_MONEY => 'decimal(19,4)', Schema::TYPE_MONEY => 'decimal(19,4)',
Schema::TYPE_JSON => 'json'
]; ];
/** /**

View File

@ -67,6 +67,7 @@ class Schema extends \yii\db\Schema
'timestamp' => self::TYPE_TIMESTAMP, 'timestamp' => self::TYPE_TIMESTAMP,
'enum' => self::TYPE_STRING, 'enum' => self::TYPE_STRING,
'varbinary' => self::TYPE_BINARY, 'varbinary' => self::TYPE_BINARY,
'json' => self::TYPE_JSON,
]; ];
/** /**

View File

@ -71,7 +71,7 @@ class QueryBuilder extends \yii\db\QueryBuilder
Schema::TYPE_BINARY => 'bytea', Schema::TYPE_BINARY => 'bytea',
Schema::TYPE_BOOLEAN => 'boolean', Schema::TYPE_BOOLEAN => 'boolean',
Schema::TYPE_MONEY => 'numeric(19,4)', Schema::TYPE_MONEY => 'numeric(19,4)',
Schema::TYPE_JSON => 'jsonb' Schema::TYPE_JSON => 'jsonb',
]; ];
/** /**

View File

@ -142,7 +142,8 @@ CREATE TABLE `type` (
`bool_col` tinyint(1) NOT NULL, `bool_col` tinyint(1) NOT NULL,
`bool_col2` tinyint(1) DEFAULT '1', `bool_col2` tinyint(1) DEFAULT '1',
`ts_default` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `ts_default` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`bit_col` BIT(8) NOT NULL DEFAULT b'10000010' `bit_col` BIT(8) NOT NULL DEFAULT b'10000010',
`json_col` json
) ENGINE=InnoDB DEFAULT CHARSET=utf8; ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `animal` ( CREATE TABLE `animal` (

View File

@ -1128,6 +1128,9 @@ abstract class ActiveRecordTest extends DatabaseTestCase
$this->assertEquals(5, $itemClass::find()->count()); $this->assertEquals(5, $itemClass::find()->count());
} }
/**
* @requires PHP 5.6
*/
public function testCastValues() public function testCastValues()
{ {
$model = new Type(); $model = new Type();

View File

@ -442,6 +442,18 @@ abstract class SchemaTest extends DatabaseTestCase
'scale' => null, 'scale' => null,
'defaultValue' => 130, // b'10000010' 'defaultValue' => 130, // b'10000010'
], ],
'json_col' => [
'type' => 'json',
'dbType' => 'json',
'phpType' => 'array',
'allowNull' => true,
'autoIncrement' => false,
'enumValues' => null,
'size' => null,
'precision' => null,
'scale' => null,
'defaultValue' => null,
],
]; ];
} }

View File

@ -49,6 +49,7 @@ class SchemaTest extends \yiiunit\framework\db\SchemaTest
public function getExpectedColumns() public function getExpectedColumns()
{ {
$columns = parent::getExpectedColumns(); $columns = parent::getExpectedColumns();
unset($columns['json_col']);
$columns['int_col']['dbType'] = 'integer'; $columns['int_col']['dbType'] = 'integer';
$columns['int_col']['size'] = null; $columns['int_col']['size'] = null;
$columns['int_col']['precision'] = null; $columns['int_col']['precision'] = null;

View File

@ -26,7 +26,7 @@ class QueryBuilderTest extends \yiiunit\framework\db\QueryBuilderTest
*/ */
public function columnTypes() public function columnTypes()
{ {
return array_merge(parent::columnTypes(), [ $columns = [
[ [
Schema::TYPE_PK . ' AFTER `col_before`', Schema::TYPE_PK . ' AFTER `col_before`',
$this->primaryKey()->after('col_before'), $this->primaryKey()->after('col_before'),
@ -62,7 +62,23 @@ class QueryBuilderTest extends \yiiunit\framework\db\QueryBuilderTest
$this->primaryKey()->comment('test')->after('col_before'), $this->primaryKey()->comment('test')->after('col_before'),
"int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'test' AFTER `col_before`", "int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'test' AFTER `col_before`",
], ],
]); ];
/*
* TODO Remove in Yii 2.1
*
* Disabled due bug in MySQL extension
* @link https://bugs.php.net/bug.php?id=70384
*/
if (version_compare(PHP_VERSION, '5.6', '>=')) {
$columns[] = [
Schema::TYPE_JSON,
$this->json(),
"json",
];
}
return array_merge(parent::columnTypes(), $columns);
} }
public function primaryKeysProvider() public function primaryKeysProvider()

View File

@ -24,6 +24,7 @@ class SchemaTest extends \yiiunit\framework\db\SchemaTest
{ {
$columns = parent::getExpectedColumns(); $columns = parent::getExpectedColumns();
unset($columns['enum_col']); unset($columns['enum_col']);
unset($columns['json_col']);
$columns['int_col']['dbType'] = 'NUMBER'; $columns['int_col']['dbType'] = 'NUMBER';
$columns['int_col']['size'] = 22; $columns['int_col']['size'] = 22;
$columns['int_col']['precision'] = null; $columns['int_col']['precision'] = null;

View File

@ -26,7 +26,7 @@ class QueryBuilderTest extends \yiiunit\framework\db\QueryBuilderTest
public function columnTypes() public function columnTypes()
{ {
return array_merge(parent::columnTypes(), [ $columns = [
[ [
Schema::TYPE_BOOLEAN . ' NOT NULL DEFAULT TRUE', Schema::TYPE_BOOLEAN . ' NOT NULL DEFAULT TRUE',
$this->boolean()->notNull()->defaultValue(true), $this->boolean()->notNull()->defaultValue(true),
@ -57,7 +57,14 @@ class QueryBuilderTest extends \yiiunit\framework\db\QueryBuilderTest
$this->timestamp(4), $this->timestamp(4),
'timestamp(4)', 'timestamp(4)',
], ],
]); [
Schema::TYPE_JSON,
$this->json(),
"jsonb",
],
];
return array_merge(parent::columnTypes(), $columns);
} }
public function conditionProvider() public function conditionProvider()

View File

@ -27,6 +27,7 @@ class SchemaTest extends \yiiunit\framework\db\SchemaTest
$columns = parent::getExpectedColumns(); $columns = parent::getExpectedColumns();
unset($columns['enum_col']); unset($columns['enum_col']);
unset($columns['bit_col']); unset($columns['bit_col']);
unset($columns['json_col']);
$columns['int_col']['dbType'] = 'integer'; $columns['int_col']['dbType'] = 'integer';
$columns['int_col']['size'] = null; $columns['int_col']['size'] = null;
$columns['int_col']['precision'] = null; $columns['int_col']['precision'] = null;