Reorder and new queries, also change to Query/Builder

This commit is contained in:
2023-02-28 23:47:02 -03:00
parent 849d42ea57
commit d266008224
33 changed files with 839 additions and 612 deletions

View File

@ -0,0 +1,62 @@
<?php
namespace ProVM\Implement\Database\Query;
use ProVM\Implement\Database\Query;
use ProVM\Concept\Database;
abstract class Create extends Query implements Database\Query\Create
{
use hasTable;
public function __construct(string $table)
{
$this->table($table);
}
public function table(string $table): Database\Query\Create
{
return $this->setTable($table);
}
public function columns(array|string $columns): Database\Query\Create
{
return $this->setColumns($columns);
}
protected array|string $columns;
public function getColumns(): array
{
return $this->columns;
}
public function addColumn(string $column): Database\Query\Create
{
$this->columns []= $column;
return $this;
}
public function setColumns(array|string $columns): Database\Query\Create
{
if (is_string($columns)) {
$this->columns = $columns;
return $this;
}
foreach ($columns as $column) {
$this->addColumn($column);
}
return $this;
}
protected function getColumnsString(): string
{
if (is_string($this->columns)) {
return $this->columns;
}
return implode(', ', $this->getColumns());
}
public function build(): string
{
return "CREATE {$this->getTable()} ({$this->getColumnsString()})";
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace ProVM\Implement\Database\Query;
use ProVM\Concept\Database;
use ProVM\Implement\Database\Query;
abstract class Delete extends Query implements Database\Query\Delete
{
use hasTable, hasConditions;
public function from(string $table): Database\Query\Delete
{
return $this->setTable($table);
}
public function where(array|string $conditions): Database\Query\Delete
{
return $this->setConditions($conditions);
}
public function build(): string
{
return implode('', [
"DELETE FROM {$this->getTable()}",
$this->getConditionsString()
]);
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace ProVM\Implement\Database\Query;
use ProVM\Implement\Database\Query;
use ProVM\Concept\Database;
abstract class Drop extends Query implements Database\Query\Drop
{
use hasTable;
public function __construct(?string $table = null)
{
if ($table !== null) {
$this->table($table);
}
}
public function table(string $table): Database\Query\Drop
{
return $this->setTable($table);
}
public function build(): string
{
return "DROP TABLE {$this->getTable()}";
}
}

View File

@ -0,0 +1,94 @@
<?php
namespace ProVM\Implement\Database\Query;
use ProVM\Implement\Database\Query;
use ProVM\Concept\Database;
abstract class Insert extends Query implements Database\Query\Insert
{
use hasTable;
public function into(string $table): Database\Query\Insert
{
return $this->setTable($table);
}
public function columns(array|string $columns): Database\Query\Insert
{
return $this->setColumns($columns);
}
public function values(array|string $values): Database\Query\Insert
{
return $this->setValues($values);
}
public function select(Database\Query\Select|string $select): Database\Query\Insert
{
return $this->setSelect($select);
}
protected array|string $columns;
protected array|string $values;
protected Database\Query\Select|string $select;
public function getColumns(): array|string
{
return $this->columns;
}
public function getValues(): array|string
{
return $this->values;
}
public function getSelect(): Database\Query\Select|string
{
return $this->select;
}
public function setColumns(array|string $columns): Database\Query\Insert
{
$this->columns = $columns;
return $this;
}
public function setValues(array|string $values): Database\Query\Insert
{
$this->values = $values;
return $this;
}
public function setSelect(Database\Query\Select|string $select): Database\Query\Insert
{
$this->select = $select;
return $this;
}
protected function getColumnString(): string
{
if (!isset($this->columns)) {
return '';
}
$columns = (is_array($this->getColumns())) ? implode(', ', $this->getColumns()) : $this->getColumns();
if (trim($columns) === '') {
return '';
}
return " ({$columns})";
}
protected function getValueString(): string
{
if (!isset($this->values)) {
return '';
}
$values = (is_array($this->getValues())) ? implode(', ', $this->getValues()) : $this->getValues();
return " VALUES ({$values})";
}
protected function getSelectString(): string
{
return (isset($this->select)) ? " {$this->getSelect()}" : '';
}
public function build(): string
{
return implode('', [
"INSERT INTO {$this->getTable()}",
$this->getColumnString(),
$this->getValueString(),
$this->getSelectString()
]);
}
}

View File

@ -0,0 +1,260 @@
<?php
namespace ProVM\Implement\Database\Query;
use ProVM\Concept\Database;
use ProVM\Implement\Database\Query;
abstract class Select extends Query implements Database\Query\Select
{
use hasTable, hasConditions;
public function __construct(array|string $columns = '*')
{
$this->columns($columns);
}
public function columns(array|string $columns = '*'): Database\Query\Select
{
return $this->setColumns($columns);
}
public function from(string $table): Database\Query\Select
{
return $this->setTable($table);
}
public function joined(array|string $joins): Database\Query\Select
{
return $this->setJoins($joins);
}
public function where(array|string $conditions): Database\Query\Select
{
return $this->setConditions($conditions);
}
public function groupBy(array|string $grouping): Database\Query\Select
{
return $this->setGroups($grouping);
}
public function having(array|string $having): Database\Query\Select
{
return $this->setHaving($having);
}
public function orderBy(array|string $ordering): Database\Query\Select
{
return $this->setOrders($ordering);
}
protected array|string $columns;
protected array|string $joins;
protected array|string $groups;
protected array|string $having;
protected array|string $orders;
public function getColumns(): array|string
{
return $this->columns ?? '*';
}
public function getJoins(): array|string
{
return $this->joins;
}
public function getGroups(): array|string
{
return $this->groups;
}
public function getHaving(): array|string
{
return $this->having;
}
public function getOrders(): array|string
{
return $this->orders;
}
public function addColumn(string $column, ?string $alias = null): Database\Query\Select
{
if ($column === '*') {
$this->columns []= $column;
return $this;
}
$a = '';
if ($alias !== null) {
$a = " AS '{$alias}'";
}
$this->columns[] = "`{$column}`{$a}";
return $this;
}
public function addJoin(string $table, string $expression): Database\Query\Select
{
$this->joins []= "{$table} ON {$expression}";
return $this;
}
public function addGroup(string $group): Database\Query\Select
{
$this->groups []= "`{$group}`";
return $this;
}
public function addHaving(string $having): Database\Query\Select
{
$this->having []= $having;
return $this;
}
public function addOrder(string $column, ?string $direction = null): Database\Query\Select
{
if ($direction === null) {
$direction = 'ASC';
}
$this->orders []= "{$column} {$direction}";
return $this;
}
public function setColumns(array|string $columns): Database\Query\Select
{
if (is_string($columns)) {
$this->columns = $columns;
return $this;
}
foreach ($columns as $column) {
$col = $column;
$alias = null;
if (is_array($column)) {
$col = $column['column'] ?? $column[0];
$alias = $column['alias'] ?? $column[1];
}
$this->addColumn($column, $alias);
}
return $this;
}
public function setJoins(array|string $joins): Database\Query\Select
{
if (is_string($joins)) {
$this->joins = $joins;
return $this;
}
foreach ($joins as $join) {
$table = $join['table'] ?? $join[0];
$expression = $join['expression'] ?? $join[1];
$this->addJoin($table, $expression);
}
return $this;
}
public function setGroups(array|string $groups): Database\Query\Select
{
if (is_string($groups)) {
$this->groups = $groups;
return $this;
}
foreach ($groups as $group) {
$this->addGroup($group);
}
return $this;
}
public function setHaving(array|string $having): Database\Query\Select
{
if (is_string($having)) {
$this->having = $having;
return $this;
}
foreach ($having as $item) {
$this->addHaving($item);
}
return $this;
}
public function setOrders(array|string $orders): Database\Query\Select
{
if (is_string($orders)) {
$this->orders = $orders;
return $this;
}
foreach ($orders as $order) {
$column = $order;
$direction = null;
if (is_array($order)) {
$direction = $order['direction'] ?? $order[1];
$column = $order['column'] ?? $order[0];
}
$this->addOrder($column, $direction);
}
return $this;
}
protected function getColumnsString(): string
{
$columns = (is_array($this->getColumns())) ? implode(', ', $this->getColumns()) : $this->getColumns();
return " ({$columns})";
}
protected function getJoinsString(): string
{
if (!isset($this->joins)) {
return '';
}
if (is_string($this->getJoins())) {
$str = $this->getJoins();
return " {$str}";
}
$str = [];
foreach ($this->getJoins() as $i => $join) {
if (!str_contains(strtolower($join), 'join')) {
$str []= "JOIN {$join}";
continue;
}
$str []= $join;
}
$str = implode(' ', $str);
return " {$str}";
}
protected function getGroupsString(): string
{
if (!isset($this->groups)) {
return '';
}
$groups = (is_array($this->getGroups())) ? implode(', ', $this->getGroups()) : $this->getGroups();
return " GROUP BY {$groups}";
}
protected function getHavingString(): string
{
if (!isset($this->having)) {
return '';
}
$having = $this->getHaving();
if (is_array($having)) {
$first = array_shift($having);
$matched = preg_match_all('/^and|or\s/i', trim($first));
if ($matched > 0) {
$temp = str_replace(['and ', 'or '], ['', ''], strtolower($first));
$dif = strlen($first) - strlen($temp);
$first = substr($first, $dif);
}
$having = "$first " . implode(' ', array_map(function(string $h) {
$matched = preg_match_all('/^and|or\s/i', trim($h));
if ($matched > 0) {
return $h;
}
return "AND {$h}";
}, $having));
}
if (trim($having) === '') {
return '';
}
return " HAVING {$having}";
}
protected function getOrderString(): string
{
if (!isset($this->orders)) {
return '';
}
$ordering = (is_array($this->getOrders())) ? implode(', ', $this->getOrders()) : $this->getOrders();
return " ORDER BY {$ordering}";
}
public function build(): string
{
return implode('', [
"SELECT {$this->getColumnsString()}",
"FROM {$this->getTable()}",
$this->getJoinsString(),
$this->getConditionsString(),
$this->getGroupsString(),
$this->getHavingString(),
$this->getOrderString()
]);
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace ProVM\Implement\Database\Query;
use ProVM\Implement\Database\Query;
use ProVM\Concept\Database;
abstract class Truncate extends Query implements Database\Query\Truncate
{
use hasTable;
public function __construct(string $table)
{
$this->table($table);
}
public function table(string $table): Database\Query\Truncate
{
return $this->setTable($table);
}
public function build(): string
{
return "TRUNCATE TABLE {$this->getTable()}";
}
}

View File

@ -0,0 +1,71 @@
<?php
namespace ProVM\Implement\Database\Query;
use ProVM\Implement\Database\Query;
use ProVM\Concept\Database;
abstract class Update extends Query implements Database\Query\Update
{
use hasTable, hasConditions;
public function table(string $table): Database\Query\Update
{
return $this->setTable($table);
}
public function set(array|string $value_pairs): Database\Query\Update
{
return $this->setValues($value_pairs);
}
public function where(array|string $conditions): Database\Query\Update
{
return $this->setConditions($conditions);
}
protected array|string $values;
public function getValues(): array
{
return $this->values;
}
public function addValue(string $column, int|string $value): Database\Query\Update
{
if (!is_numeric($value)) {
$value = "'{$value}'";
}
$this->values []= "`{$column}` = {$value}";
return $this;
}
public function setValues(array|string $values): Database\Query\Update
{
if (is_string($values)) {
$this->values = $values;
return $this;
}
foreach ($values as $value) {
$column = $value['column'] ?? $value[0];
$val = $value['value'] ?? $value[1];
$this->addValue($column, $val);
}
return $this;
}
protected function getValuesString(): string
{
if (!isset($this->values)) {
return '';
}
$values = (is_array($this->getValues())) ? implode(', ', $this->getValues()) : $this->getValues();
return " SET {$values}";
}
public function build(): string
{
return implode('', [
"UPDATE {$this->getTable()}",
$this->getValuesString(),
$this->getConditionsString()
]);
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace ProVM\Implement\Database\Query;
trait hasConditions
{
protected array|string $conditions;
protected function getConditions(): array|string
{
return $this->conditions ?? '';
}
protected function setConditions(array|string $conditions)
{
$this->conditions = $conditions;
return $this;
}
protected function getConditionsString(): string
{
$conditions = $this->getConditions();
if (is_array($conditions)) {
$first = array_shift($conditions);
$matched = preg_match_all('/^and|or\s/i', trim($first));
if ($matched > 0) {
$temp = str_replace(['and ', 'or '], ['', ''], strtolower($first));
$dif = strlen($first) - strlen($temp);
$first = substr($first, $dif);
}
$conditions = "{$first} " . implode(' ', array_map(function(string $condition) {
$matched = preg_match_all('/^and|or\s/i', trim($condition));
if ($matched > 0) {
return $condition;
}
return "AND {$condition}";
}, $conditions));
}
if (trim($conditions) === '') {
return '';
}
return " WHERE {$conditions}";
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace ProVM\Implement\Database\Query;
trait hasTable
{
protected string $table;
public function getTable(): string
{
return $this->table;
}
public function setTable(string $table, ?string $alias = null)
{
$table = "`{$table}`";
if ($alias !== null) {
$table = "{$table} '{$alias}'";
}
$this->table = $table;
return $this;
}
}