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