diff --git a/CHANGELOG.md b/CHANGELOG.md index 1046c5e1c..bb798fb04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ - Enh #372: Rename `ColumnSchemaInterface` to `ColumnInterface` (@Tigrov) - Enh #373: Replace `DbArrayHelper::getColumn()` with `array_column()` (@Tigrov) - New #374: Add `IndexType` and `IndexMethod` classes (@Tigrov) +- Enh #376: Move `JsonExpressionBuilder` and JSON type tests to `yiisoft/db` package (@Tigrov) - Bug #377: Explicitly mark nullable parameters (@vjik) ## 1.2.0 March 21, 2024 diff --git a/src/Builder/JsonExpressionBuilder.php b/src/Builder/JsonExpressionBuilder.php deleted file mode 100644 index a2dbd7b8f..000000000 --- a/src/Builder/JsonExpressionBuilder.php +++ /dev/null @@ -1,57 +0,0 @@ -getValue(); - - if ($value instanceof QueryInterface) { - [$sql, $params] = $this->queryBuilder->build($value, $params); - - return "($sql)"; - } - - $placeholder = self::PARAM_PREFIX . count($params); - $params[$placeholder] = Json::encode($value); - - return $placeholder; - } -} diff --git a/src/DQLQueryBuilder.php b/src/DQLQueryBuilder.php index 269ac87c5..b447b32f8 100644 --- a/src/DQLQueryBuilder.php +++ b/src/DQLQueryBuilder.php @@ -6,9 +6,7 @@ use Yiisoft\Db\Expression\Expression; use Yiisoft\Db\Expression\ExpressionInterface; -use Yiisoft\Db\Expression\JsonExpression; use Yiisoft\Db\Mysql\Builder\ExpressionBuilder; -use Yiisoft\Db\Mysql\Builder\JsonExpressionBuilder; use Yiisoft\Db\Mysql\Builder\JsonOverlapsConditionBuilder; use Yiisoft\Db\QueryBuilder\AbstractDQLQueryBuilder; use Yiisoft\Db\QueryBuilder\Condition\JsonOverlapsCondition; @@ -83,7 +81,6 @@ protected function defaultExpressionBuilders(): array { return [ ...parent::defaultExpressionBuilders(), - JsonExpression::class => JsonExpressionBuilder::class, JsonOverlapsCondition::class => JsonOverlapsConditionBuilder::class, Expression::class => ExpressionBuilder::class, ]; diff --git a/tests/ColumnFactoryTest.php b/tests/ColumnFactoryTest.php index 4e5f73cdc..4f6f32e1d 100644 --- a/tests/ColumnFactoryTest.php +++ b/tests/ColumnFactoryTest.php @@ -9,6 +9,7 @@ use Yiisoft\Db\Expression\Expression; use Yiisoft\Db\Mysql\Tests\Provider\ColumnFactoryProvider; use Yiisoft\Db\Mysql\Tests\Support\TestTrait; +use Yiisoft\Db\Schema\Column\ColumnInterface; use Yiisoft\Db\Tests\AbstractColumnFactoryTest; /** @@ -25,23 +26,15 @@ public function testFromDbType(string $dbType, string $expectedType, string $exp } #[DataProviderExternal(ColumnFactoryProvider::class, 'definitions')] - public function testFromDefinition( - string $definition, - string $expectedType, - string $expectedInstanceOf, - array $expectedMethodResults = [] - ): void { - parent::testFromDefinition($definition, $expectedType, $expectedInstanceOf, $expectedMethodResults); + public function testFromDefinition(string $definition, ColumnInterface $expected): void + { + parent::testFromDefinition($definition, $expected); } #[DataProviderExternal(ColumnFactoryProvider::class, 'pseudoTypes')] - public function testFromPseudoType( - string $pseudoType, - string $expectedType, - string $expectedInstanceOf, - array $expectedMethodResults = [] - ): void { - parent::testFromPseudoType($pseudoType, $expectedType, $expectedInstanceOf, $expectedMethodResults); + public function testFromPseudoType(string $pseudoType, ColumnInterface $expected): void + { + parent::testFromPseudoType($pseudoType, $expected); } #[DataProviderExternal(ColumnFactoryProvider::class, 'types')] diff --git a/tests/ColumnTest.php b/tests/ColumnTest.php index 31cb73c38..df2177c5b 100644 --- a/tests/ColumnTest.php +++ b/tests/ColumnTest.php @@ -15,7 +15,7 @@ use Yiisoft\Db\Schema\Column\IntegerColumn; use Yiisoft\Db\Schema\Column\JsonColumn; use Yiisoft\Db\Schema\Column\StringColumn; -use Yiisoft\Db\Tests\Common\CommonColumnTest; +use Yiisoft\Db\Tests\AbstractColumnTest; use function str_repeat; @@ -24,7 +24,7 @@ * * @psalm-suppress PropertyNotSetInConstructor */ -final class ColumnTest extends CommonColumnTest +final class ColumnTest extends AbstractColumnTest { use TestTrait; diff --git a/tests/JsonCommandTest.php b/tests/JsonCommandTest.php deleted file mode 100644 index ba9ea8f51..000000000 --- a/tests/JsonCommandTest.php +++ /dev/null @@ -1,82 +0,0 @@ -getConnection(); - - if ($db->getSchema()->getTableSchema('json') !== null) { - $db->createCommand()->dropTable('json')->execute(); - } - - $command = $db->createCommand(); - $command->createTable('json', [ - 'id' => PseudoType::PK, - 'data' => ColumnType::JSON, - ])->execute(); - - $this->assertTrue($db->getTableSchema('json') !== null); - $this->assertSame('data', $db->getTableSchema('json')->getColumn('data')->getName()); - $this->assertSame('json', $db->getTableSchema('json')->getColumn('data')->getType()); - } - - public function testInsertAndSelect(): void - { - $db = $this->getConnection(true); - - $command = $db->createCommand(); - $command->insert('storage', ['data' => ['a' => 1, 'b' => 2]])->execute(); - $rowExpected = match (str_contains($db->getServerInfo()->getVersion(), 'MariaDB')) { - true => '{"a":1,"b":2}', - default => '{"a": 1, "b": 2}', - }; - - $this->assertSame( - $rowExpected, - $command->setSql( - <<queryScalar(), - ); - } - - public function testInsertJsonExpressionAndSelect(): void - { - $db = $this->getConnection(true); - - $command = $db->createCommand(); - $command->insert('storage', ['data' => new JsonExpression(['a' => 1, 'b' => 2])])->execute(); - $rowExpected = match (str_contains($db->getServerInfo()->getVersion(), 'MariaDB')) { - true => '{"a":1,"b":2}', - default => '{"a": 1, "b": 2}', - }; - - $this->assertSame( - $rowExpected, - $command->setSql( - <<queryScalar(), - ); - } -} diff --git a/tests/Provider/ColumnFactoryProvider.php b/tests/Provider/ColumnFactoryProvider.php index 03fe197fd..bd142bba6 100644 --- a/tests/Provider/ColumnFactoryProvider.php +++ b/tests/Provider/ColumnFactoryProvider.php @@ -56,7 +56,7 @@ public static function definitions(): array { $definitions = parent::definitions(); - $definitions[] = ['bit(1)', ColumnType::BOOLEAN, BooleanColumn::class, ['getDbType' => 'bit', 'getSize' => 1]]; + $definitions[] = ['bit(1)', new BooleanColumn(dbType: 'bit', size: 1)]; return $definitions; } diff --git a/tests/Provider/QueryBuilderProvider.php b/tests/Provider/QueryBuilderProvider.php index 987e24fcc..2d38bc9eb 100644 --- a/tests/Provider/QueryBuilderProvider.php +++ b/tests/Provider/QueryBuilderProvider.php @@ -7,10 +7,8 @@ use Yiisoft\Db\Constant\ColumnType; use Yiisoft\Db\Constant\PseudoType; use Yiisoft\Db\Expression\Expression; -use Yiisoft\Db\Expression\JsonExpression; use Yiisoft\Db\Mysql\Column\ColumnBuilder; use Yiisoft\Db\Mysql\Tests\Support\TestTrait; -use Yiisoft\Db\Query\Query; use function array_replace; @@ -27,85 +25,6 @@ public static function alterColumn(): array ]; } - public static function buildCondition(): array - { - return [ - ...parent::buildCondition(), - [ - ['=', 'jsoncol', new JsonExpression(['lang' => 'uk', 'country' => 'UA'])], - '[[jsoncol]] = :qp0', [':qp0' => '{"lang":"uk","country":"UA"}'], - ], - [ - ['=', 'jsoncol', new JsonExpression([false])], - '[[jsoncol]] = :qp0', [':qp0' => '[false]'], - ], - 'object with type. Type is ignored for MySQL' => [ - ['=', 'prices', new JsonExpression(['seeds' => 15, 'apples' => 25], 'jsonb')], - '[[prices]] = :qp0', [':qp0' => '{"seeds":15,"apples":25}'], - ], - 'nested json' => [ - [ - '=', - 'data', - new JsonExpression( - [ - 'user' => ['login' => 'silverfire', 'password' => 'c4ny0ur34d17?'], - 'props' => ['mood' => 'good'], - ] - ), - ], - '[[data]] = :qp0', - [':qp0' => '{"user":{"login":"silverfire","password":"c4ny0ur34d17?"},"props":{"mood":"good"}}'], - ], - 'null value' => [ - ['=', 'jsoncol', new JsonExpression(null)], - '[[jsoncol]] = :qp0', [':qp0' => 'null'], - ], - 'null as array value' => [ - ['=', 'jsoncol', new JsonExpression([null])], - '[[jsoncol]] = :qp0', [':qp0' => '[null]'], - ], - 'null as object value' => [ - ['=', 'jsoncol', new JsonExpression(['nil' => null])], - '[[jsoncol]] = :qp0', [':qp0' => '{"nil":null}'], - ], - 'query' => [ - [ - '=', - 'jsoncol', - new JsonExpression((new Query(self::getDb()))->select('params')->from('user')->where(['id' => 1])), - ], - '[[jsoncol]] = (SELECT [[params]] FROM [[user]] WHERE [[id]]=:qp0)', - [':qp0' => 1], - ], - 'query with type, that is ignored in MySQL' => [ - [ - '=', - 'jsoncol', - new JsonExpression( - (new Query(self::getDb()))->select('params')->from('user')->where(['id' => 1]), - 'jsonb' - ), - ], - '[[jsoncol]] = (SELECT [[params]] FROM [[user]] WHERE [[id]]=:qp0)', [':qp0' => 1], - ], - 'nested and combined json expression' => [ - [ - '=', - 'jsoncol', - new JsonExpression( - new JsonExpression(['a' => 1, 'b' => 2, 'd' => new JsonExpression(['e' => 3])]) - ), - ], - '[[jsoncol]] = :qp0', [':qp0' => '{"a":1,"b":2,"d":{"e":3}}'], - ], - 'search by property in JSON column (issue #15838)' => [ - ['=', new Expression("(jsoncol->>'$.someKey')"), '42'], - "(jsoncol->>'$.someKey') = :qp0", [':qp0' => 42], - ], - ]; - } - public static function insert(): array { $insert = parent::insert(); @@ -213,7 +132,7 @@ public static function buildColumnDefinition(): array $values['binary()'][0] = 'blob'; $values['binary(1000)'][0] = 'blob(1000)'; $values['uuid()'][0] = 'binary(16)'; - $values["check('value > 5')"][0] = 'int CHECK (`col_59` > 5)'; + $values["check('value > 5')"][0] = 'int CHECK (`check_col` > 5)'; $values["check('')"][0] = 'int'; $values['check(null)'][0] = 'int'; $values['defaultValue($expression)'][0] = 'int DEFAULT (1 + 2)'; diff --git a/tests/QueryBuilderJsonTest.php b/tests/QueryBuilderJsonTest.php deleted file mode 100644 index d15e58e75..000000000 --- a/tests/QueryBuilderJsonTest.php +++ /dev/null @@ -1,90 +0,0 @@ -getConnection()->getQueryBuilder(); - $column = ColumnBuilder::json(); - $sql = $qb->alterColumn('storage', 'id', $column); - - $this->assertStringEndsWith( - <<getConnection()->getQueryBuilder(); - $column = ColumnBuilder::json(); - $sql = $qb->addColumn('storage', 'abc', $column); - - $this->assertSame( - <<getConnection()->getQueryBuilder(); - $column = ColumnBuilder::json(); - $sql = $qb->createTable('storage', ['abc' => $column]); - - $this->assertSame( - <<getConnection(true); - $qb = $db->getQueryBuilder(); - - $this->assertSame( - <<insert('storage', ['data' => ['a' => 1, 'b' => 2]]), - ); - } - - public function testInsertJsonExpresionAndSelect() - { - $db = $this->getConnection(true); - $qb = $db->getQueryBuilder(); - - $this->assertSame( - <<insert('storage', ['data' => new JsonExpression(['a' => 1, 'b' => 2])]), - ); - } -} diff --git a/tests/QueryBuilderTest.php b/tests/QueryBuilderTest.php index beac8535b..86f23b7a2 100644 --- a/tests/QueryBuilderTest.php +++ b/tests/QueryBuilderTest.php @@ -6,6 +6,8 @@ use PHPUnit\Framework\Attributes\DataProviderExternal; use Throwable; +use Yiisoft\Db\Command\Param; +use Yiisoft\Db\Constant\DataType; use Yiisoft\Db\Exception\Exception; use Yiisoft\Db\Exception\InvalidArgumentException; use Yiisoft\Db\Exception\InvalidConfigException; @@ -695,14 +697,14 @@ public function testJsonOverlapsConditionBuilder(): void $sql = $qb->buildExpression(new JsonOverlapsCondition('column', [1, 2, 3]), $params); $this->assertSame('JSON_OVERLAPS(`column`, :qp0)', $sql); - $this->assertSame([':qp0' => '[1,2,3]'], $params); + $this->assertEquals([':qp0' => new Param('[1,2,3]', DataType::STRING)], $params); // Test column as Expression $params = []; $sql = $qb->buildExpression(new JsonOverlapsCondition(new Expression('column'), [1, 2, 3]), $params); $this->assertSame('JSON_OVERLAPS(column, :qp0)', $sql); - $this->assertSame([':qp0' => '[1,2,3]'], $params); + $this->assertEquals([':qp0' => new Param('[1,2,3]', DataType::STRING)], $params); $db->close(); }