Take two:
[www-register-wizard.git] / database / drivers / odbc / odbc_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  * ODBC 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_odbc_driver extends CI_DB {\r
32 \r
33         var $dbdriver = 'odbc';\r
34         \r
35         // the character used to excape - not necessary for ODBC\r
36         var $_escape_char = '';\r
37 \r
38         /**\r
39          * The syntax to count rows is slightly different across different\r
40          * database engines, so this string appears in each driver and is\r
41          * used for the count_all() and count_all_results() functions.\r
42          */\r
43         var $_count_string = "SELECT COUNT(*) AS ";\r
44         var $_random_keyword;\r
45 \r
46 \r
47         function CI_DB_odbc_driver($params)\r
48         {\r
49                 parent::CI_DB($params);\r
50                 \r
51                 $this->_random_keyword = ' RND('.time().')'; // database specific random keyword\r
52         }\r
53 \r
54         /**\r
55          * Non-persistent database connection\r
56          *\r
57          * @access      private called by the base class\r
58          * @return      resource\r
59          */     \r
60         function db_connect()\r
61         {\r
62                 return @odbc_connect($this->hostname, $this->username, $this->password);\r
63         }\r
64         \r
65         // --------------------------------------------------------------------\r
66 \r
67         /**\r
68          * Persistent database connection\r
69          *\r
70          * @access      private called by the base class\r
71          * @return      resource\r
72          */     \r
73         function db_pconnect()\r
74         {\r
75                 return @odbc_pconnect($this->hostname, $this->username, $this->password);\r
76         }\r
77         \r
78         // --------------------------------------------------------------------\r
79 \r
80         /**\r
81          * Select the database\r
82          *\r
83          * @access      private called by the base class\r
84          * @return      resource\r
85          */     \r
86         function db_select()\r
87         {\r
88                 // Not needed for ODBC\r
89                 return TRUE;\r
90         }\r
91 \r
92         // --------------------------------------------------------------------\r
93 \r
94         /**\r
95          * Set client character set\r
96          *\r
97          * @access      public\r
98          * @param       string\r
99          * @param       string\r
100          * @return      resource\r
101          */\r
102         function db_set_charset($charset, $collation)\r
103         {\r
104                 // @todo - add support if needed\r
105                 return TRUE;\r
106         }\r
107 \r
108         // --------------------------------------------------------------------\r
109         \r
110         /**\r
111          * Version number query string\r
112          *\r
113          * @access      public\r
114          * @return      string\r
115          */\r
116         function _version()\r
117         {\r
118                 return "SELECT version() AS ver";\r
119         }\r
120 \r
121         // --------------------------------------------------------------------\r
122 \r
123         /**\r
124          * Execute the query\r
125          *\r
126          * @access      private called by the base class\r
127          * @param       string  an SQL query\r
128          * @return      resource\r
129          */     \r
130         function _execute($sql)\r
131         {\r
132                 $sql = $this->_prep_query($sql);\r
133                 return @odbc_exec($this->conn_id, $sql);\r
134         }\r
135         \r
136         // --------------------------------------------------------------------\r
137 \r
138         /**\r
139          * Prep the query\r
140          *\r
141          * If needed, each database adapter can prep the query string\r
142          *\r
143          * @access      private called by execute()\r
144          * @param       string  an SQL query\r
145          * @return      string\r
146          */     \r
147         function _prep_query($sql)\r
148         {\r
149                 return $sql;\r
150         }\r
151 \r
152         // --------------------------------------------------------------------\r
153 \r
154         /**\r
155          * Begin Transaction\r
156          *\r
157          * @access      public\r
158          * @return      bool            \r
159          */     \r
160         function trans_begin($test_mode = FALSE)\r
161         {\r
162                 if ( ! $this->trans_enabled)\r
163                 {\r
164                         return TRUE;\r
165                 }\r
166                 \r
167                 // When transactions are nested we only begin/commit/rollback the outermost ones\r
168                 if ($this->_trans_depth > 0)\r
169                 {\r
170                         return TRUE;\r
171                 }\r
172 \r
173                 // Reset the transaction failure flag.\r
174                 // If the $test_mode flag is set to TRUE transactions will be rolled back\r
175                 // even if the queries produce a successful result.\r
176                 $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;\r
177 \r
178                 return odbc_autocommit($this->conn_id, FALSE);\r
179         }\r
180 \r
181         // --------------------------------------------------------------------\r
182 \r
183         /**\r
184          * Commit Transaction\r
185          *\r
186          * @access      public\r
187          * @return      bool            \r
188          */     \r
189         function trans_commit()\r
190         {\r
191                 if ( ! $this->trans_enabled)\r
192                 {\r
193                         return TRUE;\r
194                 }\r
195 \r
196                 // When transactions are nested we only begin/commit/rollback the outermost ones\r
197                 if ($this->_trans_depth > 0)\r
198                 {\r
199                         return TRUE;\r
200                 }\r
201 \r
202                 $ret = odbc_commit($this->conn_id);\r
203                 odbc_autocommit($this->conn_id, TRUE);\r
204                 return $ret;\r
205         }\r
206 \r
207         // --------------------------------------------------------------------\r
208 \r
209         /**\r
210          * Rollback Transaction\r
211          *\r
212          * @access      public\r
213          * @return      bool            \r
214          */     \r
215         function trans_rollback()\r
216         {\r
217                 if ( ! $this->trans_enabled)\r
218                 {\r
219                         return TRUE;\r
220                 }\r
221 \r
222                 // When transactions are nested we only begin/commit/rollback the outermost ones\r
223                 if ($this->_trans_depth > 0)\r
224                 {\r
225                         return TRUE;\r
226                 }\r
227 \r
228                 $ret = odbc_rollback($this->conn_id);\r
229                 odbc_autocommit($this->conn_id, TRUE);\r
230                 return $ret;\r
231         }\r
232 \r
233         // --------------------------------------------------------------------\r
234 \r
235         /**\r
236          * Escape String\r
237          *\r
238          * @access      public\r
239          * @param       string\r
240          * @return      string\r
241          */\r
242         function escape_str($str)       \r
243         {\r
244                 // Access the CI object\r
245                 $CI =& get_instance();\r
246 \r
247                 // ODBC doesn't require escaping\r
248                 return $CI->_remove_invisible_characters($str);\r
249         }\r
250         \r
251         // --------------------------------------------------------------------\r
252 \r
253         /**\r
254          * Affected Rows\r
255          *\r
256          * @access      public\r
257          * @return      integer\r
258          */\r
259         function affected_rows()\r
260         {\r
261                 return @odbc_num_rows($this->conn_id);\r
262         }\r
263         \r
264         // --------------------------------------------------------------------\r
265 \r
266         /**\r
267          * Insert ID\r
268          *\r
269          * @access      public\r
270          * @return      integer\r
271          */\r
272         function insert_id()\r
273         {\r
274                 return @odbc_insert_id($this->conn_id);\r
275         }\r
276 \r
277         // --------------------------------------------------------------------\r
278 \r
279         /**\r
280          * "Count All" query\r
281          *\r
282          * Generates a platform-specific query string that counts all records in\r
283          * the specified database\r
284          *\r
285          * @access      public\r
286          * @param       string\r
287          * @return      string\r
288          */\r
289         function count_all($table = '')\r
290         {\r
291                 if ($table == '')\r
292                         return '0';\r
293         \r
294                 $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));\r
295         \r
296                 if ($query->num_rows() == 0)\r
297                         return '0';\r
298 \r
299                 $row = $query->row();\r
300                 return $row->numrows;\r
301         }\r
302 \r
303         // --------------------------------------------------------------------\r
304 \r
305         /**\r
306          * Show table query\r
307          *\r
308          * Generates a platform-specific query string so that the table names can be fetched\r
309          *\r
310          * @access      private\r
311          * @param       boolean\r
312          * @return      string\r
313          */\r
314         function _list_tables($prefix_limit = FALSE)\r
315         {\r
316                 $sql = "SHOW TABLES FROM `".$this->database."`";\r
317 \r
318                 if ($prefix_limit !== FALSE AND $this->dbprefix != '')\r
319                 {\r
320                         //$sql .= " LIKE '".$this->dbprefix."%'";\r
321                         return FALSE; // not currently supported\r
322                 }\r
323                 \r
324                 return $sql;\r
325         }\r
326         \r
327         // --------------------------------------------------------------------\r
328 \r
329         /**\r
330          * Show column query\r
331          *\r
332          * Generates a platform-specific query string so that the column names can be fetched\r
333          *\r
334          * @access      public\r
335          * @param       string  the table name\r
336          * @return      string\r
337          */\r
338         function _list_columns($table = '')\r
339         {\r
340                 return "SHOW COLUMNS FROM ".$table;\r
341         }\r
342 \r
343         // --------------------------------------------------------------------\r
344 \r
345         /**\r
346          * Field data query\r
347          *\r
348          * Generates a platform-specific query so that the column data can be retrieved\r
349          *\r
350          * @access      public\r
351          * @param       string  the table name\r
352          * @return      object\r
353          */\r
354         function _field_data($table)\r
355         {\r
356                 return "SELECT TOP 1 FROM ".$table;\r
357         }\r
358 \r
359         // --------------------------------------------------------------------\r
360 \r
361         /**\r
362          * The error message string\r
363          *\r
364          * @access      private\r
365          * @return      string\r
366          */\r
367         function _error_message()\r
368         {\r
369                 return odbc_errormsg($this->conn_id);\r
370         }\r
371         \r
372         // --------------------------------------------------------------------\r
373 \r
374         /**\r
375          * The error message number\r
376          *\r
377          * @access      private\r
378          * @return      integer\r
379          */\r
380         function _error_number()\r
381         {\r
382                 return odbc_error($this->conn_id);\r
383         }\r
384 \r
385         // --------------------------------------------------------------------\r
386 \r
387         /**\r
388          * Escape the SQL Identifiers\r
389          *\r
390          * This function escapes column and table names\r
391          *\r
392          * @access      private\r
393          * @param       string\r
394          * @return      string\r
395          */\r
396         function _escape_identifiers($item)\r
397         {\r
398                 if ($this->_escape_char == '')\r
399                 {\r
400                         return $item;\r
401                 }\r
402         \r
403                 if (strpos($item, '.') !== FALSE)\r
404                 {\r
405                         $str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;                    \r
406                 }\r
407                 else\r
408                 {\r
409                         $str = $this->_escape_char.$item.$this->_escape_char;\r
410                 }\r
411                 \r
412                 // remove duplicates if the user already included the escape\r
413                 return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);\r
414         }\r
415                         \r
416         // --------------------------------------------------------------------\r
417 \r
418         /**\r
419          * From Tables\r
420          *\r
421          * This function implicitly groups FROM tables so there is no confusion\r
422          * about operator precedence in harmony with SQL standards\r
423          *\r
424          * @access      public\r
425          * @param       type\r
426          * @return      type\r
427          */\r
428         function _from_tables($tables)\r
429         {\r
430                 if ( ! is_array($tables))\r
431                 {\r
432                         $tables = array($tables);\r
433                 }\r
434                 \r
435                 return '('.implode(', ', $tables).')';\r
436         }\r
437 \r
438         // --------------------------------------------------------------------\r
439         \r
440         /**\r
441          * Insert statement\r
442          *\r
443          * Generates a platform-specific insert string from the supplied data\r
444          *\r
445          * @access      public\r
446          * @param       string  the table name\r
447          * @param       array   the insert keys\r
448          * @param       array   the insert values\r
449          * @return      string\r
450          */\r
451         function _insert($table, $keys, $values)\r
452         {       \r
453                 return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";\r
454         }\r
455         \r
456         // --------------------------------------------------------------------\r
457 \r
458         /**\r
459          * Update statement\r
460          *\r
461          * Generates a platform-specific update string from the supplied data\r
462          *\r
463          * @access      public\r
464          * @param       string  the table name\r
465          * @param       array   the update data\r
466          * @param       array   the where clause\r
467          * @param       array   the orderby clause\r
468          * @param       array   the limit clause\r
469          * @return      string\r
470          */\r
471         function _update($table, $values, $where, $orderby = array(), $limit = FALSE)\r
472         {\r
473                 foreach($values as $key => $val)\r
474                 {\r
475                         $valstr[] = $key." = ".$val;\r
476                 }\r
477                 \r
478                 $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;\r
479                 \r
480                 $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';\r
481         \r
482                 $sql = "UPDATE ".$table." SET ".implode(', ', $valstr);\r
483 \r
484                 $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';\r
485 \r
486                 $sql .= $orderby.$limit;\r
487                 \r
488                 return $sql;\r
489         }\r
490 \r
491         \r
492         // --------------------------------------------------------------------\r
493 \r
494         /**\r
495          * Truncate statement\r
496          *\r
497          * Generates a platform-specific truncate string from the supplied data\r
498          * If the database does not support the truncate() command\r
499          * This function maps to "DELETE FROM table"\r
500          *\r
501          * @access      public\r
502          * @param       string  the table name\r
503          * @return      string\r
504          */     \r
505         function _truncate($table)\r
506         {\r
507                 return $this->_delete($table);\r
508         }\r
509         \r
510         // --------------------------------------------------------------------\r
511 \r
512         /**\r
513          * Delete statement\r
514          *\r
515          * Generates a platform-specific delete string from the supplied data\r
516          *\r
517          * @access      public\r
518          * @param       string  the table name\r
519          * @param       array   the where clause\r
520          * @param       string  the limit clause\r
521          * @return      string\r
522          */     \r
523         function _delete($table, $where = array(), $like = array(), $limit = FALSE)\r
524         {\r
525                 $conditions = '';\r
526 \r
527                 if (count($where) > 0 OR count($like) > 0)\r
528                 {\r
529                         $conditions = "\nWHERE ";\r
530                         $conditions .= implode("\n", $this->ar_where);\r
531 \r
532                         if (count($where) > 0 && count($like) > 0)\r
533                         {\r
534                                 $conditions .= " AND ";\r
535                         }\r
536                         $conditions .= implode("\n", $like);\r
537                 }\r
538 \r
539                 $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;\r
540         \r
541                 return "DELETE FROM ".$table.$conditions.$limit;\r
542         }\r
543 \r
544         // --------------------------------------------------------------------\r
545 \r
546         /**\r
547          * Limit string\r
548          *\r
549          * Generates a platform-specific LIMIT clause\r
550          *\r
551          * @access      public\r
552          * @param       string  the sql query string\r
553          * @param       integer the number of rows to limit the query to\r
554          * @param       integer the offset value\r
555          * @return      string\r
556          */\r
557         function _limit($sql, $limit, $offset)\r
558         {\r
559                 // Does ODBC doesn't use the LIMIT clause?\r
560                 return $sql;\r
561         }\r
562 \r
563         // --------------------------------------------------------------------\r
564 \r
565         /**\r
566          * Close DB Connection\r
567          *\r
568          * @access      public\r
569          * @param       resource\r
570          * @return      void\r
571          */\r
572         function _close($conn_id)\r
573         {\r
574                 @odbc_close($conn_id);\r
575         }\r
576 \r
577         \r
578 }\r
579 \r
580 \r
581 \r
582 /* End of file odbc_driver.php */\r
583 /* Location: ./system/database/drivers/odbc/odbc_driver.php */