1<?php 2/** 3 * This file was originally written by Chris Petersen for several different open 4 * source projects. It is distrubuted under the GNU General Public License. 5 * I (Chris Petersen) have also granted a special LGPL license for this code to 6 * several companies I do work for on the condition that these companies will 7 * release any changes to this back to me and the open source community as GPL, 8 * thus continuing to improve the open source version of the library. If you 9 * would like to inquire about the status of this arrangement, please contact 10 * me personally. 11 * 12 * --- 13 * 14 * Query handler for MySQL 15 * 16 * @copyright Silicon Mechanics 17 * @license GPL 18 * 19 * @package MythWeb 20 * @subpackage Database 21 * 22 * @uses Database.php 23 * @uses Database_mysql.php 24 * @uses Database_Query.php 25 * 26 **/ 27 28/** 29 * The basic MySQL database query type. 30 **/ 31class Database_Query_mysql extends Database_Query { 32 33/** 34 * Executes the query that was previously passed to the constructor. 35 * 36 * @param mixed $arg Query arguments to escape and insert at ? placeholders in $query 37 * @param mixed ... Additional arguments 38 **/ 39 function execute() { 40 // Load the function arguments, minus the query itself, which we already extracted 41 $args = func_get_args(); 42 // Split out sub-arrays, etc.. 43 $args = Database::smart_args($args); 44 // Were enough arguments passed in? 45 if (count($args) != $this->num_args_needed) 46 trigger_error('Database_Query called with '.count($args)." arguments, but requires $this->num_args_needed.", E_USER_ERROR); 47 // Finish any previous statements 48 $this->finish(); 49 // Replace in the arguments 50 $this->last_query = ''; 51 foreach ($this->query as $part) { 52 $this->last_query .= $part; 53 if (count($args)) { 54 $arg = array_shift($args); 55 $this->last_query .= is_null($arg) 56 ? 'NULL' 57 : "'".mysqli_real_escape_string($arg)."'"; 58 } 59 } 60 // Perform the query 61 // If we don't have a valid connection, fataly error out. 62 if ($this->dbh === false) { 63 $this->db->error(); 64 trigger_error($this->db->error, E_USER_ERROR); 65 } 66 $this->sh = mysqli_query($this->last_query, $this->dbh); 67 68 // Cache these 69 if (is_bool($this->sh)) { 70 $this->insert_id = mysqli_insert_id($this->dbh); 71 $this->affected_rows = mysqli_affected_rows($this->dbh); 72 } 73 else { 74 $this->num_rows = mysqli_num_rows($this->sh); 75 } 76 77 if ($this->sh === false) { 78 if ($this->db->fatal_errors) 79 trigger_error('SQL Error: '.mysqli_error($this->dbh).' [#'.mysqli_errno($this->dbh).']', E_USER_ERROR); 80 else 81 $this->db->error(); 82 } 83 } 84 85/** 86 * The following routines basically replicate the mysql functions built into 87 * php. The only difference is that the resource handle gets passed-in 88 * automatically. eg. 89 * 90 * mysqli_fetch_row($result); -> $sh->fetch_row(); 91 * mysqli_affected_rows($dbh); -> $sh->affected_rows(); 92 **/ 93 94/** 95 * Fetch a single column 96 * @return mixed 97 **/ 98 function fetch_col() { 99 list($return) = mysqli_fetch_row($this->sh); 100 return $return; 101 } 102 103 function fetch_cols() { 104 $return = array(); 105 while ($col = $this->fetch_col()) 106 $return[] = $col; 107 return $return; 108 } 109 110/** 111 * Fetch a single row 112 * 113 * @link http://www.php.net/manual/en/function.mysql-fetch-row.php 114 * @return array 115 **/ 116 function fetch_row() { 117 return mysqli_fetch_row($this->sh); 118 } 119 120/** 121 * Fetch a single assoc row 122 * 123 * @link http://www.php.net/manual/en/function.mysql-fetch-assoc.php 124 * @return assoc 125 **/ 126 function fetch_assoc() { 127 return mysqli_fetch_assoc($this->sh); 128 } 129 130/** 131 * Fetch a single row as an array containing both numeric and assoc fields 132 * 133 * @link http://www.php.net/manual/en/function.mysql-fetch-array.php 134 * @return assoc 135 **/ 136 function fetch_array($result_type=MYSQL_BOTH) { 137 return mysqli_fetch_array($this->sh, $result_type); 138 } 139 140/** 141 * Fetch a single row as an object 142 * 143 * @link http://www.php.net/manual/en/function.mysql-fetch-object.php 144 * @return object 145 **/ 146 function fetch_object() { 147 return mysqli_fetch_object($this->sh); 148 } 149 150/** 151 * @link http://www.php.net/manual/en/function.mysql-data-seek.php 152 * @return bool 153 **/ 154 function data_seek($row_number) { 155 return mysqli_data_seek($this->sh, $row_number); 156 } 157 158/** 159 * @link http://www.php.net/manual/en/function.mysql-num-rows.php 160 * @return int 161 **/ 162 function num_rows() { 163 return $this->num_rows; 164 } 165 166/** 167 * @link http://www.php.net/manual/en/function.mysql-data-seek.php 168 * @return int 169 **/ 170 function affected_rows() { 171 return $this->affected_rows; 172 } 173 174/** 175 * @link http://www.php.net/manual/en/function.mysql-insert-id.php 176 * @return int 177 **/ 178 function insert_id() { 179 return $this->insert_id; 180 } 181 182/** 183 * For anal people like me who like to free up memory manually 184 **/ 185 function finish() { 186 if ($this->sh && is_resource($this->sh)) 187 mysqli_free_result($this->sh); 188 unset($this->sh); 189 } 190 191} 192