Take two:
[www-register-wizard.git] / database / drivers / postgre / postgre_driver.php
1 <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
2 /**\r
3  * CodeIgniter\r
4  *\r
5  * An open source application development framework for PHP 4.3.2 or newer\r
6  *\r
7  * @package             CodeIgniter\r
8  * @author              ExpressionEngine Dev Team\r
9  * @copyright   Copyright (c) 2008, EllisLab, Inc.\r
10  * @license             http://codeigniter.com/user_guide/license.html\r
11  * @link                http://codeigniter.com\r
12  * @since               Version 1.0\r
13  * @filesource\r
14  */\r
15 \r
16 // ------------------------------------------------------------------------\r
17 \r
18 /**\r
19  * Postgre Database Adapter Class\r
20  *\r
21  * Note: _DB is an extender class that the app controller\r
22  * creates dynamically based on whether the active record\r
23  * class is being used or not.\r
24  *\r
25  * @package             CodeIgniter\r
26  * @subpackage  Drivers\r
27  * @category    Database\r
28  * @author              ExpressionEngine Dev Team\r
29  * @link                http://codeigniter.com/user_guide/database/\r
30  */\r
31 class CI_DB_postgre_driver extends CI_DB {\r
32 \r
33         var $dbdriver = 'postgre';\r
34         \r
35         var $_escape_char = '"';\r
36 \r
37         /**\r
38          * The syntax to count rows is slightly different across different\r
39          * database engines, so this string appears in each driver and is\r
40          * used for the count_all() and count_all_results() functions.\r
41          */\r
42         var $_count_string = "SELECT COUNT(*) AS ";\r
43         var $_random_keyword = ' RANDOM()'; // database specific random keyword\r
44 \r
45         /**\r
46          * Connection String\r
47          *\r
48          * @access      private\r
49          * @return      string\r
50          */     \r
51         function _connect_string()\r
52         {\r
53                 $components = array(\r
54                                                                 'hostname'      => 'host',\r
55                                                                 'port'          => 'port',\r
56                                                                 'database'      => 'dbname',\r
57                                                                 'username'      => 'user',\r
58                                                                 'password'      => 'password'\r
59                                                         );\r
60                 \r
61                 $connect_string = "";\r
62                 foreach ($components as $key => $val)\r
63                 {\r
64                         if (isset($this->$key) && $this->$key != '')\r
65                         {\r
66                                 $connect_string .= " $val=".$this->$key;\r
67                         }\r
68                 }\r
69                 return trim($connect_string);\r
70         }\r
71 \r
72         // --------------------------------------------------------------------\r
73 \r
74         /**\r
75          * Non-persistent database connection\r
76          *\r
77          * @access      private called by the base class\r
78          * @return      resource\r
79          */     \r
80         function db_connect()\r
81         {               \r
82                 return @pg_connect($this->_connect_string());\r
83         }\r
84 \r
85         // --------------------------------------------------------------------\r
86 \r
87         /**\r
88          * Persistent database connection\r
89          *\r
90          * @access      private called by the base class\r
91          * @return      resource\r
92          */     \r
93         function db_pconnect()\r
94         {\r
95                 return @pg_pconnect($this->_connect_string());\r
96         }\r
97         \r
98         // --------------------------------------------------------------------\r
99 \r
100         /**\r
101          * Select the database\r
102          *\r
103          * @access      private called by the base class\r
104          * @return      resource\r
105          */     \r
106         function db_select()\r
107         {\r
108                 // Not needed for Postgre so we'll return TRUE\r
109                 return TRUE;\r
110         }\r
111 \r
112         // --------------------------------------------------------------------\r
113 \r
114         /**\r
115          * Set client character set\r
116          *\r
117          * @access      public\r
118          * @param       string\r
119          * @param       string\r
120          * @return      resource\r
121          */\r
122         function db_set_charset($charset, $collation)\r
123         {\r
124                 // @todo - add support if needed\r
125                 return TRUE;\r
126         }\r
127 \r
128         // --------------------------------------------------------------------\r
129         \r
130         /**\r
131          * Version number query string\r
132          *\r
133          * @access      public\r
134          * @return      string\r
135          */\r
136         function _version()\r
137         {\r
138                 return "SELECT version() AS ver";\r
139         }\r
140 \r
141         // --------------------------------------------------------------------\r
142 \r
143         /**\r
144          * Execute the query\r
145          *\r
146          * @access      private called by the base class\r
147          * @param       string  an SQL query\r
148          * @return      resource\r
149          */     \r
150         function _execute($sql)\r
151         {\r
152                 $sql = $this->_prep_query($sql);\r
153                 return @pg_query($this->conn_id, $sql);\r
154         }\r
155         \r
156         // --------------------------------------------------------------------\r
157 \r
158         /**\r
159          * Prep the query\r
160          *\r
161          * If needed, each database adapter can prep the query string\r
162          *\r
163          * @access      private called by execute()\r
164          * @param       string  an SQL query\r
165          * @return      string\r
166          */     \r
167         function _prep_query($sql)\r
168         {\r
169                 return $sql;\r
170         }\r
171 \r
172         // --------------------------------------------------------------------\r
173 \r
174         /**\r
175          * Begin Transaction\r
176          *\r
177          * @access      public\r
178          * @return      bool            \r
179          */     \r
180         function trans_begin($test_mode = FALSE)\r
181         {\r
182                 if ( ! $this->trans_enabled)\r
183                 {\r
184                         return TRUE;\r
185                 }\r
186                 \r
187                 // When transactions are nested we only begin/commit/rollback the outermost ones\r
188                 if ($this->_trans_depth > 0)\r
189                 {\r
190                         return TRUE;\r
191                 }\r
192 \r
193                 // Reset the transaction failure flag.\r
194                 // If the $test_mode flag is set to TRUE transactions will be rolled back\r
195                 // even if the queries produce a successful result.\r
196                 $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;\r
197 \r
198                 return @pg_exec($this->conn_id, "begin");\r
199         }\r
200 \r
201         // --------------------------------------------------------------------\r
202 \r
203         /**\r
204          * Commit Transaction\r
205          *\r
206          * @access      public\r
207          * @return      bool            \r
208          */     \r
209         function trans_commit()\r
210         {\r
211                 if ( ! $this->trans_enabled)\r
212                 {\r
213                         return TRUE;\r
214                 }\r
215 \r
216                 // When transactions are nested we only begin/commit/rollback the outermost ones\r
217                 if ($this->_trans_depth > 0)\r
218                 {\r
219                         return TRUE;\r
220                 }\r
221 \r
222                 return @pg_exec($this->conn_id, "commit");\r
223         }\r
224 \r
225         // --------------------------------------------------------------------\r
226 \r
227         /**\r
228          * Rollback Transaction\r
229          *\r
230          * @access      public\r
231          * @return      bool            \r
232          */     \r
233         function trans_rollback()\r
234         {\r
235                 if ( ! $this->trans_enabled)\r
236                 {\r
237                         return TRUE;\r
238                 }\r
239 \r
240                 // When transactions are nested we only begin/commit/rollback the outermost ones\r
241                 if ($this->_trans_depth > 0)\r
242                 {\r
243                         return TRUE;\r
244                 }\r
245 \r
246                 return @pg_exec($this->conn_id, "rollback");\r
247         }\r
248 \r
249         // --------------------------------------------------------------------\r
250 \r
251         /**\r
252          * Escape String\r
253          *\r
254          * @access      public\r
255          * @param       string\r
256          * @return      string\r
257          */\r
258         function escape_str($str)       \r
259         {       \r
260                 return pg_escape_string($str);\r
261         }\r
262                 \r
263         // --------------------------------------------------------------------\r
264 \r
265         /**\r
266          * Affected Rows\r
267          *\r
268          * @access      public\r
269          * @return      integer\r
270          */\r
271         function affected_rows()\r
272         {\r
273                 return @pg_affected_rows($this->result_id);\r
274         }\r
275         \r
276         // --------------------------------------------------------------------\r
277 \r
278         /**\r
279          * Insert ID\r
280          *\r
281          * @access      public\r
282          * @return      integer\r
283          */\r
284         function insert_id()\r
285         {\r
286                 $v = $this->_version();\r
287                 $v = $v['server'];\r
288                 \r
289                 $table  = func_num_args() > 0 ? func_get_arg(0) : null;\r
290                 $column = func_num_args() > 1 ? func_get_arg(1) : null;\r
291                 \r
292                 if ($table == null && $v >= '8.1')\r
293                 {\r
294                         $sql='SELECT LASTVAL() as ins_id';\r
295                 }\r
296                 elseif ($table != null && $column != null && $v >= '8.0')\r
297                 {\r
298                         $sql = sprintf("SELECT pg_get_serial_sequence('%s','%s') as seq", $table, $column);\r
299                         $query = $this->query($sql);\r
300                         $row = $query->row();\r
301                         $sql = sprintf("SELECT CURRVAL('%s') as ins_id", $row->seq);\r
302                 }\r
303                 elseif ($table != null)\r
304                 {\r
305                         // seq_name passed in table parameter\r
306                         $sql = sprintf("SELECT CURRVAL('%s') as ins_id", $table);\r
307                 }\r
308                 else\r
309                 {\r
310                         return pg_last_oid($this->result_id);\r
311                 }\r
312                 $query = $this->query($sql);\r
313                 $row = $query->row();\r
314                 return $row->ins_id;\r
315         }\r
316 \r
317         // --------------------------------------------------------------------\r
318 \r
319         /**\r
320          * "Count All" query\r
321          *\r
322          * Generates a platform-specific query string that counts all records in\r
323          * the specified database\r
324          *\r
325          * @access      public\r
326          * @param       string\r
327          * @return      string\r
328          */\r
329         function count_all($table = '')\r
330         {\r
331                 if ($table == '')\r
332                         return '0';\r
333 \r
334                 $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));\r
335                                 \r
336                 if ($query->num_rows() == 0)\r
337                         return '0';\r
338 \r
339                 $row = $query->row();\r
340                 return $row->numrows;\r
341         }\r
342 \r
343         // --------------------------------------------------------------------\r
344 \r
345         /**\r
346          * Show table query\r
347          *\r
348          * Generates a platform-specific query string so that the table names can be fetched\r
349          *\r
350          * @access      private\r
351          * @param       boolean\r
352          * @return      string\r
353          */\r
354         function _list_tables($prefix_limit = FALSE)\r
355         {       \r
356                 $sql = "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'";        \r
357                 \r
358                 if ($prefix_limit !== FALSE AND $this->dbprefix != '')\r
359                 {\r
360                         $sql .= " AND table_name LIKE '".$this->dbprefix."%'";\r
361                 }\r
362                 \r
363                 return $sql;\r
364         }\r
365         \r
366         // --------------------------------------------------------------------\r
367 \r
368         /**\r
369          * Show column query\r
370          *\r
371          * Generates a platform-specific query string so that the column names can be fetched\r
372          *\r
373          * @access      public\r
374          * @param       string  the table name\r
375          * @return      string\r
376          */\r
377         function _list_columns($table = '')\r
378         {\r
379                 return "SELECT column_name FROM information_schema.columns WHERE table_name ='".$table."'";\r
380         }\r
381 \r
382         // --------------------------------------------------------------------\r
383 \r
384         /**\r
385          * Field data query\r
386          *\r
387          * Generates a platform-specific query so that the column data can be retrieved\r
388          *\r
389          * @access      public\r
390          * @param       string  the table name\r
391          * @return      object\r
392          */\r
393         function _field_data($table)\r
394         {\r
395                 return "SELECT * FROM ".$table." LIMIT 1";\r
396         }\r
397 \r
398         // --------------------------------------------------------------------\r
399 \r
400         /**\r
401          * The error message string\r
402          *\r
403          * @access      private\r
404          * @return      string\r
405          */\r
406         function _error_message()\r
407         {\r
408                 return pg_last_error($this->conn_id);\r
409         }\r
410         \r
411         // --------------------------------------------------------------------\r
412 \r
413         /**\r
414          * The error message number\r
415          *\r
416          * @access      private\r
417          * @return      integer\r
418          */\r
419         function _error_number()\r
420         {\r
421                 return '';\r
422         }\r
423 \r
424         // --------------------------------------------------------------------\r
425 \r
426         /**\r
427          * Escape the SQL Identifiers\r
428          *\r
429          * This function escapes column and table names\r
430          *\r
431          * @access      private\r
432          * @param       string\r
433          * @return      string\r
434          */\r
435         function _escape_identifiers($item)\r
436         {\r
437                 if ($this->_escape_char == '')\r
438                 {\r
439                         return $item;\r
440                 }\r
441         \r
442                 if (strpos($item, '.') !== FALSE)\r
443                 {\r
444                         $str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;                    \r
445                 }\r
446                 else\r
447                 {\r
448                         $str = $this->_escape_char.$item.$this->_escape_char;\r
449                 }\r
450                 \r
451                 // remove duplicates if the user already included the escape\r
452                 return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);\r
453         }\r
454                         \r
455         // --------------------------------------------------------------------\r
456 \r
457         /**\r
458          * From Tables\r
459          *\r
460          * This function implicitly groups FROM tables so there is no confusion\r
461          * about operator precedence in harmony with SQL standards\r
462          *\r
463          * @access      public\r
464          * @param       type\r
465          * @return      type\r
466          */\r
467         function _from_tables($tables)\r
468         {\r
469                 if ( ! is_array($tables))\r
470                 {\r
471                         $tables = array($tables);\r
472                 }\r
473                 \r
474                 return implode(', ', $tables);\r
475         }\r
476 \r
477         // --------------------------------------------------------------------\r
478         \r
479         /**\r
480          * Insert statement\r
481          *\r
482          * Generates a platform-specific insert string from the supplied data\r
483          *\r
484          * @access      public\r
485          * @param       string  the table name\r
486          * @param       array   the insert keys\r
487          * @param       array   the insert values\r
488          * @return      string\r
489          */\r
490         function _insert($table, $keys, $values)\r
491         {       \r
492                 return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";\r
493         }\r
494         \r
495         // --------------------------------------------------------------------\r
496 \r
497         /**\r
498          * Update statement\r
499          *\r
500          * Generates a platform-specific update string from the supplied data\r
501          *\r
502          * @access      public\r
503          * @param       string  the table name\r
504          * @param       array   the update data\r
505          * @param       array   the where clause\r
506          * @param       array   the orderby clause\r
507          * @param       array   the limit clause\r
508          * @return      string\r
509          */\r
510         function _update($table, $values, $where, $orderby = array(), $limit = FALSE)\r
511         {\r
512                 foreach($values as $key => $val)\r
513                 {\r
514                         $valstr[] = $key." = ".$val;\r
515                 }\r
516                 \r
517                 $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;\r
518                 \r
519                 $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';\r
520         \r
521                 $sql = "UPDATE ".$table." SET ".implode(', ', $valstr);\r
522 \r
523                 $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';\r
524 \r
525                 $sql .= $orderby.$limit;\r
526                 \r
527                 return $sql;\r
528         }\r
529 \r
530         // --------------------------------------------------------------------\r
531 \r
532         /**\r
533          * Truncate statement\r
534          *\r
535          * Generates a platform-specific truncate string from the supplied data\r
536          * If the database does not support the truncate() command\r
537          * This function maps to "DELETE FROM table"\r
538          *\r
539          * @access      public\r
540          * @param       string  the table name\r
541          * @return      string\r
542          */     \r
543         function _truncate($table)\r
544         {\r
545                 return "TRUNCATE ".$table;\r
546         }\r
547         \r
548         // --------------------------------------------------------------------\r
549 \r
550         /**\r
551          * Delete statement\r
552          *\r
553          * Generates a platform-specific delete string from the supplied data\r
554          *\r
555          * @access      public\r
556          * @param       string  the table name\r
557          * @param       array   the where clause\r
558          * @param       string  the limit clause\r
559          * @return      string\r
560          */     \r
561         function _delete($table, $where = array(), $like = array(), $limit = FALSE)\r
562         {\r
563                 $conditions = '';\r
564 \r
565                 if (count($where) > 0 OR count($like) > 0)\r
566                 {\r
567                         $conditions = "\nWHERE ";\r
568                         $conditions .= implode("\n", $this->ar_where);\r
569 \r
570                         if (count($where) > 0 && count($like) > 0)\r
571                         {\r
572                                 $conditions .= " AND ";\r
573                         }\r
574                         $conditions .= implode("\n", $like);\r
575                 }\r
576 \r
577                 $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;\r
578         \r
579                 return "DELETE FROM ".$table.$conditions.$limit;\r
580         }\r
581 \r
582         // --------------------------------------------------------------------\r
583         /**\r
584          * Limit string\r
585          *\r
586          * Generates a platform-specific LIMIT clause\r
587          *\r
588          * @access      public\r
589          * @param       string  the sql query string\r
590          * @param       integer the number of rows to limit the query to\r
591          * @param       integer the offset value\r
592          * @return      string\r
593          */\r
594         function _limit($sql, $limit, $offset)\r
595         {       \r
596                 $sql .= "LIMIT ".$limit;\r
597         \r
598                 if ($offset > 0)\r
599                 {\r
600                         $sql .= " OFFSET ".$offset;\r
601                 }\r
602                 \r
603                 return $sql;\r
604         }\r
605 \r
606         // --------------------------------------------------------------------\r
607 \r
608         /**\r
609          * Close DB Connection\r
610          *\r
611          * @access      public\r
612          * @param       resource\r
613          * @return      void\r
614          */\r
615         function _close($conn_id)\r
616         {\r
617                 @pg_close($conn_id);\r
618         }\r
619 \r
620 \r
621 }\r
622 \r
623 \r
624 /* End of file postgre_driver.php */\r
625 /* Location: ./system/database/drivers/postgre/postgre_driver.php */