2024-05-24 13:05:42 +00:00
|
|
|
<?php /* Copyright (c) 2024 Freya Murphy */
|
|
|
|
|
2024-09-18 18:14:53 +00:00
|
|
|
function __nullify(mixed $val): mixed
|
|
|
|
{
|
2024-07-08 21:22:30 +00:00
|
|
|
if (!$val) {
|
|
|
|
return NULL;
|
|
|
|
} else {
|
|
|
|
return $val;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-24 13:05:42 +00:00
|
|
|
class DatabaseQuery {
|
|
|
|
|
2024-07-08 21:22:30 +00:00
|
|
|
private \PDO $conn;
|
|
|
|
private string $query;
|
2024-05-24 13:05:42 +00:00
|
|
|
|
2024-07-08 21:22:30 +00:00
|
|
|
private bool $where;
|
|
|
|
private bool $set;
|
2024-05-24 13:05:42 +00:00
|
|
|
|
2024-07-08 21:22:30 +00:00
|
|
|
private array $param;
|
2024-05-24 13:05:42 +00:00
|
|
|
|
2024-09-18 18:14:53 +00:00
|
|
|
function __construct(\PDO $conn)
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
$this->conn = $conn;
|
|
|
|
$this->query = '';
|
|
|
|
|
|
|
|
$this->set = FALSE;
|
|
|
|
$this->where = FALSE;
|
|
|
|
$this->param = array();
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
|
|
|
/// ARBITRARY QUERY
|
|
|
|
///
|
|
|
|
|
2024-09-18 18:14:53 +00:00
|
|
|
public function query(string $query): DatabaseQuery
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
$this->query .= $query;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
|
|
|
/// SELECT
|
|
|
|
///
|
|
|
|
|
2024-09-18 18:14:53 +00:00
|
|
|
public function select(string $select): DatabaseQuery
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
$this->query .= "SELECT $select\n";
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2024-09-18 18:14:53 +00:00
|
|
|
public function from(string $from): DatabaseQuery
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
$this->query .= "FROM $from\n";
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
|
|
|
/// INSERT
|
|
|
|
///
|
|
|
|
|
2024-09-18 18:14:53 +00:00
|
|
|
public function insert_into(string $insert, string ...$columns): DatabaseQuery
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
$this->query .= "INSERT INTO $insert\n (";
|
|
|
|
foreach ($columns as $idx => $column) {
|
|
|
|
if ($idx !== 0) {
|
|
|
|
$this->query .= ",";
|
|
|
|
}
|
|
|
|
$this->query .= $column;
|
|
|
|
}
|
|
|
|
$this->query .= ")\n";
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2024-09-18 18:14:53 +00:00
|
|
|
public function values(mixed ...$values): DatabaseQuery
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
$this->query .= "VALUES (";
|
|
|
|
foreach ($values as $idx => $value) {
|
|
|
|
if ($idx !== 0) {
|
|
|
|
$this->query .= ",";
|
|
|
|
}
|
|
|
|
$this->query .= "?";
|
|
|
|
array_push($this->param, $value);
|
|
|
|
}
|
|
|
|
$this->query .= ")\n";
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
|
|
|
/// WHERE
|
|
|
|
///
|
|
|
|
|
2024-09-18 18:14:53 +00:00
|
|
|
public function where(string $cond): DatabaseQuery
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
if (!$this->where) {
|
|
|
|
$this->where = TRUE;
|
|
|
|
$this->query .= "WHERE ";
|
|
|
|
} else {
|
|
|
|
$this->query .= "AND ";
|
|
|
|
}
|
|
|
|
$this->query .= "$cond ";
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2024-07-08 21:22:30 +00:00
|
|
|
/**
|
|
|
|
* @param array<mixed> $array
|
|
|
|
*/
|
2024-09-18 18:14:53 +00:00
|
|
|
public function where_in(string $column, array $array): DatabaseQuery
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
if (!$this->where) {
|
|
|
|
$this->where = TRUE;
|
|
|
|
$this->query .= "WHERE ";
|
|
|
|
} else {
|
|
|
|
$this->query .= "AND ";
|
|
|
|
}
|
|
|
|
if (empty($array)) {
|
|
|
|
$this->query .= "FALSE\n";
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
$in = $this->in($array);
|
|
|
|
$this->query .= "$column $in\n";
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2024-07-08 21:22:30 +00:00
|
|
|
/**
|
|
|
|
* @param array<mixed> $array
|
|
|
|
*/
|
2024-09-18 18:14:53 +00:00
|
|
|
private function in(array $array): DatabaseQuery
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
$in = 'IN (';
|
|
|
|
foreach ($array as $idx => $item) {
|
|
|
|
if ($idx != 0) {
|
|
|
|
$in .= ",";
|
|
|
|
}
|
|
|
|
$in .= "?";
|
|
|
|
array_push($this->param, $item);
|
|
|
|
}
|
|
|
|
$in .= ")";
|
|
|
|
return $in;
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
|
|
|
/// OPERATORS
|
|
|
|
///
|
|
|
|
|
2024-09-18 18:14:53 +00:00
|
|
|
public function like(mixed $item): DatabaseQuery
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
$this->query .= "LIKE ?\n";
|
|
|
|
array_push($this->param, $item);
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2024-09-18 18:14:53 +00:00
|
|
|
public function eq(mixed $item): DatabaseQuery
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
$this->query .= "= ?\n";
|
|
|
|
array_push($this->param, $item);
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2024-09-18 18:14:53 +00:00
|
|
|
public function ne(mixed $item): DatabaseQuery
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
$this->query .= "<> ?\n";
|
|
|
|
array_push($this->param, $item);
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2024-09-18 18:14:53 +00:00
|
|
|
public function lt(mixed $item): DatabaseQuery
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
$this->query .= "< ?\n";
|
|
|
|
array_push($this->param, $item);
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2024-09-18 18:14:53 +00:00
|
|
|
public function le(mixed $item): DatabaseQuery
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
$this->query .= "<= ?\n";
|
|
|
|
array_push($this->param, $item);
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
|
|
|
/// JOINS
|
|
|
|
///
|
|
|
|
|
2024-09-18 18:14:53 +00:00
|
|
|
public function join(string $table, string $on, string $type = 'LEFT'): DatabaseQuery
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
$this->query .= "$type JOIN $table ON $on\n";
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
|
|
|
/// LIMIT, OFFSET, ORDER
|
|
|
|
///
|
|
|
|
|
2024-09-18 18:14:53 +00:00
|
|
|
public function limit(int $limit): DatabaseQuery
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
$this->query .= "LIMIT ?\n";
|
|
|
|
array_push($this->param, $limit);
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2024-09-18 18:14:53 +00:00
|
|
|
public function offset(int $offset): DatabaseQuery
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
$this->query .= "OFFSET ?\n";
|
|
|
|
array_push($this->param, $offset);
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2024-09-18 18:14:53 +00:00
|
|
|
public function order_by(string $column, string $order = 'ASC'): DatabaseQuery
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
$this->query .= "ORDER BY " . $column . ' ' . $order . ' ';
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
|
|
|
/// COLLECT
|
|
|
|
///
|
|
|
|
|
2024-09-18 18:14:53 +00:00
|
|
|
public function rows(mixed ...$params): ?array
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
$args = $this->param;
|
|
|
|
foreach ($params as $param) {
|
|
|
|
array_push($args, $param);
|
|
|
|
}
|
|
|
|
$stmt = $this->conn->prepare($this->query);
|
|
|
|
try {
|
|
|
|
$stmt->execute($args);
|
|
|
|
} catch (Exception $ex) {
|
|
|
|
echo $ex;
|
|
|
|
echo '<br> >> caused by <<<br>';
|
|
|
|
echo str_replace("\n", "<br>", $this->query);
|
|
|
|
}
|
2024-07-08 21:22:30 +00:00
|
|
|
return __nullify($stmt->fetchAll(PDO::FETCH_ASSOC));
|
2024-05-24 13:05:42 +00:00
|
|
|
}
|
|
|
|
|
2024-09-18 18:14:53 +00:00
|
|
|
public function row(mixed ...$params): ?array
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
$args = $this->param;
|
|
|
|
foreach ($params as $param) {
|
|
|
|
array_push($args, $param);
|
|
|
|
}
|
|
|
|
$stmt = $this->conn->prepare($this->query);
|
|
|
|
$stmt->execute($args);
|
2024-07-08 21:22:30 +00:00
|
|
|
return __nullify($stmt->fetch(PDO::FETCH_ASSOC));
|
2024-05-24 13:05:42 +00:00
|
|
|
}
|
|
|
|
|
2024-09-18 18:14:53 +00:00
|
|
|
public function execute(mixed ...$params): bool
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
$args = $this->param;
|
|
|
|
foreach ($params as $param) {
|
|
|
|
array_push($args, $param);
|
|
|
|
}
|
|
|
|
$stmt = $this->conn->prepare($this->query);
|
|
|
|
try {
|
|
|
|
$stmt->execute($args);
|
|
|
|
return TRUE;
|
|
|
|
} catch (Exception $_e) {
|
|
|
|
echo $_e;
|
|
|
|
echo '<br> >> caused by <<<br>';
|
|
|
|
echo str_replace("\n", "<br>", $this->query);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* DatabaseHelper
|
|
|
|
* allows queries on the
|
|
|
|
* postgres database
|
|
|
|
*/
|
|
|
|
class DatabaseHelper {
|
|
|
|
|
2024-07-08 21:22:30 +00:00
|
|
|
private ?\PDO $conn;
|
2024-05-24 13:05:42 +00:00
|
|
|
|
2024-09-18 18:14:53 +00:00
|
|
|
function __construct()
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
$this->conn = NULL;
|
|
|
|
}
|
|
|
|
|
2024-09-18 18:14:53 +00:00
|
|
|
private function connect(): \PDO
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
if ($this->conn === NULL) {
|
|
|
|
$user = getenv("POSTGRES_USER");
|
|
|
|
$pass = getenv("POSTGRES_PASSWORD");
|
|
|
|
$db = getenv("POSTGRES_DB");
|
|
|
|
$host = 'db';
|
|
|
|
$port = '5432';
|
|
|
|
|
|
|
|
$conn_str = sprintf("pgsql:host=%s;port=%d;dbname=%s;user=%s;password=%s",
|
|
|
|
$host,
|
|
|
|
$port,
|
|
|
|
$db,
|
|
|
|
$user,
|
|
|
|
$pass
|
|
|
|
);
|
|
|
|
$this->conn = new \PDO($conn_str);
|
|
|
|
$this->conn->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
|
|
|
}
|
|
|
|
return $this->conn;
|
|
|
|
}
|
|
|
|
|
2024-09-18 18:14:53 +00:00
|
|
|
public function select(string $select): DatabaseQuery
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
$conn = $this->connect();
|
|
|
|
$query = new DatabaseQuery($conn);
|
|
|
|
return $query->select($select);
|
|
|
|
}
|
|
|
|
|
2024-09-18 18:14:53 +00:00
|
|
|
public function insert_into(string $insert, string ...$columns): DatabaseQuery
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
$conn = $this->connect();
|
|
|
|
$query = new DatabaseQuery($conn);
|
|
|
|
return $query->insert_into($insert, ...$columns);
|
|
|
|
}
|
|
|
|
|
2024-09-18 18:14:53 +00:00
|
|
|
public function query(string $query_str): DatabaseQuery
|
|
|
|
{
|
2024-05-24 13:05:42 +00:00
|
|
|
$conn = $this->connect();
|
|
|
|
$query = new DatabaseQuery($conn);
|
|
|
|
return $query->query($query_str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|