3 * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
4 * Copyright (C) 2012 The Nucleus Group
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 * (see nucleus/documentation/index.html#license for more info)
13 * @license http://nucleuscms.org/license.txt GNU General Public License
14 * @copyright Copyright (C) 2012 The Nucleus Group
18 if ( !class_exists('PDO') )
21 * Dummy constant of the PDO class
32 const PARAM_INPUT_OUTPUT = 128; // orignal is undefined.
34 const FETCH_ASSOC = 2;
38 const FETCH_BOUND = 6;
39 const FETCH_COLUMN = 7;
40 const FETCH_CLASS = 8;
42 const FETCH_FUNC = 10;
43 const FETCH_NAMED = 11;
44 const FETCH_KEY_PAIR = 12;
45 const FETCH_GROUP = 65536;
46 const FETCH_UNIQUE = 196608;
47 const FETCH_CLASSTYPE = 262144;
48 const FETCH_SERIALIZE = 524288;
49 const FETCH_PROPS_LATE = 1048576;
50 const ATTR_AUTOCOMMIT = 0;
51 const ATTR_PREFETCH = 1;
52 const ATTR_TIMEOUT = 2;
53 const ATTR_ERRMODE = 3;
54 const ATTR_SERVER_VERSION = 4;
55 const ATTR_CLIENT_VERSION = 5;
56 const ATTR_SERVER_INFO = 6;
57 const ATTR_CONNECTION_STATUS = 7;
59 const ATTR_CURSOR_NAME = 9;
60 const ATTR_CURSOR = 10;
61 const ATTR_ORACLE_NULLS = 11;
62 const ATTR_PERSISTENT = 12;
63 const ATTR_STATEMENT_CLASS = 13;
64 const ATTR_FETCH_TABLE_NAMES = 14;
65 const ATTR_FETCH_CATALOG_NAMES = 15;
66 const ATTR_DRIVER_NAME = 16;
67 const ATTR_STRINGIFY_FETCHES = 17;
68 const ATTR_MAX_COLUMN_LEN = 18;
69 const ATTR_DEFAULT_FETCH_MODE = 19;
70 const ATTR_EMULATE_PREPARES = 20;
71 const ERRMODE_SILENT = 0;
72 const ERRMODE_WARNING = 1;
73 const ERRMODE_EXCEPTION = 2;
74 const CASE_NATURAL = 0;
77 const NULL_NATURAL = 0;
78 const NULL_EMPTY_STRING = 1;
79 const NULL_TO_STRING = 2;
80 const FETCH_ORI_NEXT = 0;
81 const FETCH_ORI_PRIOR = 1;
82 const FETCH_ORI_FIRST = 2;
83 const FETCH_ORI_LAST = 3;
84 const FETCH_ORI_ABS = 4;
85 const FETCH_ORI_REL = 5;
86 const CURSOR_FWDONLY = 0;
87 const CURSOR_SCROLL = 1;
88 // from here orignal is undefined.
89 const ERR_CANT_MAP = 0;
91 const ERR_CONSTRAINT = 0;
92 const ERR_NOT_FOUND = 0;
93 const ERR_ALREADY_EXISTS = 0;
94 const ERR_NOT_IMPLEMENTED = 0;
95 const ERR_MISMATCH = 0;
96 const ERR_TRUNCATED = 0;
97 const ERR_DISCONNECTED = 0;
98 const ERR_NO_PERM = 0;
100 const ERR_NONE = '00000';
101 const PARAM_EVT_ALLOC = 0;
102 const PARAM_EVT_FREE = 1;
103 const PARAM_EVT_EXEC_PRE = 2;
104 const PARAM_EVT_EXEC_POST = 3;
105 const PARAM_EVT_FETCH_PRE = 4;
106 const PARAM_EVT_FETCH_POST = 5;
107 const PARAM_EVT_NORMALIZE = 6;
109 const MYSQL_ATTR_INIT_COMMAND = 1002;
113 * PDOException class of dummy
115 class PDOException extends Exception
120 * MysqlPDO class that wraps the mysql_ or mysqli_ function like PDO class
124 // Prefix function name
125 public static $handler;
130 * Creates a PDO instance representing a connection to a MySQL database.
131 * @param string $dsn DSN
132 * @param string $username UserName
133 * @param string $password Password
134 * @param mixed $driver_options Options[optional]
135 * @throws PDOException Thrown when failed to connect to the database.
137 public function __construct($dsn, $username, $password, $driver_options = '')
139 // select use function
140 if ( function_exists('mysql_query') )
142 MysqlPDO::$handler = 'mysql_';
144 else if ( function_exists('mysqli_query') )
146 MysqlPDO::$handler = 'mysqli_';
150 throw new PDOException('Can not be found mysql_ or mysqli_ functions.', 'IM000');
153 if ( preg_match('/host=([^;]+)/', $dsn, $matches) )
159 throw new PDOException('Host has not been set.', '01000');
161 if ( preg_match('/port=([^;]+)/', $dsn, $matches) )
163 $host .= ':' . $matches[1];
167 $this->dbcon = @call_user_func(MysqlPDO::$handler . 'connect', $host, $username, $password);
169 if ( $this->dbcon == FALSE )
171 throw new PDOException('Failed to connect to the server.', '01000');
175 if ( preg_match('/dbname=([^;]+)/', $dsn, $matches) )
177 $dbname = $matches[1];
180 if ( MysqlPDO::$handler == 'mysql_' )
182 call_user_func(MysqlPDO::$handler . 'select_db', $dbname, $this->dbcon);
186 call_user_func(MysqlPDO::$handler . 'select_db', $this->dbcon, $dbname);
191 if ( is_array($driver_options) && array_key_exists(PDO::MYSQL_ATTR_INIT_COMMAND, $driver_options) )
193 if ( preg_match('/SET\s+CHARACTER\s+SET\s+\'?([a-z0-9_-]+)\'?/', $driver_options[PDO::MYSQL_ATTR_INIT_COMMAND], $matches) )
195 $charset = $matches[1];
198 $server_info = call_user_func(MysqlPDO::$handler . 'get_server_info', $this->dbcon);
199 $mysql_version = preg_replace('/^([0-9]{1,2})\.([0-9]{1,2})\.([0-9]{1,2})(.*)$/', '$1.$2.$3', $server_info);
201 if ( version_compare($mysql_version, '5.0.7', '>=') && function_exists(MysqlPDO::$handler . 'set_charset') )
203 call_user_func(MysqlPDO::$handler . 'set_charset', $charset);
205 else if ( version_compare($mysql_version, '5.0.7', '<') )
207 $this->exec("SET CHARACTER SET '{$charset}';");
211 $this->exec("SET NAMES '{$charset}';");
218 * Close the connection to the MySQL server.
220 public function __destruct()
224 @call_user_func(MysqlPDO::$handler . 'close', $this->dbcon);
231 public function beginTransaction()
239 public function commit()
245 * Fetch the SQLSTATE associated with the last operation.
246 * However, if successful '00000' Otherwise, the return to '01000'.
247 * @return string Error code
249 public function errorCode()
251 $errno = call_user_func(MysqlPDO::$handler . 'errno', $this->dbcon);
252 return $errno === 0 ? '00000' : '01000';
256 * To get extended error information associated with the last operation.
257 * Element 0: if successful '00000' Otherwise, the return to '01000'
258 * Element 1: The return value of mysql_errno()
259 * Element 2: The return value of mysql_error()
260 * @return array Array of error information
262 public function errorInfo()
264 $errno = call_user_func(MysqlPDO::$handler . 'errno', $this->dbcon);
265 $error = call_user_func(MysqlPDO::$handler . 'error', $this->dbcon);
266 return array($errno === 0 ? '00000' : '01000', $errno, $error);
269 public function exec($statement)
271 $result = @call_user_func(MysqlPDO::$handler . 'query', $statement, $this->dbcon);
272 if ( $result === TRUE )
274 return @call_user_func(MysqlPDO::$handler . 'affected_rows', $this->dbcon);
276 else if ( is_resource($result) )
283 public function getAttribute($attribute)
285 switch ( $attribute )
287 case PDO::ATTR_SERVER_VERSION:
288 return call_user_func(MysqlPDO::$handler . 'get_server_info', $this->dbcon);
290 case PDO::ATTR_CLIENT_VERSION:
291 return call_user_func(MysqlPDO::$handler . 'get_client_info');
298 public static function getAvailableDrivers()
300 return array('mysql');
306 public function inTransaction()
311 public function lastInsertId($name = null)
313 return call_user_func(MysqlPDO::$handler . 'insert_id', $this->dbcon);
319 public function prepare($statement, $driver_options = array())
324 public function query($statement)
326 $result = @call_user_func(MysqlPDO::$handler . 'query', $statement, $this->dbcon);
327 return ($result == FALSE) ? FALSE : new MysqlPDOStatement($statement, $result, $this->dbcon);
330 public function quote($string, $parameter_type = PDO::PARAM_STR)
332 switch ( $parameter_type )
334 case PDO::PARAM_NULL:
336 case PDO::PARAM_BOOL:
337 return $string ? '1' : '0';
339 if ( $parameter_type == PDO::PARAM_INT && is_numeric($string) )
345 return '\'' . call_user_func(MysqlPDO::$handler . 'real_escape_string', $string) . '\'';
353 public function rollBack()
361 public function setAttribute($attribute, $value)
368 * MysqlPDOStatement class PDOStatement class like.
370 class MysqlPDOStatement implements Iterator
374 private $_queryString = '';
376 private $def_fetch_mode = PDO::FETCH_BOTH;
377 private $def_col_num = 0;
378 private $def_class_name = 'stdClass';
379 private $def_ctorargs = null;
380 private $bind_object = null;
382 public function __get($name)
384 if ( $name == 'queryString' )
386 return $this->_queryString;
390 public function __construct($query, $result, $dbconnect = null)
392 $this->dbcon = $dbconnect;
393 $this->_queryString = $query;
394 $this->result = $result;
397 public function __destruct()
399 $this->result = null;
405 public function bindColumn($column, &$param, $type, $maxlen, $driverdata)
413 public function bindParam($parameter, &$variable, $data_type = PDO::PARAM_STR, $length, $driver_options)
421 public function bindValue($parameter, $value, $data_type = PDO::PARAM_STR)
426 public function closeCursor()
428 return call_user_func(MysqlPDO::$handler . 'free_result', $this->result);
431 public function columnCount()
433 return call_user_func(MysqlPDO::$handler . 'num_fields', $this->result);
439 public function debugDumpParams()
444 public function errorCode()
446 $errno = call_user_func(MysqlPDO::$handler . 'errno', $this->dbcon);
447 return $errno === 0 ? '00000' : '01000';
450 public function errorInfo()
452 $errno = call_user_func(MysqlPDO::$handler . 'errno', $this->dbcon);
453 $error = call_user_func(MysqlPDO::$handler . 'error', $this->dbcon);
454 return array($errno === 0 ? '00000' : '01000', $errno, $error);
460 public function execute($input_parameters)
465 public function fetch($fetch_style = PDO::ATTR_DEFAULT_FETCH_MODE, $cursor_orientation = PDO::FETCH_ORI_NEXT, $cursor_offset = 0)
467 if ( !is_resource($this->result) || $cursor_orientation != PDO::FETCH_ORI_NEXT )
472 if ( $fetch_style == PDO::ATTR_DEFAULT_FETCH_MODE )
474 $fetch_style = $this->def_fetch_mode;
477 switch ( $fetch_style )
479 case PDO::FETCH_ASSOC:
480 return @call_user_func(MysqlPDO::$handler . 'fetch_array', $this->result, MYSQL_ASSOC);
481 case PDO::FETCH_BOTH:
482 return @call_user_func(MysqlPDO::$handler . 'fetch_array', $this->result, MYSQL_BOTH);
484 return @call_user_func(MysqlPDO::$handler . 'fetch_array', $this->result, MYSQL_NUM);
486 return $this->fetchObject();
487 case PDO::FETCH_CLASS:
488 return $this->fetchObject($this->def_class_name, $this->def_ctorargs);
489 case PDO::FETCH_COLUMN:
490 return $this->fetchColumn($this->def_col_num);
491 case PDO::FETCH_BOUND:
492 return FALSE; // Not supported
493 case PDO::FETCH_INTO:
494 return FALSE; // Not supported
495 case PDO::FETCH_LAZY:
496 return FALSE; // Not supported
502 public function fetchAll($fetch_style = PDO::ATTR_DEFAULT_FETCH_MODE, $fetch_argument = null, $ctor_args = array())
504 if ( $fetch_style == PDO::ATTR_DEFAULT_FETCH_MODE )
506 $fetch_style = PDO::FETCH_BOTH;
510 if ( ($fetch_style & PDO::FETCH_COLUMN) != 0 )
512 if ( $fetch_style == PDO::FETCH_COLUMN )
514 $column = $fetch_argument == null ? 0 : intval($fetch_argument);
515 while ( $row = $this->fetchColumn($column) )
520 elseif ( ($fetch_style & PDO::FETCH_UNIQUE) != 0 )
524 elseif ( ($fetch_style & PDO::FETCH_GROUP) != 0 )
529 elseif ( $fetch_style == PDO::FETCH_CLASS )
531 while ( $row = $this->fetchObject($fetch_argument, $ctor_args) )
536 elseif ( $fetch_style == PDO::FETCH_FUNC )
538 while ( $row = $this->fetch(PDO::FETCH_ASSOC) )
540 $ret[] = call_user_func_array($fetch_argument, array_values($row));
545 while ( $row = $this->fetch($fetch_style) )
553 public function fetchColumn($column_number = 0)
555 if ( $ret = $this->fetch(PDO::FETCH_NUM) )
557 return $ret[$column_number];
562 public function fetchObject($class_name = 'stdClass', $ctor_args = null)
564 if ( is_array($ctor_args) && !empty($ctor_args) )
566 return @call_user_func(MysqlPDO::$handler . 'fetch_object', $this->result, $class_name, $ctor_args);
570 return @call_user_func(MysqlPDO::$handler . 'fetch_object', $this->result, $class_name);
574 public function getAttribute($attribute)
576 switch ( $attribute )
586 public function getColumnMeta($column)
589 if ( MysqlPDO::$handler == 'mysql_' )
591 $result['name'] = @call_user_func(MysqlPDO::$handler . 'field_name', $this->result, $column);
599 public function nextRowset()
604 public function rowCount()
606 return @call_user_func(MysqlPDO::$handler . 'affected_rows', $this->dbcon);
612 public function setAttribute($attribute, $value)
617 public function setFetchMode($mode, &$mode_argument, $ctorargs)
621 case PDO::FETCH_COLUMN:
622 $this->def_col_num = $mode_argument;
624 case PDO::FETCH_CLASS:
625 $this->def_class_name = $mode_argument;
626 $this->def_ctorargs = $ctorargs;
628 case PDO::FETCH_INTO:
629 $this->bind_object = &$mode_argument;
630 return FALSE; // Not supported
632 $this->def_fetch_mode = $mode;
639 private $iterator_value;
649 return ($this->iterator_value = $this->fetch());
654 return $this->iterator_value;