Source for file jDbPDOConnection.class.php

Documentation is available at jDbPDOConnection.class.php

  1. <?php
  2. /**
  3. @package    jelix
  4. @subpackage db
  5. @author     Laurent Jouanneau
  6. @contributor Gwendal Jouannic, Thomas, Julien Issler
  7. @copyright  2005-2010 Laurent Jouanneau
  8. @copyright  2008 Gwendal Jouannic, 2009 Thomas
  9. @copyright  2009 Julien Issler
  10. @link      http://www.jelix.org
  11. @licence  http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public Licence, see LICENCE file
  12. */
  13.  
  14. /**
  15.  * A connection object based on PDO
  16.  * @package  jelix
  17.  * @subpackage db
  18.  */
  19. class jDbPDOConnection extends PDO {
  20.  
  21.     private $_mysqlCharsets array('UTF-8'=>'utf8''ISO-8859-1'=>'latin1');
  22.     private $_pgsqlCharsets array('UTF-8'=>'UNICODE''ISO-8859-1'=>'LATIN1');
  23.  
  24.     /**
  25.      * the profile the connection is using
  26.      * @var array 
  27.      */
  28.     public $profile;
  29.  
  30.     /**
  31.      * The database type name (mysql, pgsql ...)
  32.      * @var string 
  33.      */
  34.     public $dbms;
  35.  
  36.     /**
  37.      * Use a profile to do the connection
  38.      * @param array $profile the profile data readed from the ini file
  39.      */
  40.     function __construct($profile{
  41.         $this->profile = $profile;
  42.         $prof $profile;
  43.         $user '';
  44.         $password '';
  45.         $dsn '';
  46.         if (isset($profile['dsn'])) {
  47.             $this->dbms = substr($profile['dsn'],0,strpos($profile['dsn'],':'));
  48.             $dsn $profile['dsn'];
  49.             unset($prof['dsn']);
  50.             if ($this->dbms == 'sqlite')
  51.                 $dsn str_replace(array('app:','lib:','var:')array(jApp::appPath()LIB_PATHjApp::varPath())$dsn);
  52.         }
  53.         else {
  54.             $this->dbms = $profile['driver'];
  55.             $db $profile['database'];
  56.             $dsn $this->dbms.':host='.$profile['host'].';dbname='.$db;
  57.             if($this->dbms != 'sqlite')
  58.                 $dsn $this->dbms.':host='.$profile['host'].';dbname='.$db;
  59.             else {
  60.                 if (preg_match('/^(app|lib|var)\:/'$db$m))
  61.                     $dsn 'sqlite:'.str_replace(array('app:','lib:','var:')array(jApp::appPath()LIB_PATHjApp::varPath())$db);
  62.                 else
  63.                     $dsn 'sqlite:'.jApp::varPath('db/sqlite/'.$db);
  64.             }
  65.         }
  66.         if(isset($prof['usepdo']))
  67.             unset($prof['usepdo']);
  68.  
  69.         // we check user and password because some db like sqlite doesn't have user/password
  70.         if (isset($prof['user'])) {
  71.             $user $prof['user'];
  72.             unset($prof['user']);
  73.         }
  74.  
  75.         if (isset($prof['password'])) {
  76.             $password $profile['password'];
  77.             unset($prof['password']);
  78.         }
  79.  
  80.         unset($prof['driver']);
  81.  
  82.         parent::__construct($dsn$user$password$prof);
  83.  
  84.         $this->setAttribute(PDO::ATTR_STATEMENT_CLASSarray('jDbPDOResultSet'));
  85.         $this->setAttribute(PDO::ATTR_ERRMODEPDO::ERRMODE_EXCEPTION);
  86.  
  87.         // we cannot launch two queries at the same time with PDO ! except if
  88.         // we use mysql with the attribute MYSQL_ATTR_USE_BUFFERED_QUERY
  89.         // TODO check if PHP 5.3 or higher fixes this issue
  90.         if ($this->dbms == 'mysql')
  91.             $this->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERYtrue);
  92.  
  93.         // Oracle returns names of columns in upper case by default. so here
  94.         // we force the case in lower.
  95.         if ($this->dbms == 'oci')
  96.             $this->setAttribute(PDO::ATTR_CASEPDO::CASE_LOWER);
  97.  
  98.         if (isset($prof['force_encoding']&& $prof['force_encoding']==true{
  99.             if ($this->dbms == 'mysql' && isset($this->_mysqlCharsets[$GLOBALS['gJConfig']->charset])) {
  100.                 $this->exec("SET NAMES '".$this->_mysqlCharsets[$GLOBALS['gJConfig']->charset]."'");
  101.             }
  102.             elseif($this->dbms == 'pgsql' && isset($this->_pgsqlCharsets[$GLOBALS['gJConfig']->charset])) {
  103.                 $this->exec("SET client_encoding to '".$this->_pgsqlCharsets[$GLOBALS['gJConfig']->charset]."'");
  104.             }
  105.         }
  106.     }
  107.  
  108.     /**
  109.      * @internal the implementation of Iterator on PDOStatement doesn't call
  110.      *  fetch method of classes which inherit of PDOStatement.
  111.      *  so, we cannot indicate to fetch object directly in jDbPDOResultSet::fetch().
  112.      *  So we overload query() to do it.
  113.      *  TODO check if this is still the case in PHP 5.3
  114.      */
  115.     public function query({
  116.         $args func_get_args();
  117.  
  118.         switch (count($args)) {
  119.         case 1:
  120.             $log new jSQLLogMessage($args[0]);
  121.             $rs parent::query($args[0]);
  122.             $log->endQuery();
  123.             jLog::log($log,'sql');
  124.             $rs->setFetchMode(PDO::FETCH_OBJ);
  125.             return $rs;
  126.         case 2:
  127.             $log new jSQLLogMessage($args[0]);
  128.             $result parent::query($args[0]$args[1]);
  129.             $log->endQuery();
  130.             jLog::log($log,'sql');
  131.             return $result;
  132.         case 3:
  133.             $log new jSQLLogMessage($args[0]);
  134.             $result parent::query($args[0]$args[1]$args[2]);
  135.             $log->endQuery();
  136.             jLog::log($log,'sql');
  137.             return $result;
  138.         default:
  139.             throw new Exception('jDbPDOConnection: bad argument number in query');
  140.         }
  141.     }
  142.  
  143.     public function exec($query{
  144.         $log new jSQLLogMessage($query);
  145.         $result parent::exec($query);
  146.         $log->endQuery();
  147.         jLog::log($log,'sql');
  148.         return $result;
  149.     }
  150.  
  151.     /**
  152.     * Launch a SQL Query with limit parameter (so only a subset of a result)
  153.     * @param   string   $queryString   the SQL query
  154.     * @param   integer  $limitOffset   the offset of the first row to return
  155.     * @param   integer  $limitCount    the maximum of number of rows to return
  156.     * @return  jDbPDOResultSet|boolean SQL Select. False if the query has failed.
  157.     */
  158.     public function limitQuery ($queryString$limitOffset null$limitCount null{
  159.         if ($limitOffset !== null && $limitCount !== null{
  160.             if ($this->dbms == 'mysql' || $this->dbms == 'sqlite'{
  161.                 $queryString.= ' LIMIT '.intval($limitOffset).','intval($limitCount);
  162.             }
  163.             elseif ($this->dbms == 'pgsql'{
  164.                 $queryString .= ' LIMIT '.intval($limitCount).' OFFSET '.intval($limitOffset);
  165.             }
  166.             elseif ($this->dbms == 'oci'{
  167.                 $limitOffset $limitOffset 1// rnum begins at 1
  168.                 $queryString 'SELECT * FROM ( SELECT ocilimit.*, rownum rnum FROM ('.$queryString.') ocilimit WHERE
  169.                     rownum<'.(intval($limitOffset)+intval($limitCount)).'  ) WHERE rnum >='.intval($limitOffset);
  170.             }
  171.         }
  172.         return $this->query ($queryString);
  173.     }
  174.  
  175.     /**
  176.      * sets the autocommit state
  177.      * @param boolean $state the status of autocommit
  178.      */
  179.     public function setAutoCommit($state=true{
  180.         $this->setAttribute(PDO::ATTR_AUTOCOMMIT,$state);
  181.     }
  182.  
  183.     /**
  184.      * return the maximum value of the given primary key in a table
  185.      * @param string $fieldName the name of the primary key
  186.      * @param string $tableName the name of the table
  187.      * @return integer the maximum value
  188.      */
  189.     public function lastIdInTable($fieldName$tableName{
  190.       $rs $this->query ('SELECT MAX('.$fieldName.') as ID FROM '.$tableName);
  191.       if (($rs !== null&& $r $rs->fetch ()){
  192.          return $r->ID;
  193.       }
  194.       return 0;
  195.     }
  196.  
  197.     /**
  198.      * Prefix the given table with the prefix specified in the connection's profile
  199.      * If there's no prefix for the connection's profile, return the table's name unchanged.
  200.      *
  201.      * @param string $table the table's name
  202.      * @return string the prefixed table's name
  203.      * @author Julien Issler
  204.      * @since 1.0
  205.      */
  206.     public function prefixTable($table_name{
  207.         if (!isset($this->profile['table_prefix']))
  208.             return $table_name;
  209.         return $this->profile['table_prefix'].$table_name;
  210.     }
  211.  
  212.     /**
  213.      * Check if the current connection has a table prefix set
  214.      *
  215.      * @return boolean 
  216.      * @author Julien Issler
  217.      * @since 1.0
  218.      */
  219.     public function hasTablePrefix({
  220.         return (isset($this->profile['table_prefix']&& $this->profile['table_prefix']!='');
  221.     }
  222.  
  223.     /**
  224.      * enclose the field name
  225.      * @param string $fieldName the field name
  226.      * @return string the enclosed field name
  227.      * @since 1.1.2
  228.      */
  229.     public function encloseName($fieldName{
  230.         switch ($this->dbms{
  231.             case 'mysql'return '`'.$fieldName.'`';
  232.             case 'pgsql'return '"'.$fieldName.'"';
  233.             defaultreturn $fieldName;
  234.         }
  235.     }
  236.  
  237.     /**
  238.     * Escape and quotes strings. if null, will only return the text "NULL"
  239.     * @param string $text   string to quote
  240.     * @param boolean $checknull if true, check if $text is a null value, and then return NULL
  241.     * @param boolean $binary  set to true if $text contains a binary string
  242.     * @return string escaped string
  243.     * @since 1.2
  244.     * @todo $binary parameter is not really supported, check if PDOConnection::quote supports binary strings
  245.     */
  246.     public function quote2 ($text$checknull=true$binary=false{
  247.         if ($checknull)
  248.             return (is_null ($text'NULL' $this->quote($text));
  249.         else
  250.             return $this->quote($text);
  251.     }
  252.  
  253.     /**
  254.      * @var jDbTools 
  255.      */
  256.     protected $_tools = null;
  257.  
  258.     /**
  259.      * @return jDbTools 
  260.      */
  261.     public function tools ({
  262.         if (!$this->_tools{
  263.             $this->_tools = jApp::loadPlugin($this->dbms'db''.dbtools.php'$this->dbms.'DbTools'$this);
  264.             if (is_null($this->_tools))
  265.                 throw new jException('jelix~db.error.driver.notfound'$this->dbms);
  266.         }
  267.  
  268.         return $this->_tools;
  269.     }
  270.  
  271. }

Documentation generated on Mon, 19 Sep 2011 14:12:28 +0200 by phpDocumentor 1.4.3