From 824fe7fedf35ad989d0633108a63b369f1724c1e Mon Sep 17 00:00:00 2001
From: Nigel Kukard <nkukard@lbsd.net>
Date: Thu, 7 May 2009 06:20:55 +0000
Subject: [PATCH] * Added DBSelect family of functions

---
 webgui/include/db.php | 288 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 287 insertions(+), 1 deletion(-)

diff --git a/webgui/include/db.php b/webgui/include/db.php
index 1b948c4d..44f7d770 100644
--- a/webgui/include/db.php
+++ b/webgui/include/db.php
@@ -63,5 +63,291 @@ function connect_postfix_db()
 }
 
 
+## @fn DBSelect($query)
+# Return database selection results...
+#
+# @param query Query to run
+#
+# @return DBI statement handle, undef on error
+function DBSelect($query) 
+{
+	# Prepare query
+	if (!($sth = $db->query($query))) {
+		return NULL;
+	}
+
+	return $sth;
+}
+
+
+
+## @fn DBSelectNumResults($query)
+# Return how many results came up from the specific SELECT query
+#
+# @param query Query to perform, minus "SELECT COUNT(*) AS num_results"
+#
+# @return Number of results, undef on error
+function DBSelectNumResults($query) 
+{
+	# Prepare query
+	if (!($sth = $dbh->query("SELECT COUNT(*) AS num_results $query"))) {
+		return NULL;
+	}
+
+	# Grab row
+	$row = $sth->fetchObject();
+	if (!defined($row)) {
+		return NULL;
+	}
+
+	# Pull number
+	$num_results = $row->num_results;
+
+	return $num_results;
+}
+
+
+
+## @fn DBSelectSearch($query,$search,$filters,$sorts)
+# Select results from database and return the total number aswell
+#
+# @param query Base query
+#
+# @param search Search hash ref
+# @li Filter - Filter based on this...
+# [filter] => Array ( 
+#	[0] => Array ( 
+#		[field] => Name 
+#		[data] => Array ( 
+#			[type] => string 
+#			[value] => hi there 
+#		) 
+#	)
+# )
+# { 'data' => { 'comparison' => 'gt', 'value' => '5', 'type' => 'numeric' }, 'field' => 'ID' }
+# @li Start - Start item number, indexed from 0 onwards
+# @li Limit - Limit number of results
+# @li Sort - Sort by this item
+# @li SortDirection - Sort in this direction, either ASC or DESC 
+#
+# @param filters Filter hash ref
+# Hash:  'Column' -> 'Table.DBColumn'
+#
+# @param sorts Hash ref of valid sort criteria, indexed by what we get, pointing to the DB column in the query
+# Hash:  'Column' -> 'Table.DBColumn'
+#
+# @return Number of results, undef on error
+function DBSelectSearch($query,$search,$filters,$sorts) {
+	# Stuff we need to add to the SQL query
+	$where = array(); # Where clauses
+	$sqlWhere = "";
+	$sqlLimit = "";
+	$sqlOffset = "";
+	$sqlOrderBy = "";
+	$sqlOrderByDirection = "";
+
+	# Check if we're searching
+	if (isset($search)) {
+		# Check it is a hash
+		if (gettype($search) != "ARRAY") {
+			return array(NULL,"Parameter 'search' is not a hashtable");
+		}
+		# Check if we need to filter
+		if (isset($search['Filter'])) {
+			# We need filters in order to use filtering
+			if (!isset($filters)) {
+				return array(NULL,"Parameter 'search' element 'Filter' requires 'filters' to be defined");
+			}
+
+			# Check type of Filter
+			if (isset($search->{'Filter'}) != "ARRAY") {
+				return array(NULL,"Parameter 'search' element 'Filter' is of invalid type, it must be an ARRAY'");
+			}
+
+			# Loop with filters
+			foreach ($search->{'Filter'} as $item) {
+				$data = $item['data'];  # value, type, comparison
+				$field = $item['field'];
+				$column = $filters[$field];
+
+				# Check if field is in our allowed filters
+				if (!isset($filters[$field])) {
+					return array(NULL,"Parameter 'search' element 'Filter' has invalid field item '$field' according to 'filters'"); 
+				}
+				# Check data
+				if (!isset($data['type'])) {
+					return array(NULL,"Parameter 'search' element 'Filter' requires field data element 'type' for field '$field'"); 
+				}
+				if (!isset($data['value'])) {
+					return array(NULL,"Parameter 'search' element 'Filter' requires field data element 'value' for field '$field'"); 
+				}
+
+				# match =, LIKE, IN (
+				# matchEnd '' or )
+				$match;
+				$matchEnd = "";
+				# value is the $db->quote()'d value
+				$value;
+
+				# Check what type of comparison
+				if ($data['type'] == "boolean") {
+					$match = '=';
+					$value = $db->quote($data['value']);
+
+
+				} elseif ($data['type'] == "date") {
+
+					# The comparison type must be defined
+					if (!isset($data['comparison'])) {
+						return array(NULL,"Parameter 'search' element 'Filter' requires field data element 'comparison' for date field '$field'"); 
+					}
+
+					# Check comparison type
+					if ($data['comparison'] == "gt") {
+						$match = ">";
+
+					} elseif ($data['comparison'] == "lt") {
+						$match = "<";
+					
+					} elseif ($data['comparison'] == "eq") {
+						$match = "=";
+					}
+					# Convert to ISO format	
+					# FIXME
+#					$unixtime = str2time($data['value']);
+#					$date = DateTime->from_epoch( epoch => $unixtime );
+#					$value = $db->quote($date->ymd());
+
+
+				} elseif ($data['type'] == "list") {
+					# Quote all values
+					$valueList = array();
+					foreach (explode(",",$data['value']) as $i) {
+						array_push($valueList,$db->quote($i));
+					}
+
+					$match = "IN (";
+					# Join up 'xx','yy','zz'
+					$value = implode(',',$valueList);
+					$matchEnd = ")";
+
+
+				} elseif ($data['type'] == "numeric") {
+
+					# The comparison type must be defined
+					if (!isset($data['comparison'])) {
+						return array(NULL,"Parameter 'search' element 'Filter' requires field data element 'comparison' for numeric field '$field'"); 
+					}
+
+					# Check comparison type
+					if ($data['comparison'] == "gt") {
+						$match = ">";
+
+					} elseif ($data['comparison'] == "lt") {
+						$match = "<";
+					
+					} elseif ($data['comparison'] == "eq") {
+						$match = "=";
+					}
+					
+					$value = $db->quote($data['value']);
+
+
+				} elseif ($data['type'] == "string") {
+					$match = "LIKE";
+					$value = $db->quote("%".$data['value']."%");
+
+				}
+
+				# Add to list
+				array_push($where,"$column $match $value $matchEnd");
+			}
+
+			# Check if we have any WHERE clauses to add ...
+			if (count($where) > 0) {
+				# Check if we have WHERE clauses in the query
+				if (preg_match("/\sWHERE\s/i",$query)) {
+					# If so start off with AND
+					$sqlWhere .= "AND ";
+				} else {
+					$sqlWhere = "WHERE ";
+				}
+				$sqlWhere .= implode(" AND ",$where);
+			}
+		}
+
+		# Check if we starting at an OFFSET
+		if (isset($search['Start'])) {
+			# Check if Start is valid
+			if ($search['Start'] < 0) {
+				return array(NULL,"Parameter 'search' element 'Start' invalid value '".$search['Start']."'"); 
+			}
+
+			$sqlOffset = sprintf("OFFSET %i",$search['Start']);
+		}
+
+		# Check if results will be LIMIT'd
+		if (isset($search['Limit'])) {
+			# Check if Limit is valid
+			if ($search['Limit'] < 1) {
+				return array(NULL,"Parameter 'search' element 'Limit' invalid value '".$search['Limit']."'"); 
+			}
+
+			$sqlLimit = sprintf("LIMIT %i",$search['Limit']);
+		}
+
+		# Check if we going to be sorting
+		if (isset($search['Sort'])) {
+			# We need sorts in order to use sorting
+			if (!isset($sorts)) {
+				return array(NULL,"Parameter 'search' element 'Filter' requires 'filters' to be defined");
+			}
+
+			# Check if sort is defined
+			if (!isset($sorts->{$search['Sort']})) {
+				return array(NULL,"Parameter 'search' element 'Sort' invalid item '".$search['Sort']."' according to 'sorts'"); 
+			}
+
+			# Build ORDER By
+			$sqlOrderBy = "ORDER BY ".$sorts->{$search['Sort']};
+
+			# Check for sort ORDER
+			if (isset($search['SortDirection'])) {
+
+				# Check for valid directions
+				if (strtolower($search['SortDirection']) == "asc") {
+					$sqlOrderByDirection = "ASC";
+
+				} elseif (strtolower($search['SortDirection']) == "desc") {
+					$sqlOrderByDirection = "DESC";
+
+				} else {
+					return array(NULL,"Parameter 'search' element 'SortDirection' invalid value '".$search['SortDirection']."'"); 
+				}
+			}
+		}
+	}
+
+	# Select row count, pull out   "SELECT .... "  as we replace this in the NumResults query
+	$queryCount = $query; preg_replace("/^\s*SELECT\s.*\sFROM/is","FROM",$queryCount);
+	$numResults = DBSelectNumResults("$queryCount $sqlWhere");
+	if (!isset($numResults)) {
+		return NULL;
+	}
+
+	# Add Start, Limit, Sort, Direction
+	$sth = DBSelect("$query $sqlWhere $sqlOrderBy $sqlOrderByDirection $sqlLimit $sqlOffset");
+	if (!isset($sth)) {
+		return NULL;
+	}
+
+	return array($sth,$numResults);
+}
+
+
+
+# Connet to database when we load this file
+$db = connect_db();
+
+
 # vim: ts=4
-?>
-- 
GitLab