3 /**********************************************************************
4 * Author: Justin Vincent (jv@jvmultimedia.com)
5 * Web...: http://twitter.com/justinvincent
7 * Desc..: PDO component (part of ezSQL databse abstraction library)
11 /**********************************************************************
12 * ezSQL error strings - PDO
15 global $ezsql_pdo_str;
17 $ezsql_pdo_str = array
19 1 => 'Require $dsn and $user and $password to create a connection'
22 /**********************************************************************
23 * ezSQL Database specific class - PDO
26 if ( ! class_exists ('PDO') ) die('<b>Fatal Error:</b> ezSQL_pdo requires PDO Lib to be compiled and or linked in to the PHP engine');
27 if ( ! class_exists ('ezSQLcore') ) die('<b>Fatal Error:</b> ezSQL_pdo requires ezSQLcore (ez_sql_core.php) to be included/loaded before it can be used');
29 class ezSQL_pdo extends ezSQLcore
35 var $rows_affected = false;
37 /**********************************************************************
38 * Constructor - allow the user to perform a qucik connect at the
39 * same time as initialising the ezSQL_pdo class
42 function __construct($dsn='', $user='', $password='', $ssl=array())
44 // Turn on track errors
45 ini_set('track_errors',1);
49 $this->connect($dsn, $user, $password);
53 /**********************************************************************
54 * Try to connect to database server
57 function connect($dsn='', $user='', $password='', $ssl=array())
59 global $ezsql_pdo_str; $return_val = false;
61 // Must have a dsn and user
62 if ( ! $dsn || ! $user )
64 $this->register_error($ezsql_pdo_str[1].' in '.__FILE__.' on line '.__LINE__);
65 $this->show_errors ? trigger_error($ezsql_pdo_str[1],E_USER_WARNING) : null;
68 // Establish PDO connection
73 $this->dbh = new PDO($dsn, $user, $password, $ssl);
77 $this->dbh = new PDO($dsn, $user, $password);
82 catch (PDOException $e)
84 $this->register_error($e->getMessage());
85 $this->show_errors ? trigger_error($e->getMessage(),E_USER_WARNING) : null;
91 /**********************************************************************
92 * In the case of PDO quick_connect is not really needed
93 * because std. connect already does what quick connect does -
94 * but for the sake of consistency it has been included
97 function quick_connect($dsn='', $user='', $password='', $ssl=array())
99 return $this->connect($dsn, $user, $password);
102 /**********************************************************************
103 * No real equivalent of mySQL select in PDO
104 * once again, function included for the sake of consistency
107 function select($dsn='', $user='', $password='', $ssl=array())
109 return $this->connect($dsn, $user, $password);
112 /**********************************************************************
113 * Format a string correctly for safe PDO insert
114 * (no mater if magic quotes are on or not)
117 function escape($str)
119 switch (gettype($str))
121 case 'string' : $str = addslashes(stripslashes($str));
123 case 'boolean' : $str = ($str === FALSE) ? 0 : 1;
125 default : $str = ($str === NULL) ? 'NULL' : $str;
132 /**********************************************************************
133 * Return specific system date syntax
134 * i.e. Oracle: SYSDATE Mysql: NOW()
142 /**********************************************************************
143 * Hooks into PDO error system and reports it to user
146 function catch_error()
148 $error_str = 'No error info';
150 $err_array = $this->dbh->errorInfo();
152 // Note: Ignoring error - bind or column index out of range
153 if ( isset($err_array[1]) && $err_array[1] != 25)
157 foreach ( $err_array as $entry )
159 $error_str .= $entry . ', ';
162 $error_str = substr($error_str,0,-2);
164 $this->register_error($error_str);
165 $this->show_errors ? trigger_error($error_str.' '.$this->last_query,E_USER_WARNING) : null;
172 // ==================================================================
173 // Basic Query - see docs for more detail
175 function query($query)
178 // For reg expressions
179 $query = str_replace("/[\n\r]/",'',trim($query));
184 // Flush cached values..
187 // Log how the function was called
188 $this->func_call = "\$db->query(\"$query\")";
190 // Keep track of the last query for debug..
191 $this->last_query = $query;
193 $this->num_queries++;
196 $this->timer_start($this->num_queries);
198 // Use core file cache function
199 if ( $cache = $this->get_cache($query) )
202 // Keep tack of how long all queries have taken
203 $this->timer_update_global($this->num_queries);
206 if ( $this->use_trace_log )
208 $this->trace_log[] = $this->debug(false);
214 // If there is no existing database connection then try to connect
215 if ( ! isset($this->dbh) || ! $this->dbh )
217 $this->connect($this->dsn, $this->user, $this->password);
218 if ( ! isset($this->dbh) || ! $this->dbh )
222 // Query was an insert, delete, update, replace
223 if ( preg_match("/^(insert|delete|update|replace|drop|create)\s+/i",$query) )
226 // Perform the query and log number of affected rows
227 $this->rows_affected = $this->dbh->exec($query);
229 // If there is an error then take note of it..
230 if ( $this->catch_error() ) return false;
234 // Take note of the insert_id
235 if ( preg_match("/^(insert|replace)\s+/i",$query) )
237 $this->insert_id = @$this->dbh->lastInsertId();
240 // Return number fo rows affected
241 $return_val = $this->rows_affected;
244 // Query was an select
248 // Perform the query and log number of affected rows
249 $sth = $this->dbh->query($query);
251 // If there is an error then take note of it..
252 if ( $this->catch_error() ) return false;
256 $col_count = $sth->columnCount();
258 for ( $i=0 ; $i < $col_count ; $i++ )
260 $this->col_info[$i] = new stdClass();
262 if ( $meta = $sth->getColumnMeta($i) )
264 $this->col_info[$i]->name = $meta['name'];
265 $this->col_info[$i]->type = !empty($meta['native_type']) ? $meta['native_type'] : 'undefined';
266 $this->col_info[$i]->max_length = '';
270 $this->col_info[$i]->name = 'undefined';
271 $this->col_info[$i]->type = 'undefined';
272 $this->col_info[$i]->max_length = '';
276 // Store Query Results
278 while ( $row = @$sth->fetch(PDO::FETCH_ASSOC) )
280 // Store relults as an objects within main array
281 $this->last_result[$num_rows] = (object) $row;
285 // Log number of rows the query returned
286 $this->num_rows = $num_rows;
288 // Return number of rows selected
289 $return_val = $this->num_rows;
293 // disk caching of queries
294 $this->store_cache($query,$is_insert);
296 // If debug ALL queries
297 $this->trace || $this->debug_all ? $this->debug() : null ;
299 // Keep tack of how long all queries have taken
300 $this->timer_update_global($this->num_queries);
303 if ( $this->use_trace_log )
305 $this->trace_log[] = $this->debug(false);