79 lines
2.5 KiB
PHP
79 lines
2.5 KiB
PHP
|
<?php
|
||
|
namespace DatabaseHelper\classes;
|
||
|
|
||
|
use DatabaseHelper\enums\ColumnTypes;
|
||
|
use DatabaseHelper\interfaces\QueryBuilder;
|
||
|
use DatabaseHelper\interfaces\TableBlueprint;
|
||
|
use InvalidArgumentException;
|
||
|
|
||
|
class Query implements QueryBuilder
|
||
|
{
|
||
|
private TableBlueprint $table;
|
||
|
private array $columns = ['*'];
|
||
|
private array $conditions = [];
|
||
|
|
||
|
/**
|
||
|
* @var ColumnTypes[]
|
||
|
*/
|
||
|
private array $columnTypes = [];
|
||
|
|
||
|
public function __construct(TableBlueprint $table) {
|
||
|
$this->columnTypes = array_map(fn($col) => $col['colType'], $table->columns);
|
||
|
$this->table = $table;
|
||
|
}
|
||
|
|
||
|
public function select(string ...$cols): QueryBuilder {
|
||
|
if (!empty($cols))
|
||
|
$this->columns = $cols;
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
public function where(string $col, string $operator, mixed $val): QueryBuilder {
|
||
|
return $this->addCondition($col, $operator, $val, "AND");
|
||
|
}
|
||
|
|
||
|
public function andWhere(string $col, string $operator, mixed $val): QueryBuilder {
|
||
|
return $this->addCondition($col, $operator, $val, "AND");
|
||
|
}
|
||
|
|
||
|
public function orWhere(string $col, string $operator, mixed $val): QueryBuilder {
|
||
|
return $this->addCondition($col, $operator, $val, "OR");
|
||
|
}
|
||
|
|
||
|
private function addCondition(string $colName, string $operator, mixed $val, string $prefix): QueryBuilder {
|
||
|
if (!isset($this->columnTypes[$colName]))
|
||
|
throw new InvalidArgumentException("Unknown column: $colName");
|
||
|
|
||
|
$columnType = $this->columnTypes[$colName];
|
||
|
$castedValue = $columnType->dbCast($val);
|
||
|
|
||
|
if (!empty($this->conditions))
|
||
|
$this->conditions[] = $prefix;
|
||
|
$this->conditions[] = "$colName $operator $castedValue";
|
||
|
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
public function toSql(): string {
|
||
|
$columns = implode(", ", $this->columns);
|
||
|
$table = $this->table->tableName;
|
||
|
$whereClause = !empty($this->conditions) ? " WHERE " . implode(" ", $this->conditions) : "";
|
||
|
return esc_sql("SELECT $columns FROM $table$whereClause");
|
||
|
}
|
||
|
|
||
|
public function query(): array {
|
||
|
global $wpdb;
|
||
|
$query = $this->toSql();
|
||
|
$results = $wpdb->get_results($wpdb->prepare($query), ARRAY_A);
|
||
|
return $this->castResults($results);
|
||
|
}
|
||
|
|
||
|
private function castResults(array $results): array {
|
||
|
foreach ($results as &$row)
|
||
|
foreach ($row as $column => &$value)
|
||
|
if (isset($this->columnTypes[$column]))
|
||
|
$value = $this->columnTypes[$column]->valCast($value);
|
||
|
return $results;
|
||
|
}
|
||
|
}
|