diff --git a/composer.lock b/composer.lock index 5953fb189..1e014ce8a 100644 --- a/composer.lock +++ b/composer.lock @@ -753,16 +753,16 @@ }, { "name": "google/apiclient-services", - "version": "v0.439.0", + "version": "v0.440.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-api-php-client-services.git", - "reference": "1ce71ed1e35d5998f8a6e39475cf398f62bb25c7" + "reference": "f835f7a84611071ca2f58e8f44aac497d3aa7c44" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/1ce71ed1e35d5998f8a6e39475cf398f62bb25c7", - "reference": "1ce71ed1e35d5998f8a6e39475cf398f62bb25c7", + "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/f835f7a84611071ca2f58e8f44aac497d3aa7c44", + "reference": "f835f7a84611071ca2f58e8f44aac497d3aa7c44", "shasum": "" }, "require": { @@ -791,9 +791,9 @@ ], "support": { "issues": "https://github.com/googleapis/google-api-php-client-services/issues", - "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.439.0" + "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.440.0" }, - "time": "2026-04-26T01:20:24+00:00" + "time": "2026-05-04T01:36:24+00:00" }, { "name": "google/auth", diff --git a/src/bridge/symfony/telemetry-bundle/tests/Flow/Bridge/Symfony/TelemetryBundle/Tests/Unit/Instrumentation/Doctrine/DBAL/TracingConnectionTest.php b/src/bridge/symfony/telemetry-bundle/tests/Flow/Bridge/Symfony/TelemetryBundle/Tests/Unit/Instrumentation/Doctrine/DBAL/TracingConnectionTest.php index 080928b5d..132bc98f0 100644 --- a/src/bridge/symfony/telemetry-bundle/tests/Flow/Bridge/Symfony/TelemetryBundle/Tests/Unit/Instrumentation/Doctrine/DBAL/TracingConnectionTest.php +++ b/src/bridge/symfony/telemetry-bundle/tests/Flow/Bridge/Symfony/TelemetryBundle/Tests/Unit/Instrumentation/Doctrine/DBAL/TracingConnectionTest.php @@ -5,7 +5,7 @@ namespace Flow\Bridge\Symfony\TelemetryBundle\Tests\Unit\Instrumentation\Doctrine\DBAL; use Doctrine\DBAL\Driver\{Connection as ConnectionInterface, Result, Statement as DriverStatement}; -use Doctrine\DBAL\{ParameterType, VersionAwarePlatformDriver}; +use Doctrine\DBAL\ParameterType; use Flow\Bridge\Symfony\TelemetryBundle\Instrumentation\Doctrine\DBAL\V4\TracingConnection; use Flow\Telemetry\Context\MemoryContextStorage; use Flow\Telemetry\Logger\LoggerProvider; @@ -23,7 +23,7 @@ final class TracingConnectionTest extends TestCase { protected function setUp() : void { - if (\interface_exists(VersionAwarePlatformDriver::class)) { + if (\interface_exists('Doctrine\DBAL\VersionAwarePlatformDriver')) { self::markTestSkipped('Test requires Doctrine DBAL 4.x'); } } diff --git a/src/bridge/symfony/telemetry-bundle/tests/Flow/Bridge/Symfony/TelemetryBundle/Tests/Unit/Instrumentation/Doctrine/DBAL/TracingDriverTest.php b/src/bridge/symfony/telemetry-bundle/tests/Flow/Bridge/Symfony/TelemetryBundle/Tests/Unit/Instrumentation/Doctrine/DBAL/TracingDriverTest.php index 0c8305c5f..48d7cbccd 100644 --- a/src/bridge/symfony/telemetry-bundle/tests/Flow/Bridge/Symfony/TelemetryBundle/Tests/Unit/Instrumentation/Doctrine/DBAL/TracingDriverTest.php +++ b/src/bridge/symfony/telemetry-bundle/tests/Flow/Bridge/Symfony/TelemetryBundle/Tests/Unit/Instrumentation/Doctrine/DBAL/TracingDriverTest.php @@ -6,7 +6,7 @@ use Doctrine\DBAL\Driver\API\ExceptionConverter; use Doctrine\DBAL\Driver\{Connection, Result, Statement}; -use Doctrine\DBAL\{Driver, ServerVersionProvider, VersionAwarePlatformDriver}; +use Doctrine\DBAL\{Driver, ServerVersionProvider}; use Doctrine\DBAL\Platforms\{AbstractPlatform, DB2Platform, MariaDBPlatform, MySQL80Platform, OraclePlatform, PostgreSQLPlatform, SQLServerPlatform, SQLitePlatform}; use Flow\Bridge\Symfony\TelemetryBundle\Instrumentation\Doctrine\DBAL\V4\TracingDriver; use Flow\Telemetry\Context\MemoryContextStorage; @@ -25,7 +25,7 @@ final class TracingDriverTest extends TestCase { protected function setUp() : void { - if (\interface_exists(VersionAwarePlatformDriver::class)) { + if (\interface_exists('Doctrine\DBAL\VersionAwarePlatformDriver')) { self::markTestSkipped('Test requires Doctrine DBAL 4.x'); } } diff --git a/src/bridge/symfony/telemetry-bundle/tests/Flow/Bridge/Symfony/TelemetryBundle/Tests/Unit/Instrumentation/Doctrine/DBAL/V3/TracingConnectionTest.php b/src/bridge/symfony/telemetry-bundle/tests/Flow/Bridge/Symfony/TelemetryBundle/Tests/Unit/Instrumentation/Doctrine/DBAL/V3/TracingConnectionTest.php index f38ab4428..754c93f73 100644 --- a/src/bridge/symfony/telemetry-bundle/tests/Flow/Bridge/Symfony/TelemetryBundle/Tests/Unit/Instrumentation/Doctrine/DBAL/V3/TracingConnectionTest.php +++ b/src/bridge/symfony/telemetry-bundle/tests/Flow/Bridge/Symfony/TelemetryBundle/Tests/Unit/Instrumentation/Doctrine/DBAL/V3/TracingConnectionTest.php @@ -5,7 +5,7 @@ namespace Flow\Bridge\Symfony\TelemetryBundle\Tests\Unit\Instrumentation\Doctrine\DBAL\V3; use Doctrine\DBAL\Driver\{Connection as ConnectionInterface, Result, Statement as DriverStatement}; -use Doctrine\DBAL\{ParameterType, VersionAwarePlatformDriver}; +use Doctrine\DBAL\ParameterType; use Flow\Bridge\Symfony\TelemetryBundle\Instrumentation\Doctrine\DBAL\V3\TracingConnection; use Flow\Telemetry\Context\MemoryContextStorage; use Flow\Telemetry\Logger\LoggerProvider; @@ -23,7 +23,7 @@ final class TracingConnectionTest extends TestCase { protected function setUp() : void { - if (!\interface_exists(VersionAwarePlatformDriver::class)) { + if (!\interface_exists('Doctrine\DBAL\VersionAwarePlatformDriver')) { self::markTestSkipped('Test requires Doctrine DBAL 3.x'); } } diff --git a/src/bridge/symfony/telemetry-bundle/tests/Flow/Bridge/Symfony/TelemetryBundle/Tests/Unit/Instrumentation/Doctrine/DBAL/V3/TracingDriverTest.php b/src/bridge/symfony/telemetry-bundle/tests/Flow/Bridge/Symfony/TelemetryBundle/Tests/Unit/Instrumentation/Doctrine/DBAL/V3/TracingDriverTest.php index 0e2a198d4..cc9804860 100644 --- a/src/bridge/symfony/telemetry-bundle/tests/Flow/Bridge/Symfony/TelemetryBundle/Tests/Unit/Instrumentation/Doctrine/DBAL/V3/TracingDriverTest.php +++ b/src/bridge/symfony/telemetry-bundle/tests/Flow/Bridge/Symfony/TelemetryBundle/Tests/Unit/Instrumentation/Doctrine/DBAL/V3/TracingDriverTest.php @@ -6,8 +6,7 @@ use Doctrine\DBAL\Driver\API\ExceptionConverter; use Doctrine\DBAL\Driver\{Connection, Result, Statement}; -use Doctrine\DBAL\{Driver, VersionAwarePlatformDriver}; -use Doctrine\DBAL\ParameterType; +use Doctrine\DBAL\{Driver, ParameterType}; use Doctrine\DBAL\Platforms\{AbstractPlatform, DB2Platform, MariaDBPlatform, MySQL80Platform, OraclePlatform, PostgreSQLPlatform, SQLServerPlatform, SqlitePlatform}; use Doctrine\DBAL\Schema\AbstractSchemaManager; use Flow\Bridge\Symfony\TelemetryBundle\Instrumentation\Doctrine\DBAL\V3\TracingDriver; @@ -27,7 +26,7 @@ final class TracingDriverTest extends TestCase { protected function setUp() : void { - if (!\interface_exists(VersionAwarePlatformDriver::class)) { + if (!\interface_exists('Doctrine\DBAL\VersionAwarePlatformDriver')) { self::markTestSkipped('Test requires Doctrine DBAL 3.x'); } } diff --git a/src/lib/postgresql/src/Flow/PostgreSql/Client/Types/Converter/ByteaConverter.php b/src/lib/postgresql/src/Flow/PostgreSql/Client/Types/Converter/ByteaConverter.php index f7dbf3eb1..29fa9049c 100644 --- a/src/lib/postgresql/src/Flow/PostgreSql/Client/Types/Converter/ByteaConverter.php +++ b/src/lib/postgresql/src/Flow/PostgreSql/Client/Types/Converter/ByteaConverter.php @@ -21,7 +21,7 @@ public function toDatabase(mixed $value) : ?string } if (\is_string($value)) { - return $value; + return '\x' . \bin2hex($value); } throw ValueConversionException::cannotConvert($value, 'bytea'); diff --git a/src/lib/postgresql/tests/Flow/PostgreSql/Tests/Integration/Client/Types/Converter/ByteaConverterTest.php b/src/lib/postgresql/tests/Flow/PostgreSql/Tests/Integration/Client/Types/Converter/ByteaConverterTest.php index 62b4a4764..c5caaaa57 100644 --- a/src/lib/postgresql/tests/Flow/PostgreSql/Tests/Integration/Client/Types/Converter/ByteaConverterTest.php +++ b/src/lib/postgresql/tests/Flow/PostgreSql/Tests/Integration/Client/Types/Converter/ByteaConverterTest.php @@ -4,7 +4,8 @@ namespace Flow\PostgreSql\Tests\Integration\Client\Types\Converter; -use function Flow\PostgreSql\DSL\{cast, column_type_bytea, literal, param, select}; +use function Flow\PostgreSql\DSL\{cast, column_type_bytea, literal, param, select, typed}; +use Flow\PostgreSql\Client\Types\ValueType; use Flow\PostgreSql\Tests\Integration\PostgreSqlTestCase; use PHPUnit\Framework\Attributes\DataProvider; @@ -31,6 +32,17 @@ public static function provide_hex_bytea_values() : \Generator yield 'mixed case' => ['deadbeef', "\xde\xad\xbe\xef"]; } + /** + * @return \Generator + */ + public static function provide_typed_bytea_binary_values() : \Generator + { + yield 'leading null bytes' => ["\x00\x00\x00\x02\x11\x06value1"]; + yield 'embedded null bytes' => ["hello\x00world"]; + yield 'high bytes' => ["\x01\x02\x03\xff\xfe"]; + yield 'serialize output' => [\serialize(['greeting' => 'world', 'count' => 7])]; + } + public function test_binary_data_via_hex_literal() : void { $result = $this->pgsqlContext()->client()->fetchScalar(select(cast(literal('\\x00010203'), column_type_bytea())->as('val'))->toSql()); @@ -76,4 +88,15 @@ public function test_null_bytea() : void self::assertNull($result); } + + #[DataProvider('provide_typed_bytea_binary_values')] + public function test_typed_bytea_round_trip_preserves_binary(string $input) : void + { + $result = $this->pgsqlContext()->client()->fetchScalar( + select(cast(param(1), column_type_bytea())->as('val'))->toSql(), + [typed($input, ValueType::BYTEA)], + ); + + self::assertSame($input, $result); + } } diff --git a/src/lib/postgresql/tests/Flow/PostgreSql/Tests/Unit/Client/Types/Converter/ByteaConverterTest.php b/src/lib/postgresql/tests/Flow/PostgreSql/Tests/Unit/Client/Types/Converter/ByteaConverterTest.php index 362d007ad..9eb8b8ec3 100644 --- a/src/lib/postgresql/tests/Flow/PostgreSql/Tests/Unit/Client/Types/Converter/ByteaConverterTest.php +++ b/src/lib/postgresql/tests/Flow/PostgreSql/Tests/Unit/Client/Types/Converter/ByteaConverterTest.php @@ -24,17 +24,17 @@ public static function provide_invalid_values() : \Generator public static function provide_valid_values() : \Generator { - yield 'simple text' => ['simple text', 'simple text']; - yield 'hello' => ['hello', 'hello']; - yield 'empty string' => ['', '']; - yield 'binary with null byte' => ["hello\x00world", "hello\x00world"]; - yield 'binary with special bytes' => ["\x01\x02\x03\xff\xfe", "\x01\x02\x03\xff\xfe"]; - yield 'unicode characters' => ['日本語テスト', '日本語テスト']; - yield 'emoji' => ['Hello 🎉 World', 'Hello 🎉 World']; - yield 'newlines and tabs' => ["line1\nline2\ttab", "line1\nline2\ttab"]; - yield 'backslash' => ['path\\to\\file', 'path\\to\\file']; - yield 'single quote' => ["it's a test", "it's a test"]; - yield 'double quote' => ['say "hello"', 'say "hello"']; + yield 'simple text' => ['simple text', '\x' . \bin2hex('simple text')]; + yield 'hello' => ['hello', '\x' . \bin2hex('hello')]; + yield 'empty string' => ['', '\x']; + yield 'binary with null byte' => ["hello\x00world", '\x' . \bin2hex("hello\x00world")]; + yield 'binary with special bytes' => ["\x01\x02\x03\xff\xfe", '\x' . \bin2hex("\x01\x02\x03\xff\xfe")]; + yield 'unicode characters' => ['日本語テスト', '\x' . \bin2hex('日本語テスト')]; + yield 'emoji' => ['Hello 🎉 World', '\x' . \bin2hex('Hello 🎉 World')]; + yield 'newlines and tabs' => ["line1\nline2\ttab", '\x' . \bin2hex("line1\nline2\ttab")]; + yield 'backslash' => ['path\\to\\file', '\x' . \bin2hex('path\\to\\file')]; + yield 'single quote' => ["it's a test", '\x' . \bin2hex("it's a test")]; + yield 'double quote' => ['say "hello"', '\x' . \bin2hex('say "hello"')]; } #[DataProvider('provide_invalid_values')]