juggl/juggl-server/api/services/dbOperations.inc.php
2020-11-21 00:49:22 +01:00

292 lines
8.1 KiB
PHP

<?php
require_once(__DIR__ . "/basicEnum.inc.php");
class DbOperations
{
function __construct($tablePrefix = null)
{
$this->resetQuery();
$this->tablePrefix = $tablePrefix;
require(__DIR__ . "/../config/config.php");
$this->config = $config;
if ($this->tablePrefix == null) {
$this->tablePrefix = $this->config["table_prefix"];
}
}
function resetQuery()
{
$this->query = "";
$this->data = array();
$this->table = "";
}
private function openConnection()
{
$host = $this->config['host'];
$dbname = $this->config['dbname'];
$dsn = "mysql:host=$host;dbname=$dbname";
$options = array(PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC);
$this->pdo = new PDO($dsn, $this->config['username'], $this->config['password'], $options);
}
function select(string $table, array $attributes = array(), bool $addTableName = true)
{
$this->table = $this->tablePrefix . $table;
if (count($attributes) == 0)
$formattedAttributes = "*";
else {
for ($i = 0; $i < count($attributes); $i++) {
$a = $attributes[$i];
// Add table name prefix if missing
if ($addTableName && strpos($a, ".") === false) {
$attributes[$i] = "$this->table.$a";
}
}
$formattedAttributes = implode(', ', $attributes);
}
$this->addToQuery("SELECT $formattedAttributes FROM $this->tablePrefix$table");
return $this;
}
function orderBy(string $attribute, string $order = Order::ASC)
{
$this->addToQuery("ORDER BY $attribute $order");
return $this;
}
static function getLatestIdInTable(string $table, string $attribute = "id")
{
$db = new DbOperations();
$db->select($table, array($attribute));
$db->orderBy($attribute, Order::DESC);
return $db->execute()[0][$attribute];
}
function insert(string $table, array $data)
{
$this->table = $this->tablePrefix . $table;
$attributes = implode(", ", array_keys($data));
$valuesIds = array();
foreach ($data as $attribute => $value) {
$valuesIds[] = $this->addData($value, $attribute);
}
$values = implode(" , ", $valuesIds);
$this->addToQuery("INSERT INTO $this->tablePrefix$table ( $attributes ) VALUES ( $values )");
return $this;
}
function insertMultiple(string $table, array $attributes, array $data)
{
$this->table = $this->tablePrefix . $table;
$attributesString = implode(", ", $attributes);
$valueGroups = array();
$groupIndex = 0; // To avoid same value ids
foreach ($data as $dataGroup) {
if (sizeof($attributes) != sizeof($dataGroup)) {
continue;
}
$valueIds = array();
// Indexed for used, so that attributes can easily be assigned to the according values
for ($i = 0; $i < sizeof($dataGroup); $i++) {
$valueIds[] = $this->addData($dataGroup[$i], $attributes[$i] . "_" . (string) $groupIndex);
}
$valueGroups[] = "(" . implode(", ", $valueIds) . ")";
$groupIndex++;
}
$values = implode(", ", $valueGroups);
$this->addToQuery("INSERT INTO $this->tablePrefix$table ( $attributesString ) VALUES $values");
return $this;
}
function update(string $table, array $data)
{
$this->table = $this->tablePrefix . $table;
$sets = array();
foreach ($data as $attribute => $value) {
$valueId = $this->addData($value, $attribute);
$sets[] = "$attribute = $valueId";
}
$setString = implode(", ", $sets);
$this->addToQuery("UPDATE $this->tablePrefix$table SET $setString");
return $this;
}
function delete(string $table)
{
$this->table = $this->tablePrefix . $table;
$this->addToQuery("DELETE FROM $this->tablePrefix$table");
return $this;
}
function limit(int $limit, int $offset = null)
{
$this->addToQuery("LIMIT $limit");
if ($offset != null) {
$this->addToQuery("OFFSET $offset");
}
return $this;
}
private function addToQuery(string $phrase)
{
$delimeter = " ";
$this->query = implode($delimeter, array($this->query, $phrase));
}
function where(string $attribute, string $comparison, $value, string $connector = Combination::AND)
{
if (Comparison::isValidValue($comparison) == false)
return;
$keyWord = "WHERE";
if (!(strpos($this->query, $keyWord) === false))
$keyWord = $connector;
$valueId = $this->addData($value, $attribute);
$this->addToQuery("$keyWord $attribute $comparison $valueId");
return $this;
}
function whereOneOf(string $attribute, string $comparison, $values, string $connector = Combination::AND)
{
if (Comparison::isValidValue($comparison) == false)
return;
$keyWord = "WHERE";
if (!(strpos($this->query, $keyWord) === false))
$keyWord = $connector;
$whereClause = "$keyWord ( ";
for ($i = 0; $i < sizeof($values); $i++) {
if ($i > 0) {
$whereClause .= " OR ";
}
$valueId = $this->addData($values[$i], $attribute . '_' . $i);
$whereClause .= "$attribute $comparison $valueId";
}
$whereClause .= " )";
$this->addToQuery($whereClause);
return $this;
}
function innerJoin(string $table, string $externAttribute, string $internAttribute = "", string $internTable = "")
{
if ($internTable === "") {
$internTable = substr($this->table, sizeof($this->tablePrefix));
}
if ($internAttribute === "") {
$internAttribute = $externAttribute;
}
$innerJoin = "INNER JOIN $this->tablePrefix$table ON $this->tablePrefix$table.$externAttribute = $this->tablePrefix$internTable.$internAttribute";
$this->addToQuery($innerJoin);
return $this;
}
private function addData($data, $attribute)
{
$name = str_replace(".", "", $attribute);
$this->data[$name] = $data;
return ":" . $name;
}
function addSql($sql)
{
$this->addToQuery($sql);
}
function addValue($value)
{
$identifier = "customIdentifier" . $this->customValueId;
$this->customValueId += 1;
$this->addToQuery($this->addData($value, $identifier));
}
function execute()
{
try {
$this->openConnection();
$pdoQuery = $this->pdo->prepare($this->query);
$pdoQuery->execute($this->data);
$results = array();
while ($row = $pdoQuery->fetch()) {
$results[] = $row;
}
$this->resetQuery();
return $results;
} catch (PDOException $e) {
// TODO: Hide errors from user and log them
print($e);
return array();
}
}
function sql(string $sqlStatement, array $data)
{
$this->query = $sqlStatement;
foreach ($data as $attribute => $value) {
$this->addData($value, $attribute);
}
}
}
abstract class Comparison extends BasicEnum
{
const EQUAL = "=";
const GREATER_THAN = ">";
const GREATER_THAN_OR_EQUAL = ">=";
const LESS_THAN = "<";
const LESS_THAN_OR_EQUAL = "<=";
const UNEQUAL = "!=";
const LIKE = "LIKE";
}
abstract class Combination extends BasicEnum
{
const AND = "AND";
const OR = "OR";
}
abstract class Order extends BasicEnum
{
const ASC = "ASC";
const DESC = "DESC";
}