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