From e9b2b785a8e6b88d5b00454255f8437b6a64424c Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sun, 7 May 2023 13:17:11 +0200 Subject: [PATCH] Support unserializing 2.14 ParserResult instances --- lib/Doctrine/ORM/Query/ParserResult.php | 24 ++++++ .../ParserResultSerializationTest.php | 70 ++++++++++++++++++ .../ParserResults/single_select_2_14_3.txt | Bin 0 -> 2373 bytes .../ParserResults/single_select_2_15_0.txt | Bin 0 -> 2370 bytes 4 files changed, 94 insertions(+) create mode 100644 tests/Doctrine/Tests/ORM/Functional/ParserResultSerializationTest.php create mode 100644 tests/Doctrine/Tests/ORM/Functional/ParserResults/single_select_2_14_3.txt create mode 100644 tests/Doctrine/Tests/ORM/Functional/ParserResults/single_select_2_15_0.txt diff --git a/lib/Doctrine/ORM/Query/ParserResult.php b/lib/Doctrine/ORM/Query/ParserResult.php index 0f685a054fd..e16b5ebc351 100644 --- a/lib/Doctrine/ORM/Query/ParserResult.php +++ b/lib/Doctrine/ORM/Query/ParserResult.php @@ -6,6 +6,8 @@ use Doctrine\ORM\Query\Exec\AbstractSqlExecutor; +use function sprintf; + /** * Encapsulates the resulting components from a DQL query parsing process that * can be serialized. @@ -14,6 +16,12 @@ */ class ParserResult { + private const LEGACY_PROPERTY_MAPPING = [ + 'sqlExecutor' => '_sqlExecutor', + 'resultSetMapping' => '_resultSetMapping', + 'parameterMappings' => '_parameterMappings', + ]; + /** * The SQL executor used for executing the SQL. * @@ -122,4 +130,20 @@ public function getSqlParameterPositions($dqlPosition) { return $this->parameterMappings[$dqlPosition]; } + + public function __wakeup(): void + { + $this->__unserialize((array) $this); + } + + /** @param array $data */ + public function __unserialize(array $data): void + { + foreach (self::LEGACY_PROPERTY_MAPPING as $property => $legacyProperty) { + $this->$property = $data[sprintf("\0%s\0%s", self::class, $legacyProperty)] + ?? $data[sprintf("\0%s\0%s", self::class, $property)] + ?? $this->$property + ?? null; + } + } } diff --git a/tests/Doctrine/Tests/ORM/Functional/ParserResultSerializationTest.php b/tests/Doctrine/Tests/ORM/Functional/ParserResultSerializationTest.php new file mode 100644 index 00000000000..f5718715e2a --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/ParserResultSerializationTest.php @@ -0,0 +1,70 @@ +useModelSet('company'); + + parent::setUp(); + } + + public function testSerializeParserResult(): void + { + $query = $this->_em + ->createQuery('SELECT u FROM Doctrine\Tests\Models\Company\CompanyEmployee u WHERE u.name = :name'); + + $parserResult = self::parseQuery($query); + $serialized = serialize($parserResult); + $unserialized = unserialize($serialized); + + $this->assertInstanceOf(ParserResult::class, $unserialized); + $this->assertInstanceOf(ResultSetMapping::class, $unserialized->getResultSetMapping()); + $this->assertEquals(['name' => [0]], $unserialized->getParameterMappings()); + $this->assertInstanceOf(SingleSelectExecutor::class, $unserialized->getSqlExecutor()); + } + + /** + * @dataProvider provideSerializedSingleSelectResults + */ + public function testUnserializeSingleSelectResult(string $serialized): void + { + $unserialized = unserialize($serialized); + + $this->assertInstanceOf(ParserResult::class, $unserialized); + $this->assertInstanceOf(ResultSetMapping::class, $unserialized->getResultSetMapping()); + $this->assertEquals(['name' => [0]], $unserialized->getParameterMappings()); + $this->assertInstanceOf(SingleSelectExecutor::class, $unserialized->getSqlExecutor()); + } + + /** @return Generator */ + public static function provideSerializedSingleSelectResults(): Generator + { + yield '2.14.3' => [file_get_contents(__DIR__ . '/ParserResults/single_select_2_14_3.txt')]; + yield '2.15.0' => [file_get_contents(__DIR__ . '/ParserResults/single_select_2_15_0.txt')]; + } + + private static function parseQuery(Query $query): ParserResult + { + $r = new ReflectionMethod($query, 'parse'); + $r->setAccessible(true); + + return $r->invoke($query); + } +} diff --git a/tests/Doctrine/Tests/ORM/Functional/ParserResults/single_select_2_14_3.txt b/tests/Doctrine/Tests/ORM/Functional/ParserResults/single_select_2_14_3.txt new file mode 100644 index 0000000000000000000000000000000000000000..db83fe2de48b85df26d722963cb94cc6a96554be GIT binary patch literal 2373 zcmbW3TTk0C6vuhqr-<@6O{nRGiz_s-QZy#ovKDDCl`NASn5SGy>ohH2=P&ay7qErJ-_4W|`Vhbi|7h-JS>!-dK7d z&0{)zrg&+KGVD)8x4ZXvUNWEQ{2`?or4-xs9?@o7(J^d&bf?X%vXoJ7P1rZ0a}0lH z!|UPTHi%pDP$$9pEYOK;eRA_$WyBKxml0%t|&_b1#k7nIwCOg$W z3-tx8yRG#^cA;&{L#u7-G;Sb!kiwrto49nx@jxDVsaX_DL()6Dp2%Z=Qmo2Ks+ED6u&+eq zs1o6l17VWa_HM~oGanTRrDi_xDX;&BRpvvEF9LZbrON6euTE`=7gm6AkOYp-8x|{F zM}+s9(xeI(5G!%y+6g`bTbEcK^595>9$e?8pYRaz)#z5s{FEnATZBz^oeZVe$eaYu zn+?J&I&DaJjePGmI)i*r$A%?bq1Vf|?q4lfaVe6M4jz5VYaz z2PpU?HyWh!OXrrrE6QLpe%SUBlryPC<3c+`UJ4t6cS9lBtE_jE3qa2R9wM8x<_USyK=Pz7A&QV1f zQj$;%0s+b(RmRZXR(eNk@3!6lUk-mX=)1hwSIGArgevS*{axp5BeM09|Lf8m`Nzd$ z4?eWHO1LL+4OSF1$_g7fJx%U@;TxdYj=t(`^aeL-qO8If3Ep(;ddEK;H5+Z*v0JRI nmpVlFD3H}dR^EP|aF1_U*#HYy_-Dak)e_hhhu7%{`tRh^&@)3>*W z8#0xvuh_(a9PU71*!t<+bUEGU^D21Bx$pN}QGPHV6BU1>o3i+#QwqoP@dNO<{0BTr z2h@t}Ol>x(KQl5o>m<;#*IFu~OJ)OTXfxAyl!W8Yq6fz=SmHTiQRGD`)ylw3I94KZ zP>FEMaSYq`Zpm1)o)rnDWM_MbAd4?3ZnGYQinwYz&9Yz%)>{GtYx;1vUp|-}|Be3M!M2^@Jf;N2l z00p1qR)17}>D&@<qAf8!VDuWsuO z&k&Y(w8>yxq}wcC{LG2d$RIeJk=q&s6v+X4z(Fm11VJtCtbcV5Biqzi4qYIX>ag1N zVTYBerS6zIRC(S$=21EP4iti~3YR>c>0IG0n7H5_{;hI2>KYcffY_(=gzjE*1vy6* zWk^XvF$e@GlT;Z)ovn04Yd>zg|GylbH0V)YbQSWrgPvCXsB;bx;m5yu$p3U{&ivcr zu?HX8TqoR@H4nkcLAJ%T6Qy58{*N6khbckBUc r%~FR59|f|``0;82=>E<*!8LwhWX~%+;j5Wl2frH64*wn=9-jRItfCbX literal 0 HcmV?d00001