Namespace and ClassPath rewrites
This commit is contained in:
133
Core/Driver/SQL/Query/AlterTable.class.php
Normal file
133
Core/Driver/SQL/Query/AlterTable.class.php
Normal file
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
namespace Core\Driver\SQL\Query;
|
||||
|
||||
use Core\Driver\SQL\Column\Column;
|
||||
use Core\Driver\SQL\Column\EnumColumn;
|
||||
use Core\Driver\SQL\Constraint\Constraint;
|
||||
use Core\Driver\SQL\Constraint\ForeignKey;
|
||||
use Core\Driver\SQL\Constraint\PrimaryKey;
|
||||
use Core\Driver\SQL\PostgreSQL;
|
||||
use Core\Driver\SQL\SQL;
|
||||
|
||||
class AlterTable extends Query {
|
||||
|
||||
private string $table;
|
||||
private string $action;
|
||||
private $data;
|
||||
|
||||
private ?Column $column;
|
||||
private ?Constraint $constraint;
|
||||
|
||||
public function __construct(SQL $sql, string $table) {
|
||||
parent::__construct($sql);
|
||||
$this->table = $table;
|
||||
$this->column = null;
|
||||
$this->constraint = null;
|
||||
}
|
||||
|
||||
public function add($what): AlterTable {
|
||||
if ($what instanceof Column) {
|
||||
$this->column = $what;
|
||||
} else if ($what instanceof Constraint) {
|
||||
$this->constraint = $what;
|
||||
} else {
|
||||
$this->column = new Column($what);
|
||||
}
|
||||
|
||||
$this->action = "ADD";
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function modify(Column $column): AlterTable {
|
||||
$this->column = $column;
|
||||
$this->action = "MODIFY";
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function drop($what): AlterTable {
|
||||
if ($what instanceof Column) {
|
||||
$this->column = $what;
|
||||
} else if ($what instanceof Constraint) {
|
||||
$this->constraint = $what;
|
||||
} else {
|
||||
$this->column = new Column($what);
|
||||
}
|
||||
$this->action = "DROP";
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function resetAutoIncrement(): AlterTable {
|
||||
$this->action = "RESET_AUTO_INCREMENT";
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addToEnum(EnumColumn $column, string $newValue): AlterTable {
|
||||
$this->action = "MODIFY";
|
||||
$this->column = $column;
|
||||
$this->data = $newValue;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAction(): string { return $this->action; }
|
||||
public function getColumn(): ?Column { return $this->column; }
|
||||
public function getConstraint(): ?Constraint { return $this->constraint; }
|
||||
public function getTable(): string { return $this->table; }
|
||||
|
||||
public function build(array &$params): ?string {
|
||||
$tableName = $this->sql->tableName($this->getTable());
|
||||
$action = $this->getAction();
|
||||
$column = $this->getColumn();
|
||||
$constraint = $this->getConstraint();
|
||||
|
||||
if ($action === "RESET_AUTO_INCREMENT") {
|
||||
return "ALTER TABLE $tableName AUTO_INCREMENT=1";
|
||||
}
|
||||
|
||||
$query = "ALTER TABLE $tableName $action ";
|
||||
|
||||
if ($column) {
|
||||
$query .= "COLUMN ";
|
||||
if ($action === "DROP") {
|
||||
$query .= $this->sql->columnName($column->getName());
|
||||
} else {
|
||||
// ADD or modify
|
||||
if ($column instanceof EnumColumn) {
|
||||
if ($this->sql instanceof PostgreSQL) {
|
||||
$typeName = $this->sql->getColumnType($column);
|
||||
$value = $this->sql->addValue($this->data, $params);
|
||||
return "ALTER TYPE $typeName ADD VALUE $value";
|
||||
}
|
||||
$column->addValue($this->data);
|
||||
}
|
||||
|
||||
$query .= $this->sql->getColumnDefinition($column);
|
||||
}
|
||||
} else if ($constraint) {
|
||||
if ($action === "DROP") {
|
||||
if ($constraint instanceof PrimaryKey) {
|
||||
$query .= "PRIMARY KEY";
|
||||
} else {
|
||||
$constraintName = $constraint->getName();
|
||||
if ($constraintName) {
|
||||
$query .= "CONSTRAINT " . $this->sql->columnName($constraintName);
|
||||
} else {
|
||||
$this->sql->setLastError("Cannot DROP CONSTRAINT without a constraint name.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} else if ($action === "ADD") {
|
||||
$query .= "CONSTRAINT ";
|
||||
$query .= $this->sql->getConstraintDefinition($constraint);
|
||||
} else if ($action === "MODIFY") {
|
||||
$this->sql->setLastError("MODIFY CONSTRAINT foreign key is not supported.");
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
$this->sql->setLastError("'ALTER TABLE' requires at least a column or a constraint.");
|
||||
return null;
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
}
|
||||
15
Core/Driver/SQL/Query/Commit.class.php
Normal file
15
Core/Driver/SQL/Query/Commit.class.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Core\Driver\SQL\Query;
|
||||
|
||||
use Core\Driver\SQL\SQL;
|
||||
|
||||
class Commit extends Query {
|
||||
public function __construct(SQL $sql) {
|
||||
parent::__construct($sql);
|
||||
}
|
||||
|
||||
public function build(array &$params): ?string {
|
||||
return "COMMIT";
|
||||
}
|
||||
}
|
||||
50
Core/Driver/SQL/Query/CreateProcedure.class.php
Normal file
50
Core/Driver/SQL/Query/CreateProcedure.class.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Core\Driver\SQL\Query;
|
||||
|
||||
use Core\Driver\SQL\Column\Column;
|
||||
use Core\Driver\SQL\SQL;
|
||||
|
||||
class CreateProcedure extends Query {
|
||||
|
||||
private string $name;
|
||||
private array $parameters;
|
||||
private array $statements;
|
||||
private $returns;
|
||||
|
||||
public function __construct(SQL $sql, string $procName) {
|
||||
parent::__construct($sql);
|
||||
$this->name = $procName;
|
||||
$this->parameters = [];
|
||||
$this->statements = [];
|
||||
$this->returns = NULL;
|
||||
}
|
||||
|
||||
public function param(Column $parameter): CreateProcedure {
|
||||
$this->parameters[] = $parameter;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function returns($column): CreateProcedure {
|
||||
$this->returns = $column;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function exec(array $statements): CreateProcedure {
|
||||
$this->statements = $statements;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function build(array &$params): ?string {
|
||||
$head = $this->sql->getProcedureHead($this);
|
||||
$body = $this->sql->getProcedureBody($this);
|
||||
$tail = $this->sql->getProcedureTail();
|
||||
return "$head BEGIN $body END; $tail";
|
||||
}
|
||||
|
||||
public function getName(): string { return $this->name; }
|
||||
public function getParameters(): array { return $this->parameters; }
|
||||
public function getReturns() { return $this->returns; }
|
||||
public function getStatements(): array { return $this->statements; }
|
||||
}
|
||||
156
Core/Driver/SQL/Query/CreateTable.class.php
Normal file
156
Core/Driver/SQL/Query/CreateTable.class.php
Normal file
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
namespace Core\Driver\SQL\Query;
|
||||
|
||||
use Core\Driver\SQL\Column\BigIntColumn;
|
||||
use Core\Driver\SQL\Column\Column;
|
||||
use Core\Driver\SQL\Column\DoubleColumn;
|
||||
use Core\Driver\SQL\Column\FloatColumn;
|
||||
use Core\Driver\SQL\Column\NumericColumn;
|
||||
use Core\Driver\SQL\Column\SerialColumn;
|
||||
use Core\Driver\SQL\Column\StringColumn;
|
||||
use Core\Driver\SQL\Column\IntColumn;
|
||||
use Core\Driver\SQL\Column\DateTimeColumn;
|
||||
use Core\Driver\SQL\Column\EnumColumn;
|
||||
use Core\Driver\SQL\Column\BoolColumn;
|
||||
use Core\Driver\SQL\Column\JsonColumn;
|
||||
|
||||
use Core\Driver\SQL\Constraint\Constraint;
|
||||
use Core\Driver\SQL\Constraint\PrimaryKey;
|
||||
use Core\Driver\SQL\Constraint\Unique;
|
||||
use Core\Driver\SQL\Constraint\ForeignKey;
|
||||
use Core\Driver\SQL\SQL;
|
||||
use Core\Driver\SQL\Strategy\Strategy;
|
||||
|
||||
class CreateTable extends Query {
|
||||
|
||||
private string $tableName;
|
||||
private array $columns;
|
||||
private array $constraints;
|
||||
private bool $ifNotExists;
|
||||
|
||||
public function __construct(SQL $sql, string $name) {
|
||||
parent::__construct($sql);
|
||||
$this->tableName = $name;
|
||||
$this->columns = array();
|
||||
$this->constraints = array();
|
||||
$this->ifNotExists = false;
|
||||
}
|
||||
|
||||
public function addColumn(Column $column): CreateTable {
|
||||
$this->columns[$column->getName()] = $column;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addConstraint(Constraint $constraint): CreateTable {
|
||||
$this->constraints[] = $constraint;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addSerial(string $name): CreateTable {
|
||||
$this->columns[$name] = new SerialColumn($name);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addString(string $name, ?int $maxSize = NULL, bool $nullable = false, $defaultValue = NULL): CreateTable {
|
||||
$this->columns[$name] = new StringColumn($name, $maxSize, $nullable, $defaultValue);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addDateTime(string $name, bool $nullable = false, $defaultValue = NULL): CreateTable {
|
||||
$this->columns[$name] = new DateTimeColumn($name, $nullable, $defaultValue);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addInt(string $name, bool $nullable = false, $defaultValue = NULL, bool $unsigned = false): CreateTable {
|
||||
$this->columns[$name] = new IntColumn($name, $nullable, $defaultValue, $unsigned);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addBigInt(string $name, bool $nullable = false, $defaultValue = NULL, bool $unsigned = false): CreateTable {
|
||||
$this->columns[$name] = new BigIntColumn($name, $nullable, $defaultValue, $unsigned);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addBool(string $name, $defaultValue = false): CreateTable {
|
||||
$this->columns[$name] = new BoolColumn($name, $defaultValue);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addJson(string $name, bool $nullable = false, $defaultValue = NULL): CreateTable {
|
||||
$this->columns[$name] = new JsonColumn($name, $nullable, $defaultValue);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addEnum(string $name, array $values, bool $nullable = false, $defaultValue = NULL): CreateTable {
|
||||
$this->columns[$name] = new EnumColumn($name, $values, $nullable, $defaultValue);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addNumeric(string $name, bool $nullable = false, $defaultValue = NULL, ?int $digitsTotal = 10, ?int $digitsDecimal = 0): CreateTable {
|
||||
$this->columns[$name] = new NumericColumn($name, $nullable, $defaultValue, $digitsTotal, $digitsDecimal);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addFloat(string $name, bool $nullable = false, $defaultValue = NULL, ?int $digitsTotal = null, ?int $digitsDecimal = null): CreateTable {
|
||||
$this->columns[$name] = new FloatColumn($name, $nullable, $defaultValue, $digitsTotal, $digitsDecimal);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addDouble(string $name, bool $nullable = false, $defaultValue = NULL, ?int $digitsTotal = null, ?int $digitsDecimal = null): CreateTable {
|
||||
$this->columns[$name] = new DoubleColumn($name, $nullable, $defaultValue, $digitsTotal, $digitsDecimal);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function primaryKey(...$names): CreateTable {
|
||||
$pk = new PrimaryKey($names);
|
||||
$pk->setName(strtolower("pk_{$this->tableName}"));
|
||||
$this->constraints[] = $pk;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function unique(...$names): CreateTable {
|
||||
$this->constraints[] = new Unique($names);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function foreignKey(string $column, string $refTable, string $refColumn, ?Strategy $strategy = NULL): CreateTable {
|
||||
$fk = new ForeignKey($column, $refTable, $refColumn, $strategy);
|
||||
$fk->setName(strtolower("fk_{$this->tableName}_${refTable}_${refColumn}"));
|
||||
$this->constraints[] = $fk;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function onlyIfNotExists(): CreateTable {
|
||||
$this->ifNotExists = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function ifNotExists(): bool { return $this->ifNotExists; }
|
||||
public function getTableName(): string { return $this->tableName; }
|
||||
public function getColumns(): array { return $this->columns; }
|
||||
public function getConstraints(): array { return $this->constraints; }
|
||||
|
||||
public function build(array &$params): ?string {
|
||||
$tableName = $this->sql->tableName($this->getTableName());
|
||||
$ifNotExists = $this->ifNotExists() ? " IF NOT EXISTS" : "";
|
||||
|
||||
$entries = array();
|
||||
foreach ($this->getColumns() as $column) {
|
||||
$entries[] = ($tmp = $this->sql->getColumnDefinition($column));
|
||||
if (is_null($tmp)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->getConstraints() as $constraint) {
|
||||
$entries[] = ($tmp = $this->sql->getConstraintDefinition($constraint));
|
||||
if (is_null($tmp)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$entries = implode(",", $entries);
|
||||
return "CREATE TABLE$ifNotExists $tableName ($entries)";
|
||||
}
|
||||
}
|
||||
83
Core/Driver/SQL/Query/CreateTrigger.class.php
Normal file
83
Core/Driver/SQL/Query/CreateTrigger.class.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace Core\Driver\SQL\Query;
|
||||
|
||||
use Core\API\User\Create;
|
||||
use Core\Driver\SQL\SQL;
|
||||
|
||||
class CreateTrigger extends Query {
|
||||
|
||||
private string $name;
|
||||
private string $time;
|
||||
private string $event;
|
||||
private string $tableName;
|
||||
private array $parameters;
|
||||
private ?CreateProcedure $procedure;
|
||||
|
||||
public function __construct(SQL $sql, string $triggerName) {
|
||||
parent::__construct($sql);
|
||||
$this->name = $triggerName;
|
||||
$this->time = "AFTER";
|
||||
$this->tableName = "";
|
||||
$this->event = "";
|
||||
$this->parameters = [];
|
||||
$this->procedure = null;
|
||||
}
|
||||
|
||||
public function before(): CreateTrigger {
|
||||
$this->time = "BEFORE";
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function after(): CreateTrigger {
|
||||
$this->time = "AFTER";
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function update(string $table): CreateTrigger {
|
||||
$this->tableName = $table;
|
||||
$this->event = "UPDATE";
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function insert(string $table): CreateTrigger {
|
||||
$this->tableName = $table;
|
||||
$this->event = "INSERT";
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function delete(string $table): CreateTrigger {
|
||||
$this->tableName = $table;
|
||||
$this->event = "DELETE";
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function exec(CreateProcedure $procedure, array $parameters = []): CreateTrigger {
|
||||
$this->procedure = $procedure;
|
||||
$this->parameters = $parameters;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getName(): string { return $this->name; }
|
||||
public function getTime(): string { return $this->time; }
|
||||
public function getEvent(): string { return $this->event; }
|
||||
public function getTable(): string { return $this->tableName; }
|
||||
public function getProcedure(): CreateProcedure { return $this->procedure; }
|
||||
|
||||
public function build(array &$params): ?string {
|
||||
$name = $this->sql->tableName($this->getName());
|
||||
$time = $this->getTime();
|
||||
$event = $this->getEvent();
|
||||
$tableName = $this->sql->tableName($this->getTable());
|
||||
|
||||
$params = array();
|
||||
$query = "CREATE TRIGGER $name $time $event ON $tableName FOR EACH ROW ";
|
||||
$triggerBody = $this->sql->createTriggerBody($this, $this->parameters);
|
||||
if ($triggerBody === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$query .= $triggerBody;
|
||||
return $query;
|
||||
}
|
||||
}
|
||||
32
Core/Driver/SQL/Query/Delete.class.php
Normal file
32
Core/Driver/SQL/Query/Delete.class.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Core\Driver\SQL\Query;
|
||||
|
||||
use Core\Driver\SQL\Condition\CondOr;
|
||||
use Core\Driver\SQL\SQL;
|
||||
|
||||
class Delete extends Query {
|
||||
|
||||
private string $table;
|
||||
private array $conditions;
|
||||
|
||||
public function __construct(SQL $sql, string $table) {
|
||||
parent::__construct($sql);
|
||||
$this->table = $table;
|
||||
$this->conditions = array();
|
||||
}
|
||||
|
||||
public function where(...$conditions): Delete {
|
||||
$this->conditions[] = (count($conditions) === 1 ? $conditions : new CondOr($conditions));
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTable(): string { return $this->table; }
|
||||
public function getConditions(): array { return $this->conditions; }
|
||||
|
||||
public function build(array &$params): ?string {
|
||||
$table = $this->sql->tableName($this->getTable());
|
||||
$where = $this->sql->getWhereClause($this->getConditions(), $params);
|
||||
return "DELETE FROM $table$where";
|
||||
}
|
||||
}
|
||||
29
Core/Driver/SQL/Query/Drop.php
Normal file
29
Core/Driver/SQL/Query/Drop.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Core\Driver\SQL\Query;
|
||||
|
||||
use Core\Driver\SQL\SQL;
|
||||
|
||||
class Drop extends Query {
|
||||
|
||||
private string $table;
|
||||
|
||||
/**
|
||||
* Drop constructor.
|
||||
* @param SQL $sql
|
||||
* @param string $table
|
||||
*/
|
||||
public function __construct(SQL $sql, string $table) {
|
||||
parent::__construct($sql);
|
||||
$this->table = $table;
|
||||
}
|
||||
|
||||
public function getTable(): string {
|
||||
return $this->table;
|
||||
}
|
||||
|
||||
public function build(array &$params): ?string {
|
||||
return "DROP TABLE " . $this->sql->tableName($this->getTable());
|
||||
}
|
||||
}
|
||||
83
Core/Driver/SQL/Query/Insert.class.php
Normal file
83
Core/Driver/SQL/Query/Insert.class.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace Core\Driver\SQL\Query;
|
||||
|
||||
use Core\Driver\SQL\SQL;
|
||||
use Core\Driver\SQL\Strategy\Strategy;
|
||||
|
||||
class Insert extends Query {
|
||||
|
||||
private string $tableName;
|
||||
private array $columns;
|
||||
private array $rows;
|
||||
private ?Strategy $onDuplicateKey;
|
||||
private ?string $returning;
|
||||
|
||||
public function __construct(SQL $sql, string $name, array $columns = array()) {
|
||||
parent::__construct($sql);
|
||||
$this->tableName = $name;
|
||||
$this->columns = $columns;
|
||||
$this->rows = array();
|
||||
$this->onDuplicateKey = NULL;
|
||||
$this->returning = NULL;
|
||||
}
|
||||
|
||||
public function addRow(...$values): Insert {
|
||||
$this->rows[] = $values;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function onDuplicateKeyStrategy(Strategy $strategy): Insert {
|
||||
$this->onDuplicateKey = $strategy;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function returning(string $column): Insert {
|
||||
$this->returning = $column;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTableName(): string { return $this->tableName; }
|
||||
public function getColumns(): array { return $this->columns; }
|
||||
public function getRows(): array { return $this->rows; }
|
||||
public function onDuplicateKey(): ?Strategy { return $this->onDuplicateKey; }
|
||||
public function getReturning(): ?string { return $this->returning; }
|
||||
|
||||
public function build(array &$params): ?string {
|
||||
$tableName = $this->sql->tableName($this->getTableName());
|
||||
$columns = $this->getColumns();
|
||||
$rows = $this->getRows();
|
||||
|
||||
if (empty($rows)) {
|
||||
$this->sql->setLastError("No rows to insert given.");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (is_null($columns) || empty($columns)) {
|
||||
$columnStr = "";
|
||||
} else {
|
||||
$columnStr = " (" . $this->sql->columnName($columns) . ")";
|
||||
}
|
||||
|
||||
$values = array();
|
||||
foreach ($rows as $row) {
|
||||
$rowPlaceHolder = array();
|
||||
foreach ($row as $val) {
|
||||
$rowPlaceHolder[] = $this->sql->addValue($val, $params);
|
||||
}
|
||||
|
||||
$values[] = "(" . implode(",", $rowPlaceHolder) . ")";
|
||||
}
|
||||
|
||||
$values = implode(",", $values);
|
||||
|
||||
$onDuplicateKey = $this->sql->getOnDuplicateStrategy($this->onDuplicateKey(), $params);
|
||||
if ($onDuplicateKey === FALSE) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$returningCol = $this->getReturning();
|
||||
$returning = $this->sql->getReturning($returningCol);
|
||||
return "INSERT INTO $tableName$columnStr VALUES $values$onDuplicateKey$returning";
|
||||
}
|
||||
}
|
||||
29
Core/Driver/SQL/Query/Query.class.php
Normal file
29
Core/Driver/SQL/Query/Query.class.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Core\Driver\SQL\Query;
|
||||
|
||||
use Core\Driver\SQL\Expression\Expression;
|
||||
use Core\Driver\SQL\SQL;
|
||||
|
||||
abstract class Query extends Expression {
|
||||
|
||||
protected SQL $sql;
|
||||
public bool $dump;
|
||||
|
||||
public function __construct(SQL $sql) {
|
||||
$this->sql = $sql;
|
||||
$this->dump = false;
|
||||
}
|
||||
|
||||
public function dump(): Query {
|
||||
$this->dump = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
// can actually return bool|array (depending on success and query type)
|
||||
public function execute() {
|
||||
return $this->sql->executeQuery($this);
|
||||
}
|
||||
|
||||
public abstract function build(array &$params): ?string;
|
||||
}
|
||||
15
Core/Driver/SQL/Query/RollBack.class.php
Normal file
15
Core/Driver/SQL/Query/RollBack.class.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Core\Driver\SQL\Query;
|
||||
|
||||
use Core\Driver\SQL\SQL;
|
||||
|
||||
class RollBack extends Query {
|
||||
public function __construct(SQL $sql) {
|
||||
parent::__construct($sql);
|
||||
}
|
||||
|
||||
public function build(array &$params): ?string {
|
||||
return "ROLLBACK";
|
||||
}
|
||||
}
|
||||
214
Core/Driver/SQL/Query/Select.class.php
Normal file
214
Core/Driver/SQL/Query/Select.class.php
Normal file
@@ -0,0 +1,214 @@
|
||||
<?php
|
||||
|
||||
namespace Core\Driver\SQL\Query;
|
||||
|
||||
use Core\Driver\SQL\Condition\CondOr;
|
||||
use Core\Driver\SQL\Expression\JsonArrayAgg;
|
||||
use Core\Driver\SQL\Join;
|
||||
use Core\Driver\SQL\SQL;
|
||||
|
||||
class Select extends Query {
|
||||
|
||||
private array $selectValues;
|
||||
private array $tables;
|
||||
private array $conditions;
|
||||
private array $joins;
|
||||
private array $orderColumns;
|
||||
private array $groupColumns;
|
||||
private array $havings;
|
||||
private bool $sortAscending;
|
||||
private int $limit;
|
||||
private int $offset;
|
||||
private bool $forUpdate;
|
||||
private int $fetchType;
|
||||
|
||||
public function __construct($sql, ...$selectValues) {
|
||||
parent::__construct($sql);
|
||||
$this->selectValues = (!empty($selectValues) && is_array($selectValues[0])) ? $selectValues[0] : $selectValues;
|
||||
$this->tables = array();
|
||||
$this->conditions = array();
|
||||
$this->havings = array();
|
||||
$this->joins = array();
|
||||
$this->orderColumns = array();
|
||||
$this->groupColumns = array();
|
||||
$this->limit = 0;
|
||||
$this->offset = 0;
|
||||
$this->sortAscending = true;
|
||||
$this->forUpdate = false;
|
||||
$this->fetchType = SQL::FETCH_ALL;
|
||||
}
|
||||
|
||||
public function from(...$tables): Select {
|
||||
$this->tables = array_merge($this->tables, $tables);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addValue($value): Select {
|
||||
$this->selectValues[] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function where(...$conditions): Select {
|
||||
$this->conditions[] = (count($conditions) === 1 ? $conditions : new CondOr($conditions));
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function having(...$conditions): Select {
|
||||
$this->havings[] = (count($conditions) === 1 ? $conditions : new CondOr($conditions));
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function innerJoin(string $table, string $columnA, string $columnB, ?string $tableAlias = null, array $conditions = []): Select {
|
||||
$this->joins[] = new Join("INNER", $table, $columnA, $columnB, $tableAlias, $conditions);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function leftJoin(string $table, string $columnA, string $columnB, ?string $tableAlias = null, array $conditions = []): Select {
|
||||
$this->joins[] = new Join("LEFT", $table, $columnA, $columnB, $tableAlias, $conditions);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addJoin(Join $join): Select {
|
||||
$this->joins[] = $join;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function groupBy(...$columns): Select {
|
||||
$this->groupColumns = $columns;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function orderBy(...$columns): Select {
|
||||
$this->orderColumns = $columns;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function ascending(): Select {
|
||||
$this->sortAscending = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function descending(): Select {
|
||||
$this->sortAscending = false;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function limit(int $limit): Select {
|
||||
$this->limit = $limit;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function offset(int $offset): Select {
|
||||
$this->offset = $offset;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function lockForUpdate(): Select {
|
||||
$this->forUpdate = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function iterator(): Select {
|
||||
$this->fetchType = SQL::FETCH_ITERATIVE;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function first(): Select {
|
||||
$this->fetchType = SQL::FETCH_ONE;
|
||||
$this->limit = 1;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function execute() {
|
||||
return $this->sql->executeQuery($this, $this->fetchType);
|
||||
}
|
||||
|
||||
public function getSelectValues(): array { return $this->selectValues; }
|
||||
public function getTables(): array { return $this->tables; }
|
||||
public function getConditions(): array { return $this->conditions; }
|
||||
public function getJoins(): array { return $this->joins; }
|
||||
public function isOrderedAscending(): bool { return $this->sortAscending; }
|
||||
public function getOrderBy(): array { return $this->orderColumns; }
|
||||
public function getLimit(): int { return $this->limit; }
|
||||
public function getOffset(): int { return $this->offset; }
|
||||
public function getGroupBy(): array { return $this->groupColumns; }
|
||||
public function getHavings(): array { return $this->havings; }
|
||||
|
||||
public function build(array &$params): ?string {
|
||||
|
||||
$selectValues = [];
|
||||
foreach ($this->selectValues as $value) {
|
||||
if (is_string($value)) {
|
||||
$selectValues[] = $this->sql->columnName($value);
|
||||
} else if ($value instanceof Select) {
|
||||
$subSelect = $value->build($params);
|
||||
if (count($value->getSelectValues()) !== 1) {
|
||||
$selectValues[] = "($subSelect)";
|
||||
} else {
|
||||
$columnAlias = null;
|
||||
$subSelectColumn = $value->getSelectValues()[0];
|
||||
if (is_string($subSelectColumn) && ($index = stripos($subSelectColumn, " as ")) !== FALSE) {
|
||||
$columnAlias = substr($subSelectColumn, $index + 4);
|
||||
} else if ($subSelectColumn instanceof JsonArrayAgg) {
|
||||
$columnAlias = $subSelectColumn->getAlias();
|
||||
}
|
||||
|
||||
if ($columnAlias) {
|
||||
$selectValues[] = "($subSelect) as $columnAlias";
|
||||
} else {
|
||||
$selectValues[] = "($subSelect)";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$selectValues[] = $this->sql->addValue($value, $params);
|
||||
}
|
||||
}
|
||||
|
||||
$tables = $this->getTables();
|
||||
$selectValues = implode(",", $selectValues);
|
||||
|
||||
if (!$tables) {
|
||||
return "SELECT $selectValues";
|
||||
}
|
||||
|
||||
$tables = $this->sql->tableName($tables);
|
||||
$where = $this->sql->getWhereClause($this->getConditions(), $params);
|
||||
$havingClause = "";
|
||||
if (count($this->havings) > 0) {
|
||||
$havingClause = " HAVING " . $this->sql->buildCondition($this->getHavings(), $params);
|
||||
}
|
||||
|
||||
$joinStr = "";
|
||||
$joins = $this->getJoins();
|
||||
if (!empty($joins)) {
|
||||
foreach ($joins as $join) {
|
||||
$type = $join->getType();
|
||||
$joinTable = $this->sql->tableName($join->getTable());
|
||||
$tableAlias = ($join->getTableAlias() ? " " . $join->getTableAlias() : "");
|
||||
$condition = $this->sql->buildCondition($join->getConditions(), $params);
|
||||
$joinStr .= " $type JOIN $joinTable$tableAlias ON ($condition)";
|
||||
}
|
||||
}
|
||||
|
||||
$groupBy = "";
|
||||
$groupColumns = $this->getGroupBy();
|
||||
if (!empty($groupColumns)) {
|
||||
$groupBy = " GROUP BY " . $this->sql->columnName($groupColumns);
|
||||
}
|
||||
|
||||
$orderBy = "";
|
||||
$orderColumns = $this->getOrderBy();
|
||||
if (!empty($orderColumns)) {
|
||||
$orderBy = " ORDER BY " . $this->sql->columnName($orderColumns);
|
||||
$orderBy .= ($this->isOrderedAscending() ? " ASC" : " DESC");
|
||||
}
|
||||
|
||||
$limit = ($this->getLimit() > 0 ? (" LIMIT " . $this->getLimit()) : "");
|
||||
$offset = ($this->getOffset() > 0 ? (" OFFSET " . $this->getOffset()) : "");
|
||||
$forUpdate = ($this->forUpdate ? " FOR UPDATE" : "");
|
||||
return "SELECT $selectValues FROM $tables$joinStr$where$groupBy$havingClause$orderBy$limit$offset$forUpdate";
|
||||
}
|
||||
}
|
||||
15
Core/Driver/SQL/Query/StartTransaction.class.php
Normal file
15
Core/Driver/SQL/Query/StartTransaction.class.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Core\Driver\SQL\Query;
|
||||
|
||||
use Core\Driver\SQL\SQL;
|
||||
|
||||
class StartTransaction extends Query {
|
||||
public function __construct(SQL $sql) {
|
||||
parent::__construct($sql);
|
||||
}
|
||||
|
||||
public function build(array &$params): ?string {
|
||||
return "START TRANSACTION";
|
||||
}
|
||||
}
|
||||
21
Core/Driver/SQL/Query/Truncate.class.php
Normal file
21
Core/Driver/SQL/Query/Truncate.class.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Core\Driver\SQL\Query;
|
||||
|
||||
use Core\Driver\SQL\SQL;
|
||||
|
||||
class Truncate extends Query {
|
||||
|
||||
private string $tableName;
|
||||
|
||||
public function __construct(SQL $sql, string $name) {
|
||||
parent::__construct($sql);
|
||||
$this->tableName = $name;
|
||||
}
|
||||
|
||||
public function getTable(): string { return $this->tableName; }
|
||||
|
||||
public function build(array &$params): ?string {
|
||||
return "TRUNCATE " . $this->sql->tableName($this->getTable());
|
||||
}
|
||||
}
|
||||
47
Core/Driver/SQL/Query/Update.class.php
Normal file
47
Core/Driver/SQL/Query/Update.class.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Core\Driver\SQL\Query;
|
||||
|
||||
use Core\Driver\SQL\Condition\CondOr;
|
||||
use Core\Driver\SQL\SQL;
|
||||
|
||||
class Update extends Query {
|
||||
|
||||
private array $values;
|
||||
private string $table;
|
||||
private array $conditions;
|
||||
|
||||
public function __construct(SQL $sql, string $table) {
|
||||
parent::__construct($sql);
|
||||
$this->values = array();
|
||||
$this->table = $table;
|
||||
$this->conditions = array();
|
||||
}
|
||||
|
||||
public function where(...$conditions): Update {
|
||||
$this->conditions[] = (count($conditions) === 1 ? $conditions : new CondOr($conditions));
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function set(string $key, $val): Update {
|
||||
$this->values[$key] = $val;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTable(): string { return $this->table; }
|
||||
public function getConditions(): array { return $this->conditions; }
|
||||
public function getValues(): array { return $this->values; }
|
||||
|
||||
public function build(array &$params): ?string {
|
||||
$table = $this->sql->tableName($this->getTable());
|
||||
|
||||
$valueStr = array();
|
||||
foreach($this->getValues() as $key => $val) {
|
||||
$valueStr[] = $this->sql->columnName($key) . "=" . $this->sql->addValue($val, $params);
|
||||
}
|
||||
$valueStr = implode(",", $valueStr);
|
||||
|
||||
$where = $this->sql->getWhereClause($this->getConditions(), $params);
|
||||
return "UPDATE $table SET $valueStr$where";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user