packages/ztd-query-sqlite/src/Rewrite/GeneratedColumn/SqliteGeneratedColumnProjector.php
1<?php
2
3declare(strict_types=1);
4
5namespace ZtdQuery\Platform\Sqlite\Rewrite\GeneratedColumn;
6
7use ZtdQuery\Platform\IdentifierQuoter;
8
9/**
10 * Recomputes database-generated columns from a complete base-row projection.
11 */
12final class SqliteGeneratedColumnProjector
13{
14 private const SOURCE_ALIAS = '__ztd_generated_source';
15
16 private readonly IdentifierQuoter $quoter;
17
18 /**
19 * Binds the dependencies used by this operation.
20 */
21 public function __construct()
22 {
23 $this->quoter = new \ZtdQuery\Platform\Sqlite\Sql\SqliteIdentifierQuoter();
24 }
25
26 /**
27 * @param array<int, string> $columns
28 * @param array<string, string> $generatedExpressions
29 */
30 public function project(string $sourceSql, array $columns, array $generatedExpressions): string
31 {
32 if ($generatedExpressions === []) {
33 return $sourceSql;
34 }
35
36 $sourceAlias = $this->quoter->quote(self::SOURCE_ALIAS);
37 $selects = [];
38 foreach ($columns as $column) {
39 $quotedColumn = $this->quoter->quote($column);
40 $expression = $generatedExpressions[$column] ?? null;
41 $selects[] = $expression === null
42 ? "$sourceAlias.$quotedColumn AS $quotedColumn"
43 : "$expression AS $quotedColumn";
44 }
45
46 return 'SELECT ' . implode(', ', $selects) . " FROM ($sourceSql) AS $sourceAlias";
47 }
48}
49