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.             $log new jSQLLogMessage($args[0]);
  129.             $rs parent::query($args[0]);
  130.             $log->endQuery();
  131.             jLog::log($log,'sql');
  132.             $rs->setFetchMode(PDO::FETCH_OBJ);
  133.             return $rs;
  134.         case 2:
  135.             $log new jSQLLogMessage($args[0]);
  136.             $result parent::query($args[0]$args[1]);
  137.             $log->endQuery();
  138.             jLog::log($log,'sql');
  139.             return $result;
  140.         case 3:
  141.             $log new jSQLLogMessage($args[0]);
  142.             $result parent::query($args[0]$args[1]$args[2]);
  143.             $log->endQuery();
  144.             jLog::log($log,'sql');
  145.             return $result;
  146.         default:
  147.             throw new Exception('jDbPDOConnection: bad argument number in query');
  148.         }
  149.     }
  150.  
  151.     public function exec($query{
  152.         $log new jSQLLogMessage($query);
  153.         $result parent::exec($query);
  154.         $log->endQuery();
  155.         jLog::log($log,'sql');
  156.         return $result;
  157.     }
  158.  
  159.     /**
  160.     * Launch a SQL Query with limit parameter (so only a subset of a result)
  161.     * @param   string   $queryString   the SQL query
  162.     * @param   integer  $limitOffset   the offset of the first row to return
  163.     * @param   integer  $limitCount    the maximum of number of rows to return
  164.     * @return  jDbPDOResultSet|boolean SQL Select. False if the query has failed.
  165.     */
  166.     public function limitQuery ($queryString$limitOffset null$limitCount null{
  167.         if ($limitOffset !== null && $limitCount !== null{
  168.             if ($this->dbms == 'mysql' || $this->dbms == 'sqlite'{
  169.                 $queryString.= ' LIMIT '.intval($limitOffset).','intval($limitCount);
  170.             }
  171.             elseif ($this->dbms == 'pgsql'{
  172.                 $queryString .= ' LIMIT '.intval($limitCount).' OFFSET '.intval($limitOffset);
  173.             }
  174.             elseif ($this->dbms == 'oci'{
  175.                 $limitOffset $limitOffset 1// rnum begins at 1
  176.                 $queryString 'SELECT * FROM ( SELECT ocilimit.*, rownum rnum FROM ('.$queryString.') ocilimit WHERE
  177.                     rownum<'.(intval($limitOffset)+intval($limitCount)).'  ) WHERE rnum >='.intval($limitOffset);
  178.             }
  179.         }
  180.         return $this->query ($queryString);
  181.     }
  182.  
  183.     /**
  184.      * sets the autocommit state
  185.      * @param boolean $state the status of autocommit
  186.      */
  187.     public function setAutoCommit($state=true{
  188.         $this->setAttribute(PDO::ATTR_AUTOCOMMIT,$state);
  189.     }
  190.  
  191.     /**
  192.      * return the maximum value of the given primary key in a table
  193.      * @param string $fieldName the name of the primary key
  194.      * @param string $tableName the name of the table
  195.      * @return integer the maximum value
  196.      */
  197.     public function lastIdInTable($fieldName$tableName{
  198.       $rs $this->query ('SELECT MAX('.$fieldName.') as ID FROM '.$tableName);
  199.       if (($rs !== null&& $r $rs->fetch ()){
  200.          return $r->ID;
  201.       }
  202.       return 0;
  203.     }
  204.  
  205.     /**
  206.      * Prefix the given table with the prefix specified in the connection's profile
  207.      * If there's no prefix for the connection's profile, return the table's name unchanged.
  208.      *
  209.      * @param string $table the table's name
  210.      * @return string the prefixed table's name
  211.      * @author Julien Issler
  212.      * @since 1.0
  213.      */
  214.     public function prefixTable($table_name{
  215.         if (!isset($this->profile['table_prefix']))
  216.             return $table_name;
  217.         return $this->profile['table_prefix'].$table_name;
  218.     }
  219.  
  220.     /**
  221.      * Check if the current connection has a table prefix set
  222.      *
  223.      * @return boolean 
  224.      * @author Julien Issler
  225.      * @since 1.0
  226.      */
  227.     public function hasTablePrefix({
  228.         return (isset($this->profile['table_prefix']&& $this->profile['table_prefix']!='');
  229.     }
  230.  
  231.     /**
  232.      * enclose the field name
  233.      * @param string $fieldName the field name
  234.      * @return string the enclosed field name
  235.      * @since 1.1.2
  236.      */
  237.     public function encloseName($fieldName{
  238.         switch ($this->dbms{
  239.             case 'mysql'return '`'.$fieldName.'`';
  240.             case 'pgsql'return '"'.$fieldName.'"';
  241.             defaultreturn $fieldName;
  242.         }
  243.     }
  244.  
  245.     /**
  246.     * Escape and quotes strings. if null, will only return the text "NULL"
  247.     * @param string $text   string to quote
  248.     * @param boolean $checknull if true, check if $text is a null value, and then return NULL
  249.     * @param boolean $binary  set to true if $text contains a binary string
  250.     * @return string escaped string
  251.     * @since 1.2
  252.     * @todo $binary parameter is not really supported, check if PDOConnection::quote supports binary strings
  253.     */
  254.     public function quote2 ($text$checknull=true$binary=false{
  255.         if ($checknull)
  256.             return (is_null ($text'NULL' $this->quote($text));
  257.         else
  258.             return $this->quote($text);
  259.     }
  260.  
  261.     /**
  262.      * @var jDbTools 
  263.      */
  264.     protected $_tools = null;
  265.  
  266.     /**
  267.      * @return jDbTools 
  268.      */
  269.     public function tools ({
  270.         if (!$this->_tools{
  271.             $dbms ($this->dbms === 'sqlite''sqlite3' $this->dbms
  272.             $this->_tools = jApp::loadPlugin($dbms'db''.dbtools.php'$dbms.'DbTools'$this);
  273.             if (is_null($this->_tools))
  274.                 throw new jException('jelix~db.error.driver.notfound'$dbms);
  275.         }
  276.  
  277.         return $this->_tools;
  278.     }
  279.  
  280.     /**
  281.      * Get the ID of the last inserted row
  282.      * Mssql pdo driver does not support this feature.
  283.      * so, we use a custom query
  284.      * @param string $fromSequence the sequence name, if needed
  285.      * @return string 
  286.      */
  287.     public function lastInsertId($fromSequence=null{
  288.         if ($this->dbms == 'mssql'{
  289.             $res $this->query('SELECT SCOPE_IDENTITY()');
  290.             return (int) $res->fetchColumn();
  291.         }
  292.  
  293.         return parent::lastInsertId($fromSequence);
  294.     }
  295.  
  296. }

Documentation generated on Mon, 26 Oct 2015 21:53:16 +0100 by phpDocumentor 1.4.3