Skip to content

Commit d7ba187

Browse files
committed
Eliminate SqlFragment, inline string concatenation, simplify prepare wiring
Replace SqlFragment fluent chain with direct string concatenation in Select, Update, and Delete buildSqlString() — removes object allocation, array building, and implode() from every render. Simplify Quantifier to store raw ExpressionInterface|string instead of ArgumentInterface wrappers (same pattern as ColumnRef/OrderSpec). Make Columns fields public for direct access from Table::prepare(), eliminating six method calls per prepare cycle. Make From::$ref public so Table can check it directly instead of calling isEmpty(). Delete SqlFragment class — no remaining callers. Signed-off-by: Simon Mundy <simon.mundy@peptolab.com>
1 parent 106ceab commit d7ba187

File tree

8 files changed

+81
-131
lines changed

8 files changed

+81
-131
lines changed

src/Sql/Delete.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
use PhpDb\Adapter\Driver\DriverInterface;
99
use PhpDb\Adapter\ParameterContainer;
1010
use PhpDb\Adapter\Platform\PlatformInterface;
11-
use PhpDb\Sql\Part\SqlFragment;
1211
use PhpDb\Sql\Part\SqlProcessor;
1312
use PhpDb\Sql\Part\From;
1413
use PhpDb\Sql\Part\Where as WherePart;
@@ -90,9 +89,15 @@ public function buildSqlString(
9089
$processor->setParamPrefix($this->processInfo['paramPrefix']);
9190
$sqlPlatform?->getTypeDecorator($this)?->prepare($this, $processor);
9291

93-
return (string) SqlFragment::of($this->getStatementKeyword())
94-
->part($this->table->toSql($processor))
95-
->part($this->where?->toSql($processor));
92+
$sql = $this->getStatementKeyword();
93+
if (($part = $this->table->toSql($processor)) !== null) {
94+
$sql .= ' ' . $part;
95+
}
96+
if (($part = $this->where?->toSql($processor)) !== null) {
97+
$sql .= ' ' . $part;
98+
}
99+
100+
return $sql;
96101
}
97102

98103
/**

src/Sql/Part/Columns.php

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,13 @@ class Columns extends AbstractPart
3131
/** @var array Raw columns for getRawState() backward compatibility */
3232
private array $rawColumns = [Select::SQL_STAR];
3333

34-
private bool $prefixColumnsWithTable = true;
34+
public bool $prefixColumnsWithTable = true;
3535

36-
/**
37-
* Set during preparePartsForBuild -- the resolved table prefix (e.g. "table".)
38-
*/
39-
private string $fromTablePrefix = '';
36+
/** @var string Resolved table prefix (e.g. "table".) — set by Table::prepare() */
37+
public string $fromTablePrefix = '';
4038

41-
/** @var JoinSpec[] Join specs for column resolution */
42-
private array $joinSpecs = [];
39+
/** @var JoinSpec[] Join specs — set by Table::prepare() */
40+
public array $joinSpecs = [];
4341

4442
public function __construct()
4543
{
@@ -168,26 +166,6 @@ public function getPrefixColumnsWithTable(): bool
168166
return $this->prefixColumnsWithTable;
169167
}
170168

171-
/**
172-
* Set the table prefix for column resolution (e.g. "table".)
173-
*/
174-
public function setFromTablePrefix(string $prefix): static
175-
{
176-
$this->fromTablePrefix = $prefix;
177-
return $this;
178-
}
179-
180-
/**
181-
* Set join specs for column resolution during rendering.
182-
*
183-
* @param JoinSpec[] $specs
184-
*/
185-
public function setJoinSpecs(array $specs): static
186-
{
187-
$this->joinSpecs = $specs;
188-
return $this;
189-
}
190-
191169
/**
192170
* Normalize the raw columns array into ColumnRef[].
193171
*/

