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

Documentation generated on Thu, 19 Sep 2013 00:04:01 +0200 by phpDocumentor 1.4.3