Files
PdoWrapper/src/QueryBuilder.php

234 lines
5.9 KiB
PHP

<?php
namespace Kletellier\PdoWrapper;
class QueryBuilder
{
protected Db $db;
protected array $columns;
protected array $wheres;
protected array $orders;
protected string $table;
protected string $pk;
protected ?int $take;
protected ?int $offset;
protected string $raw_query;
public function __construct($table, $pk = "id")
{
$this->table = $table;
$this->pk = $pk;
$this->db = Db::getInstance();
$this->reset();
}
public function reset()
{
$this->columns = [];
$this->wheres = [];
$this->orders = [];
$this->offset = null;
$this->take = null;
$this->raw_query = "";
}
public function raw(string $query)
{
$this->raw_query = $query;
return $this;
}
public function take(?int $nb)
{
$this->take = $nb;
return $this;
}
public function offset(?int $offset)
{
$this->offset = $offset;
return $this;
}
public function orderBy($columns, $sort = "ASC")
{
if (is_array($columns)) {
foreach ($columns as $column) {
$this->orders[] = $column . " " . $sort;
}
} else {
$this->orders[] = $columns . " " . $sort;
}
return $this;
}
public function columns($columns)
{
if (is_array($columns)) {
$this->columns = array_merge($this->columns, $columns);
}
if (is_string($columns)) {
$this->columns[] = $columns;
}
return $this;
}
public function where($condition, $operator, $value = null)
{
if ($value === null) {
$this->wheres[] = new Expression($condition, "=", $operator);
} else {
$this->wheres[] = new Expression($condition, $operator, $value);
}
return $this;
}
public function whereRaw(string $raw)
{
$this->wheres[] = $raw;
return $this;
}
public function find($id): mixed
{
$this->reset();
$expression = new Expression($this->pk, "=", $id);
$this->wheres = [$expression];
$this->columns = ["*"];
$data = $this->getData();
if (count($data) > 0) {
return $this->prepareModels($data)[0];
}
return null;
}
public function get(): mixed
{
$data = $this->getData();
return $this->prepareModels($data);
}
public function getPreparedQuery(array $data, $insert = true): Query
{
$ret = new Query();
$columns = implode(",", array_keys($data));
$query = "";
if ($insert) {
$keys = implode(",", str_split(str_repeat("?", count($data))));
$query = "INSERT INTO " . $this->table . " (" . $columns . ") VALUES (" . $keys . ");";
foreach ($data as $key => $value) {
$ret->addData($value);
}
} else {
$query = "UPDATE " . $this->table . " SET ";
$up = "";
foreach ($data as $key => $value) {
if ($up != "") {
$up .= ", ";
}
$up .= $key . " = ? ";
$ret->addData($value);
}
$query .= $up . " WHERE " . $this->pk . " = ? ;";
$ret->addData($data[$this->pk]);
}
$ret->setQuery($query);
return $ret;
}
private function prepareModels(mixed $data): mixed
{
$ret = array();
foreach ($data as $row) {
$model = new Model();
$ret[] = $model->setPk($this->pk)->setTable($this->table)->fillData($row);
}
return $ret;
}
private function getData(): mixed
{
return $this->db->getSelectQuery($this->getQuery());
}
private function getConstructedQuery(): Query
{
$ret = new Query();
$ret->setQuery("");
$ret->setData([]);
if (count($this->columns) == 0) {
$this->columns("*");
}
$columns = implode(",", $this->columns);
$where = "";
foreach ($this->wheres as $expression) {
$sw = "";
if ($expression instanceof Expression) {
$sw = $expression->raw();
$ret->addData($expression->getValue());
}
if ($expression instanceof string) {
if (trim($expression) !== "") {
$sw = "(" . $expression . ")";
}
}
if ($where != "" && $sw != "") {
$where .= " AND ";
}
$where .= $sw;
}
$query = "SELECT " . $columns . " FROM " . $this->table ;
if ($where != "") {
$query .= " WHERE " . $where;
}
if (count($this->orders) > 0) {
$query .= " ORDER BY ";
$iOrder = 0;
foreach ($this->orders as $order) {
if ($iOrder > 0) {
$query .= ",";
}
$query .= $order;
$iOrder++;
}
}
$query .= $this->getLimit();
$ret->setQuery($query);
return $ret;
}
private function getLimit(): string
{
if ($this->take !== null || $this->offset !== null) {
$ret = "";
if ($this->take !== null) {
$ret = " LIMIT " . $this->take;
}
if ($this->offset !== null) {
$ret .= " OFFSET " . $this->offset;
}
return $ret;
} else {
return "";
}
}
private function getQuery(): Query
{
if ($this->raw_query !== "") {
$query = new Query();
$query->setQuery($this->raw_query);
$query->setData([]);
return $query;
} else {
return $this->getConstructedQuery();
}
}
}