diff --git a/.github/workflows/test-unit.yml b/.github/workflows/test-unit.yml index 47bb2dcd5..24a730b1e 100644 --- a/.github/workflows/test-unit.yml +++ b/.github/workflows/test-unit.yml @@ -61,6 +61,12 @@ jobs: if: matrix.type == 'Phpunit' run: "vendor/bin/phpunit \"$(if [ -n \"$LOG_COVERAGE\" ]; then echo '--coverage-text'; else echo '--no-coverage'; fi)\" -v" + - name: "Run tests: SQLite Hintable (only for Phpunit)" + if: matrix.type == 'Phpunit' + run: | + sed -i 's~"psr-4": {~"psr-4": { "Mvorisek\\\\Atk4\\\\Hintable\\\\Tests\\\\": "vendor/mahalux/atk4-hintable/tests/",~' composer.json && composer dump + vendor/bin/phpunit --configuration vendor/mahalux/atk4-hintable/phpunit.xml.dist --bootstrap vendor/autoload.php --no-coverage -v + - name: Check Coding Style (only for CodingStyle) if: matrix.type == 'CodingStyle' run: vendor/bin/php-cs-fixer fix --dry-run --using-cache=no --diff --diff-format=udiff --verbose --show-progress=dots diff --git a/src/Persistence/Array_.php b/src/Persistence/Array_.php index 5f7496600..6c5437e87 100644 --- a/src/Persistence/Array_.php +++ b/src/Persistence/Array_.php @@ -385,7 +385,15 @@ protected function setLimitOrder(Model $model, Action $action) */ protected function applyScope(Model $model, Action $action): void { - $action->filter($model->scope()); + $scope = $model->scope(); + + // add entity ID to scope to allow easy traversal + if ($model->id_field && $model->getId() !== null) { + $scope = new Model\Scope([$scope]); + $scope->addCondition($model->getField($model->id_field), $model->getId()); + } + + $action->filter($scope); } /** diff --git a/src/Persistence/Sql.php b/src/Persistence/Sql.php index 902e03c3c..1523a2ee5 100644 --- a/src/Persistence/Sql.php +++ b/src/Persistence/Sql.php @@ -14,6 +14,8 @@ use Atk4\Dsql\Expression; use Atk4\Dsql\Query; use Doctrine\DBAL\Platforms; +use Doctrine\DBAL\Platforms\OraclePlatform; +use Doctrine\DBAL\Platforms\SQLServer2012Platform; class Sql extends Persistence { @@ -369,6 +371,18 @@ protected function setLimitOrder(Model $model, Query $query) public function initQueryConditions(Model $model, Query $query): void { $this->_initQueryConditions($query, $model->scope()); + + // add entity ID to scope to allow easy traversal + if ($model->id_field && $model->getId() !== null) { + $query->group($model->getField($model->id_field)); + if ($this->getDatabasePlatform() instanceof SQLServer2012Platform + || $this->getDatabasePlatform() instanceof OraclePlatform) { + foreach ($query->args['field'] as $alias => $field) { + $query->group(is_int($alias) ? $field : $alias); + } + } + $query->having($model->getField($model->id_field), $model->getId()); + } } private function _initQueryConditions(Query $query, Model\Scope\AbstractScope $condition = null): void diff --git a/tests/ExpressionSqlTest.php b/tests/ExpressionSqlTest.php index 4b017c07b..a57fd598e 100644 --- a/tests/ExpressionSqlTest.php +++ b/tests/ExpressionSqlTest.php @@ -113,9 +113,9 @@ public function testQuery() ); } - $i->tryLoad(1); - $this->assertEquals(10, $i->get('total_net')); - $this->assertEquals(30, $i->get('sum_net')); + $ii = (clone $i)->tryLoad(1); + $this->assertEquals(10, $ii->get('total_net')); + $this->assertEquals(30, $ii->get('sum_net')); $q = $db->dsql(); $q->field($i->action('count'), 'total_orders');