"Fossies" - the Fresh Open Source Software Archive

Member "yii-1.1.24.a5ab20/framework/db/CDbConnection.php" (7 Jun 2021, 30256 Bytes) of package /linux/www/yii-1.1.24.a5ab20.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "CDbConnection.php" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.1.23.445827_vs_1.1.24.a5ab20.

    1 <?php
    2 /**
    3  * CDbConnection class file
    4  *
    5  * @author Qiang Xue <qiang.xue@gmail.com>
    6  * @link http://www.yiiframework.com/
    7  * @copyright 2008-2013 Yii Software LLC
    8  * @license http://www.yiiframework.com/license/
    9  */
   10 
   11 /**
   12  * CDbConnection represents a connection to a database.
   13  *
   14  * CDbConnection works together with {@link CDbCommand}, {@link CDbDataReader}
   15  * and {@link CDbTransaction} to provide data access to various DBMS
   16  * in a common set of APIs. They are a thin wrapper of the {@link http://www.php.net/manual/en/ref.pdo.php PDO}
   17  * PHP extension.
   18  *
   19  * To establish a connection, set {@link setActive active} to true after
   20  * specifying {@link connectionString}, {@link username} and {@link password}.
   21  *
   22  * The following example shows how to create a CDbConnection instance and establish
   23  * the actual connection:
   24  * <pre>
   25  * $connection=new CDbConnection($dsn,$username,$password);
   26  * $connection->active=true;
   27  * </pre>
   28  *
   29  * After the DB connection is established, one can execute an SQL statement like the following:
   30  * <pre>
   31  * $command=$connection->createCommand($sqlStatement);
   32  * $command->execute();   // a non-query SQL statement execution
   33  * // or execute an SQL query and fetch the result set
   34  * $reader=$command->query();
   35  *
   36  * // each $row is an array representing a row of data
   37  * foreach($reader as $row) ...
   38  * </pre>
   39  *
   40  * One can do prepared SQL execution and bind parameters to the prepared SQL:
   41  * <pre>
   42  * $command=$connection->createCommand($sqlStatement);
   43  * $command->bindParam($name1,$value1);
   44  * $command->bindParam($name2,$value2);
   45  * $command->execute();
   46  * </pre>
   47  *
   48  * To use transaction, do like the following:
   49  * <pre>
   50  * $transaction=$connection->beginTransaction();
   51  * try
   52  * {
   53  *    $connection->createCommand($sql1)->execute();
   54  *    $connection->createCommand($sql2)->execute();
   55  *    //.... other SQL executions
   56  *    $transaction->commit();
   57  * }
   58  * catch(Exception $e)
   59  * {
   60  *    $transaction->rollback();
   61  * }
   62  * </pre>
   63  *
   64  * CDbConnection also provides a set of methods to support setting and querying
   65  * of certain DBMS attributes, such as {@link getNullConversion nullConversion}.
   66  *
   67  * Since CDbConnection implements the interface IApplicationComponent, it can
   68  * be used as an application component and be configured in application configuration,
   69  * like the following,
   70  * <pre>
   71  * array(
   72  *     'components'=>array(
   73  *         'db'=>array(
   74  *             'class'=>'CDbConnection',
   75  *             'connectionString'=>'sqlite:path/to/dbfile',
   76  *         ),
   77  *     ),
   78  * )
   79  * </pre>
   80  *
   81  * Use the {@link driverName} property if you want to force the DB connection to use a particular driver
   82  * by the given name, disregarding of what was set in the {@link connectionString} property. This might
   83  * be useful when working with ODBC connections. Sample code:
   84  *
   85  * <pre>
   86  * 'db'=>array(
   87  *     'class'=>'CDbConnection',
   88  *     'driverName'=>'mysql',
   89  *     'connectionString'=>'odbc:Driver={MySQL};Server=127.0.0.1;Database=test',
   90  *     'username'=>'',
   91  *     'password'=>'',
   92  * ),
   93  * </pre>
   94  *
   95  * @property boolean $active Whether the DB connection is established.
   96  * @property PDO $pdoInstance The PDO instance, null if the connection is not established yet.
   97  * @property CDbTransaction $currentTransaction The currently active transaction. Null if no active transaction.
   98  * @property CDbSchema $schema The database schema for the current connection.
   99  * @property CDbCommandBuilder $commandBuilder The command builder.
  100  * @property string $lastInsertID The row ID of the last row inserted, or the last value retrieved from the sequence object.
  101  * @property mixed $columnCase The case of the column names.
  102  * @property mixed $nullConversion How the null and empty strings are converted.
  103  * @property boolean $autoCommit Whether creating or updating a DB record will be automatically committed.
  104  * @property boolean $persistent Whether the connection is persistent or not.
  105  * @property string $driverName Name of the DB driver. This property is read-write since 1.1.16.
  106  * Before 1.1.15 it was read-only.
  107  * @property string $clientVersion The version information of the DB driver.
  108  * @property string $connectionStatus The status of the connection.
  109  * @property boolean $prefetch Whether the connection performs data prefetching.
  110  * @property string $serverInfo The information of DBMS server.
  111  * @property string $serverVersion The version information of DBMS server.
  112  * @property integer $timeout Timeout settings for the connection.
  113  * @property array $attributes Attributes (name=>value) that are previously explicitly set for the DB connection.
  114  * @property array $stats The first element indicates the number of SQL statements executed,
  115  * and the second element the total time spent in SQL execution.
  116  *
  117  * @author Qiang Xue <qiang.xue@gmail.com>
  118  * @package system.db
  119  * @since 1.0
  120  */
  121 class CDbConnection extends CApplicationComponent
  122 {
  123     /**
  124      * @var string The Data Source Name, or DSN, contains the information required to connect to the database.
  125      * @see http://www.php.net/manual/en/function.PDO-construct.php
  126      *
  127      * Note that if you're using GBK or BIG5 then it's highly recommended to
  128      * update to PHP 5.3.6+ and to specify charset via DSN like
  129      * 'mysql:dbname=mydatabase;host=127.0.0.1;charset=GBK;'.
  130      */
  131     public $connectionString;
  132     /**
  133      * @var string the username for establishing DB connection. Defaults to empty string.
  134      */
  135     public $username='';
  136     /**
  137      * @var string the password for establishing DB connection. Defaults to empty string.
  138      */
  139     public $password='';
  140     /**
  141      * @var integer number of seconds that table metadata can remain valid in cache.
  142      * Use 0 or negative value to indicate not caching schema.
  143      * If greater than 0 and the primary cache is enabled, the table metadata will be cached.
  144      * @see schemaCachingExclude
  145      */
  146     public $schemaCachingDuration=0;
  147     /**
  148      * @var array list of tables whose metadata should NOT be cached. Defaults to empty array.
  149      * @see schemaCachingDuration
  150      */
  151     public $schemaCachingExclude=array();
  152     /**
  153      * @var string the ID of the cache application component that is used to cache the table metadata.
  154      * Defaults to 'cache' which refers to the primary cache application component.
  155      * Set this property to false if you want to disable caching table metadata.
  156      */
  157     public $schemaCacheID='cache';
  158     /**
  159      * @var integer number of seconds that query results can remain valid in cache.
  160      * Use 0 or negative value to indicate not caching query results (the default behavior).
  161      *
  162      * In order to enable query caching, this property must be a positive
  163      * integer and {@link queryCacheID} must point to a valid cache component ID.
  164      *
  165      * The method {@link cache()} is provided as a convenient way of setting this property
  166      * and {@link queryCachingDependency} on the fly.
  167      *
  168      * @see cache
  169      * @see queryCachingDependency
  170      * @see queryCacheID
  171      * @since 1.1.7
  172      */
  173     public $queryCachingDuration=0;
  174     /**
  175      * @var CCacheDependency|ICacheDependency the dependency that will be used when saving query results into cache.
  176      * @see queryCachingDuration
  177      * @since 1.1.7
  178      */
  179     public $queryCachingDependency;
  180     /**
  181      * @var integer the number of SQL statements that need to be cached next.
  182      * If this is 0, then even if query caching is enabled, no query will be cached.
  183      * Note that each time after executing a SQL statement (whether executed on DB server or fetched from
  184      * query cache), this property will be reduced by 1 until 0.
  185      * @since 1.1.7
  186      */
  187     public $queryCachingCount=0;
  188     /**
  189      * @var string the ID of the cache application component that is used for query caching.
  190      * Defaults to 'cache' which refers to the primary cache application component.
  191      * Set this property to false if you want to disable query caching.
  192      * @since 1.1.7
  193      */
  194     public $queryCacheID='cache';
  195     /**
  196      * @var boolean whether the database connection should be automatically established
  197      * the component is being initialized. Defaults to true. Note, this property is only
  198      * effective when the CDbConnection object is used as an application component.
  199      */
  200     public $autoConnect=true;
  201     /**
  202      * @var string the charset used for database connection. The property is only used
  203      * for MySQL, MariaDB and PostgreSQL databases. Defaults to null, meaning using default charset
  204      * as specified by the database.
  205      *
  206      * Note that if you're using GBK or BIG5 then it's highly recommended to
  207      * update to PHP 5.3.6+ and to specify charset via DSN like
  208      * 'mysql:dbname=mydatabase;host=127.0.0.1;charset=GBK;'.
  209      */
  210     public $charset;
  211     /**
  212      * @var boolean whether to turn on prepare emulation. Defaults to false, meaning PDO
  213      * will use the native prepare support if available. For some databases (such as MySQL),
  214      * this may need to be set true so that PDO can emulate the prepare support to bypass
  215      * the buggy native prepare support. Note, this property is only effective for PHP 5.1.3 or above.
  216      * The default value is null, which will not change the ATTR_EMULATE_PREPARES value of PDO.
  217      */
  218     public $emulatePrepare;
  219     /**
  220      * @var boolean whether to log the values that are bound to a prepare SQL statement.
  221      * Defaults to false. During development, you may consider setting this property to true
  222      * so that parameter values bound to SQL statements are logged for debugging purpose.
  223      * You should be aware that logging parameter values could be expensive and have significant
  224      * impact on the performance of your application.
  225      */
  226     public $enableParamLogging=false;
  227     /**
  228      * @var boolean whether to enable profiling the SQL statements being executed.
  229      * Defaults to false. This should be mainly enabled and used during development
  230      * to find out the bottleneck of SQL executions.
  231      */
  232     public $enableProfiling=false;
  233     /**
  234      * @var string the default prefix for table names. Defaults to null, meaning no table prefix.
  235      * By setting this property, any token like '{{tableName}}' in {@link CDbCommand::text} will
  236      * be replaced by 'prefixTableName', where 'prefix' refers to this property value.
  237      * @since 1.1.0
  238      */
  239     public $tablePrefix;
  240     /**
  241      * @var array list of SQL statements that should be executed right after the DB connection is established.
  242      * @since 1.1.1
  243      */
  244     public $initSQLs;
  245     /**
  246      * @var array mapping between PDO driver and schema class name.
  247      * A schema class can be specified using path alias.
  248      * @since 1.1.6
  249      */
  250     public $driverMap=array(
  251         'cubrid'=>'CCubridSchema',  // CUBRID
  252         'pgsql'=>'CPgsqlSchema',    // PostgreSQL
  253         'mysqli'=>'CMysqlSchema',   // MySQL
  254         'mysql'=>'CMysqlSchema',    // MySQL,MariaDB
  255         'sqlite'=>'CSqliteSchema',  // sqlite 3
  256         'sqlite2'=>'CSqliteSchema', // sqlite 2
  257         'mssql'=>'CMssqlSchema',    // Mssql driver on windows hosts
  258         'dblib'=>'CMssqlSchema',    // dblib drivers on linux (and maybe others os) hosts
  259         'sqlsrv'=>'CMssqlSchema',   // Mssql
  260         'oci'=>'COciSchema',        // Oracle driver
  261     );
  262 
  263     /**
  264      * @var string Custom PDO wrapper class.
  265      * @since 1.1.8
  266      */
  267     public $pdoClass = 'PDO';
  268 
  269     private $_driverName;
  270     private $_attributes=array();
  271     private $_active=false;
  272     private $_pdo;
  273     private $_transaction;
  274     private $_schema;
  275 
  276 
  277     /**
  278      * Constructor.
  279      * Note, the DB connection is not established when this connection
  280      * instance is created. Set {@link setActive active} property to true
  281      * to establish the connection.
  282      * @param string $dsn The Data Source Name, or DSN, contains the information required to connect to the database.
  283      * @param string $username The user name for the DSN string.
  284      * @param string $password The password for the DSN string.
  285      * @see http://www.php.net/manual/en/function.PDO-construct.php
  286      */
  287     public function __construct($dsn='',$username='',$password='')
  288     {
  289         $this->connectionString=$dsn;
  290         $this->username=$username;
  291         $this->password=$password;
  292     }
  293 
  294     /**
  295      * Close the connection when serializing.
  296      * @return array
  297      */
  298     public function __sleep()
  299     {
  300         $this->close();
  301         return array_keys(get_object_vars($this));
  302     }
  303 
  304     /**
  305      * Returns a list of available PDO drivers.
  306      * @return array list of available PDO drivers
  307      * @see http://www.php.net/manual/en/function.PDO-getAvailableDrivers.php
  308      */
  309     public static function getAvailableDrivers()
  310     {
  311         return PDO::getAvailableDrivers();
  312     }
  313 
  314     /**
  315      * Initializes the component.
  316      * This method is required by {@link IApplicationComponent} and is invoked by application
  317      * when the CDbConnection is used as an application component.
  318      * If you override this method, make sure to call the parent implementation
  319      * so that the component can be marked as initialized.
  320      */
  321     public function init()
  322     {
  323         parent::init();
  324         if($this->autoConnect)
  325             $this->setActive(true);
  326     }
  327 
  328     /**
  329      * Returns whether the DB connection is established.
  330      * @return boolean whether the DB connection is established
  331      */
  332     public function getActive()
  333     {
  334         return $this->_active;
  335     }
  336 
  337     /**
  338      * Open or close the DB connection.
  339      * @param boolean $value whether to open or close DB connection
  340      * @throws CException if connection fails
  341      */
  342     public function setActive($value)
  343     {
  344         if($value!=$this->_active)
  345         {
  346             if($value)
  347                 $this->open();
  348             else
  349                 $this->close();
  350         }
  351     }
  352 
  353     /**
  354      * Sets the parameters about query caching.
  355      * This method can be used to enable or disable query caching.
  356      * By setting the $duration parameter to be 0, the query caching will be disabled.
  357      * Otherwise, query results of the new SQL statements executed next will be saved in cache
  358      * and remain valid for the specified duration.
  359      * If the same query is executed again, the result may be fetched from cache directly
  360      * without actually executing the SQL statement.
  361      * @param integer $duration the number of seconds that query results may remain valid in cache.
  362      * If this is 0, the caching will be disabled.
  363      * @param CCacheDependency|ICacheDependency $dependency the dependency that will be used when saving
  364      * the query results into cache.
  365      * @param integer $queryCount number of SQL queries that need to be cached after calling this method. Defaults to 1,
  366      * meaning that the next SQL query will be cached.
  367      * @return static the connection instance itself.
  368      * @since 1.1.7
  369      */
  370     public function cache($duration, $dependency=null, $queryCount=1)
  371     {
  372         $this->queryCachingDuration=$duration;
  373         $this->queryCachingDependency=$dependency;
  374         $this->queryCachingCount=$queryCount;
  375         return $this;
  376     }
  377 
  378     /**
  379      * Opens DB connection if it is currently not
  380      * @throws CException if connection fails
  381      */
  382     protected function open()
  383     {
  384         if($this->_pdo===null)
  385         {
  386             if(empty($this->connectionString))
  387                 throw new CDbException('CDbConnection.connectionString cannot be empty.');
  388             try
  389             {
  390                 Yii::trace('Opening DB connection','system.db.CDbConnection');
  391                 $this->_pdo=$this->createPdoInstance();
  392                 $this->initConnection($this->_pdo);
  393                 $this->_active=true;
  394             }
  395             catch(PDOException $e)
  396             {
  397                 if(YII_DEBUG)
  398                 {
  399                     throw new CDbException('CDbConnection failed to open the DB connection: '.
  400                         $e->getMessage(),(int)$e->getCode(),$e->errorInfo);
  401                 }
  402                 else
  403                 {
  404                     Yii::log($e->getMessage(),CLogger::LEVEL_ERROR,'exception.CDbException');
  405                     throw new CDbException('CDbConnection failed to open the DB connection.',(int)$e->getCode(),$e->errorInfo);
  406                 }
  407             }
  408         }
  409     }
  410 
  411     /**
  412      * Closes the currently active DB connection.
  413      * It does nothing if the connection is already closed.
  414      */
  415     protected function close()
  416     {
  417         Yii::trace('Closing DB connection','system.db.CDbConnection');
  418         $this->_pdo=null;
  419         $this->_active=false;
  420         $this->_schema=null;
  421     }
  422 
  423     /**
  424      * Creates the PDO instance.
  425      * When some functionalities are missing in the pdo driver, we may use
  426      * an adapter class to provide them.
  427      * @throws CDbException when failed to open DB connection
  428      * @return PDO the pdo instance
  429      */
  430     protected function createPdoInstance()
  431     {
  432         $pdoClass=$this->pdoClass;
  433         if(($driver=$this->getDriverName())!==null)
  434         {
  435             if($driver==='mssql' || $driver==='dblib')
  436                 $pdoClass='CMssqlPdoAdapter';
  437             elseif($driver==='sqlsrv')
  438                 $pdoClass='CMssqlSqlsrvPdoAdapter';
  439         }
  440 
  441         if(!class_exists($pdoClass))
  442             throw new CDbException(Yii::t('yii','CDbConnection is unable to find PDO class "{className}". Make sure PDO is installed correctly.',
  443                 array('{className}'=>$pdoClass)));
  444 
  445         @$instance=new $pdoClass($this->connectionString,$this->username,$this->password,$this->_attributes);
  446 
  447         if(!$instance)
  448             throw new CDbException(Yii::t('yii','CDbConnection failed to open the DB connection.'));
  449 
  450         return $instance;
  451     }
  452 
  453     /**
  454      * Initializes the open db connection.
  455      * This method is invoked right after the db connection is established.
  456      * The default implementation is to set the charset for MySQL, MariaDB and PostgreSQL database connections.
  457      * @param PDO $pdo the PDO instance
  458      */
  459     protected function initConnection($pdo)
  460     {
  461         $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  462         if($this->emulatePrepare!==null && constant('PDO::ATTR_EMULATE_PREPARES'))
  463             $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,$this->emulatePrepare);
  464         if($this->charset!==null)
  465         {
  466             $driver=strtolower($pdo->getAttribute(PDO::ATTR_DRIVER_NAME));
  467             if(in_array($driver,array('pgsql','mysql','mysqli')))
  468                 $pdo->exec('SET NAMES '.$pdo->quote($this->charset));
  469         }
  470         if($this->initSQLs!==null)
  471         {
  472             foreach($this->initSQLs as $sql)
  473                 $pdo->exec($sql);
  474         }
  475     }
  476 
  477     /**
  478      * Returns the PDO instance.
  479      * @return PDO the PDO instance, null if the connection is not established yet
  480      */
  481     public function getPdoInstance()
  482     {
  483         return $this->_pdo;
  484     }
  485 
  486     /**
  487      * Creates a command for execution.
  488      * @param mixed $query the DB query to be executed. This can be either a string representing a SQL statement,
  489      * or an array representing different fragments of a SQL statement. Please refer to {@link CDbCommand::__construct}
  490      * for more details about how to pass an array as the query. If this parameter is not given,
  491      * you will have to call query builder methods of {@link CDbCommand} to build the DB query.
  492      * @return CDbCommand the DB command
  493      */
  494     public function createCommand($query=null)
  495     {
  496         $this->setActive(true);
  497         return new CDbCommand($this,$query);
  498     }
  499 
  500     /**
  501      * Returns the currently active transaction.
  502      * @return CDbTransaction the currently active transaction. Null if no active transaction.
  503      */
  504     public function getCurrentTransaction()
  505     {
  506         if($this->_transaction!==null)
  507         {
  508             if($this->_transaction->getActive())
  509                 return $this->_transaction;
  510         }
  511         return null;
  512     }
  513 
  514     /**
  515      * Starts a transaction.
  516      * @return CDbTransaction the transaction initiated
  517      */
  518     public function beginTransaction()
  519     {
  520         Yii::trace('Starting transaction','system.db.CDbConnection');
  521         $this->setActive(true);
  522         $this->_pdo->beginTransaction();
  523         return $this->_transaction=new CDbTransaction($this);
  524     }
  525 
  526     /**
  527      * Returns the database schema for the current connection
  528      * @throws CDbException if CDbConnection does not support reading schema for specified database driver
  529      * @return CDbSchema the database schema for the current connection
  530      */
  531     public function getSchema()
  532     {
  533         if($this->_schema!==null)
  534             return $this->_schema;
  535         else
  536         {
  537             $driver=$this->getDriverName();
  538             if(isset($this->driverMap[$driver]))
  539                 return $this->_schema=Yii::createComponent($this->driverMap[$driver], $this);
  540             else
  541                 throw new CDbException(Yii::t('yii','CDbConnection does not support reading schema for {driver} database.',
  542                     array('{driver}'=>$driver)));
  543         }
  544     }
  545 
  546     /**
  547      * Returns the SQL command builder for the current DB connection.
  548      * @return CDbCommandBuilder the command builder
  549      */
  550     public function getCommandBuilder()
  551     {
  552         return $this->getSchema()->getCommandBuilder();
  553     }
  554 
  555     /**
  556      * Returns the ID of the last inserted row or sequence value.
  557      * @param string $sequenceName name of the sequence object (required by some DBMS)
  558      * @return string the row ID of the last row inserted, or the last value retrieved from the sequence object
  559      * @see http://www.php.net/manual/en/function.PDO-lastInsertId.php
  560      */
  561     public function getLastInsertID($sequenceName='')
  562     {
  563         $this->setActive(true);
  564         return $this->_pdo->lastInsertId($sequenceName);
  565     }
  566 
  567     /**
  568      * Quotes a string value for use in a query.
  569      * @param string $str string to be quoted
  570      * @return string the properly quoted string
  571      * @see http://www.php.net/manual/en/function.PDO-quote.php
  572      */
  573     public function quoteValue($str)
  574     {
  575         if(is_int($str) || is_float($str))
  576             return $str;
  577 
  578         $this->setActive(true);
  579         return $this->quoteValueInternal($str, PDO::PARAM_STR);
  580     }
  581 
  582     /**
  583      * Quotes a value for use in a query using a given type.
  584      * @param mixed $value the value to be quoted.
  585      * @param integer $type The type to be used for quoting.
  586      * This should be one of the `PDO::PARAM_*` constants described in
  587      * {@link http://www.php.net/manual/en/pdo.constants.php PDO documentation}.
  588      * This parameter will be passed to the `PDO::quote()` function.
  589      * @return string the properly quoted string.
  590      * @see http://www.php.net/manual/en/function.PDO-quote.php
  591      * @since 1.1.18
  592      */
  593     public function quoteValueWithType($value, $type)
  594     {
  595         $this->setActive(true);
  596         return $this->quoteValueInternal($value, $type);
  597     }
  598 
  599     /**
  600      * Quotes a value for use in a query using a given type. This method is internally used.
  601      * @param mixed $value
  602      * @param int $type
  603      * @return string
  604      */
  605     private function quoteValueInternal($value, $type)
  606     {
  607         if(mb_stripos($this->connectionString, 'odbc:')===false)
  608         {
  609             if(($quoted=$this->_pdo->quote($value, $type))!==false)
  610                 return $quoted;
  611         }
  612 
  613         // fallback for drivers that don't support quote (e.g. oci and odbc)
  614         return "'" . addcslashes(str_replace("'", "''", $value), "\000\n\r\\\032") . "'";
  615     }
  616 
  617     /**
  618      * Quotes a table name for use in a query.
  619      * If the table name contains schema prefix, the prefix will also be properly quoted.
  620      * @param string $name table name
  621      * @return string the properly quoted table name
  622      */
  623     public function quoteTableName($name)
  624     {
  625         return $this->getSchema()->quoteTableName($name);
  626     }
  627 
  628     /**
  629      * Quotes a column name for use in a query.
  630      * If the column name contains prefix, the prefix will also be properly quoted.
  631      * @param string $name column name
  632      * @return string the properly quoted column name
  633      */
  634     public function quoteColumnName($name)
  635     {
  636         return $this->getSchema()->quoteColumnName($name);
  637     }
  638 
  639     /**
  640      * Determines the PDO type for the specified PHP type.
  641      * @param string $type The PHP type (obtained by gettype() call).
  642      * @return integer the corresponding PDO type
  643      */
  644     public function getPdoType($type)
  645     {
  646         static $map=array
  647         (
  648             'boolean'=>PDO::PARAM_BOOL,
  649             'integer'=>PDO::PARAM_INT,
  650             'string'=>PDO::PARAM_STR,
  651             'resource'=>PDO::PARAM_LOB,
  652             'NULL'=>PDO::PARAM_NULL,
  653         );
  654         return isset($map[$type]) ? $map[$type] : PDO::PARAM_STR;
  655     }
  656 
  657     /**
  658      * Returns the case of the column names
  659      * @return mixed the case of the column names
  660      * @see http://www.php.net/manual/en/pdo.setattribute.php
  661      */
  662     public function getColumnCase()
  663     {
  664         return $this->getAttribute(PDO::ATTR_CASE);
  665     }
  666 
  667     /**
  668      * Sets the case of the column names.
  669      * @param mixed $value the case of the column names
  670      * @see http://www.php.net/manual/en/pdo.setattribute.php
  671      */
  672     public function setColumnCase($value)
  673     {
  674         $this->setAttribute(PDO::ATTR_CASE,$value);
  675     }
  676 
  677     /**
  678      * Returns how the null and empty strings are converted.
  679      * @return mixed how the null and empty strings are converted
  680      * @see http://www.php.net/manual/en/pdo.setattribute.php
  681      */
  682     public function getNullConversion()
  683     {
  684         return $this->getAttribute(PDO::ATTR_ORACLE_NULLS);
  685     }
  686 
  687     /**
  688      * Sets how the null and empty strings are converted.
  689      * @param mixed $value how the null and empty strings are converted
  690      * @see http://www.php.net/manual/en/pdo.setattribute.php
  691      */
  692     public function setNullConversion($value)
  693     {
  694         $this->setAttribute(PDO::ATTR_ORACLE_NULLS,$value);
  695     }
  696 
  697     /**
  698      * Returns whether creating or updating a DB record will be automatically committed.
  699      * Some DBMS (such as sqlite) may not support this feature.
  700      * @return boolean whether creating or updating a DB record will be automatically committed.
  701      */
  702     public function getAutoCommit()
  703     {
  704         return $this->getAttribute(PDO::ATTR_AUTOCOMMIT);
  705     }
  706 
  707     /**
  708      * Sets whether creating or updating a DB record will be automatically committed.
  709      * Some DBMS (such as sqlite) may not support this feature.
  710      * @param boolean $value whether creating or updating a DB record will be automatically committed.
  711      */
  712     public function setAutoCommit($value)
  713     {
  714         $this->setAttribute(PDO::ATTR_AUTOCOMMIT,$value);
  715     }
  716 
  717     /**
  718      * Returns whether the connection is persistent or not.
  719      * Some DBMS (such as sqlite) may not support this feature.
  720      * @return boolean whether the connection is persistent or not
  721      */
  722     public function getPersistent()
  723     {
  724         return $this->getAttribute(PDO::ATTR_PERSISTENT);
  725     }
  726 
  727     /**
  728      * Sets whether the connection is persistent or not.
  729      * Some DBMS (such as sqlite) may not support this feature.
  730      * @param boolean $value whether the connection is persistent or not
  731      */
  732     public function setPersistent($value)
  733     {
  734         return $this->setAttribute(PDO::ATTR_PERSISTENT,$value);
  735     }
  736 
  737     /**
  738      * Returns the name of the DB driver.
  739      * @return string name of the DB driver.
  740      */
  741     public function getDriverName()
  742     {
  743         if($this->_driverName!==null)
  744             return $this->_driverName;
  745         elseif(($pos=strpos($this->connectionString,':'))!==false)
  746             return $this->_driverName=strtolower(substr($this->connectionString,0,$pos));
  747         //return $this->getAttribute(PDO::ATTR_DRIVER_NAME);
  748     }
  749 
  750     /**
  751      * Changes the name of the DB driver. Overrides value extracted from the {@link connectionString},
  752      * which is behavior by default.
  753      * @param string $driverName to be set. Valid values are the keys from the {@link driverMap} property.
  754      * @see getDriverName
  755      * @see driverName
  756      * @since 1.1.16
  757      */
  758     public function setDriverName($driverName)
  759     {
  760         $this->_driverName=strtolower($driverName);
  761     }
  762 
  763     /**
  764      * Returns the version information of the DB driver.
  765      * @return string the version information of the DB driver
  766      */
  767     public function getClientVersion()
  768     {
  769         return $this->getAttribute(PDO::ATTR_CLIENT_VERSION);
  770     }
  771 
  772     /**
  773      * Returns the status of the connection.
  774      * Some DBMS (such as sqlite) may not support this feature.
  775      * @return string the status of the connection
  776      */
  777     public function getConnectionStatus()
  778     {
  779         return $this->getAttribute(PDO::ATTR_CONNECTION_STATUS);
  780     }
  781 
  782     /**
  783      * Returns whether the connection performs data prefetching.
  784      * @return boolean whether the connection performs data prefetching
  785      */
  786     public function getPrefetch()
  787     {
  788         return $this->getAttribute(PDO::ATTR_PREFETCH);
  789     }
  790 
  791     /**
  792      * Returns the information of DBMS server.
  793      * @return string the information of DBMS server
  794      */
  795     public function getServerInfo()
  796     {
  797         return $this->getAttribute(PDO::ATTR_SERVER_INFO);
  798     }
  799 
  800     /**
  801      * Returns the version information of DBMS server.
  802      * @return string the version information of DBMS server
  803      */
  804     public function getServerVersion()
  805     {
  806         return $this->getAttribute(PDO::ATTR_SERVER_VERSION);
  807     }
  808 
  809     /**
  810      * Returns the timeout settings for the connection.
  811      * @return integer timeout settings for the connection
  812      */
  813     public function getTimeout()
  814     {
  815         return $this->getAttribute(PDO::ATTR_TIMEOUT);
  816     }
  817 
  818     /**
  819      * Obtains a specific DB connection attribute information.
  820      * @param integer $name the attribute to be queried
  821      * @return mixed the corresponding attribute information
  822      * @see http://www.php.net/manual/en/function.PDO-getAttribute.php
  823      */
  824     public function getAttribute($name)
  825     {
  826         $this->setActive(true);
  827         return $this->_pdo->getAttribute($name);
  828     }
  829 
  830     /**
  831      * Sets an attribute on the database connection.
  832      * @param integer $name the attribute to be set
  833      * @param mixed $value the attribute value
  834      * @see http://www.php.net/manual/en/function.PDO-setAttribute.php
  835      */
  836     public function setAttribute($name,$value)
  837     {
  838         if($this->_pdo instanceof PDO)
  839             $this->_pdo->setAttribute($name,$value);
  840         else
  841             $this->_attributes[$name]=$value;
  842     }
  843 
  844     /**
  845      * Returns the attributes that are previously explicitly set for the DB connection.
  846      * @return array attributes (name=>value) that are previously explicitly set for the DB connection.
  847      * @see setAttributes
  848      * @since 1.1.7
  849      */
  850     public function getAttributes()
  851     {
  852         return $this->_attributes;
  853     }
  854 
  855     /**
  856      * Sets a set of attributes on the database connection.
  857      * @param array $values attributes (name=>value) to be set.
  858      * @see setAttribute
  859      * @since 1.1.7
  860      */
  861     public function setAttributes($values)
  862     {
  863         foreach($values as $name=>$value)
  864             $this->_attributes[$name]=$value;
  865     }
  866 
  867     /**
  868      * Returns the statistical results of SQL executions.
  869      * The results returned include the number of SQL statements executed and
  870      * the total time spent.
  871      * In order to use this method, {@link enableProfiling} has to be set true.
  872      * @return array the first element indicates the number of SQL statements executed,
  873      * and the second element the total time spent in SQL execution.
  874      */
  875     public function getStats()
  876     {
  877         $logger=Yii::getLogger();
  878         $timings=$logger->getProfilingResults(null,'system.db.CDbCommand.query');
  879         $count=count($timings);
  880         $time=array_sum($timings);
  881         $timings=$logger->getProfilingResults(null,'system.db.CDbCommand.execute');
  882         $count+=count($timings);
  883         $time+=array_sum($timings);
  884         return array($count,$time);
  885     }
  886 }