summaryrefslogtreecommitdiffstats
path: root/modules/database/classes/driver/pdo/query.php
diff options
context:
space:
mode:
Diffstat (limited to 'modules/database/classes/driver/pdo/query.php')
-rw-r--r--modules/database/classes/driver/pdo/query.php448
1 files changed, 257 insertions, 191 deletions
diff --git a/modules/database/classes/driver/pdo/query.php b/modules/database/classes/driver/pdo/query.php
index f23e28b..d37e459 100644
--- a/modules/database/classes/driver/pdo/query.php
+++ b/modules/database/classes/driver/pdo/query.php
@@ -4,22 +4,23 @@
* PDO implementation of the database Query
* @package Database
*/
-class Query_PDO_Driver extends Query_Database {
-
- /**
+class Query_PDO_Driver extends Query_Database
+{
+
+ /**
* Type of the database, e.g. mysql, pgsql etc.
* @var string
* @access public
*/
- protected $_db_type;
-
- /**
+ protected $_db_type;
+
+ /**
* Character to use for quoting fields
* @var string
* @access public
*/
- protected $_quote;
-
+ protected $_quote;
+
/**
* Creates a new query object, checks which driver we are using and set the character used for quoting
*
@@ -27,188 +28,247 @@ class Query_PDO_Driver extends Query_Database {
* @param string $type Query type. Available types: select, update, insert, delete, count
* @return void
* @access public
- * @see Query_Database::__construct()
+ * @see Query_Database::__construct()
*/
- public function __construct($db, $type) {
- parent::__construct($db, $type);
- $this->_db_type = $this->_db->db_type;
- $this->_quote=$this->_db_type=='mysql'?'`':'"';
- }
-
+ public function __construct($db, $type)
+ {
+ parent::__construct($db, $type);
+ $this->_db_type = $this->_db->db_type;
+ $this->_quote = $this->_db_type == 'mysql' ? '`' : '"';
+ }
+
/**
* Puts quotes around a string
*
* @param string $str String to be enclosed in quotes
* @return string String surrounded with quotes
* @access protected
- */
- protected function quote($str) {
- return $this->_quote.$str.$this->_quote;
- }
-
+ */
+ protected function quote($str)
+ {
+ return $this->_quote.$str.$this->_quote;
+ }
+
/**
* If a string is passed escapes a field by enclosing it in specified quotes.
- * If you pass an Expression_Database object the value will be inserted into the query unescaped
+ * 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
+ * if the field must not be escaped
* @return string Escaped field representation
* @access public
- * @see Expression_Database
+ * @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->last_alias());
- $str = $this->quote($field[0]).'.';
- if (trim($field[1]) == '*')
- return $str.'*';
- return $str.$this->quote($field[1]);
- }
-
+ 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->last_alias());
+ }
+ $str = $this->quote($field[0]).'.';
+ if (trim($field[1]) == '*')
+ {
+ return $str.'*';
+ }
+ return $str.$this->quote($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
+ * 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
+ * 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 '?';
- }
-
+ 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->quote($this->_table)} ";
- if (empty($this->_data) && $this->_db_type == 'pgsql'){
- $query.= "DEFAULT VALUES ";
- }else{
- $columns = '';
- $values = '';
- $first = true;
- foreach($this->_data as $key => $val) {
- if (!$first) {
- $values.= ', ';
- $columns.= ', ';
- }else {
- $first=false;
- }
- $columns.= $this->quote($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;
- }
- if(is_array($f)){
- $query.= "{$this->escape_field($f[0])} AS {$f[1]} ";
- }else {
- $query.= "{$this->escape_field($f)} ";
- }
- }
- }
- $query.= "FROM {$this->quote($this->_table)} ";
- }
- if ($this->_type == 'count') {
- $query.= "SELECT COUNT(*) as {$this->quote('count')} FROM {$this->quote($this->_table)} ";
- }
- if ($this->_type == 'delete') {
- if($this->_db_type!='sqlite'){
- $query.= "DELETE {$this->last_alias()}.* FROM {$this->quote($this->_table)} ";
- }else {
- if (!empty($this->_joins))
- throw new Exception("SQLite doesn't support deleting a table with JOIN in the query");
- $query.= "DELETE FROM {$this->quote($this->_table)} ";
- }
- }
- if($this->_type=='update'){
- $query.= "UPDATE {$this->quote($this->_table)} SET ";
- $first = true;
- foreach($this->_data as $key=>$val){
- if (!$first) {
- $query.=", ";
- }else {
- $first=false;
- }
- $query.= "{$this->quote($key)} = {$this->escape_value($val,$params)}";
- }
- $query.= " ";
- }
-
- foreach($this->_joins as $join) {
- $table = $join[0];
- if (is_array($table)){
- $table = "{$this->quote($table[0])} as {$this->quote($table[1])}";
- }else {
- $table="{$this->quote($table)}";
- }
- $query.= strtoupper($join[1])." JOIN {$table} ON {$this->get_condition_query($join[2],$params,true,true)} ";
- }
+ public function query()
+ {
+
+ $query = '';
+ $params = array();
+ if ($this->_type == 'insert')
+ {
+ $query.= "INSERT INTO {$this->quote($this->_table)} ";
+ if (empty($this->_data) && $this->_db_type == 'pgsql')
+ {
+ $query.= "DEFAULT VALUES ";
+ }
+ else
+ {
+ $columns = '';
+ $values = '';
+ $first = true;
+ foreach ($this->_data as $key => $val)
+ {
+ if (!$first)
+ {
+ $values .= ', ';
+ $columns .= ', ';
+ }
+ else
+ {
+ $first = false;
+ }
+ $columns .= $this->quote($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;
+ }
+ if (is_array($f))
+ {
+ $query .= "{$this->escape_field($f[0])} AS {$f[1]} ";
+ }
+ else
+ {
+ $query .= "{$this->escape_field($f)} ";
+ }
+ }
+ }
+ $query .= "FROM {$this->quote($this->_table)} ";
+ }
+ if ($this->_type == 'count')
+ {
+ $query .= "SELECT COUNT(*) as {$this->quote('count')} FROM {$this->quote($this->_table)} ";
+ }
+ if ($this->_type == 'delete')
+ {
+ if ($this->_db_type != 'sqlite')
+ {
+ $query .= "DELETE {$this->last_alias()}.* FROM {$this->quote($this->_table)} ";
+ }
+ else
+ {
+ if (!empty($this->_joins))
+ {
+ throw new Exception("SQLite doesn't support deleting a table with JOIN in the query");
+ }
+ $query .= "DELETE FROM {$this->quote($this->_table)} ";
+ }
+ }
+ if ($this->_type == 'update')
+ {
+ $query .= "UPDATE {$this->quote($this->_table)} SET ";
+ $first = true;
+ foreach ($this->_data as $key => $val)
+ {
+ if (!$first)
+ {
+ $query .= ", ";
+ }
+ else
+ {
+ $first = false;
+ }
+ $query .= "{$this->quote($key)} = {$this->escape_value($val, $params)}";
+ }
+ $query .= " ";
+ }
+
+ foreach ($this->_joins as $join)
+ {
+ $table = $join[0];
+ if (is_array($table))
+ {
+ $table = "{$this->quote($table[0])} as {$this->quote($table[1])}";
+ }
+ else
+ {
+ $table = "{$this->quote($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);
- }
+ 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
@@ -216,41 +276,47 @@ class Query_PDO_Driver extends Query_Database {
* @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
+ * 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
+ * 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));
- }
+ 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