diff --git a/CHANGELOG.md b/CHANGELOG.md index a5703b8..f608709 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ from `$table, $columns, $rows` to `$table, $rows, $columns = []` (@Tigrov) - Enh #260: Support `Traversable` values for `DMLQueryBuilder::batchInsert()` method with empty columns (@Tigrov) - Enh #255, #321: Implement and use `SqlParser` class (@Tigrov) -- New #236: Implement `ColumnSchemaInterface` classes according to the data type of database table columns +- New #236, #349: Implement `ColumnInterface` classes according to the data type of database table columns for type casting performance. Related with yiisoft/db#752 (@Tigrov) - Chg #272: Replace call of `SchemaInterface::getRawTableName()` to `QuoterInterface::getRawTableName()` (@Tigrov) - Enh #275: Refactor PHP type of `ColumnSchemaInterface` instances (@Tigrov) diff --git a/src/Column/BinaryColumn.php b/src/Column/BinaryColumn.php index 534ef17..cbf4bc4 100644 --- a/src/Column/BinaryColumn.php +++ b/src/Column/BinaryColumn.php @@ -7,6 +7,7 @@ use Yiisoft\Db\Command\Param; use Yiisoft\Db\Expression\Expression; use Yiisoft\Db\Schema\Column\BinaryColumn as BaseBinaryColumn; +use Yiisoft\Db\Schema\Data\StringableStream; use function is_string; @@ -15,8 +16,10 @@ final class BinaryColumn extends BaseBinaryColumn public function dbTypecast(mixed $value): mixed { if ($this->getDbType() === 'blob') { - if ($value instanceof Param && is_string($value->value)) { + if ($value instanceof Param) { $value = $value->value; + } elseif ($value instanceof StringableStream) { + $value = $value->getValue(); } if (is_string($value)) { diff --git a/tests/ColumnTest.php b/tests/ColumnTest.php index b795cb4..beed37d 100644 --- a/tests/ColumnTest.php +++ b/tests/ColumnTest.php @@ -21,11 +21,11 @@ use Yiisoft\Db\Schema\Column\DoubleColumn; use Yiisoft\Db\Schema\Column\IntegerColumn; use Yiisoft\Db\Schema\Column\StringColumn; +use Yiisoft\Db\Schema\Data\StringableStream; use Yiisoft\Db\Tests\Common\CommonColumnTest; use function iterator_to_array; use function str_repeat; -use function stream_get_contents; use function version_compare; /** @@ -65,7 +65,7 @@ protected function assertTypecastedValues(array $result, bool $allTypecasted = f $this->assertSame(str_repeat('x', 100), $result['char_col']); $this->assertNull($result['char_col3']); $this->assertSame(1.234, $result['float_col']); - $this->assertSame("\x10\x11\x12", stream_get_contents($result['blob_col'])); + $this->assertSame("\x10\x11\x12", (string) $result['blob_col']); $this->assertEquals(new DateTimeImmutable('2023-07-11 14:50:23', $utcTimezone), $result['timestamp_col']); $this->assertEquals(new DateTimeImmutable('2023-07-11 14:50:23', $utcTimezone), $result['timestamp_local']); $this->assertEquals(new DateTimeImmutable('14:50:23'), $result['time_col']); @@ -75,7 +75,7 @@ protected function assertTypecastedValues(array $result, bool $allTypecasted = f if ($allTypecasted) { $this->assertSame([['a' => 1, 'b' => null, 'c' => [1, 3, 5]]], $result['json_col']); } else { - $this->assertSame('[{"a":1,"b":null,"c":[1,3,5]}]', stream_get_contents($result['json_col'])); + $this->assertSame('[{"a":1,"b":null,"c":[1,3,5]}]', (string) $result['json_col']); } } @@ -240,11 +240,20 @@ public function testBinaryColumn(): void $binaryCol = new BinaryColumn(); $binaryCol->dbType('blob'); - $this->assertInstanceOf(Expression::class, $binaryCol->dbTypecast("\x10\x11\x12")); - $this->assertInstanceOf( - Expression::class, + $expected = new Expression('TO_BLOB(UTL_RAW.CAST_TO_RAW(:value))', ['value' => "\x10\x11\x12"]); + + $this->assertEquals( + $expected, + $binaryCol->dbTypecast("\x10\x11\x12"), + ); + $this->assertEquals( + $expected, $binaryCol->dbTypecast(new Param("\x10\x11\x12", PDO::PARAM_LOB)), ); + $this->assertEquals( + $expected, + $binaryCol->dbTypecast(new StringableStream("\x10\x11\x12")), + ); } public function testJsonColumn(): void diff --git a/tests/Provider/QueryBuilderProvider.php b/tests/Provider/QueryBuilderProvider.php index 106bb92..5e753ef 100644 --- a/tests/Provider/QueryBuilderProvider.php +++ b/tests/Provider/QueryBuilderProvider.php @@ -421,6 +421,7 @@ public static function prepareValue(): array $values['binary'][0] = "HEXTORAW('737472696e67')"; $values['paramBinary'][0] = "HEXTORAW('737472696e67')"; $values['paramResource'][0] = "HEXTORAW('737472696e67')"; + $values['ResourceStream'][0] = "HEXTORAW('737472696e67')"; return $values; }