src/Sql/Part/From.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
*/
1515
class From extends AbstractPart
1616
{
17-
private ?TableRef $ref = null;
17+
public ?TableRef $ref = null;
1818

1919
private ?string $resolvedTable = null;
2020

src/Sql/Part/Quantifier.php

Lines changed: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,25 @@
44

55
namespace PhpDb\Sql\Part;
66

7-
use PhpDb\Sql\Argument\Literal;
8-
use PhpDb\Sql\Argument\Select as SelectArgument;
9-
use PhpDb\Sql\ArgumentInterface;
10-
use PhpDb\Sql\ArgumentType;
117
use PhpDb\Sql\ExpressionInterface;
12-
use ValueError;
138

14-
/**
15-
* Holds and renders a SELECT quantifier (DISTINCT, ALL, or expression).
16-
* Normalizes input to ArgumentInterface at set time.
17-
*/
9+
use function is_string;
10+
1811
class Quantifier extends AbstractPart
1912
{
20-
private ?ArgumentInterface $quantifier = null;
13+
private ExpressionInterface|string|null $quantifier = null;
2114

2215
public function toSql(SqlProcessor $processor): ?string
2316
{
2417
if ($this->quantifier === null) {
2518
return null;
2619
}
2720

28-
return match ($this->quantifier->getType()) {
29-
ArgumentType::Literal => $this->quantifier->getValue(),
30-
ArgumentType::Select => $processor->renderExpression($this->quantifier->getValue(), 'quantifier'),
31-
default => throw new ValueError('Unexpected ArgumentType: ' . $this->quantifier->getType()->name),
32-
};
21+
if (is_string($this->quantifier)) {
22+
return $this->quantifier;
23+
}
24+
25+
return $processor->renderExpression($this->quantifier, 'quantifier');
3326
}
3427

3528
public function isEmpty(): bool
@@ -39,25 +32,12 @@ public function isEmpty(): bool
3932

4033
public function set(string|ExpressionInterface|null $quantifier): static
4134
{
42-
if ($quantifier === null) {
43-
$this->quantifier = null;
44-
} elseif ($quantifier instanceof ExpressionInterface) {
45-
$this->quantifier = new SelectArgument($quantifier);
46-
} else {
47-
$this->quantifier = new Literal($quantifier);
48-
}
35+
$this->quantifier = $quantifier;
4936
return $this;
5037
}
5138

52-
/**
53-
* Reconstruct the original format for getRawState() compatibility.
54-
*/
5539
public function get(): string|ExpressionInterface|null
5640
{
57-
if ($this->quantifier === null) {
58-
return null;
59-
}
60-
61-
return $this->quantifier->getValue();
41+
return $this->quantifier;
6242
}
6343
}

src/Sql/Part/SqlFragment.php

Lines changed: 0 additions & 40 deletions
This file was deleted.

src/Sql/Part/Table.php

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class Table
2222
{
2323
private From $from;
2424
private Columns $columns;
25-
private ?Joins $joins = null;
25+
private ?Joins $joins = null;
2626
private ?int $preparedPlatformId = null;
2727

2828
/** Backward-compat model exposed via getRawState / __get */
@@ -50,7 +50,7 @@ public function getFrom(): string|array|TableIdentifier|Select|null
5050

5151
public function hasFrom(): bool
5252
{
53-
return !$this->from->isEmpty();
53+
return ! $this->from->isEmpty();
5454
}
5555

5656
public function resetFrom(): static
@@ -106,12 +106,12 @@ public function join(
106106

107107
public function hasJoins(): bool
108108
{
109-
return $this->joins !== null && !$this->joins->isEmpty();
109+
return $this->joins !== null && ! $this->joins->isEmpty();
110110
}
111111

112112
public function resetJoins(): static
113113
{
114-
$this->joins = null;
114+
$this->joins = null;
115115
$this->preparedPlatformId = null;
116116
return $this;
117117
}
@@ -125,12 +125,10 @@ public function prepare(SqlProcessor $processor): void
125125
return;
126126
}
127127

128-
if ($this->columns->getPrefixColumnsWithTable() && !$this->from->isEmpty()) {
129-
$this->columns->setFromTablePrefix($this->from->getQuotedPrefix($processor));
130-
} else {
131-
$this->columns->setFromTablePrefix('');
132-
}
133-
$this->columns->setJoinSpecs($this->joins !== null ? $this->joins->getSpecs() : []);
128+
$this->columns->fromTablePrefix = $this->columns->prefixColumnsWithTable && $this->from->ref !== null
129+
? $this->from->getQuotedPrefix($processor)
130+
: '';
131+
$this->columns->joinSpecs = $this->joins?->getSpecs() ?? [];
134132
$this->preparedPlatformId = $platformId;
135133
}
136134

src/Sql/Select.php

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
use PhpDb\Sql\Part\Offset;
1616
use PhpDb\Sql\Part\OrderBy;
1717
use PhpDb\Sql\Part\Quantifier;
18-
use PhpDb\Sql\Part\SqlFragment;
1918
use PhpDb\Sql\Part\SqlProcessor;
2019
use PhpDb\Sql\Part\Table;
2120
use PhpDb\Sql\Part\Where as WherePart;
@@ -387,18 +386,41 @@ public function buildSqlString(
387386
$sqlPlatform?->getTypeDecorator($this)?->prepare($this, $processor);
388387
$this->table->prepare($processor);
389388

390-
return (string) SqlFragment::of('SELECT')
391-
->part($this->quantifier?->toSql($processor))
392-
->part($this->table->columns()->toSql($processor))
393-
->part($this->table->from()->toSql($processor))
394-
->part($this->table->joins()?->toSql($processor))
395-
->part($this->where?->toSql($processor))
396-
->part($this->groupBy?->toSql($processor))
397-
->part($this->having?->toSql($processor))
398-
->part($this->orderBy?->toSql($processor))
399-
->part($this->limit?->toSql($processor))
400-
->part($this->offset?->toSql($processor))
401-
->wrap($this->combine?->toSql($processor));
389+
$sql = 'SELECT';
390+
391+
if (($part = $this->quantifier?->toSql($processor)) !== null) {
392+
$sql .= ' ' . $part;
393+
}
394+
$sql .= ' ' . $this->table->columns()->toSql($processor);
395+
if (($part = $this->table->from()->toSql($processor)) !== null) {
396+
$sql .= ' ' . $part;
397+
}
398+
if (($part = $this->table->joins()?->toSql($processor)) !== null) {
399+
$sql .= ' ' . $part;
400+
}
401+
if (($part = $this->where?->toSql($processor)) !== null) {
402+
$sql .= ' ' . $part;
403+
}
404+
if (($part = $this->groupBy?->toSql($processor)) !== null) {
405+
$sql .= ' ' . $part;
406+
}
407+
if (($part = $this->having?->toSql($processor)) !== null) {
408+
$sql .= ' ' . $part;
409+
}
410+
if (($part = $this->orderBy?->toSql($processor)) !== null) {
411+
$sql .= ' ' . $part;
412+
}
413+
if (($part = $this->limit?->toSql($processor)) !== null) {
414+
$sql .= ' ' . $part;
415+
}
416+
if (($part = $this->offset?->toSql($processor)) !== null) {
417+
$sql .= ' ' . $part;
418+
}
419+
if (($part = $this->combine?->toSql($processor)) !== null) {
420+
$sql = '( ' . $sql . ' ) ' . $part;
421+
}
422+
423+
return $sql;
402424
}
403425

404426
/**

src/Sql/Update.php

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
use PhpDb\Adapter\Platform\PlatformInterface;
1111
use PhpDb\Sql\Part\Joins as JoinsPart;
1212
use PhpDb\Sql\Part\Set as SetPart;
13-
use PhpDb\Sql\Part\SqlFragment;
1413
use PhpDb\Sql\Part\SqlProcessor;
1514
use PhpDb\Sql\Part\From;
1615
use PhpDb\Sql\Part\Where as WherePart;
@@ -136,11 +135,19 @@ public function buildSqlString(
136135
$processor->setParamPrefix($this->processInfo['paramPrefix']);
137136
$sqlPlatform?->getTypeDecorator($this)?->prepare($this, $processor);
138137

139-
return (string) SqlFragment::of($this->getStatementKeyword())
140-
->part($this->table->renderTable($processor))
141-
->part($this->joins?->toSql($processor))
142-
->part($this->set->toSql($processor))
143-
->part($this->where?->toSql($processor));
138+
$sql = $this->getStatementKeyword();
139+
$sql .= ' ' . $this->table->renderTable($processor);
140+
if (($part = $this->joins?->toSql($processor)) !== null) {
141+
$sql .= ' ' . $part;
142+
}
143+
if (($part = $this->set->toSql($processor)) !== null) {
144+
$sql .= ' ' . $part;
145+
}
146+
if (($part = $this->where?->toSql($processor)) !== null) {
147+
$sql .= ' ' . $part;
148+
}
149+
150+
return $sql;
144151
}
145152

146153
/**

0 commit comments

Comments
 (0)