diff options
author | Dracony <draconyster@gmail.com> | 2013-01-04 10:57:43 +0200 |
---|---|---|
committer | Dracony <draconyster@gmail.com> | 2013-01-04 10:57:43 +0200 |
commit | 6fac740b801bfdf36ec8079a34efa3e7c0a51db2 (patch) | |
tree | a85e7ad59ac4ac0d31281a3d7ecff9d74c2d8705 | |
parent | 7bea16124915f435427bd1e6a80bc517ffed4faf (diff) | |
download | PHPixie-6fac740b801bfdf36ec8079a34efa3e7c0a51db2.zip PHPixie-6fac740b801bfdf36ec8079a34efa3e7c0a51db2.tar.gz PHPixie-6fac740b801bfdf36ec8079a34efa3e7c0a51db2.tar.bz2 |
Changed groupby to group_by
-rw-r--r-- | modules/database/classes/database/query.php | 758 | ||||
-rw-r--r-- | modules/database/classes/driver/mysql/query.php | 396 |
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 |