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

Documentation generated on Wed, 04 Jan 2017 22:53:48 +0100 by phpDocumentor 1.4.3