From 61e4f32ac9699f6da494ff65b290cdd18c1ab7ff Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Tue, 11 Apr 2023 10:01:58 +0200 Subject: [PATCH] Query: Fix cloning --- src/Query.php | 2 +- src/Resolver.php | 27 ++++++++++++++++++++++++++ tests/QueryTest.php | 46 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/src/Query.php b/src/Query.php index 7da886e..de09944 100644 --- a/src/Query.php +++ b/src/Query.php @@ -824,7 +824,7 @@ protected function order(Select $select) public function __clone() { - $this->resolver = clone $this->resolver; + $this->resolver = $this->resolver->cloneMe($this); if ($this->filter !== null) { $this->filter = clone $this->filter; diff --git a/src/Resolver.php b/src/Resolver.php index 4ce2aac..cf11093 100644 --- a/src/Resolver.php +++ b/src/Resolver.php @@ -795,4 +795,31 @@ protected function collectMetaData(Model $subject) return $definitions; } + + private function setQuery(Query $query): self + { + $this->query = $query; + + return $this; + } + + public function cloneMe($query) + { + $self = clone $this; + $self->setQuery($query); + + return $self; + } + + public function __clone() + { + $this->relations = clone $this->relations; + $this->behaviors = clone $this->behaviors; + $this->defaults = clone $this->defaults; + $this->aliases = clone $this->aliases; + $this->selectableColumns = clone $this->selectableColumns; + $this->selectColumns = clone $this->selectColumns; + $this->metaData = clone $this->metaData; + $this->resolvedRelations = clone $this->resolvedRelations; + } } diff --git a/tests/QueryTest.php b/tests/QueryTest.php index cdf3920..ca25892 100644 --- a/tests/QueryTest.php +++ b/tests/QueryTest.php @@ -5,6 +5,7 @@ use ipl\Orm\Exception\InvalidRelationException; use ipl\Orm\Query; use ipl\Sql\Expression; +use ipl\Stdlib\Filter; use ipl\Tests\Sql\TestCase; class QueryTest extends TestCase @@ -485,4 +486,49 @@ public function testWithoutColumnsDoesNotWorkWithExpressions() $query->assembleSelect() ); } + + public function testSubQueriesCanBeAdjustedAfterBeingCloned() + { + $query = (new Query()) + ->setModel(new User()) + ->setDb(new TestConnection()); + + $carOneSubQuery = $query->createSubQuery(new Car(), 'user.car') + ->columns([new Expression('%s', ['passenger.name'])]); + + $carTwoSubQuery = clone $carOneSubQuery; + + $carOneSubQuery->filter(Filter::equal('manufacturer', 'wv')); + $carTwoSubQuery->filter(Filter::equal('manufacturer', 'taif')); + + list($carOneSelect, $carOneValues) = $carOneSubQuery->dump(); + list($carTwoSelect, $carTwoValues) = $carTwoSubQuery->dump(); + + $query->withColumns([ + new Expression($carOneSelect, null, $carOneValues), + new Expression($carTwoSelect, null, $carTwoValues) + ]); + + $sql = <<<'SQL' +SELECT user.id, + user.username, + user.password, + (SELECT (sub_car_passenger.name) FROM car sub_car + INNER JOIN passenger sub_car_passenger ON sub_car_passenger.car_id = sub_car.id + INNER JOIN car_user sub_car_car_user ON sub_car_car_user.car_id = sub_car.id + INNER JOIN user sub_car_user ON sub_car_user.id = sub_car_car_user.user_id + WHERE (sub_car_user.id = user.id) AND (sub_car.manufacturer = ?)), + (SELECT (sub_car_passenger.name) FROM car sub_car + INNER JOIN passenger sub_car_passenger ON sub_car_passenger.car_id = sub_car.id + INNER JOIN car_user sub_car_car_user ON sub_car_car_user.car_id = sub_car.id + INNER JOIN user sub_car_user ON sub_car_user.id = sub_car_car_user.user_id + WHERE (sub_car_user.id = user.id) AND (sub_car.manufacturer = ?)) + FROM user +SQL; + + $this->assertSql( + $sql, + $query->assembleSelect() + ); + } }