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 resultset based on PDOStatement
  16.  * @package  jelix
  17.  * @subpackage db
  18.  */
  19. class jDbPDOResultSet extends PDOStatement {
  20.  
  21.     const FETCH_CLASS = 8;
  22.  
  23.     protected $_fetchMode = 0;
  24.  
  25.  
  26.     public function fetch ($fetch_style = PDO::FETCH_BOTH, $cursor_orientation = PDO::FETCH_ORI_NEXT, $cursor_offset = 0) {
  27.         $rec = parent::fetch();
  28.         if ($rec && count($this->modifier)) {
  29.             foreach($this->modifier as $m)
  30.                 call_user_func_array($m, array($rec, $this));
  31.         }
  32.         return $rec;
  33.     }
  34.  
  35.     /**
  36.      * return all results from the statement.
  37.      * Arguments are ignored. JDb don't care about it (fetch always as classes or objects)
  38.      * But there are here because of the compatibility of internal methods of PDOStatement
  39.      * @param integer $fetch_style ignored
  40.      * @param integer $column_index 
  41.      * @param array $ctor_arg  (ignored)
  42.      * @return array list of object which contain all rows
  43.      */
  44.     public function fetchAll ( $fetch_style = PDO::FETCH_OBJ, $column_index=0, $ctor_arg=null ){
  45.         if($this->_fetchMode){
  46.             if( $this->_fetchMode != PDO::FETCH_COLUMN)
  47.                 return parent::fetchAll($this->_fetchMode);
  48.             else
  49.                 return parent::fetchAll($this->_fetchMode, $column_index);
  50.         }else{
  51.             return parent::fetchAll(PDO::FETCH_OBJ);
  52.         }
  53.     }
  54.  
  55.     /**
  56.      * Set the fetch mode.
  57.      * @param int $mode  the mode, a PDO::FETCH_* constant
  58.      * @param mixed $arg1 a parameter for the given mode
  59.      * @param mixed $arg2 a parameter for the given mode
  60.      */
  61.     public function setFetchMode($mode, $arg1=null , $arg2=null){
  62.         $this->_fetchMode = $mode;
  63.         // depending the mode, original setFetchMode throw an error if wrong arguments
  64.         // are given, even if there are null
  65.         if ($arg1 === null)
  66.             return parent::setFetchMode($mode);
  67.         else if ($arg2 === null)
  68.             return parent::setFetchMode($mode, $arg1);
  69.         return parent::setFetchMode($mode, $arg1, $arg2);
  70.     }
  71.  
  72.     /**
  73.      * @param string a binary string to unescape
  74.      * @since 1.1.6
  75.      */
  76.     public function unescapeBin($text) {
  77.         return $text;
  78.     }
  79.  
  80.     /**
  81.      * a callback function which will modify on the fly record's value
  82.      * @var array of callback
  83.      * @since 1.1.6
  84.      */
  85.     protected $modifier = array();
  86.  
  87.     /**
  88.      * @param callback $function a callback function
  89.      *      the function should accept in parameter the record,
  90.      *      and the resulset object
  91.      * @since 1.1.6
  92.      */
  93.     public function addModifier($function) {
  94.         $this->modifier[] = $function;
  95.     }
  96. }
  97.  
  98.  
  99. /**
  100.  * A connection object based on PDO
  101.  * @package  jelix
  102.  * @subpackage db
  103.  */
  104. class jDbPDOConnection extends PDO {
  105.  
  106.     private $_mysqlCharsets =array( 'UTF-8'=>'utf8', 'ISO-8859-1'=>'latin1');
  107.     private $_pgsqlCharsets =array( 'UTF-8'=>'UNICODE', 'ISO-8859-1'=>'LATIN1');
  108.  
  109.     /**
  110.      * the profile the connection is using
  111.      * @var array 
  112.      */
  113.     public $profile;
  114.  
  115.     /**
  116.      * The database type name (mysql, pgsql ...)
  117.      */
  118.     public $dbms;
  119.  
  120.     /**
  121.      * Use a profile to do the connection
  122.      */
  123.     function __construct($profile){
  124.         $this->profile = $profile;
  125.         $this->dbms = substr($profile['dsn'],0,strpos($profile['dsn'],':'));
  126.         $prof=$profile;
  127.         $user= '';
  128.         $password='';
  129.         unset($prof['dsn']);
  130.         if(isset($prof['user'])){ // sqlite par ex n'a pas besoin de user/password -> on test alors leur presence
  131.             $user =$prof['user'];
  132.             unset($prof['user']);
  133.         }
  134.         if(isset($prof['password'])){
  135.             $password = $profile['password'];
  136.             unset($prof['password']);
  137.         }
  138.         unset($prof['driver']);
  139.         parent::__construct($profile['dsn'], $user, $password, $prof);
  140.         $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('jDbPDOResultSet'));
  141.         $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  142.         // on ne peut pas lancer deux query en même temps avec PDO ! sauf si on utilise mysql
  143.         // et que l'on utilise cet attribut...
  144.         if($this->dbms == 'mysql')
  145.             $this->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
  146.  
  147.         // Oracle renvoie les noms de colonnes en majuscules, il faut donc forcer la casse en minuscules
  148.         if ($this->dbms == 'oci')
  149.             $this->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
  150.  
  151.         if(isset($prof['force_encoding']) && $prof['force_encoding']==true){
  152.             if($this->dbms == 'mysql' && isset($this->_mysqlCharsets[$GLOBALS['gJConfig']->charset])){
  153.                 $this->exec("SET NAMES '".$this->_mysqlCharsets[$GLOBALS['gJConfig']->charset]."'");
  154.             }elseif($this->dbms == 'pgsql' && isset($this->_pgsqlCharsets[$GLOBALS['gJConfig']->charset])){
  155.                 $this->exec("SET client_encoding to '".$this->_pgsqlCharsets[$GLOBALS['gJConfig']->charset]."'");
  156.             }
  157.         }
  158.     }
  159.  
  160.     /**
  161.      * @internal the implementation of Iterator on PDOStatement doesn't call fetch method of classes which inherit of PDOStatement
  162.      *  so, we cannot indicate to fetch object directly in jDbPDOResultSet::fetch(). So we overload query() to do it.
  163.      */
  164.     public function query(){
  165.         $args=func_get_args();
  166.         switch(count($args)){
  167.         case 1:
  168.             $rs = parent::query($args[0]);
  169.             $rs->setFetchMode(PDO::FETCH_OBJ);
  170.             return $rs;
  171.             break;
  172.         case 2:
  173.             return parent::query($args[0], $args[1]);
  174.             break;
  175.         case 3:
  176.             return parent::query($args[0], $args[1], $args[2]);
  177.             break;
  178.         default:
  179.             trigger_error('bad argument number in query',E_USER_ERROR);
  180.         }
  181.  
  182.     }
  183.  
  184.     public function limitQuery ($queryString, $limitOffset = null, $limitCount = null){
  185.         if ($limitOffset !== null && $limitCount !== null){
  186.            if($this->dbms == 'mysql' || $this->dbms == 'sqlite'){
  187.                $queryString.= ' LIMIT '.intval($limitOffset).','. intval($limitCount);
  188.            }elseif($this->dbms == 'pgsql'){
  189.                $queryString.= ' LIMIT '.intval($limitCount).' OFFSET '.intval($limitOffset);
  190.            }
  191.         }
  192.         $result = $this->query ($queryString);
  193.         return $result;
  194.     }
  195.  
  196.     /**
  197.      * sets the autocommit state
  198.      * @param boolean state the status of autocommit
  199.      */
  200.     public function setAutoCommit($state=true){
  201.         $this->setAttribute(PDO::ATTR_AUTOCOMMIT,$state);
  202.     }
  203.  
  204.     public function lastIdInTable($fieldName, $tableName){
  205.       $rs = $this->query ('SELECT MAX('.$fieldName.') as ID FROM '.$tableName);
  206.       if (($rs !== null) && $r = $rs->fetch ()){
  207.          return $r->ID;
  208.       }
  209.       return 0;
  210.     }
  211.  
  212.     /**
  213.      * Prefix the given table with the prefix specified in the connection's profile
  214.      * If there's no prefix for the connection's profile, return the table's name unchanged.
  215.      *
  216.      * @param string $table the table's name
  217.      * @return string the prefixed table's name
  218.      * @author Julien Issler
  219.      * @since 1.0
  220.      */
  221.     public function prefixTable($table_name){
  222.         if(!isset($this->profile['table_prefix']))
  223.             return $table_name;
  224.         return $this->profile['table_prefix'].$table_name;
  225.     }
  226.  
  227.     /**
  228.      * Check if the current connection has a table prefix set
  229.      *
  230.      * @return boolean 
  231.      * @author Julien Issler
  232.      * @since 1.0
  233.      */
  234.     public function hasTablePrefix(){
  235.         return (isset($this->profile['table_prefix']) && $this->profile['table_prefix']!='');
  236.     }
  237.  
  238.     /**
  239.      * enclose the field name
  240.      * @param string $fieldName the field name
  241.      * @return string the enclosed field name
  242.      * @since 1.1.2
  243.      */
  244.     public function encloseName($fieldName){
  245.         switch($this->dbms){
  246.             case 'mysql': return '`'.$fieldName.'`';
  247.             case 'pgsql': return '"'.$fieldName.'"';
  248.             default: return $fieldName;
  249.         }
  250.     }
  251. }

Documentation generated on Thu, 22 Mar 2012 22:15:20 +0100 by phpDocumentor 1.4.3