table = $table; $this->pk = $pk; $this->connection = $connection; $this->reset(); } public function reset() { $this->columns = []; $this->wheres = []; $this->orders = []; $this->groupby = []; $this->offset = null; $this->take = null; $this->distinct = false; $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 distinct() { $this->distinct = true; 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 groupBy($columns) { if (is_array($columns)) { $this->groupby = array_merge($this->groupby, $columns); } if (is_string($columns)) { $this->groupby[] = $columns; } return $this; } public function whereIn($condition, array $values) { $this->wheres[] = new Expression($condition, "in", $values); return $this; } public function whereBetween($condition, $value1, $value2) { $this->wheres[] = new Expression($condition, "between", [$value1,$value2]); return $this; } public function whereNotNull($condition) { $this->wheres[] = new Expression($condition, "notnull", ""); return $this; } public function whereNull($condition) { $this->wheres[] = new Expression($condition, "isnull", ""); 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)->first(); } 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 new Collection($ret); } private function getData(): mixed { return Connection::getInstance($this->connection)->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); $distinct = ($this->distinct) ? " DISTINCT " : ""; $query = "SELECT " . $distinct . " " . $columns . " FROM " . $this->table ; $where = $this->getWhere(); $this->fillData($ret); if ($where != "") { $query .= " WHERE " . $where; } $query .= $this->getClause("GROUP By", $this->groupby); $query .= $this->getClause("ORDER By", $this->orders); $query .= $this->getLimit(); $ret->setQuery($query); return $ret; } private function fillData(Query &$query): void { foreach ($this->wheres as $expression) { if ($expression instanceof Expression) { if ($expression->hasData()) { $query->addData($expression->getValue()); } } } } private function getWhere(): string { $where = ""; foreach ($this->wheres as $expression) { $sw = ""; if ($expression instanceof Expression) { $sw = $expression->raw(); } if (is_string($expression)) { if (trim($expression) !== "") { $sw = "(" . $expression . ")"; } } if ($where != "" && $sw != "") { $where .= " AND "; } $where .= $sw; } return $where; } private function getClause(string $word, array $data): string { if (!empty($data)) { return " $word " . implode(",", $data); } return ""; } private function getLimit(): string { if ($this->take !== null || $this->offset !== null) { $ret = ($this->take !== null ? " LIMIT " . $this->take : "") . ($this->offset !== null ? " 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(); } } public function getConnection() { return $this->connection; } public function setConnection($connection) { $this->connection = $connection; return $this; } }