Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
ca9b0e7
fix: add enclosure for sql identifiers
barbosa89 Apr 29, 2026
65e28ef
fix: add enclosure for sql identifiers
barbosa89 Apr 29, 2026
0dcd170
refactor: change strategy to compile join into dialects
barbosa89 Apr 30, 2026
5f34105
refactor: restructure Clause and Join classes to enhance code organiz…
barbosa89 Apr 30, 2026
3bfc84c
feat: add having compiler
barbosa89 Apr 30, 2026
182e7cf
fix: remove unused PrepareColumns trait to enhance code clarity
barbosa89 Apr 30, 2026
ef1b3e7
Enhance Query AST Management and Security Improvements
barbosa89 Apr 30, 2026
563e2fc
refactor: simplify placeholder conversion using arrow functions
barbosa89 Apr 30, 2026
6021454
refactor: streamline SQL compilation by directly invoking buildAst in…
barbosa89 Apr 30, 2026
4dd1cf0
Refactor ClauseCompiler and related compilers to use QueryAst directly
barbosa89 May 1, 2026
fc80668
refactor: streamline access to AST properties in SelectCompiler
barbosa89 May 1, 2026
ce1dc01
refactor: update AST driver access in compile methods for consistency
barbosa89 May 1, 2026
9f52add
refactor: remove unused ast() method and streamline AST access in Sel…
barbosa89 May 1, 2026
87c54ef
refactor: improve subquery handling and remove dialect factory caching
barbosa89 May 1, 2026
c39a9ff
refactor: replace Functions with Funct for improved function handling…
barbosa89 May 1, 2026
287bcc1
Refactor query generator tests to use new function syntax
barbosa89 May 2, 2026
91745f9
style: php cs
barbosa89 May 2, 2026
e897a76
refactor: update subquery function to accept columns parameter and en…
barbosa89 May 2, 2026
30e9dbe
refactor: remove unused case_of function to streamline code
barbosa89 May 2, 2026
2529af2
feat: add alias function and update tests to use it for improved quer…
barbosa89 May 4, 2026
852abb4
style: php cs
barbosa89 May 4, 2026
4a6d756
refactor: streamline having and lock compilation in SelectCompiler
barbosa89 May 4, 2026
a0f6cc1
refactor: reorganize imports and simplify null/boolean clause compila…
barbosa89 May 4, 2026
f0b4ca3
refactor: remove TODO comment for efficiency in HasPlaceholders trait
barbosa89 May 4, 2026
dfb31c6
fix: refactor resetBaseProperties to directly initialize QueryAst
barbosa89 May 4, 2026
d064fc8
style: php cs
barbosa89 May 4, 2026
76b7c97
refactor: rename alias function to alias_of for clarity
barbosa89 May 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"Phenix\\": "src/"
},
"files": [
"src/functions.php"
"src/functions.php",
"src/Database/functions.php"
]
},
"autoload-dev": {
Expand Down
12 changes: 11 additions & 1 deletion src/Database/Alias.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@

namespace Phenix\Database;

use Phenix\Database\Concerns\HasDriver;
use Stringable;

class Alias implements Stringable
{
use HasDriver;

protected string $alias;

public function __construct(protected readonly string $name)
Expand All @@ -24,7 +27,14 @@ public function as(string $alias): self

public function __toString(): string
{
return "{$this->name} AS {$this->alias}";
$parts = array_map(
fn (string $part): string => (string) Wrapper::of($this->getDriver(), $part),
explode('.', $this->name)
);

$alias = Wrapper::of($this->getDriver(), $this->alias);

return implode('.', $parts) . " AS {$alias}";
}

public static function of(string $name): self
Expand Down
88 changes: 2 additions & 86 deletions src/Database/Clause.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,93 +4,9 @@

namespace Phenix\Database;

use Closure;
use Phenix\Database\Clauses\BasicWhereClause;
use Phenix\Database\Clauses\SubqueryWhereClause;
use Phenix\Database\Clauses\WhereClause;
use Phenix\Database\Concerns\Query\HasWhereClause;
use Phenix\Database\Concerns\Query\PrepareColumns;
use Phenix\Database\Constants\LogicalConnector;
use Phenix\Database\Constants\Operator;
use Phenix\Database\Contracts\Builder;

use function count;

abstract class Clause extends Grammar implements Builder
abstract class Clause extends ClauseBuilder implements Builder
{
use HasWhereClause;
use PrepareColumns;

/**
* @var array<int, WhereClause>
*/
protected array $clauses;

protected array $arguments;

protected function resolveWhereMethod(
string $column,
Operator $operator,
Closure|array|string|int $value,
LogicalConnector $logicalConnector = LogicalConnector::AND
): void {
if ($value instanceof Closure) {
$this->whereSubquery(
subquery: $value,
comparisonOperator: $operator,
column: $column,
logicalConnector: $logicalConnector
);
} else {
$this->pushWhereWithArgs($column, $operator, $value, $logicalConnector);
}
}

protected function whereSubquery(
Closure $subquery,
Operator $comparisonOperator,
string|null $column = null,
Operator|null $operator = null,
LogicalConnector $logicalConnector = LogicalConnector::AND
): void {
$builder = new Subquery($this->driver);
$builder->select(['*']);

$subquery($builder);

[$dml, $arguments] = $builder->toSql();

$connector = count($this->clauses) === 0 ? null : $logicalConnector;

$this->clauses[] = new SubqueryWhereClause(
comparisonOperator: $comparisonOperator,
sql: trim($dml, '()'),
params: $arguments,
column: $column,
operator: $operator,
connector: $connector
);

$this->arguments = array_merge($this->arguments, $arguments);
}

protected function pushWhereWithArgs(
string $column,
Operator $operator,
array|string|int $value,
LogicalConnector $logicalConnector = LogicalConnector::AND
): void {
$this->pushClause(new BasicWhereClause($column, $operator, $value, null, true), $logicalConnector);

$this->arguments = array_merge($this->arguments, (array) $value);
}

protected function pushClause(WhereClause $where, LogicalConnector $logicalConnector = LogicalConnector::AND): void
{
if (count($this->clauses) > 0) {
$where->setConnector($logicalConnector);
}

$this->clauses[] = $where;
}
//
}
161 changes: 161 additions & 0 deletions src/Database/ClauseBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
<?php

declare(strict_types=1);

namespace Phenix\Database;

use Closure;
use Phenix\Database\Clauses\BasicWhereClause;
use Phenix\Database\Clauses\RowWhereClause;
use Phenix\Database\Clauses\SubqueryWhereClause;
use Phenix\Database\Clauses\WhereClause;
use Phenix\Database\Concerns\Query\HasWhereClause;
use Phenix\Database\Constants\LogicalConnector;
use Phenix\Database\Constants\Operator;

use function count;

abstract class ClauseBuilder extends Grammar
{
use HasWhereClause;

/**
* @var array<int, WhereClause>
*/
protected array $clauses;

/**
* @var array<int, mixed>
*/
protected array $arguments;

/**
* @return array<int, WhereClause>
*/
protected function getClauses(): array
{
return $this->clauses;
}

/**
* @return array<int, mixed>
*/
protected function getArguments(): array
{
return $this->arguments;
}

protected function hasWhereClauses(): bool
{
return count($this->getClauses()) > 0;
}

protected function addArguments(array $arguments): void
{
$this->arguments = [...$this->arguments, ...$arguments];
}

protected function pushWhereClause(
WhereClause $where,
LogicalConnector $logicalConnector = LogicalConnector::AND
): void {
if ($this->hasWhereClauses()) {
$where->setConnector($logicalConnector);
}

$this->clauses[] = $where;
}

protected function resolveWhereMethod(
string $column,
Operator $operator,
Closure|array|string|int $value,
LogicalConnector $logicalConnector = LogicalConnector::AND
): void {
if ($value instanceof Closure) {
$this->whereSubquery(
subquery: $value,
comparisonOperator: $operator,
column: $column,
logicalConnector: $logicalConnector
);
} else {
$this->pushWhereWithArgs($column, $operator, $value, $logicalConnector);
}
}

protected function whereSubquery(
Closure $subquery,
Operator $comparisonOperator,
string|null $column = null,
Operator|null $operator = null,
LogicalConnector $logicalConnector = LogicalConnector::AND
): void {
$builder = new Subquery($this->driver);
$builder->setDriver($this->driver);
$builder->selectAllColumns();

$subquery($builder);

[$dml, $arguments] = $builder->toSql();

$connector = $this->hasWhereClauses() ? $logicalConnector : null;

$this->pushWhereClause(new SubqueryWhereClause(
comparisonOperator: $comparisonOperator,
sql: trim($dml, '()'),
params: $arguments,
column: $column,
operator: $operator,
connector: $connector
), $logicalConnector);

$this->addArguments($arguments);
}

/**
* @param array<int, string> $columns
*/
protected function whereRowSubquery(
Closure $subquery,
Operator $comparisonOperator,
array $columns,
LogicalConnector $logicalConnector = LogicalConnector::AND
): void {
$builder = new Subquery($this->driver);
$builder->setDriver($this->driver);
$builder->selectAllColumns();

$subquery($builder);

[$dml, $arguments] = $builder->toSql();

$connector = $this->hasWhereClauses() ? $logicalConnector : null;

$this->pushWhereClause(new RowWhereClause(
columns: $columns,
comparisonOperator: $comparisonOperator,
sql: trim($dml, '()'),
params: $arguments,
connector: $connector
), $logicalConnector);

$this->addArguments($arguments);
}

protected function pushWhereWithArgs(
string $column,
Operator $operator,
array|string|int $value,
LogicalConnector $logicalConnector = LogicalConnector::AND
): void {
$this->pushClause(new BasicWhereClause($column, $operator, $value, null, true), $logicalConnector);

$this->addArguments((array) $value);
}

protected function pushClause(WhereClause $where, LogicalConnector $logicalConnector = LogicalConnector::AND): void
{
$this->pushWhereClause($where, $logicalConnector);
}
}
5 changes: 5 additions & 0 deletions src/Database/Clauses/BasicWhereClause.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,9 @@ public function isInOperator(): bool
{
return $this->operator === Operator::IN || $this->operator === Operator::NOT_IN;
}

public function usesPlaceholder(): bool
{
return $this->usePlaceholder;
}
}
60 changes: 60 additions & 0 deletions src/Database/Clauses/DateWhereClause.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

namespace Phenix\Database\Clauses;

use Phenix\Database\Constants\DatabaseFunction;
use Phenix\Database\Constants\LogicalConnector;
use Phenix\Database\Constants\Operator;
use Phenix\Database\Constants\SQL;

class DateWhereClause extends WhereClause
{
protected string $column;

protected Operator $operator;

protected DatabaseFunction $function;

protected string|int $value;

public function __construct(
string $column,
Operator $operator,
DatabaseFunction $function,
string|int $value,
LogicalConnector|null $connector = null
) {
$this->column = $column;
$this->operator = $operator;
$this->function = $function;
$this->value = $value;
$this->connector = $connector;
}

public function getColumn(): string
{
return $this->column;
}

public function getOperator(): Operator
{
return $this->operator;
}

public function getFunction(): DatabaseFunction
{
return $this->function;
}

public function getValue(): string|int
{
return $this->value;
}

public function renderValue(): string
{
return SQL::PLACEHOLDER->value;
}
}
Loading
Loading