sqlite_driver.php

Go to the documentation of this file.
00001 <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
00002 /**
00003  * CodeIgniter
00004  *
00005  * An open source application development framework for PHP 4.3.2 or newer
00006  *
00007  * @package             CodeIgniter
00008  * @author              ExpressionEngine Dev Team
00009  * @copyright   Copyright (c) 2006, EllisLab, Inc.
00010  * @license             http://codeigniter.com/user_guide/license.html
00011  * @link                http://codeigniter.com
00012  * @since               Version 1.0
00013  * @filesource
00014  */
00015 
00016 // ------------------------------------------------------------------------
00017 
00018 
00019 
00020 /**
00021  * SQLite Database Adapter Class
00022  *
00023  * Note: _DB is an extender class that the app controller
00024  * creates dynamically based on whether the active record
00025  * class is being used or not.
00026  *
00027  * @package             CodeIgniter
00028  * @subpackage  Drivers
00029  * @category    Database
00030  * @author              ExpressionEngine Dev Team
00031  * @link                http://codeigniter.com/user_guide/database/
00032  */
00033 class CI_DB_sqlite_driver extends CI_DB {
00034 
00035         /**
00036          * The syntax to count rows is slightly different across different
00037          * database engines, so this string appears in each driver and is
00038          * used for the count_all() and count_all_results() functions.
00039          */
00040         var $_count_string = "SELECT COUNT(*) AS ";
00041         var $_random_keyword = ' Random()'; // database specific random keyword
00042 
00043         /**
00044          * Non-persistent database connection
00045          *
00046          * @access      private called by the base class
00047          * @return      resource
00048          */     
00049         function db_connect()
00050         {
00051                 if ( ! $conn_id = @sqlite_open($this->database, FILE_WRITE_MODE, $error))
00052                 {
00053                         log_message('error', $error);
00054                         
00055                         if ($this->db_debug)
00056                         {
00057                                 $this->display_error($error, '', TRUE);
00058                         }
00059                         
00060                         return FALSE;
00061                 }
00062                 
00063                 return $conn_id;
00064         }
00065         
00066         // --------------------------------------------------------------------
00067 
00068         /**
00069          * Persistent database connection
00070          *
00071          * @access      private called by the base class
00072          * @return      resource
00073          */     
00074         function db_pconnect()
00075         {
00076                 if ( ! $conn_id = @sqlite_popen($this->database, FILE_WRITE_MODE, $error))
00077                 {
00078                         log_message('error', $error);
00079                         
00080                         if ($this->db_debug)
00081                         {
00082                                 $this->display_error($error, '', TRUE);
00083                         }
00084                         
00085                         return FALSE;
00086                 }
00087                 
00088                 return $conn_id;
00089         }
00090         
00091         // --------------------------------------------------------------------
00092 
00093         /**
00094          * Select the database
00095          *
00096          * @access      private called by the base class
00097          * @return      resource
00098          */     
00099         function db_select()
00100         {
00101                 return TRUE;
00102         }
00103 
00104         // --------------------------------------------------------------------
00105 
00106         /**
00107          * Set client character set
00108          *
00109          * @access      public
00110          * @param       string
00111          * @param       string
00112          * @return      resource
00113          */
00114         function db_set_charset($charset, $collation)
00115         {
00116                 // TODO - add support if needed
00117                 return TRUE;
00118         }
00119 
00120         // --------------------------------------------------------------------
00121         
00122         /**
00123          * Version number query string
00124          *
00125          * @access      public
00126          * @return      string
00127          */
00128         function _version()
00129         {
00130                 return sqlite_libversion();
00131         }
00132         
00133         // --------------------------------------------------------------------
00134 
00135         /**
00136          * Execute the query
00137          *
00138          * @access      private called by the base class
00139          * @param       string  an SQL query
00140          * @return      resource
00141          */     
00142         function _execute($sql)
00143         {
00144                 $sql = $this->_prep_query($sql);
00145                 return @sqlite_query($this->conn_id, $sql);
00146         }
00147         
00148         // --------------------------------------------------------------------
00149 
00150         /**
00151          * Prep the query
00152          *
00153          * If needed, each database adapter can prep the query string
00154          *
00155          * @access      private called by execute()
00156          * @param       string  an SQL query
00157          * @return      string
00158          */     
00159         function _prep_query($sql)
00160         {
00161                 return $sql;
00162         }
00163 
00164         // --------------------------------------------------------------------
00165 
00166         /**
00167          * Begin Transaction
00168          *
00169          * @access      public
00170          * @return      bool            
00171          */     
00172         function trans_begin($test_mode = FALSE)
00173         {
00174                 if ( ! $this->trans_enabled)
00175                 {
00176                         return TRUE;
00177                 }
00178                 
00179                 // When transactions are nested we only begin/commit/rollback the outermost ones
00180                 if ($this->_trans_depth > 0)
00181                 {
00182                         return TRUE;
00183                 }
00184 
00185                 // Reset the transaction failure flag.
00186                 // If the $test_mode flag is set to TRUE transactions will be rolled back
00187                 // even if the queries produce a successful result.
00188                 $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
00189 
00190                 $this->simple_query('BEGIN TRANSACTION');
00191                 return TRUE;
00192         }
00193 
00194         // --------------------------------------------------------------------
00195 
00196         /**
00197          * Commit Transaction
00198          *
00199          * @access      public
00200          * @return      bool            
00201          */     
00202         function trans_commit()
00203         {
00204                 if ( ! $this->trans_enabled)
00205                 {
00206                         return TRUE;
00207                 }
00208 
00209                 // When transactions are nested we only begin/commit/rollback the outermost ones
00210                 if ($this->_trans_depth > 0)
00211                 {
00212                         return TRUE;
00213                 }
00214 
00215                 $this->simple_query('COMMIT');
00216                 return TRUE;
00217         }
00218 
00219         // --------------------------------------------------------------------
00220 
00221         /**
00222          * Rollback Transaction
00223          *
00224          * @access      public
00225          * @return      bool            
00226          */     
00227         function trans_rollback()
00228         {
00229                 if ( ! $this->trans_enabled)
00230                 {
00231                         return TRUE;
00232                 }
00233 
00234                 // When transactions are nested we only begin/commit/rollback the outermost ones
00235                 if ($this->_trans_depth > 0)
00236                 {
00237                         return TRUE;
00238                 }
00239 
00240                 $this->simple_query('ROLLBACK');
00241                 return TRUE;
00242         }
00243         
00244         // --------------------------------------------------------------------
00245 
00246         /**
00247          * Escape String
00248          *
00249          * @access      public
00250          * @param       string
00251          * @return      string
00252          */
00253         function escape_str($str)       
00254         {
00255                 return sqlite_escape_string($str);
00256         }
00257                 
00258         // --------------------------------------------------------------------
00259 
00260         /**
00261          * Affected Rows
00262          *
00263          * @access      public
00264          * @return      integer
00265          */
00266         function affected_rows()
00267         {
00268                 return sqlite_changes($this->conn_id);
00269         }
00270         
00271         // --------------------------------------------------------------------
00272 
00273         /**
00274          * Insert ID
00275          *
00276          * @access      public
00277          * @return      integer
00278          */
00279         function insert_id()
00280         {
00281                 return @sqlite_last_insert_rowid($this->conn_id);
00282         }
00283 
00284         // --------------------------------------------------------------------
00285 
00286         /**
00287          * "Count All" query
00288          *
00289          * Generates a platform-specific query string that counts all records in
00290          * the specified database
00291          *
00292          * @access      public
00293          * @param       string
00294          * @return      string
00295          */
00296         function count_all($table = '')
00297         {
00298                 if ($table == '')
00299                         return '0';
00300         
00301                 $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($this->dbprefix.$table));
00302                 
00303                 if ($query->num_rows() == 0)
00304                         return '0';
00305 
00306                 $row = $query->row();
00307                 return $row->numrows;
00308         }
00309 
00310         // --------------------------------------------------------------------
00311 
00312         /**
00313          * List table query
00314          *
00315          * Generates a platform-specific query string so that the table names can be fetched
00316          *
00317          * @access      private
00318          * @param       boolean
00319          * @return      string
00320          */
00321         function _list_tables($prefix_limit = FALSE)
00322         {
00323                 $sql = "SELECT name from sqlite_master WHERE type='table'";
00324 
00325                 if ($prefix_limit !== FALSE AND $this->dbprefix != '')
00326                 {
00327                         $sql .= " AND 'name' LIKE '".$this->dbprefix."%'";
00328                 }
00329                 return $sql;
00330         }
00331 
00332         // --------------------------------------------------------------------
00333 
00334         /**
00335          * Show column query
00336          *
00337          * Generates a platform-specific query string so that the column names can be fetched
00338          *
00339          * @access      public
00340          * @param       string  the table name
00341          * @return      string
00342          */
00343         function _list_columns($table = '')
00344         {
00345                 // Not supported
00346                 return FALSE;
00347         }
00348 
00349         // --------------------------------------------------------------------
00350 
00351         /**
00352          * Field data query
00353          *
00354          * Generates a platform-specific query so that the column data can be retrieved
00355          *
00356          * @access      public
00357          * @param       string  the table name
00358          * @return      object
00359          */
00360         function _field_data($table)
00361         {
00362                 return "SELECT * FROM ".$this->_escape_table($table)." LIMIT 1";
00363         }
00364 
00365         // --------------------------------------------------------------------
00366 
00367         /**
00368          * The error message string
00369          *
00370          * @access      private
00371          * @return      string
00372          */
00373         function _error_message()
00374         {
00375                 return sqlite_error_string(sqlite_last_error($this->conn_id));
00376         }
00377         
00378         // --------------------------------------------------------------------
00379 
00380         /**
00381          * The error message number
00382          *
00383          * @access      private
00384          * @return      integer
00385          */
00386         function _error_number()
00387         {
00388                 return sqlite_last_error($this->conn_id);
00389         }
00390                 
00391         // --------------------------------------------------------------------
00392 
00393         /**
00394          * Escape Table Name
00395          *
00396          * This function adds backticks if the table name has a period
00397          * in it. Some DBs will get cranky unless periods are escaped
00398          *
00399          * @access      private
00400          * @param       string  the table name
00401          * @return      string
00402          */
00403         function _escape_table($table)
00404         {
00405 
00406                 // other database drivers use this to add backticks, hence this
00407                 // function is simply going to return the tablename for sqlite          
00408                 return $table;
00409         }
00410                 
00411         // --------------------------------------------------------------------
00412 
00413         /**
00414          * Protect Identifiers
00415          *
00416          * This function adds backticks if appropriate based on db type
00417          *
00418          * @access      private
00419          * @param       mixed   the item to escape
00420          * @param       boolean only affect the first word
00421          * @return      mixed   the item with backticks
00422          */
00423         function _protect_identifiers($item, $first_word_only = FALSE)
00424         {
00425                 if (is_array($item))
00426                 {
00427                         $escaped_array = array();
00428 
00429                         foreach($item as $k=>$v)
00430                         {
00431                                 $escaped_array[$this->_protect_identifiers($k)] = $this->_protect_identifiers($v, $first_word_only);
00432                         }
00433 
00434                         return $escaped_array;
00435                 }       
00436 
00437                 // This function may get "item1 item2" as a string, and so
00438                 // we may need "item1 item2" and not "item1 item2"
00439                 if (ctype_alnum($item) === FALSE)
00440                 {
00441                         if (strpos($item, '.') !== FALSE)
00442                         {
00443                                 $aliased_tables = implode(".",$this->ar_aliased_tables).'.';
00444                                 $table_name =  substr($item, 0, strpos($item, '.')+1);
00445                                 $item = (strpos($aliased_tables, $table_name) !== FALSE) ? $item = $item : $this->dbprefix.$item;
00446                         }
00447 
00448                         // This function may get "field >= 1", and need it to return "field >= 1"
00449                         $lbound = ($first_word_only === TRUE) ? '' : '|\s|\(';
00450 
00451                         $item = preg_replace('/(^'.$lbound.')([\w\d\-\_]+?)(\s|\)|$)/iS', '$1$2$3', $item);
00452                 }
00453                 else
00454                 {
00455                         return "{$item}";
00456                 }
00457 
00458                 $exceptions = array('AS', '/', '-', '%', '+', '*', 'OR', 'IS');
00459                 
00460                 foreach ($exceptions as $exception)
00461                 {
00462                 
00463                         if (stristr($item, " {$exception} ") !== FALSE)
00464                         {
00465                                 $item = preg_replace('/ ('.preg_quote($exception).') /i', ' $1 ', $item);
00466                         }
00467                 }
00468                 return $item;
00469         }
00470                         
00471         // --------------------------------------------------------------------
00472 
00473         /**
00474          * From Tables
00475          *
00476          * This function implicitly groups FROM tables so there is no confusion
00477          * about operator precedence in harmony with SQL standards
00478          *
00479          * @access      public
00480          * @param       type
00481          * @return      type
00482          */
00483         function _from_tables($tables)
00484         {
00485                 if ( ! is_array($tables))
00486                 {
00487                         $tables = array($tables);
00488                 }
00489                 
00490                 return '('.implode(', ', $tables).')';
00491         }
00492 
00493         // --------------------------------------------------------------------
00494         
00495         /**
00496          * Insert statement
00497          *
00498          * Generates a platform-specific insert string from the supplied data
00499          *
00500          * @access      public
00501          * @param       string  the table name
00502          * @param       array   the insert keys
00503          * @param       array   the insert values
00504          * @return      string
00505          */
00506         function _insert($table, $keys, $values)
00507         {       
00508                 return "INSERT INTO ".$this->_escape_table($table)." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
00509         }
00510         
00511         // --------------------------------------------------------------------
00512 
00513         /**
00514          * Update statement
00515          *
00516          * Generates a platform-specific update string from the supplied data
00517          *
00518          * @access      public
00519          * @param       string  the table name
00520          * @param       array   the update data
00521          * @param       array   the where clause
00522          * @param       array   the orderby clause
00523          * @param       array   the limit clause
00524          * @return      string
00525          */
00526         function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
00527         {
00528                 foreach($values as $key => $val)
00529                 {
00530                         $valstr[] = $key." = ".$val;
00531                 }
00532                 
00533                 $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
00534                 
00535                 $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
00536         
00537                 $sql = "UPDATE ".$this->_escape_table($table)." SET ".implode(', ', $valstr);
00538                 $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
00539                 $sql .= $orderby.$limit;
00540                 
00541                 return $sql;
00542         }
00543 
00544         
00545         // --------------------------------------------------------------------
00546 
00547         /**
00548          * Truncate statement
00549          *
00550          * Generates a platform-specific truncate string from the supplied data
00551          * If the database does not support the truncate() command
00552          * This function maps to "DELETE FROM table"
00553          *
00554          * @access      public
00555          * @param       string  the table name
00556          * @return      string
00557          */     
00558         function _truncate($table)
00559         {
00560                 return $this->_delete($table);
00561         }
00562         
00563         // --------------------------------------------------------------------
00564 
00565         /**
00566          * Delete statement
00567          *
00568          * Generates a platform-specific delete string from the supplied data
00569          *
00570          * @access      public
00571          * @param       string  the table name
00572          * @param       array   the where clause
00573          * @param       string  the limit clause
00574          * @return      string
00575          */     
00576         function _delete($table, $where = array(), $like = array(), $limit = FALSE)
00577         {
00578                 $conditions = '';
00579 
00580                 if (count($where) > 0 OR count($like) > 0)
00581                 {
00582                         $conditions = "\nWHERE ";
00583                         $conditions .= implode("\n", $this->ar_where);
00584 
00585                         if (count($where) > 0 && count($like) > 0)
00586                         {
00587                                 $conditions .= " AND ";
00588                         }
00589                         $conditions .= implode("\n", $like);
00590                 }
00591 
00592                 $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
00593         
00594                 return "DELETE FROM ".$table.$conditions.$limit;
00595         }
00596         
00597         // --------------------------------------------------------------------
00598 
00599         /**
00600          * Limit string
00601          *
00602          * Generates a platform-specific LIMIT clause
00603          *
00604          * @access      public
00605          * @param       string  the sql query string
00606          * @param       integer the number of rows to limit the query to
00607          * @param       integer the offset value
00608          * @return      string
00609          */
00610         function _limit($sql, $limit, $offset)
00611         {       
00612                 if ($offset == 0)
00613                 {
00614                         $offset = '';
00615                 }
00616                 else
00617                 {
00618                         $offset .= ", ";
00619                 }
00620                 
00621                 return $sql."LIMIT ".$offset.$limit;
00622         }
00623 
00624         // --------------------------------------------------------------------
00625 
00626         /**
00627          * Close DB Connection
00628          *
00629          * @access      public
00630          * @param       resource
00631          * @return      void
00632          */
00633         function _close($conn_id)
00634         {
00635                 @sqlite_close($conn_id);
00636         }
00637 
00638         // --------------------------------------------------------------------
00639 
00640         /**
00641          * Rename a table
00642          *
00643          * Generates a platform-specific query so that a table can be renamed
00644          *
00645          * @access      private
00646          * @param       string  the old table name
00647          * @param       string  the new table name
00648          * @return      string
00649          */
00650         function _rename_table($table_name, $new_table_name)
00651         {
00652                 $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);
00653                 return $sql;
00654         }
00655 
00656 
00657 }
00658 
00659 
00660 /* End of file sqlite_driver.php */
00661 /* Location: ./system/database/drivers/sqlite/sqlite_driver.php */