postgre_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) 2008, 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  * Postgre Database Adapter Class
00020  *
00021  * Note: _DB is an extender class that the app controller
00022  * creates dynamically based on whether the active record
00023  * class is being used or not.
00024  *
00025  * @package             CodeIgniter
00026  * @subpackage  Drivers
00027  * @category    Database
00028  * @author              ExpressionEngine Dev Team
00029  * @link                http://codeigniter.com/user_guide/database/
00030  */
00031 class CI_DB_postgre_driver extends CI_DB {
00032 
00033         var $dbdriver = 'postgre';
00034         
00035         var $_escape_char = '"';
00036 
00037         /**
00038          * The syntax to count rows is slightly different across different
00039          * database engines, so this string appears in each driver and is
00040          * used for the count_all() and count_all_results() functions.
00041          */
00042         var $_count_string = "SELECT COUNT(*) AS ";
00043         var $_random_keyword = ' RANDOM()'; // database specific random keyword
00044 
00045         /**
00046          * Connection String
00047          *
00048          * @access      private
00049          * @return      string
00050          */     
00051         function _connect_string()
00052         {
00053                 $components = array(
00054                                                                 'hostname'      => 'host',
00055                                                                 'port'          => 'port',
00056                                                                 'database'      => 'dbname',
00057                                                                 'username'      => 'user',
00058                                                                 'password'      => 'password'
00059                                                         );
00060                 
00061                 $connect_string = "";
00062                 foreach ($components as $key => $val)
00063                 {
00064                         if (isset($this->$key) && $this->$key != '')
00065                         {
00066                                 $connect_string .= " $val=".$this->$key;
00067                         }
00068                 }
00069                 return trim($connect_string);
00070         }
00071 
00072         // --------------------------------------------------------------------
00073 
00074         /**
00075          * Non-persistent database connection
00076          *
00077          * @access      private called by the base class
00078          * @return      resource
00079          */     
00080         function db_connect()
00081         {               
00082                 return @pg_connect($this->_connect_string());
00083         }
00084 
00085         // --------------------------------------------------------------------
00086 
00087         /**
00088          * Persistent database connection
00089          *
00090          * @access      private called by the base class
00091          * @return      resource
00092          */     
00093         function db_pconnect()
00094         {
00095                 return @pg_pconnect($this->_connect_string());
00096         }
00097         
00098         // --------------------------------------------------------------------
00099 
00100         /**
00101          * Select the database
00102          *
00103          * @access      private called by the base class
00104          * @return      resource
00105          */     
00106         function db_select()
00107         {
00108                 // Not needed for Postgre so we'll return TRUE
00109                 return TRUE;
00110         }
00111 
00112         // --------------------------------------------------------------------
00113 
00114         /**
00115          * Set client character set
00116          *
00117          * @access      public
00118          * @param       string
00119          * @param       string
00120          * @return      resource
00121          */
00122         function db_set_charset($charset, $collation)
00123         {
00124                 // @todo - add support if needed
00125                 return TRUE;
00126         }
00127 
00128         // --------------------------------------------------------------------
00129         
00130         /**
00131          * Version number query string
00132          *
00133          * @access      public
00134          * @return      string
00135          */
00136         function _version()
00137         {
00138                 return "SELECT version() AS ver";
00139         }
00140 
00141         // --------------------------------------------------------------------
00142 
00143         /**
00144          * Execute the query
00145          *
00146          * @access      private called by the base class
00147          * @param       string  an SQL query
00148          * @return      resource
00149          */     
00150         function _execute($sql)
00151         {
00152                 $sql = $this->_prep_query($sql);
00153                 return @pg_query($this->conn_id, $sql);
00154         }
00155         
00156         // --------------------------------------------------------------------
00157 
00158         /**
00159          * Prep the query
00160          *
00161          * If needed, each database adapter can prep the query string
00162          *
00163          * @access      private called by execute()
00164          * @param       string  an SQL query
00165          * @return      string
00166          */     
00167         function _prep_query($sql)
00168         {
00169                 return $sql;
00170         }
00171 
00172         // --------------------------------------------------------------------
00173 
00174         /**
00175          * Begin Transaction
00176          *
00177          * @access      public
00178          * @return      bool            
00179          */     
00180         function trans_begin($test_mode = FALSE)
00181         {
00182                 if ( ! $this->trans_enabled)
00183                 {
00184                         return TRUE;
00185                 }
00186                 
00187                 // When transactions are nested we only begin/commit/rollback the outermost ones
00188                 if ($this->_trans_depth > 0)
00189                 {
00190                         return TRUE;
00191                 }
00192 
00193                 // Reset the transaction failure flag.
00194                 // If the $test_mode flag is set to TRUE transactions will be rolled back
00195                 // even if the queries produce a successful result.
00196                 $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
00197 
00198                 return @pg_exec($this->conn_id, "begin");
00199         }
00200 
00201         // --------------------------------------------------------------------
00202 
00203         /**
00204          * Commit Transaction
00205          *
00206          * @access      public
00207          * @return      bool            
00208          */     
00209         function trans_commit()
00210         {
00211                 if ( ! $this->trans_enabled)
00212                 {
00213                         return TRUE;
00214                 }
00215 
00216                 // When transactions are nested we only begin/commit/rollback the outermost ones
00217                 if ($this->_trans_depth > 0)
00218                 {
00219                         return TRUE;
00220                 }
00221 
00222                 return @pg_exec($this->conn_id, "commit");
00223         }
00224 
00225         // --------------------------------------------------------------------
00226 
00227         /**
00228          * Rollback Transaction
00229          *
00230          * @access      public
00231          * @return      bool            
00232          */     
00233         function trans_rollback()
00234         {
00235                 if ( ! $this->trans_enabled)
00236                 {
00237                         return TRUE;
00238                 }
00239 
00240                 // When transactions are nested we only begin/commit/rollback the outermost ones
00241                 if ($this->_trans_depth > 0)
00242                 {
00243                         return TRUE;
00244                 }
00245 
00246                 return @pg_exec($this->conn_id, "rollback");
00247         }
00248 
00249         // --------------------------------------------------------------------
00250 
00251         /**
00252          * Escape String
00253          *
00254          * @access      public
00255          * @param       string
00256          * @return      string
00257          */
00258         function escape_str($str)       
00259         {       
00260                 return pg_escape_string($str);
00261         }
00262                 
00263         // --------------------------------------------------------------------
00264 
00265         /**
00266          * Affected Rows
00267          *
00268          * @access      public
00269          * @return      integer
00270          */
00271         function affected_rows()
00272         {
00273                 return @pg_affected_rows($this->result_id);
00274         }
00275         
00276         // --------------------------------------------------------------------
00277 
00278         /**
00279          * Insert ID
00280          *
00281          * @access      public
00282          * @return      integer
00283          */
00284         function insert_id()
00285         {
00286                 $v = $this->_version();
00287                 $v = $v['server'];
00288                 
00289                 $table  = func_num_args() > 0 ? func_get_arg(0) : null;
00290                 $column = func_num_args() > 1 ? func_get_arg(1) : null;
00291                 
00292                 if ($table == null && $v >= '8.1')
00293                 {
00294                         $sql='SELECT LASTVAL() as ins_id';
00295                 }
00296                 elseif ($table != null && $column != null && $v >= '8.0')
00297                 {
00298                         $sql = sprintf("SELECT pg_get_serial_sequence('%s','%s') as seq", $table, $column);
00299                         $query = $this->query($sql);
00300                         $row = $query->row();
00301                         $sql = sprintf("SELECT CURRVAL('%s') as ins_id", $row->seq);
00302                 }
00303                 elseif ($table != null)
00304                 {
00305                         // seq_name passed in table parameter
00306                         $sql = sprintf("SELECT CURRVAL('%s') as ins_id", $table);
00307                 }
00308                 else
00309                 {
00310                         return pg_last_oid($this->result_id);
00311                 }
00312                 $query = $this->query($sql);
00313                 $row = $query->row();
00314                 return $row->ins_id;
00315         }
00316 
00317         // --------------------------------------------------------------------
00318 
00319         /**
00320          * "Count All" query
00321          *
00322          * Generates a platform-specific query string that counts all records in
00323          * the specified database
00324          *
00325          * @access      public
00326          * @param       string
00327          * @return      string
00328          */
00329         function count_all($table = '')
00330         {
00331                 if ($table == '')
00332                         return '0';
00333 
00334                 $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
00335                                 
00336                 if ($query->num_rows() == 0)
00337                         return '0';
00338 
00339                 $row = $query->row();
00340                 return $row->numrows;
00341         }
00342 
00343         // --------------------------------------------------------------------
00344 
00345         /**
00346          * Show table query
00347          *
00348          * Generates a platform-specific query string so that the table names can be fetched
00349          *
00350          * @access      private
00351          * @param       boolean
00352          * @return      string
00353          */
00354         function _list_tables($prefix_limit = FALSE)
00355         {       
00356                 $sql = "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'";        
00357                 
00358                 if ($prefix_limit !== FALSE AND $this->dbprefix != '')
00359                 {
00360                         $sql .= " AND table_name LIKE '".$this->dbprefix."%'";
00361                 }
00362                 
00363                 return $sql;
00364         }
00365         
00366         // --------------------------------------------------------------------
00367 
00368         /**
00369          * Show column query
00370          *
00371          * Generates a platform-specific query string so that the column names can be fetched
00372          *
00373          * @access      public
00374          * @param       string  the table name
00375          * @return      string
00376          */
00377         function _list_columns($table = '')
00378         {
00379                 return "SELECT column_name FROM information_schema.columns WHERE table_name ='".$table."'";
00380         }
00381 
00382         // --------------------------------------------------------------------
00383 
00384         /**
00385          * Field data query
00386          *
00387          * Generates a platform-specific query so that the column data can be retrieved
00388          *
00389          * @access      public
00390          * @param       string  the table name
00391          * @return      object
00392          */
00393         function _field_data($table)
00394         {
00395                 return "SELECT * FROM ".$table." LIMIT 1";
00396         }
00397 
00398         // --------------------------------------------------------------------
00399 
00400         /**
00401          * The error message string
00402          *
00403          * @access      private
00404          * @return      string
00405          */
00406         function _error_message()
00407         {
00408                 return pg_last_error($this->conn_id);
00409         }
00410         
00411         // --------------------------------------------------------------------
00412 
00413         /**
00414          * The error message number
00415          *
00416          * @access      private
00417          * @return      integer
00418          */
00419         function _error_number()
00420         {
00421                 return '';
00422         }
00423 
00424         // --------------------------------------------------------------------
00425 
00426         /**
00427          * Escape the SQL Identifiers
00428          *
00429          * This function escapes column and table names
00430          *
00431          * @access      private
00432          * @param       string
00433          * @return      string
00434          */
00435         function _escape_identifiers($item)
00436         {
00437                 if ($this->_escape_char == '')
00438                 {
00439                         return $item;
00440                 }
00441         
00442                 if (strpos($item, '.') !== FALSE)
00443                 {
00444                         $str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;                    
00445                 }
00446                 else
00447                 {
00448                         $str = $this->_escape_char.$item.$this->_escape_char;
00449                 }
00450                 
00451                 // remove duplicates if the user already included the escape
00452                 return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
00453         }
00454                         
00455         // --------------------------------------------------------------------
00456 
00457         /**
00458          * From Tables
00459          *
00460          * This function implicitly groups FROM tables so there is no confusion
00461          * about operator precedence in harmony with SQL standards
00462          *
00463          * @access      public
00464          * @param       type
00465          * @return      type
00466          */
00467         function _from_tables($tables)
00468         {
00469                 if ( ! is_array($tables))
00470                 {
00471                         $tables = array($tables);
00472                 }
00473                 
00474                 return implode(', ', $tables);
00475         }
00476 
00477         // --------------------------------------------------------------------
00478         
00479         /**
00480          * Insert statement
00481          *
00482          * Generates a platform-specific insert string from the supplied data
00483          *
00484          * @access      public
00485          * @param       string  the table name
00486          * @param       array   the insert keys
00487          * @param       array   the insert values
00488          * @return      string
00489          */
00490         function _insert($table, $keys, $values)
00491         {       
00492                 return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
00493         }
00494         
00495         // --------------------------------------------------------------------
00496 
00497         /**
00498          * Update statement
00499          *
00500          * Generates a platform-specific update string from the supplied data
00501          *
00502          * @access      public
00503          * @param       string  the table name
00504          * @param       array   the update data
00505          * @param       array   the where clause
00506          * @param       array   the orderby clause
00507          * @param       array   the limit clause
00508          * @return      string
00509          */
00510         function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
00511         {
00512                 foreach($values as $key => $val)
00513                 {
00514                         $valstr[] = $key." = ".$val;
00515                 }
00516                 
00517                 $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
00518                 
00519                 $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
00520         
00521                 $sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
00522 
00523                 $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
00524 
00525                 $sql .= $orderby.$limit;
00526                 
00527                 return $sql;
00528         }
00529 
00530         // --------------------------------------------------------------------
00531 
00532         /**
00533          * Truncate statement
00534          *
00535          * Generates a platform-specific truncate string from the supplied data
00536          * If the database does not support the truncate() command
00537          * This function maps to "DELETE FROM table"
00538          *
00539          * @access      public
00540          * @param       string  the table name
00541          * @return      string
00542          */     
00543         function _truncate($table)
00544         {
00545                 return "TRUNCATE ".$table;
00546         }
00547         
00548         // --------------------------------------------------------------------
00549 
00550         /**
00551          * Delete statement
00552          *
00553          * Generates a platform-specific delete string from the supplied data
00554          *
00555          * @access      public
00556          * @param       string  the table name
00557          * @param       array   the where clause
00558          * @param       string  the limit clause
00559          * @return      string
00560          */     
00561         function _delete($table, $where = array(), $like = array(), $limit = FALSE)
00562         {
00563                 $conditions = '';
00564 
00565                 if (count($where) > 0 OR count($like) > 0)
00566                 {
00567                         $conditions = "\nWHERE ";
00568                         $conditions .= implode("\n", $this->ar_where);
00569 
00570                         if (count($where) > 0 && count($like) > 0)
00571                         {
00572                                 $conditions .= " AND ";
00573                         }
00574                         $conditions .= implode("\n", $like);
00575                 }
00576 
00577                 $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
00578         
00579                 return "DELETE FROM ".$table.$conditions.$limit;
00580         }
00581 
00582         // --------------------------------------------------------------------
00583         /**
00584          * Limit string
00585          *
00586          * Generates a platform-specific LIMIT clause
00587          *
00588          * @access      public
00589          * @param       string  the sql query string
00590          * @param       integer the number of rows to limit the query to
00591          * @param       integer the offset value
00592          * @return      string
00593          */
00594         function _limit($sql, $limit, $offset)
00595         {       
00596                 $sql .= "LIMIT ".$limit;
00597         
00598                 if ($offset > 0)
00599                 {
00600                         $sql .= " OFFSET ".$offset;
00601                 }
00602                 
00603                 return $sql;
00604         }
00605 
00606         // --------------------------------------------------------------------
00607 
00608         /**
00609          * Close DB Connection
00610          *
00611          * @access      public
00612          * @param       resource
00613          * @return      void
00614          */
00615         function _close($conn_id)
00616         {
00617                 @pg_close($conn_id);
00618         }
00619 
00620 
00621 }
00622 
00623 
00624 /* End of file postgre_driver.php */
00625 /* Location: ./system/database/drivers/postgre/postgre_driver.php */