summaryrefslogtreecommitdiffstats
path: root/modules/database/classes
diff options
context:
space:
mode:
Diffstat (limited to 'modules/database/classes')
-rw-r--r--modules/database/classes/database/query.php758
-rw-r--r--modules/database/classes/driver/mysql/query.php396
2 files changed, 577 insertions, 577 deletions
diff --git a/modules/database/classes/database/query.php b/modules/database/classes/database/query.php
index 3338986..5a151bd 100644
--- a/modules/database/classes/database/query.php
+++ b/modules/database/classes/database/query.php
@@ -1,380 +1,380 @@
-<?php
-
-/**
- * Query builder. It allows building queries by using methods to set specific query parameters.
- * Database drivers extend this class so that they can generate database specific queries.
- * The idea is to provide a database agnostic interface to query writing.
- *
- * @method mixed table(string $table = null) Set table to query.
- * Without arguments returns current table, returns self otherwise.
- *
- * @method mixed data(array $data = null) Set data for insert or update queries.
- * Without arguments returns current data, returns self otherwise.
- *
- * @method mixed limit(int $limit = null) Set number of rows to return.
- * Without arguments returns current limit, returns self otherwise.
- *
- * @method mixed offset(string $offset = null) Set the offset for the first row in result.
- * Without arguments returns current offset, returns self otherwise.
- *
- * @method mixed groupby(string $groupby = null) A column to group rows by for aggregator functions.
- * Without arguments returns current groupby argument, returns self otherwise.
- *
- * @method mixed type(string $type = null) Set query type. Available types: select, update, insert, delete, count.
- * Without arguments returns current type argument, returns self otherwise.
- */
-abstract class Query_Database {
-
- /**
- * Array of conditions that rows must meet
- * @var array
- * @access protected
- */
- protected $_conditions = array();
-
- /**
- * Table to query
- * @var unknown
- * @access protected
- */
- protected $_table;
-
- /**
- * Fields to return in the query
- * @var array
- * @access protected
- */
- protected $_fields;
-
- /**
- * Data for row insertion or update
- * @var unknown
- * @access protected
- */
- protected $_data;
-
- /**
- * Query type. Available types: select, update, insert, delete, count
- * @var string
- * @access protected
- */
- protected $_type;
-
- /**
- * Parameters for tables to join
- * @var array
- * @access protected
- */
- protected $_joins = array();
-
- /**
- * Number of rows to return
- * @var int
- * @access protected
- */
- protected $_limit;
-
- /**
- * Offset of the first row
- * @var int
- * @access protected
- */
- protected $_offset;
-
- /**
- * Columns and directions to order by
- * @var array
- * @access protected
- */
- protected $_orderby = array();
-
- /**
- * Database connection
- * @var DB
- * @access protected
- */
- protected $_db;
-
- /**
- * Conditions for aggregator functions
- * @var array
- * @access protected
- */
- protected $_having=array();
-
- /**
- * Column to group by for aggregator functions
- * @var string
- * @access protected
- */
- protected $_groupby;
-
- /**
- * Last alias used on the table
- * @var string
- * @access protected
- */
- protected $alias = null;
-
- /**
- * Methods and type of value they allow that are available via __call
- * @var array
- * @access protected
- */
- protected $methods = array('table' => 'string','data' => 'array','limit' => 'integer','offset' => 'integer','groupby' => 'string','type' => 'string');
-
- /**
- * Generates a query in format that can be executed on current database implementation
- *
- * @access public
- */
- public abstract function query();
-
- /**
- * Creates a new query
- *
- * @param DB $db Database connection
- * @param string $type Query type. Available types: select, update, insert, delete, count
- * @return void
- * @access public
- */
- public function __construct($db, $type) {
- $this->_db=$db;
- $this->_type=$type;
- }
-
- /**
- * Sets fields to be queried from the database
- *
- * @param mixed A single field or an array of them
- * @return mixed If no parameters are passed returns current array of fields,
- * otherwise returns self.
- * @access public
- */
- public function fields() {
- $p = func_get_args();
- if (empty($p)) {
- return $this->_fields;
- }elseif (is_array($p[0])) {
- $this->_fields=$p[0];
- }else {
- $this->_fields=array($p[0]);
- }
- return $this;
- }
-
- /**
- * Magic methods to create methods for all generic query parts
- *
- * @param string $method Name of the method to call
- * @param array $args Array of parameters
- * @return mixed If no arguments are passed returns the current value of the property,
- * otherwise returns self.
- * @access public
- * @throws Exception If method doesn't exist
- * @throws Exception If value is of incorrect type
- * @see $methods
- */
- public function __call($method, $args) {
-
- if (isset($this->methods[$method])) {
-
- $property = '_'.$method;
-
- if (empty($args))
- return $this->$property;
- $val = $args[0];
- if (is_int($val))
- $val=(int) $val;
- if (gettype($val) != $this->methods[$method])
- throw new Exception("Method '{$method}' only accepts values of type: '{$this->methods[$method]}', '{$val}' was passed");
- $this->$property = $val;
- return $this;
- }
- throw new Exception("Method '{$method}' doesn't exist.");
- }
-
- /**
- * Executes the query
- *
- * @return object Executes current query on its database connection
- * @access public
- * @see DB
- */
- public function execute() {
- $query = $this->query();
- $result = $this->_db->execute($query[0], $query[1]);
- if ($this->_type == 'count')
- return $result->current()->count;
- return $result;
- }
-
- /**
- * Adds a joined table to the query.
- *
- * @param string $table Table to join
- * @param array $conds Conditions to join tables on, same behavior as with where() method
- * @param string $type Type of join. Defaults to 'left'
- * @return Query_Database Returns self
- * @access public
- * @see where()
- */
- public function join($table,$conds,$type='left'){
- $this->_joins[] = array($table, $type, $this->get_condition_part($conds));
- return $this;
- }
-
- /**
- * Sets conditions for aggregate functions, same behavior as with where() method
- *
- * @return Query_Database Returns self
- * @access public
- * @see where()
- */
- public function having() {
- $p = func_get_args();
- $cond = $this->get_condition_part($p);
- $this->_having = array_merge($this->_having,$cond);
- return $this;
- }
-
- /**
- * Adds a column to ordering parameters.
- *
- * @param string $column Column to order by
- * @param string $dir Ordering direction.
- * @return Query_Database Returns self
- * @throws Exception If ordering direction isn't DESC or ASC
- * @access public
- */
- public function orderby($column, $dir) {
- $dir=strtoupper($dir);
- if ($dir != 'DESC' && $dir != 'ASC')
- throw new Exception("Invalid sorting direction {$dir} specified");
- $this->_orderby[]=array($column,$dir);
- return $this;
- }
-
- /**
- * Sets conditions for the query.
- * Can be called in many ways, examples:
- * Shorthand equals condition:
- * <code>
- * $q->where('name', 'Tinkerbell')
- * </code>
- * Conditions with operator:
- * <code>
- * $q->where('id', '>', 3)
- * </code>
- * OR logic:
- * <code>
- * $q->where('or', array('name', 'Tinkerbell'))
- * </code>
- * OR logic with operator
- * <code>
- * ->where('or', array('id', '>', 3))
- * </code>
- * Arrays represent brackets. e.g
- * <code>
- * $q->where('name', 'Tinkerbell')
- * ->where('or', array(
- * array('id', '>', 7),
- * array('id', '<', 15)
- * );
- * //Will produce "WHERE `name`='Tinkerbell' OR (`id` > 7 AND `id` < 15)"
- * </code>
- * Multiple calls to where() append new conditions to previous ones
- *
- * @param mixed $column Column name, logic parameter 'OR' or 'AND' or an array of conditions
- * @param mixed $operator Condition value, operator or an array of parameters
- * @param mixed $val Condition value
- *
- * @return Query_Database Returns self
- * @access public
- */
- public function where() {
- $p = func_get_args();
- $cond = $this->get_condition_part($p);
- $this->_conditions= array_merge($this->_conditions,$cond);
-
- return $this;
- }
-
- /**
- * Recursively builds condition arrays for methods like where(), having()
- *
- * @param array $p Parameters passed to the method
- * @return array Array in condition format
- * @access private
- * @throws Exception If condition format is incorrect
- */
- private function get_condition_part($p) {
- if (is_string($p[0]) && (strtolower($p[0]) == 'or'||strtolower($p[0]) == 'and') && isset($p[1]) && is_array($p[1])) {
- $cond = $this->get_condition_part($p[1]);
- $cond['logic'] = strtolower($p[0]);
- return $cond;
- }
-
- if (is_array($p[0])) {
- if (count($p) == 1)
- return $this->get_condition_part($p[0]);
- $conds = array();
- foreach($p as $q) {
- $conds[]=$this->get_condition_part($q);
- }
- if (count($conds) == 1)
- return $conds;
- return array('logic'=>'and','conditions'=>$conds);
- }
-
-
- if ((is_string($p[0]) || get_class($p[0]) == 'Expression_Database') && isset($p[1])) {
- if (strpos($p[0], '.') === false)
- $p[0]=$this->lastAlias().'.'.$p[0];
- return array(
- 'logic' => 'and',
- 'conditions'=>array(
- 'field' => $p[0],
- 'operator' => isset($p[2])?$p[1]:'=',
- 'value' => isset($p[2])?$p[2]:$p[1]
- )
- );
- }
-
- throw new Exception('Incorrect conditional statement passed');
- }
-
- /**
- * Gets last generated alias
- *
- * @return string Last generated alias. If no alias were created returns table name.
- * @access public
- */
- public function lastAlias() {
- if ($this->alias === null)
- return $this->_table;
- return 'a'.$this->alias;
- }
-
- /**
- * Generates new alias. Useful for dynamically adding aliases to joins.
- * Alias is just a letter 'a' with an incremented number.
- *
- * @return string New alias
- * @access public
- */
- public function addAlias() {
- if ($this->alias === null){
- $this->alias = 0;
- }else {
- $this->alias++;
- }
- return $this->lastAlias();
- }
-
-
-
-
-
-
+<?php
+
+/**
+ * Query builder. It allows building queries by using methods to set specific query parameters.
+ * Database drivers extend this class so that they can generate database specific queries.
+ * The idea is to provide a database agnostic interface to query writing.
+ *
+ * @method mixed table(string $table = null) Set table to query.
+ * Without arguments returns current table, returns self otherwise.
+ *
+ * @method mixed data(array $data = null) Set data for insert or update queries.
+ * Without arguments returns current data, returns self otherwise.
+ *
+ * @method mixed limit(int $limit = null) Set number of rows to return.
+ * Without arguments returns current limit, returns self otherwise.
+ *
+ * @method mixed offset(string $offset = null) Set the offset for the first row in result.
+ * Without arguments returns current offset, returns self otherwise.
+ *
+ * @method mixed group_by(string $group_by = null) A column to group rows by for aggregator functions.
+ * Without arguments returns current group_by argument, returns self otherwise.
+ *
+ * @method mixed type(string $type = null) Set query type. Available types: select, update, insert, delete, count.
+ * Without arguments returns current type argument, returns self otherwise.
+ */
+abstract class Query_Database {
+
+ /**
+ * Array of conditions that rows must meet
+ * @var array
+ * @access protected
+ */
+ protected $_conditions = array();
+
+ /**
+ * Table to query
+ * @var unknown
+ * @access protected
+ */
+ protected $_table;
+
+ /**
+ * Fields to return in the query
+ * @var array
+ * @access protected
+ */
+ protected $_fields;
+
+ /**
+ * Data for row insertion or update
+ * @var unknown
+ * @access protected
+ */
+ protected $_data;
+
+ /**
+ * Query type. Available types: select, update, insert, delete, count
+ * @var string
+ * @access protected
+ */
+ protected $_type;
+
+ /**
+ * Parameters for tables to join
+ * @var array
+ * @access protected
+ */
+ protected $_joins = array();
+
+ /**
+ * Number of rows to return
+ * @var int
+ * @access protected
+ */
+ protected $_limit;
+
+ /**
+ * Offset of the first row
+ * @var int
+ * @access protected
+ */
+ protected $_offset;
+
+ /**
+ * Columns and directions to order by
+ * @var array
+ * @access protected
+ */
+ protected $_orderby = array();
+
+ /**
+ * Database connection
+ * @var DB
+ * @access protected
+ */
+ protected $_db;
+
+ /**
+ * Conditions for aggregator functions
+ * @var array
+ * @access protected
+ */
+ protected $_having=array();
+
+ /**
+ * Column to group by for aggregator functions
+ * @var string
+ * @access protected
+ */
+ protected $_group_by;
+
+ /**
+ * Last alias used on the table
+ * @var string
+ * @access protected
+ */
+ protected $alias = null;
+
+ /**
+ * Methods and type of value they allow that are available via __call
+ * @var array
+ * @access protected
+ */
+ protected $methods = array('table' => 'string','data' => 'array','limit' => 'integer','offset' => 'integer','group_by' => 'string','type' => 'string');
+
+ /**
+ * Generates a query in format that can be executed on current database implementation
+ *
+ * @access public
+ */
+ public abstract function query();
+
+ /**
+ * Creates a new query
+ *
+ * @param DB $db Database connection
+ * @param string $type Query type. Available types: select, update, insert, delete, count
+ * @return void
+ * @access public
+ */
+ public function __construct($db, $type) {
+ $this->_db=$db;
+ $this->_type=$type;
+ }
+
+ /**
+ * Sets fields to be queried from the database
+ *
+ * @param mixed A single field or an array of them
+ * @return mixed If no parameters are passed returns current array of fields,
+ * otherwise returns self.
+ * @access public
+ */
+ public function fields() {
+ $p = func_get_args();
+ if (empty($p)) {
+ return $this->_fields;
+ }elseif (is_array($p[0])) {
+ $this->_fields=$p[0];
+ }else {
+ $this->_fields=array($p[0]);
+ }
+ return $this;
+ }
+
+ /**
+ * Magic methods to create methods for all generic query parts
+ *
+ * @param string $method Name of the method to call
+ * @param array $args Array of parameters
+ * @return mixed If no arguments are passed returns the current value of the property,
+ * otherwise returns self.
+ * @access public
+ * @throws Exception If method doesn't exist
+ * @throws Exception If value is of incorrect type
+ * @see $methods
+ */
+ public function __call($method, $args) {
+
+ if (isset($this->methods[$method])) {
+
+ $property = '_'.$method;
+
+ if (empty($args))
+ return $this->$property;
+ $val = $args[0];
+ if (is_int($val))
+ $val=(int) $val;
+ if (gettype($val) != $this->methods[$method])
+ throw new Exception("Method '{$method}' only accepts values of type: '{$this->methods[$method]}', '{$val}' was passed");
+ $this->$property = $val;
+ return $this;
+ }
+ throw new Exception("Method '{$method}' doesn't exist.");
+ }
+
+ /**
+ * Executes the query
+ *
+ * @return object Executes current query on its database connection
+ * @access public
+ * @see DB
+ */
+ public function execute() {
+ $query = $this->query();
+ $result = $this->_db->execute($query[0], $query[1]);
+ if ($this->_type == 'count')
+ return $result->current()->count;
+ return $result;
+ }
+
+ /**
+ * Adds a joined table to the query.
+ *
+ * @param string $table Table to join
+ * @param array $conds Conditions to join tables on, same behavior as with where() method
+ * @param string $type Type of join. Defaults to 'left'
+ * @return Query_Database Returns self
+ * @access public
+ * @see where()
+ */
+ public function join($table,$conds,$type='left'){
+ $this->_joins[] = array($table, $type, $this->get_condition_part($conds));
+ return $this;
+ }
+
+ /**
+ * Sets conditions for aggregate functions, same behavior as with where() method
+ *
+ * @return Query_Database Returns self
+ * @access public
+ * @see where()
+ */
+ public function having() {
+ $p = func_get_args();
+ $cond = $this->get_condition_part($p);
+ $this->_having = array_merge($this->_having,$cond);
+ return $this;
+ }
+
+ /**
+ * Adds a column to ordering parameters.
+ *
+ * @param string $column Column to order by
+ * @param string $dir Ordering direction.
+ * @return Query_Database Returns self
+ * @throws Exception If ordering direction isn't DESC or ASC
+ * @access public
+ */
+ public function orderby($column, $dir) {
+ $dir=strtoupper($dir);
+ if ($dir != 'DESC' && $dir != 'ASC')
+ throw new Exception("Invalid sorting direction {$dir} specified");
+ $this->_orderby[]=array($column,$dir);
+ return $this;
+ }
+
+ /**
+ * Sets conditions for the query.
+ * Can be called in many ways, examples:
+ * Shorthand equals condition:
+ * <code>
+ * $q->where('name', 'Tinkerbell')
+ * </code>
+ * Conditions with operator:
+ * <code>
+ * $q->where('id', '>', 3)
+ * </code>
+ * OR logic:
+ * <code>
+ * $q->where('or', array('name', 'Tinkerbell'))
+ * </code>
+ * OR logic with operator
+ * <code>
+ * ->where('or', array('id', '>', 3))
+ * </code>
+ * Arrays represent brackets. e.g
+ * <code>
+ * $q->where('name', 'Tinkerbell')
+ * ->where('or', array(
+ * array('id', '>', 7),
+ * array('id', '<', 15)
+ * );
+ * //Will produce "WHERE `name`='Tinkerbell' OR (`id` > 7 AND `id` < 15)"
+ * </code>
+ * Multiple calls to where() append new conditions to previous ones
+ *
+ * @param mixed $column Column name, logic parameter 'OR' or 'AND' or an array of conditions
+ * @param mixed $operator Condition value, operator or an array of parameters
+ * @param mixed $val Condition value
+ *
+ * @return Query_Database Returns self
+ * @access public
+ */
+ public function where() {
+ $p = func_get_args();
+ $cond = $this->get_condition_part($p);
+ $this->_conditions= array_merge($this->_conditions,$cond);
+
+ return $this;
+ }
+
+ /**
+ * Recursively builds condition arrays for methods like where(), having()
+ *
+ * @param array $p Parameters passed to the method
+ * @return array Array in condition format
+ * @access private
+ * @throws Exception If condition format is incorrect
+ */
+ private function get_condition_part($p) {
+ if (is_string($p[0]) && (strtolower($p[0]) == 'or'||strtolower($p[0]) == 'and') && isset($p[1]) && is_array($p[1])) {
+ $cond = $this->get_condition_part($p[1]);
+ $cond['logic'] = strtolower($p[0]);
+ return $cond;
+ }
+
+ if (is_array($p[0])) {
+ if (count($p) == 1)
+ return $this->get_condition_part($p[0]);
+ $conds = array();
+ foreach($p as $q) {
+ $conds[]=$this->get_condition_part($q);
+ }
+ if (count($conds) == 1)
+ return $conds;
+ return array('logic'=>'and','conditions'=>$conds);
+ }
+
+
+ if ((is_string($p[0]) || get_class($p[0]) == 'Expression_Database') && isset($p[1])) {
+ if (strpos($p[0], '.') === false)
+ $p[0]=$this->lastAlias().'.'.$p[0];
+ return array(
+ 'logic' => 'and',
+ 'conditions'=>array(
+ 'field' => $p[0],
+ 'operator' => isset($p[2])?$p[1]:'=',
+ 'value' => isset($p[2])?$p[2]:$p[1]
+ )
+ );
+ }
+
+ throw new Exception('Incorrect conditional statement passed');
+ }
+
+ /**
+ * Gets last generated alias
+ *
+ * @return string Last generated alias. If no alias were created returns table name.
+ * @access public
+ */
+ public function lastAlias() {
+ if ($this->alias === null)
+ return $this->_table;
+ return 'a'.$this->alias;
+ }
+
+ /**
+ * Generates new alias. Useful for dynamically adding aliases to joins.
+ * Alias is just a letter 'a' with an incremented number.
+ *
+ * @return string New alias
+ * @access public
+ */
+ public function addAlias() {
+ if ($this->alias === null){
+ $this->alias = 0;
+ }else {
+ $this->alias++;
+ }
+ return $this->lastAlias();
+ }
+
+
+
+
+
+
} \ No newline at end of file
diff --git a/modules/database/classes/driver/mysql/query.php b/modules/database/classes/driver/mysql/query.php
index f800b20..d2767b9 100644
--- a/modules/database/classes/driver/mysql/query.php
+++ b/modules/database/classes/driver/mysql/query.php
@@ -1,199 +1,199 @@
-<?php
-
-/**
- * Mysqli implementation of the database Query
- */
-class Query_Mysql_Driver extends Query_Database{
-
- /**
- * If a string is passed escapes a field by enclosing it in `` quotes.
- * If you pass an Expression_Database object the value will be inserted into the query unescaped
- *
- * @param mixed $field Field to be escaped or an Expression_Database object
- * if the field must not be escaped
- * @return string Escaped field representation
- * @access public
- * @see Expression_Database
- */
- public function escape_field($field) {
- if (is_object($field) && get_class($field) == 'Expression_Database')
- return $field->value.' ';
- $field = explode('.', $field);
- if (count($field) == 1)
- array_unshift($field,$this->lastAlias());
- $str = '`'.$field[0].'`.';
- if (trim($field[1]) == '*')
- return $str.'* ';
- return $str."`{$field[1]}` ";
- }
-
- /**
- * Replaces the value with ? and appends it to the parameters array
- * If you pass an Expression_Database object the value will be inserted into the query unescaped
- * @param mixed $val Value to be escaped or an Expression_Database object
- * if the value must not be escaped
- * @param array &$params Reference to parameters array
- * @return string Escaped value representation
- * @access public
- */
- public function escape_value($val,&$params) {
- if (is_object($val) && get_class($val) == 'Expression_Database')
- return $val->value.' ';
- $params[] = $val;
- return '? ';
- }
-
- /**
- * Builds a query and fills the $params array with parameter values
- *
- * @return array An array with a prepared query string and an array of parameters
- * @access public
- */
- public function query() {
-
- $query = '';
- $params = array();
- if ($this->_type == 'insert') {
- $query.= "INSERT INTO `{$this->_table}`";
- $columns = '';
- $values = '';
- $first = true;
- foreach($this->_data as $key => $val) {
- if (!$first) {
- $values.= ',';
- $columns.= ',';
- }else {
- $first=false;
- }
- $columns.= "`{$key}` ";
- $values.=$this->escape_value($val,$params);
- }
- $query.= "({$columns}) VALUES({$values})";
- }else{
- if ($this->_type == 'select'){
- $query.= "SELECT ";
- if($this->_fields==null){
- $query.= "* ";
- }else{
- $first = true;
- foreach($this->_fields as $f) {
- if (!$first) {
- $query.=", ";
- }else {
- $first = false;
- }
- $query.="{$this->escape_field($f)} ";
- }
- }
- $query.= "FROM `{$this->_table}` ";
- }
- if ($this->_type == 'count') {
- $query.= "SELECT COUNT(*) as `count` FROM `{$this->_table}` ";
- }
- if($this->_type=='delete')
- $query.= "DELETE FROM `{$this->_table}` ";
- if($this->_type=='update'){
- $query.= "UPDATE `{$this->_table}` SET ";
- $first = true;
- foreach($this->_data as $key=>$val){
- if (!$first) {
- $query.=',';
- }else {
- $first=false;
- }
- $query.= "`{$key}`=".$this->escape_value($val,$params);
- }
- }
-
- foreach($this->_joins as $join) {
- $table = $join[0];
- if (is_array($table)){
- $table = "`{$table[0]}` as `{$table[1]}`";
- }else {
- $table="`{$table}`";
- }
- $query.= strtoupper($join[1])." JOIN {$table} ON ".$this->get_condition_query($join[2],$params,true,true);
- }
-
- if (!empty($this->_conditions)) {
- $query.="WHERE ".$this->get_condition_query($this->_conditions,$params,true);
- }
- if (($this->_type == 'select' || $this->_type == 'count') && $this->_groupby!=null) {
- $query.="GROUP BY ".$this->escape_field($this->_groupby);
- }
- if (($this->_type == 'select' || $this->_type == 'count') && !empty($this->_having)) {
- $query.="HAVING ".$this->get_condition_query($this->_having,$params,true);
- }
-
- if ($this->_type == 'select' && !empty($this->_orderby)) {
- $query.="ORDER BY ";
- $first = true;
- foreach($this->_orderby as $order) {
- if (!$first) {
- $query.=',';
- }else {
- $first=false;
- }
- $query.= $this->escape_field($order[0]);
- if (isset($order[1])) {
- $dir = strtoupper($order[1]);
- $query.=$dir." ";
- }
- }
- }
- if($this->_type != 'count'){
- if ($this->_limit != null)
- $query.= "LIMIT {$this->_limit} ";
- if ($this->_offset != null)
- $query.= "OFFSET {$this->_offset} ";
- }
-
- }
-
- return array($query,$params);
- }
-
- /**
- * Recursively parses conditions array into a query string
- *
- * @param array $p Element of the cobditions array
- * @param array &$params Reference to parameters array
- * @param boolean $skip_first_operator Flag to skip the first logical operator in a query
- * to prevent AND or OR to be at the beginning of the query
- * @param boolean $value_is_field Flag if the the value in the logical operations should
- * be treated as a field. E.g. for joins where the fields are
- * compared between themselves and not with actual values
- * @return string String representation of the conditions
- * @access public
- * @throws Exception If condition cannot be parsed
- */
- public function get_condition_query($p,&$params,$skip_first_operator,$value_is_field=false) {
- if (isset($p['field'])) {
- if ($value_is_field){
- $param = $this->escape_field($p['value']);
- }else {
- $param = $this->escape_value($p['value'],$params);
- }
- return $this->escape_field($p['field']).' '.$p['operator'].' '.$param;
- }
- if (isset($p['logic'])) {
- return ($skip_first_operator?'':strtoupper($p['logic'])).' '
- .$this->get_condition_query($p['conditions'],$params,false,$value_is_field);
- }
-
- $conds = '';
- $skip=$skip_first_operator||(count($p) > 1);
- foreach($p as $q) {
- $conds.=$this->get_condition_query($q,$params,$skip,$value_is_field);
- $skip=false;
- }
- if (count($p) > 1 && !$skip_first_operator)
- return "( ".$conds." ) ";
- return $conds;
-
- throw new Exception("Cannot parse condition:\n".var_export($p,true));
- }
-
-
-
+<?php
+
+/**
+ * Mysqli implementation of the database Query
+ */
+class Query_Mysql_Driver extends Query_Database{
+
+ /**
+ * If a string is passed escapes a field by enclosing it in `` quotes.
+ * If you pass an Expression_Database object the value will be inserted into the query unescaped
+ *
+ * @param mixed $field Field to be escaped or an Expression_Database object
+ * if the field must not be escaped
+ * @return string Escaped field representation
+ * @access public
+ * @see Expression_Database
+ */
+ public function escape_field($field) {
+ if (is_object($field) && get_class($field) == 'Expression_Database')
+ return $field->value.' ';
+ $field = explode('.', $field);
+ if (count($field) == 1)
+ array_unshift($field,$this->lastAlias());
+ $str = '`'.$field[0].'`.';
+ if (trim($field[1]) == '*')
+ return $str.'* ';
+ return $str."`{$field[1]}` ";
+ }
+
+ /**
+ * Replaces the value with ? and appends it to the parameters array
+ * If you pass an Expression_Database object the value will be inserted into the query unescaped
+ * @param mixed $val Value to be escaped or an Expression_Database object
+ * if the value must not be escaped
+ * @param array &$params Reference to parameters array
+ * @return string Escaped value representation
+ * @access public
+ */
+ public function escape_value($val,&$params) {
+ if (is_object($val) && get_class($val) == 'Expression_Database')
+ return $val->value.' ';
+ $params[] = $val;
+ return '? ';
+ }
+
+ /**
+ * Builds a query and fills the $params array with parameter values
+ *
+ * @return array An array with a prepared query string and an array of parameters
+ * @access public
+ */
+ public function query() {
+
+ $query = '';
+ $params = array();
+ if ($this->_type == 'insert') {
+ $query.= "INSERT INTO `{$this->_table}`";
+ $columns = '';
+ $values = '';
+ $first = true;
+ foreach($this->_data as $key => $val) {
+ if (!$first) {
+ $values.= ',';
+ $columns.= ',';
+ }else {
+ $first=false;
+ }
+ $columns.= "`{$key}` ";
+ $values.=$this->escape_value($val,$params);
+ }
+ $query.= "({$columns}) VALUES({$values})";
+ }else{
+ if ($this->_type == 'select'){
+ $query.= "SELECT ";
+ if($this->_fields==null){
+ $query.= "* ";
+ }else{
+ $first = true;
+ foreach($this->_fields as $f) {
+ if (!$first) {
+ $query.=", ";
+ }else {
+ $first = false;
+ }
+ $query.="{$this->escape_field($f)} ";
+ }
+ }
+ $query.= "FROM `{$this->_table}` ";
+ }
+ if ($this->_type == 'count') {
+ $query.= "SELECT COUNT(*) as `count` FROM `{$this->_table}` ";
+ }
+ if($this->_type=='delete')
+ $query.= "DELETE FROM `{$this->_table}` ";
+ if($this->_type=='update'){
+ $query.= "UPDATE `{$this->_table}` SET ";
+ $first = true;
+ foreach($this->_data as $key=>$val){
+ if (!$first) {
+ $query.=',';
+ }else {
+ $first=false;
+ }
+ $query.= "`{$key}`=".$this->escape_value($val,$params);
+ }
+ }
+
+ foreach($this->_joins as $join) {
+ $table = $join[0];
+ if (is_array($table)){
+ $table = "`{$table[0]}` as `{$table[1]}`";
+ }else {
+ $table="`{$table}`";
+ }
+ $query.= strtoupper($join[1])." JOIN {$table} ON ".$this->get_condition_query($join[2],$params,true,true);
+ }
+
+ if (!empty($this->_conditions)) {
+ $query.="WHERE ".$this->get_condition_query($this->_conditions,$params,true);
+ }
+ if (($this->_type == 'select' || $this->_type == 'count') && $this->_group_by!=null) {
+ $query.="GROUP BY ".$this->escape_field($this->_group_by);
+ }
+ if (($this->_type == 'select' || $this->_type == 'count') && !empty($this->_having)) {
+ $query.="HAVING ".$this->get_condition_query($this->_having,$params,true);
+ }
+
+ if ($this->_type == 'select' && !empty($this->_orderby)) {
+ $query.="ORDER BY ";
+ $first = true;
+ foreach($this->_orderby as $order) {
+ if (!$first) {
+ $query.=',';
+ }else {
+ $first=false;
+ }
+ $query.= $this->escape_field($order[0]);
+ if (isset($order[1])) {
+ $dir = strtoupper($order[1]);
+ $query.=$dir." ";
+ }
+ }
+ }
+ if($this->_type != 'count'){
+ if ($this->_limit != null)
+ $query.= "LIMIT {$this->_limit} ";
+ if ($this->_offset != null)
+ $query.= "OFFSET {$this->_offset} ";
+ }
+
+ }
+
+ return array($query,$params);
+ }
+
+ /**
+ * Recursively parses conditions array into a query string
+ *
+ * @param array $p Element of the cobditions array
+ * @param array &$params Reference to parameters array
+ * @param boolean $skip_first_operator Flag to skip the first logical operator in a query
+ * to prevent AND or OR to be at the beginning of the query
+ * @param boolean $value_is_field Flag if the the value in the logical operations should
+ * be treated as a field. E.g. for joins where the fields are
+ * compared between themselves and not with actual values
+ * @return string String representation of the conditions
+ * @access public
+ * @throws Exception If condition cannot be parsed
+ */
+ public function get_condition_query($p,&$params,$skip_first_operator,$value_is_field=false) {
+ if (isset($p['field'])) {
+ if ($value_is_field){
+ $param = $this->escape_field($p['value']);
+ }else {
+ $param = $this->escape_value($p['value'],$params);
+ }
+ return $this->escape_field($p['field']).' '.$p['operator'].' '.$param;
+ }
+ if (isset($p['logic'])) {
+ return ($skip_first_operator?'':strtoupper($p['logic'])).' '
+ .$this->get_condition_query($p['conditions'],$params,false,$value_is_field);
+ }
+
+ $conds = '';
+ $skip=$skip_first_operator||(count($p) > 1);
+ foreach($p as $q) {
+ $conds.=$this->get_condition_query($q,$params,$skip,$value_is_field);
+ $skip=false;
+ }
+ if (count($p) > 1 && !$skip_first_operator)
+ return "( ".$conds." ) ";
+ return $conds;
+
+ throw new Exception("Cannot parse condition:\n".var_export($p,true));
+ }
+
+
+
} \ No newline at end of file