"Fossies" - the Fresh Open Source Software Archive

Member "icingaweb2-2.7.3/library/vendor/Zend/Db/Adapter/Abstract.php" (18 Oct 2019, 40689 Bytes) of package /linux/www/icingaweb2-2.7.3.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 "Abstract.php" see the Fossies "Dox" file reference documentation.

    1 <?php
    2 /**
    3  * Zend Framework
    4  *
    5  * LICENSE
    6  *
    7  * This source file is subject to the new BSD license that is bundled
    8  * with this package in the file LICENSE.txt.
    9  * It is also available through the world-wide-web at this URL:
   10  * http://framework.zend.com/license/new-bsd
   11  * If you did not receive a copy of the license and are unable to
   12  * obtain it through the world-wide-web, please send an email
   13  * to license@zend.com so we can send you a copy immediately.
   14  *
   15  * @category   Zend
   16  * @package    Zend_Db
   17  * @subpackage Adapter
   18  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
   19  * @license    http://framework.zend.com/license/new-bsd     New BSD License
   20  * @version    $Id$
   21  */
   22 
   23 
   24 /**
   25  * @see Zend_Db
   26  */
   27 
   28 /**
   29  * @see Zend_Db_Select
   30  */
   31 
   32 /**
   33  * Class for connecting to SQL databases and performing common operations.
   34  *
   35  * @category   Zend
   36  * @package    Zend_Db
   37  * @subpackage Adapter
   38  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
   39  * @license    http://framework.zend.com/license/new-bsd     New BSD License
   40  */
   41 abstract class Zend_Db_Adapter_Abstract
   42 {
   43 
   44     /**
   45      * User-provided configuration
   46      *
   47      * @var array
   48      */
   49     protected $_config = array();
   50 
   51     /**
   52      * Fetch mode
   53      *
   54      * @var integer
   55      */
   56     protected $_fetchMode = Zend_Db::FETCH_ASSOC;
   57 
   58     /**
   59      * Query profiler object, of type Zend_Db_Profiler
   60      * or a subclass of that.
   61      *
   62      * @var Zend_Db_Profiler
   63      */
   64     protected $_profiler;
   65 
   66     /**
   67      * Default class name for a DB statement.
   68      *
   69      * @var string
   70      */
   71     protected $_defaultStmtClass = 'Zend_Db_Statement';
   72 
   73     /**
   74      * Default class name for the profiler object.
   75      *
   76      * @var string
   77      */
   78     protected $_defaultProfilerClass = 'Zend_Db_Profiler';
   79 
   80     /**
   81      * Database connection
   82      *
   83      * @var object|resource|null
   84      */
   85     protected $_connection = null;
   86 
   87     /**
   88      * Specifies the case of column names retrieved in queries
   89      * Options
   90      * Zend_Db::CASE_NATURAL (default)
   91      * Zend_Db::CASE_LOWER
   92      * Zend_Db::CASE_UPPER
   93      *
   94      * @var integer
   95      */
   96     protected $_caseFolding = Zend_Db::CASE_NATURAL;
   97 
   98     /**
   99      * Specifies whether the adapter automatically quotes identifiers.
  100      * If true, most SQL generated by Zend_Db classes applies
  101      * identifier quoting automatically.
  102      * If false, developer must quote identifiers themselves
  103      * by calling quoteIdentifier().
  104      *
  105      * @var bool
  106      */
  107     protected $_autoQuoteIdentifiers = true;
  108 
  109     /**
  110      * Keys are UPPERCASE SQL datatypes or the constants
  111      * Zend_Db::INT_TYPE, Zend_Db::BIGINT_TYPE, or Zend_Db::FLOAT_TYPE.
  112      *
  113      * Values are:
  114      * 0 = 32-bit integer
  115      * 1 = 64-bit integer
  116      * 2 = float or decimal
  117      *
  118      * @var array Associative array of datatypes to values 0, 1, or 2.
  119      */
  120     protected $_numericDataTypes = array(
  121         Zend_Db::INT_TYPE    => Zend_Db::INT_TYPE,
  122         Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE,
  123         Zend_Db::FLOAT_TYPE  => Zend_Db::FLOAT_TYPE
  124     );
  125 
  126     /** Weither or not that object can get serialized
  127      *
  128      * @var bool
  129      */
  130     protected $_allowSerialization = true;
  131 
  132     /**
  133      * Weither or not the database should be reconnected
  134      * to that adapter when waking up
  135      *
  136      * @var bool
  137      */
  138     protected $_autoReconnectOnUnserialize = false;
  139 
  140     /**
  141      * Constructor.
  142      *
  143      * $config is an array of key/value pairs or an instance of Zend_Config
  144      * containing configuration options.  These options are common to most adapters:
  145      *
  146      * dbname         => (string) The name of the database to user
  147      * username       => (string) Connect to the database as this username.
  148      * password       => (string) Password associated with the username.
  149      * host           => (string) What host to connect to, defaults to localhost
  150      *
  151      * Some options are used on a case-by-case basis by adapters:
  152      *
  153      * port           => (string) The port of the database
  154      * persistent     => (boolean) Whether to use a persistent connection or not, defaults to false
  155      * protocol       => (string) The network protocol, defaults to TCPIP
  156      * caseFolding    => (int) style of case-alteration used for identifiers
  157      * socket         => (string) The socket or named pipe that should be used
  158      *
  159      * @param  array|Zend_Config $config An array or instance of Zend_Config having configuration data
  160      * @throws Zend_Db_Adapter_Exception
  161      */
  162     public function __construct($config)
  163     {
  164         /*
  165          * Verify that adapter parameters are in an array.
  166          */
  167         if (!is_array($config)) {
  168             /*
  169              * Convert Zend_Config argument to a plain array.
  170              */
  171             if ($config instanceof Zend_Config) {
  172                 $config = $config->toArray();
  173             } else {
  174                 /**
  175                  * @see Zend_Db_Adapter_Exception
  176                  */
  177                 throw new Zend_Db_Adapter_Exception('Adapter parameters must be in an array or a Zend_Config object');
  178             }
  179         }
  180 
  181         $this->_checkRequiredOptions($config);
  182 
  183         $options = array(
  184             Zend_Db::CASE_FOLDING           => $this->_caseFolding,
  185             Zend_Db::AUTO_QUOTE_IDENTIFIERS => $this->_autoQuoteIdentifiers,
  186             Zend_Db::FETCH_MODE             => $this->_fetchMode,
  187         );
  188         $driverOptions = array();
  189 
  190         /*
  191          * normalize the config and merge it with the defaults
  192          */
  193         if (array_key_exists('options', $config)) {
  194             // can't use array_merge() because keys might be integers
  195             foreach ((array) $config['options'] as $key => $value) {
  196                 $options[$key] = $value;
  197             }
  198         }
  199         if (array_key_exists('driver_options', $config)) {
  200             if (!empty($config['driver_options'])) {
  201                 // can't use array_merge() because keys might be integers
  202                 foreach ((array) $config['driver_options'] as $key => $value) {
  203                     $driverOptions[$key] = $value;
  204                 }
  205             }
  206         }
  207 
  208         if (!isset($config['charset'])) {
  209             $config['charset'] = null;
  210         }
  211 
  212         if (!isset($config['persistent'])) {
  213             $config['persistent'] = false;
  214         }
  215 
  216         $this->_config = array_merge($this->_config, $config);
  217         $this->_config['options'] = $options;
  218         $this->_config['driver_options'] = $driverOptions;
  219 
  220 
  221         // obtain the case setting, if there is one
  222         if (array_key_exists(Zend_Db::CASE_FOLDING, $options)) {
  223             $case = (int) $options[Zend_Db::CASE_FOLDING];
  224             switch ($case) {
  225                 case Zend_Db::CASE_LOWER:
  226                 case Zend_Db::CASE_UPPER:
  227                 case Zend_Db::CASE_NATURAL:
  228                     $this->_caseFolding = $case;
  229                     break;
  230                 default:
  231                     /** @see Zend_Db_Adapter_Exception */
  232                     throw new Zend_Db_Adapter_Exception('Case must be one of the following constants: '
  233                         . 'Zend_Db::CASE_NATURAL, Zend_Db::CASE_LOWER, Zend_Db::CASE_UPPER');
  234             }
  235         }
  236 
  237         if (array_key_exists(Zend_Db::FETCH_MODE, $options)) {
  238             if (is_string($options[Zend_Db::FETCH_MODE])) {
  239                 $constant = 'Zend_Db::FETCH_' . strtoupper($options[Zend_Db::FETCH_MODE]);
  240                 if(defined($constant)) {
  241                     $options[Zend_Db::FETCH_MODE] = constant($constant);
  242                 }
  243             }
  244             $this->setFetchMode((int) $options[Zend_Db::FETCH_MODE]);
  245         }
  246 
  247         // obtain quoting property if there is one
  248         if (array_key_exists(Zend_Db::AUTO_QUOTE_IDENTIFIERS, $options)) {
  249             $this->_autoQuoteIdentifiers = (bool) $options[Zend_Db::AUTO_QUOTE_IDENTIFIERS];
  250         }
  251 
  252         // obtain allow serialization property if there is one
  253         if (array_key_exists(Zend_Db::ALLOW_SERIALIZATION, $options)) {
  254             $this->_allowSerialization = (bool) $options[Zend_Db::ALLOW_SERIALIZATION];
  255         }
  256 
  257         // obtain auto reconnect on unserialize property if there is one
  258         if (array_key_exists(Zend_Db::AUTO_RECONNECT_ON_UNSERIALIZE, $options)) {
  259             $this->_autoReconnectOnUnserialize = (bool) $options[Zend_Db::AUTO_RECONNECT_ON_UNSERIALIZE];
  260         }
  261 
  262         // create a profiler object
  263         $profiler = false;
  264         if (array_key_exists(Zend_Db::PROFILER, $this->_config)) {
  265             $profiler = $this->_config[Zend_Db::PROFILER];
  266             unset($this->_config[Zend_Db::PROFILER]);
  267         }
  268         $this->setProfiler($profiler);
  269     }
  270 
  271     /**
  272      * Check for config options that are mandatory.
  273      * Throw exceptions if any are missing.
  274      *
  275      * @param array $config
  276      * @throws Zend_Db_Adapter_Exception
  277      */
  278     protected function _checkRequiredOptions(array $config)
  279     {
  280         // we need at least a dbname
  281         if (! array_key_exists('dbname', $config)) {
  282             /** @see Zend_Db_Adapter_Exception */
  283             throw new Zend_Db_Adapter_Exception("Configuration array must have a key for 'dbname' that names the database instance");
  284         }
  285 
  286         if (! array_key_exists('password', $config)) {
  287             /**
  288              * @see Zend_Db_Adapter_Exception
  289              */
  290             throw new Zend_Db_Adapter_Exception("Configuration array must have a key for 'password' for login credentials");
  291         }
  292 
  293         if (! array_key_exists('username', $config)) {
  294             /**
  295              * @see Zend_Db_Adapter_Exception
  296              */
  297             throw new Zend_Db_Adapter_Exception("Configuration array must have a key for 'username' for login credentials");
  298         }
  299     }
  300 
  301     /**
  302      * Returns the underlying database connection object or resource.
  303      * If not presently connected, this initiates the connection.
  304      *
  305      * @return object|resource|null
  306      */
  307     public function getConnection()
  308     {
  309         $this->_connect();
  310         return $this->_connection;
  311     }
  312 
  313     /**
  314      * Returns the configuration variables in this adapter.
  315      *
  316      * @return array
  317      */
  318     public function getConfig()
  319     {
  320         return $this->_config;
  321     }
  322 
  323     /**
  324      * Set the adapter's profiler object.
  325      *
  326      * The argument may be a boolean, an associative array, an instance of
  327      * Zend_Db_Profiler, or an instance of Zend_Config.
  328      *
  329      * A boolean argument sets the profiler to enabled if true, or disabled if
  330      * false.  The profiler class is the adapter's default profiler class,
  331      * Zend_Db_Profiler.
  332      *
  333      * An instance of Zend_Db_Profiler sets the adapter's instance to that
  334      * object.  The profiler is enabled and disabled separately.
  335      *
  336      * An associative array argument may contain any of the keys 'enabled',
  337      * 'class', and 'instance'. The 'enabled' and 'instance' keys correspond to the
  338      * boolean and object types documented above. The 'class' key is used to name a
  339      * class to use for a custom profiler. The class must be Zend_Db_Profiler or a
  340      * subclass. The class is instantiated with no constructor arguments. The 'class'
  341      * option is ignored when the 'instance' option is supplied.
  342      *
  343      * An object of type Zend_Config may contain the properties 'enabled', 'class', and
  344      * 'instance', just as if an associative array had been passed instead.
  345      *
  346      * @param  Zend_Db_Profiler|Zend_Config|array|boolean $profiler
  347      * @return Zend_Db_Adapter_Abstract Provides a fluent interface
  348      * @throws Zend_Db_Profiler_Exception if the object instance or class specified
  349      *         is not Zend_Db_Profiler or an extension of that class.
  350      */
  351     public function setProfiler($profiler)
  352     {
  353         $enabled          = null;
  354         $profilerClass    = $this->_defaultProfilerClass;
  355         $profilerInstance = null;
  356 
  357         if ($profilerIsObject = is_object($profiler)) {
  358             if ($profiler instanceof Zend_Db_Profiler) {
  359                 $profilerInstance = $profiler;
  360             } else if ($profiler instanceof Zend_Config) {
  361                 $profiler = $profiler->toArray();
  362             } else {
  363                 /**
  364                  * @see Zend_Db_Profiler_Exception
  365                  */
  366                 throw new Zend_Db_Profiler_Exception('Profiler argument must be an instance of either Zend_Db_Profiler'
  367                     . ' or Zend_Config when provided as an object');
  368             }
  369         }
  370 
  371         if (is_array($profiler)) {
  372             if (isset($profiler['enabled'])) {
  373                 $enabled = (bool) $profiler['enabled'];
  374             }
  375             if (isset($profiler['class'])) {
  376                 $profilerClass = $profiler['class'];
  377             }
  378             if (isset($profiler['instance'])) {
  379                 $profilerInstance = $profiler['instance'];
  380             }
  381         } else if (!$profilerIsObject) {
  382             $enabled = (bool) $profiler;
  383         }
  384 
  385         if ($profilerInstance === null) {
  386             if (!class_exists($profilerClass)) {
  387                 Zend_Loader::loadClass($profilerClass);
  388             }
  389             $profilerInstance = new $profilerClass();
  390         }
  391 
  392         if (!$profilerInstance instanceof Zend_Db_Profiler) {
  393             /** @see Zend_Db_Profiler_Exception */
  394             throw new Zend_Db_Profiler_Exception('Class ' . get_class($profilerInstance) . ' does not extend '
  395                 . 'Zend_Db_Profiler');
  396         }
  397 
  398         if (null !== $enabled) {
  399             $profilerInstance->setEnabled($enabled);
  400         }
  401 
  402         $this->_profiler = $profilerInstance;
  403 
  404         return $this;
  405     }
  406 
  407 
  408     /**
  409      * Returns the profiler for this adapter.
  410      *
  411      * @return Zend_Db_Profiler
  412      */
  413     public function getProfiler()
  414     {
  415         return $this->_profiler;
  416     }
  417 
  418     /**
  419      * Get the default statement class.
  420      *
  421      * @return string
  422      */
  423     public function getStatementClass()
  424     {
  425         return $this->_defaultStmtClass;
  426     }
  427 
  428     /**
  429      * Set the default statement class.
  430      *
  431      * @return Zend_Db_Adapter_Abstract Fluent interface
  432      */
  433     public function setStatementClass($class)
  434     {
  435         $this->_defaultStmtClass = $class;
  436         return $this;
  437     }
  438 
  439     /**
  440      * Prepares and executes an SQL statement with bound data.
  441      *
  442      * @param  mixed  $sql  The SQL statement with placeholders.
  443      *                      May be a string or Zend_Db_Select.
  444      * @param  mixed  $bind An array of data to bind to the placeholders.
  445      * @return Zend_Db_Statement_Interface
  446      */
  447     public function query($sql, $bind = array())
  448     {
  449         // connect to the database if needed
  450         $this->_connect();
  451 
  452         // is the $sql a Zend_Db_Select object?
  453         if ($sql instanceof Zend_Db_Select) {
  454             if (empty($bind)) {
  455                 $bind = $sql->getBind();
  456             }
  457 
  458             $sql = $sql->assemble();
  459         }
  460 
  461         // make sure $bind to an array;
  462         // don't use (array) typecasting because
  463         // because $bind may be a Zend_Db_Expr object
  464         if (!is_array($bind)) {
  465             $bind = array($bind);
  466         }
  467 
  468         // prepare and execute the statement with profiling
  469         $stmt = $this->prepare($sql);
  470         $stmt->execute($bind);
  471 
  472         // return the results embedded in the prepared statement object
  473         $stmt->setFetchMode($this->_fetchMode);
  474         return $stmt;
  475     }
  476 
  477     /**
  478      * Leave autocommit mode and begin a transaction.
  479      *
  480      * @return Zend_Db_Adapter_Abstract
  481      */
  482     public function beginTransaction()
  483     {
  484         $this->_connect();
  485         $q = $this->_profiler->queryStart('begin', Zend_Db_Profiler::TRANSACTION);
  486         $this->_beginTransaction();
  487         $this->_profiler->queryEnd($q);
  488         return $this;
  489     }
  490 
  491     /**
  492      * Commit a transaction and return to autocommit mode.
  493      *
  494      * @return Zend_Db_Adapter_Abstract
  495      */
  496     public function commit()
  497     {
  498         $this->_connect();
  499         $q = $this->_profiler->queryStart('commit', Zend_Db_Profiler::TRANSACTION);
  500         $this->_commit();
  501         $this->_profiler->queryEnd($q);
  502         return $this;
  503     }
  504 
  505     /**
  506      * Roll back a transaction and return to autocommit mode.
  507      *
  508      * @return Zend_Db_Adapter_Abstract
  509      */
  510     public function rollBack()
  511     {
  512         $this->_connect();
  513         $q = $this->_profiler->queryStart('rollback', Zend_Db_Profiler::TRANSACTION);
  514         $this->_rollBack();
  515         $this->_profiler->queryEnd($q);
  516         return $this;
  517     }
  518 
  519     /**
  520      * Inserts a table row with specified data.
  521      *
  522      * @param mixed $table The table to insert data into.
  523      * @param array $bind Column-value pairs.
  524      * @return int The number of affected rows.
  525      * @throws Zend_Db_Adapter_Exception
  526      */
  527     public function insert($table, array $bind)
  528     {
  529         // extract and quote col names from the array keys
  530         $cols = array();
  531         $vals = array();
  532         $i = 0;
  533         foreach ($bind as $col => $val) {
  534             $cols[] = $this->quoteIdentifier($col, true);
  535             if ($val instanceof Zend_Db_Expr) {
  536                 $vals[] = $val->__toString();
  537                 unset($bind[$col]);
  538             } else {
  539                 if ($this->supportsParameters('positional')) {
  540                     $vals[] = '?';
  541                 } else {
  542                     if ($this->supportsParameters('named')) {
  543                         unset($bind[$col]);
  544                         $bind[':col'.$i] = $val;
  545                         $vals[] = ':col'.$i;
  546                         $i++;
  547                     } else {
  548                         /** @see Zend_Db_Adapter_Exception */
  549                         throw new Zend_Db_Adapter_Exception(get_class($this) ." doesn't support positional or named binding");
  550                     }
  551                 }
  552             }
  553         }
  554 
  555         // build the statement
  556         $sql = "INSERT INTO "
  557              . $this->quoteIdentifier($table, true)
  558              . ' (' . implode(', ', $cols) . ') '
  559              . 'VALUES (' . implode(', ', $vals) . ')';
  560 
  561         // execute the statement and return the number of affected rows
  562         if ($this->supportsParameters('positional')) {
  563             $bind = array_values($bind);
  564         }
  565         $stmt = $this->query($sql, $bind);
  566         $result = $stmt->rowCount();
  567         return $result;
  568     }
  569 
  570     /**
  571      * Updates table rows with specified data based on a WHERE clause.
  572      *
  573      * @param  mixed        $table The table to update.
  574      * @param  array        $bind  Column-value pairs.
  575      * @param  mixed        $where UPDATE WHERE clause(s).
  576      * @return int          The number of affected rows.
  577      * @throws Zend_Db_Adapter_Exception
  578      */
  579     public function update($table, array $bind, $where = '')
  580     {
  581         /**
  582          * Build "col = ?" pairs for the statement,
  583          * except for Zend_Db_Expr which is treated literally.
  584          */
  585         $set = array();
  586         $i = 0;
  587         foreach ($bind as $col => $val) {
  588             if ($val instanceof Zend_Db_Expr) {
  589                 $val = $val->__toString();
  590                 unset($bind[$col]);
  591             } else {
  592                 if ($this->supportsParameters('positional')) {
  593                     $val = '?';
  594                 } else {
  595                     if ($this->supportsParameters('named')) {
  596                         unset($bind[$col]);
  597                         $bind[':col'.$i] = $val;
  598                         $val = ':col'.$i;
  599                         $i++;
  600                     } else {
  601                         /** @see Zend_Db_Adapter_Exception */
  602                         throw new Zend_Db_Adapter_Exception(get_class($this) ." doesn't support positional or named binding");
  603                     }
  604                 }
  605             }
  606             $set[] = $this->quoteIdentifier($col, true) . ' = ' . $val;
  607         }
  608 
  609         $where = $this->_whereExpr($where);
  610 
  611         /**
  612          * Build the UPDATE statement
  613          */
  614         $sql = "UPDATE "
  615              . $this->quoteIdentifier($table, true)
  616              . ' SET ' . implode(', ', $set)
  617              . (($where) ? " WHERE $where" : '');
  618 
  619         /**
  620          * Execute the statement and return the number of affected rows
  621          */
  622         if ($this->supportsParameters('positional')) {
  623             $stmt = $this->query($sql, array_values($bind));
  624         } else {
  625             $stmt = $this->query($sql, $bind);
  626         }
  627         $result = $stmt->rowCount();
  628         return $result;
  629     }
  630 
  631     /**
  632      * Deletes table rows based on a WHERE clause.
  633      *
  634      * @param  mixed        $table The table to update.
  635      * @param  mixed        $where DELETE WHERE clause(s).
  636      * @return int          The number of affected rows.
  637      */
  638     public function delete($table, $where = '')
  639     {
  640         $where = $this->_whereExpr($where);
  641 
  642         /**
  643          * Build the DELETE statement
  644          */
  645         $sql = "DELETE FROM "
  646              . $this->quoteIdentifier($table, true)
  647              . (($where) ? " WHERE $where" : '');
  648 
  649         /**
  650          * Execute the statement and return the number of affected rows
  651          */
  652         $stmt = $this->query($sql);
  653         $result = $stmt->rowCount();
  654         return $result;
  655     }
  656 
  657     /**
  658      * Convert an array, string, or Zend_Db_Expr object
  659      * into a string to put in a WHERE clause.
  660      *
  661      * @param mixed $where
  662      * @return string
  663      */
  664     protected function _whereExpr($where)
  665     {
  666         if (empty($where)) {
  667             return $where;
  668         }
  669         if (!is_array($where)) {
  670             $where = array($where);
  671         }
  672         foreach ($where as $cond => &$term) {
  673             // is $cond an int? (i.e. Not a condition)
  674             if (is_int($cond)) {
  675                 // $term is the full condition
  676                 if ($term instanceof Zend_Db_Expr) {
  677                     $term = $term->__toString();
  678                 }
  679             } else {
  680                 // $cond is the condition with placeholder,
  681                 // and $term is quoted into the condition
  682                 $term = $this->quoteInto($cond, $term);
  683             }
  684             $term = '(' . $term . ')';
  685         }
  686 
  687         $where = implode(' AND ', $where);
  688         return $where;
  689     }
  690 
  691     /**
  692      * Creates and returns a new Zend_Db_Select object for this adapter.
  693      *
  694      * @return Zend_Db_Select
  695      */
  696     public function select()
  697     {
  698         return new Zend_Db_Select($this);
  699     }
  700 
  701     /**
  702      * Get the fetch mode.
  703      *
  704      * @return int
  705      */
  706     public function getFetchMode()
  707     {
  708         return $this->_fetchMode;
  709     }
  710 
  711     /**
  712      * Fetches all SQL result rows as a sequential array.
  713      * Uses the current fetchMode for the adapter.
  714      *
  715      * @param string|Zend_Db_Select $sql  An SQL SELECT statement.
  716      * @param mixed                 $bind Data to bind into SELECT placeholders.
  717      * @param mixed                 $fetchMode Override current fetch mode.
  718      * @return array
  719      */
  720     public function fetchAll($sql, $bind = array(), $fetchMode = null)
  721     {
  722         if ($fetchMode === null) {
  723             $fetchMode = $this->_fetchMode;
  724         }
  725         $stmt = $this->query($sql, $bind);
  726         $result = $stmt->fetchAll($fetchMode);
  727         return $result;
  728     }
  729 
  730     /**
  731      * Fetches the first row of the SQL result.
  732      * Uses the current fetchMode for the adapter.
  733      *
  734      * @param string|Zend_Db_Select $sql An SQL SELECT statement.
  735      * @param mixed $bind Data to bind into SELECT placeholders.
  736      * @param mixed                 $fetchMode Override current fetch mode.
  737      * @return mixed Array, object, or scalar depending on fetch mode.
  738      */
  739     public function fetchRow($sql, $bind = array(), $fetchMode = null)
  740     {
  741         if ($fetchMode === null) {
  742             $fetchMode = $this->_fetchMode;
  743         }
  744         $stmt = $this->query($sql, $bind);
  745         $result = $stmt->fetch($fetchMode);
  746         return $result;
  747     }
  748 
  749     /**
  750      * Fetches all SQL result rows as an associative array.
  751      *
  752      * The first column is the key, the entire row array is the
  753      * value.  You should construct the query to be sure that
  754      * the first column contains unique values, or else
  755      * rows with duplicate values in the first column will
  756      * overwrite previous data.
  757      *
  758      * @param string|Zend_Db_Select $sql An SQL SELECT statement.
  759      * @param mixed $bind Data to bind into SELECT placeholders.
  760      * @return array
  761      */
  762     public function fetchAssoc($sql, $bind = array())
  763     {
  764         $stmt = $this->query($sql, $bind);
  765         $data = array();
  766         while ($row = $stmt->fetch(Zend_Db::FETCH_ASSOC)) {
  767             $tmp = array_values(array_slice($row, 0, 1));
  768             $data[$tmp[0]] = $row;
  769         }
  770         return $data;
  771     }
  772 
  773     /**
  774      * Fetches the first column of all SQL result rows as an array.
  775      *
  776      * @param string|Zend_Db_Select $sql An SQL SELECT statement.
  777      * @param mixed $bind Data to bind into SELECT placeholders.
  778      * @return array
  779      */
  780     public function fetchCol($sql, $bind = array())
  781     {
  782         $stmt = $this->query($sql, $bind);
  783         $result = $stmt->fetchAll(Zend_Db::FETCH_COLUMN, 0);
  784         return $result;
  785     }
  786 
  787     /**
  788      * Fetches all SQL result rows as an array of key-value pairs.
  789      *
  790      * The first column is the key, the second column is the
  791      * value.
  792      *
  793      * @param string|Zend_Db_Select $sql An SQL SELECT statement.
  794      * @param mixed $bind Data to bind into SELECT placeholders.
  795      * @return array
  796      */
  797     public function fetchPairs($sql, $bind = array())
  798     {
  799         $stmt = $this->query($sql, $bind);
  800         $data = array();
  801         while ($row = $stmt->fetch(Zend_Db::FETCH_NUM)) {
  802             $data[$row[0]] = $row[1];
  803         }
  804         return $data;
  805     }
  806 
  807     /**
  808      * Fetches the first column of the first row of the SQL result.
  809      *
  810      * @param string|Zend_Db_Select $sql An SQL SELECT statement.
  811      * @param mixed $bind Data to bind into SELECT placeholders.
  812      * @return string
  813      */
  814     public function fetchOne($sql, $bind = array())
  815     {
  816         $stmt = $this->query($sql, $bind);
  817         $result = $stmt->fetchColumn(0);
  818         return $result;
  819     }
  820 
  821     /**
  822      * Quote a raw string.
  823      *
  824      * @param string $value     Raw string
  825      * @return string           Quoted string
  826      */
  827     protected function _quote($value)
  828     {
  829         if (is_int($value)) {
  830             return $value;
  831         } elseif (is_float($value)) {
  832             return sprintf('%F', $value);
  833         }
  834         return "'" . addcslashes($value, "\000\n\r\\'\"\032") . "'";
  835     }
  836 
  837     /**
  838      * Safely quotes a value for an SQL statement.
  839      *
  840      * If an array is passed as the value, the array values are quoted
  841      * and then returned as a comma-separated string.
  842      *
  843      * @param mixed $value The value to quote.
  844      * @param mixed $type  OPTIONAL the SQL datatype name, or constant, or null.
  845      * @return mixed An SQL-safe quoted value (or string of separated values).
  846      */
  847     public function quote($value, $type = null)
  848     {
  849         $this->_connect();
  850 
  851         if ($value instanceof Zend_Db_Select) {
  852             return '(' . $value->assemble() . ')';
  853         }
  854 
  855         if ($value instanceof Zend_Db_Expr) {
  856             return $value->__toString();
  857         }
  858 
  859         if (is_array($value)) {
  860             foreach ($value as &$val) {
  861                 $val = $this->quote($val, $type);
  862             }
  863             return implode(', ', $value);
  864         }
  865 
  866         if ($type !== null && array_key_exists($type = strtoupper($type), $this->_numericDataTypes)) {
  867             $quotedValue = '0';
  868             switch ($this->_numericDataTypes[$type]) {
  869                 case Zend_Db::INT_TYPE: // 32-bit integer
  870                     $quotedValue = (string) intval($value);
  871                     break;
  872                 case Zend_Db::BIGINT_TYPE: // 64-bit integer
  873                     // ANSI SQL-style hex literals (e.g. x'[\dA-F]+')
  874                     // are not supported here, because these are string
  875                     // literals, not numeric literals.
  876                     if (preg_match('/^(
  877                           [+-]?                  # optional sign
  878                           (?:
  879                             0[Xx][\da-fA-F]+     # ODBC-style hexadecimal
  880                             |\d+                 # decimal or octal, or MySQL ZEROFILL decimal
  881                             (?:[eE][+-]?\d+)?    # optional exponent on decimals or octals
  882                           )
  883                         )/x',
  884                         (string) $value, $matches)) {
  885                         $quotedValue = $matches[1];
  886                     }
  887                     break;
  888                 case Zend_Db::FLOAT_TYPE: // float or decimal
  889                     $quotedValue = sprintf('%F', $value);
  890             }
  891             return $quotedValue;
  892         }
  893 
  894         return $this->_quote($value);
  895     }
  896 
  897     /**
  898      * Quotes a value and places into a piece of text at a placeholder.
  899      *
  900      * The placeholder is a question-mark; all placeholders will be replaced
  901      * with the quoted value.   For example:
  902      *
  903      * <code>
  904      * $text = "WHERE date < ?";
  905      * $date = "2005-01-02";
  906      * $safe = $sql->quoteInto($text, $date);
  907      * // $safe = "WHERE date < '2005-01-02'"
  908      * </code>
  909      *
  910      * @param string  $text  The text with a placeholder.
  911      * @param mixed   $value The value to quote.
  912      * @param string  $type  OPTIONAL SQL datatype
  913      * @param integer $count OPTIONAL count of placeholders to replace
  914      * @return string An SQL-safe quoted value placed into the original text.
  915      */
  916     public function quoteInto($text, $value, $type = null, $count = null)
  917     {
  918         if ($count === null) {
  919             return str_replace('?', $this->quote($value, $type), $text);
  920         } else {
  921             return implode($this->quote($value, $type), explode('?', $text, $count + 1));
  922         }
  923     }
  924 
  925     /**
  926      * Quotes an identifier.
  927      *
  928      * Accepts a string representing a qualified indentifier. For Example:
  929      * <code>
  930      * $adapter->quoteIdentifier('myschema.mytable')
  931      * </code>
  932      * Returns: "myschema"."mytable"
  933      *
  934      * Or, an array of one or more identifiers that may form a qualified identifier:
  935      * <code>
  936      * $adapter->quoteIdentifier(array('myschema','my.table'))
  937      * </code>
  938      * Returns: "myschema"."my.table"
  939      *
  940      * The actual quote character surrounding the identifiers may vary depending on
  941      * the adapter.
  942      *
  943      * @param string|array|Zend_Db_Expr $ident The identifier.
  944      * @param boolean $auto If true, heed the AUTO_QUOTE_IDENTIFIERS config option.
  945      * @return string The quoted identifier.
  946      */
  947     public function quoteIdentifier($ident, $auto=false)
  948     {
  949         return $this->_quoteIdentifierAs($ident, null, $auto);
  950     }
  951 
  952     /**
  953      * Quote a column identifier and alias.
  954      *
  955      * @param string|array|Zend_Db_Expr $ident The identifier or expression.
  956      * @param string $alias An alias for the column.
  957      * @param boolean $auto If true, heed the AUTO_QUOTE_IDENTIFIERS config option.
  958      * @return string The quoted identifier and alias.
  959      */
  960     public function quoteColumnAs($ident, $alias, $auto=false)
  961     {
  962         return $this->_quoteIdentifierAs($ident, $alias, $auto);
  963     }
  964 
  965     /**
  966      * Quote a table identifier and alias.
  967      *
  968      * @param string|array|Zend_Db_Expr $ident The identifier or expression.
  969      * @param string $alias An alias for the table.
  970      * @param boolean $auto If true, heed the AUTO_QUOTE_IDENTIFIERS config option.
  971      * @return string The quoted identifier and alias.
  972      */
  973     public function quoteTableAs($ident, $alias = null, $auto = false)
  974     {
  975         return $this->_quoteIdentifierAs($ident, $alias, $auto);
  976     }
  977 
  978     /**
  979      * Quote an identifier and an optional alias.
  980      *
  981      * @param string|array|Zend_Db_Expr $ident The identifier or expression.
  982      * @param string $alias An optional alias.
  983      * @param boolean $auto If true, heed the AUTO_QUOTE_IDENTIFIERS config option.
  984      * @param string $as The string to add between the identifier/expression and the alias.
  985      * @return string The quoted identifier and alias.
  986      */
  987     protected function _quoteIdentifierAs($ident, $alias = null, $auto = false, $as = ' AS ')
  988     {
  989         if ($ident instanceof Zend_Db_Expr) {
  990             $quoted = $ident->__toString();
  991         } elseif ($ident instanceof Zend_Db_Select) {
  992             $quoted = '(' . $ident->assemble() . ')';
  993         } else {
  994             if (is_string($ident)) {
  995                 $ident = explode('.', $ident);
  996             }
  997             if (is_array($ident)) {
  998                 $segments = array();
  999                 foreach ($ident as $segment) {
 1000                     if ($segment instanceof Zend_Db_Expr) {
 1001                         $segments[] = $segment->__toString();
 1002                     } else {
 1003                         $segments[] = $this->_quoteIdentifier($segment, $auto);
 1004                     }
 1005                 }
 1006                 if ($alias !== null && end($ident) == $alias) {
 1007                     $alias = null;
 1008                 }
 1009                 $quoted = implode('.', $segments);
 1010             } else {
 1011                 $quoted = $this->_quoteIdentifier($ident, $auto);
 1012             }
 1013         }
 1014         if ($alias !== null) {
 1015             $quoted .= $as . $this->_quoteIdentifier($alias, $auto);
 1016         }
 1017         return $quoted;
 1018     }
 1019 
 1020     /**
 1021      * Quote an identifier.
 1022      *
 1023      * @param  string $value The identifier or expression.
 1024      * @param boolean $auto If true, heed the AUTO_QUOTE_IDENTIFIERS config option.
 1025      * @return string        The quoted identifier and alias.
 1026      */
 1027     protected function _quoteIdentifier($value, $auto=false)
 1028     {
 1029         if ($auto === false || $this->_autoQuoteIdentifiers === true) {
 1030             $q = $this->getQuoteIdentifierSymbol();
 1031             return ($q . str_replace("$q", "$q$q", $value) . $q);
 1032         }
 1033         return $value;
 1034     }
 1035 
 1036     /**
 1037      * Returns the symbol the adapter uses for delimited identifiers.
 1038      *
 1039      * @return string
 1040      */
 1041     public function getQuoteIdentifierSymbol()
 1042     {
 1043         return '"';
 1044     }
 1045 
 1046     /**
 1047      * Return the most recent value from the specified sequence in the database.
 1048      * This is supported only on RDBMS brands that support sequences
 1049      * (e.g. Oracle, PostgreSQL, DB2).  Other RDBMS brands return null.
 1050      *
 1051      * @param string $sequenceName
 1052      * @return string
 1053      */
 1054     public function lastSequenceId($sequenceName)
 1055     {
 1056         return null;
 1057     }
 1058 
 1059     /**
 1060      * Generate a new value from the specified sequence in the database, and return it.
 1061      * This is supported only on RDBMS brands that support sequences
 1062      * (e.g. Oracle, PostgreSQL, DB2).  Other RDBMS brands return null.
 1063      *
 1064      * @param string $sequenceName
 1065      * @return string
 1066      */
 1067     public function nextSequenceId($sequenceName)
 1068     {
 1069         return null;
 1070     }
 1071 
 1072     /**
 1073      * Helper method to change the case of the strings used
 1074      * when returning result sets in FETCH_ASSOC and FETCH_BOTH
 1075      * modes.
 1076      *
 1077      * This is not intended to be used by application code,
 1078      * but the method must be public so the Statement class
 1079      * can invoke it.
 1080      *
 1081      * @param string $key
 1082      * @return string
 1083      */
 1084     public function foldCase($key)
 1085     {
 1086         switch ($this->_caseFolding) {
 1087             case Zend_Db::CASE_LOWER:
 1088                 $value = strtolower((string) $key);
 1089                 break;
 1090             case Zend_Db::CASE_UPPER:
 1091                 $value = strtoupper((string) $key);
 1092                 break;
 1093             case Zend_Db::CASE_NATURAL:
 1094             default:
 1095                 $value = (string) $key;
 1096         }
 1097         return $value;
 1098     }
 1099 
 1100     /**
 1101      * called when object is getting serialized
 1102      * This disconnects the DB object that cant be serialized
 1103      *
 1104      * @throws Zend_Db_Adapter_Exception
 1105      * @return array
 1106      */
 1107     public function __sleep()
 1108     {
 1109         if ($this->_allowSerialization == false) {
 1110             /** @see Zend_Db_Adapter_Exception */
 1111             throw new Zend_Db_Adapter_Exception(
 1112                 get_class($this) . ' is not allowed to be serialized'
 1113             );
 1114         }
 1115         $this->_connection = null;
 1116 
 1117         return array_keys(
 1118             array_diff_key(get_object_vars($this), array('_connection' => null))
 1119         );
 1120     }
 1121 
 1122     /**
 1123      * called when object is getting unserialized
 1124      *
 1125      * @return void
 1126      */
 1127     public function __wakeup()
 1128     {
 1129         if ($this->_autoReconnectOnUnserialize == true) {
 1130             $this->getConnection();
 1131         }
 1132     }
 1133 
 1134     /**
 1135      * Abstract Methods
 1136      */
 1137 
 1138     /**
 1139      * Returns a list of the tables in the database.
 1140      *
 1141      * @return array
 1142      */
 1143     abstract public function listTables();
 1144 
 1145     /**
 1146      * Returns the column descriptions for a table.
 1147      *
 1148      * The return value is an associative array keyed by the column name,
 1149      * as returned by the RDBMS.
 1150      *
 1151      * The value of each array element is an associative array
 1152      * with the following keys:
 1153      *
 1154      * SCHEMA_NAME => string; name of database or schema
 1155      * TABLE_NAME  => string;
 1156      * COLUMN_NAME => string; column name
 1157      * COLUMN_POSITION => number; ordinal position of column in table
 1158      * DATA_TYPE   => string; SQL datatype name of column
 1159      * DEFAULT     => string; default expression of column, null if none
 1160      * NULLABLE    => boolean; true if column can have nulls
 1161      * LENGTH      => number; length of CHAR/VARCHAR
 1162      * SCALE       => number; scale of NUMERIC/DECIMAL
 1163      * PRECISION   => number; precision of NUMERIC/DECIMAL
 1164      * UNSIGNED    => boolean; unsigned property of an integer type
 1165      * PRIMARY     => boolean; true if column is part of the primary key
 1166      * PRIMARY_POSITION => integer; position of column in primary key
 1167      *
 1168      * @param string $tableName
 1169      * @param string $schemaName OPTIONAL
 1170      * @return array
 1171      */
 1172     abstract public function describeTable($tableName, $schemaName = null);
 1173 
 1174     /**
 1175      * Creates a connection to the database.
 1176      *
 1177      * @return void
 1178      */
 1179     abstract protected function _connect();
 1180 
 1181     /**
 1182      * Test if a connection is active
 1183      *
 1184      * @return boolean
 1185      */
 1186     abstract public function isConnected();
 1187 
 1188     /**
 1189      * Force the connection to close.
 1190      *
 1191      * @return void
 1192      */
 1193     abstract public function closeConnection();
 1194 
 1195     /**
 1196      * Prepare a statement and return a PDOStatement-like object.
 1197      *
 1198      * @param string|Zend_Db_Select $sql SQL query
 1199      * @return Zend_Db_Statement|PDOStatement
 1200      */
 1201     abstract public function prepare($sql);
 1202 
 1203     /**
 1204      * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column.
 1205      *
 1206      * As a convention, on RDBMS brands that support sequences
 1207      * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence
 1208      * from the arguments and returns the last id generated by that sequence.
 1209      * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method
 1210      * returns the last value generated for such a column, and the table name
 1211      * argument is disregarded.
 1212      *
 1213      * @param string $tableName   OPTIONAL Name of table.
 1214      * @param string $primaryKey  OPTIONAL Name of primary key column.
 1215      * @return string
 1216      */
 1217     abstract public function lastInsertId($tableName = null, $primaryKey = null);
 1218 
 1219     /**
 1220      * Begin a transaction.
 1221      */
 1222     abstract protected function _beginTransaction();
 1223 
 1224     /**
 1225      * Commit a transaction.
 1226      */
 1227     abstract protected function _commit();
 1228 
 1229     /**
 1230      * Roll-back a transaction.
 1231      */
 1232     abstract protected function _rollBack();
 1233 
 1234     /**
 1235      * Set the fetch mode.
 1236      *
 1237      * @param integer $mode
 1238      * @return void
 1239      * @throws Zend_Db_Adapter_Exception
 1240      */
 1241     abstract public function setFetchMode($mode);
 1242 
 1243     /**
 1244      * Adds an adapter-specific LIMIT clause to the SELECT statement.
 1245      *
 1246      * @param mixed $sql
 1247      * @param integer $count
 1248      * @param integer $offset
 1249      * @return string
 1250      */
 1251     abstract public function limit($sql, $count, $offset = 0);
 1252 
 1253     /**
 1254      * Check if the adapter supports real SQL parameters.
 1255      *
 1256      * @param string $type 'positional' or 'named'
 1257      * @return bool
 1258      */
 1259     abstract public function supportsParameters($type);
 1260 
 1261     /**
 1262      * Retrieve server version in PHP style
 1263      *
 1264      * @return string
 1265      */
 1266     abstract public function getServerVersion();
 1267 }