OSDN Git Service

Merge branch 'skinnable-master'
[nucleus-jp/nucleus-next.git] / nucleus / libs / sql / MYSQLPDO.php
1 <<<<<<< HEAD
2 <?php\r
3 /*\r
4  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)\r
5  * Copyright (C) 2012 The Nucleus Group\r
6  *\r
7  * This program is free software; you can redistribute it and/or\r
8  * modify it under the terms of the GNU General Public License\r
9  * as published by the Free Software Foundation; either version 2\r
10  * of the License, or (at your option) any later version.\r
11  * (see nucleus/documentation/index.html#license for more info)\r
12  */\r
13 /**\r
14  * @license http://nucleuscms.org/license.txt GNU General Public License\r
15  * @copyright Copyright (C) 2012 The Nucleus Group\r
16  * @version $Id$\r
17  */\r
18 \r
19 if ( !class_exists('PDO') )\r
20 {\r
21 \r
22         /**\r
23          * Dummy constant of the PDO class\r
24          */\r
25         class PDO\r
26         {\r
27                 /* constant values */\r
28                 const PARAM_NULL = 0;\r
29                 const PARAM_INT = 1;\r
30                 const PARAM_STR = 2;\r
31                 const PARAM_LOB = 3;\r
32                 const PARAM_STMT = 4;\r
33                 const PARAM_BOOL = 5;\r
34                 const PARAM_INPUT_OUTPUT = 128; // orignal is undefined.\r
35                 const FETCH_LAZY = 1;\r
36                 const FETCH_ASSOC = 2;\r
37                 const FETCH_NUM = 3;\r
38                 const FETCH_BOTH = 4;\r
39                 const FETCH_OBJ = 5;\r
40                 const FETCH_BOUND = 6;\r
41                 const FETCH_COLUMN = 7;\r
42                 const FETCH_CLASS = 8;\r
43                 const FETCH_INTO = 9;\r
44                 const FETCH_FUNC = 10;\r
45                 const FETCH_NAMED = 11;\r
46                 const FETCH_KEY_PAIR = 12;\r
47                 const FETCH_GROUP = 65536;\r
48                 const FETCH_UNIQUE = 196608;\r
49                 const FETCH_CLASSTYPE = 262144;\r
50                 const FETCH_SERIALIZE = 524288;\r
51                 const FETCH_PROPS_LATE = 1048576;\r
52                 const ATTR_AUTOCOMMIT = 0;\r
53                 const ATTR_PREFETCH = 1;\r
54                 const ATTR_TIMEOUT = 2;\r
55                 const ATTR_ERRMODE = 3;\r
56                 const ATTR_SERVER_VERSION = 4;\r
57                 const ATTR_CLIENT_VERSION = 5;\r
58                 const ATTR_SERVER_INFO = 6;\r
59                 const ATTR_CONNECTION_STATUS = 7;\r
60                 const ATTR_CASE = 8;\r
61                 const ATTR_CURSOR_NAME = 9;\r
62                 const ATTR_CURSOR = 10;\r
63                 const ATTR_ORACLE_NULLS = 11;\r
64                 const ATTR_PERSISTENT = 12;\r
65                 const ATTR_STATEMENT_CLASS = 13;\r
66                 const ATTR_FETCH_TABLE_NAMES = 14;\r
67                 const ATTR_FETCH_CATALOG_NAMES = 15;\r
68                 const ATTR_DRIVER_NAME = 16;\r
69                 const ATTR_STRINGIFY_FETCHES = 17;\r
70                 const ATTR_MAX_COLUMN_LEN = 18;\r
71                 const ATTR_DEFAULT_FETCH_MODE = 19;\r
72                 const ATTR_EMULATE_PREPARES = 20;\r
73                 const ERRMODE_SILENT = 0;\r
74                 const ERRMODE_WARNING = 1;\r
75                 const ERRMODE_EXCEPTION = 2;\r
76                 const CASE_NATURAL = 0;\r
77                 const CASE_UPPER = 1;\r
78                 const CASE_LOWER = 2;\r
79                 const NULL_NATURAL = 0;\r
80                 const NULL_EMPTY_STRING = 1;\r
81                 const NULL_TO_STRING = 2;\r
82                 const FETCH_ORI_NEXT = 0;\r
83                 const FETCH_ORI_PRIOR = 1;\r
84                 const FETCH_ORI_FIRST = 2;\r
85                 const FETCH_ORI_LAST = 3;\r
86                 const FETCH_ORI_ABS = 4;\r
87                 const FETCH_ORI_REL = 5;\r
88                 const CURSOR_FWDONLY = 0;\r
89                 const CURSOR_SCROLL = 1;\r
90                 // from here orignal is undefined.\r
91                 const ERR_CANT_MAP = 0;\r
92                 const ERR_SYNTAX = 0;\r
93                 const ERR_CONSTRAINT = 0;\r
94                 const ERR_NOT_FOUND = 0;\r
95                 const ERR_ALREADY_EXISTS = 0;\r
96                 const ERR_NOT_IMPLEMENTED = 0;\r
97                 const ERR_MISMATCH = 0;\r
98                 const ERR_TRUNCATED = 0;\r
99                 const ERR_DISCONNECTED = 0;\r
100                 const ERR_NO_PERM = 0;\r
101                 // so far\r
102                 const ERR_NONE = '00000';\r
103                 const PARAM_EVT_ALLOC = 0;\r
104                 const PARAM_EVT_FREE = 1;\r
105                 const PARAM_EVT_EXEC_PRE = 2;\r
106                 const PARAM_EVT_EXEC_POST = 3;\r
107                 const PARAM_EVT_FETCH_PRE = 4;\r
108                 const PARAM_EVT_FETCH_POST = 5;\r
109                 const PARAM_EVT_NORMALIZE = 6;\r
110 \r
111                 const MYSQL_ATTR_INIT_COMMAND = 1002;\r
112         }\r
113 \r
114         /**\r
115          * PDOException class of dummy\r
116          */\r
117         class PDOException extends Exception\r
118         {}\r
119 }\r
120 \r
121 /**\r
122  * MysqlPDO class that wraps the mysql_ or mysqli_ function like PDO class\r
123  */\r
124 class MysqlPDO\r
125 {\r
126         // Prefix function name\r
127         public static $handler;\r
128 \r
129         private $dbcon;\r
130 \r
131         /**\r
132          * Creates a PDO instance representing a connection to a MySQL database.\r
133          * @param string $dsn DSN\r
134          * @param string $username UserName\r
135          * @param string $password Password\r
136          * @param mixed $driver_options Options[optional]\r
137          * @throws PDOException Thrown when failed to connect to the database.\r
138          */\r
139         public function __construct($dsn, $username, $password, $driver_options = '')\r
140         {\r
141                 // select use function\r
142                 if ( function_exists('mysql_query') )\r
143                 {\r
144                         MysqlPDO::$handler = 'mysql_';\r
145                 }\r
146                 else if ( function_exists('mysqli_query') )\r
147                 {\r
148                         MysqlPDO::$handler = 'mysqli_';\r
149                 }\r
150                 else\r
151                 {\r
152                         throw new PDOException('Can not be found mysql_ or mysqli_ functions.', 'IM000');\r
153                 }\r
154 \r
155                 if ( preg_match('/host=([^;]+)/', $dsn, $matches) )\r
156                 {\r
157                         $host = $matches[1];\r
158                 }\r
159                 else\r
160                 {\r
161                         throw new PDOException('Host has not been set.', '01000');\r
162                 }\r
163                 if ( preg_match('/port=([^;]+)/', $dsn, $matches) )\r
164                 {\r
165                         $host .= ':' . $matches[1];\r
166                 }\r
167 \r
168                 // mysql connect\r
169                 $this->dbcon = @call_user_func(MysqlPDO::$handler . 'connect', $host, $username, $password);\r
170 \r
171                 if ( $this->dbcon == FALSE )\r
172                 {\r
173                         throw new PDOException('Failed to connect to the server.', '01000');\r
174                 }\r
175 \r
176                 // select database\r
177                 if ( preg_match('/dbname=([^;]+)/', $dsn, $matches) )\r
178                 {\r
179                         $dbname = $matches[1];\r
180                         if ( $dbname )\r
181                         {\r
182                                 if ( MysqlPDO::$handler == 'mysql_' )\r
183                                 {\r
184                                         call_user_func(MysqlPDO::$handler . 'select_db', $dbname, $this->dbcon);\r
185                                 }\r
186                                 else\r
187                                 {\r
188                                         call_user_func(MysqlPDO::$handler . 'select_db', $this->dbcon, $dbname);\r
189                                 }\r
190 \r
191                                 // set use character\r
192                                 $charset = 'utf8';\r
193                                 if ( is_array($driver_options) && array_key_exists(PDO::MYSQL_ATTR_INIT_COMMAND, $driver_options) )\r
194                                 {\r
195                                         if ( preg_match('/SET\s+CHARACTER\s+SET\s+\'?([a-z0-9_-]+)\'?/', $driver_options[PDO::MYSQL_ATTR_INIT_COMMAND], $matches) )\r
196                                         {\r
197                                                 $charset = $matches[1];\r
198                                         }\r
199                                 }\r
200                                 $server_info = call_user_func(MysqlPDO::$handler . 'get_server_info', $this->dbcon);\r
201                                 $mysql_version = preg_replace('/^([0-9]{1,2})\.([0-9]{1,2})\.([0-9]{1,2})(.*)$/', '$1.$2.$3', $server_info);\r
202 \r
203                                 if ( version_compare($mysql_version, '5.0.7', '>=') && function_exists(MysqlPDO::$handler . 'set_charset') )\r
204                                 {\r
205                                         call_user_func(MysqlPDO::$handler . 'set_charset', $charset);\r
206                                 }\r
207                                 else if ( version_compare($mysql_version, '5.0.7', '<') )\r
208                                 {\r
209                                         $this->exec("SET CHARACTER SET '{$charset}';");\r
210                                 }\r
211                                 else\r
212                                 {\r
213                                         $this->exec("SET NAMES '{$charset}';");\r
214                                 }\r
215                         }\r
216                 }\r
217         }\r
218 \r
219         /**\r
220          * Close the connection to the MySQL server.\r
221          */\r
222         public function __destruct()\r
223         {\r
224                 if ( $this->dbcon )\r
225                 {\r
226                         @call_user_func(MysqlPDO::$handler . 'close', $this->dbcon);\r
227                 }\r
228         }\r
229 \r
230         /**\r
231          * Not supported\r
232          */\r
233         public function beginTransaction()\r
234         {\r
235                 return FALSE;\r
236         }\r
237 \r
238         /**\r
239          * Not supported\r
240          */\r
241         public function commit()\r
242         {\r
243                 return FALSE;\r
244         }\r
245 \r
246         /**\r
247          * Fetch the SQLSTATE associated with the last operation.\r
248          * However, if successful '00000' Otherwise, the return to '01000'.\r
249          * @return string Error code\r
250          */\r
251         public function errorCode()\r
252         {\r
253                 $errno = call_user_func(MysqlPDO::$handler . 'errno', $this->dbcon);\r
254                 return $errno === 0 ? '00000' : '01000';\r
255         }\r
256 \r
257         /**\r
258          * To get extended error information associated with the last operation.\r
259          * Element 0: if successful '00000' Otherwise, the return to '01000'\r
260          * Element 1: The return value of mysql_errno()\r
261          * Element 2: The return value of mysql_error()\r
262          * @return array Array of error information\r
263          */\r
264         public function errorInfo()\r
265         {\r
266                 $errno = call_user_func(MysqlPDO::$handler . 'errno', $this->dbcon);\r
267                 $error = call_user_func(MysqlPDO::$handler . 'error', $this->dbcon);\r
268                 return array($errno === 0 ? '00000' : '01000', $errno, $error);\r
269         }\r
270 \r
271         public function exec($statement)\r
272         {\r
273                 $result = @call_user_func(MysqlPDO::$handler . 'query', $statement, $this->dbcon);\r
274                 if ( $result === TRUE )\r
275                 {\r
276                         return @call_user_func(MysqlPDO::$handler . 'affected_rows', $this->dbcon);\r
277                 }\r
278                 else if ( is_resource($result) )\r
279                 {\r
280                         return;\r
281                 }\r
282                 return FALSE;\r
283         }\r
284 \r
285         public function getAttribute($attribute)\r
286         {\r
287                 switch ( $attribute )\r
288                 {\r
289                         case PDO::ATTR_SERVER_VERSION:\r
290                                 return call_user_func(MysqlPDO::$handler . 'get_server_info', $this->dbcon);\r
291                                 break;\r
292                         case PDO::ATTR_CLIENT_VERSION:\r
293                                 return call_user_func(MysqlPDO::$handler . 'get_client_info');\r
294                                 break;\r
295                         default:\r
296                                 return FALSE;\r
297                 }\r
298         }\r
299 \r
300         public static function getAvailableDrivers()\r
301         {\r
302                 return array('mysql');\r
303         }\r
304 \r
305         /**\r
306          * Not supported\r
307          */\r
308         public function inTransaction()\r
309         {\r
310                 return FALSE;\r
311         }\r
312 \r
313         public function lastInsertId($name = null)\r
314         {\r
315                 return call_user_func(MysqlPDO::$handler . 'insert_id', $this->dbcon);\r
316         }\r
317 \r
318         /**\r
319          * Not supported\r
320          */\r
321         public function prepare($statement, $driver_options = array())\r
322         {\r
323                 return FALSE;\r
324         }\r
325 \r
326         public function query($statement)\r
327         {\r
328                 $result = @call_user_func(MysqlPDO::$handler . 'query', $statement, $this->dbcon);\r
329                 return ($result == FALSE) ? FALSE : new MysqlPDOStatement($statement, $result, $this->dbcon);\r
330         }\r
331 \r
332         public function quote($string, $parameter_type = PDO::PARAM_STR)\r
333         {\r
334                 switch ( $parameter_type )\r
335                 {\r
336                         case PDO::PARAM_NULL:\r
337                                 return 'null';\r
338                         case PDO::PARAM_BOOL:\r
339                                 return $string ? '1' : '0';\r
340                         default:\r
341                                 if ( $parameter_type == PDO::PARAM_INT && is_numeric($string) )\r
342                                 {\r
343                                         return $string;\r
344                                 }\r
345                                 else\r
346                                 {\r
347                                         return '\'' . call_user_func(MysqlPDO::$handler . 'real_escape_string', $string) . '\'';\r
348                                 }\r
349                 }\r
350         }\r
351 \r
352         /**\r
353          * Not supported\r
354          */\r
355         public function rollBack()\r
356         {\r
357                 return FALSE;\r
358         }\r
359 \r
360         /**\r
361          * Not supported\r
362          */\r
363         public function setAttribute($attribute, $value)\r
364         {\r
365                 return FALSE;\r
366         }\r
367 }\r
368 \r
369 /**\r
370  * MysqlPDOStatement class PDOStatement class like.\r
371  */\r
372 class MysqlPDOStatement implements Iterator\r
373 {\r
374         private $result;\r
375         private $dbcon;\r
376         private $_queryString = '';\r
377 \r
378         private $def_fetch_mode = PDO::FETCH_BOTH;\r
379         private $def_col_num = 0;\r
380         private $def_class_name = 'stdClass';\r
381         private $def_ctorargs = null;\r
382         private $bind_object = null;\r
383 \r
384         public function __get($name)\r
385         {\r
386                 if ( $name == 'queryString' )\r
387                 {\r
388                         return $this->_queryString;\r
389                 }\r
390         }\r
391 \r
392         public function __construct($query, $result, $dbconnect = null)\r
393         {\r
394                 $this->dbcon = $dbconnect;\r
395                 $this->_queryString = $query;\r
396                 $this->result = $result;\r
397         }\r
398 \r
399         public function __destruct()\r
400         {\r
401                 $this->result = null;\r
402         }\r
403 \r
404         /**\r
405          * Not supported\r
406          */\r
407         public function bindColumn($column, &$param, $type, $maxlen, $driverdata)\r
408         {\r
409                 return FALSE;\r
410         }\r
411 \r
412         /**\r
413          * Not supported\r
414          */\r
415         public function bindParam($parameter, &$variable, $data_type = PDO::PARAM_STR, $length, $driver_options)\r
416         {\r
417                 return FALSE;\r
418         }\r
419 \r
420         /**\r
421          * Not supported\r
422          */\r
423         public function bindValue($parameter, $value, $data_type = PDO::PARAM_STR)\r
424         {\r
425                 return FALSE;\r
426         }\r
427 \r
428         public function closeCursor()\r
429         {\r
430                 return call_user_func(MysqlPDO::$handler . 'free_result', $this->result);\r
431         }\r
432 \r
433         public function columnCount()\r
434         {\r
435                 return call_user_func(MysqlPDO::$handler . 'num_fields', $this->result);\r
436         }\r
437 \r
438         /**\r
439          * Not supported\r
440          */\r
441         public function debugDumpParams()\r
442         {\r
443                 return;\r
444         }\r
445 \r
446         public function errorCode()\r
447         {\r
448                 $errno = call_user_func(MysqlPDO::$handler . 'errno', $this->dbcon);\r
449                 return $errno === 0 ? '00000' : '01000';\r
450         }\r
451 \r
452         public function errorInfo()\r
453         {\r
454                 $errno = call_user_func(MysqlPDO::$handler . 'errno', $this->dbcon);\r
455                 $error = call_user_func(MysqlPDO::$handler . 'error', $this->dbcon);\r
456                 return array($errno === 0 ? '00000' : '01000', $errno, $error);\r
457         }\r
458 \r
459         /**\r
460          * Not supported\r
461          */\r
462         public function execute($input_parameters)\r
463         {\r
464                 return FALSE;\r
465         }\r
466 \r
467         public function fetch($fetch_style = PDO::ATTR_DEFAULT_FETCH_MODE, $cursor_orientation = PDO::FETCH_ORI_NEXT, $cursor_offset = 0)\r
468         {\r
469                 if ( !is_resource($this->result) || $cursor_orientation != PDO::FETCH_ORI_NEXT )\r
470                 {\r
471                         return FALSE;\r
472                 }\r
473                 \r
474                 if ( $fetch_style == PDO::ATTR_DEFAULT_FETCH_MODE )\r
475                 {\r
476                         $fetch_style = $this->def_fetch_mode;\r
477                 }\r
478 \r
479                 switch ( $fetch_style )\r
480                 {\r
481                         case PDO::FETCH_ASSOC:\r
482                                 return @call_user_func(MysqlPDO::$handler . 'fetch_array', $this->result, MYSQL_ASSOC);\r
483                         case PDO::FETCH_BOTH:\r
484                                 return @call_user_func(MysqlPDO::$handler . 'fetch_array', $this->result, MYSQL_BOTH);\r
485                         case PDO::FETCH_NUM:\r
486                                 return @call_user_func(MysqlPDO::$handler . 'fetch_array', $this->result, MYSQL_NUM);\r
487                         case PDO::FETCH_OBJ:\r
488                                 return $this->fetchObject();\r
489                         case PDO::FETCH_CLASS:\r
490                                 return $this->fetchObject($this->def_class_name, $this->def_ctorargs);\r
491                         case PDO::FETCH_COLUMN:\r
492                                 return $this->fetchColumn($this->def_col_num);\r
493                         case PDO::FETCH_BOUND:\r
494                                 return FALSE; // Not supported\r
495                         case PDO::FETCH_INTO:\r
496                                 return FALSE; // Not supported\r
497                         case PDO::FETCH_LAZY:\r
498                                 return FALSE; // Not supported\r
499                         default:\r
500                                 return FALSE;\r
501                 }\r
502         }\r
503 \r
504         public function fetchAll($fetch_style = PDO::ATTR_DEFAULT_FETCH_MODE, $fetch_argument = null, $ctor_args = array())\r
505         {\r
506                 if ( $fetch_style == PDO::ATTR_DEFAULT_FETCH_MODE )\r
507                 {\r
508                         $fetch_style = PDO::FETCH_BOTH;\r
509                 }\r
510                 \r
511                 $ret = array();\r
512                 if ( ($fetch_style & PDO::FETCH_COLUMN) != 0 )\r
513                 {\r
514                         if ( $fetch_style == PDO::FETCH_COLUMN )\r
515                         {\r
516                                 $column = $fetch_argument == null ? 0 : intval($fetch_argument);\r
517                                 while ( $row = $this->fetchColumn($column) )\r
518                                 {\r
519                                         $ret[] = $row;\r
520                                 }\r
521                         }\r
522                         elseif ( ($fetch_style & PDO::FETCH_UNIQUE) != 0 )\r
523                         {\r
524                                 return FALSE;\r
525                         }\r
526                         elseif ( ($fetch_style & PDO::FETCH_GROUP) != 0 )\r
527                         {\r
528                                 return FALSE;\r
529                         }\r
530                 }\r
531                 elseif ( $fetch_style == PDO::FETCH_CLASS )\r
532                 {\r
533                         while ( $row = $this->fetchObject($fetch_argument, $ctor_args) )\r
534                         {\r
535                                 $ret[] = $row;\r
536                         }\r
537                 }\r
538                 elseif ( $fetch_style == PDO::FETCH_FUNC )\r
539                 {\r
540                         while ( $row = $this->fetch(PDO::FETCH_ASSOC) )\r
541                         {\r
542                                 $ret[] = call_user_func_array($fetch_argument, array_values($row));\r
543                         }\r
544                 }\r
545                 else\r
546                 {\r
547                         while ( $row = $this->fetch($fetch_style) )\r
548                         {\r
549                                 $ret[] = $row;\r
550                         }\r
551                 }\r
552                 return $ret;\r
553         }\r
554 \r
555         public function fetchColumn($column_number = 0)\r
556         {\r
557                 if ( $ret = $this->fetch(PDO::FETCH_NUM) )\r
558                 {\r
559                         return $ret[$column_number];\r
560                 }\r
561                 return FALSE;\r
562         }\r
563 \r
564         public function fetchObject($class_name = 'stdClass', $ctor_args = null)\r
565         {\r
566                 if ( is_array($ctor_args) && !empty($ctor_args) )\r
567                 {\r
568                         return @call_user_func(MysqlPDO::$handler . 'fetch_object', $this->result, $class_name, $ctor_args);\r
569                 }\r
570                 else\r
571                 {\r
572                         return @call_user_func(MysqlPDO::$handler . 'fetch_object', $this->result, $class_name);\r
573                 }\r
574         }\r
575 \r
576         public function getAttribute($attribute)\r
577         {\r
578                 switch ( $attribute )\r
579                 {\r
580                         default:\r
581                                 return FALSE;\r
582                 }\r
583         }\r
584 \r
585         /**\r
586          * Not supported\r
587          */\r
588         public function getColumnMeta($column)\r
589         {\r
590                 $result = array();\r
591                 if ( MysqlPDO::$handler == 'mysql_' )\r
592                 {\r
593                         $result['name'] = @call_user_func(MysqlPDO::$handler . 'field_name', $this->result, $column);\r
594                 }\r
595                 return $result;\r
596         }\r
597 \r
598         /**\r
599          * Not supported\r
600          */\r
601         public function nextRowset()\r
602         {\r
603                 return FALSE;\r
604         }\r
605 \r
606         public function rowCount()\r
607         {\r
608                 return @call_user_func(MysqlPDO::$handler . 'affected_rows', $this->dbcon);\r
609         }\r
610 \r
611         /**\r
612          * Not supported\r
613          */\r
614         public function setAttribute($attribute, $value)\r
615         {\r
616                 return FALSE;\r
617         }\r
618 \r
619         public function setFetchMode($mode, &$mode_argument, $ctorargs)\r
620         {\r
621                 switch ( $mode )\r
622                 {\r
623                         case PDO::FETCH_COLUMN:\r
624                                 $this->def_col_num = $mode_argument;\r
625                                 break;\r
626                         case PDO::FETCH_CLASS:\r
627                                 $this->def_class_name = $mode_argument;\r
628                                 $this->def_ctorargs = $ctorargs;\r
629                                 break;\r
630                         case PDO::FETCH_INTO:\r
631                                 $this->bind_object = &$mode_argument;\r
632                                 return FALSE; // Not supported\r
633                         default:\r
634                                 $this->def_fetch_mode = $mode;\r
635                                 break;\r
636                 }\r
637                 return 1;\r
638         }\r
639 \r
640         // Iterator\r
641         private $iterator_value;\r
642 \r
643         function rewind()\r
644         {}\r
645 \r
646         function next()\r
647         {}\r
648 \r
649         function valid()\r
650         {\r
651                 return ($this->iterator_value = $this->fetch());\r
652         }\r
653 \r
654         function current()\r
655         {\r
656                 return $this->iterator_value;\r
657         }\r
658 \r
659         function key()\r
660         {\r
661                 return null;\r
662         }\r
663 }\r
664 =======
665 <?php
666 /*
667  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
668  * Copyright (C) 2012 The Nucleus Group
669  *
670  * This program is free software; you can redistribute it and/or
671  * modify it under the terms of the GNU General Public License
672  * as published by the Free Software Foundation; either version 2
673  * of the License, or (at your option) any later version.
674  * (see nucleus/documentation/index.html#license for more info)
675  */
676 /**
677  * @license http://nucleuscms.org/license.txt GNU General Public License
678  * @copyright Copyright (C) 2012 The Nucleus Group
679  * @version $Id$
680  */
681
682 if ( !class_exists('PDO') )
683 {
684         /**
685          * Dummy constant of the PDO class
686          */
687         class PDO
688         {
689                 /* constant values */
690                 const PARAM_NULL = 0;
691                 const PARAM_INT = 1;
692                 const PARAM_STR = 2;
693                 const PARAM_LOB = 3;
694                 const PARAM_STMT = 4;
695                 const PARAM_BOOL = 5;
696                 const PARAM_INPUT_OUTPUT = 128; // orignal is undefined.
697                 const FETCH_LAZY = 1;
698                 const FETCH_ASSOC = 2;
699                 const FETCH_NUM = 3;
700                 const FETCH_BOTH = 4;
701                 const FETCH_OBJ = 5;
702                 const FETCH_BOUND = 6;
703                 const FETCH_COLUMN = 7;
704                 const FETCH_CLASS = 8;
705                 const FETCH_INTO = 9;
706                 const FETCH_FUNC = 10;
707                 const FETCH_NAMED = 11;
708                 const FETCH_KEY_PAIR = 12;
709                 const FETCH_GROUP = 65536;
710                 const FETCH_UNIQUE = 196608;
711                 const FETCH_CLASSTYPE = 262144;
712                 const FETCH_SERIALIZE = 524288;
713                 const FETCH_PROPS_LATE = 1048576;
714                 const ATTR_AUTOCOMMIT = 0;
715                 const ATTR_PREFETCH = 1;
716                 const ATTR_TIMEOUT = 2;
717                 const ATTR_ERRMODE = 3;
718                 const ATTR_SERVER_VERSION = 4;
719                 const ATTR_CLIENT_VERSION = 5;
720                 const ATTR_SERVER_INFO = 6;
721                 const ATTR_CONNECTION_STATUS = 7;
722                 const ATTR_CASE = 8;
723                 const ATTR_CURSOR_NAME = 9;
724                 const ATTR_CURSOR = 10;
725                 const ATTR_ORACLE_NULLS = 11;
726                 const ATTR_PERSISTENT = 12;
727                 const ATTR_STATEMENT_CLASS = 13;
728                 const ATTR_FETCH_TABLE_NAMES = 14;
729                 const ATTR_FETCH_CATALOG_NAMES = 15;
730                 const ATTR_DRIVER_NAME = 16;
731                 const ATTR_STRINGIFY_FETCHES = 17;
732                 const ATTR_MAX_COLUMN_LEN = 18;
733                 const ATTR_DEFAULT_FETCH_MODE = 19;
734                 const ATTR_EMULATE_PREPARES = 20;
735                 const ERRMODE_SILENT = 0;
736                 const ERRMODE_WARNING = 1;
737                 const ERRMODE_EXCEPTION = 2;
738                 const CASE_NATURAL = 0;
739                 const CASE_UPPER = 1;
740                 const CASE_LOWER = 2;
741                 const NULL_NATURAL = 0;
742                 const NULL_EMPTY_STRING = 1;
743                 const NULL_TO_STRING = 2;
744                 const FETCH_ORI_NEXT = 0;
745                 const FETCH_ORI_PRIOR = 1;
746                 const FETCH_ORI_FIRST = 2;
747                 const FETCH_ORI_LAST = 3;
748                 const FETCH_ORI_ABS = 4;
749                 const FETCH_ORI_REL = 5;
750                 const CURSOR_FWDONLY = 0;
751                 const CURSOR_SCROLL = 1;
752                 // from here orignal is undefined.
753                 const ERR_CANT_MAP = 0;
754                 const ERR_SYNTAX = 0;
755                 const ERR_CONSTRAINT = 0;
756                 const ERR_NOT_FOUND = 0;
757                 const ERR_ALREADY_EXISTS = 0;
758                 const ERR_NOT_IMPLEMENTED = 0;
759                 const ERR_MISMATCH = 0;
760                 const ERR_TRUNCATED = 0;
761                 const ERR_DISCONNECTED = 0;
762                 const ERR_NO_PERM = 0;
763                 // so far
764                 const ERR_NONE = '00000';
765                 const PARAM_EVT_ALLOC = 0;
766                 const PARAM_EVT_FREE = 1;
767                 const PARAM_EVT_EXEC_PRE = 2;
768                 const PARAM_EVT_EXEC_POST = 3;
769                 const PARAM_EVT_FETCH_PRE = 4;
770                 const PARAM_EVT_FETCH_POST = 5;
771                 const PARAM_EVT_NORMALIZE = 6;
772
773                 const MYSQL_ATTR_INIT_COMMAND = 1002;
774         }
775
776         /**
777          * PDOException class of dummy
778          */
779         class PDOException extends Exception
780         {}
781 }
782
783 /**
784  * MysqlPDO class that wraps the mysql_ or mysqli_ function like PDO class
785  */
786 class MysqlPDO
787 {
788         // Prefix function name
789         public static $handler;
790
791         private $dbcon;
792
793         /**
794          * Creates a PDO instance representing a connection to a MySQL database.
795          * @param string $dsn DSN
796          * @param string $username UserName
797          * @param string $password Password
798          * @param mixed $driver_options Options[optional]
799          * @throws PDOException Thrown when failed to connect to the database.
800          */
801         public function __construct($dsn, $username, $password, $driver_options = '')
802         {
803                 // select use function
804                 if ( function_exists('mysql_query') )
805                 {
806                         MysqlPDO::$handler = 'mysql_';
807                 }
808                 else if ( function_exists('mysqli_query') )
809                 {
810                         MysqlPDO::$handler = 'mysqli_';
811                 }
812                 else
813                 {
814                         throw new PDOException('Can not be found mysql_ or mysqli_ functions.', 'IM000');
815                 }
816
817                 if ( preg_match('/host=([^;]+)/', $dsn, $matches) )
818                 {
819                         $host = $matches[1];
820                 }
821                 else
822                 {
823                         throw new PDOException('Host has not been set.', '01000');
824                 }
825                 if ( preg_match('/port=([^;]+)/', $dsn, $matches) )
826                 {
827                         $host .= ':' . $matches[1];
828                 }
829
830                 // mysql connect
831                 $this->dbcon = @call_user_func(MysqlPDO::$handler . 'connect', $host, $username, $password);
832
833                 if ( $this->dbcon == FALSE )
834                 {
835                         throw new PDOException('Failed to connect to the server.', '01000');
836                 }
837
838                 // select database
839                 if ( preg_match('/dbname=([^;]+)/', $dsn, $matches) )
840                 {
841                         $dbname = $matches[1];
842                         if ( $dbname )
843                         {
844                                 if ( MysqlPDO::$handler == 'mysql_' )
845                                 {
846                                         call_user_func(MysqlPDO::$handler . 'select_db', $dbname, $this->dbcon);
847                                 }
848                                 else
849                                 {
850                                         call_user_func(MysqlPDO::$handler . 'select_db', $this->dbcon, $dbname);
851                                 }
852
853                                 // set use character
854                                 $charset = 'utf8';
855                                 if ( is_array($driver_options) && array_key_exists(PDO::MYSQL_ATTR_INIT_COMMAND, $driver_options) )
856                                 {
857                                         if ( preg_match('/SET\s+CHARACTER\s+SET\s+\'?([a-z0-9_-]+)\'?/', $driver_options[PDO::MYSQL_ATTR_INIT_COMMAND], $matches) )
858                                         {
859                                                 $charset = $matches[1];
860                                         }
861                                 }
862                                 $server_info = call_user_func(MysqlPDO::$handler . 'get_server_info', $this->dbcon);
863                                 $mysql_version = preg_replace('/^([0-9]{1,2})\.([0-9]{1,2})\.([0-9]{1,2})(.*)$/', '$1.$2.$3', $server_info);
864
865                                 if ( version_compare($mysql_version, '5.0.7', '>=') && function_exists(MysqlPDO::$handler . 'set_charset') )
866                                 {
867                                         call_user_func(MysqlPDO::$handler . 'set_charset', $charset);
868                                 }
869                                 else if ( version_compare($mysql_version, '5.0.7', '<') )
870                                 {
871                                         $this->exec("SET CHARACTER SET '{$charset}';");
872                                 }
873                                 else
874                                 {
875                                         $this->exec("SET NAMES '{$charset}';");
876                                 }
877                         }
878                 }
879         }
880
881         /**
882          * Close the connection to the MySQL server.
883          */
884         public function __destruct()
885         {
886                 if ( $this->dbcon )
887                 {
888                         @call_user_func(MysqlPDO::$handler . 'close', $this->dbcon);
889                 }
890         }
891
892         /**
893          * Not supported
894          */
895         public function beginTransaction()
896         {
897                 return FALSE;
898         }
899
900         /**
901          * Not supported
902          */
903         public function commit()
904         {
905                 return FALSE;
906         }
907
908         /**
909          * Fetch the SQLSTATE associated with the last operation.
910          * However, if successful '00000' Otherwise, the return to '01000'.
911          * @return string Error code
912          */
913         public function errorCode()
914         {
915                 $errno = call_user_func(MysqlPDO::$handler . 'errno', $this->dbcon);
916                 return $errno === 0 ? '00000' : '01000';
917         }
918
919         /**
920          * To get extended error information associated with the last operation.
921          * Element 0: if successful '00000' Otherwise, the return to '01000'
922          * Element 1: The return value of mysql_errno()
923          * Element 2: The return value of mysql_error()
924          * @return array Array of error information
925          */
926         public function errorInfo()
927         {
928                 $errno = call_user_func(MysqlPDO::$handler . 'errno', $this->dbcon);
929                 $error = call_user_func(MysqlPDO::$handler . 'error', $this->dbcon);
930                 return array($errno === 0 ? '00000' : '01000', $errno, $error);
931         }
932
933         public function exec($statement)
934         {
935                 $result = @call_user_func(MysqlPDO::$handler . 'query', $statement, $this->dbcon);
936                 if ( $result === TRUE )
937                 {
938                         return @call_user_func(MysqlPDO::$handler . 'affected_rows', $this->dbcon);
939                 }
940                 else if ( is_resource($result) )
941                 {
942                         return;
943                 }
944                 return FALSE;
945         }
946
947         public function getAttribute($attribute)
948         {
949                 switch ( $attribute )
950                 {
951                         case PDO::ATTR_SERVER_VERSION:
952                                 return call_user_func(MysqlPDO::$handler . 'get_server_info', $this->dbcon);
953                                 break;
954                         case PDO::ATTR_CLIENT_VERSION:
955                                 return call_user_func(MysqlPDO::$handler . 'get_client_info');
956                                 break;
957                         default:
958                                 return FALSE;
959                 }
960         }
961
962         public static function getAvailableDrivers()
963         {
964                 return array('mysql');
965         }
966
967         /**
968          * Not supported
969          */
970         public function inTransaction()
971         {
972                 return FALSE;
973         }
974
975         public function lastInsertId($name = null)
976         {
977                 return call_user_func(MysqlPDO::$handler . 'insert_id', $this->dbcon);
978         }
979
980         /**
981          * Not supported
982          */
983         public function prepare($statement, $driver_options = array())
984         {
985                 return FALSE;
986         }
987
988         public function query($statement)
989         {
990                 $result = @call_user_func(MysqlPDO::$handler . 'query', $statement, $this->dbcon);
991                 return ($result == FALSE) ? FALSE : new MysqlPDOStatement($statement, $result, $this->dbcon);
992         }
993
994         public function quote($string, $parameter_type = PDO::PARAM_STR)
995         {
996                 switch ( $parameter_type )
997                 {
998                         case PDO::PARAM_NULL:
999                                 return 'null';
1000                         case PDO::PARAM_BOOL:
1001                                 return $string ? '1' : '0';
1002                         default:
1003                                 if ( $parameter_type == PDO::PARAM_INT && is_numeric($string) )
1004                                 {
1005                                         return $string;
1006                                 }
1007                                 else
1008                                 {
1009                                         return '\'' . call_user_func(MysqlPDO::$handler . 'real_escape_string', $string) . '\'';
1010                                 }
1011                 }
1012         }
1013
1014         /**
1015          * Not supported
1016          */
1017         public function rollBack()
1018         {
1019                 return FALSE;
1020         }
1021
1022         /**
1023          * Not supported
1024          */
1025         public function setAttribute($attribute, $value)
1026         {
1027                 return FALSE;
1028         }
1029 }
1030
1031 /**
1032  * MysqlPDOStatement class PDOStatement class like.
1033  */
1034 class MysqlPDOStatement implements Iterator
1035 {
1036         private $result;
1037         private $dbcon;
1038         private $_queryString = '';
1039
1040         private $def_fetch_mode = PDO::FETCH_BOTH;
1041         private $def_col_num = 0;
1042         private $def_class_name = 'stdClass';
1043         private $def_ctorargs = null;
1044         private $bind_object = null;
1045
1046         public function __get($name)
1047         {
1048                 if ( $name == 'queryString' )
1049                 {
1050                         return $this->_queryString;
1051                 }
1052         }
1053
1054         public function __construct($query, $result, $dbconnect = null)
1055         {
1056                 $this->dbcon = $dbconnect;
1057                 $this->_queryString = $query;
1058                 $this->result = $result;
1059         }
1060
1061         public function __destruct()
1062         {
1063                 $this->result = null;
1064         }
1065
1066         /**
1067          * Not supported
1068          */
1069         public function bindColumn($column, &$param, $type, $maxlen, $driverdata)
1070         {
1071                 return FALSE;
1072         }
1073
1074         /**
1075          * Not supported
1076          */
1077         public function bindParam($parameter, &$variable, $data_type = PDO::PARAM_STR, $length, $driver_options)
1078         {
1079                 return FALSE;
1080         }
1081
1082         /**
1083          * Not supported
1084          */
1085         public function bindValue($parameter, $value, $data_type = PDO::PARAM_STR)
1086         {
1087                 return FALSE;
1088         }
1089
1090         public function closeCursor()
1091         {
1092                 return call_user_func(MysqlPDO::$handler . 'free_result', $this->result);
1093         }
1094
1095         public function columnCount()
1096         {
1097                 return call_user_func(MysqlPDO::$handler . 'num_fields', $this->result);
1098         }
1099
1100         /**
1101          * Not supported
1102          */
1103         public function debugDumpParams()
1104         {
1105                 return;
1106         }
1107
1108         public function errorCode()
1109         {
1110                 $errno = call_user_func(MysqlPDO::$handler . 'errno', $this->dbcon);
1111                 return $errno === 0 ? '00000' : '01000';
1112         }
1113
1114         public function errorInfo()
1115         {
1116                 $errno = call_user_func(MysqlPDO::$handler . 'errno', $this->dbcon);
1117                 $error = call_user_func(MysqlPDO::$handler . 'error', $this->dbcon);
1118                 return array($errno === 0 ? '00000' : '01000', $errno, $error);
1119         }
1120
1121         /**
1122          * Not supported
1123          */
1124         public function execute($input_parameters)
1125         {
1126                 return FALSE;
1127         }
1128
1129         public function fetch($fetch_style = PDO::ATTR_DEFAULT_FETCH_MODE, $cursor_orientation = PDO::FETCH_ORI_NEXT, $cursor_offset = 0)
1130         {
1131                 if ( !is_resource($this->result) || $cursor_orientation != PDO::FETCH_ORI_NEXT )
1132                 {
1133                         return FALSE;
1134                 }
1135                 
1136                 if ( $fetch_style == PDO::ATTR_DEFAULT_FETCH_MODE )
1137                 {
1138                         $fetch_style = $this->def_fetch_mode;
1139                 }
1140
1141                 switch ( $fetch_style )
1142                 {
1143                         case PDO::FETCH_ASSOC:
1144                                 return @call_user_func(MysqlPDO::$handler . 'fetch_array', $this->result, MYSQL_ASSOC);
1145                         case PDO::FETCH_BOTH:
1146                                 return @call_user_func(MysqlPDO::$handler . 'fetch_array', $this->result, MYSQL_BOTH);
1147                         case PDO::FETCH_NUM:
1148                                 return @call_user_func(MysqlPDO::$handler . 'fetch_array', $this->result, MYSQL_NUM);
1149                         case PDO::FETCH_OBJ:
1150                                 return $this->fetchObject();
1151                         case PDO::FETCH_CLASS:
1152                                 return $this->fetchObject($this->def_class_name, $this->def_ctorargs);
1153                         case PDO::FETCH_COLUMN:
1154                                 return $this->fetchColumn($this->def_col_num);
1155                         case PDO::FETCH_BOUND:
1156                                 return FALSE; // Not supported
1157                         case PDO::FETCH_INTO:
1158                                 return FALSE; // Not supported
1159                         case PDO::FETCH_LAZY:
1160                                 return FALSE; // Not supported
1161                         default:
1162                                 return FALSE;
1163                 }
1164         }
1165
1166         public function fetchAll($fetch_style = PDO::ATTR_DEFAULT_FETCH_MODE, $fetch_argument = null, $ctor_args = array())
1167         {
1168                 if ( $fetch_style == PDO::ATTR_DEFAULT_FETCH_MODE )
1169                 {
1170                         $fetch_style = PDO::FETCH_BOTH;
1171                 }
1172                 
1173                 $ret = array();
1174                 if ( ($fetch_style & PDO::FETCH_COLUMN) != 0 )
1175                 {
1176                         if ( $fetch_style == PDO::FETCH_COLUMN )
1177                         {
1178                                 $column = $fetch_argument == null ? 0 : intval($fetch_argument);
1179                                 while ( $row = $this->fetchColumn($column) )
1180                                 {
1181                                         $ret[] = $row;
1182                                 }
1183                         }
1184                         elseif ( ($fetch_style & PDO::FETCH_UNIQUE) != 0 )
1185                         {
1186                                 return FALSE;
1187                         }
1188                         elseif ( ($fetch_style & PDO::FETCH_GROUP) != 0 )
1189                         {
1190                                 return FALSE;
1191                         }
1192                 }
1193                 elseif ( $fetch_style == PDO::FETCH_CLASS )
1194                 {
1195                         while ( $row = $this->fetchObject($fetch_argument, $ctor_args) )
1196                         {
1197                                 $ret[] = $row;
1198                         }
1199                 }
1200                 elseif ( $fetch_style == PDO::FETCH_FUNC )
1201                 {
1202                         while ( $row = $this->fetch(PDO::FETCH_ASSOC) )
1203                         {
1204                                 $ret[] = call_user_func_array($fetch_argument, array_values($row));
1205                         }
1206                 }
1207                 else
1208                 {
1209                         while ( $row = $this->fetch($fetch_style) )
1210                         {
1211                                 $ret[] = $row;
1212                         }
1213                 }
1214                 return $ret;
1215         }
1216
1217         public function fetchColumn($column_number = 0)
1218         {
1219                 if ( $ret = $this->fetch(PDO::FETCH_NUM) )
1220                 {
1221                         return $ret[$column_number];
1222                 }
1223                 return FALSE;
1224         }
1225
1226         public function fetchObject($class_name = 'stdClass', $ctor_args = null)
1227         {
1228                 if ( is_array($ctor_args) && !empty($ctor_args) )
1229                 {
1230                         return @call_user_func(MysqlPDO::$handler . 'fetch_object', $this->result, $class_name, $ctor_args);
1231                 }
1232                 else
1233                 {
1234                         return @call_user_func(MysqlPDO::$handler . 'fetch_object', $this->result, $class_name);
1235                 }
1236         }
1237
1238         public function getAttribute($attribute)
1239         {
1240                 switch ( $attribute )
1241                 {
1242                         default:
1243                                 return FALSE;
1244                 }
1245         }
1246
1247         /**
1248          * Not supported
1249          */
1250         public function getColumnMeta($column)
1251         {
1252                 $result = array();
1253                 if ( MysqlPDO::$handler == 'mysql_' )
1254                 {
1255                         $result['name'] = @call_user_func(MysqlPDO::$handler . 'field_name', $this->result, $column);
1256                 }
1257                 return $result;
1258         }
1259
1260         /**
1261          * Not supported
1262          */
1263         public function nextRowset()
1264         {
1265                 return FALSE;
1266         }
1267
1268         public function rowCount()
1269         {
1270                 return @call_user_func(MysqlPDO::$handler . 'affected_rows', $this->dbcon);
1271         }
1272
1273         /**
1274          * Not supported
1275          */
1276         public function setAttribute($attribute, $value)
1277         {
1278                 return FALSE;
1279         }
1280
1281         public function setFetchMode($mode, &$mode_argument, $ctorargs)
1282         {
1283                 switch ( $mode )
1284                 {
1285                         case PDO::FETCH_COLUMN:
1286                                 $this->def_col_num = $mode_argument;
1287                                 break;
1288                         case PDO::FETCH_CLASS:
1289                                 $this->def_class_name = $mode_argument;
1290                                 $this->def_ctorargs = $ctorargs;
1291                                 break;
1292                         case PDO::FETCH_INTO:
1293                                 $this->bind_object = &$mode_argument;
1294                                 return FALSE; // Not supported
1295                         default:
1296                                 $this->def_fetch_mode = $mode;
1297                                 break;
1298                 }
1299                 return 1;
1300         }
1301
1302         // Iterator
1303         private $iterator_value;
1304
1305         function rewind()
1306         {}
1307
1308         function next()
1309         {}
1310
1311         function valid()
1312         {
1313                 return ($this->iterator_value = $this->fetch());
1314         }
1315
1316         function current()
1317         {
1318                 return $this->iterator_value;
1319         }
1320
1321         function key()
1322         {
1323                 return null;
1324         }
1325 }
1326 >>>>>>> skinnable-master