From 26367195833434f9c9e8ace608bb07b2ab10b60f Mon Sep 17 00:00:00 2001 From: Roman Hergenreder Date: Fri, 3 Apr 2020 14:46:29 +0200 Subject: [PATCH] Limit, Order By --- core/Api/Notifications/Fetch.class.php | 2 + core/Driver/SQL/MySQL.class.php | 114 +----------------------- core/Driver/SQL/PostgreSQL.class.php | 106 ---------------------- core/Driver/SQL/Query/Select.class.php | 38 ++++++++ core/Driver/SQL/SQL.class.php | 116 +++++++++++++++++++++++-- 5 files changed, 150 insertions(+), 226 deletions(-) diff --git a/core/Api/Notifications/Fetch.class.php b/core/Api/Notifications/Fetch.class.php index 79234b7..6e0bdd8 100644 --- a/core/Api/Notifications/Fetch.class.php +++ b/core/Api/Notifications/Fetch.class.php @@ -22,6 +22,7 @@ class Fetch extends Request { ->innerJoin("UserNotification", "UserNotification.notification_id", "Notification.uid") ->where(new Compare("UserNotification.user_id", $userId)) ->where(new Compare("UserNotification.seen", false)) + ->orderBy("created_at")->descending() ->execute(); $this->success = ($res !== FALSE); @@ -53,6 +54,7 @@ class Fetch extends Request { ->innerJoin("UserGroup", "GroupNotification.group_id", "UserGroup.group_id") ->where(new Compare("UserGroup.user_id", $userId)) ->where(new Compare("GroupNotification.seen", false)) + ->orderBy("created_at")->descending() ->execute(); $this->success = ($res !== FALSE); diff --git a/core/Driver/SQL/MySQL.class.php b/core/Driver/SQL/MySQL.class.php index 057e52e..91505e7 100644 --- a/core/Driver/SQL/MySQL.class.php +++ b/core/Driver/SQL/MySQL.class.php @@ -18,10 +18,6 @@ use \Driver\SQL\Strategy\SetDefaultStrategy; use \Driver\SQL\Strategy\SetNullStrategy; use \Driver\SQL\Strategy\UpdateStrategy; -use \Driver\SQL\Constraint\Unique; -use \Driver\SQL\Constraint\PrimaryKey; -use \Driver\SQL\Constraint\ForeignKey; - class MySQL extends SQL { public function __construct($connectionData) { @@ -222,88 +218,8 @@ class MySQL extends SQL { return $success; } - public function executeSelect($select) { - - $columns = $this->columnName($select->getColumns()); - $tables = $select->getTables(); - $params = array(); - - if (is_null($tables) || empty($tables)) { - return "SELECT $columns"; - } else { - $tables = $this->tableName($tables); - } - - $conditions = $select->getConditions(); - if (!empty($conditions)) { - $condition = " WHERE " . $this->buildCondition($conditions, $params); - } else { - $condition = ""; - } - - $joinStr = ""; - $joins = $select->getJoins(); - if (!empty($joins)) { - $joinStr = ""; - foreach($joins as $join) { - $type = $join->getType(); - $joinTable = $this->tableName($join->getTable()); - $columnA = $this->columnName($join->getColumnA()); - $columnB = $this->columnName($join->getColumnB()); - $joinStr .= " $type JOIN $joinTable ON $columnA=$columnB"; - } - } - - $orderBy = ""; - $limit = ""; - $offset = ""; - - $query = "SELECT $columns FROM $tables$joinStr$condition$orderBy$limit$offset"; - return $this->execute($query, $params, true); - } - - public function executeDelete($delete) { - - $table = $delete->getTable(); - $conditions = $delete->getConditions(); - if (!empty($conditions)) { - $condition = " WHERE " . $this->buildCondition($conditions, $params); - } else { - $condition = ""; - } - - $query = "DELETE FROM $table$condition"; - return $this->execute($query); - } - - public function executeTruncate($truncate) { - return $this->execute("TRUNCATE " . $truncate->getTable()); - } - - public function executeUpdate($update) { - - $params = array(); - $table = $update->getTable(); - - $valueStr = array(); - foreach($update->getValues() as $key => $val) { - $valueStr[] = "$key=" . $this->addValue($val, $params); - } - $valueStr = implode(",", $valueStr); - - $conditions = $update->getConditions(); - if (!empty($conditions)) { - $condition = " WHERE " . $this->buildCondition($conditions, $params); - } else { - $condition = ""; - } - - $query = "UPDATE $table SET $valueStr$condition"; - return $this->execute($query, $params); - } - public function getColumnDefinition($column) { - $columnName = $column->getName(); + $columnName = $this->columnName($column->getName()); $defaultValue = $column->getDefaultValue(); if ($column instanceof StringColumn) { @@ -344,35 +260,9 @@ class MySQL extends SQL { $defaultValue = ""; } - return "`$columnName` $type$notNull$defaultValue"; + return "$columnName $type$notNull$defaultValue"; } - public function getConstraintDefinition($constraint) { - $columnName = $constraint->getColumnName(); - if ($constraint instanceof PrimaryKey) { - if (is_array($columnName)) $columnName = implode('`,`', $columnName); - return "PRIMARY KEY (`$columnName`)"; - } else if ($constraint instanceof Unique) { - if (is_array($columnName)) $columnName = implode('`,`', $columnName); - return "UNIQUE (`$columnName`)"; - } else if ($constraint instanceof ForeignKey) { - $refTable = $constraint->getReferencedTable(); - $refColumn = $constraint->getReferencedColumn(); - $strategy = $constraint->onDelete(); - $code = "FOREIGN KEY (`$columnName`) REFERENCES `$refTable` (`$refColumn`)"; - if ($strategy instanceof SetDefaultStrategy) { - $code .= " ON DELETE SET DEFAULT"; - } else if($strategy instanceof SetNullStrategy) { - $code .= " ON DELETE SET NULL"; - } else if($strategy instanceof CascadeStrategy) { - $code .= " ON DELETE CASCADE"; - } - - return $code; - } - } - - // TODO: check this please.. public function getValueDefinition($value) { if (is_numeric($value)) { return $value; diff --git a/core/Driver/SQL/PostgreSQL.class.php b/core/Driver/SQL/PostgreSQL.class.php index 5df5996..c7d01ea 100644 --- a/core/Driver/SQL/PostgreSQL.class.php +++ b/core/Driver/SQL/PostgreSQL.class.php @@ -18,10 +18,6 @@ use \Driver\SQL\Strategy\SetDefaultStrategy; use \Driver\SQL\Strategy\SetNullStrategy; use \Driver\SQL\Strategy\UpdateStrategy; -use \Driver\SQL\Constraint\Unique; -use \Driver\SQL\Constraint\PrimaryKey; -use \Driver\SQL\Constraint\ForeignKey; - class PostgreSQL extends SQL { public function __construct($connectionData) { @@ -203,85 +199,6 @@ class PostgreSQL extends SQL { return $success; } - public function executeSelect($select) { - - $columns = $this->columnName($select->getColumns()); - $tables = $select->getTables(); - $params = array(); - - if (is_null($tables) || empty($tables)) { - return "SELECT $columns"; - } else { - $tableStr = $this->tableName($tables); - } - - $conditions = $select->getConditions(); - if (!empty($conditions)) { - $condition = " WHERE " . $this->buildCondition($conditions, $params); - } else { - $condition = ""; - } - - $joinStr = ""; - $joins = $select->getJoins(); - if (!empty($joins)) { - $joinStr = ""; - foreach($joins as $join) { - $type = $join->getType(); - $joinTable = $this->tableName($join->getTable()); - $columnA = $this->columnName($join->getColumnA()); - $columnB = $this->columnName($join->getColumnB()); - $joinStr .= " $type JOIN $joinTable ON $columnA=$columnB"; - } - } - - $orderBy = ""; - $limit = ""; - $offset = ""; - - $query = "SELECT $columns FROM $tableStr$joinStr$condition$orderBy$limit$offset"; - return $this->execute($query, $params, true); - } - - public function executeDelete($delete) { - $table = $delete->getTable(); - $conditions = $delete->getConditions(); - if (!empty($conditions)) { - $condition = " WHERE " . $this->buildCondition($conditions, $params); - } else { - $condition = ""; - } - - $query = "DELETE FROM \"$table\"$condition"; - return $this->execute($query); - } - - public function executeTruncate($truncate) { - $table = $truncate->getTable(); - return $this->execute("TRUNCATE \"$table\""); - } - - public function executeUpdate($update) { - $params = array(); - $table = $update->getTable(); - - $valueStr = array(); - foreach($update->getValues() as $key => $val) { - $valueStr[] = "$key=" . $this->addValue($val, $params); - } - $valueStr = implode(",", $valueStr); - - $conditions = $update->getConditions(); - if (!empty($conditions)) { - $condition = " WHERE " . $this->buildCondition($conditions, $params); - } else { - $condition = ""; - } - - $query = "UPDATE \"$table\" SET $valueStr$condition"; - return $this->execute($query, $params); - } - // UGLY but.. what should i do? private function createEnum($enumColumn) { $typeName = $enumColumn->getName(); @@ -342,29 +259,6 @@ class PostgreSQL extends SQL { return "$columnName $type$notNull$defaultValue"; } - protected function getConstraintDefinition($constraint) { - $columnName = $this->columnName($constraint->getColumnName()); - if ($constraint instanceof PrimaryKey) { - return "PRIMARY KEY ($columnName)"; - } else if ($constraint instanceof Unique) { - return "UNIQUE ($columnName)"; - } else if ($constraint instanceof ForeignKey) { - $refTable = $this->tableName($constraint->getReferencedTable()); - $refColumn = $this->columnName($constraint->getReferencedColumn()); - $strategy = $constraint->onDelete(); - $code = "FOREIGN KEY ($columnName) REFERENCES $refTable ($refColumn)"; - if ($strategy instanceof SetDefaultStrategy) { - $code .= " ON DELETE SET DEFAULT"; - } else if($strategy instanceof SetNullStrategy) { - $code .= " ON DELETE SET NULL"; - } else if($strategy instanceof CascadeStrategy) { - $code .= " ON DELETE CASCADE"; - } - - return $code; - } - } - protected function getValueDefinition($value) { if (is_numeric($value)) { return $value; diff --git a/core/Driver/SQL/Query/Select.class.php b/core/Driver/SQL/Query/Select.class.php index 4616393..5f2b4c0 100644 --- a/core/Driver/SQL/Query/Select.class.php +++ b/core/Driver/SQL/Query/Select.class.php @@ -8,6 +8,10 @@ class Select extends Query { private $tables; private $conditions; private $joins; + private $orderColumns; + private $sortAscending; + private $limit; + private $offset; public function __construct($sql, ...$columns) { parent::__construct($sql); @@ -15,6 +19,10 @@ class Select extends Query { $this->tables = array(); $this->conditions = array(); $this->joins = array(); + $this->orderColumns = array(); + $this->limit = 0; + $this->offset = 0; + $this->sortAscending = true; } public function from(...$tables) { @@ -37,6 +45,31 @@ class Select extends Query { return $this; } + public function orderBy(...$columns) { + $this->orderColumns = $columns; + return $this; + } + + public function ascending() { + $this->ascending = true; + return $this; + } + + public function descending() { + $this->ascending = false; + return $this; + } + + public function limit($limit) { + $this->limit = $limit; + return $this; + } + + public function offset($offset) { + $this->offset = $offset; + return $this; + } + public function execute() { return $this->sql->executeSelect($this); } @@ -45,6 +78,11 @@ class Select extends Query { public function getTables() { return $this->tables; } public function getConditions() { return $this->conditions; } public function getJoins() { return $this->joins; } + public function isOrderedAscending() { return $this->ascending; } + public function getOrderBy() { return $this->orderColumns; } + public function getLimit() { return $this->limit; } + public function getOffset() { return $this->offset; } + }; ?> diff --git a/core/Driver/SQL/SQL.class.php b/core/Driver/SQL/SQL.class.php index d00bda3..8a46120 100644 --- a/core/Driver/SQL/SQL.class.php +++ b/core/Driver/SQL/SQL.class.php @@ -2,6 +2,10 @@ namespace Driver\SQL; +use \Driver\SQL\Constraint\Unique; +use \Driver\SQL\Constraint\PrimaryKey; +use \Driver\SQL\Constraint\ForeignKey; + abstract class SQL { protected $lastError; @@ -11,7 +15,7 @@ abstract class SQL { public function __construct($connectionData) { $this->connection = NULL; - $this->lastError = 'Not connected'; + $this->lastError = 'Unknown Error'; $this->connectionData = $connectionData; $this->lastInsertId = 0; } @@ -60,8 +64,6 @@ abstract class SQL { public abstract function connect(); public abstract function disconnect(); - // TODO: pull code duplicates up - // Querybuilder public function executeCreateTable($createTable) { $tableName = $this->tableName($createTable->getTableName()); @@ -87,13 +89,111 @@ abstract class SQL { return $this->execute($query); } + // TODO pull this function up public abstract function executeInsert($query); - public abstract function executeSelect($query); - public abstract function executeDelete($query); - public abstract function executeTruncate($query); - public abstract function executeUpdate($query); + + public function executeSelect($select) { + + $columns = $this->columnName($select->getColumns()); + $tables = $select->getTables(); + $params = array(); + + if (!$tables) { + return "SELECT $columns"; + } + + $tables = $this->tableName($tables); + $where = $this->getWhereClause($select->getConditions(), $params); + + $joinStr = ""; + $joins = $select->getJoins(); + if (!empty($joins)) { + foreach($joins as $join) { + $type = $join->getType(); + $joinTable = $this->tableName($join->getTable()); + $columnA = $this->columnName($join->getColumnA()); + $columnB = $this->columnName($join->getColumnB()); + $joinStr .= " $type JOIN $joinTable ON $columnA=$columnB"; + } + } + + $orderBy = ""; + $orderColumns = $select->getOrderBy(); + if (!empty($orderColumns)) { + $orderBy = " ORDER BY " . $this->columnName($orderColumns); + $orderBy .= ($select->isOrderedAscending() ? " ASC" : " DESC"); + } + + $limit = ($select->getLimit() > 0 ? (" LIMIT " . $select->getLimit()) : ""); + $offset = ($select->getOffset() > 0 ? (" OFFSET " . $select->getOffset()) : ""); + $query = "SELECT $columns FROM $tables$joinStr$where$orderBy$limit$offset"; + return $this->execute($query, $params, true); + } + + public function executeDelete($delete) { + + $table = $this->tableName($delete->getTable()); + $where = $this->getWhereClause($delete->getConditions(), $params); + + $query = "DELETE FROM $table$where"; + return $this->execute($query); + } + + public function executeTruncate($truncate) { + return $this->execute("TRUNCATE " . $truncate->getTable()); + } + + public function executeUpdate($update) { + + $params = array(); + $table = $this->tableName($update->getTable()); + + $valueStr = array(); + foreach($update->getValues() as $key => $val) { + $valueStr[] = "$key=" . $this->addValue($val, $params); + } + $valueStr = implode(",", $valueStr); + + $where = $this->getWhereClause($update->getConditions(), $params); + $query = "UPDATE $table SET $valueStr$where"; + return $this->execute($query, $params); + } + + protected function getWhereClause($conditions, &$params) { + if (!$conditions) { + return ""; + } else { + return " WHERE " . $this->buildCondition($conditions, $params); + } + } + protected abstract function getColumnDefinition($column); - protected abstract function getConstraintDefinition($constraint); + + public function getConstraintDefinition($constraint) { + $columnName = $this->columnName($constraint->getColumnName()); + if ($constraint instanceof PrimaryKey) { + return "PRIMARY KEY ($columnName)"; + } else if ($constraint instanceof Unique) { + return "UNIQUE ($columnName)"; + } else if ($constraint instanceof ForeignKey) { + $refTable = $this->tableName($constraint->getReferencedTable()); + $refColumn = $this->columnName($constraint->getReferencedColumn()); + $strategy = $constraint->onDelete(); + $code = "FOREIGN KEY ($columnName) REFERENCES $refTable ($refColumn)"; + if ($strategy instanceof SetDefaultStrategy) { + $code .= " ON DELETE SET DEFAULT"; + } else if($strategy instanceof SetNullStrategy) { + $code .= " ON DELETE SET NULL"; + } else if($strategy instanceof CascadeStrategy) { + $code .= " ON DELETE CASCADE"; + } + + return $code; + } else { + $this->lastError = "Unsupported constraint type: " . get_class($strategy); + } + } + protected abstract function getValueDefinition($val); protected abstract function addValue($val, &$params);