summaryrefslogtreecommitdiffstats
path: root/library/vendor/Zend/Db
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--library/vendor/Zend/Db.php282
-rw-r--r--library/vendor/Zend/Db/Adapter/Abstract.php1267
-rw-r--r--library/vendor/Zend/Db/Adapter/Db2.php827
-rw-r--r--library/vendor/Zend/Db/Adapter/Db2/Exception.php44
-rw-r--r--library/vendor/Zend/Db/Adapter/Exception.php56
-rw-r--r--library/vendor/Zend/Db/Adapter/Mysqli.php543
-rw-r--r--library/vendor/Zend/Db/Adapter/Mysqli/Exception.php39
-rw-r--r--library/vendor/Zend/Db/Adapter/Oracle.php631
-rw-r--r--library/vendor/Zend/Db/Adapter/Oracle/Exception.php59
-rw-r--r--library/vendor/Zend/Db/Adapter/Pdo/Abstract.php397
-rw-r--r--library/vendor/Zend/Db/Adapter/Pdo/Ibm.php354
-rw-r--r--library/vendor/Zend/Db/Adapter/Pdo/Ibm/Db2.php224
-rw-r--r--library/vendor/Zend/Db/Adapter/Pdo/Ibm/Ids.php297
-rw-r--r--library/vendor/Zend/Db/Adapter/Pdo/Mssql.php435
-rw-r--r--library/vendor/Zend/Db/Adapter/Pdo/Mysql.php269
-rw-r--r--library/vendor/Zend/Db/Adapter/Pdo/Oci.php375
-rw-r--r--library/vendor/Zend/Db/Adapter/Pdo/Pgsql.php333
-rw-r--r--library/vendor/Zend/Db/Adapter/Pdo/Sqlite.php305
-rw-r--r--library/vendor/Zend/Db/Adapter/Sqlsrv.php662
-rw-r--r--library/vendor/Zend/Db/Adapter/Sqlsrv/Exception.php62
-rw-r--r--library/vendor/Zend/Db/Exception.php34
-rw-r--r--library/vendor/Zend/Db/Expr.php77
-rw-r--r--library/vendor/Zend/Db/Profiler.php469
-rw-r--r--library/vendor/Zend/Db/Profiler/Exception.php39
-rw-r--r--library/vendor/Zend/Db/Profiler/Query.php213
-rw-r--r--library/vendor/Zend/Db/Select.php1368
-rw-r--r--library/vendor/Zend/Db/Select/Exception.php38
-rw-r--r--library/vendor/Zend/Db/Statement.php488
-rw-r--r--library/vendor/Zend/Db/Statement/Db2.php354
-rw-r--r--library/vendor/Zend/Db/Statement/Db2/Exception.php57
-rw-r--r--library/vendor/Zend/Db/Statement/Exception.php55
-rw-r--r--library/vendor/Zend/Db/Statement/Interface.php203
-rw-r--r--library/vendor/Zend/Db/Statement/Mysqli.php356
-rw-r--r--library/vendor/Zend/Db/Statement/Mysqli/Exception.php37
-rw-r--r--library/vendor/Zend/Db/Statement/Oracle.php561
-rw-r--r--library/vendor/Zend/Db/Statement/Oracle/Exception.php58
-rw-r--r--library/vendor/Zend/Db/Statement/Pdo.php426
-rw-r--r--library/vendor/Zend/Db/Statement/Pdo/Ibm.php92
-rw-r--r--library/vendor/Zend/Db/Statement/Pdo/Oci.php90
-rw-r--r--library/vendor/Zend/Db/Statement/Sqlsrv.php430
-rw-r--r--library/vendor/Zend/Db/Statement/Sqlsrv/Exception.php60
-rw-r--r--library/vendor/Zend/Db/Table.php77
-rw-r--r--library/vendor/Zend/Db/Table/Abstract.php1599
-rw-r--r--library/vendor/Zend/Db/Table/Definition.php131
-rw-r--r--library/vendor/Zend/Db/Table/Exception.php37
-rw-r--r--library/vendor/Zend/Db/Table/Row.php41
-rw-r--r--library/vendor/Zend/Db/Table/Row/Abstract.php1160
-rw-r--r--library/vendor/Zend/Db/Table/Row/Exception.php37
-rw-r--r--library/vendor/Zend/Db/Table/Rowset.php42
-rw-r--r--library/vendor/Zend/Db/Table/Rowset/Abstract.php443
-rw-r--r--library/vendor/Zend/Db/Table/Rowset/Exception.php36
-rw-r--r--library/vendor/Zend/Db/Table/Select.php221
-rw-r--r--library/vendor/Zend/Db/Table/Select/Exception.php38
53 files changed, 16828 insertions, 0 deletions
diff --git a/library/vendor/Zend/Db.php b/library/vendor/Zend/Db.php
new file mode 100644
index 0000000..1712929
--- /dev/null
+++ b/library/vendor/Zend/Db.php
@@ -0,0 +1,282 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+
+/**
+ * Class for connecting to SQL databases and performing common operations.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db
+{
+
+ /**
+ * Use the PROFILER constant in the config of a Zend_Db_Adapter.
+ */
+ const PROFILER = 'profiler';
+
+ /**
+ * Use the CASE_FOLDING constant in the config of a Zend_Db_Adapter.
+ */
+ const CASE_FOLDING = 'caseFolding';
+
+ /**
+ * Use the FETCH_MODE constant in the config of a Zend_Db_Adapter.
+ */
+ const FETCH_MODE = 'fetchMode';
+
+ /**
+ * Use the AUTO_QUOTE_IDENTIFIERS constant in the config of a Zend_Db_Adapter.
+ */
+ const AUTO_QUOTE_IDENTIFIERS = 'autoQuoteIdentifiers';
+
+ /**
+ * Use the ALLOW_SERIALIZATION constant in the config of a Zend_Db_Adapter.
+ */
+ const ALLOW_SERIALIZATION = 'allowSerialization';
+
+ /**
+ * Use the AUTO_RECONNECT_ON_UNSERIALIZE constant in the config of a Zend_Db_Adapter.
+ */
+ const AUTO_RECONNECT_ON_UNSERIALIZE = 'autoReconnectOnUnserialize';
+
+ /**
+ * Use the INT_TYPE, BIGINT_TYPE, and FLOAT_TYPE with the quote() method.
+ */
+ const INT_TYPE = 0;
+ const BIGINT_TYPE = 1;
+ const FLOAT_TYPE = 2;
+
+ /**
+ * PDO constant values discovered by this script result:
+ *
+ * $list = array(
+ * 'PARAM_BOOL', 'PARAM_NULL', 'PARAM_INT', 'PARAM_STR', 'PARAM_LOB',
+ * 'PARAM_STMT', 'PARAM_INPUT_OUTPUT', 'FETCH_LAZY', 'FETCH_ASSOC',
+ * 'FETCH_NUM', 'FETCH_BOTH', 'FETCH_OBJ', 'FETCH_BOUND',
+ * 'FETCH_COLUMN', 'FETCH_CLASS', 'FETCH_INTO', 'FETCH_FUNC',
+ * 'FETCH_GROUP', 'FETCH_UNIQUE', 'FETCH_CLASSTYPE', 'FETCH_SERIALIZE',
+ * 'FETCH_NAMED', 'ATTR_AUTOCOMMIT', 'ATTR_PREFETCH', 'ATTR_TIMEOUT',
+ * 'ATTR_ERRMODE', 'ATTR_SERVER_VERSION', 'ATTR_CLIENT_VERSION',
+ * 'ATTR_SERVER_INFO', 'ATTR_CONNECTION_STATUS', 'ATTR_CASE',
+ * 'ATTR_CURSOR_NAME', 'ATTR_CURSOR', 'ATTR_ORACLE_NULLS',
+ * 'ATTR_PERSISTENT', 'ATTR_STATEMENT_CLASS', 'ATTR_FETCH_TABLE_NAMES',
+ * 'ATTR_FETCH_CATALOG_NAMES', 'ATTR_DRIVER_NAME',
+ * 'ATTR_STRINGIFY_FETCHES', 'ATTR_MAX_COLUMN_LEN', 'ERRMODE_SILENT',
+ * 'ERRMODE_WARNING', 'ERRMODE_EXCEPTION', 'CASE_NATURAL',
+ * 'CASE_LOWER', 'CASE_UPPER', 'NULL_NATURAL', 'NULL_EMPTY_STRING',
+ * 'NULL_TO_STRING', 'ERR_NONE', 'FETCH_ORI_NEXT',
+ * 'FETCH_ORI_PRIOR', 'FETCH_ORI_FIRST', 'FETCH_ORI_LAST',
+ * 'FETCH_ORI_ABS', 'FETCH_ORI_REL', 'CURSOR_FWDONLY', 'CURSOR_SCROLL',
+ * 'ERR_CANT_MAP', 'ERR_SYNTAX', 'ERR_CONSTRAINT', 'ERR_NOT_FOUND',
+ * 'ERR_ALREADY_EXISTS', 'ERR_NOT_IMPLEMENTED', 'ERR_MISMATCH',
+ * 'ERR_TRUNCATED', 'ERR_DISCONNECTED', 'ERR_NO_PERM',
+ * );
+ *
+ * $const = array();
+ * foreach ($list as $name) {
+ * $const[$name] = constant("PDO::$name");
+ * }
+ * var_export($const);
+ */
+ const ATTR_AUTOCOMMIT = 0;
+ const ATTR_CASE = 8;
+ const ATTR_CLIENT_VERSION = 5;
+ const ATTR_CONNECTION_STATUS = 7;
+ const ATTR_CURSOR = 10;
+ const ATTR_CURSOR_NAME = 9;
+ const ATTR_DRIVER_NAME = 16;
+ const ATTR_ERRMODE = 3;
+ const ATTR_FETCH_CATALOG_NAMES = 15;
+ const ATTR_FETCH_TABLE_NAMES = 14;
+ const ATTR_MAX_COLUMN_LEN = 18;
+ const ATTR_ORACLE_NULLS = 11;
+ const ATTR_PERSISTENT = 12;
+ const ATTR_PREFETCH = 1;
+ const ATTR_SERVER_INFO = 6;
+ const ATTR_SERVER_VERSION = 4;
+ const ATTR_STATEMENT_CLASS = 13;
+ const ATTR_STRINGIFY_FETCHES = 17;
+ const ATTR_TIMEOUT = 2;
+ const CASE_LOWER = 2;
+ const CASE_NATURAL = 0;
+ const CASE_UPPER = 1;
+ const CURSOR_FWDONLY = 0;
+ const CURSOR_SCROLL = 1;
+ const ERR_ALREADY_EXISTS = NULL;
+ const ERR_CANT_MAP = NULL;
+ const ERR_CONSTRAINT = NULL;
+ const ERR_DISCONNECTED = NULL;
+ const ERR_MISMATCH = NULL;
+ const ERR_NO_PERM = NULL;
+ const ERR_NONE = '00000';
+ const ERR_NOT_FOUND = NULL;
+ const ERR_NOT_IMPLEMENTED = NULL;
+ const ERR_SYNTAX = NULL;
+ const ERR_TRUNCATED = NULL;
+ const ERRMODE_EXCEPTION = 2;
+ const ERRMODE_SILENT = 0;
+ const ERRMODE_WARNING = 1;
+ const FETCH_ASSOC = 2;
+ const FETCH_BOTH = 4;
+ const FETCH_BOUND = 6;
+ const FETCH_CLASS = 8;
+ const FETCH_CLASSTYPE = 262144;
+ const FETCH_COLUMN = 7;
+ const FETCH_FUNC = 10;
+ const FETCH_GROUP = 65536;
+ const FETCH_INTO = 9;
+ const FETCH_LAZY = 1;
+ const FETCH_NAMED = 11;
+ const FETCH_NUM = 3;
+ const FETCH_OBJ = 5;
+ const FETCH_ORI_ABS = 4;
+ const FETCH_ORI_FIRST = 2;
+ const FETCH_ORI_LAST = 3;
+ const FETCH_ORI_NEXT = 0;
+ const FETCH_ORI_PRIOR = 1;
+ const FETCH_ORI_REL = 5;
+ const FETCH_SERIALIZE = 524288;
+ const FETCH_UNIQUE = 196608;
+ const NULL_EMPTY_STRING = 1;
+ const NULL_NATURAL = 0;
+ const NULL_TO_STRING = NULL;
+ const PARAM_BOOL = 5;
+ const PARAM_INPUT_OUTPUT = -2147483648;
+ const PARAM_INT = 1;
+ const PARAM_LOB = 3;
+ const PARAM_NULL = 0;
+ const PARAM_STMT = 4;
+ const PARAM_STR = 2;
+
+ /**
+ * Factory for Zend_Db_Adapter_Abstract classes.
+ *
+ * First argument may be a string containing the base of the adapter class
+ * name, e.g. 'Mysqli' corresponds to class Zend_Db_Adapter_Mysqli. This
+ * name is currently case-insensitive, but is not ideal to rely on this behavior.
+ * If your class is named 'My_Company_Pdo_Mysql', where 'My_Company' is the namespace
+ * and 'Pdo_Mysql' is the adapter name, it is best to use the name exactly as it
+ * is defined in the class. This will ensure proper use of the factory API.
+ *
+ * First argument may alternatively be an object of type Zend_Config.
+ * The adapter class base name is read from the 'adapter' property.
+ * The adapter config parameters are read from the 'params' property.
+ *
+ * Second argument is optional and may be an associative array of key-value
+ * pairs. This is used as the argument to the adapter constructor.
+ *
+ * If the first argument is of type Zend_Config, it is assumed to contain
+ * all parameters, and the second argument is ignored.
+ *
+ * @param mixed $adapter String name of base adapter class, or Zend_Config object.
+ * @param mixed $config OPTIONAL; an array or Zend_Config object with adapter parameters.
+ * @return Zend_Db_Adapter_Abstract
+ * @throws Zend_Db_Exception
+ */
+ public static function factory($adapter, $config = array())
+ {
+ if ($config instanceof Zend_Config) {
+ $config = $config->toArray();
+ }
+
+ /*
+ * Convert Zend_Config argument to plain string
+ * adapter name and separate config object.
+ */
+ if ($adapter instanceof Zend_Config) {
+ if (isset($adapter->params)) {
+ $config = $adapter->params->toArray();
+ }
+ if (isset($adapter->adapter)) {
+ $adapter = (string) $adapter->adapter;
+ } else {
+ $adapter = null;
+ }
+ }
+
+ /*
+ * Verify that adapter parameters are in an array.
+ */
+ if (!is_array($config)) {
+ /**
+ * @see Zend_Db_Exception
+ */
+ throw new Zend_Db_Exception('Adapter parameters must be in an array or a Zend_Config object');
+ }
+
+ /*
+ * Verify that an adapter name has been specified.
+ */
+ if (!is_string($adapter) || empty($adapter)) {
+ /**
+ * @see Zend_Db_Exception
+ */
+ throw new Zend_Db_Exception('Adapter name must be specified in a string');
+ }
+
+ /*
+ * Form full adapter class name
+ */
+ $adapterNamespace = 'Zend_Db_Adapter';
+ if (isset($config['adapterNamespace'])) {
+ if ($config['adapterNamespace'] != '') {
+ $adapterNamespace = $config['adapterNamespace'];
+ }
+ unset($config['adapterNamespace']);
+ }
+
+ // Adapter no longer normalized- see http://framework.zend.com/issues/browse/ZF-5606
+ $adapterName = $adapterNamespace . '_';
+ $adapterName .= str_replace(' ', '_', ucwords(str_replace('_', ' ', strtolower($adapter))));
+
+ /*
+ * Load the adapter class. This throws an exception
+ * if the specified class cannot be loaded.
+ */
+ if (!class_exists($adapterName)) {
+ Zend_Loader::loadClass($adapterName);
+ }
+
+ /*
+ * Create an instance of the adapter class.
+ * Pass the config to the adapter class constructor.
+ */
+ $dbAdapter = new $adapterName($config);
+
+ /*
+ * Verify that the object created is a descendent of the abstract adapter type.
+ */
+ if (! $dbAdapter instanceof Zend_Db_Adapter_Abstract) {
+ /**
+ * @see Zend_Db_Exception
+ */
+ throw new Zend_Db_Exception("Adapter class '$adapterName' does not extend Zend_Db_Adapter_Abstract");
+ }
+
+ return $dbAdapter;
+ }
+
+}
diff --git a/library/vendor/Zend/Db/Adapter/Abstract.php b/library/vendor/Zend/Db/Adapter/Abstract.php
new file mode 100644
index 0000000..cc00ea1
--- /dev/null
+++ b/library/vendor/Zend/Db/Adapter/Abstract.php
@@ -0,0 +1,1267 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+
+/**
+ * @see Zend_Db
+ */
+
+/**
+ * @see Zend_Db_Select
+ */
+
+/**
+ * Class for connecting to SQL databases and performing common operations.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+abstract class Zend_Db_Adapter_Abstract
+{
+
+ /**
+ * User-provided configuration
+ *
+ * @var array
+ */
+ protected $_config = array();
+
+ /**
+ * Fetch mode
+ *
+ * @var integer
+ */
+ protected $_fetchMode = Zend_Db::FETCH_ASSOC;
+
+ /**
+ * Query profiler object, of type Zend_Db_Profiler
+ * or a subclass of that.
+ *
+ * @var Zend_Db_Profiler
+ */
+ protected $_profiler;
+
+ /**
+ * Default class name for a DB statement.
+ *
+ * @var string
+ */
+ protected $_defaultStmtClass = 'Zend_Db_Statement';
+
+ /**
+ * Default class name for the profiler object.
+ *
+ * @var string
+ */
+ protected $_defaultProfilerClass = 'Zend_Db_Profiler';
+
+ /**
+ * Database connection
+ *
+ * @var object|resource|null
+ */
+ protected $_connection = null;
+
+ /**
+ * Specifies the case of column names retrieved in queries
+ * Options
+ * Zend_Db::CASE_NATURAL (default)
+ * Zend_Db::CASE_LOWER
+ * Zend_Db::CASE_UPPER
+ *
+ * @var integer
+ */
+ protected $_caseFolding = Zend_Db::CASE_NATURAL;
+
+ /**
+ * Specifies whether the adapter automatically quotes identifiers.
+ * If true, most SQL generated by Zend_Db classes applies
+ * identifier quoting automatically.
+ * If false, developer must quote identifiers themselves
+ * by calling quoteIdentifier().
+ *
+ * @var bool
+ */
+ protected $_autoQuoteIdentifiers = true;
+
+ /**
+ * Keys are UPPERCASE SQL datatypes or the constants
+ * Zend_Db::INT_TYPE, Zend_Db::BIGINT_TYPE, or Zend_Db::FLOAT_TYPE.
+ *
+ * Values are:
+ * 0 = 32-bit integer
+ * 1 = 64-bit integer
+ * 2 = float or decimal
+ *
+ * @var array Associative array of datatypes to values 0, 1, or 2.
+ */
+ protected $_numericDataTypes = array(
+ Zend_Db::INT_TYPE => Zend_Db::INT_TYPE,
+ Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE,
+ Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE
+ );
+
+ /** Weither or not that object can get serialized
+ *
+ * @var bool
+ */
+ protected $_allowSerialization = true;
+
+ /**
+ * Weither or not the database should be reconnected
+ * to that adapter when waking up
+ *
+ * @var bool
+ */
+ protected $_autoReconnectOnUnserialize = false;
+
+ /**
+ * Constructor.
+ *
+ * $config is an array of key/value pairs or an instance of Zend_Config
+ * containing configuration options. These options are common to most adapters:
+ *
+ * dbname => (string) The name of the database to user
+ * username => (string) Connect to the database as this username.
+ * password => (string) Password associated with the username.
+ * host => (string) What host to connect to, defaults to localhost
+ *
+ * Some options are used on a case-by-case basis by adapters:
+ *
+ * port => (string) The port of the database
+ * persistent => (boolean) Whether to use a persistent connection or not, defaults to false
+ * protocol => (string) The network protocol, defaults to TCPIP
+ * caseFolding => (int) style of case-alteration used for identifiers
+ * socket => (string) The socket or named pipe that should be used
+ *
+ * @param array|Zend_Config $config An array or instance of Zend_Config having configuration data
+ * @throws Zend_Db_Adapter_Exception
+ */
+ public function __construct($config)
+ {
+ /*
+ * Verify that adapter parameters are in an array.
+ */
+ if (!is_array($config)) {
+ /*
+ * Convert Zend_Config argument to a plain array.
+ */
+ if ($config instanceof Zend_Config) {
+ $config = $config->toArray();
+ } else {
+ /**
+ * @see Zend_Db_Adapter_Exception
+ */
+ throw new Zend_Db_Adapter_Exception('Adapter parameters must be in an array or a Zend_Config object');
+ }
+ }
+
+ $this->_checkRequiredOptions($config);
+
+ $options = array(
+ Zend_Db::CASE_FOLDING => $this->_caseFolding,
+ Zend_Db::AUTO_QUOTE_IDENTIFIERS => $this->_autoQuoteIdentifiers,
+ Zend_Db::FETCH_MODE => $this->_fetchMode,
+ );
+ $driverOptions = array();
+
+ /*
+ * normalize the config and merge it with the defaults
+ */
+ if (array_key_exists('options', $config)) {
+ // can't use array_merge() because keys might be integers
+ foreach ((array) $config['options'] as $key => $value) {
+ $options[$key] = $value;
+ }
+ }
+ if (array_key_exists('driver_options', $config)) {
+ if (!empty($config['driver_options'])) {
+ // can't use array_merge() because keys might be integers
+ foreach ((array) $config['driver_options'] as $key => $value) {
+ $driverOptions[$key] = $value;
+ }
+ }
+ }
+
+ if (!isset($config['charset'])) {
+ $config['charset'] = null;
+ }
+
+ if (!isset($config['persistent'])) {
+ $config['persistent'] = false;
+ }
+
+ $this->_config = array_merge($this->_config, $config);
+ $this->_config['options'] = $options;
+ $this->_config['driver_options'] = $driverOptions;
+
+
+ // obtain the case setting, if there is one
+ if (array_key_exists(Zend_Db::CASE_FOLDING, $options)) {
+ $case = (int) $options[Zend_Db::CASE_FOLDING];
+ switch ($case) {
+ case Zend_Db::CASE_LOWER:
+ case Zend_Db::CASE_UPPER:
+ case Zend_Db::CASE_NATURAL:
+ $this->_caseFolding = $case;
+ break;
+ default:
+ /** @see Zend_Db_Adapter_Exception */
+ throw new Zend_Db_Adapter_Exception('Case must be one of the following constants: '
+ . 'Zend_Db::CASE_NATURAL, Zend_Db::CASE_LOWER, Zend_Db::CASE_UPPER');
+ }
+ }
+
+ if (array_key_exists(Zend_Db::FETCH_MODE, $options)) {
+ if (is_string($options[Zend_Db::FETCH_MODE])) {
+ $constant = 'Zend_Db::FETCH_' . strtoupper($options[Zend_Db::FETCH_MODE]);
+ if(defined($constant)) {
+ $options[Zend_Db::FETCH_MODE] = constant($constant);
+ }
+ }
+ $this->setFetchMode((int) $options[Zend_Db::FETCH_MODE]);
+ }
+
+ // obtain quoting property if there is one
+ if (array_key_exists(Zend_Db::AUTO_QUOTE_IDENTIFIERS, $options)) {
+ $this->_autoQuoteIdentifiers = (bool) $options[Zend_Db::AUTO_QUOTE_IDENTIFIERS];
+ }
+
+ // obtain allow serialization property if there is one
+ if (array_key_exists(Zend_Db::ALLOW_SERIALIZATION, $options)) {
+ $this->_allowSerialization = (bool) $options[Zend_Db::ALLOW_SERIALIZATION];
+ }
+
+ // obtain auto reconnect on unserialize property if there is one
+ if (array_key_exists(Zend_Db::AUTO_RECONNECT_ON_UNSERIALIZE, $options)) {
+ $this->_autoReconnectOnUnserialize = (bool) $options[Zend_Db::AUTO_RECONNECT_ON_UNSERIALIZE];
+ }
+
+ // create a profiler object
+ $profiler = false;
+ if (array_key_exists(Zend_Db::PROFILER, $this->_config)) {
+ $profiler = $this->_config[Zend_Db::PROFILER];
+ unset($this->_config[Zend_Db::PROFILER]);
+ }
+ $this->setProfiler($profiler);
+ }
+
+ /**
+ * Check for config options that are mandatory.
+ * Throw exceptions if any are missing.
+ *
+ * @param array $config
+ * @throws Zend_Db_Adapter_Exception
+ */
+ protected function _checkRequiredOptions(array $config)
+ {
+ // we need at least a dbname
+ if (! array_key_exists('dbname', $config)) {
+ /** @see Zend_Db_Adapter_Exception */
+ throw new Zend_Db_Adapter_Exception("Configuration array must have a key for 'dbname' that names the database instance");
+ }
+
+ if (! array_key_exists('password', $config)) {
+ /**
+ * @see Zend_Db_Adapter_Exception
+ */
+ throw new Zend_Db_Adapter_Exception("Configuration array must have a key for 'password' for login credentials");
+ }
+
+ if (! array_key_exists('username', $config)) {
+ /**
+ * @see Zend_Db_Adapter_Exception
+ */
+ throw new Zend_Db_Adapter_Exception("Configuration array must have a key for 'username' for login credentials");
+ }
+ }
+
+ /**
+ * Returns the underlying database connection object or resource.
+ * If not presently connected, this initiates the connection.
+ *
+ * @return object|resource|null
+ */
+ public function getConnection()
+ {
+ $this->_connect();
+ return $this->_connection;
+ }
+
+ /**
+ * Returns the configuration variables in this adapter.
+ *
+ * @return array
+ */
+ public function getConfig()
+ {
+ return $this->_config;
+ }
+
+ /**
+ * Set the adapter's profiler object.
+ *
+ * The argument may be a boolean, an associative array, an instance of
+ * Zend_Db_Profiler, or an instance of Zend_Config.
+ *
+ * A boolean argument sets the profiler to enabled if true, or disabled if
+ * false. The profiler class is the adapter's default profiler class,
+ * Zend_Db_Profiler.
+ *
+ * An instance of Zend_Db_Profiler sets the adapter's instance to that
+ * object. The profiler is enabled and disabled separately.
+ *
+ * An associative array argument may contain any of the keys 'enabled',
+ * 'class', and 'instance'. The 'enabled' and 'instance' keys correspond to the
+ * boolean and object types documented above. The 'class' key is used to name a
+ * class to use for a custom profiler. The class must be Zend_Db_Profiler or a
+ * subclass. The class is instantiated with no constructor arguments. The 'class'
+ * option is ignored when the 'instance' option is supplied.
+ *
+ * An object of type Zend_Config may contain the properties 'enabled', 'class', and
+ * 'instance', just as if an associative array had been passed instead.
+ *
+ * @param Zend_Db_Profiler|Zend_Config|array|boolean $profiler
+ * @return Zend_Db_Adapter_Abstract Provides a fluent interface
+ * @throws Zend_Db_Profiler_Exception if the object instance or class specified
+ * is not Zend_Db_Profiler or an extension of that class.
+ */
+ public function setProfiler($profiler)
+ {
+ $enabled = null;
+ $profilerClass = $this->_defaultProfilerClass;
+ $profilerInstance = null;
+
+ if ($profilerIsObject = is_object($profiler)) {
+ if ($profiler instanceof Zend_Db_Profiler) {
+ $profilerInstance = $profiler;
+ } else if ($profiler instanceof Zend_Config) {
+ $profiler = $profiler->toArray();
+ } else {
+ /**
+ * @see Zend_Db_Profiler_Exception
+ */
+ throw new Zend_Db_Profiler_Exception('Profiler argument must be an instance of either Zend_Db_Profiler'
+ . ' or Zend_Config when provided as an object');
+ }
+ }
+
+ if (is_array($profiler)) {
+ if (isset($profiler['enabled'])) {
+ $enabled = (bool) $profiler['enabled'];
+ }
+ if (isset($profiler['class'])) {
+ $profilerClass = $profiler['class'];
+ }
+ if (isset($profiler['instance'])) {
+ $profilerInstance = $profiler['instance'];
+ }
+ } else if (!$profilerIsObject) {
+ $enabled = (bool) $profiler;
+ }
+
+ if ($profilerInstance === null) {
+ if (!class_exists($profilerClass)) {
+ Zend_Loader::loadClass($profilerClass);
+ }
+ $profilerInstance = new $profilerClass();
+ }
+
+ if (!$profilerInstance instanceof Zend_Db_Profiler) {
+ /** @see Zend_Db_Profiler_Exception */
+ throw new Zend_Db_Profiler_Exception('Class ' . get_class($profilerInstance) . ' does not extend '
+ . 'Zend_Db_Profiler');
+ }
+
+ if (null !== $enabled) {
+ $profilerInstance->setEnabled($enabled);
+ }
+
+ $this->_profiler = $profilerInstance;
+
+ return $this;
+ }
+
+
+ /**
+ * Returns the profiler for this adapter.
+ *
+ * @return Zend_Db_Profiler
+ */
+ public function getProfiler()
+ {
+ return $this->_profiler;
+ }
+
+ /**
+ * Get the default statement class.
+ *
+ * @return string
+ */
+ public function getStatementClass()
+ {
+ return $this->_defaultStmtClass;
+ }
+
+ /**
+ * Set the default statement class.
+ *
+ * @return Zend_Db_Adapter_Abstract Fluent interface
+ */
+ public function setStatementClass($class)
+ {
+ $this->_defaultStmtClass = $class;
+ return $this;
+ }
+
+ /**
+ * Prepares and executes an SQL statement with bound data.
+ *
+ * @param mixed $sql The SQL statement with placeholders.
+ * May be a string or Zend_Db_Select.
+ * @param mixed $bind An array of data to bind to the placeholders.
+ * @return Zend_Db_Statement_Interface
+ */
+ public function query($sql, $bind = array())
+ {
+ // connect to the database if needed
+ $this->_connect();
+
+ // is the $sql a Zend_Db_Select object?
+ if ($sql instanceof Zend_Db_Select) {
+ if (empty($bind)) {
+ $bind = $sql->getBind();
+ }
+
+ $sql = $sql->assemble();
+ }
+
+ // make sure $bind to an array;
+ // don't use (array) typecasting because
+ // because $bind may be a Zend_Db_Expr object
+ if (!is_array($bind)) {
+ $bind = array($bind);
+ }
+
+ // prepare and execute the statement with profiling
+ $stmt = $this->prepare($sql);
+ $stmt->execute($bind);
+
+ // return the results embedded in the prepared statement object
+ $stmt->setFetchMode($this->_fetchMode);
+ return $stmt;
+ }
+
+ /**
+ * Leave autocommit mode and begin a transaction.
+ *
+ * @return Zend_Db_Adapter_Abstract
+ */
+ public function beginTransaction()
+ {
+ $this->_connect();
+ $q = $this->_profiler->queryStart('begin', Zend_Db_Profiler::TRANSACTION);
+ $this->_beginTransaction();
+ $this->_profiler->queryEnd($q);
+ return $this;
+ }
+
+ /**
+ * Commit a transaction and return to autocommit mode.
+ *
+ * @return Zend_Db_Adapter_Abstract
+ */
+ public function commit()
+ {
+ $this->_connect();
+ $q = $this->_profiler->queryStart('commit', Zend_Db_Profiler::TRANSACTION);
+ $this->_commit();
+ $this->_profiler->queryEnd($q);
+ return $this;
+ }
+
+ /**
+ * Roll back a transaction and return to autocommit mode.
+ *
+ * @return Zend_Db_Adapter_Abstract
+ */
+ public function rollBack()
+ {
+ $this->_connect();
+ $q = $this->_profiler->queryStart('rollback', Zend_Db_Profiler::TRANSACTION);
+ $this->_rollBack();
+ $this->_profiler->queryEnd($q);
+ return $this;
+ }
+
+ /**
+ * Inserts a table row with specified data.
+ *
+ * @param mixed $table The table to insert data into.
+ * @param array $bind Column-value pairs.
+ * @return int The number of affected rows.
+ * @throws Zend_Db_Adapter_Exception
+ */
+ public function insert($table, array $bind)
+ {
+ // extract and quote col names from the array keys
+ $cols = array();
+ $vals = array();
+ $i = 0;
+ foreach ($bind as $col => $val) {
+ $cols[] = $this->quoteIdentifier($col, true);
+ if ($val instanceof Zend_Db_Expr) {
+ $vals[] = $val->__toString();
+ unset($bind[$col]);
+ } else {
+ if ($this->supportsParameters('positional')) {
+ $vals[] = '?';
+ } else {
+ if ($this->supportsParameters('named')) {
+ unset($bind[$col]);
+ $bind[':col'.$i] = $val;
+ $vals[] = ':col'.$i;
+ $i++;
+ } else {
+ /** @see Zend_Db_Adapter_Exception */
+ throw new Zend_Db_Adapter_Exception(get_class($this) ." doesn't support positional or named binding");
+ }
+ }
+ }
+ }
+
+ // build the statement
+ $sql = "INSERT INTO "
+ . $this->quoteIdentifier($table, true)
+ . ' (' . implode(', ', $cols) . ') '
+ . 'VALUES (' . implode(', ', $vals) . ')';
+
+ // execute the statement and return the number of affected rows
+ if ($this->supportsParameters('positional')) {
+ $bind = array_values($bind);
+ }
+ $stmt = $this->query($sql, $bind);
+ $result = $stmt->rowCount();
+ return $result;
+ }
+
+ /**
+ * Updates table rows with specified data based on a WHERE clause.
+ *
+ * @param mixed $table The table to update.
+ * @param array $bind Column-value pairs.
+ * @param mixed $where UPDATE WHERE clause(s).
+ * @return int The number of affected rows.
+ * @throws Zend_Db_Adapter_Exception
+ */
+ public function update($table, array $bind, $where = '')
+ {
+ /**
+ * Build "col = ?" pairs for the statement,
+ * except for Zend_Db_Expr which is treated literally.
+ */
+ $set = array();
+ $i = 0;
+ foreach ($bind as $col => $val) {
+ if ($val instanceof Zend_Db_Expr) {
+ $val = $val->__toString();
+ unset($bind[$col]);
+ } else {
+ if ($this->supportsParameters('positional')) {
+ $val = '?';
+ } else {
+ if ($this->supportsParameters('named')) {
+ unset($bind[$col]);
+ $bind[':col'.$i] = $val;
+ $val = ':col'.$i;
+ $i++;
+ } else {
+ /** @see Zend_Db_Adapter_Exception */
+ throw new Zend_Db_Adapter_Exception(get_class($this) ." doesn't support positional or named binding");
+ }
+ }
+ }
+ $set[] = $this->quoteIdentifier($col, true) . ' = ' . $val;
+ }
+
+ $where = $this->_whereExpr($where);
+
+ /**
+ * Build the UPDATE statement
+ */
+ $sql = "UPDATE "
+ . $this->quoteIdentifier($table, true)
+ . ' SET ' . implode(', ', $set)
+ . (($where) ? " WHERE $where" : '');
+
+ /**
+ * Execute the statement and return the number of affected rows
+ */
+ if ($this->supportsParameters('positional')) {
+ $stmt = $this->query($sql, array_values($bind));
+ } else {
+ $stmt = $this->query($sql, $bind);
+ }
+ $result = $stmt->rowCount();
+ return $result;
+ }
+
+ /**
+ * Deletes table rows based on a WHERE clause.
+ *
+ * @param mixed $table The table to update.
+ * @param mixed $where DELETE WHERE clause(s).
+ * @return int The number of affected rows.
+ */
+ public function delete($table, $where = '')
+ {
+ $where = $this->_whereExpr($where);
+
+ /**
+ * Build the DELETE statement
+ */
+ $sql = "DELETE FROM "
+ . $this->quoteIdentifier($table, true)
+ . (($where) ? " WHERE $where" : '');
+
+ /**
+ * Execute the statement and return the number of affected rows
+ */
+ $stmt = $this->query($sql);
+ $result = $stmt->rowCount();
+ return $result;
+ }
+
+ /**
+ * Convert an array, string, or Zend_Db_Expr object
+ * into a string to put in a WHERE clause.
+ *
+ * @param mixed $where
+ * @return string
+ */
+ protected function _whereExpr($where)
+ {
+ if (empty($where)) {
+ return $where;
+ }
+ if (!is_array($where)) {
+ $where = array($where);
+ }
+ foreach ($where as $cond => &$term) {
+ // is $cond an int? (i.e. Not a condition)
+ if (is_int($cond)) {
+ // $term is the full condition
+ if ($term instanceof Zend_Db_Expr) {
+ $term = $term->__toString();
+ }
+ } else {
+ // $cond is the condition with placeholder,
+ // and $term is quoted into the condition
+ $term = $this->quoteInto($cond, $term);
+ }
+ $term = '(' . $term . ')';
+ }
+
+ $where = implode(' AND ', $where);
+ return $where;
+ }
+
+ /**
+ * Creates and returns a new Zend_Db_Select object for this adapter.
+ *
+ * @return Zend_Db_Select
+ */
+ public function select()
+ {
+ return new Zend_Db_Select($this);
+ }
+
+ /**
+ * Get the fetch mode.
+ *
+ * @return int
+ */
+ public function getFetchMode()
+ {
+ return $this->_fetchMode;
+ }
+
+ /**
+ * Fetches all SQL result rows as a sequential array.
+ * Uses the current fetchMode for the adapter.
+ *
+ * @param string|Zend_Db_Select $sql An SQL SELECT statement.
+ * @param mixed $bind Data to bind into SELECT placeholders.
+ * @param mixed $fetchMode Override current fetch mode.
+ * @return array
+ */
+ public function fetchAll($sql, $bind = array(), $fetchMode = null)
+ {
+ if ($fetchMode === null) {
+ $fetchMode = $this->_fetchMode;
+ }
+ $stmt = $this->query($sql, $bind);
+ $result = $stmt->fetchAll($fetchMode);
+ return $result;
+ }
+
+ /**
+ * Fetches the first row of the SQL result.
+ * Uses the current fetchMode for the adapter.
+ *
+ * @param string|Zend_Db_Select $sql An SQL SELECT statement.
+ * @param mixed $bind Data to bind into SELECT placeholders.
+ * @param mixed $fetchMode Override current fetch mode.
+ * @return mixed Array, object, or scalar depending on fetch mode.
+ */
+ public function fetchRow($sql, $bind = array(), $fetchMode = null)
+ {
+ if ($fetchMode === null) {
+ $fetchMode = $this->_fetchMode;
+ }
+ $stmt = $this->query($sql, $bind);
+ $result = $stmt->fetch($fetchMode);
+ return $result;
+ }
+
+ /**
+ * Fetches all SQL result rows as an associative array.
+ *
+ * The first column is the key, the entire row array is the
+ * value. You should construct the query to be sure that
+ * the first column contains unique values, or else
+ * rows with duplicate values in the first column will
+ * overwrite previous data.
+ *
+ * @param string|Zend_Db_Select $sql An SQL SELECT statement.
+ * @param mixed $bind Data to bind into SELECT placeholders.
+ * @return array
+ */
+ public function fetchAssoc($sql, $bind = array())
+ {
+ $stmt = $this->query($sql, $bind);
+ $data = array();
+ while ($row = $stmt->fetch(Zend_Db::FETCH_ASSOC)) {
+ $tmp = array_values(array_slice($row, 0, 1));
+ $data[$tmp[0]] = $row;
+ }
+ return $data;
+ }
+
+ /**
+ * Fetches the first column of all SQL result rows as an array.
+ *
+ * @param string|Zend_Db_Select $sql An SQL SELECT statement.
+ * @param mixed $bind Data to bind into SELECT placeholders.
+ * @return array
+ */
+ public function fetchCol($sql, $bind = array())
+ {
+ $stmt = $this->query($sql, $bind);
+ $result = $stmt->fetchAll(Zend_Db::FETCH_COLUMN, 0);
+ return $result;
+ }
+
+ /**
+ * Fetches all SQL result rows as an array of key-value pairs.
+ *
+ * The first column is the key, the second column is the
+ * value.
+ *
+ * @param string|Zend_Db_Select $sql An SQL SELECT statement.
+ * @param mixed $bind Data to bind into SELECT placeholders.
+ * @return array
+ */
+ public function fetchPairs($sql, $bind = array())
+ {
+ $stmt = $this->query($sql, $bind);
+ $data = array();
+ while ($row = $stmt->fetch(Zend_Db::FETCH_NUM)) {
+ $data[$row[0]] = $row[1];
+ }
+ return $data;
+ }
+
+ /**
+ * Fetches the first column of the first row of the SQL result.
+ *
+ * @param string|Zend_Db_Select $sql An SQL SELECT statement.
+ * @param mixed $bind Data to bind into SELECT placeholders.
+ * @return string
+ */
+ public function fetchOne($sql, $bind = array())
+ {
+ $stmt = $this->query($sql, $bind);
+ $result = $stmt->fetchColumn(0);
+ return $result;
+ }
+
+ /**
+ * Quote a raw string.
+ *
+ * @param string $value Raw string
+ * @return string Quoted string
+ */
+ protected function _quote($value)
+ {
+ if (is_int($value)) {
+ return $value;
+ } elseif (is_float($value)) {
+ return sprintf('%F', $value);
+ }
+ return "'" . addcslashes($value, "\000\n\r\\'\"\032") . "'";
+ }
+
+ /**
+ * Safely quotes a value for an SQL statement.
+ *
+ * If an array is passed as the value, the array values are quoted
+ * and then returned as a comma-separated string.
+ *
+ * @param mixed $value The value to quote.
+ * @param mixed $type OPTIONAL the SQL datatype name, or constant, or null.
+ * @return mixed An SQL-safe quoted value (or string of separated values).
+ */
+ public function quote($value, $type = null)
+ {
+ $this->_connect();
+
+ if ($value instanceof Zend_Db_Select) {
+ return '(' . $value->assemble() . ')';
+ }
+
+ if ($value instanceof Zend_Db_Expr) {
+ return $value->__toString();
+ }
+
+ if (is_array($value)) {
+ foreach ($value as &$val) {
+ $val = $this->quote($val, $type);
+ }
+ return implode(', ', $value);
+ }
+
+ if ($type !== null && array_key_exists($type = strtoupper($type), $this->_numericDataTypes)) {
+ $quotedValue = '0';
+ switch ($this->_numericDataTypes[$type]) {
+ case Zend_Db::INT_TYPE: // 32-bit integer
+ $quotedValue = (string) intval($value);
+ break;
+ case Zend_Db::BIGINT_TYPE: // 64-bit integer
+ // ANSI SQL-style hex literals (e.g. x'[\dA-F]+')
+ // are not supported here, because these are string
+ // literals, not numeric literals.
+ if (preg_match('/^(
+ [+-]? # optional sign
+ (?:
+ 0[Xx][\da-fA-F]+ # ODBC-style hexadecimal
+ |\d+ # decimal or octal, or MySQL ZEROFILL decimal
+ (?:[eE][+-]?\d+)? # optional exponent on decimals or octals
+ )
+ )/x',
+ (string) $value, $matches)) {
+ $quotedValue = $matches[1];
+ }
+ break;
+ case Zend_Db::FLOAT_TYPE: // float or decimal
+ $quotedValue = sprintf('%F', $value);
+ }
+ return $quotedValue;
+ }
+
+ return $this->_quote($value);
+ }
+
+ /**
+ * Quotes a value and places into a piece of text at a placeholder.
+ *
+ * The placeholder is a question-mark; all placeholders will be replaced
+ * with the quoted value. For example:
+ *
+ * <code>
+ * $text = "WHERE date < ?";
+ * $date = "2005-01-02";
+ * $safe = $sql->quoteInto($text, $date);
+ * // $safe = "WHERE date < '2005-01-02'"
+ * </code>
+ *
+ * @param string $text The text with a placeholder.
+ * @param mixed $value The value to quote.
+ * @param string $type OPTIONAL SQL datatype
+ * @param integer $count OPTIONAL count of placeholders to replace
+ * @return string An SQL-safe quoted value placed into the original text.
+ */
+ public function quoteInto($text, $value, $type = null, $count = null)
+ {
+ if ($count === null) {
+ return str_replace('?', $this->quote($value, $type), $text);
+ } else {
+ return implode($this->quote($value, $type), explode('?', $text, $count + 1));
+ }
+ }
+
+ /**
+ * Quotes an identifier.
+ *
+ * Accepts a string representing a qualified indentifier. For Example:
+ * <code>
+ * $adapter->quoteIdentifier('myschema.mytable')
+ * </code>
+ * Returns: "myschema"."mytable"
+ *
+ * Or, an array of one or more identifiers that may form a qualified identifier:
+ * <code>
+ * $adapter->quoteIdentifier(array('myschema','my.table'))
+ * </code>
+ * Returns: "myschema"."my.table"
+ *
+ * The actual quote character surrounding the identifiers may vary depending on
+ * the adapter.
+ *
+ * @param string|array|Zend_Db_Expr $ident The identifier.
+ * @param boolean $auto If true, heed the AUTO_QUOTE_IDENTIFIERS config option.
+ * @return string The quoted identifier.
+ */
+ public function quoteIdentifier($ident, $auto=false)
+ {
+ return $this->_quoteIdentifierAs($ident, null, $auto);
+ }
+
+ /**
+ * Quote a column identifier and alias.
+ *
+ * @param string|array|Zend_Db_Expr $ident The identifier or expression.
+ * @param string $alias An alias for the column.
+ * @param boolean $auto If true, heed the AUTO_QUOTE_IDENTIFIERS config option.
+ * @return string The quoted identifier and alias.
+ */
+ public function quoteColumnAs($ident, $alias, $auto=false)
+ {
+ return $this->_quoteIdentifierAs($ident, $alias, $auto);
+ }
+
+ /**
+ * Quote a table identifier and alias.
+ *
+ * @param string|array|Zend_Db_Expr $ident The identifier or expression.
+ * @param string $alias An alias for the table.
+ * @param boolean $auto If true, heed the AUTO_QUOTE_IDENTIFIERS config option.
+ * @return string The quoted identifier and alias.
+ */
+ public function quoteTableAs($ident, $alias = null, $auto = false)
+ {
+ return $this->_quoteIdentifierAs($ident, $alias, $auto);
+ }
+
+ /**
+ * Quote an identifier and an optional alias.
+ *
+ * @param string|array|Zend_Db_Expr $ident The identifier or expression.
+ * @param string $alias An optional alias.
+ * @param boolean $auto If true, heed the AUTO_QUOTE_IDENTIFIERS config option.
+ * @param string $as The string to add between the identifier/expression and the alias.
+ * @return string The quoted identifier and alias.
+ */
+ protected function _quoteIdentifierAs($ident, $alias = null, $auto = false, $as = ' AS ')
+ {
+ if ($ident instanceof Zend_Db_Expr) {
+ $quoted = $ident->__toString();
+ } elseif ($ident instanceof Zend_Db_Select) {
+ $quoted = '(' . $ident->assemble() . ')';
+ } else {
+ if (is_string($ident)) {
+ $ident = explode('.', $ident);
+ }
+ if (is_array($ident)) {
+ $segments = array();
+ foreach ($ident as $segment) {
+ if ($segment instanceof Zend_Db_Expr) {
+ $segments[] = $segment->__toString();
+ } else {
+ $segments[] = $this->_quoteIdentifier($segment, $auto);
+ }
+ }
+ if ($alias !== null && end($ident) == $alias) {
+ $alias = null;
+ }
+ $quoted = implode('.', $segments);
+ } else {
+ $quoted = $this->_quoteIdentifier($ident, $auto);
+ }
+ }
+ if ($alias !== null) {
+ $quoted .= $as . $this->_quoteIdentifier($alias, $auto);
+ }
+ return $quoted;
+ }
+
+ /**
+ * Quote an identifier.
+ *
+ * @param string $value The identifier or expression.
+ * @param boolean $auto If true, heed the AUTO_QUOTE_IDENTIFIERS config option.
+ * @return string The quoted identifier and alias.
+ */
+ protected function _quoteIdentifier($value, $auto=false)
+ {
+ if ($auto === false || $this->_autoQuoteIdentifiers === true) {
+ $q = $this->getQuoteIdentifierSymbol();
+ return ($q . str_replace("$q", "$q$q", $value) . $q);
+ }
+ return $value;
+ }
+
+ /**
+ * Returns the symbol the adapter uses for delimited identifiers.
+ *
+ * @return string
+ */
+ public function getQuoteIdentifierSymbol()
+ {
+ return '"';
+ }
+
+ /**
+ * Return the most recent value from the specified sequence in the database.
+ * This is supported only on RDBMS brands that support sequences
+ * (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null.
+ *
+ * @param string $sequenceName
+ * @return string
+ */
+ public function lastSequenceId($sequenceName)
+ {
+ return null;
+ }
+
+ /**
+ * Generate a new value from the specified sequence in the database, and return it.
+ * This is supported only on RDBMS brands that support sequences
+ * (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null.
+ *
+ * @param string $sequenceName
+ * @return string
+ */
+ public function nextSequenceId($sequenceName)
+ {
+ return null;
+ }
+
+ /**
+ * Helper method to change the case of the strings used
+ * when returning result sets in FETCH_ASSOC and FETCH_BOTH
+ * modes.
+ *
+ * This is not intended to be used by application code,
+ * but the method must be public so the Statement class
+ * can invoke it.
+ *
+ * @param string $key
+ * @return string
+ */
+ public function foldCase($key)
+ {
+ switch ($this->_caseFolding) {
+ case Zend_Db::CASE_LOWER:
+ $value = strtolower((string) $key);
+ break;
+ case Zend_Db::CASE_UPPER:
+ $value = strtoupper((string) $key);
+ break;
+ case Zend_Db::CASE_NATURAL:
+ default:
+ $value = (string) $key;
+ }
+ return $value;
+ }
+
+ /**
+ * called when object is getting serialized
+ * This disconnects the DB object that cant be serialized
+ *
+ * @throws Zend_Db_Adapter_Exception
+ * @return array
+ */
+ public function __sleep()
+ {
+ if ($this->_allowSerialization == false) {
+ /** @see Zend_Db_Adapter_Exception */
+ throw new Zend_Db_Adapter_Exception(
+ get_class($this) . ' is not allowed to be serialized'
+ );
+ }
+ $this->_connection = null;
+
+ return array_keys(
+ array_diff_key(get_object_vars($this), array('_connection' => null))
+ );
+ }
+
+ /**
+ * called when object is getting unserialized
+ *
+ * @return void
+ */
+ public function __wakeup()
+ {
+ if ($this->_autoReconnectOnUnserialize == true) {
+ $this->getConnection();
+ }
+ }
+
+ /**
+ * Abstract Methods
+ */
+
+ /**
+ * Returns a list of the tables in the database.
+ *
+ * @return array
+ */
+ abstract public function listTables();
+
+ /**
+ * Returns the column descriptions for a table.
+ *
+ * The return value is an associative array keyed by the column name,
+ * as returned by the RDBMS.
+ *
+ * The value of each array element is an associative array
+ * with the following keys:
+ *
+ * SCHEMA_NAME => string; name of database or schema
+ * TABLE_NAME => string;
+ * COLUMN_NAME => string; column name
+ * COLUMN_POSITION => number; ordinal position of column in table
+ * DATA_TYPE => string; SQL datatype name of column
+ * DEFAULT => string; default expression of column, null if none
+ * NULLABLE => boolean; true if column can have nulls
+ * LENGTH => number; length of CHAR/VARCHAR
+ * SCALE => number; scale of NUMERIC/DECIMAL
+ * PRECISION => number; precision of NUMERIC/DECIMAL
+ * UNSIGNED => boolean; unsigned property of an integer type
+ * PRIMARY => boolean; true if column is part of the primary key
+ * PRIMARY_POSITION => integer; position of column in primary key
+ *
+ * @param string $tableName
+ * @param string $schemaName OPTIONAL
+ * @return array
+ */
+ abstract public function describeTable($tableName, $schemaName = null);
+
+ /**
+ * Creates a connection to the database.
+ *
+ * @return void
+ */
+ abstract protected function _connect();
+
+ /**
+ * Test if a connection is active
+ *
+ * @return boolean
+ */
+ abstract public function isConnected();
+
+ /**
+ * Force the connection to close.
+ *
+ * @return void
+ */
+ abstract public function closeConnection();
+
+ /**
+ * Prepare a statement and return a PDOStatement-like object.
+ *
+ * @param string|Zend_Db_Select $sql SQL query
+ * @return Zend_Db_Statement|PDOStatement
+ */
+ abstract public function prepare($sql);
+
+ /**
+ * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column.
+ *
+ * As a convention, on RDBMS brands that support sequences
+ * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence
+ * from the arguments and returns the last id generated by that sequence.
+ * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method
+ * returns the last value generated for such a column, and the table name
+ * argument is disregarded.
+ *
+ * @param string $tableName OPTIONAL Name of table.
+ * @param string $primaryKey OPTIONAL Name of primary key column.
+ * @return string
+ */
+ abstract public function lastInsertId($tableName = null, $primaryKey = null);
+
+ /**
+ * Begin a transaction.
+ */
+ abstract protected function _beginTransaction();
+
+ /**
+ * Commit a transaction.
+ */
+ abstract protected function _commit();
+
+ /**
+ * Roll-back a transaction.
+ */
+ abstract protected function _rollBack();
+
+ /**
+ * Set the fetch mode.
+ *
+ * @param integer $mode
+ * @return void
+ * @throws Zend_Db_Adapter_Exception
+ */
+ abstract public function setFetchMode($mode);
+
+ /**
+ * Adds an adapter-specific LIMIT clause to the SELECT statement.
+ *
+ * @param mixed $sql
+ * @param integer $count
+ * @param integer $offset
+ * @return string
+ */
+ abstract public function limit($sql, $count, $offset = 0);
+
+ /**
+ * Check if the adapter supports real SQL parameters.
+ *
+ * @param string $type 'positional' or 'named'
+ * @return bool
+ */
+ abstract public function supportsParameters($type);
+
+ /**
+ * Retrieve server version in PHP style
+ *
+ * @return string
+ */
+ abstract public function getServerVersion();
+}
diff --git a/library/vendor/Zend/Db/Adapter/Db2.php b/library/vendor/Zend/Db/Adapter/Db2.php
new file mode 100644
index 0000000..28793d1
--- /dev/null
+++ b/library/vendor/Zend/Db/Adapter/Db2.php
@@ -0,0 +1,827 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ *
+ */
+
+/**
+ * @see Zend_Db
+ */
+
+/**
+ * @see Zend_Db_Adapter_Abstract
+ */
+
+/**
+ * @see Zend_Db_Statement_Db2
+ */
+
+
+/**
+ * @package Zend_Db
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+class Zend_Db_Adapter_Db2 extends Zend_Db_Adapter_Abstract
+{
+ /**
+ * User-provided configuration.
+ *
+ * Basic keys are:
+ *
+ * username => (string) Connect to the database as this username.
+ * password => (string) Password associated with the username.
+ * host => (string) What host to connect to (default 127.0.0.1)
+ * dbname => (string) The name of the database to user
+ * protocol => (string) Protocol to use, defaults to "TCPIP"
+ * port => (integer) Port number to use for TCP/IP if protocol is "TCPIP"
+ * persistent => (boolean) Set TRUE to use a persistent connection (db2_pconnect)
+ * os => (string) This should be set to 'i5' if the db is on an os400/i5
+ * schema => (string) The default schema the connection should use
+ *
+ * @var array
+ */
+ protected $_config = array(
+ 'dbname' => null,
+ 'username' => null,
+ 'password' => null,
+ 'host' => 'localhost',
+ 'port' => '50000',
+ 'protocol' => 'TCPIP',
+ 'persistent' => false,
+ 'os' => null,
+ 'schema' => null
+ );
+
+ /**
+ * Execution mode
+ *
+ * @var int execution flag (DB2_AUTOCOMMIT_ON or DB2_AUTOCOMMIT_OFF)
+ */
+ protected $_execute_mode = DB2_AUTOCOMMIT_ON;
+
+ /**
+ * Default class name for a DB statement.
+ *
+ * @var string
+ */
+ protected $_defaultStmtClass = 'Zend_Db_Statement_Db2';
+ protected $_isI5 = false;
+
+ /**
+ * Keys are UPPERCASE SQL datatypes or the constants
+ * Zend_Db::INT_TYPE, Zend_Db::BIGINT_TYPE, or Zend_Db::FLOAT_TYPE.
+ *
+ * Values are:
+ * 0 = 32-bit integer
+ * 1 = 64-bit integer
+ * 2 = float or decimal
+ *
+ * @var array Associative array of datatypes to values 0, 1, or 2.
+ */
+ protected $_numericDataTypes = array(
+ Zend_Db::INT_TYPE => Zend_Db::INT_TYPE,
+ Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE,
+ Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE,
+ 'INTEGER' => Zend_Db::INT_TYPE,
+ 'SMALLINT' => Zend_Db::INT_TYPE,
+ 'BIGINT' => Zend_Db::BIGINT_TYPE,
+ 'DECIMAL' => Zend_Db::FLOAT_TYPE,
+ 'NUMERIC' => Zend_Db::FLOAT_TYPE
+ );
+
+ /**
+ * Creates a connection resource.
+ *
+ * @return void
+ */
+ protected function _connect()
+ {
+ if (is_resource($this->_connection)) {
+ // connection already exists
+ return;
+ }
+
+ if (!extension_loaded('ibm_db2')) {
+ /**
+ * @see Zend_Db_Adapter_Db2_Exception
+ */
+ throw new Zend_Db_Adapter_Db2_Exception('The IBM DB2 extension is required for this adapter but the extension is not loaded');
+ }
+
+ $this->_determineI5();
+ if ($this->_config['persistent']) {
+ // use persistent connection
+ $conn_func_name = 'db2_pconnect';
+ } else {
+ // use "normal" connection
+ $conn_func_name = 'db2_connect';
+ }
+
+ if (!isset($this->_config['driver_options']['autocommit'])) {
+ // set execution mode
+ $this->_config['driver_options']['autocommit'] = &$this->_execute_mode;
+ }
+
+ if (isset($this->_config['options'][Zend_Db::CASE_FOLDING])) {
+ $caseAttrMap = array(
+ Zend_Db::CASE_NATURAL => DB2_CASE_NATURAL,
+ Zend_Db::CASE_UPPER => DB2_CASE_UPPER,
+ Zend_Db::CASE_LOWER => DB2_CASE_LOWER
+ );
+ $this->_config['driver_options']['DB2_ATTR_CASE'] = $caseAttrMap[$this->_config['options'][Zend_Db::CASE_FOLDING]];
+ }
+
+ if ($this->_isI5 && isset($this->_config['driver_options']['i5_naming'])) {
+ if ($this->_config['driver_options']['i5_naming']) {
+ $this->_config['driver_options']['i5_naming'] = DB2_I5_NAMING_ON;
+ } else {
+ $this->_config['driver_options']['i5_naming'] = DB2_I5_NAMING_OFF;
+ }
+ }
+
+ if ($this->_config['host'] !== 'localhost' && !$this->_isI5) {
+ // if the host isn't localhost, use extended connection params
+ $dbname = 'DRIVER={IBM DB2 ODBC DRIVER}' .
+ ';DATABASE=' . $this->_config['dbname'] .
+ ';HOSTNAME=' . $this->_config['host'] .
+ ';PORT=' . $this->_config['port'] .
+ ';PROTOCOL=' . $this->_config['protocol'] .
+ ';UID=' . $this->_config['username'] .
+ ';PWD=' . $this->_config['password'] .';';
+ $this->_connection = $conn_func_name(
+ $dbname,
+ null,
+ null,
+ $this->_config['driver_options']
+ );
+ } else {
+ // host is localhost, so use standard connection params
+ $this->_connection = $conn_func_name(
+ $this->_config['dbname'],
+ $this->_config['username'],
+ $this->_config['password'],
+ $this->_config['driver_options']
+ );
+ }
+
+ // check the connection
+ if (!$this->_connection) {
+ /**
+ * @see Zend_Db_Adapter_Db2_Exception
+ */
+ throw new Zend_Db_Adapter_Db2_Exception(db2_conn_errormsg(), db2_conn_error());
+ }
+ }
+
+ /**
+ * Test if a connection is active
+ *
+ * @return boolean
+ */
+ public function isConnected()
+ {
+ return ((bool) (is_resource($this->_connection)
+ && get_resource_type($this->_connection) == 'DB2 Connection'));
+ }
+
+ /**
+ * Force the connection to close.
+ *
+ * @return void
+ */
+ public function closeConnection()
+ {
+ if ($this->isConnected()) {
+ db2_close($this->_connection);
+ }
+ $this->_connection = null;
+ }
+
+ /**
+ * Returns an SQL statement for preparation.
+ *
+ * @param string $sql The SQL statement with placeholders.
+ * @return Zend_Db_Statement_Db2
+ */
+ public function prepare($sql)
+ {
+ $this->_connect();
+ $stmtClass = $this->_defaultStmtClass;
+ if (!class_exists($stmtClass)) {
+ Zend_Loader::loadClass($stmtClass);
+ }
+ $stmt = new $stmtClass($this, $sql);
+ $stmt->setFetchMode($this->_fetchMode);
+ return $stmt;
+ }
+
+ /**
+ * Gets the execution mode
+ *
+ * @return int the execution mode (DB2_AUTOCOMMIT_ON or DB2_AUTOCOMMIT_OFF)
+ */
+ public function _getExecuteMode()
+ {
+ return $this->_execute_mode;
+ }
+
+ /**
+ * @param integer $mode
+ * @return void
+ */
+ public function _setExecuteMode($mode)
+ {
+ switch ($mode) {
+ case DB2_AUTOCOMMIT_OFF:
+ case DB2_AUTOCOMMIT_ON:
+ $this->_execute_mode = $mode;
+ db2_autocommit($this->_connection, $mode);
+ break;
+ default:
+ /**
+ * @see Zend_Db_Adapter_Db2_Exception
+ */
+ throw new Zend_Db_Adapter_Db2_Exception("execution mode not supported");
+ break;
+ }
+ }
+
+ /**
+ * Quote a raw string.
+ *
+ * @param string $value Raw string
+ * @return string Quoted string
+ */
+ protected function _quote($value)
+ {
+ if (is_int($value) || is_float($value)) {
+ return $value;
+ }
+ /**
+ * Use db2_escape_string() if it is present in the IBM DB2 extension.
+ * But some supported versions of PHP do not include this function,
+ * so fall back to default quoting in the parent class.
+ */
+ if (function_exists('db2_escape_string')) {
+ return "'" . db2_escape_string($value) . "'";
+ }
+ return parent::_quote($value);
+ }
+
+ /**
+ * @return string
+ */
+ public function getQuoteIdentifierSymbol()
+ {
+ $this->_connect();
+ $info = db2_server_info($this->_connection);
+ if ($info) {
+ $identQuote = $info->IDENTIFIER_QUOTE_CHAR;
+ } else {
+ // db2_server_info() does not return result on some i5 OS version
+ if ($this->_isI5) {
+ $identQuote ="'";
+ }
+ }
+ return $identQuote;
+ }
+
+ /**
+ * Returns a list of the tables in the database.
+ * @param string $schema OPTIONAL
+ * @return array
+ */
+ public function listTables($schema = null)
+ {
+ $this->_connect();
+
+ if ($schema === null && $this->_config['schema'] != null) {
+ $schema = $this->_config['schema'];
+ }
+
+ $tables = array();
+
+ if (!$this->_isI5) {
+ if ($schema) {
+ $stmt = db2_tables($this->_connection, null, $schema);
+ } else {
+ $stmt = db2_tables($this->_connection);
+ }
+ while ($row = db2_fetch_assoc($stmt)) {
+ $tables[] = $row['TABLE_NAME'];
+ }
+ } else {
+ $tables = $this->_i5listTables($schema);
+ }
+
+ return $tables;
+ }
+
+
+ /**
+ * Returns the column descriptions for a table.
+ *
+ * The return value is an associative array keyed by the column name,
+ * as returned by the RDBMS.
+ *
+ * The value of each array element is an associative array
+ * with the following keys:
+ *
+ * SCHEMA_NAME => string; name of database or schema
+ * TABLE_NAME => string;
+ * COLUMN_NAME => string; column name
+ * COLUMN_POSITION => number; ordinal position of column in table
+ * DATA_TYPE => string; SQL datatype name of column
+ * DEFAULT => string; default expression of column, null if none
+ * NULLABLE => boolean; true if column can have nulls
+ * LENGTH => number; length of CHAR/VARCHAR
+ * SCALE => number; scale of NUMERIC/DECIMAL
+ * PRECISION => number; precision of NUMERIC/DECIMAL
+ * UNSIGNED => boolean; unsigned property of an integer type
+ * DB2 not supports UNSIGNED integer.
+ * PRIMARY => boolean; true if column is part of the primary key
+ * PRIMARY_POSITION => integer; position of column in primary key
+ * IDENTITY => integer; true if column is auto-generated with unique values
+ *
+ * @param string $tableName
+ * @param string $schemaName OPTIONAL
+ * @return array
+ */
+ public function describeTable($tableName, $schemaName = null)
+ {
+ // Ensure the connection is made so that _isI5 is set
+ $this->_connect();
+
+ if ($schemaName === null && $this->_config['schema'] != null) {
+ $schemaName = $this->_config['schema'];
+ }
+
+ if (!$this->_isI5) {
+
+ $sql = "SELECT DISTINCT c.tabschema, c.tabname, c.colname, c.colno,
+ c.typename, c.default, c.nulls, c.length, c.scale,
+ c.identity, tc.type AS tabconsttype, k.colseq
+ FROM syscat.columns c
+ LEFT JOIN (syscat.keycoluse k JOIN syscat.tabconst tc
+ ON (k.tabschema = tc.tabschema
+ AND k.tabname = tc.tabname
+ AND tc.type = 'P'))
+ ON (c.tabschema = k.tabschema
+ AND c.tabname = k.tabname
+ AND c.colname = k.colname)
+ WHERE "
+ . $this->quoteInto('UPPER(c.tabname) = UPPER(?)', $tableName);
+
+ if ($schemaName) {
+ $sql .= $this->quoteInto(' AND UPPER(c.tabschema) = UPPER(?)', $schemaName);
+ }
+
+ $sql .= " ORDER BY c.colno";
+
+ } else {
+
+ // DB2 On I5 specific query
+ $sql = "SELECT DISTINCT C.TABLE_SCHEMA, C.TABLE_NAME, C.COLUMN_NAME, C.ORDINAL_POSITION,
+ C.DATA_TYPE, C.COLUMN_DEFAULT, C.NULLS ,C.LENGTH, C.SCALE, LEFT(C.IDENTITY,1),
+ LEFT(tc.TYPE, 1) AS tabconsttype, k.COLSEQ
+ FROM QSYS2.SYSCOLUMNS C
+ LEFT JOIN (QSYS2.syskeycst k JOIN QSYS2.SYSCST tc
+ ON (k.TABLE_SCHEMA = tc.TABLE_SCHEMA
+ AND k.TABLE_NAME = tc.TABLE_NAME
+ AND LEFT(tc.type,1) = 'P'))
+ ON (C.TABLE_SCHEMA = k.TABLE_SCHEMA
+ AND C.TABLE_NAME = k.TABLE_NAME
+ AND C.COLUMN_NAME = k.COLUMN_NAME)
+ WHERE "
+ . $this->quoteInto('UPPER(C.TABLE_NAME) = UPPER(?)', $tableName);
+
+ if ($schemaName) {
+ $sql .= $this->quoteInto(' AND UPPER(C.TABLE_SCHEMA) = UPPER(?)', $schemaName);
+ }
+
+ $sql .= " ORDER BY C.ORDINAL_POSITION FOR FETCH ONLY";
+ }
+
+ $desc = array();
+ $stmt = $this->query($sql);
+
+ /**
+ * To avoid case issues, fetch using FETCH_NUM
+ */
+ $result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
+
+ /**
+ * The ordering of columns is defined by the query so we can map
+ * to variables to improve readability
+ */
+ $tabschema = 0;
+ $tabname = 1;
+ $colname = 2;
+ $colno = 3;
+ $typename = 4;
+ $default = 5;
+ $nulls = 6;
+ $length = 7;
+ $scale = 8;
+ $identityCol = 9;
+ $tabconstType = 10;
+ $colseq = 11;
+
+ foreach ($result as $key => $row) {
+ list ($primary, $primaryPosition, $identity) = array(false, null, false);
+ if ($row[$tabconstType] == 'P') {
+ $primary = true;
+ $primaryPosition = $row[$colseq];
+ }
+ /**
+ * In IBM DB2, an column can be IDENTITY
+ * even if it is not part of the PRIMARY KEY.
+ */
+ if ($row[$identityCol] == 'Y') {
+ $identity = true;
+ }
+
+ // only colname needs to be case adjusted
+ $desc[$this->foldCase($row[$colname])] = array(
+ 'SCHEMA_NAME' => $this->foldCase($row[$tabschema]),
+ 'TABLE_NAME' => $this->foldCase($row[$tabname]),
+ 'COLUMN_NAME' => $this->foldCase($row[$colname]),
+ 'COLUMN_POSITION' => (!$this->_isI5) ? $row[$colno]+1 : $row[$colno],
+ 'DATA_TYPE' => $row[$typename],
+ 'DEFAULT' => $row[$default],
+ 'NULLABLE' => (bool) ($row[$nulls] == 'Y'),
+ 'LENGTH' => $row[$length],
+ 'SCALE' => $row[$scale],
+ 'PRECISION' => ($row[$typename] == 'DECIMAL' ? $row[$length] : 0),
+ 'UNSIGNED' => false,
+ 'PRIMARY' => $primary,
+ 'PRIMARY_POSITION' => $primaryPosition,
+ 'IDENTITY' => $identity
+ );
+ }
+
+ return $desc;
+ }
+
+ /**
+ * Return the most recent value from the specified sequence in the database.
+ * This is supported only on RDBMS brands that support sequences
+ * (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null.
+ *
+ * @param string $sequenceName
+ * @return string
+ */
+ public function lastSequenceId($sequenceName)
+ {
+ $this->_connect();
+
+ if (!$this->_isI5) {
+ $quotedSequenceName = $this->quoteIdentifier($sequenceName, true);
+ $sql = 'SELECT PREVVAL FOR ' . $quotedSequenceName . ' AS VAL FROM SYSIBM.SYSDUMMY1';
+ } else {
+ $quotedSequenceName = $sequenceName;
+ $sql = 'SELECT PREVVAL FOR ' . $this->quoteIdentifier($sequenceName, true) . ' AS VAL FROM QSYS2.QSQPTABL';
+ }
+
+ $value = $this->fetchOne($sql);
+ return (string) $value;
+ }
+
+ /**
+ * Generate a new value from the specified sequence in the database, and return it.
+ * This is supported only on RDBMS brands that support sequences
+ * (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null.
+ *
+ * @param string $sequenceName
+ * @return string
+ */
+ public function nextSequenceId($sequenceName)
+ {
+ $this->_connect();
+ $sql = 'SELECT NEXTVAL FOR '.$this->quoteIdentifier($sequenceName, true).' AS VAL FROM SYSIBM.SYSDUMMY1';
+ $value = $this->fetchOne($sql);
+ return (string) $value;
+ }
+
+ /**
+ * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column.
+ *
+ * As a convention, on RDBMS brands that support sequences
+ * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence
+ * from the arguments and returns the last id generated by that sequence.
+ * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method
+ * returns the last value generated for such a column, and the table name
+ * argument is disregarded.
+ *
+ * The IDENTITY_VAL_LOCAL() function gives the last generated identity value
+ * in the current process, even if it was for a GENERATED column.
+ *
+ * @param string $tableName OPTIONAL
+ * @param string $primaryKey OPTIONAL
+ * @param string $idType OPTIONAL used for i5 platform to define sequence/idenity unique value
+ * @return string
+ */
+
+ public function lastInsertId($tableName = null, $primaryKey = null, $idType = null)
+ {
+ $this->_connect();
+
+ if ($this->_isI5) {
+ return (string) $this->_i5LastInsertId($tableName, $idType);
+ }
+
+ if ($tableName !== null) {
+ $sequenceName = $tableName;
+ if ($primaryKey) {
+ $sequenceName .= "_$primaryKey";
+ }
+ $sequenceName .= '_seq';
+ return $this->lastSequenceId($sequenceName);
+ }
+
+ $sql = 'SELECT IDENTITY_VAL_LOCAL() AS VAL FROM SYSIBM.SYSDUMMY1';
+ $value = $this->fetchOne($sql);
+ return (string) $value;
+ }
+
+ /**
+ * Begin a transaction.
+ *
+ * @return void
+ */
+ protected function _beginTransaction()
+ {
+ $this->_setExecuteMode(DB2_AUTOCOMMIT_OFF);
+ }
+
+ /**
+ * Commit a transaction.
+ *
+ * @return void
+ */
+ protected function _commit()
+ {
+ if (!db2_commit($this->_connection)) {
+ /**
+ * @see Zend_Db_Adapter_Db2_Exception
+ */
+ throw new Zend_Db_Adapter_Db2_Exception(
+ db2_conn_errormsg($this->_connection),
+ db2_conn_error($this->_connection));
+ }
+
+ $this->_setExecuteMode(DB2_AUTOCOMMIT_ON);
+ }
+
+ /**
+ * Rollback a transaction.
+ *
+ * @return void
+ */
+ protected function _rollBack()
+ {
+ if (!db2_rollback($this->_connection)) {
+ /**
+ * @see Zend_Db_Adapter_Db2_Exception
+ */
+ throw new Zend_Db_Adapter_Db2_Exception(
+ db2_conn_errormsg($this->_connection),
+ db2_conn_error($this->_connection));
+ }
+ $this->_setExecuteMode(DB2_AUTOCOMMIT_ON);
+ }
+
+ /**
+ * Set the fetch mode.
+ *
+ * @param integer $mode
+ * @return void
+ * @throws Zend_Db_Adapter_Db2_Exception
+ */
+ public function setFetchMode($mode)
+ {
+ switch ($mode) {
+ case Zend_Db::FETCH_NUM: // seq array
+ case Zend_Db::FETCH_ASSOC: // assoc array
+ case Zend_Db::FETCH_BOTH: // seq+assoc array
+ case Zend_Db::FETCH_OBJ: // object
+ $this->_fetchMode = $mode;
+ break;
+ case Zend_Db::FETCH_BOUND: // bound to PHP variable
+ /**
+ * @see Zend_Db_Adapter_Db2_Exception
+ */
+ throw new Zend_Db_Adapter_Db2_Exception('FETCH_BOUND is not supported yet');
+ break;
+ default:
+ /**
+ * @see Zend_Db_Adapter_Db2_Exception
+ */
+ throw new Zend_Db_Adapter_Db2_Exception("Invalid fetch mode '$mode' specified");
+ break;
+ }
+ }
+
+ /**
+ * Adds an adapter-specific LIMIT clause to the SELECT statement.
+ *
+ * @param string $sql
+ * @param integer $count
+ * @param integer $offset OPTIONAL
+ * @return string
+ */
+ public function limit($sql, $count, $offset = 0)
+ {
+ $count = intval($count);
+ if ($count <= 0) {
+ /**
+ * @see Zend_Db_Adapter_Db2_Exception
+ */
+ throw new Zend_Db_Adapter_Db2_Exception("LIMIT argument count=$count is not valid");
+ }
+
+ $offset = intval($offset);
+ if ($offset < 0) {
+ /**
+ * @see Zend_Db_Adapter_Db2_Exception
+ */
+ throw new Zend_Db_Adapter_Db2_Exception("LIMIT argument offset=$offset is not valid");
+ }
+
+ if ($offset == 0) {
+ $limit_sql = $sql . " FETCH FIRST $count ROWS ONLY";
+ return $limit_sql;
+ }
+
+ /**
+ * DB2 does not implement the LIMIT clause as some RDBMS do.
+ * We have to simulate it with subqueries and ROWNUM.
+ * Unfortunately because we use the column wildcard "*",
+ * this puts an extra column into the query result set.
+ */
+ $limit_sql = "SELECT z2.*
+ FROM (
+ SELECT ROW_NUMBER() OVER() AS \"ZEND_DB_ROWNUM\", z1.*
+ FROM (
+ " . $sql . "
+ ) z1
+ ) z2
+ WHERE z2.zend_db_rownum BETWEEN " . ($offset+1) . " AND " . ($offset+$count);
+ return $limit_sql;
+ }
+
+ /**
+ * Check if the adapter supports real SQL parameters.
+ *
+ * @param string $type 'positional' or 'named'
+ * @return bool
+ */
+ public function supportsParameters($type)
+ {
+ if ($type == 'positional') {
+ return true;
+ }
+
+ // if its 'named' or anything else
+ return false;
+ }
+
+ /**
+ * Retrieve server version in PHP style
+ *
+ * @return string
+ */
+ public function getServerVersion()
+ {
+ $this->_connect();
+ $server_info = db2_server_info($this->_connection);
+ if ($server_info !== false) {
+ $version = $server_info->DBMS_VER;
+ if ($this->_isI5) {
+ $version = (int) substr($version, 0, 2) . '.' . (int) substr($version, 2, 2) . '.' . (int) substr($version, 4);
+ }
+ return $version;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Return whether or not this is running on i5
+ *
+ * @return bool
+ */
+ public function isI5()
+ {
+ if ($this->_isI5 === null) {
+ $this->_determineI5();
+ }
+
+ return (bool) $this->_isI5;
+ }
+
+ /**
+ * Check the connection parameters according to verify
+ * type of used OS
+ *
+ * @return void
+ */
+ protected function _determineI5()
+ {
+ // first us the compiled flag.
+ $this->_isI5 = (php_uname('s') == 'OS400') ? true : false;
+
+ // if this is set, then us it
+ if (isset($this->_config['os'])){
+ if (strtolower($this->_config['os']) === 'i5') {
+ $this->_isI5 = true;
+ } else {
+ // any other value passed in, its null
+ $this->_isI5 = false;
+ }
+ }
+
+ }
+
+ /**
+ * Db2 On I5 specific method
+ *
+ * Returns a list of the tables in the database .
+ * Used only for DB2/400.
+ *
+ * @return array
+ */
+ protected function _i5listTables($schema = null)
+ {
+ //list of i5 libraries.
+ $tables = array();
+ if ($schema) {
+ $tablesStatement = db2_tables($this->_connection, null, $schema);
+ while ($rowTables = db2_fetch_assoc($tablesStatement) ) {
+ if ($rowTables['TABLE_NAME'] !== null) {
+ $tables[] = $rowTables['TABLE_NAME'];
+ }
+ }
+ } else {
+ $schemaStatement = db2_tables($this->_connection);
+ while ($schema = db2_fetch_assoc($schemaStatement)) {
+ if ($schema['TABLE_SCHEM'] !== null) {
+ // list of the tables which belongs to the selected library
+ $tablesStatement = db2_tables($this->_connection, NULL, $schema['TABLE_SCHEM']);
+ if (is_resource($tablesStatement)) {
+ while ($rowTables = db2_fetch_assoc($tablesStatement) ) {
+ if ($rowTables['TABLE_NAME'] !== null) {
+ $tables[] = $rowTables['TABLE_NAME'];
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return $tables;
+ }
+
+ protected function _i5LastInsertId($objectName = null, $idType = null)
+ {
+
+ if ($objectName === null) {
+ $sql = 'SELECT IDENTITY_VAL_LOCAL() AS VAL FROM QSYS2.QSQPTABL';
+ $value = $this->fetchOne($sql);
+ return $value;
+ }
+
+ if (strtoupper($idType) === 'S'){
+ //check i5_lib option
+ $sequenceName = $objectName;
+ return $this->lastSequenceId($sequenceName);
+ }
+
+ //returns last identity value for the specified table
+ //if (strtoupper($idType) === 'I') {
+ $tableName = $objectName;
+ return $this->fetchOne('SELECT IDENTITY_VAL_LOCAL() from ' . $this->quoteIdentifier($tableName));
+ }
+
+}
+
+
diff --git a/library/vendor/Zend/Db/Adapter/Db2/Exception.php b/library/vendor/Zend/Db/Adapter/Db2/Exception.php
new file mode 100644
index 0000000..d12dc48
--- /dev/null
+++ b/library/vendor/Zend/Db/Adapter/Db2/Exception.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * Zend_Db_Adapter_Exception
+ */
+
+/**
+ * Zend_Db_Adapter_Db2_Exception
+ *
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Adapter_Db2_Exception extends Zend_Db_Adapter_Exception
+{
+ protected $code = '00000';
+ protected $message = 'unknown exception';
+
+ function __construct($message = 'unknown exception', $code = '00000', Exception $e = null)
+ {
+ parent::__construct($message, $code, $e);
+ }
+}
diff --git a/library/vendor/Zend/Db/Adapter/Exception.php b/library/vendor/Zend/Db/Adapter/Exception.php
new file mode 100644
index 0000000..c302bc7
--- /dev/null
+++ b/library/vendor/Zend/Db/Adapter/Exception.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * Zend_Db_Exception
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Adapter_Exception extends Zend_Db_Exception
+{
+ protected $_chainedException = null;
+
+ public function __construct($message = '', $code = 0, Exception $e = null)
+ {
+ if ($e && (0 === $code)) {
+ $code = $e->getCode();
+ }
+ parent::__construct($message, $code, $e);
+ }
+
+ public function hasChainedException()
+ {
+ return ($this->getPrevious() !== null);
+ }
+
+ public function getChainedException()
+ {
+ return $this->getPrevious();
+ }
+
+}
diff --git a/library/vendor/Zend/Db/Adapter/Mysqli.php b/library/vendor/Zend/Db/Adapter/Mysqli.php
new file mode 100644
index 0000000..087d3ac
--- /dev/null
+++ b/library/vendor/Zend/Db/Adapter/Mysqli.php
@@ -0,0 +1,543 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+
+/**
+ * @see Zend_Db_Adapter_Abstract
+ */
+
+/**
+ * @see Zend_Db_Profiler
+ */
+
+/**
+ * @see Zend_Db_Select
+ */
+
+/**
+ * @see Zend_Db_Statement_Mysqli
+ */
+
+
+/**
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Adapter_Mysqli extends Zend_Db_Adapter_Abstract
+{
+
+ /**
+ * Keys are UPPERCASE SQL datatypes or the constants
+ * Zend_Db::INT_TYPE, Zend_Db::BIGINT_TYPE, or Zend_Db::FLOAT_TYPE.
+ *
+ * Values are:
+ * 0 = 32-bit integer
+ * 1 = 64-bit integer
+ * 2 = float or decimal
+ *
+ * @var array Associative array of datatypes to values 0, 1, or 2.
+ */
+ protected $_numericDataTypes = array(
+ Zend_Db::INT_TYPE => Zend_Db::INT_TYPE,
+ Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE,
+ Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE,
+ 'INT' => Zend_Db::INT_TYPE,
+ 'INTEGER' => Zend_Db::INT_TYPE,
+ 'MEDIUMINT' => Zend_Db::INT_TYPE,
+ 'SMALLINT' => Zend_Db::INT_TYPE,
+ 'TINYINT' => Zend_Db::INT_TYPE,
+ 'BIGINT' => Zend_Db::BIGINT_TYPE,
+ 'SERIAL' => Zend_Db::BIGINT_TYPE,
+ 'DEC' => Zend_Db::FLOAT_TYPE,
+ 'DECIMAL' => Zend_Db::FLOAT_TYPE,
+ 'DOUBLE' => Zend_Db::FLOAT_TYPE,
+ 'DOUBLE PRECISION' => Zend_Db::FLOAT_TYPE,
+ 'FIXED' => Zend_Db::FLOAT_TYPE,
+ 'FLOAT' => Zend_Db::FLOAT_TYPE
+ );
+
+ /**
+ * @var Zend_Db_Statement_Mysqli
+ */
+ protected $_stmt = null;
+
+ /**
+ * Default class name for a DB statement.
+ *
+ * @var string
+ */
+ protected $_defaultStmtClass = 'Zend_Db_Statement_Mysqli';
+
+ /**
+ * Quote a raw string.
+ *
+ * @param mixed $value Raw string
+ *
+ * @return string Quoted string
+ */
+ protected function _quote($value)
+ {
+ if (is_int($value) || is_float($value)) {
+ return $value;
+ }
+ $this->_connect();
+ return "'" . $this->_connection->real_escape_string($value) . "'";
+ }
+
+ /**
+ * Returns the symbol the adapter uses for delimiting identifiers.
+ *
+ * @return string
+ */
+ public function getQuoteIdentifierSymbol()
+ {
+ return "`";
+ }
+
+ /**
+ * Returns a list of the tables in the database.
+ *
+ * @return array
+ */
+ public function listTables()
+ {
+ $result = array();
+ // Use mysqli extension API, because SHOW doesn't work
+ // well as a prepared statement on MySQL 4.1.
+ $sql = 'SHOW TABLES';
+ if ($queryResult = $this->getConnection()->query($sql)) {
+ while ($row = $queryResult->fetch_row()) {
+ $result[] = $row[0];
+ }
+ $queryResult->close();
+ } else {
+ /**
+ * @see Zend_Db_Adapter_Mysqli_Exception
+ */
+ throw new Zend_Db_Adapter_Mysqli_Exception($this->getConnection()->error);
+ }
+ return $result;
+ }
+
+ /**
+ * Returns the column descriptions for a table.
+ *
+ * The return value is an associative array keyed by the column name,
+ * as returned by the RDBMS.
+ *
+ * The value of each array element is an associative array
+ * with the following keys:
+ *
+ * SCHEMA_NAME => string; name of database or schema
+ * TABLE_NAME => string;
+ * COLUMN_NAME => string; column name
+ * COLUMN_POSITION => number; ordinal position of column in table
+ * DATA_TYPE => string; SQL datatype name of column
+ * DEFAULT => string; default expression of column, null if none
+ * NULLABLE => boolean; true if column can have nulls
+ * LENGTH => number; length of CHAR/VARCHAR
+ * SCALE => number; scale of NUMERIC/DECIMAL
+ * PRECISION => number; precision of NUMERIC/DECIMAL
+ * UNSIGNED => boolean; unsigned property of an integer type
+ * PRIMARY => boolean; true if column is part of the primary key
+ * PRIMARY_POSITION => integer; position of column in primary key
+ * IDENTITY => integer; true if column is auto-generated with unique values
+ *
+ * @param string $tableName
+ * @param string $schemaName OPTIONAL
+ * @return array
+ */
+ public function describeTable($tableName, $schemaName = null)
+ {
+ /**
+ * @todo use INFORMATION_SCHEMA someday when
+ * MySQL's implementation isn't too slow.
+ */
+
+ if ($schemaName) {
+ $sql = 'DESCRIBE ' . $this->quoteIdentifier("$schemaName.$tableName", true);
+ } else {
+ $sql = 'DESCRIBE ' . $this->quoteIdentifier($tableName, true);
+ }
+
+ /**
+ * Use mysqli extension API, because DESCRIBE doesn't work
+ * well as a prepared statement on MySQL 4.1.
+ */
+ if ($queryResult = $this->getConnection()->query($sql)) {
+ while ($row = $queryResult->fetch_assoc()) {
+ $result[] = $row;
+ }
+ $queryResult->close();
+ } else {
+ /**
+ * @see Zend_Db_Adapter_Mysqli_Exception
+ */
+ throw new Zend_Db_Adapter_Mysqli_Exception($this->getConnection()->error);
+ }
+
+ $desc = array();
+
+ $row_defaults = array(
+ 'Length' => null,
+ 'Scale' => null,
+ 'Precision' => null,
+ 'Unsigned' => null,
+ 'Primary' => false,
+ 'PrimaryPosition' => null,
+ 'Identity' => false
+ );
+ $i = 1;
+ $p = 1;
+ foreach ($result as $key => $row) {
+ $row = array_merge($row_defaults, $row);
+ if (preg_match('/unsigned/', $row['Type'])) {
+ $row['Unsigned'] = true;
+ }
+ if (preg_match('/^((?:var)?char)\((\d+)\)/', $row['Type'], $matches)) {
+ $row['Type'] = $matches[1];
+ $row['Length'] = $matches[2];
+ } else if (preg_match('/^decimal\((\d+),(\d+)\)/', $row['Type'], $matches)) {
+ $row['Type'] = 'decimal';
+ $row['Precision'] = $matches[1];
+ $row['Scale'] = $matches[2];
+ } else if (preg_match('/^float\((\d+),(\d+)\)/', $row['Type'], $matches)) {
+ $row['Type'] = 'float';
+ $row['Precision'] = $matches[1];
+ $row['Scale'] = $matches[2];
+ } else if (preg_match('/^((?:big|medium|small|tiny)?int)\((\d+)\)/', $row['Type'], $matches)) {
+ $row['Type'] = $matches[1];
+ /**
+ * The optional argument of a MySQL int type is not precision
+ * or length; it is only a hint for display width.
+ */
+ }
+ if (strtoupper($row['Key']) == 'PRI') {
+ $row['Primary'] = true;
+ $row['PrimaryPosition'] = $p;
+ if ($row['Extra'] == 'auto_increment') {
+ $row['Identity'] = true;
+ } else {
+ $row['Identity'] = false;
+ }
+ ++$p;
+ }
+ $desc[$this->foldCase($row['Field'])] = array(
+ 'SCHEMA_NAME' => null, // @todo
+ 'TABLE_NAME' => $this->foldCase($tableName),
+ 'COLUMN_NAME' => $this->foldCase($row['Field']),
+ 'COLUMN_POSITION' => $i,
+ 'DATA_TYPE' => $row['Type'],
+ 'DEFAULT' => $row['Default'],
+ 'NULLABLE' => (bool) ($row['Null'] == 'YES'),
+ 'LENGTH' => $row['Length'],
+ 'SCALE' => $row['Scale'],
+ 'PRECISION' => $row['Precision'],
+ 'UNSIGNED' => $row['Unsigned'],
+ 'PRIMARY' => $row['Primary'],
+ 'PRIMARY_POSITION' => $row['PrimaryPosition'],
+ 'IDENTITY' => $row['Identity']
+ );
+ ++$i;
+ }
+ return $desc;
+ }
+
+ /**
+ * Creates a connection to the database.
+ *
+ * @return void
+ * @throws Zend_Db_Adapter_Mysqli_Exception
+ */
+ protected function _connect()
+ {
+ if ($this->_connection) {
+ return;
+ }
+
+ if (!extension_loaded('mysqli')) {
+ /**
+ * @see Zend_Db_Adapter_Mysqli_Exception
+ */
+ throw new Zend_Db_Adapter_Mysqli_Exception('The Mysqli extension is required for this adapter but the extension is not loaded');
+ }
+
+ if (isset($this->_config['port'])) {
+ $port = (integer) $this->_config['port'];
+ } else {
+ $port = null;
+ }
+
+ if (isset($this->_config['socket'])) {
+ $socket = $this->_config['socket'];
+ } else {
+ $socket = null;
+ }
+
+ $this->_connection = mysqli_init();
+
+ if(!empty($this->_config['driver_options'])) {
+ foreach($this->_config['driver_options'] as $option=>$value) {
+ if(is_string($option)) {
+ // Suppress warnings here
+ // Ignore it if it's not a valid constant
+ $option = @constant(strtoupper($option));
+ if($option === null)
+ continue;
+ }
+ mysqli_options($this->_connection, $option, $value);
+ }
+ }
+
+ // Suppress connection warnings here.
+ // Throw an exception instead.
+ $_isConnected = @mysqli_real_connect(
+ $this->_connection,
+ $this->_config['host'],
+ $this->_config['username'],
+ $this->_config['password'],
+ $this->_config['dbname'],
+ $port,
+ $socket
+ );
+
+ if ($_isConnected === false || mysqli_connect_errno()) {
+
+ $this->closeConnection();
+ /**
+ * @see Zend_Db_Adapter_Mysqli_Exception
+ */
+ throw new Zend_Db_Adapter_Mysqli_Exception(mysqli_connect_error());
+ }
+
+ if (!empty($this->_config['charset'])) {
+ mysqli_set_charset($this->_connection, $this->_config['charset']);
+ }
+ }
+
+ /**
+ * Test if a connection is active
+ *
+ * @return boolean
+ */
+ public function isConnected()
+ {
+ return ((bool) ($this->_connection instanceof mysqli));
+ }
+
+ /**
+ * Force the connection to close.
+ *
+ * @return void
+ */
+ public function closeConnection()
+ {
+ if ($this->isConnected()) {
+ $this->_connection->close();
+ }
+ $this->_connection = null;
+ }
+
+ /**
+ * Prepare a statement and return a PDOStatement-like object.
+ *
+ * @param string $sql SQL query
+ * @return Zend_Db_Statement_Mysqli
+ */
+ public function prepare($sql)
+ {
+ $this->_connect();
+ if ($this->_stmt) {
+ $this->_stmt->close();
+ }
+ $stmtClass = $this->_defaultStmtClass;
+ if (!class_exists($stmtClass)) {
+ Zend_Loader::loadClass($stmtClass);
+ }
+ $stmt = new $stmtClass($this, $sql);
+ if ($stmt === false) {
+ return false;
+ }
+ $stmt->setFetchMode($this->_fetchMode);
+ $this->_stmt = $stmt;
+ return $stmt;
+ }
+
+ /**
+ * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column.
+ *
+ * As a convention, on RDBMS brands that support sequences
+ * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence
+ * from the arguments and returns the last id generated by that sequence.
+ * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method
+ * returns the last value generated for such a column, and the table name
+ * argument is disregarded.
+ *
+ * MySQL does not support sequences, so $tableName and $primaryKey are ignored.
+ *
+ * @param string $tableName OPTIONAL Name of table.
+ * @param string $primaryKey OPTIONAL Name of primary key column.
+ * @return string
+ * @todo Return value should be int?
+ */
+ public function lastInsertId($tableName = null, $primaryKey = null)
+ {
+ $mysqli = $this->_connection;
+ return (string) $mysqli->insert_id;
+ }
+
+ /**
+ * Begin a transaction.
+ *
+ * @return void
+ */
+ protected function _beginTransaction()
+ {
+ $this->_connect();
+ $this->_connection->autocommit(false);
+ }
+
+ /**
+ * Commit a transaction.
+ *
+ * @return void
+ */
+ protected function _commit()
+ {
+ $this->_connect();
+ $this->_connection->commit();
+ $this->_connection->autocommit(true);
+ }
+
+ /**
+ * Roll-back a transaction.
+ *
+ * @return void
+ */
+ protected function _rollBack()
+ {
+ $this->_connect();
+ $this->_connection->rollback();
+ $this->_connection->autocommit(true);
+ }
+
+ /**
+ * Set the fetch mode.
+ *
+ * @param int $mode
+ * @return void
+ * @throws Zend_Db_Adapter_Mysqli_Exception
+ */
+ public function setFetchMode($mode)
+ {
+ switch ($mode) {
+ case Zend_Db::FETCH_LAZY:
+ case Zend_Db::FETCH_ASSOC:
+ case Zend_Db::FETCH_NUM:
+ case Zend_Db::FETCH_BOTH:
+ case Zend_Db::FETCH_NAMED:
+ case Zend_Db::FETCH_OBJ:
+ $this->_fetchMode = $mode;
+ break;
+ case Zend_Db::FETCH_BOUND: // bound to PHP variable
+ /**
+ * @see Zend_Db_Adapter_Mysqli_Exception
+ */
+ throw new Zend_Db_Adapter_Mysqli_Exception('FETCH_BOUND is not supported yet');
+ break;
+ default:
+ /**
+ * @see Zend_Db_Adapter_Mysqli_Exception
+ */
+ throw new Zend_Db_Adapter_Mysqli_Exception("Invalid fetch mode '$mode' specified");
+ }
+ }
+
+ /**
+ * Adds an adapter-specific LIMIT clause to the SELECT statement.
+ *
+ * @param string $sql
+ * @param int $count
+ * @param int $offset OPTIONAL
+ * @return string
+ */
+ public function limit($sql, $count, $offset = 0)
+ {
+ $count = intval($count);
+ if ($count <= 0) {
+ /**
+ * @see Zend_Db_Adapter_Mysqli_Exception
+ */
+ throw new Zend_Db_Adapter_Mysqli_Exception("LIMIT argument count=$count is not valid");
+ }
+
+ $offset = intval($offset);
+ if ($offset < 0) {
+ /**
+ * @see Zend_Db_Adapter_Mysqli_Exception
+ */
+ throw new Zend_Db_Adapter_Mysqli_Exception("LIMIT argument offset=$offset is not valid");
+ }
+
+ $sql .= " LIMIT $count";
+ if ($offset > 0) {
+ $sql .= " OFFSET $offset";
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Check if the adapter supports real SQL parameters.
+ *
+ * @param string $type 'positional' or 'named'
+ * @return bool
+ */
+ public function supportsParameters($type)
+ {
+ switch ($type) {
+ case 'positional':
+ return true;
+ case 'named':
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Retrieve server version in PHP style
+ *
+ *@return string
+ */
+ public function getServerVersion()
+ {
+ $this->_connect();
+ $version = $this->_connection->server_version;
+ $major = (int) ($version / 10000);
+ $minor = (int) ($version % 10000 / 100);
+ $revision = (int) ($version % 100);
+ return $major . '.' . $minor . '.' . $revision;
+ }
+}
diff --git a/library/vendor/Zend/Db/Adapter/Mysqli/Exception.php b/library/vendor/Zend/Db/Adapter/Mysqli/Exception.php
new file mode 100644
index 0000000..9c94adc
--- /dev/null
+++ b/library/vendor/Zend/Db/Adapter/Mysqli/Exception.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ *
+ */
+
+/**
+ * Zend
+ */
+
+/**
+ * Zend_Db_Adapter_Mysqli_Exception
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Adapter_Mysqli_Exception extends Zend_Db_Adapter_Exception
+{
+}
diff --git a/library/vendor/Zend/Db/Adapter/Oracle.php b/library/vendor/Zend/Db/Adapter/Oracle.php
new file mode 100644
index 0000000..9ed8fb6
--- /dev/null
+++ b/library/vendor/Zend/Db/Adapter/Oracle.php
@@ -0,0 +1,631 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * @see Zend_Db_Adapter_Abstract
+ */
+
+/**
+ * @see Zend_Db_Statement_Oracle
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Adapter_Oracle extends Zend_Db_Adapter_Abstract
+{
+ /**
+ * User-provided configuration.
+ *
+ * Basic keys are:
+ *
+ * username => (string) Connect to the database as this username.
+ * password => (string) Password associated with the username.
+ * dbname => Either the name of the local Oracle instance, or the
+ * name of the entry in tnsnames.ora to which you want to connect.
+ * persistent => (boolean) Set TRUE to use a persistent connection
+ * @var array
+ */
+ protected $_config = array(
+ 'dbname' => null,
+ 'username' => null,
+ 'password' => null,
+ 'persistent' => false
+ );
+
+ /**
+ * Keys are UPPERCASE SQL datatypes or the constants
+ * Zend_Db::INT_TYPE, Zend_Db::BIGINT_TYPE, or Zend_Db::FLOAT_TYPE.
+ *
+ * Values are:
+ * 0 = 32-bit integer
+ * 1 = 64-bit integer
+ * 2 = float or decimal
+ *
+ * @var array Associative array of datatypes to values 0, 1, or 2.
+ */
+ protected $_numericDataTypes = array(
+ Zend_Db::INT_TYPE => Zend_Db::INT_TYPE,
+ Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE,
+ Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE,
+ 'BINARY_DOUBLE' => Zend_Db::FLOAT_TYPE,
+ 'BINARY_FLOAT' => Zend_Db::FLOAT_TYPE,
+ 'NUMBER' => Zend_Db::FLOAT_TYPE,
+ );
+
+ /**
+ * @var integer
+ */
+ protected $_execute_mode = null;
+
+ /**
+ * Default class name for a DB statement.
+ *
+ * @var string
+ */
+ protected $_defaultStmtClass = 'Zend_Db_Statement_Oracle';
+
+ /**
+ * Check if LOB field are returned as string
+ * instead of OCI-Lob object
+ *
+ * @var boolean
+ */
+ protected $_lobAsString = null;
+
+ /**
+ * Creates a connection resource.
+ *
+ * @return void
+ * @throws Zend_Db_Adapter_Oracle_Exception
+ */
+ protected function _connect()
+ {
+ if (is_resource($this->_connection)) {
+ // connection already exists
+ return;
+ }
+
+ if (!extension_loaded('oci8')) {
+ /**
+ * @see Zend_Db_Adapter_Oracle_Exception
+ */
+ throw new Zend_Db_Adapter_Oracle_Exception('The OCI8 extension is required for this adapter but the extension is not loaded');
+ }
+
+ $this->_setExecuteMode(OCI_COMMIT_ON_SUCCESS);
+
+ $connectionFuncName = ($this->_config['persistent'] == true) ? 'oci_pconnect' : 'oci_connect';
+
+ $this->_connection = @$connectionFuncName(
+ $this->_config['username'],
+ $this->_config['password'],
+ $this->_config['dbname'],
+ $this->_config['charset']);
+
+ // check the connection
+ if (!$this->_connection) {
+ /**
+ * @see Zend_Db_Adapter_Oracle_Exception
+ */
+ throw new Zend_Db_Adapter_Oracle_Exception(oci_error());
+ }
+ }
+
+ /**
+ * Test if a connection is active
+ *
+ * @return boolean
+ */
+ public function isConnected()
+ {
+ return ((bool) (is_resource($this->_connection)
+ && (get_resource_type($this->_connection) == 'oci8 connection'
+ || get_resource_type($this->_connection) == 'oci8 persistent connection')));
+ }
+
+ /**
+ * Force the connection to close.
+ *
+ * @return void
+ */
+ public function closeConnection()
+ {
+ if ($this->isConnected()) {
+ oci_close($this->_connection);
+ }
+ $this->_connection = null;
+ }
+
+ /**
+ * Activate/deactivate return of LOB as string
+ *
+ * @param string $lob_as_string
+ * @return Zend_Db_Adapter_Oracle
+ */
+ public function setLobAsString($lobAsString)
+ {
+ $this->_lobAsString = (bool) $lobAsString;
+ return $this;
+ }
+
+ /**
+ * Return whether or not LOB are returned as string
+ *
+ * @return boolean
+ */
+ public function getLobAsString()
+ {
+ if ($this->_lobAsString === null) {
+ // if never set by user, we use driver option if it exists otherwise false
+ if (isset($this->_config['driver_options']) &&
+ isset($this->_config['driver_options']['lob_as_string'])) {
+ $this->_lobAsString = (bool) $this->_config['driver_options']['lob_as_string'];
+ } else {
+ $this->_lobAsString = false;
+ }
+ }
+ return $this->_lobAsString;
+ }
+
+ /**
+ * Returns an SQL statement for preparation.
+ *
+ * @param string $sql The SQL statement with placeholders.
+ * @return Zend_Db_Statement_Oracle
+ */
+ public function prepare($sql)
+ {
+ $this->_connect();
+ $stmtClass = $this->_defaultStmtClass;
+ if (!class_exists($stmtClass)) {
+ Zend_Loader::loadClass($stmtClass);
+ }
+ $stmt = new $stmtClass($this, $sql);
+ if ($stmt instanceof Zend_Db_Statement_Oracle) {
+ $stmt->setLobAsString($this->getLobAsString());
+ }
+ $stmt->setFetchMode($this->_fetchMode);
+ return $stmt;
+ }
+
+ /**
+ * Quote a raw string.
+ *
+ * @param string $value Raw string
+ * @return string Quoted string
+ */
+ protected function _quote($value)
+ {
+ if (is_int($value) || is_float($value)) {
+ return $value;
+ }
+ $value = str_replace("'", "''", $value);
+ return "'" . addcslashes($value, "\000\n\r\\\032") . "'";
+ }
+
+ /**
+ * Quote a table identifier and alias.
+ *
+ * @param string|array|Zend_Db_Expr $ident The identifier or expression.
+ * @param string $alias An alias for the table.
+ * @param boolean $auto If true, heed the AUTO_QUOTE_IDENTIFIERS config option.
+ * @return string The quoted identifier and alias.
+ */
+ public function quoteTableAs($ident, $alias = null, $auto = false)
+ {
+ // Oracle doesn't allow the 'AS' keyword between the table identifier/expression and alias.
+ return $this->_quoteIdentifierAs($ident, $alias, $auto, ' ');
+ }
+
+ /**
+ * Return the most recent value from the specified sequence in the database.
+ * This is supported only on RDBMS brands that support sequences
+ * (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null.
+ *
+ * @param string $sequenceName
+ * @return string
+ */
+ public function lastSequenceId($sequenceName)
+ {
+ $this->_connect();
+ $sql = 'SELECT '.$this->quoteIdentifier($sequenceName, true).'.CURRVAL FROM dual';
+ $value = $this->fetchOne($sql);
+ return $value;
+ }
+
+ /**
+ * Generate a new value from the specified sequence in the database, and return it.
+ * This is supported only on RDBMS brands that support sequences
+ * (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null.
+ *
+ * @param string $sequenceName
+ * @return string
+ */
+ public function nextSequenceId($sequenceName)
+ {
+ $this->_connect();
+ $sql = 'SELECT '.$this->quoteIdentifier($sequenceName, true).'.NEXTVAL FROM dual';
+ $value = $this->fetchOne($sql);
+ return $value;
+ }
+
+ /**
+ * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column.
+ *
+ * As a convention, on RDBMS brands that support sequences
+ * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence
+ * from the arguments and returns the last id generated by that sequence.
+ * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method
+ * returns the last value generated for such a column, and the table name
+ * argument is disregarded.
+ *
+ * Oracle does not support IDENTITY columns, so if the sequence is not
+ * specified, this method returns null.
+ *
+ * @param string $tableName OPTIONAL Name of table.
+ * @param string $primaryKey OPTIONAL Name of primary key column.
+ * @return string
+ */
+ public function lastInsertId($tableName = null, $primaryKey = null)
+ {
+ if ($tableName !== null) {
+ $sequenceName = $tableName;
+ if ($primaryKey) {
+ $sequenceName .= "_$primaryKey";
+ }
+ $sequenceName .= '_seq';
+ return $this->lastSequenceId($sequenceName);
+ }
+
+ // No support for IDENTITY columns; return null
+ return null;
+ }
+
+ /**
+ * Returns a list of the tables in the database.
+ *
+ * @return array
+ */
+ public function listTables()
+ {
+ $this->_connect();
+ $data = $this->fetchCol('SELECT table_name FROM all_tables');
+ return $data;
+ }
+
+ /**
+ * Returns the column descriptions for a table.
+ *
+ * The return value is an associative array keyed by the column name,
+ * as returned by the RDBMS.
+ *
+ * The value of each array element is an associative array
+ * with the following keys:
+ *
+ * SCHEMA_NAME => string; name of schema
+ * TABLE_NAME => string;
+ * COLUMN_NAME => string; column name
+ * COLUMN_POSITION => number; ordinal position of column in table
+ * DATA_TYPE => string; SQL datatype name of column
+ * DEFAULT => string; default expression of column, null if none
+ * NULLABLE => boolean; true if column can have nulls
+ * LENGTH => number; length of CHAR/VARCHAR
+ * SCALE => number; scale of NUMERIC/DECIMAL
+ * PRECISION => number; precision of NUMERIC/DECIMAL
+ * UNSIGNED => boolean; unsigned property of an integer type
+ * PRIMARY => boolean; true if column is part of the primary key
+ * PRIMARY_POSITION => integer; position of column in primary key
+ * IDENTITY => integer; true if column is auto-generated with unique values
+ *
+ * @todo Discover integer unsigned property.
+ *
+ * @param string $tableName
+ * @param string $schemaName OPTIONAL
+ * @return array
+ */
+ public function describeTable($tableName, $schemaName = null)
+ {
+ $version = $this->getServerVersion();
+ if (($version === null) || version_compare($version, '9.0.0', '>=')) {
+ $sql = "SELECT TC.TABLE_NAME, TC.OWNER, TC.COLUMN_NAME, TC.DATA_TYPE,
+ TC.DATA_DEFAULT, TC.NULLABLE, TC.COLUMN_ID, TC.DATA_LENGTH,
+ TC.DATA_SCALE, TC.DATA_PRECISION, C.CONSTRAINT_TYPE, CC.POSITION
+ FROM ALL_TAB_COLUMNS TC
+ LEFT JOIN (ALL_CONS_COLUMNS CC JOIN ALL_CONSTRAINTS C
+ ON (CC.CONSTRAINT_NAME = C.CONSTRAINT_NAME AND CC.TABLE_NAME = C.TABLE_NAME AND CC.OWNER = C.OWNER AND C.CONSTRAINT_TYPE = 'P'))
+ ON TC.TABLE_NAME = CC.TABLE_NAME AND TC.COLUMN_NAME = CC.COLUMN_NAME
+ WHERE UPPER(TC.TABLE_NAME) = UPPER(:TBNAME)";
+ $bind[':TBNAME'] = $tableName;
+ if ($schemaName) {
+ $sql .= ' AND UPPER(TC.OWNER) = UPPER(:SCNAME)';
+ $bind[':SCNAME'] = $schemaName;
+ }
+ $sql .= ' ORDER BY TC.COLUMN_ID';
+ } else {
+ $subSql="SELECT AC.OWNER, AC.TABLE_NAME, ACC.COLUMN_NAME, AC.CONSTRAINT_TYPE, ACC.POSITION
+ from ALL_CONSTRAINTS AC, ALL_CONS_COLUMNS ACC
+ WHERE ACC.CONSTRAINT_NAME = AC.CONSTRAINT_NAME
+ AND ACC.TABLE_NAME = AC.TABLE_NAME
+ AND ACC.OWNER = AC.OWNER
+ AND AC.CONSTRAINT_TYPE = 'P'
+ AND UPPER(AC.TABLE_NAME) = UPPER(:TBNAME)";
+ $bind[':TBNAME'] = $tableName;
+ if ($schemaName) {
+ $subSql .= ' AND UPPER(ACC.OWNER) = UPPER(:SCNAME)';
+ $bind[':SCNAME'] = $schemaName;
+ }
+ $sql="SELECT TC.TABLE_NAME, TC.OWNER, TC.COLUMN_NAME, TC.DATA_TYPE,
+ TC.DATA_DEFAULT, TC.NULLABLE, TC.COLUMN_ID, TC.DATA_LENGTH,
+ TC.DATA_SCALE, TC.DATA_PRECISION, CC.CONSTRAINT_TYPE, CC.POSITION
+ FROM ALL_TAB_COLUMNS TC, ($subSql) CC
+ WHERE UPPER(TC.TABLE_NAME) = UPPER(:TBNAME)
+ AND TC.OWNER = CC.OWNER(+) AND TC.TABLE_NAME = CC.TABLE_NAME(+) AND TC.COLUMN_NAME = CC.COLUMN_NAME(+)";
+ if ($schemaName) {
+ $sql .= ' AND UPPER(TC.OWNER) = UPPER(:SCNAME)';
+ }
+ $sql .= ' ORDER BY TC.COLUMN_ID';
+ }
+
+ $stmt = $this->query($sql, $bind);
+
+ /**
+ * Use FETCH_NUM so we are not dependent on the CASE attribute of the PDO connection
+ */
+ $result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
+
+ $table_name = 0;
+ $owner = 1;
+ $column_name = 2;
+ $data_type = 3;
+ $data_default = 4;
+ $nullable = 5;
+ $column_id = 6;
+ $data_length = 7;
+ $data_scale = 8;
+ $data_precision = 9;
+ $constraint_type = 10;
+ $position = 11;
+
+ $desc = array();
+ foreach ($result as $key => $row) {
+ list ($primary, $primaryPosition, $identity) = array(false, null, false);
+ if ($row[$constraint_type] == 'P') {
+ $primary = true;
+ $primaryPosition = $row[$position];
+ /**
+ * Oracle does not support auto-increment keys.
+ */
+ $identity = false;
+ }
+ $desc[$this->foldCase($row[$column_name])] = array(
+ 'SCHEMA_NAME' => $this->foldCase($row[$owner]),
+ 'TABLE_NAME' => $this->foldCase($row[$table_name]),
+ 'COLUMN_NAME' => $this->foldCase($row[$column_name]),
+ 'COLUMN_POSITION' => $row[$column_id],
+ 'DATA_TYPE' => $row[$data_type],
+ 'DEFAULT' => $row[$data_default],
+ 'NULLABLE' => (bool) ($row[$nullable] == 'Y'),
+ 'LENGTH' => $row[$data_length],
+ 'SCALE' => $row[$data_scale],
+ 'PRECISION' => $row[$data_precision],
+ 'UNSIGNED' => null, // @todo
+ 'PRIMARY' => $primary,
+ 'PRIMARY_POSITION' => $primaryPosition,
+ 'IDENTITY' => $identity
+ );
+ }
+ return $desc;
+ }
+
+ /**
+ * Leave autocommit mode and begin a transaction.
+ *
+ * @return void
+ */
+ protected function _beginTransaction()
+ {
+ $this->_setExecuteMode(OCI_DEFAULT);
+ }
+
+ /**
+ * Commit a transaction and return to autocommit mode.
+ *
+ * @return void
+ * @throws Zend_Db_Adapter_Oracle_Exception
+ */
+ protected function _commit()
+ {
+ if (!oci_commit($this->_connection)) {
+ /**
+ * @see Zend_Db_Adapter_Oracle_Exception
+ */
+ throw new Zend_Db_Adapter_Oracle_Exception(oci_error($this->_connection));
+ }
+ $this->_setExecuteMode(OCI_COMMIT_ON_SUCCESS);
+ }
+
+ /**
+ * Roll back a transaction and return to autocommit mode.
+ *
+ * @return void
+ * @throws Zend_Db_Adapter_Oracle_Exception
+ */
+ protected function _rollBack()
+ {
+ if (!oci_rollback($this->_connection)) {
+ /**
+ * @see Zend_Db_Adapter_Oracle_Exception
+ */
+ throw new Zend_Db_Adapter_Oracle_Exception(oci_error($this->_connection));
+ }
+ $this->_setExecuteMode(OCI_COMMIT_ON_SUCCESS);
+ }
+
+ /**
+ * Set the fetch mode.
+ *
+ * @todo Support FETCH_CLASS and FETCH_INTO.
+ *
+ * @param integer $mode A fetch mode.
+ * @return void
+ * @throws Zend_Db_Adapter_Oracle_Exception
+ */
+ public function setFetchMode($mode)
+ {
+ switch ($mode) {
+ case Zend_Db::FETCH_NUM: // seq array
+ case Zend_Db::FETCH_ASSOC: // assoc array
+ case Zend_Db::FETCH_BOTH: // seq+assoc array
+ case Zend_Db::FETCH_OBJ: // object
+ $this->_fetchMode = $mode;
+ break;
+ case Zend_Db::FETCH_BOUND: // bound to PHP variable
+ /**
+ * @see Zend_Db_Adapter_Oracle_Exception
+ */
+ throw new Zend_Db_Adapter_Oracle_Exception('FETCH_BOUND is not supported yet');
+ break;
+ default:
+ /**
+ * @see Zend_Db_Adapter_Oracle_Exception
+ */
+ throw new Zend_Db_Adapter_Oracle_Exception("Invalid fetch mode '$mode' specified");
+ break;
+ }
+ }
+
+ /**
+ * Adds an adapter-specific LIMIT clause to the SELECT statement.
+ *
+ * @param string $sql
+ * @param integer $count
+ * @param integer $offset OPTIONAL
+ * @return string
+ * @throws Zend_Db_Adapter_Oracle_Exception
+ */
+ public function limit($sql, $count, $offset = 0)
+ {
+ $count = intval($count);
+ if ($count <= 0) {
+ /**
+ * @see Zend_Db_Adapter_Oracle_Exception
+ */
+ throw new Zend_Db_Adapter_Oracle_Exception("LIMIT argument count=$count is not valid");
+ }
+
+ $offset = intval($offset);
+ if ($offset < 0) {
+ /**
+ * @see Zend_Db_Adapter_Oracle_Exception
+ */
+ throw new Zend_Db_Adapter_Oracle_Exception("LIMIT argument offset=$offset is not valid");
+ }
+
+ /**
+ * Oracle does not implement the LIMIT clause as some RDBMS do.
+ * We have to simulate it with subqueries and ROWNUM.
+ * Unfortunately because we use the column wildcard "*",
+ * this puts an extra column into the query result set.
+ */
+ $limit_sql = "SELECT z2.*
+ FROM (
+ SELECT z1.*, ROWNUM AS \"zend_db_rownum\"
+ FROM (
+ " . $sql . "
+ ) z1
+ ) z2
+ WHERE z2.\"zend_db_rownum\" BETWEEN " . ($offset+1) . " AND " . ($offset+$count);
+ return $limit_sql;
+ }
+
+ /**
+ * @param integer $mode
+ * @throws Zend_Db_Adapter_Oracle_Exception
+ */
+ private function _setExecuteMode($mode)
+ {
+ switch($mode) {
+ case OCI_COMMIT_ON_SUCCESS:
+ case OCI_DEFAULT:
+ case OCI_DESCRIBE_ONLY:
+ $this->_execute_mode = $mode;
+ break;
+ default:
+ /**
+ * @see Zend_Db_Adapter_Oracle_Exception
+ */
+ throw new Zend_Db_Adapter_Oracle_Exception("Invalid execution mode '$mode' specified");
+ break;
+ }
+ }
+
+ /**
+ * @return int
+ */
+ public function _getExecuteMode()
+ {
+ return $this->_execute_mode;
+ }
+
+ /**
+ * Check if the adapter supports real SQL parameters.
+ *
+ * @param string $type 'positional' or 'named'
+ * @return bool
+ */
+ public function supportsParameters($type)
+ {
+ switch ($type) {
+ case 'named':
+ return true;
+ case 'positional':
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Retrieve server version in PHP style
+ *
+ * @return string
+ */
+ public function getServerVersion()
+ {
+ $this->_connect();
+ $version = oci_server_version($this->_connection);
+ if ($version !== false) {
+ $matches = null;
+ if (preg_match('/((?:[0-9]{1,2}\.){1,3}[0-9]{1,2})/', $version, $matches)) {
+ return $matches[1];
+ } else {
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/library/vendor/Zend/Db/Adapter/Oracle/Exception.php b/library/vendor/Zend/Db/Adapter/Oracle/Exception.php
new file mode 100644
index 0000000..6b7d914
--- /dev/null
+++ b/library/vendor/Zend/Db/Adapter/Oracle/Exception.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * Zend_Db_Adapter_Exception
+ */
+
+/**
+ * Zend_Db_Adapter_Oracle_Exception
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Adapter_Oracle_Exception extends Zend_Db_Adapter_Exception
+{
+ protected $message = 'Unknown exception';
+ protected $code = 0;
+
+ function __construct($error = null, $code = 0) {
+ if (is_array($error)) {
+ if (!isset($error['offset'])) {
+ $this->message = $error['code'] .' '. $error['message'];
+ } else {
+ $this->message = $error['code'] .' '. $error['message']." "
+ . substr($error['sqltext'], 0, $error['offset'])
+ . "*"
+ . substr($error['sqltext'], $error['offset']);
+ }
+ $this->code = $error['code'];
+ } else if (is_string($error)) {
+ $this->message = $error;
+ }
+ if (!$this->code && $code) {
+ $this->code = $code;
+ }
+ }
+}
diff --git a/library/vendor/Zend/Db/Adapter/Pdo/Abstract.php b/library/vendor/Zend/Db/Adapter/Pdo/Abstract.php
new file mode 100644
index 0000000..3a0e13e
--- /dev/null
+++ b/library/vendor/Zend/Db/Adapter/Pdo/Abstract.php
@@ -0,0 +1,397 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+
+/**
+ * @see Zend_Db_Adapter_Abstract
+ */
+
+
+/**
+ * @see Zend_Db_Statement_Pdo
+ */
+
+
+/**
+ * Class for connecting to SQL databases and performing common operations using PDO.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+abstract class Zend_Db_Adapter_Pdo_Abstract extends Zend_Db_Adapter_Abstract
+{
+
+ /**
+ * Default class name for a DB statement.
+ *
+ * @var string
+ */
+ protected $_defaultStmtClass = 'Zend_Db_Statement_Pdo';
+
+ /**
+ * Creates a PDO DSN for the adapter from $this->_config settings.
+ *
+ * @return string
+ */
+ protected function _dsn()
+ {
+ // baseline of DSN parts
+ $dsn = $this->_config;
+
+ // don't pass the username, password, charset, persistent and driver_options in the DSN
+ unset($dsn['username']);
+ unset($dsn['password']);
+ unset($dsn['options']);
+ unset($dsn['charset']);
+ unset($dsn['persistent']);
+ unset($dsn['driver_options']);
+
+ // use all remaining parts in the DSN
+ foreach ($dsn as $key => $val) {
+ $dsn[$key] = "$key=$val";
+ }
+
+ return $this->_pdoType . ':' . implode(';', $dsn);
+ }
+
+ /**
+ * Creates a PDO object and connects to the database.
+ *
+ * @return void
+ * @throws Zend_Db_Adapter_Exception
+ */
+ protected function _connect()
+ {
+ // if we already have a PDO object, no need to re-connect.
+ if ($this->_connection) {
+ return;
+ }
+
+ // get the dsn first, because some adapters alter the $_pdoType
+ $dsn = $this->_dsn();
+
+ // check for PDO extension
+ if (!extension_loaded('pdo')) {
+ /**
+ * @see Zend_Db_Adapter_Exception
+ */
+ throw new Zend_Db_Adapter_Exception('The PDO extension is required for this adapter but the extension is not loaded');
+ }
+
+ // check the PDO driver is available
+ if (!in_array($this->_pdoType, PDO::getAvailableDrivers())) {
+ /**
+ * @see Zend_Db_Adapter_Exception
+ */
+ throw new Zend_Db_Adapter_Exception('The ' . $this->_pdoType . ' driver is not currently installed');
+ }
+
+ // create PDO connection
+ $q = $this->_profiler->queryStart('connect', Zend_Db_Profiler::CONNECT);
+
+ // add the persistence flag if we find it in our config array
+ if (isset($this->_config['persistent']) && ($this->_config['persistent'] == true)) {
+ $this->_config['driver_options'][PDO::ATTR_PERSISTENT] = true;
+ }
+
+ try {
+ $this->_connection = new PDO(
+ $dsn,
+ $this->_config['username'],
+ $this->_config['password'],
+ $this->_config['driver_options']
+ );
+
+ $this->_profiler->queryEnd($q);
+
+ // set the PDO connection to perform case-folding on array keys, or not
+ $this->_connection->setAttribute(PDO::ATTR_CASE, $this->_caseFolding);
+
+ // always use exceptions.
+ $this->_connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+ } catch (PDOException $e) {
+ $message = $e->getMessage();
+ if ($e->getPrevious() !== null && preg_match('~^SQLSTATE\[HY000\] \[\d{1,4}\]\s$~', $message)) {
+ // See https://bugs.php.net/bug.php?id=76604
+ $message .= $e->getPrevious()->getMessage();
+ }
+
+ /**
+ * @see Zend_Db_Adapter_Exception
+ */
+ throw new Zend_Db_Adapter_Exception($message, $e->getCode(), $e);
+ }
+
+ }
+
+ /**
+ * Test if a connection is active
+ *
+ * @return boolean
+ */
+ public function isConnected()
+ {
+ return ((bool) ($this->_connection instanceof PDO));
+ }
+
+ /**
+ * Force the connection to close.
+ *
+ * @return void
+ */
+ public function closeConnection()
+ {
+ $this->_connection = null;
+ }
+
+ /**
+ * Prepares an SQL statement.
+ *
+ * @param string $sql The SQL statement with placeholders.
+ * @param array $bind An array of data to bind to the placeholders.
+ * @return PDOStatement
+ */
+ public function prepare($sql)
+ {
+ $this->_connect();
+ $stmtClass = $this->_defaultStmtClass;
+ if (!class_exists($stmtClass)) {
+ Zend_Loader::loadClass($stmtClass);
+ }
+ $stmt = new $stmtClass($this, $sql);
+ $stmt->setFetchMode($this->_fetchMode);
+ return $stmt;
+ }
+
+ /**
+ * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column.
+ *
+ * As a convention, on RDBMS brands that support sequences
+ * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence
+ * from the arguments and returns the last id generated by that sequence.
+ * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method
+ * returns the last value generated for such a column, and the table name
+ * argument is disregarded.
+ *
+ * On RDBMS brands that don't support sequences, $tableName and $primaryKey
+ * are ignored.
+ *
+ * @param string $tableName OPTIONAL Name of table.
+ * @param string $primaryKey OPTIONAL Name of primary key column.
+ * @return string
+ */
+ public function lastInsertId($tableName = null, $primaryKey = null)
+ {
+ $this->_connect();
+ return $this->_connection->lastInsertId();
+ }
+
+ /**
+ * Special handling for PDO query().
+ * All bind parameter names must begin with ':'
+ *
+ * @param string|Zend_Db_Select $sql The SQL statement with placeholders.
+ * @param array $bind An array of data to bind to the placeholders.
+ * @return Zend_Db_Statement_Pdo
+ * @throws Zend_Db_Adapter_Exception To re-throw PDOException.
+ */
+ public function query($sql, $bind = array())
+ {
+ if (empty($bind) && $sql instanceof Zend_Db_Select) {
+ $bind = $sql->getBind();
+ }
+
+ if (is_array($bind)) {
+ foreach ($bind as $name => $value) {
+ if (!is_int($name) && !preg_match('/^:/', $name)) {
+ $newName = ":$name";
+ unset($bind[$name]);
+ $bind[$newName] = $value;
+ }
+ }
+ }
+
+ try {
+ return parent::query($sql, $bind);
+ } catch (PDOException $e) {
+ /**
+ * @see Zend_Db_Statement_Exception
+ */
+ throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * Executes an SQL statement and return the number of affected rows
+ *
+ * @param mixed $sql The SQL statement with placeholders.
+ * May be a string or Zend_Db_Select.
+ * @return integer Number of rows that were modified
+ * or deleted by the SQL statement
+ */
+ public function exec($sql)
+ {
+ if ($sql instanceof Zend_Db_Select) {
+ $sql = $sql->assemble();
+ }
+
+ try {
+ $affected = $this->getConnection()->exec($sql);
+
+ if ($affected === false) {
+ $errorInfo = $this->getConnection()->errorInfo();
+ /**
+ * @see Zend_Db_Adapter_Exception
+ */
+ throw new Zend_Db_Adapter_Exception($errorInfo[2]);
+ }
+
+ return $affected;
+ } catch (PDOException $e) {
+ /**
+ * @see Zend_Db_Adapter_Exception
+ */
+ throw new Zend_Db_Adapter_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * Quote a raw string.
+ *
+ * @param string $value Raw string
+ * @return string Quoted string
+ */
+ protected function _quote($value)
+ {
+ if ($value === null) {
+ $value = '';
+ } elseif (is_int($value) || is_float($value)) {
+ return $value;
+ }
+ $this->_connect();
+ return $this->_connection->quote($value);
+ }
+
+ /**
+ * Begin a transaction.
+ */
+ protected function _beginTransaction()
+ {
+ $this->_connect();
+ $this->_connection->beginTransaction();
+ }
+
+ /**
+ * Commit a transaction.
+ */
+ protected function _commit()
+ {
+ $this->_connect();
+ $this->_connection->commit();
+ }
+
+ /**
+ * Roll-back a transaction.
+ */
+ protected function _rollBack() {
+ $this->_connect();
+ $this->_connection->rollBack();
+ }
+
+ /**
+ * Set the PDO fetch mode.
+ *
+ * @todo Support FETCH_CLASS and FETCH_INTO.
+ *
+ * @param int $mode A PDO fetch mode.
+ * @return void
+ * @throws Zend_Db_Adapter_Exception
+ */
+ public function setFetchMode($mode)
+ {
+ //check for PDO extension
+ if (!extension_loaded('pdo')) {
+ /**
+ * @see Zend_Db_Adapter_Exception
+ */
+ throw new Zend_Db_Adapter_Exception('The PDO extension is required for this adapter but the extension is not loaded');
+ }
+ switch ($mode) {
+ case PDO::FETCH_LAZY:
+ case PDO::FETCH_ASSOC:
+ case PDO::FETCH_NUM:
+ case PDO::FETCH_BOTH:
+ case PDO::FETCH_NAMED:
+ case PDO::FETCH_OBJ:
+ $this->_fetchMode = $mode;
+ break;
+ default:
+ /**
+ * @see Zend_Db_Adapter_Exception
+ */
+ throw new Zend_Db_Adapter_Exception("Invalid fetch mode '$mode' specified");
+ break;
+ }
+ }
+
+ /**
+ * Check if the adapter supports real SQL parameters.
+ *
+ * @param string $type 'positional' or 'named'
+ * @return bool
+ */
+ public function supportsParameters($type)
+ {
+ switch ($type) {
+ case 'positional':
+ case 'named':
+ default:
+ return true;
+ }
+ }
+
+ /**
+ * Retrieve server version in PHP style
+ *
+ * @return string
+ */
+ public function getServerVersion()
+ {
+ $this->_connect();
+ try {
+ $version = $this->_connection->getAttribute(PDO::ATTR_SERVER_VERSION);
+ } catch (PDOException $e) {
+ // In case of the driver doesn't support getting attributes
+ return null;
+ }
+ $matches = null;
+ if (preg_match('/((?:[0-9]{1,2}\.){1,3}[0-9]{1,2})/', $version, $matches)) {
+ return $matches[1];
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/library/vendor/Zend/Db/Adapter/Pdo/Ibm.php b/library/vendor/Zend/Db/Adapter/Pdo/Ibm.php
new file mode 100644
index 0000000..cfb11a3
--- /dev/null
+++ b/library/vendor/Zend/Db/Adapter/Pdo/Ibm.php
@@ -0,0 +1,354 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+
+/** @see Zend_Db_Adapter_Pdo_Abstract */
+
+/** @see Zend_Db_Abstract_Pdo_Ibm_Db2 */
+
+/** @see Zend_Db_Abstract_Pdo_Ibm_Ids */
+
+/** @see Zend_Db_Statement_Pdo_Ibm */
+
+
+/**
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Adapter_Pdo_Ibm extends Zend_Db_Adapter_Pdo_Abstract
+{
+ /**
+ * PDO type.
+ *
+ * @var string
+ */
+ protected $_pdoType = 'ibm';
+
+ /**
+ * The IBM data server connected to
+ *
+ * @var string
+ */
+ protected $_serverType = null;
+
+ /**
+ * Keys are UPPERCASE SQL datatypes or the constants
+ * Zend_Db::INT_TYPE, Zend_Db::BIGINT_TYPE, or Zend_Db::FLOAT_TYPE.
+ *
+ * Values are:
+ * 0 = 32-bit integer
+ * 1 = 64-bit integer
+ * 2 = float or decimal
+ *
+ * @var array Associative array of datatypes to values 0, 1, or 2.
+ */
+ protected $_numericDataTypes = array(
+ Zend_Db::INT_TYPE => Zend_Db::INT_TYPE,
+ Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE,
+ Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE,
+ 'INTEGER' => Zend_Db::INT_TYPE,
+ 'SMALLINT' => Zend_Db::INT_TYPE,
+ 'BIGINT' => Zend_Db::BIGINT_TYPE,
+ 'DECIMAL' => Zend_Db::FLOAT_TYPE,
+ 'DEC' => Zend_Db::FLOAT_TYPE,
+ 'REAL' => Zend_Db::FLOAT_TYPE,
+ 'NUMERIC' => Zend_Db::FLOAT_TYPE,
+ 'DOUBLE PRECISION' => Zend_Db::FLOAT_TYPE,
+ 'FLOAT' => Zend_Db::FLOAT_TYPE
+ );
+
+ /**
+ * Creates a PDO object and connects to the database.
+ *
+ * The IBM data server is set.
+ * Current options are DB2 or IDS
+ * @todo also differentiate between z/OS and i/5
+ *
+ * @return void
+ * @throws Zend_Db_Adapter_Exception
+ */
+ public function _connect()
+ {
+ if ($this->_connection) {
+ return;
+ }
+ parent::_connect();
+
+ $this->getConnection()->setAttribute(Zend_Db::ATTR_STRINGIFY_FETCHES, true);
+
+ try {
+ if ($this->_serverType === null) {
+ $server = substr($this->getConnection()->getAttribute(PDO::ATTR_SERVER_INFO), 0, 3);
+
+ switch ($server) {
+ case 'DB2':
+ $this->_serverType = new Zend_Db_Adapter_Pdo_Ibm_Db2($this);
+
+ // Add DB2-specific numeric types
+ $this->_numericDataTypes['DECFLOAT'] = Zend_Db::FLOAT_TYPE;
+ $this->_numericDataTypes['DOUBLE'] = Zend_Db::FLOAT_TYPE;
+ $this->_numericDataTypes['NUM'] = Zend_Db::FLOAT_TYPE;
+
+ break;
+ case 'IDS':
+ $this->_serverType = new Zend_Db_Adapter_Pdo_Ibm_Ids($this);
+
+ // Add IDS-specific numeric types
+ $this->_numericDataTypes['SERIAL'] = Zend_Db::INT_TYPE;
+ $this->_numericDataTypes['SERIAL8'] = Zend_Db::BIGINT_TYPE;
+ $this->_numericDataTypes['INT8'] = Zend_Db::BIGINT_TYPE;
+ $this->_numericDataTypes['SMALLFLOAT'] = Zend_Db::FLOAT_TYPE;
+ $this->_numericDataTypes['MONEY'] = Zend_Db::FLOAT_TYPE;
+
+ break;
+ }
+ }
+ } catch (PDOException $e) {
+ /** @see Zend_Db_Adapter_Exception */
+ $error = strpos($e->getMessage(), 'driver does not support that attribute');
+ if ($error) {
+ throw new Zend_Db_Adapter_Exception("PDO_IBM driver extension is downlevel. Please use driver release version 1.2.1 or later", 0, $e);
+ } else {
+ throw new Zend_Db_Adapter_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+ }
+
+ /**
+ * Creates a PDO DSN for the adapter from $this->_config settings.
+ *
+ * @return string
+ */
+ protected function _dsn()
+ {
+ $this->_checkRequiredOptions($this->_config);
+
+ // check if using full connection string
+ if (array_key_exists('host', $this->_config)) {
+ $dsn = ';DATABASE=' . $this->_config['dbname']
+ . ';HOSTNAME=' . $this->_config['host']
+ . ';PORT=' . $this->_config['port']
+ // PDO_IBM supports only DB2 TCPIP protocol
+ . ';PROTOCOL=' . 'TCPIP;';
+ } else {
+ // catalogued connection
+ $dsn = $this->_config['dbname'];
+ }
+ return $this->_pdoType . ': ' . $dsn;
+ }
+
+ /**
+ * Checks required options
+ *
+ * @param array $config
+ * @throws Zend_Db_Adapter_Exception
+ * @return void
+ */
+ protected function _checkRequiredOptions(array $config)
+ {
+ parent::_checkRequiredOptions($config);
+
+ if (array_key_exists('host', $this->_config) &&
+ !array_key_exists('port', $config)) {
+ /** @see Zend_Db_Adapter_Exception */
+ throw new Zend_Db_Adapter_Exception("Configuration must have a key for 'port' when 'host' is specified");
+ }
+ }
+
+ /**
+ * Prepares an SQL statement.
+ *
+ * @param string $sql The SQL statement with placeholders.
+ * @param array $bind An array of data to bind to the placeholders.
+ * @return PDOStatement
+ */
+ public function prepare($sql)
+ {
+ $this->_connect();
+ $stmtClass = $this->_defaultStmtClass;
+ $stmt = new $stmtClass($this, $sql);
+ $stmt->setFetchMode($this->_fetchMode);
+ return $stmt;
+ }
+
+ /**
+ * Returns a list of the tables in the database.
+ *
+ * @return array
+ */
+ public function listTables()
+ {
+ $this->_connect();
+ return $this->_serverType->listTables();
+ }
+
+ /**
+ * Returns the column descriptions for a table.
+ *
+ * The return value is an associative array keyed by the column name,
+ * as returned by the RDBMS.
+ *
+ * The value of each array element is an associative array
+ * with the following keys:
+ *
+ * SCHEMA_NAME => string; name of database or schema
+ * TABLE_NAME => string;
+ * COLUMN_NAME => string; column name
+ * COLUMN_POSITION => number; ordinal position of column in table
+ * DATA_TYPE => string; SQL datatype name of column
+ * DEFAULT => string; default expression of column, null if none
+ * NULLABLE => boolean; true if column can have nulls
+ * LENGTH => number; length of CHAR/VARCHAR
+ * SCALE => number; scale of NUMERIC/DECIMAL
+ * PRECISION => number; precision of NUMERIC/DECIMAL
+ * UNSIGNED => boolean; unsigned property of an integer type
+ * PRIMARY => boolean; true if column is part of the primary key
+ * PRIMARY_POSITION => integer; position of column in primary key
+ *
+ * @todo Discover integer unsigned property.
+ *
+ * @param string $tableName
+ * @param string $schemaName OPTIONAL
+ * @return array
+ */
+ public function describeTable($tableName, $schemaName = null)
+ {
+ $this->_connect();
+ return $this->_serverType->describeTable($tableName, $schemaName);
+ }
+
+ /**
+ * Inserts a table row with specified data.
+ * Special handling for PDO_IBM
+ * remove empty slots
+ *
+ * @param mixed $table The table to insert data into.
+ * @param array $bind Column-value pairs.
+ * @return int The number of affected rows.
+ */
+ public function insert($table, array $bind)
+ {
+ $this->_connect();
+ $newbind = array();
+ if (is_array($bind)) {
+ foreach ($bind as $name => $value) {
+ if($value !== null) {
+ $newbind[$name] = $value;
+ }
+ }
+ }
+
+ return parent::insert($table, $newbind);
+ }
+
+ /**
+ * Adds an adapter-specific LIMIT clause to the SELECT statement.
+ *
+ * @param string $sql
+ * @param integer $count
+ * @param integer $offset OPTIONAL
+ * @return string
+ */
+ public function limit($sql, $count, $offset = 0)
+ {
+ $this->_connect();
+ return $this->_serverType->limit($sql, $count, $offset);
+ }
+
+ /**
+ * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT
+ * column.
+ *
+ * @param string $tableName OPTIONAL
+ * @param string $primaryKey OPTIONAL
+ * @return integer
+ */
+ public function lastInsertId($tableName = null, $primaryKey = null)
+ {
+ $this->_connect();
+
+ if ($tableName !== null) {
+ $sequenceName = $tableName;
+ if ($primaryKey) {
+ $sequenceName .= "_$primaryKey";
+ }
+ $sequenceName .= '_seq';
+ return $this->lastSequenceId($sequenceName);
+ }
+
+ $id = $this->getConnection()->lastInsertId();
+
+ return $id;
+ }
+
+ /**
+ * Return the most recent value from the specified sequence in the database.
+ *
+ * @param string $sequenceName
+ * @return integer
+ */
+ public function lastSequenceId($sequenceName)
+ {
+ $this->_connect();
+ return $this->_serverType->lastSequenceId($sequenceName);
+ }
+
+ /**
+ * Generate a new value from the specified sequence in the database,
+ * and return it.
+ *
+ * @param string $sequenceName
+ * @return integer
+ */
+ public function nextSequenceId($sequenceName)
+ {
+ $this->_connect();
+ return $this->_serverType->nextSequenceId($sequenceName);
+ }
+
+ /**
+ * Retrieve server version in PHP style
+ * Pdo_Idm doesn't support getAttribute(PDO::ATTR_SERVER_VERSION)
+ * @return string
+ */
+ public function getServerVersion()
+ {
+ try {
+ $stmt = $this->query('SELECT service_level, fixpack_num FROM TABLE (sysproc.env_get_inst_info()) as INSTANCEINFO');
+ $result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
+ if (count($result)) {
+ $matches = null;
+ if (preg_match('/((?:[0-9]{1,2}\.){1,3}[0-9]{1,2})/', $result[0][0], $matches)) {
+ return $matches[1];
+ } else {
+ return null;
+ }
+ }
+ return null;
+ } catch (PDOException $e) {
+ return null;
+ }
+ }
+}
diff --git a/library/vendor/Zend/Db/Adapter/Pdo/Ibm/Db2.php b/library/vendor/Zend/Db/Adapter/Pdo/Ibm/Db2.php
new file mode 100644
index 0000000..1c11c8b
--- /dev/null
+++ b/library/vendor/Zend/Db/Adapter/Pdo/Ibm/Db2.php
@@ -0,0 +1,224 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+
+/** @see Zend_Db_Adapter_Pdo_Ibm */
+
+/** @see Zend_Db_Statement_Pdo_Ibm */
+
+
+/**
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Adapter_Pdo_Ibm_Db2
+{
+ /**
+ * @var Zend_Db_Adapter_Abstract
+ */
+ protected $_adapter = null;
+
+ /**
+ * Construct the data server class.
+ *
+ * It will be used to generate non-generic SQL
+ * for a particular data server
+ *
+ * @param Zend_Db_Adapter_Abstract $adapter
+ */
+ public function __construct($adapter)
+ {
+ $this->_adapter = $adapter;
+ }
+
+ /**
+ * Returns a list of the tables in the database.
+ *
+ * @return array
+ */
+ public function listTables()
+ {
+ $sql = "SELECT tabname "
+ . "FROM SYSCAT.TABLES ";
+ return $this->_adapter->fetchCol($sql);
+ }
+
+ /**
+ * DB2 catalog lookup for describe table
+ *
+ * @param string $tableName
+ * @param string $schemaName OPTIONAL
+ * @return array
+ */
+ public function describeTable($tableName, $schemaName = null)
+ {
+ $sql = "SELECT DISTINCT c.tabschema, c.tabname, c.colname, c.colno,
+ c.typename, c.default, c.nulls, c.length, c.scale,
+ c.identity, tc.type AS tabconsttype, k.colseq
+ FROM syscat.columns c
+ LEFT JOIN (syscat.keycoluse k JOIN syscat.tabconst tc
+ ON (k.tabschema = tc.tabschema
+ AND k.tabname = tc.tabname
+ AND tc.type = 'P'))
+ ON (c.tabschema = k.tabschema
+ AND c.tabname = k.tabname
+ AND c.colname = k.colname)
+ WHERE "
+ . $this->_adapter->quoteInto('UPPER(c.tabname) = UPPER(?)', $tableName);
+ if ($schemaName) {
+ $sql .= $this->_adapter->quoteInto(' AND UPPER(c.tabschema) = UPPER(?)', $schemaName);
+ }
+ $sql .= " ORDER BY c.colno";
+
+ $desc = array();
+ $stmt = $this->_adapter->query($sql);
+
+ /**
+ * To avoid case issues, fetch using FETCH_NUM
+ */
+ $result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
+
+ /**
+ * The ordering of columns is defined by the query so we can map
+ * to variables to improve readability
+ */
+ $tabschema = 0;
+ $tabname = 1;
+ $colname = 2;
+ $colno = 3;
+ $typename = 4;
+ $default = 5;
+ $nulls = 6;
+ $length = 7;
+ $scale = 8;
+ $identityCol = 9;
+ $tabconstype = 10;
+ $colseq = 11;
+
+ foreach ($result as $key => $row) {
+ list ($primary, $primaryPosition, $identity) = array(false, null, false);
+ if ($row[$tabconstype] == 'P') {
+ $primary = true;
+ $primaryPosition = $row[$colseq];
+ }
+ /**
+ * In IBM DB2, an column can be IDENTITY
+ * even if it is not part of the PRIMARY KEY.
+ */
+ if ($row[$identityCol] == 'Y') {
+ $identity = true;
+ }
+
+ $desc[$this->_adapter->foldCase($row[$colname])] = array(
+ 'SCHEMA_NAME' => $this->_adapter->foldCase($row[$tabschema]),
+ 'TABLE_NAME' => $this->_adapter->foldCase($row[$tabname]),
+ 'COLUMN_NAME' => $this->_adapter->foldCase($row[$colname]),
+ 'COLUMN_POSITION' => $row[$colno]+1,
+ 'DATA_TYPE' => $row[$typename],
+ 'DEFAULT' => $row[$default],
+ 'NULLABLE' => (bool) ($row[$nulls] == 'Y'),
+ 'LENGTH' => $row[$length],
+ 'SCALE' => $row[$scale],
+ 'PRECISION' => ($row[$typename] == 'DECIMAL' ? $row[$length] : 0),
+ 'UNSIGNED' => false,
+ 'PRIMARY' => $primary,
+ 'PRIMARY_POSITION' => $primaryPosition,
+ 'IDENTITY' => $identity
+ );
+ }
+
+ return $desc;
+ }
+
+ /**
+ * Adds a DB2-specific LIMIT clause to the SELECT statement.
+ *
+ * @param string $sql
+ * @param integer $count
+ * @param integer $offset OPTIONAL
+ * @throws Zend_Db_Adapter_Exception
+ * @return string
+ */
+ public function limit($sql, $count, $offset = 0)
+ {
+ $count = intval($count);
+ if ($count < 0) {
+ /** @see Zend_Db_Adapter_Exception */
+ throw new Zend_Db_Adapter_Exception("LIMIT argument count=$count is not valid");
+ } else {
+ $offset = intval($offset);
+ if ($offset < 0) {
+ /** @see Zend_Db_Adapter_Exception */
+ throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid");
+ }
+
+ if ($offset == 0 && $count > 0) {
+ $limit_sql = $sql . " FETCH FIRST $count ROWS ONLY";
+ return $limit_sql;
+ }
+ /**
+ * DB2 does not implement the LIMIT clause as some RDBMS do.
+ * We have to simulate it with subqueries and ROWNUM.
+ * Unfortunately because we use the column wildcard "*",
+ * this puts an extra column into the query result set.
+ */
+ $limit_sql = "SELECT z2.*
+ FROM (
+ SELECT ROW_NUMBER() OVER() AS \"ZEND_DB_ROWNUM\", z1.*
+ FROM (
+ " . $sql . "
+ ) z1
+ ) z2
+ WHERE z2.zend_db_rownum BETWEEN " . ($offset+1) . " AND " . ($offset+$count);
+ }
+ return $limit_sql;
+ }
+
+ /**
+ * DB2-specific last sequence id
+ *
+ * @param string $sequenceName
+ * @return integer
+ */
+ public function lastSequenceId($sequenceName)
+ {
+ $sql = 'SELECT PREVVAL FOR '.$this->_adapter->quoteIdentifier($sequenceName).' AS VAL FROM SYSIBM.SYSDUMMY1';
+ $value = $this->_adapter->fetchOne($sql);
+ return $value;
+ }
+
+ /**
+ * DB2-specific sequence id value
+ *
+ * @param string $sequenceName
+ * @return integer
+ */
+ public function nextSequenceId($sequenceName)
+ {
+ $sql = 'SELECT NEXTVAL FOR '.$this->_adapter->quoteIdentifier($sequenceName).' AS VAL FROM SYSIBM.SYSDUMMY1';
+ $value = $this->_adapter->fetchOne($sql);
+ return $value;
+ }
+}
diff --git a/library/vendor/Zend/Db/Adapter/Pdo/Ibm/Ids.php b/library/vendor/Zend/Db/Adapter/Pdo/Ibm/Ids.php
new file mode 100644
index 0000000..eeec43f
--- /dev/null
+++ b/library/vendor/Zend/Db/Adapter/Pdo/Ibm/Ids.php
@@ -0,0 +1,297 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+
+/** @see Zend_Db_Adapter_Pdo_Ibm */
+
+/** @see Zend_Db_Statement_Pdo_Ibm */
+
+
+/**
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Adapter_Pdo_Ibm_Ids
+{
+ /**
+ * @var Zend_Db_Adapter_Abstract
+ */
+ protected $_adapter = null;
+
+ /**
+ * Construct the data server class.
+ *
+ * It will be used to generate non-generic SQL
+ * for a particular data server
+ *
+ * @param Zend_Db_Adapter_Abstract $adapter
+ */
+ public function __construct($adapter)
+ {
+ $this->_adapter = $adapter;
+ }
+
+ /**
+ * Returns a list of the tables in the database.
+ *
+ * @return array
+ */
+ public function listTables()
+ {
+ $sql = "SELECT tabname "
+ . "FROM systables ";
+
+ return $this->_adapter->fetchCol($sql);
+ }
+
+ /**
+ * IDS catalog lookup for describe table
+ *
+ * @param string $tableName
+ * @param string $schemaName OPTIONAL
+ * @return array
+ */
+ public function describeTable($tableName, $schemaName = null)
+ {
+ // this is still a work in progress
+
+ $sql= "SELECT DISTINCT t.owner, t.tabname, c.colname, c.colno, c.coltype,
+ d.default, c.collength, t.tabid
+ FROM syscolumns c
+ JOIN systables t ON c.tabid = t.tabid
+ LEFT JOIN sysdefaults d ON c.tabid = d.tabid AND c.colno = d.colno
+ WHERE "
+ . $this->_adapter->quoteInto('UPPER(t.tabname) = UPPER(?)', $tableName);
+ if ($schemaName) {
+ $sql .= $this->_adapter->quoteInto(' AND UPPER(t.owner) = UPPER(?)', $schemaName);
+ }
+ $sql .= " ORDER BY c.colno";
+
+ $desc = array();
+ $stmt = $this->_adapter->query($sql);
+
+ $result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
+
+ /**
+ * The ordering of columns is defined by the query so we can map
+ * to variables to improve readability
+ */
+ $tabschema = 0;
+ $tabname = 1;
+ $colname = 2;
+ $colno = 3;
+ $typename = 4;
+ $default = 5;
+ $length = 6;
+ $tabid = 7;
+
+ $primaryCols = null;
+
+ foreach ($result as $key => $row) {
+ $primary = false;
+ $primaryPosition = null;
+
+ if (!$primaryCols) {
+ $primaryCols = $this->_getPrimaryInfo($row[$tabid]);
+ }
+
+ if (array_key_exists($row[$colno], $primaryCols)) {
+ $primary = true;
+ $primaryPosition = $primaryCols[$row[$colno]];
+ }
+
+ $identity = false;
+ if ($row[$typename] == 6 + 256 ||
+ $row[$typename] == 18 + 256) {
+ $identity = true;
+ }
+
+ $desc[$this->_adapter->foldCase($row[$colname])] = array (
+ 'SCHEMA_NAME' => $this->_adapter->foldCase($row[$tabschema]),
+ 'TABLE_NAME' => $this->_adapter->foldCase($row[$tabname]),
+ 'COLUMN_NAME' => $this->_adapter->foldCase($row[$colname]),
+ 'COLUMN_POSITION' => $row[$colno],
+ 'DATA_TYPE' => $this->_getDataType($row[$typename]),
+ 'DEFAULT' => $row[$default],
+ 'NULLABLE' => (bool) !($row[$typename] - 256 >= 0),
+ 'LENGTH' => $row[$length],
+ 'SCALE' => ($row[$typename] == 5 ? $row[$length]&255 : 0),
+ 'PRECISION' => ($row[$typename] == 5 ? (int)($row[$length]/256) : 0),
+ 'UNSIGNED' => false,
+ 'PRIMARY' => $primary,
+ 'PRIMARY_POSITION' => $primaryPosition,
+ 'IDENTITY' => $identity
+ );
+ }
+
+ return $desc;
+ }
+
+ /**
+ * Map number representation of a data type
+ * to a string
+ *
+ * @param int $typeNo
+ * @return string
+ */
+ protected function _getDataType($typeNo)
+ {
+ $typemap = array(
+ 0 => "CHAR",
+ 1 => "SMALLINT",
+ 2 => "INTEGER",
+ 3 => "FLOAT",
+ 4 => "SMALLFLOAT",
+ 5 => "DECIMAL",
+ 6 => "SERIAL",
+ 7 => "DATE",
+ 8 => "MONEY",
+ 9 => "NULL",
+ 10 => "DATETIME",
+ 11 => "BYTE",
+ 12 => "TEXT",
+ 13 => "VARCHAR",
+ 14 => "INTERVAL",
+ 15 => "NCHAR",
+ 16 => "NVARCHAR",
+ 17 => "INT8",
+ 18 => "SERIAL8",
+ 19 => "SET",
+ 20 => "MULTISET",
+ 21 => "LIST",
+ 22 => "Unnamed ROW",
+ 40 => "Variable-length opaque type",
+ 4118 => "Named ROW"
+ );
+
+ if ($typeNo - 256 >= 0) {
+ $typeNo = $typeNo - 256;
+ }
+
+ return $typemap[$typeNo];
+ }
+
+ /**
+ * Helper method to retrieve primary key column
+ * and column location
+ *
+ * @param int $tabid
+ * @return array
+ */
+ protected function _getPrimaryInfo($tabid)
+ {
+ $sql = "SELECT i.part1, i.part2, i.part3, i.part4, i.part5, i.part6,
+ i.part7, i.part8, i.part9, i.part10, i.part11, i.part12,
+ i.part13, i.part14, i.part15, i.part16
+ FROM sysindexes i
+ JOIN sysconstraints c ON c.idxname = i.idxname
+ WHERE i.tabid = " . $tabid . " AND c.constrtype = 'P'";
+
+ $stmt = $this->_adapter->query($sql);
+ $results = $stmt->fetchAll();
+
+ $cols = array();
+
+ // this should return only 1 row
+ // unless there is no primary key,
+ // in which case, the empty array is returned
+ if ($results) {
+ $row = $results[0];
+ } else {
+ return $cols;
+ }
+
+ $position = 0;
+ foreach ($row as $key => $colno) {
+ $position++;
+ if ($colno == 0) {
+ return $cols;
+ } else {
+ $cols[$colno] = $position;
+ }
+ }
+ }
+
+ /**
+ * Adds an IDS-specific LIMIT clause to the SELECT statement.
+ *
+ * @param string $sql
+ * @param integer $count
+ * @param integer $offset OPTIONAL
+ * @throws Zend_Db_Adapter_Exception
+ * @return string
+ */
+ public function limit($sql, $count, $offset = 0)
+ {
+ $count = intval($count);
+ if ($count < 0) {
+ /** @see Zend_Db_Adapter_Exception */
+ throw new Zend_Db_Adapter_Exception("LIMIT argument count=$count is not valid");
+ } else if ($count == 0) {
+ $limit_sql = str_ireplace("SELECT", "SELECT * FROM (SELECT", $sql);
+ $limit_sql .= ") WHERE 0 = 1";
+ } else {
+ $offset = intval($offset);
+ if ($offset < 0) {
+ /** @see Zend_Db_Adapter_Exception */
+ throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid");
+ }
+ if ($offset == 0) {
+ $limit_sql = str_ireplace("SELECT", "SELECT FIRST $count", $sql);
+ } else {
+ $limit_sql = str_ireplace("SELECT", "SELECT SKIP $offset LIMIT $count", $sql);
+ }
+ }
+ return $limit_sql;
+ }
+
+ /**
+ * IDS-specific last sequence id
+ *
+ * @param string $sequenceName
+ * @return integer
+ */
+ public function lastSequenceId($sequenceName)
+ {
+ $sql = 'SELECT '.$this->_adapter->quoteIdentifier($sequenceName).'.CURRVAL FROM '
+ .'systables WHERE tabid = 1';
+ $value = $this->_adapter->fetchOne($sql);
+ return $value;
+ }
+
+ /**
+ * IDS-specific sequence id value
+ *
+ * @param string $sequenceName
+ * @return integer
+ */
+ public function nextSequenceId($sequenceName)
+ {
+ $sql = 'SELECT '.$this->_adapter->quoteIdentifier($sequenceName).'.NEXTVAL FROM '
+ .'systables WHERE tabid = 1';
+ $value = $this->_adapter->fetchOne($sql);
+ return $value;
+ }
+}
diff --git a/library/vendor/Zend/Db/Adapter/Pdo/Mssql.php b/library/vendor/Zend/Db/Adapter/Pdo/Mssql.php
new file mode 100644
index 0000000..7c7c1cd
--- /dev/null
+++ b/library/vendor/Zend/Db/Adapter/Pdo/Mssql.php
@@ -0,0 +1,435 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+
+/**
+ * @see Zend_Db_Adapter_Pdo_Abstract
+ */
+
+
+/**
+ * Class for connecting to Microsoft SQL Server databases and performing common operations.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Adapter_Pdo_Mssql extends Zend_Db_Adapter_Pdo_Abstract
+{
+ /**
+ * PDO type.
+ *
+ * @var string
+ */
+ protected $_pdoType = 'mssql';
+
+ /**
+ * Keys are UPPERCASE SQL datatypes or the constants
+ * Zend_Db::INT_TYPE, Zend_Db::BIGINT_TYPE, or Zend_Db::FLOAT_TYPE.
+ *
+ * Values are:
+ * 0 = 32-bit integer
+ * 1 = 64-bit integer
+ * 2 = float or decimal
+ *
+ * @var array Associative array of datatypes to values 0, 1, or 2.
+ */
+ protected $_numericDataTypes = array(
+ Zend_Db::INT_TYPE => Zend_Db::INT_TYPE,
+ Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE,
+ Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE,
+ 'INT' => Zend_Db::INT_TYPE,
+ 'SMALLINT' => Zend_Db::INT_TYPE,
+ 'TINYINT' => Zend_Db::INT_TYPE,
+ 'BIGINT' => Zend_Db::BIGINT_TYPE,
+ 'DECIMAL' => Zend_Db::FLOAT_TYPE,
+ 'FLOAT' => Zend_Db::FLOAT_TYPE,
+ 'MONEY' => Zend_Db::FLOAT_TYPE,
+ 'NUMERIC' => Zend_Db::FLOAT_TYPE,
+ 'REAL' => Zend_Db::FLOAT_TYPE,
+ 'SMALLMONEY' => Zend_Db::FLOAT_TYPE
+ );
+
+ /**
+ * Creates a PDO DSN for the adapter from $this->_config settings.
+ *
+ * @return string
+ */
+ protected function _dsn()
+ {
+ // baseline of DSN parts
+ $dsn = $this->_config;
+
+ // don't pass the username and password in the DSN
+ unset($dsn['username']);
+ unset($dsn['password']);
+ unset($dsn['options']);
+ unset($dsn['persistent']);
+ unset($dsn['driver_options']);
+
+ if (isset($dsn['port'])) {
+ $seperator = ':';
+ if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
+ $seperator = ',';
+ }
+ $dsn['host'] .= $seperator . $dsn['port'];
+ unset($dsn['port']);
+ }
+
+ // this driver supports multiple DSN prefixes
+ // @see http://www.php.net/manual/en/ref.pdo-dblib.connection.php
+ if (isset($dsn['pdoType'])) {
+ switch (strtolower($dsn['pdoType'])) {
+ case 'freetds':
+ case 'sybase':
+ $this->_pdoType = 'sybase';
+ break;
+ case 'mssql':
+ $this->_pdoType = 'mssql';
+ break;
+ case 'dblib':
+ default:
+ $this->_pdoType = 'dblib';
+ break;
+ }
+ unset($dsn['pdoType']);
+ }
+
+ // use all remaining parts in the DSN
+ foreach ($dsn as $key => $val) {
+ $dsn[$key] = "$key=$val";
+ }
+
+ $dsn = $this->_pdoType . ':' . implode(';', $dsn);
+ return $dsn;
+ }
+
+ /**
+ * @return void
+ */
+ protected function _connect()
+ {
+ if ($this->_connection) {
+ return;
+ }
+ parent::_connect();
+ $this->_connection->exec('SET QUOTED_IDENTIFIER ON');
+ }
+
+ /**
+ * Begin a transaction.
+ *
+ * It is necessary to override the abstract PDO transaction functions here, as
+ * the PDO driver for MSSQL does not support transactions.
+ */
+ protected function _beginTransaction()
+ {
+ $this->_connect();
+ $this->_connection->exec('BEGIN TRANSACTION');
+ return true;
+ }
+
+ /**
+ * Commit a transaction.
+ *
+ * It is necessary to override the abstract PDO transaction functions here, as
+ * the PDO driver for MSSQL does not support transactions.
+ */
+ protected function _commit()
+ {
+ $this->_connect();
+ $this->_connection->exec('COMMIT TRANSACTION');
+ return true;
+ }
+
+ /**
+ * Roll-back a transaction.
+ *
+ * It is necessary to override the abstract PDO transaction functions here, as
+ * the PDO driver for MSSQL does not support transactions.
+ */
+ protected function _rollBack() {
+ $this->_connect();
+ $this->_connection->exec('ROLLBACK TRANSACTION');
+ return true;
+ }
+
+ /**
+ * Returns a list of the tables in the database.
+ *
+ * @return array
+ */
+ public function listTables()
+ {
+ $sql = "SELECT name FROM sysobjects WHERE type = 'U' ORDER BY name";
+ return $this->fetchCol($sql);
+ }
+
+ /**
+ * Returns the column descriptions for a table.
+ *
+ * The return value is an associative array keyed by the column name,
+ * as returned by the RDBMS.
+ *
+ * The value of each array element is an associative array
+ * with the following keys:
+ *
+ * SCHEMA_NAME => string; name of database or schema
+ * TABLE_NAME => string;
+ * COLUMN_NAME => string; column name
+ * COLUMN_POSITION => number; ordinal position of column in table
+ * DATA_TYPE => string; SQL datatype name of column
+ * DEFAULT => string; default expression of column, null if none
+ * NULLABLE => boolean; true if column can have nulls
+ * LENGTH => number; length of CHAR/VARCHAR
+ * SCALE => number; scale of NUMERIC/DECIMAL
+ * PRECISION => number; precision of NUMERIC/DECIMAL
+ * UNSIGNED => boolean; unsigned property of an integer type
+ * PRIMARY => boolean; true if column is part of the primary key
+ * PRIMARY_POSITION => integer; position of column in primary key
+ * PRIMARY_AUTO => integer; position of auto-generated column in primary key
+ *
+ * @todo Discover column primary key position.
+ * @todo Discover integer unsigned property.
+ *
+ * @param string $tableName
+ * @param string $schemaName OPTIONAL
+ * @return array
+ */
+ public function describeTable($tableName, $schemaName = null)
+ {
+ if ($schemaName != null) {
+ if (strpos($schemaName, '.') !== false) {
+ $result = explode('.', $schemaName);
+ $schemaName = $result[1];
+ }
+ }
+ /**
+ * Discover metadata information about this table.
+ */
+ $sql = "exec sp_columns @table_name = " . $this->quoteIdentifier($tableName, true);
+ if ($schemaName != null) {
+ $sql .= ", @table_owner = " . $this->quoteIdentifier($schemaName, true);
+ }
+
+ $stmt = $this->query($sql);
+ $result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
+
+ $table_name = 2;
+ $column_name = 3;
+ $type_name = 5;
+ $precision = 6;
+ $length = 7;
+ $scale = 8;
+ $nullable = 10;
+ $column_def = 12;
+ $column_position = 16;
+
+ /**
+ * Discover primary key column(s) for this table.
+ */
+ $sql = "exec sp_pkeys @table_name = " . $this->quoteIdentifier($tableName, true);
+ if ($schemaName != null) {
+ $sql .= ", @table_owner = " . $this->quoteIdentifier($schemaName, true);
+ }
+
+ $stmt = $this->query($sql);
+ $primaryKeysResult = $stmt->fetchAll(Zend_Db::FETCH_NUM);
+ $primaryKeyColumn = array();
+ $pkey_column_name = 3;
+ $pkey_key_seq = 4;
+ foreach ($primaryKeysResult as $pkeysRow) {
+ $primaryKeyColumn[$pkeysRow[$pkey_column_name]] = $pkeysRow[$pkey_key_seq];
+ }
+
+ $desc = array();
+ $p = 1;
+ foreach ($result as $key => $row) {
+ $identity = false;
+ $words = explode(' ', $row[$type_name], 2);
+ if (isset($words[0])) {
+ $type = $words[0];
+ if (isset($words[1])) {
+ $identity = (bool) preg_match('/identity/', $words[1]);
+ }
+ }
+
+ $isPrimary = array_key_exists($row[$column_name], $primaryKeyColumn);
+ if ($isPrimary) {
+ $primaryPosition = $primaryKeyColumn[$row[$column_name]];
+ } else {
+ $primaryPosition = null;
+ }
+
+ $desc[$this->foldCase($row[$column_name])] = array(
+ 'SCHEMA_NAME' => null, // @todo
+ 'TABLE_NAME' => $this->foldCase($row[$table_name]),
+ 'COLUMN_NAME' => $this->foldCase($row[$column_name]),
+ 'COLUMN_POSITION' => (int) $row[$column_position],
+ 'DATA_TYPE' => $type,
+ 'DEFAULT' => $row[$column_def],
+ 'NULLABLE' => (bool) $row[$nullable],
+ 'LENGTH' => $row[$length],
+ 'SCALE' => $row[$scale],
+ 'PRECISION' => $row[$precision],
+ 'UNSIGNED' => null, // @todo
+ 'PRIMARY' => $isPrimary,
+ 'PRIMARY_POSITION' => $primaryPosition,
+ 'IDENTITY' => $identity
+ );
+ }
+ return $desc;
+ }
+
+ /**
+ * Adds an adapter-specific LIMIT clause to the SELECT statement.
+ *
+ * @link http://lists.bestpractical.com/pipermail/rt-devel/2005-June/007339.html
+ *
+ * @param string $sql
+ * @param integer $count
+ * @param integer $offset OPTIONAL
+ * @throws Zend_Db_Adapter_Exception
+ * @return string
+ */
+ public function limit($sql, $count, $offset = 0)
+ {
+ $count = intval($count);
+ if ($count <= 0) {
+ /** @see Zend_Db_Adapter_Exception */
+ throw new Zend_Db_Adapter_Exception("LIMIT argument count=$count is not valid");
+ }
+
+ $offset = intval($offset);
+ if ($offset < 0) {
+ /** @see Zend_Db_Adapter_Exception */
+ throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid");
+ }
+
+ $sql = preg_replace(
+ '/^SELECT\s+(DISTINCT\s)?/i',
+ 'SELECT $1TOP ' . ($count+$offset) . ' ',
+ $sql
+ );
+
+ if ($offset > 0) {
+ $orderby = stristr($sql, 'ORDER BY');
+
+ if ($orderby !== false) {
+ $orderParts = explode(',', substr($orderby, 8));
+ $pregReplaceCount = null;
+ $orderbyInverseParts = array();
+ foreach ($orderParts as $orderPart) {
+ $orderPart = rtrim($orderPart);
+ $inv = preg_replace('/\s+desc$/i', ' ASC', $orderPart, 1, $pregReplaceCount);
+ if ($pregReplaceCount) {
+ $orderbyInverseParts[] = $inv;
+ continue;
+ }
+ $inv = preg_replace('/\s+asc$/i', ' DESC', $orderPart, 1, $pregReplaceCount);
+ if ($pregReplaceCount) {
+ $orderbyInverseParts[] = $inv;
+ continue;
+ } else {
+ $orderbyInverseParts[] = $orderPart . ' DESC';
+ }
+ }
+
+ $orderbyInverse = 'ORDER BY ' . implode(', ', $orderbyInverseParts);
+ }
+
+
+
+
+ $sql = 'SELECT * FROM (SELECT TOP ' . $count . ' * FROM (' . $sql . ') AS inner_tbl';
+ if ($orderby !== false) {
+ $sql .= ' ' . $orderbyInverse . ' ';
+ }
+ $sql .= ') AS outer_tbl';
+ if ($orderby !== false) {
+ $sql .= ' ' . $orderby;
+ }
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column.
+ *
+ * As a convention, on RDBMS brands that support sequences
+ * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence
+ * from the arguments and returns the last id generated by that sequence.
+ * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method
+ * returns the last value generated for such a column, and the table name
+ * argument is disregarded.
+ *
+ * Microsoft SQL Server does not support sequences, so the arguments to
+ * this method are ignored.
+ *
+ * @param string $tableName OPTIONAL Name of table.
+ * @param string $primaryKey OPTIONAL Name of primary key column.
+ * @return string
+ * @throws Zend_Db_Adapter_Exception
+ */
+ public function lastInsertId($tableName = null, $primaryKey = null)
+ {
+ $sql = 'SELECT SCOPE_IDENTITY()';
+ return (int)$this->fetchOne($sql);
+ }
+
+ /**
+ * Retrieve server version in PHP style
+ * Pdo_Mssql doesn't support getAttribute(PDO::ATTR_SERVER_VERSION)
+ * @return string
+ */
+ public function getServerVersion()
+ {
+ try {
+ $stmt = $this->query("SELECT CAST(SERVERPROPERTY('productversion') AS VARCHAR)");
+ $result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
+ if (count($result)) {
+ return $result[0][0];
+ }
+ return null;
+ } catch (PDOException $e) {
+ return null;
+ }
+ }
+
+ /**
+ * Quote a raw string.
+ *
+ * @param string $value Raw string
+ * @return string Quoted string
+ */
+ protected function _quote($value)
+ {
+ if (!is_int($value) && !is_float($value)) {
+ // Fix for null-byte injection
+ $value = addcslashes($value, "\000\032");
+ }
+ return parent::_quote($value);
+ }
+}
diff --git a/library/vendor/Zend/Db/Adapter/Pdo/Mysql.php b/library/vendor/Zend/Db/Adapter/Pdo/Mysql.php
new file mode 100644
index 0000000..951d665
--- /dev/null
+++ b/library/vendor/Zend/Db/Adapter/Pdo/Mysql.php
@@ -0,0 +1,269 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+
+/**
+ * @see Zend_Db_Adapter_Pdo_Abstract
+ */
+
+
+/**
+ * Class for connecting to MySQL databases and performing common operations.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Adapter_Pdo_Mysql extends Zend_Db_Adapter_Pdo_Abstract
+{
+
+ /**
+ * PDO type.
+ *
+ * @var string
+ */
+ protected $_pdoType = 'mysql';
+
+ /**
+ * Keys are UPPERCASE SQL datatypes or the constants
+ * Zend_Db::INT_TYPE, Zend_Db::BIGINT_TYPE, or Zend_Db::FLOAT_TYPE.
+ *
+ * Values are:
+ * 0 = 32-bit integer
+ * 1 = 64-bit integer
+ * 2 = float or decimal
+ *
+ * @var array Associative array of datatypes to values 0, 1, or 2.
+ */
+ protected $_numericDataTypes = array(
+ Zend_Db::INT_TYPE => Zend_Db::INT_TYPE,
+ Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE,
+ Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE,
+ 'INT' => Zend_Db::INT_TYPE,
+ 'INTEGER' => Zend_Db::INT_TYPE,
+ 'MEDIUMINT' => Zend_Db::INT_TYPE,
+ 'SMALLINT' => Zend_Db::INT_TYPE,
+ 'TINYINT' => Zend_Db::INT_TYPE,
+ 'BIGINT' => Zend_Db::BIGINT_TYPE,
+ 'SERIAL' => Zend_Db::BIGINT_TYPE,
+ 'DEC' => Zend_Db::FLOAT_TYPE,
+ 'DECIMAL' => Zend_Db::FLOAT_TYPE,
+ 'DOUBLE' => Zend_Db::FLOAT_TYPE,
+ 'DOUBLE PRECISION' => Zend_Db::FLOAT_TYPE,
+ 'FIXED' => Zend_Db::FLOAT_TYPE,
+ 'FLOAT' => Zend_Db::FLOAT_TYPE
+ );
+
+ /**
+ * Override _dsn() and ensure that charset is incorporated in mysql
+ * @see Zend_Db_Adapter_Pdo_Abstract::_dsn()
+ */
+ protected function _dsn()
+ {
+ $dsn = parent::_dsn();
+ if (isset($this->_config['charset'])) {
+ $dsn .= ';charset=' . $this->_config['charset'];
+ }
+ return $dsn;
+ }
+
+ /**
+ * Creates a PDO object and connects to the database.
+ *
+ * @return void
+ * @throws Zend_Db_Adapter_Exception
+ */
+ protected function _connect()
+ {
+ if ($this->_connection) {
+ return;
+ }
+
+ if (!empty($this->_config['charset'])
+ && version_compare(PHP_VERSION, '5.3.6', '<')
+ ) {
+ $initCommand = "SET NAMES '" . $this->_config['charset'] . "'";
+ $this->_config['driver_options'][1002] = $initCommand; // 1002 = PDO::MYSQL_ATTR_INIT_COMMAND
+ }
+
+ parent::_connect();
+ }
+
+ /**
+ * @return string
+ */
+ public function getQuoteIdentifierSymbol()
+ {
+ return "`";
+ }
+
+ /**
+ * Returns a list of the tables in the database.
+ *
+ * @return array
+ */
+ public function listTables()
+ {
+ return $this->fetchCol('SHOW TABLES');
+ }
+
+ /**
+ * Returns the column descriptions for a table.
+ *
+ * The return value is an associative array keyed by the column name,
+ * as returned by the RDBMS.
+ *
+ * The value of each array element is an associative array
+ * with the following keys:
+ *
+ * SCHEMA_NAME => string; name of database or schema
+ * TABLE_NAME => string;
+ * COLUMN_NAME => string; column name
+ * COLUMN_POSITION => number; ordinal position of column in table
+ * DATA_TYPE => string; SQL datatype name of column
+ * DEFAULT => string; default expression of column, null if none
+ * NULLABLE => boolean; true if column can have nulls
+ * LENGTH => number; length of CHAR/VARCHAR
+ * SCALE => number; scale of NUMERIC/DECIMAL
+ * PRECISION => number; precision of NUMERIC/DECIMAL
+ * UNSIGNED => boolean; unsigned property of an integer type
+ * PRIMARY => boolean; true if column is part of the primary key
+ * PRIMARY_POSITION => integer; position of column in primary key
+ * IDENTITY => integer; true if column is auto-generated with unique values
+ *
+ * @param string $tableName
+ * @param string $schemaName OPTIONAL
+ * @return array
+ */
+ public function describeTable($tableName, $schemaName = null)
+ {
+ // @todo use INFORMATION_SCHEMA someday when MySQL's
+ // implementation has reasonably good performance and
+ // the version with this improvement is in wide use.
+
+ if ($schemaName) {
+ $sql = 'DESCRIBE ' . $this->quoteIdentifier("$schemaName.$tableName", true);
+ } else {
+ $sql = 'DESCRIBE ' . $this->quoteIdentifier($tableName, true);
+ }
+ $stmt = $this->query($sql);
+
+ // Use FETCH_NUM so we are not dependent on the CASE attribute of the PDO connection
+ $result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
+
+ $field = 0;
+ $type = 1;
+ $null = 2;
+ $key = 3;
+ $default = 4;
+ $extra = 5;
+
+ $desc = array();
+ $i = 1;
+ $p = 1;
+ foreach ($result as $row) {
+ list($length, $scale, $precision, $unsigned, $primary, $primaryPosition, $identity)
+ = array(null, null, null, null, false, null, false);
+ if (preg_match('/unsigned/', $row[$type])) {
+ $unsigned = true;
+ }
+ if (preg_match('/^((?:var)?char)\((\d+)\)/', $row[$type], $matches)) {
+ $row[$type] = $matches[1];
+ $length = $matches[2];
+ } else if (preg_match('/^decimal\((\d+),(\d+)\)/', $row[$type], $matches)) {
+ $row[$type] = 'decimal';
+ $precision = $matches[1];
+ $scale = $matches[2];
+ } else if (preg_match('/^float\((\d+),(\d+)\)/', $row[$type], $matches)) {
+ $row[$type] = 'float';
+ $precision = $matches[1];
+ $scale = $matches[2];
+ } else if (preg_match('/^((?:big|medium|small|tiny)?int)\((\d+)\)/', $row[$type], $matches)) {
+ $row[$type] = $matches[1];
+ // The optional argument of a MySQL int type is not precision
+ // or length; it is only a hint for display width.
+ }
+ if (strtoupper($row[$key]) == 'PRI') {
+ $primary = true;
+ $primaryPosition = $p;
+ if ($row[$extra] == 'auto_increment') {
+ $identity = true;
+ } else {
+ $identity = false;
+ }
+ ++$p;
+ }
+ $desc[$this->foldCase($row[$field])] = array(
+ 'SCHEMA_NAME' => null, // @todo
+ 'TABLE_NAME' => $this->foldCase($tableName),
+ 'COLUMN_NAME' => $this->foldCase($row[$field]),
+ 'COLUMN_POSITION' => $i,
+ 'DATA_TYPE' => $row[$type],
+ 'DEFAULT' => $row[$default],
+ 'NULLABLE' => (bool) ($row[$null] == 'YES'),
+ 'LENGTH' => $length,
+ 'SCALE' => $scale,
+ 'PRECISION' => $precision,
+ 'UNSIGNED' => $unsigned,
+ 'PRIMARY' => $primary,
+ 'PRIMARY_POSITION' => $primaryPosition,
+ 'IDENTITY' => $identity
+ );
+ ++$i;
+ }
+ return $desc;
+ }
+
+ /**
+ * Adds an adapter-specific LIMIT clause to the SELECT statement.
+ *
+ * @param string $sql
+ * @param integer $count
+ * @param integer $offset OPTIONAL
+ * @throws Zend_Db_Adapter_Exception
+ * @return string
+ */
+ public function limit($sql, $count, $offset = 0)
+ {
+ $count = intval($count);
+ if ($count <= 0) {
+ /** @see Zend_Db_Adapter_Exception */
+ throw new Zend_Db_Adapter_Exception("LIMIT argument count=$count is not valid");
+ }
+
+ $offset = intval($offset);
+ if ($offset < 0) {
+ /** @see Zend_Db_Adapter_Exception */
+ throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid");
+ }
+
+ $sql .= " LIMIT $count";
+ if ($offset > 0) {
+ $sql .= " OFFSET $offset";
+ }
+
+ return $sql;
+ }
+
+}
diff --git a/library/vendor/Zend/Db/Adapter/Pdo/Oci.php b/library/vendor/Zend/Db/Adapter/Pdo/Oci.php
new file mode 100644
index 0000000..eb4e6fc
--- /dev/null
+++ b/library/vendor/Zend/Db/Adapter/Pdo/Oci.php
@@ -0,0 +1,375 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+
+/**
+ * @see Zend_Db_Adapter_Pdo_Abstract
+ */
+
+
+/**
+ * Class for connecting to Oracle databases and performing common operations.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Adapter_Pdo_Oci extends Zend_Db_Adapter_Pdo_Abstract
+{
+
+ /**
+ * PDO type.
+ *
+ * @var string
+ */
+ protected $_pdoType = 'oci';
+
+ /**
+ * Default class name for a DB statement.
+ *
+ * @var string
+ */
+ protected $_defaultStmtClass = 'Zend_Db_Statement_Pdo_Oci';
+
+ /**
+ * Keys are UPPERCASE SQL datatypes or the constants
+ * Zend_Db::INT_TYPE, Zend_Db::BIGINT_TYPE, or Zend_Db::FLOAT_TYPE.
+ *
+ * Values are:
+ * 0 = 32-bit integer
+ * 1 = 64-bit integer
+ * 2 = float or decimal
+ *
+ * @var array Associative array of datatypes to values 0, 1, or 2.
+ */
+ protected $_numericDataTypes = array(
+ Zend_Db::INT_TYPE => Zend_Db::INT_TYPE,
+ Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE,
+ Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE,
+ 'BINARY_DOUBLE' => Zend_Db::FLOAT_TYPE,
+ 'BINARY_FLOAT' => Zend_Db::FLOAT_TYPE,
+ 'NUMBER' => Zend_Db::FLOAT_TYPE
+ );
+
+ /**
+ * Creates a PDO DSN for the adapter from $this->_config settings.
+ *
+ * @return string
+ */
+ protected function _dsn()
+ {
+ // baseline of DSN parts
+ $dsn = $this->_config;
+
+ if (isset($dsn['host'])) {
+ $tns = 'dbname=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)' .
+ '(HOST=' . $dsn['host'] . ')';
+
+ if (isset($dsn['port'])) {
+ $tns .= '(PORT=' . $dsn['port'] . ')';
+ } else {
+ $tns .= '(PORT=1521)';
+ }
+
+ $tns .= '))(CONNECT_DATA=(SID=' . $dsn['dbname'] . ')))';
+ } else {
+ $tns = 'dbname=' . $dsn['dbname'];
+ }
+
+ if (isset($dsn['charset'])) {
+ $tns .= ';charset=' . $dsn['charset'];
+ }
+
+ return $this->_pdoType . ':' . $tns;
+ }
+
+ /**
+ * Quote a raw string.
+ * Most PDO drivers have an implementation for the quote() method,
+ * but the Oracle OCI driver must use the same implementation as the
+ * Zend_Db_Adapter_Abstract class.
+ *
+ * @param string $value Raw string
+ * @return string Quoted string
+ */
+ protected function _quote($value)
+ {
+ if (is_int($value) || is_float($value)) {
+ return $value;
+ }
+ $value = str_replace("'", "''", $value);
+ return "'" . addcslashes($value, "\000\n\r\\\032") . "'";
+ }
+
+ /**
+ * Quote a table identifier and alias.
+ *
+ * @param string|array|Zend_Db_Expr $ident The identifier or expression.
+ * @param string $alias An alias for the table.
+ * @return string The quoted identifier and alias.
+ */
+ public function quoteTableAs($ident, $alias = null, $auto = false)
+ {
+ // Oracle doesn't allow the 'AS' keyword between the table identifier/expression and alias.
+ return $this->_quoteIdentifierAs($ident, $alias, $auto, ' ');
+ }
+
+ /**
+ * Returns a list of the tables in the database.
+ *
+ * @return array
+ */
+ public function listTables()
+ {
+ $data = $this->fetchCol('SELECT table_name FROM all_tables');
+ return $data;
+ }
+
+ /**
+ * Returns the column descriptions for a table.
+ *
+ * The return value is an associative array keyed by the column name,
+ * as returned by the RDBMS.
+ *
+ * The value of each array element is an associative array
+ * with the following keys:
+ *
+ * SCHEMA_NAME => string; name of schema
+ * TABLE_NAME => string;
+ * COLUMN_NAME => string; column name
+ * COLUMN_POSITION => number; ordinal position of column in table
+ * DATA_TYPE => string; SQL datatype name of column
+ * DEFAULT => string; default expression of column, null if none
+ * NULLABLE => boolean; true if column can have nulls
+ * LENGTH => number; length of CHAR/VARCHAR
+ * SCALE => number; scale of NUMERIC/DECIMAL
+ * PRECISION => number; precision of NUMERIC/DECIMAL
+ * UNSIGNED => boolean; unsigned property of an integer type
+ * PRIMARY => boolean; true if column is part of the primary key
+ * PRIMARY_POSITION => integer; position of column in primary key
+ * IDENTITY => integer; true if column is auto-generated with unique values
+ *
+ * @todo Discover integer unsigned property.
+ *
+ * @param string $tableName
+ * @param string $schemaName OPTIONAL
+ * @return array
+ */
+ public function describeTable($tableName, $schemaName = null)
+ {
+ $version = $this->getServerVersion();
+ if (($version === null) || version_compare($version, '9.0.0', '>=')) {
+ $sql = "SELECT TC.TABLE_NAME, TC.OWNER, TC.COLUMN_NAME, TC.DATA_TYPE,
+ TC.DATA_DEFAULT, TC.NULLABLE, TC.COLUMN_ID, TC.DATA_LENGTH,
+ TC.DATA_SCALE, TC.DATA_PRECISION, C.CONSTRAINT_TYPE, CC.POSITION
+ FROM ALL_TAB_COLUMNS TC
+ LEFT JOIN (ALL_CONS_COLUMNS CC JOIN ALL_CONSTRAINTS C
+ ON (CC.CONSTRAINT_NAME = C.CONSTRAINT_NAME AND CC.TABLE_NAME = C.TABLE_NAME AND CC.OWNER = C.OWNER AND C.CONSTRAINT_TYPE = 'P'))
+ ON TC.TABLE_NAME = CC.TABLE_NAME AND TC.COLUMN_NAME = CC.COLUMN_NAME
+ WHERE UPPER(TC.TABLE_NAME) = UPPER(:TBNAME)";
+ $bind[':TBNAME'] = $tableName;
+ if ($schemaName) {
+ $sql .= ' AND UPPER(TC.OWNER) = UPPER(:SCNAME)';
+ $bind[':SCNAME'] = $schemaName;
+ }
+ $sql .= ' ORDER BY TC.COLUMN_ID';
+ } else {
+ $subSql="SELECT AC.OWNER, AC.TABLE_NAME, ACC.COLUMN_NAME, AC.CONSTRAINT_TYPE, ACC.POSITION
+ from ALL_CONSTRAINTS AC, ALL_CONS_COLUMNS ACC
+ WHERE ACC.CONSTRAINT_NAME = AC.CONSTRAINT_NAME
+ AND ACC.TABLE_NAME = AC.TABLE_NAME
+ AND ACC.OWNER = AC.OWNER
+ AND AC.CONSTRAINT_TYPE = 'P'
+ AND UPPER(AC.TABLE_NAME) = UPPER(:TBNAME)";
+ $bind[':TBNAME'] = $tableName;
+ if ($schemaName) {
+ $subSql .= ' AND UPPER(ACC.OWNER) = UPPER(:SCNAME)';
+ $bind[':SCNAME'] = $schemaName;
+ }
+ $sql="SELECT TC.TABLE_NAME, TC.OWNER, TC.COLUMN_NAME, TC.DATA_TYPE,
+ TC.DATA_DEFAULT, TC.NULLABLE, TC.COLUMN_ID, TC.DATA_LENGTH,
+ TC.DATA_SCALE, TC.DATA_PRECISION, CC.CONSTRAINT_TYPE, CC.POSITION
+ FROM ALL_TAB_COLUMNS TC, ($subSql) CC
+ WHERE UPPER(TC.TABLE_NAME) = UPPER(:TBNAME)
+ AND TC.OWNER = CC.OWNER(+) AND TC.TABLE_NAME = CC.TABLE_NAME(+) AND TC.COLUMN_NAME = CC.COLUMN_NAME(+)";
+ if ($schemaName) {
+ $sql .= ' AND UPPER(TC.OWNER) = UPPER(:SCNAME)';
+ }
+ $sql .= ' ORDER BY TC.COLUMN_ID';
+ }
+
+ $stmt = $this->query($sql, $bind);
+
+ /**
+ * Use FETCH_NUM so we are not dependent on the CASE attribute of the PDO connection
+ */
+ $result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
+
+ $table_name = 0;
+ $owner = 1;
+ $column_name = 2;
+ $data_type = 3;
+ $data_default = 4;
+ $nullable = 5;
+ $column_id = 6;
+ $data_length = 7;
+ $data_scale = 8;
+ $data_precision = 9;
+ $constraint_type = 10;
+ $position = 11;
+
+ $desc = array();
+ foreach ($result as $key => $row) {
+ list ($primary, $primaryPosition, $identity) = array(false, null, false);
+ if ($row[$constraint_type] == 'P') {
+ $primary = true;
+ $primaryPosition = $row[$position];
+ /**
+ * Oracle does not support auto-increment keys.
+ */
+ $identity = false;
+ }
+ $desc[$this->foldCase($row[$column_name])] = array(
+ 'SCHEMA_NAME' => $this->foldCase($row[$owner]),
+ 'TABLE_NAME' => $this->foldCase($row[$table_name]),
+ 'COLUMN_NAME' => $this->foldCase($row[$column_name]),
+ 'COLUMN_POSITION' => $row[$column_id],
+ 'DATA_TYPE' => $row[$data_type],
+ 'DEFAULT' => $row[$data_default],
+ 'NULLABLE' => (bool) ($row[$nullable] == 'Y'),
+ 'LENGTH' => $row[$data_length],
+ 'SCALE' => $row[$data_scale],
+ 'PRECISION' => $row[$data_precision],
+ 'UNSIGNED' => null, // @todo
+ 'PRIMARY' => $primary,
+ 'PRIMARY_POSITION' => $primaryPosition,
+ 'IDENTITY' => $identity
+ );
+ }
+ return $desc;
+ }
+
+ /**
+ * Return the most recent value from the specified sequence in the database.
+ * This is supported only on RDBMS brands that support sequences
+ * (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null.
+ *
+ * @param string $sequenceName
+ * @return integer
+ */
+ public function lastSequenceId($sequenceName)
+ {
+ $this->_connect();
+ $value = $this->fetchOne('SELECT '.$this->quoteIdentifier($sequenceName, true).'.CURRVAL FROM dual');
+ return $value;
+ }
+
+ /**
+ * Generate a new value from the specified sequence in the database, and return it.
+ * This is supported only on RDBMS brands that support sequences
+ * (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null.
+ *
+ * @param string $sequenceName
+ * @return integer
+ */
+ public function nextSequenceId($sequenceName)
+ {
+ $this->_connect();
+ $value = $this->fetchOne('SELECT '.$this->quoteIdentifier($sequenceName, true).'.NEXTVAL FROM dual');
+ return $value;
+ }
+
+ /**
+ * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column.
+ *
+ * As a convention, on RDBMS brands that support sequences
+ * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence
+ * from the arguments and returns the last id generated by that sequence.
+ * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method
+ * returns the last value generated for such a column, and the table name
+ * argument is disregarded.
+ *
+ * Oracle does not support IDENTITY columns, so if the sequence is not
+ * specified, this method returns null.
+ *
+ * @param string $tableName OPTIONAL Name of table.
+ * @param string $primaryKey OPTIONAL Name of primary key column.
+ * @return string
+ * @throws Zend_Db_Adapter_Oracle_Exception
+ */
+ public function lastInsertId($tableName = null, $primaryKey = null)
+ {
+ if ($tableName !== null) {
+ $sequenceName = $tableName;
+ if ($primaryKey) {
+ $sequenceName .= $this->foldCase("_$primaryKey");
+ }
+ $sequenceName .= $this->foldCase('_seq');
+ return $this->lastSequenceId($sequenceName);
+ }
+ // No support for IDENTITY columns; return null
+ return null;
+ }
+
+ /**
+ * Adds an adapter-specific LIMIT clause to the SELECT statement.
+ *
+ * @param string $sql
+ * @param integer $count
+ * @param integer $offset
+ * @throws Zend_Db_Adapter_Exception
+ * @return string
+ */
+ public function limit($sql, $count, $offset = 0)
+ {
+ $count = intval($count);
+ if ($count <= 0) {
+ /** @see Zend_Db_Adapter_Exception */
+ throw new Zend_Db_Adapter_Exception("LIMIT argument count=$count is not valid");
+ }
+
+ $offset = intval($offset);
+ if ($offset < 0) {
+ /** @see Zend_Db_Adapter_Exception */
+ throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid");
+ }
+
+ /**
+ * Oracle does not implement the LIMIT clause as some RDBMS do.
+ * We have to simulate it with subqueries and ROWNUM.
+ * Unfortunately because we use the column wildcard "*",
+ * this puts an extra column into the query result set.
+ */
+ $limit_sql = "SELECT z2.*
+ FROM (
+ SELECT z1.*, ROWNUM AS \"zend_db_rownum\"
+ FROM (
+ " . $sql . "
+ ) z1
+ ) z2
+ WHERE z2.\"zend_db_rownum\" BETWEEN " . ($offset+1) . " AND " . ($offset+$count);
+ return $limit_sql;
+ }
+
+}
diff --git a/library/vendor/Zend/Db/Adapter/Pdo/Pgsql.php b/library/vendor/Zend/Db/Adapter/Pdo/Pgsql.php
new file mode 100644
index 0000000..060ed28
--- /dev/null
+++ b/library/vendor/Zend/Db/Adapter/Pdo/Pgsql.php
@@ -0,0 +1,333 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+
+/**
+ * @see Zend_Db_Adapter_Pdo_Abstract
+ */
+
+
+/**
+ * Class for connecting to PostgreSQL databases and performing common operations.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Adapter_Pdo_Pgsql extends Zend_Db_Adapter_Pdo_Abstract
+{
+
+ /**
+ * PDO type.
+ *
+ * @var string
+ */
+ protected $_pdoType = 'pgsql';
+
+ /**
+ * Keys are UPPERCASE SQL datatypes or the constants
+ * Zend_Db::INT_TYPE, Zend_Db::BIGINT_TYPE, or Zend_Db::FLOAT_TYPE.
+ *
+ * Values are:
+ * 0 = 32-bit integer
+ * 1 = 64-bit integer
+ * 2 = float or decimal
+ *
+ * @var array Associative array of datatypes to values 0, 1, or 2.
+ */
+ protected $_numericDataTypes = array(
+ Zend_Db::INT_TYPE => Zend_Db::INT_TYPE,
+ Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE,
+ Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE,
+ 'INTEGER' => Zend_Db::INT_TYPE,
+ 'SERIAL' => Zend_Db::INT_TYPE,
+ 'SMALLINT' => Zend_Db::INT_TYPE,
+ 'BIGINT' => Zend_Db::BIGINT_TYPE,
+ 'BIGSERIAL' => Zend_Db::BIGINT_TYPE,
+ 'DECIMAL' => Zend_Db::FLOAT_TYPE,
+ 'DOUBLE PRECISION' => Zend_Db::FLOAT_TYPE,
+ 'NUMERIC' => Zend_Db::FLOAT_TYPE,
+ 'REAL' => Zend_Db::FLOAT_TYPE
+ );
+
+ /**
+ * Creates a PDO object and connects to the database.
+ *
+ * @return void
+ * @throws Zend_Db_Adapter_Exception
+ */
+ protected function _connect()
+ {
+ if ($this->_connection) {
+ return;
+ }
+
+ parent::_connect();
+
+ if (!empty($this->_config['charset'])) {
+ $sql = "SET NAMES '" . $this->_config['charset'] . "'";
+ $this->_connection->exec($sql);
+ }
+ }
+
+ /**
+ * Returns a list of the tables in the database.
+ *
+ * @return array
+ */
+ public function listTables()
+ {
+ // @todo use a better query with joins instead of subqueries
+ $sql = "SELECT c.relname AS table_name "
+ . "FROM pg_class c, pg_user u "
+ . "WHERE c.relowner = u.usesysid AND c.relkind = 'r' "
+ . "AND NOT EXISTS (SELECT 1 FROM pg_views WHERE viewname = c.relname) "
+ . "AND c.relname !~ '^(pg_|sql_)' "
+ . "UNION "
+ . "SELECT c.relname AS table_name "
+ . "FROM pg_class c "
+ . "WHERE c.relkind = 'r' "
+ . "AND NOT EXISTS (SELECT 1 FROM pg_views WHERE viewname = c.relname) "
+ . "AND NOT EXISTS (SELECT 1 FROM pg_user WHERE usesysid = c.relowner) "
+ . "AND c.relname !~ '^pg_'";
+
+ return $this->fetchCol($sql);
+ }
+
+ /**
+ * Returns the column descriptions for a table.
+ *
+ * The return value is an associative array keyed by the column name,
+ * as returned by the RDBMS.
+ *
+ * The value of each array element is an associative array
+ * with the following keys:
+ *
+ * SCHEMA_NAME => string; name of database or schema
+ * TABLE_NAME => string;
+ * COLUMN_NAME => string; column name
+ * COLUMN_POSITION => number; ordinal position of column in table
+ * DATA_TYPE => string; SQL datatype name of column
+ * DEFAULT => string; default expression of column, null if none
+ * NULLABLE => boolean; true if column can have nulls
+ * LENGTH => number; length of CHAR/VARCHAR
+ * SCALE => number; scale of NUMERIC/DECIMAL
+ * PRECISION => number; precision of NUMERIC/DECIMAL
+ * UNSIGNED => boolean; unsigned property of an integer type
+ * PRIMARY => boolean; true if column is part of the primary key
+ * PRIMARY_POSITION => integer; position of column in primary key
+ * IDENTITY => integer; true if column is auto-generated with unique values
+ *
+ * @todo Discover integer unsigned property.
+ *
+ * @param string $tableName
+ * @param string $schemaName OPTIONAL
+ * @return array
+ */
+ public function describeTable($tableName, $schemaName = null)
+ {
+ $sql = "SELECT
+ a.attnum,
+ n.nspname,
+ c.relname,
+ a.attname AS colname,
+ t.typname AS type,
+ a.atttypmod,
+ FORMAT_TYPE(a.atttypid, a.atttypmod) AS complete_type,
+ d.adsrc AS default_value,
+ a.attnotnull AS notnull,
+ a.attlen AS length,
+ co.contype,
+ ARRAY_TO_STRING(co.conkey, ',') AS conkey
+ FROM pg_attribute AS a
+ JOIN pg_class AS c ON a.attrelid = c.oid
+ JOIN pg_namespace AS n ON c.relnamespace = n.oid
+ JOIN pg_type AS t ON a.atttypid = t.oid
+ LEFT OUTER JOIN pg_constraint AS co ON (co.conrelid = c.oid
+ AND a.attnum = ANY(co.conkey) AND co.contype = 'p')
+ LEFT OUTER JOIN pg_attrdef AS d ON d.adrelid = c.oid AND d.adnum = a.attnum
+ WHERE a.attnum > 0 AND c.relname = ".$this->quote($tableName);
+ if ($schemaName) {
+ $sql .= " AND n.nspname = ".$this->quote($schemaName);
+ }
+ $sql .= ' ORDER BY a.attnum';
+
+ $stmt = $this->query($sql);
+
+ // Use FETCH_NUM so we are not dependent on the CASE attribute of the PDO connection
+ $result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
+
+ $attnum = 0;
+ $nspname = 1;
+ $relname = 2;
+ $colname = 3;
+ $type = 4;
+ $atttypemod = 5;
+ $complete_type = 6;
+ $default_value = 7;
+ $notnull = 8;
+ $length = 9;
+ $contype = 10;
+ $conkey = 11;
+
+ $desc = array();
+ foreach ($result as $key => $row) {
+ $defaultValue = $row[$default_value];
+ if ($row[$type] == 'varchar' || $row[$type] == 'bpchar' ) {
+ if (preg_match('/character(?: varying)?(?:\((\d+)\))?/', $row[$complete_type], $matches)) {
+ if (isset($matches[1])) {
+ $row[$length] = $matches[1];
+ } else {
+ $row[$length] = null; // unlimited
+ }
+ }
+ if (preg_match("/^'(.*?)'::(?:character varying|bpchar)$/", $defaultValue, $matches)) {
+ $defaultValue = $matches[1];
+ }
+ }
+ list($primary, $primaryPosition, $identity) = array(false, null, false);
+ if ($row[$contype] == 'p') {
+ $primary = true;
+ $primaryPosition = array_search($row[$attnum], explode(',', $row[$conkey])) + 1;
+ $identity = (bool) (preg_match('/^nextval/', $row[$default_value]));
+ }
+ $desc[$this->foldCase($row[$colname])] = array(
+ 'SCHEMA_NAME' => $this->foldCase($row[$nspname]),
+ 'TABLE_NAME' => $this->foldCase($row[$relname]),
+ 'COLUMN_NAME' => $this->foldCase($row[$colname]),
+ 'COLUMN_POSITION' => $row[$attnum],
+ 'DATA_TYPE' => $row[$type],
+ 'DEFAULT' => $defaultValue,
+ 'NULLABLE' => (bool) ($row[$notnull] != 't'),
+ 'LENGTH' => $row[$length],
+ 'SCALE' => null, // @todo
+ 'PRECISION' => null, // @todo
+ 'UNSIGNED' => null, // @todo
+ 'PRIMARY' => $primary,
+ 'PRIMARY_POSITION' => $primaryPosition,
+ 'IDENTITY' => $identity
+ );
+ }
+ return $desc;
+ }
+
+
+ /**
+ * Adds an adapter-specific LIMIT clause to the SELECT statement.
+ *
+ * @param string $sql
+ * @param integer $count
+ * @param integer $offset OPTIONAL
+ * @return string
+ */
+ public function limit($sql, $count, $offset = 0)
+ {
+ $count = intval($count);
+ if ($count <= 0) {
+ /**
+ * @see Zend_Db_Adapter_Exception
+ */
+ throw new Zend_Db_Adapter_Exception("LIMIT argument count=$count is not valid");
+ }
+
+ $offset = intval($offset);
+ if ($offset < 0) {
+ /**
+ * @see Zend_Db_Adapter_Exception
+ */
+ throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid");
+ }
+
+ $sql .= " LIMIT $count";
+ if ($offset > 0) {
+ $sql .= " OFFSET $offset";
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Return the most recent value from the specified sequence in the database.
+ * This is supported only on RDBMS brands that support sequences
+ * (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null.
+ *
+ * @param string $sequenceName
+ * @return string
+ */
+ public function lastSequenceId($sequenceName)
+ {
+ $this->_connect();
+ $sequenceName = str_replace($this->getQuoteIdentifierSymbol(), '', (string) $sequenceName);
+ $value = $this->fetchOne("SELECT CURRVAL("
+ . $this->quote($this->quoteIdentifier($sequenceName, true))
+ . ")");
+ return $value;
+ }
+
+ /**
+ * Generate a new value from the specified sequence in the database, and return it.
+ * This is supported only on RDBMS brands that support sequences
+ * (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null.
+ *
+ * @param string $sequenceName
+ * @return string
+ */
+ public function nextSequenceId($sequenceName)
+ {
+ $this->_connect();
+ $sequenceName = str_replace($this->getQuoteIdentifierSymbol(), '', (string) $sequenceName);
+ $value = $this->fetchOne("SELECT NEXTVAL("
+ . $this->quote($this->quoteIdentifier($sequenceName, true))
+ . ")");
+ return $value;
+ }
+
+ /**
+ * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column.
+ *
+ * As a convention, on RDBMS brands that support sequences
+ * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence
+ * from the arguments and returns the last id generated by that sequence.
+ * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method
+ * returns the last value generated for such a column, and the table name
+ * argument is disregarded.
+ *
+ * @param string $tableName OPTIONAL Name of table.
+ * @param string $primaryKey OPTIONAL Name of primary key column.
+ * @return string
+ */
+ public function lastInsertId($tableName = null, $primaryKey = null)
+ {
+ if ($tableName !== null) {
+ $sequenceName = $tableName;
+ if ($primaryKey) {
+ $sequenceName .= "_$primaryKey";
+ }
+ $sequenceName .= '_seq';
+ return $this->lastSequenceId($sequenceName);
+ }
+ return $this->_connection->lastInsertId($tableName);
+ }
+
+}
diff --git a/library/vendor/Zend/Db/Adapter/Pdo/Sqlite.php b/library/vendor/Zend/Db/Adapter/Pdo/Sqlite.php
new file mode 100644
index 0000000..6453339
--- /dev/null
+++ b/library/vendor/Zend/Db/Adapter/Pdo/Sqlite.php
@@ -0,0 +1,305 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+
+/**
+ * @see Zend_Db_Adapter_Pdo_Abstract
+ */
+
+
+/**
+ * Class for connecting to SQLite2 and SQLite3 databases and performing common operations.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Adapter_Pdo_Sqlite extends Zend_Db_Adapter_Pdo_Abstract
+{
+
+ /**
+ * PDO type
+ *
+ * @var string
+ */
+ protected $_pdoType = 'sqlite';
+
+ /**
+ * Keys are UPPERCASE SQL datatypes or the constants
+ * Zend_Db::INT_TYPE, Zend_Db::BIGINT_TYPE, or Zend_Db::FLOAT_TYPE.
+ *
+ * Values are:
+ * 0 = 32-bit integer
+ * 1 = 64-bit integer
+ * 2 = float or decimal
+ *
+ * @var array Associative array of datatypes to values 0, 1, or 2.
+ */
+ protected $_numericDataTypes = array(
+ Zend_Db::INT_TYPE => Zend_Db::INT_TYPE,
+ Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE,
+ Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE,
+ 'INTEGER' => Zend_Db::BIGINT_TYPE,
+ 'REAL' => Zend_Db::FLOAT_TYPE
+ );
+
+ /**
+ * Constructor.
+ *
+ * $config is an array of key/value pairs containing configuration
+ * options. Note that the SQLite options are different than most of
+ * the other PDO adapters in that no username or password are needed.
+ * Also, an extra config key "sqlite2" specifies compatibility mode.
+ *
+ * dbname => (string) The name of the database to user (required,
+ * use :memory: for memory-based database)
+ *
+ * sqlite2 => (boolean) PDO_SQLITE defaults to SQLite 3. For compatibility
+ * with an older SQLite 2 database, set this to TRUE.
+ *
+ * @param array $config An array of configuration keys.
+ */
+ public function __construct(array $config = array())
+ {
+ if (isset($config['sqlite2']) && $config['sqlite2']) {
+ $this->_pdoType = 'sqlite2';
+ }
+
+ // SQLite uses no username/password. Stub to satisfy parent::_connect()
+ $this->_config['username'] = null;
+ $this->_config['password'] = null;
+
+ return parent::__construct($config);
+ }
+
+ /**
+ * Check for config options that are mandatory.
+ * Throw exceptions if any are missing.
+ *
+ * @param array $config
+ * @throws Zend_Db_Adapter_Exception
+ */
+ protected function _checkRequiredOptions(array $config)
+ {
+ // we need at least a dbname
+ if (! array_key_exists('dbname', $config)) {
+ /** @see Zend_Db_Adapter_Exception */
+ throw new Zend_Db_Adapter_Exception("Configuration array must have a key for 'dbname' that names the database instance");
+ }
+ }
+
+ /**
+ * DSN builder
+ */
+ protected function _dsn()
+ {
+ return $this->_pdoType .':'. $this->_config['dbname'];
+ }
+
+ /**
+ * Special configuration for SQLite behavior: make sure that result sets
+ * contain keys like 'column' instead of 'table.column'.
+ *
+ * @throws Zend_Db_Adapter_Exception
+ */
+ protected function _connect()
+ {
+ /**
+ * if we already have a PDO object, no need to re-connect.
+ */
+ if ($this->_connection) {
+ return;
+ }
+
+ parent::_connect();
+
+ $retval = $this->_connection->exec('PRAGMA full_column_names=0');
+ if ($retval === false) {
+ $error = $this->_connection->errorInfo();
+ /** @see Zend_Db_Adapter_Exception */
+ throw new Zend_Db_Adapter_Exception($error[2]);
+ }
+
+ $retval = $this->_connection->exec('PRAGMA short_column_names=1');
+ if ($retval === false) {
+ $error = $this->_connection->errorInfo();
+ /** @see Zend_Db_Adapter_Exception */
+ throw new Zend_Db_Adapter_Exception($error[2]);
+ }
+ }
+
+ /**
+ * Returns a list of the tables in the database.
+ *
+ * @return array
+ */
+ public function listTables()
+ {
+ $sql = "SELECT name FROM sqlite_master WHERE type='table' "
+ . "UNION ALL SELECT name FROM sqlite_temp_master "
+ . "WHERE type='table' ORDER BY name";
+
+ return $this->fetchCol($sql);
+ }
+
+ /**
+ * Returns the column descriptions for a table.
+ *
+ * The return value is an associative array keyed by the column name,
+ * as returned by the RDBMS.
+ *
+ * The value of each array element is an associative array
+ * with the following keys:
+ *
+ * SCHEMA_NAME => string; name of database or schema
+ * TABLE_NAME => string;
+ * COLUMN_NAME => string; column name
+ * COLUMN_POSITION => number; ordinal position of column in table
+ * DATA_TYPE => string; SQL datatype name of column
+ * DEFAULT => string; default expression of column, null if none
+ * NULLABLE => boolean; true if column can have nulls
+ * LENGTH => number; length of CHAR/VARCHAR
+ * SCALE => number; scale of NUMERIC/DECIMAL
+ * PRECISION => number; precision of NUMERIC/DECIMAL
+ * UNSIGNED => boolean; unsigned property of an integer type
+ * PRIMARY => boolean; true if column is part of the primary key
+ * PRIMARY_POSITION => integer; position of column in primary key
+ * IDENTITY => integer; true if column is auto-generated with unique values
+ *
+ * @param string $tableName
+ * @param string $schemaName OPTIONAL
+ * @return array
+ */
+ public function describeTable($tableName, $schemaName = null)
+ {
+ $sql = 'PRAGMA ';
+
+ if ($schemaName) {
+ $sql .= $this->quoteIdentifier($schemaName) . '.';
+ }
+
+ $sql .= 'table_info('.$this->quoteIdentifier($tableName).')';
+
+ $stmt = $this->query($sql);
+
+ /**
+ * Use FETCH_NUM so we are not dependent on the CASE attribute of the PDO connection
+ */
+ $result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
+
+ $cid = 0;
+ $name = 1;
+ $type = 2;
+ $notnull = 3;
+ $dflt_value = 4;
+ $pk = 5;
+
+ $desc = array();
+
+ $p = 1;
+ foreach ($result as $key => $row) {
+ list($length, $scale, $precision, $primary, $primaryPosition, $identity) =
+ array(null, null, null, false, null, false);
+ if (preg_match('/^((?:var)?char)\((\d+)\)/i', $row[$type], $matches)) {
+ $row[$type] = $matches[1];
+ $length = $matches[2];
+ } else if (preg_match('/^decimal\((\d+),(\d+)\)/i', $row[$type], $matches)) {
+ $row[$type] = 'DECIMAL';
+ $precision = $matches[1];
+ $scale = $matches[2];
+ }
+ if ((bool) $row[$pk]) {
+ $primary = true;
+ $primaryPosition = $p;
+ /**
+ * SQLite INTEGER primary key is always auto-increment.
+ */
+ $identity = (bool) ($row[$type] == 'INTEGER');
+ ++$p;
+ }
+ $desc[$this->foldCase($row[$name])] = array(
+ 'SCHEMA_NAME' => $this->foldCase($schemaName),
+ 'TABLE_NAME' => $this->foldCase($tableName),
+ 'COLUMN_NAME' => $this->foldCase($row[$name]),
+ 'COLUMN_POSITION' => $row[$cid]+1,
+ 'DATA_TYPE' => $row[$type],
+ 'DEFAULT' => $row[$dflt_value],
+ 'NULLABLE' => ! (bool) $row[$notnull],
+ 'LENGTH' => $length,
+ 'SCALE' => $scale,
+ 'PRECISION' => $precision,
+ 'UNSIGNED' => null, // Sqlite3 does not support unsigned data
+ 'PRIMARY' => $primary,
+ 'PRIMARY_POSITION' => $primaryPosition,
+ 'IDENTITY' => $identity
+ );
+ }
+ return $desc;
+ }
+
+ /**
+ * Adds an adapter-specific LIMIT clause to the SELECT statement.
+ *
+ * @param string $sql
+ * @param integer $count
+ * @param integer $offset OPTIONAL
+ * @return string
+ */
+ public function limit($sql, $count, $offset = 0)
+ {
+ $count = intval($count);
+ if ($count <= 0) {
+ /** @see Zend_Db_Adapter_Exception */
+ throw new Zend_Db_Adapter_Exception("LIMIT argument count=$count is not valid");
+ }
+
+ $offset = intval($offset);
+ if ($offset < 0) {
+ /** @see Zend_Db_Adapter_Exception */
+ throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid");
+ }
+
+ $sql .= " LIMIT $count";
+ if ($offset > 0) {
+ $sql .= " OFFSET $offset";
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Quote a raw string.
+ *
+ * @param string $value Raw string
+ * @return string Quoted string
+ */
+ protected function _quote($value)
+ {
+ if (!is_int($value) && !is_float($value)) {
+ // Fix for null-byte injection
+ $value = addcslashes($value, "\000\032");
+ }
+ return parent::_quote($value);
+ }
+}
diff --git a/library/vendor/Zend/Db/Adapter/Sqlsrv.php b/library/vendor/Zend/Db/Adapter/Sqlsrv.php
new file mode 100644
index 0000000..ce3324f
--- /dev/null
+++ b/library/vendor/Zend/Db/Adapter/Sqlsrv.php
@@ -0,0 +1,662 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * @see Zend_Db_Adapter_Abstract
+ */
+
+/**
+ * @see Zend_Db_Statement_Sqlsrv
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Adapter_Sqlsrv extends Zend_Db_Adapter_Abstract
+{
+ /**
+ * User-provided configuration.
+ *
+ * Basic keys are:
+ *
+ * username => (string) Connect to the database as this username.
+ * password => (string) Password associated with the username.
+ * dbname => The name of the local SQL Server instance
+ *
+ * @var array
+ */
+ protected $_config = array(
+ 'dbname' => null,
+ 'username' => null,
+ 'password' => null,
+ );
+
+ /**
+ * Last insert id from INSERT query
+ *
+ * @var int
+ */
+ protected $_lastInsertId;
+
+ /**
+ * Query used to fetch last insert id
+ *
+ * @var string
+ */
+ protected $_lastInsertSQL = 'SELECT SCOPE_IDENTITY() as Current_Identity';
+
+ /**
+ * Keys are UPPERCASE SQL datatypes or the constants
+ * Zend_Db::INT_TYPE, Zend_Db::BIGINT_TYPE, or Zend_Db::FLOAT_TYPE.
+ *
+ * Values are:
+ * 0 = 32-bit integer
+ * 1 = 64-bit integer
+ * 2 = float or decimal
+ *
+ * @var array Associative array of datatypes to values 0, 1, or 2.
+ */
+ protected $_numericDataTypes = array(
+ Zend_Db::INT_TYPE => Zend_Db::INT_TYPE,
+ Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE,
+ Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE,
+ 'INT' => Zend_Db::INT_TYPE,
+ 'SMALLINT' => Zend_Db::INT_TYPE,
+ 'TINYINT' => Zend_Db::INT_TYPE,
+ 'BIGINT' => Zend_Db::BIGINT_TYPE,
+ 'DECIMAL' => Zend_Db::FLOAT_TYPE,
+ 'FLOAT' => Zend_Db::FLOAT_TYPE,
+ 'MONEY' => Zend_Db::FLOAT_TYPE,
+ 'NUMERIC' => Zend_Db::FLOAT_TYPE,
+ 'REAL' => Zend_Db::FLOAT_TYPE,
+ 'SMALLMONEY' => Zend_Db::FLOAT_TYPE,
+ );
+
+ /**
+ * Default class name for a DB statement.
+ *
+ * @var string
+ */
+ protected $_defaultStmtClass = 'Zend_Db_Statement_Sqlsrv';
+
+ /**
+ * Creates a connection resource.
+ *
+ * @return void
+ * @throws Zend_Db_Adapter_Sqlsrv_Exception
+ */
+ protected function _connect()
+ {
+ if (is_resource($this->_connection)) {
+ // connection already exists
+ return;
+ }
+
+ if (!extension_loaded('sqlsrv')) {
+ /**
+ * @see Zend_Db_Adapter_Sqlsrv_Exception
+ */
+ throw new Zend_Db_Adapter_Sqlsrv_Exception('The Sqlsrv extension is required for this adapter but the extension is not loaded');
+ }
+
+ $serverName = $this->_config['host'];
+ if (isset($this->_config['port'])) {
+ $port = (integer) $this->_config['port'];
+ $serverName .= ', ' . $port;
+ }
+
+ $connectionInfo = array(
+ 'Database' => $this->_config['dbname'],
+ );
+
+ if (isset($this->_config['username']) && isset($this->_config['password']))
+ {
+ $connectionInfo += array(
+ 'UID' => $this->_config['username'],
+ 'PWD' => $this->_config['password'],
+ );
+ }
+ // else - windows authentication
+
+ if (!empty($this->_config['driver_options'])) {
+ foreach ($this->_config['driver_options'] as $option => $value) {
+ // A value may be a constant.
+ if (is_string($value)) {
+ $constantName = strtoupper($value);
+ if (defined($constantName)) {
+ $connectionInfo[$option] = constant($constantName);
+ } else {
+ $connectionInfo[$option] = $value;
+ }
+ }
+ }
+ }
+
+ $this->_connection = sqlsrv_connect($serverName, $connectionInfo);
+
+ if (!$this->_connection) {
+ /**
+ * @see Zend_Db_Adapter_Sqlsrv_Exception
+ */
+ throw new Zend_Db_Adapter_Sqlsrv_Exception(sqlsrv_errors());
+ }
+ }
+
+ /**
+ * Check for config options that are mandatory.
+ * Throw exceptions if any are missing.
+ *
+ * @param array $config
+ * @throws Zend_Db_Adapter_Exception
+ */
+ protected function _checkRequiredOptions(array $config)
+ {
+ // we need at least a dbname
+ if (! array_key_exists('dbname', $config)) {
+ /** @see Zend_Db_Adapter_Exception */
+ throw new Zend_Db_Adapter_Exception("Configuration array must have a key for 'dbname' that names the database instance");
+ }
+
+ if (! array_key_exists('password', $config) && array_key_exists('username', $config)) {
+ /**
+ * @see Zend_Db_Adapter_Exception
+ */
+ throw new Zend_Db_Adapter_Exception("Configuration array must have a key for 'password' for login credentials.
+ If Windows Authentication is desired, both keys 'username' and 'password' should be ommited from config.");
+ }
+
+ if (array_key_exists('password', $config) && !array_key_exists('username', $config)) {
+ /**
+ * @see Zend_Db_Adapter_Exception
+ */
+ throw new Zend_Db_Adapter_Exception("Configuration array must have a key for 'username' for login credentials.
+ If Windows Authentication is desired, both keys 'username' and 'password' should be ommited from config.");
+ }
+ }
+
+ /**
+ * Set the transaction isoltion level.
+ *
+ * @param integer|null $level A fetch mode from SQLSRV_TXN_*.
+ * @return true
+ * @throws Zend_Db_Adapter_Sqlsrv_Exception
+ */
+ public function setTransactionIsolationLevel($level = null)
+ {
+ $this->_connect();
+ $sql = null;
+
+ // Default transaction level in sql server
+ if ($level === null)
+ {
+ $level = SQLSRV_TXN_READ_COMMITTED;
+ }
+
+ switch ($level) {
+ case SQLSRV_TXN_READ_UNCOMMITTED:
+ $sql = "READ UNCOMMITTED";
+ break;
+ case SQLSRV_TXN_READ_COMMITTED:
+ $sql = "READ COMMITTED";
+ break;
+ case SQLSRV_TXN_REPEATABLE_READ:
+ $sql = "REPEATABLE READ";
+ break;
+ case SQLSRV_TXN_SNAPSHOT:
+ $sql = "SNAPSHOT";
+ break;
+ case SQLSRV_TXN_SERIALIZABLE:
+ $sql = "SERIALIZABLE";
+ break;
+ default:
+ throw new Zend_Db_Adapter_Sqlsrv_Exception("Invalid transaction isolation level mode '$level' specified");
+ }
+
+ if (!sqlsrv_query($this->_connection, "SET TRANSACTION ISOLATION LEVEL $sql;")) {
+ throw new Zend_Db_Adapter_Sqlsrv_Exception("Transaction cannot be changed to '$level'");
+ }
+
+ return true;
+ }
+
+ /**
+ * Test if a connection is active
+ *
+ * @return boolean
+ */
+ public function isConnected()
+ {
+ return (is_resource($this->_connection)
+ && (get_resource_type($this->_connection) == 'SQL Server Connection')
+ );
+ }
+
+ /**
+ * Force the connection to close.
+ *
+ * @return void
+ */
+ public function closeConnection()
+ {
+ if ($this->isConnected()) {
+ sqlsrv_close($this->_connection);
+ }
+ $this->_connection = null;
+ }
+
+ /**
+ * Returns an SQL statement for preparation.
+ *
+ * @param string $sql The SQL statement with placeholders.
+ * @return Zend_Db_Statement_Sqlsrv
+ */
+ public function prepare($sql)
+ {
+ $this->_connect();
+ $stmtClass = $this->_defaultStmtClass;
+
+ if (!class_exists($stmtClass)) {
+ /**
+ * @see Zend_Loader
+ */
+ Zend_Loader::loadClass($stmtClass);
+ }
+
+ $stmt = new $stmtClass($this, $sql);
+ $stmt->setFetchMode($this->_fetchMode);
+ return $stmt;
+ }
+
+ /**
+ * Quote a raw string.
+ *
+ * @param string $value Raw string
+ * @return string Quoted string
+ */
+ protected function _quote($value)
+ {
+ if (is_int($value)) {
+ return $value;
+ } elseif (is_float($value)) {
+ return sprintf('%F', $value);
+ }
+
+ $value = addcslashes($value, "\000\032");
+ return "'" . str_replace("'", "''", $value) . "'";
+ }
+
+ /**
+ * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column.
+ *
+ * As a convention, on RDBMS brands that support sequences
+ * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence
+ * from the arguments and returns the last id generated by that sequence.
+ * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method
+ * returns the last value generated for such a column, and the table name
+ * argument is disregarded.
+ *
+ * @param string $tableName OPTIONAL Name of table.
+ * @param string $primaryKey OPTIONAL Name of primary key column.
+ * @return string
+ */
+ public function lastInsertId($tableName = null, $primaryKey = null)
+ {
+ if ($tableName) {
+ $tableName = $this->quote($tableName);
+ $sql = 'SELECT IDENT_CURRENT (' . $tableName . ') as Current_Identity';
+ return (string) $this->fetchOne($sql);
+ }
+
+ if ($this->_lastInsertId > 0) {
+ return (string) $this->_lastInsertId;
+ }
+
+ $sql = $this->_lastInsertSQL;
+ return (string) $this->fetchOne($sql);
+ }
+
+ /**
+ * Inserts a table row with specified data.
+ *
+ * @param mixed $table The table to insert data into.
+ * @param array $bind Column-value pairs.
+ * @return int The number of affected rows.
+ */
+ public function insert($table, array $bind)
+ {
+ // extract and quote col names from the array keys
+ $cols = array();
+ $vals = array();
+ foreach ($bind as $col => $val) {
+ $cols[] = $this->quoteIdentifier($col, true);
+ if ($val instanceof Zend_Db_Expr) {
+ $vals[] = $val->__toString();
+ unset($bind[$col]);
+ } else {
+ $vals[] = '?';
+ }
+ }
+
+ // build the statement
+ $sql = "INSERT INTO "
+ . $this->quoteIdentifier($table, true)
+ . ' (' . implode(', ', $cols) . ') '
+ . 'VALUES (' . implode(', ', $vals) . ')'
+ . ' ' . $this->_lastInsertSQL;
+
+ // execute the statement and return the number of affected rows
+ $stmt = $this->query($sql, array_values($bind));
+ $result = $stmt->rowCount();
+
+ $stmt->nextRowset();
+
+ $this->_lastInsertId = $stmt->fetchColumn();
+
+ return $result;
+ }
+
+ /**
+ * Returns a list of the tables in the database.
+ *
+ * @return array
+ */
+ public function listTables()
+ {
+ $this->_connect();
+ $sql = "SELECT name FROM sysobjects WHERE type = 'U' ORDER BY name";
+ return $this->fetchCol($sql);
+ }
+
+ /**
+ * Returns the column descriptions for a table.
+ *
+ * The return value is an associative array keyed by the column name,
+ * as returned by the RDBMS.
+ *
+ * The value of each array element is an associative array
+ * with the following keys:
+ *
+ * SCHEMA_NAME => string; name of schema
+ * TABLE_NAME => string;
+ * COLUMN_NAME => string; column name
+ * COLUMN_POSITION => number; ordinal position of column in table
+ * DATA_TYPE => string; SQL datatype name of column
+ * DEFAULT => string; default expression of column, null if none
+ * NULLABLE => boolean; true if column can have nulls
+ * LENGTH => number; length of CHAR/VARCHAR
+ * SCALE => number; scale of NUMERIC/DECIMAL
+ * PRECISION => number; precision of NUMERIC/DECIMAL
+ * UNSIGNED => boolean; unsigned property of an integer type
+ * PRIMARY => boolean; true if column is part of the primary key
+ * PRIMARY_POSITION => integer; position of column in primary key
+ * IDENTITY => integer; true if column is auto-generated with unique values
+ *
+ * @todo Discover integer unsigned property.
+ *
+ * @param string $tableName
+ * @param string $schemaName OPTIONAL
+ * @return array
+ */
+ public function describeTable($tableName, $schemaName = null)
+ {
+ /**
+ * Discover metadata information about this table.
+ */
+ $sql = "exec sp_columns @table_name = " . $this->quoteIdentifier($tableName, true);
+ $stmt = $this->query($sql);
+ $result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
+
+ // ZF-7698
+ $stmt->closeCursor();
+
+ if (count($result) == 0) {
+ return array();
+ }
+
+ $owner = 1;
+ $table_name = 2;
+ $column_name = 3;
+ $type_name = 5;
+ $precision = 6;
+ $length = 7;
+ $scale = 8;
+ $nullable = 10;
+ $column_def = 12;
+ $column_position = 16;
+
+ /**
+ * Discover primary key column(s) for this table.
+ */
+ $tableOwner = $result[0][$owner];
+ $sql = "exec sp_pkeys @table_owner = " . $tableOwner
+ . ", @table_name = " . $this->quoteIdentifier($tableName, true);
+ $stmt = $this->query($sql);
+
+ $primaryKeysResult = $stmt->fetchAll(Zend_Db::FETCH_NUM);
+ $primaryKeyColumn = array();
+
+ // Per http://msdn.microsoft.com/en-us/library/ms189813.aspx,
+ // results from sp_keys stored procedure are:
+ // 0=TABLE_QUALIFIER 1=TABLE_OWNER 2=TABLE_NAME 3=COLUMN_NAME 4=KEY_SEQ 5=PK_NAME
+
+ $pkey_column_name = 3;
+ $pkey_key_seq = 4;
+ foreach ($primaryKeysResult as $pkeysRow) {
+ $primaryKeyColumn[$pkeysRow[$pkey_column_name]] = $pkeysRow[$pkey_key_seq];
+ }
+
+ $desc = array();
+ $p = 1;
+ foreach ($result as $key => $row) {
+ $identity = false;
+ $words = explode(' ', $row[$type_name], 2);
+ if (isset($words[0])) {
+ $type = $words[0];
+ if (isset($words[1])) {
+ $identity = (bool) preg_match('/identity/', $words[1]);
+ }
+ }
+
+ $isPrimary = array_key_exists($row[$column_name], $primaryKeyColumn);
+ if ($isPrimary) {
+ $primaryPosition = $primaryKeyColumn[$row[$column_name]];
+ } else {
+ $primaryPosition = null;
+ }
+
+ $desc[$this->foldCase($row[$column_name])] = array(
+ 'SCHEMA_NAME' => null, // @todo
+ 'TABLE_NAME' => $this->foldCase($row[$table_name]),
+ 'COLUMN_NAME' => $this->foldCase($row[$column_name]),
+ 'COLUMN_POSITION' => (int) $row[$column_position],
+ 'DATA_TYPE' => $type,
+ 'DEFAULT' => $row[$column_def],
+ 'NULLABLE' => (bool) $row[$nullable],
+ 'LENGTH' => $row[$length],
+ 'SCALE' => $row[$scale],
+ 'PRECISION' => $row[$precision],
+ 'UNSIGNED' => null, // @todo
+ 'PRIMARY' => $isPrimary,
+ 'PRIMARY_POSITION' => $primaryPosition,
+ 'IDENTITY' => $identity,
+ );
+ }
+
+ return $desc;
+ }
+
+ /**
+ * Leave autocommit mode and begin a transaction.
+ *
+ * @return void
+ * @throws Zend_Db_Adapter_Sqlsrv_Exception
+ */
+ protected function _beginTransaction()
+ {
+ if (!sqlsrv_begin_transaction($this->_connection)) {
+ throw new Zend_Db_Adapter_Sqlsrv_Exception(sqlsrv_errors());
+ }
+ }
+
+ /**
+ * Commit a transaction and return to autocommit mode.
+ *
+ * @return void
+ * @throws Zend_Db_Adapter_Sqlsrv_Exception
+ */
+ protected function _commit()
+ {
+ if (!sqlsrv_commit($this->_connection)) {
+ throw new Zend_Db_Adapter_Sqlsrv_Exception(sqlsrv_errors());
+ }
+ }
+
+ /**
+ * Roll back a transaction and return to autocommit mode.
+ *
+ * @return void
+ * @throws Zend_Db_Adapter_Sqlsrv_Exception
+ */
+ protected function _rollBack()
+ {
+ if (!sqlsrv_rollback($this->_connection)) {
+ throw new Zend_Db_Adapter_Sqlsrv_Exception(sqlsrv_errors());
+ }
+ }
+
+ /**
+ * Set the fetch mode.
+ *
+ * @todo Support FETCH_CLASS and FETCH_INTO.
+ *
+ * @param integer $mode A fetch mode.
+ * @return void
+ * @throws Zend_Db_Adapter_Sqlsrv_Exception
+ */
+ public function setFetchMode($mode)
+ {
+ switch ($mode) {
+ case Zend_Db::FETCH_NUM: // seq array
+ case Zend_Db::FETCH_ASSOC: // assoc array
+ case Zend_Db::FETCH_BOTH: // seq+assoc array
+ case Zend_Db::FETCH_OBJ: // object
+ $this->_fetchMode = $mode;
+ break;
+ case Zend_Db::FETCH_BOUND: // bound to PHP variable
+ throw new Zend_Db_Adapter_Sqlsrv_Exception('FETCH_BOUND is not supported yet');
+ break;
+ default:
+ throw new Zend_Db_Adapter_Sqlsrv_Exception("Invalid fetch mode '$mode' specified");
+ break;
+ }
+ }
+
+ /**
+ * Adds an adapter-specific LIMIT clause to the SELECT statement.
+ *
+ * @param string $sql
+ * @param integer $count
+ * @param integer $offset OPTIONAL
+ * @return string
+ * @throws Zend_Db_Adapter_Sqlsrv_Exception
+ */
+ public function limit($sql, $count, $offset = 0)
+ {
+ $count = intval($count);
+ if ($count <= 0) {
+ throw new Zend_Db_Adapter_Exception("LIMIT argument count=$count is not valid");
+ }
+
+ $offset = intval($offset);
+ if ($offset < 0) {
+ /** @see Zend_Db_Adapter_Exception */
+ throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid");
+ }
+
+ if ($offset == 0) {
+ $sql = preg_replace('/^SELECT\s/i', 'SELECT TOP ' . $count . ' ', $sql);
+ } else {
+ $orderby = stristr($sql, 'ORDER BY');
+
+ if (!$orderby) {
+ $over = 'ORDER BY (SELECT 0)';
+ } else {
+ $over = preg_replace('/\"[^,]*\".\"([^,]*)\"/i', '"inner_tbl"."$1"', $orderby);
+ }
+
+ // Remove ORDER BY clause from $sql
+ $sql = preg_replace('/\s+ORDER BY(.*)/', '', $sql);
+
+ // Add ORDER BY clause as an argument for ROW_NUMBER()
+ $sql = "SELECT ROW_NUMBER() OVER ($over) AS \"ZEND_DB_ROWNUM\", * FROM ($sql) AS inner_tbl";
+
+ $start = $offset + 1;
+
+ if ($count == PHP_INT_MAX) {
+ $sql = "WITH outer_tbl AS ($sql) SELECT * FROM outer_tbl WHERE \"ZEND_DB_ROWNUM\" >= $start";
+ }
+ else {
+ $end = $offset + $count;
+ $sql = "WITH outer_tbl AS ($sql) SELECT * FROM outer_tbl WHERE \"ZEND_DB_ROWNUM\" BETWEEN $start AND $end";
+ }
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Check if the adapter supports real SQL parameters.
+ *
+ * @param string $type 'positional' or 'named'
+ * @return bool
+ */
+ public function supportsParameters($type)
+ {
+ if ($type == 'positional') {
+ return true;
+ }
+
+ // if its 'named' or anything else
+ return false;
+ }
+
+ /**
+ * Retrieve server version in PHP style
+ *
+ * @return string
+ */
+ public function getServerVersion()
+ {
+ $this->_connect();
+ $serverInfo = sqlsrv_server_info($this->_connection);
+
+ if ($serverInfo !== false) {
+ return $serverInfo['SQLServerVersion'];
+ }
+
+ return null;
+ }
+}
diff --git a/library/vendor/Zend/Db/Adapter/Sqlsrv/Exception.php b/library/vendor/Zend/Db/Adapter/Sqlsrv/Exception.php
new file mode 100644
index 0000000..2bbc84d
--- /dev/null
+++ b/library/vendor/Zend/Db/Adapter/Sqlsrv/Exception.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * @see Zend_Db_Adapter_Exception
+ */
+
+/**
+ * Zend_Db_Adapter_Sqlsrv_Exception
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Adapter_Sqlsrv_Exception extends Zend_Db_Adapter_Exception
+{
+ /**
+ * Constructor
+ *
+ * If $message is an array, the assumption is that the return value of
+ * sqlsrv_errors() was provided. If so, it then retrieves the most recent
+ * error from that stack, and sets the message and code based on it.
+ *
+ * @param null|array|string $message
+ * @param null|int $code
+ */
+ public function __construct($message = null, $code = 0)
+ {
+ if (is_array($message)) {
+ // Error should be array of errors
+ // We only need first one (?)
+ if (isset($message[0])) {
+ $message = $message[0];
+ }
+
+ $code = (int) $message['code'];
+ $message = (string) $message['message'];
+ }
+ parent::__construct($message, $code, new Exception($message, $code));
+ }
+}
diff --git a/library/vendor/Zend/Db/Exception.php b/library/vendor/Zend/Db/Exception.php
new file mode 100644
index 0000000..837c473
--- /dev/null
+++ b/library/vendor/Zend/Db/Exception.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * Zend_Exception
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Db
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Exception extends Zend_Exception
+{
+}
diff --git a/library/vendor/Zend/Db/Expr.php b/library/vendor/Zend/Db/Expr.php
new file mode 100644
index 0000000..d8843a4
--- /dev/null
+++ b/library/vendor/Zend/Db/Expr.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Expr
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+
+/**
+ * Class for SQL SELECT fragments.
+ *
+ * This class simply holds a string, so that fragments of SQL statements can be
+ * distinguished from identifiers and values that should be implicitly quoted
+ * when interpolated into SQL statements.
+ *
+ * For example, when specifying a primary key value when inserting into a new
+ * row, some RDBMS brands may require you to use an expression to generate the
+ * new value of a sequence. If this expression is treated as an identifier,
+ * it will be quoted and the expression will not be evaluated. Another example
+ * is that you can use Zend_Db_Expr in the Zend_Db_Select::order() method to
+ * order by an expression instead of simply a column name.
+ *
+ * The way this works is that in each context in which a column name can be
+ * specified to methods of Zend_Db classes, if the value is an instance of
+ * Zend_Db_Expr instead of a plain string, then the expression is not quoted.
+ * If it is a plain string, it is assumed to be a plain column name.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Expr
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Expr
+{
+ /**
+ * Storage for the SQL expression.
+ *
+ * @var string
+ */
+ protected $_expression;
+
+ /**
+ * Instantiate an expression, which is just a string stored as
+ * an instance member variable.
+ *
+ * @param string $expression The string containing a SQL expression.
+ */
+ public function __construct($expression)
+ {
+ $this->_expression = (string) $expression;
+ }
+
+ /**
+ * @return string The string of the SQL expression stored in this object.
+ */
+ public function __toString()
+ {
+ return $this->_expression;
+ }
+
+}
diff --git a/library/vendor/Zend/Db/Profiler.php b/library/vendor/Zend/Db/Profiler.php
new file mode 100644
index 0000000..c80ec5d
--- /dev/null
+++ b/library/vendor/Zend/Db/Profiler.php
@@ -0,0 +1,469 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Profiler
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+
+/**
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Profiler
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Profiler
+{
+
+ /**
+ * A connection operation or selecting a database.
+ */
+ const CONNECT = 1;
+
+ /**
+ * Any general database query that does not fit into the other constants.
+ */
+ const QUERY = 2;
+
+ /**
+ * Adding new data to the database, such as SQL's INSERT.
+ */
+ const INSERT = 4;
+
+ /**
+ * Updating existing information in the database, such as SQL's UPDATE.
+ *
+ */
+ const UPDATE = 8;
+
+ /**
+ * An operation related to deleting data in the database,
+ * such as SQL's DELETE.
+ */
+ const DELETE = 16;
+
+ /**
+ * Retrieving information from the database, such as SQL's SELECT.
+ */
+ const SELECT = 32;
+
+ /**
+ * Transactional operation, such as start transaction, commit, or rollback.
+ */
+ const TRANSACTION = 64;
+
+ /**
+ * Inform that a query is stored (in case of filtering)
+ */
+ const STORED = 'stored';
+
+ /**
+ * Inform that a query is ignored (in case of filtering)
+ */
+ const IGNORED = 'ignored';
+
+ /**
+ * Array of Zend_Db_Profiler_Query objects.
+ *
+ * @var array
+ */
+ protected $_queryProfiles = array();
+
+ /**
+ * Stores enabled state of the profiler. If set to False, calls to
+ * queryStart() will simply be ignored.
+ *
+ * @var boolean
+ */
+ protected $_enabled = false;
+
+ /**
+ * Stores the number of seconds to filter. NULL if filtering by time is
+ * disabled. If an integer is stored here, profiles whose elapsed time
+ * is less than this value in seconds will be unset from
+ * the self::$_queryProfiles array.
+ *
+ * @var integer
+ */
+ protected $_filterElapsedSecs = null;
+
+ /**
+ * Logical OR of any of the filter constants. NULL if filtering by query
+ * type is disable. If an integer is stored here, it is the logical OR of
+ * any of the query type constants. When the query ends, if it is not
+ * one of the types specified, it will be unset from the
+ * self::$_queryProfiles array.
+ *
+ * @var integer
+ */
+ protected $_filterTypes = null;
+
+ /**
+ * Class constructor. The profiler is disabled by default unless it is
+ * specifically enabled by passing in $enabled here or calling setEnabled().
+ *
+ * @param boolean $enabled
+ * @return void
+ */
+ public function __construct($enabled = false)
+ {
+ $this->setEnabled($enabled);
+ }
+
+ /**
+ * Enable or disable the profiler. If $enable is false, the profiler
+ * is disabled and will not log any queries sent to it.
+ *
+ * @param boolean $enable
+ * @return Zend_Db_Profiler Provides a fluent interface
+ */
+ public function setEnabled($enable)
+ {
+ $this->_enabled = (boolean) $enable;
+
+ return $this;
+ }
+
+ /**
+ * Get the current state of enable. If True is returned,
+ * the profiler is enabled.
+ *
+ * @return boolean
+ */
+ public function getEnabled()
+ {
+ return $this->_enabled;
+ }
+
+ /**
+ * Sets a minimum number of seconds for saving query profiles. If this
+ * is set, only those queries whose elapsed time is equal or greater than
+ * $minimumSeconds will be saved. To save all queries regardless of
+ * elapsed time, set $minimumSeconds to null.
+ *
+ * @param integer $minimumSeconds OPTIONAL
+ * @return Zend_Db_Profiler Provides a fluent interface
+ */
+ public function setFilterElapsedSecs($minimumSeconds = null)
+ {
+ if (null === $minimumSeconds) {
+ $this->_filterElapsedSecs = null;
+ } else {
+ $this->_filterElapsedSecs = (integer) $minimumSeconds;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns the minimum number of seconds for saving query profiles, or null if
+ * query profiles are saved regardless of elapsed time.
+ *
+ * @return integer|null
+ */
+ public function getFilterElapsedSecs()
+ {
+ return $this->_filterElapsedSecs;
+ }
+
+ /**
+ * Sets the types of query profiles to save. Set $queryType to one of
+ * the Zend_Db_Profiler::* constants to only save profiles for that type of
+ * query. To save more than one type, logical OR them together. To
+ * save all queries regardless of type, set $queryType to null.
+ *
+ * @param integer $queryTypes OPTIONAL
+ * @return Zend_Db_Profiler Provides a fluent interface
+ */
+ public function setFilterQueryType($queryTypes = null)
+ {
+ $this->_filterTypes = $queryTypes;
+
+ return $this;
+ }
+
+ /**
+ * Returns the types of query profiles saved, or null if queries are saved regardless
+ * of their types.
+ *
+ * @return integer|null
+ * @see Zend_Db_Profiler::setFilterQueryType()
+ */
+ public function getFilterQueryType()
+ {
+ return $this->_filterTypes;
+ }
+
+ /**
+ * Clears the history of any past query profiles. This is relentless
+ * and will even clear queries that were started and may not have
+ * been marked as ended.
+ *
+ * @return Zend_Db_Profiler Provides a fluent interface
+ */
+ public function clear()
+ {
+ $this->_queryProfiles = array();
+
+ return $this;
+ }
+
+ /**
+ * Clone a profiler query
+ *
+ * @param Zend_Db_Profiler_Query $query
+ * @return integer or null
+ */
+ public function queryClone(Zend_Db_Profiler_Query $query)
+ {
+ $this->_queryProfiles[] = clone $query;
+
+ end($this->_queryProfiles);
+
+ return key($this->_queryProfiles);
+ }
+
+ /**
+ * Starts a query. Creates a new query profile object (Zend_Db_Profiler_Query)
+ * and returns the "query profiler handle". Run the query, then call
+ * queryEnd() and pass it this handle to make the query as ended and
+ * record the time. If the profiler is not enabled, this takes no
+ * action and immediately returns null.
+ *
+ * @param string $queryText SQL statement
+ * @param integer $queryType OPTIONAL Type of query, one of the Zend_Db_Profiler::* constants
+ * @return integer|null
+ */
+ public function queryStart($queryText, $queryType = null)
+ {
+ if (!$this->_enabled) {
+ return null;
+ }
+
+ // make sure we have a query type
+ if (null === $queryType) {
+ switch (strtolower(substr(ltrim($queryText), 0, 6))) {
+ case 'insert':
+ $queryType = self::INSERT;
+ break;
+ case 'update':
+ $queryType = self::UPDATE;
+ break;
+ case 'delete':
+ $queryType = self::DELETE;
+ break;
+ case 'select':
+ $queryType = self::SELECT;
+ break;
+ default:
+ $queryType = self::QUERY;
+ break;
+ }
+ }
+
+ /**
+ * @see Zend_Db_Profiler_Query
+ */
+ $this->_queryProfiles[] = new Zend_Db_Profiler_Query($queryText, $queryType);
+
+ end($this->_queryProfiles);
+
+ return key($this->_queryProfiles);
+ }
+
+ /**
+ * Ends a query. Pass it the handle that was returned by queryStart().
+ * This will mark the query as ended and save the time.
+ *
+ * @param integer $queryId
+ * @throws Zend_Db_Profiler_Exception
+ * @return string Inform that a query is stored or ignored.
+ */
+ public function queryEnd($queryId)
+ {
+ // Don't do anything if the Zend_Db_Profiler is not enabled.
+ if (!$this->_enabled) {
+ return self::IGNORED;
+ }
+
+ // Check for a valid query handle.
+ if (!isset($this->_queryProfiles[$queryId])) {
+ /**
+ * @see Zend_Db_Profiler_Exception
+ */
+ throw new Zend_Db_Profiler_Exception("Profiler has no query with handle '$queryId'.");
+ }
+
+ $qp = $this->_queryProfiles[$queryId];
+
+ // Ensure that the query profile has not already ended
+ if ($qp->hasEnded()) {
+ /**
+ * @see Zend_Db_Profiler_Exception
+ */
+ throw new Zend_Db_Profiler_Exception("Query with profiler handle '$queryId' has already ended.");
+ }
+
+ // End the query profile so that the elapsed time can be calculated.
+ $qp->end();
+
+ /**
+ * If filtering by elapsed time is enabled, only keep the profile if
+ * it ran for the minimum time.
+ */
+ if (null !== $this->_filterElapsedSecs && $qp->getElapsedSecs() < $this->_filterElapsedSecs) {
+ unset($this->_queryProfiles[$queryId]);
+ return self::IGNORED;
+ }
+
+ /**
+ * If filtering by query type is enabled, only keep the query if
+ * it was one of the allowed types.
+ */
+ if (null !== $this->_filterTypes && !($qp->getQueryType() & $this->_filterTypes)) {
+ unset($this->_queryProfiles[$queryId]);
+ return self::IGNORED;
+ }
+
+ return self::STORED;
+ }
+
+ /**
+ * Get a profile for a query. Pass it the same handle that was returned
+ * by queryStart() and it will return a Zend_Db_Profiler_Query object.
+ *
+ * @param integer $queryId
+ * @throws Zend_Db_Profiler_Exception
+ * @return Zend_Db_Profiler_Query
+ */
+ public function getQueryProfile($queryId)
+ {
+ if (!array_key_exists($queryId, $this->_queryProfiles)) {
+ /**
+ * @see Zend_Db_Profiler_Exception
+ */
+ throw new Zend_Db_Profiler_Exception("Query handle '$queryId' not found in profiler log.");
+ }
+
+ return $this->_queryProfiles[$queryId];
+ }
+
+ /**
+ * Get an array of query profiles (Zend_Db_Profiler_Query objects). If $queryType
+ * is set to one of the Zend_Db_Profiler::* constants then only queries of that
+ * type will be returned. Normally, queries that have not yet ended will
+ * not be returned unless $showUnfinished is set to True. If no
+ * queries were found, False is returned. The returned array is indexed by the query
+ * profile handles.
+ *
+ * @param integer $queryType
+ * @param boolean $showUnfinished
+ * @return array|false
+ */
+ public function getQueryProfiles($queryType = null, $showUnfinished = false)
+ {
+ $queryProfiles = array();
+ foreach ($this->_queryProfiles as $key => $qp) {
+ if ($queryType === null) {
+ $condition = true;
+ } else {
+ $condition = ($qp->getQueryType() & $queryType);
+ }
+
+ if (($qp->hasEnded() || $showUnfinished) && $condition) {
+ $queryProfiles[$key] = $qp;
+ }
+ }
+
+ if (empty($queryProfiles)) {
+ $queryProfiles = false;
+ }
+
+ return $queryProfiles;
+ }
+
+ /**
+ * Get the total elapsed time (in seconds) of all of the profiled queries.
+ * Only queries that have ended will be counted. If $queryType is set to
+ * one or more of the Zend_Db_Profiler::* constants, the elapsed time will be calculated
+ * only for queries of the given type(s).
+ *
+ * @param integer $queryType OPTIONAL
+ * @return float
+ */
+ public function getTotalElapsedSecs($queryType = null)
+ {
+ $elapsedSecs = 0;
+ foreach ($this->_queryProfiles as $key => $qp) {
+ if (null === $queryType) {
+ $condition = true;
+ } else {
+ $condition = ($qp->getQueryType() & $queryType);
+ }
+ if (($qp->hasEnded()) && $condition) {
+ $elapsedSecs += $qp->getElapsedSecs();
+ }
+ }
+ return $elapsedSecs;
+ }
+
+ /**
+ * Get the total number of queries that have been profiled. Only queries that have ended will
+ * be counted. If $queryType is set to one of the Zend_Db_Profiler::* constants, only queries of
+ * that type will be counted.
+ *
+ * @param integer $queryType OPTIONAL
+ * @return integer
+ */
+ public function getTotalNumQueries($queryType = null)
+ {
+ if (null === $queryType) {
+ return count($this->_queryProfiles);
+ }
+
+ $numQueries = 0;
+ foreach ($this->_queryProfiles as $qp) {
+ if ($qp->hasEnded() && ($qp->getQueryType() & $queryType)) {
+ $numQueries++;
+ }
+ }
+
+ return $numQueries;
+ }
+
+ /**
+ * Get the Zend_Db_Profiler_Query object for the last query that was run, regardless if it has
+ * ended or not. If the query has not ended, its end time will be null. If no queries have
+ * been profiled, false is returned.
+ *
+ * @return Zend_Db_Profiler_Query|false
+ */
+ public function getLastQueryProfile()
+ {
+ if (empty($this->_queryProfiles)) {
+ return false;
+ }
+
+ end($this->_queryProfiles);
+
+ return current($this->_queryProfiles);
+ }
+
+}
+
diff --git a/library/vendor/Zend/Db/Profiler/Exception.php b/library/vendor/Zend/Db/Profiler/Exception.php
new file mode 100644
index 0000000..c2f76fa
--- /dev/null
+++ b/library/vendor/Zend/Db/Profiler/Exception.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Profiler
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+
+/**
+ * @see Zend_Db_Exception
+ */
+
+
+/**
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Profiler
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Profiler_Exception extends Zend_Db_Exception
+{
+}
+
diff --git a/library/vendor/Zend/Db/Profiler/Query.php b/library/vendor/Zend/Db/Profiler/Query.php
new file mode 100644
index 0000000..97a7fef
--- /dev/null
+++ b/library/vendor/Zend/Db/Profiler/Query.php
@@ -0,0 +1,213 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Profiler
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+
+/**
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Profiler
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Profiler_Query
+{
+
+ /**
+ * SQL query string or user comment, set by $query argument in constructor.
+ *
+ * @var string
+ */
+ protected $_query = '';
+
+ /**
+ * One of the Zend_Db_Profiler constants for query type, set by $queryType argument in constructor.
+ *
+ * @var integer
+ */
+ protected $_queryType = 0;
+
+ /**
+ * Unix timestamp with microseconds when instantiated.
+ *
+ * @var float
+ */
+ protected $_startedMicrotime = null;
+
+ /**
+ * Unix timestamp with microseconds when self::queryEnd() was called.
+ *
+ * @var integer
+ */
+ protected $_endedMicrotime = null;
+
+ /**
+ * @var array
+ */
+ protected $_boundParams = array();
+
+ /**
+ * @var array
+ */
+
+ /**
+ * Class constructor. A query is about to be started, save the query text ($query) and its
+ * type (one of the Zend_Db_Profiler::* constants).
+ *
+ * @param string $query
+ * @param integer $queryType
+ * @return void
+ */
+ public function __construct($query, $queryType)
+ {
+ $this->_query = $query;
+ $this->_queryType = $queryType;
+ // by default, and for backward-compatibility, start the click ticking
+ $this->start();
+ }
+
+ /**
+ * Clone handler for the query object.
+ * @return void
+ */
+ public function __clone()
+ {
+ $this->_boundParams = array();
+ $this->_endedMicrotime = null;
+ $this->start();
+ }
+
+ /**
+ * Starts the elapsed time click ticking.
+ * This can be called subsequent to object creation,
+ * to restart the clock. For instance, this is useful
+ * right before executing a prepared query.
+ *
+ * @return void
+ */
+ public function start()
+ {
+ $this->_startedMicrotime = microtime(true);
+ }
+
+ /**
+ * Ends the query and records the time so that the elapsed time can be determined later.
+ *
+ * @return void
+ */
+ public function end()
+ {
+ $this->_endedMicrotime = microtime(true);
+ }
+
+ /**
+ * Returns true if and only if the query has ended.
+ *
+ * @return boolean
+ */
+ public function hasEnded()
+ {
+ return $this->_endedMicrotime !== null;
+ }
+
+ /**
+ * Get the original SQL text of the query.
+ *
+ * @return string
+ */
+ public function getQuery()
+ {
+ return $this->_query;
+ }
+
+ /**
+ * Get the type of this query (one of the Zend_Db_Profiler::* constants)
+ *
+ * @return integer
+ */
+ public function getQueryType()
+ {
+ return $this->_queryType;
+ }
+
+ /**
+ * @param string $param
+ * @param mixed $variable
+ * @return void
+ */
+ public function bindParam($param, $variable)
+ {
+ $this->_boundParams[$param] = $variable;
+ }
+
+ /**
+ * @param array $param
+ * @return void
+ */
+ public function bindParams(array $params)
+ {
+ if (array_key_exists(0, $params)) {
+ array_unshift($params, null);
+ unset($params[0]);
+ }
+ foreach ($params as $param => $value) {
+ $this->bindParam($param, $value);
+ }
+ }
+
+ /**
+ * @return array
+ */
+ public function getQueryParams()
+ {
+ return $this->_boundParams;
+ }
+
+ /**
+ * Get the elapsed time (in seconds) that the query ran.
+ * If the query has not yet ended, false is returned.
+ *
+ * @return float|false
+ */
+ public function getElapsedSecs()
+ {
+ if (null === $this->_endedMicrotime) {
+ return false;
+ }
+
+ return $this->_endedMicrotime - $this->_startedMicrotime;
+ }
+
+ /**
+ * Get the time (in seconds) when the profiler started running.
+ *
+ * @return bool|float
+ */
+ public function getStartedMicrotime()
+ {
+ if(null === $this->_startedMicrotime) {
+ return false;
+ }
+
+ return $this->_startedMicrotime;
+ }
+}
+
diff --git a/library/vendor/Zend/Db/Select.php b/library/vendor/Zend/Db/Select.php
new file mode 100644
index 0000000..64908e3
--- /dev/null
+++ b/library/vendor/Zend/Db/Select.php
@@ -0,0 +1,1368 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Select
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+
+/**
+ * @see Zend_Db_Adapter_Abstract
+ */
+
+/**
+ * @see Zend_Db_Expr
+ */
+
+
+/**
+ * Class for SQL SELECT generation and results.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Select
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Select
+{
+
+ const DISTINCT = 'distinct';
+ const COLUMNS = 'columns';
+ const FROM = 'from';
+ const UNION = 'union';
+ const WHERE = 'where';
+ const GROUP = 'group';
+ const HAVING = 'having';
+ const ORDER = 'order';
+ const LIMIT_COUNT = 'limitcount';
+ const LIMIT_OFFSET = 'limitoffset';
+ const FOR_UPDATE = 'forupdate';
+
+ const INNER_JOIN = 'inner join';
+ const LEFT_JOIN = 'left join';
+ const RIGHT_JOIN = 'right join';
+ const FULL_JOIN = 'full join';
+ const CROSS_JOIN = 'cross join';
+ const NATURAL_JOIN = 'natural join';
+
+ const SQL_WILDCARD = '*';
+ const SQL_SELECT = 'SELECT';
+ const SQL_UNION = 'UNION';
+ const SQL_UNION_ALL = 'UNION ALL';
+ const SQL_FROM = 'FROM';
+ const SQL_WHERE = 'WHERE';
+ const SQL_DISTINCT = 'DISTINCT';
+ const SQL_GROUP_BY = 'GROUP BY';
+ const SQL_ORDER_BY = 'ORDER BY';
+ const SQL_HAVING = 'HAVING';
+ const SQL_FOR_UPDATE = 'FOR UPDATE';
+ const SQL_AND = 'AND';
+ const SQL_AS = 'AS';
+ const SQL_OR = 'OR';
+ const SQL_ON = 'ON';
+ const SQL_ASC = 'ASC';
+ const SQL_DESC = 'DESC';
+
+ const REGEX_COLUMN_EXPR = '/^([\w]*\s*\(([^\(\)]|(?1))*\))$/';
+ const REGEX_COLUMN_EXPR_ORDER = '/^([\w]+\s*\(([^\(\)]|(?1))*\))$/';
+ const REGEX_COLUMN_EXPR_GROUP = '/^([\w]+\s*\(([^\(\)]|(?1))*\))$/';
+
+ // @see http://stackoverflow.com/a/13823184/2028814
+ const REGEX_SQL_COMMENTS = '@
+ (([\'"]).*?[^\\\]\2) # $1 : Skip single & double quoted expressions
+ |( # $3 : Match comments
+ (?:\#|--).*?$ # - Single line comments
+ | # - Multi line (nested) comments
+ /\* # . comment open marker
+ (?: [^/*] # . non comment-marker characters
+ |/(?!\*) # . ! not a comment open
+ |\*(?!/) # . ! not a comment close
+ |(?R) # . recursive case
+ )* # . repeat eventually
+ \*\/ # . comment close marker
+ )\s* # Trim after comments
+ |(?<=;)\s+ # Trim after semi-colon
+ @msx';
+
+ /**
+ * Bind variables for query
+ *
+ * @var array
+ */
+ protected $_bind = array();
+
+ /**
+ * Zend_Db_Adapter_Abstract object.
+ *
+ * @var Zend_Db_Adapter_Abstract
+ */
+ protected $_adapter;
+
+ /**
+ * The initial values for the $_parts array.
+ * NOTE: It is important for the 'FOR_UPDATE' part to be last to ensure
+ * meximum compatibility with database adapters.
+ *
+ * @var array
+ */
+ protected static $_partsInit = array(
+ self::DISTINCT => false,
+ self::COLUMNS => array(),
+ self::UNION => array(),
+ self::FROM => array(),
+ self::WHERE => array(),
+ self::GROUP => array(),
+ self::HAVING => array(),
+ self::ORDER => array(),
+ self::LIMIT_COUNT => null,
+ self::LIMIT_OFFSET => null,
+ self::FOR_UPDATE => false
+ );
+
+ /**
+ * Specify legal join types.
+ *
+ * @var array
+ */
+ protected static $_joinTypes = array(
+ self::INNER_JOIN,
+ self::LEFT_JOIN,
+ self::RIGHT_JOIN,
+ self::FULL_JOIN,
+ self::CROSS_JOIN,
+ self::NATURAL_JOIN,
+ );
+
+ /**
+ * Specify legal union types.
+ *
+ * @var array
+ */
+ protected static $_unionTypes = array(
+ self::SQL_UNION,
+ self::SQL_UNION_ALL
+ );
+
+ /**
+ * The component parts of a SELECT statement.
+ * Initialized to the $_partsInit array in the constructor.
+ *
+ * @var array
+ */
+ protected $_parts = array();
+
+ /**
+ * Tracks which columns are being select from each table and join.
+ *
+ * @var array
+ */
+ protected $_tableCols = array();
+
+ /**
+ * Class constructor
+ *
+ * @param Zend_Db_Adapter_Abstract $adapter
+ */
+ public function __construct(Zend_Db_Adapter_Abstract $adapter)
+ {
+ $this->_adapter = $adapter;
+ $this->_parts = self::$_partsInit;
+ }
+
+ /**
+ * Get bind variables
+ *
+ * @return array
+ */
+ public function getBind()
+ {
+ return $this->_bind;
+ }
+
+ /**
+ * Set bind variables
+ *
+ * @param mixed $bind
+ * @return Zend_Db_Select
+ */
+ public function bind($bind)
+ {
+ $this->_bind = $bind;
+
+ return $this;
+ }
+
+ /**
+ * Makes the query SELECT DISTINCT.
+ *
+ * @param bool $flag Whether or not the SELECT is DISTINCT (default true).
+ * @return Zend_Db_Select This Zend_Db_Select object.
+ */
+ public function distinct($flag = true)
+ {
+ $this->_parts[self::DISTINCT] = (bool) $flag;
+ return $this;
+ }
+
+ /**
+ * Adds a FROM table and optional columns to the query.
+ *
+ * The first parameter $name can be a simple string, in which case the
+ * correlation name is generated automatically. If you want to specify
+ * the correlation name, the first parameter must be an associative
+ * array in which the key is the correlation name, and the value is
+ * the physical table name. For example, array('alias' => 'table').
+ * The correlation name is prepended to all columns fetched for this
+ * table.
+ *
+ * The second parameter can be a single string or Zend_Db_Expr object,
+ * or else an array of strings or Zend_Db_Expr objects.
+ *
+ * The first parameter can be null or an empty string, in which case
+ * no correlation name is generated or prepended to the columns named
+ * in the second parameter.
+ *
+ * @param array|string|Zend_Db_Expr $name The table name or an associative array
+ * relating correlation name to table name.
+ * @param array|string|Zend_Db_Expr $cols The columns to select from this table.
+ * @param string $schema The schema name to specify, if any.
+ * @return Zend_Db_Select This Zend_Db_Select object.
+ */
+ public function from($name, $cols = '*', $schema = null)
+ {
+ return $this->_join(self::FROM, $name, null, $cols, $schema);
+ }
+
+ /**
+ * Specifies the columns used in the FROM clause.
+ *
+ * The parameter can be a single string or Zend_Db_Expr object,
+ * or else an array of strings or Zend_Db_Expr objects.
+ *
+ * @param array|string|Zend_Db_Expr $cols The columns to select from this table.
+ * @param string $correlationName Correlation name of target table. OPTIONAL
+ * @return Zend_Db_Select This Zend_Db_Select object.
+ */
+ public function columns($cols = '*', $correlationName = null)
+ {
+ if ($correlationName === null && count($this->_parts[self::FROM])) {
+ $correlationNameKeys = array_keys($this->_parts[self::FROM]);
+ $correlationName = current($correlationNameKeys);
+ }
+
+ if (!array_key_exists($correlationName, $this->_parts[self::FROM])) {
+ /**
+ * @see Zend_Db_Select_Exception
+ */
+ throw new Zend_Db_Select_Exception("No table has been specified for the FROM clause");
+ }
+
+ $this->_tableCols($correlationName, $cols);
+
+ return $this;
+ }
+
+ /**
+ * Adds a UNION clause to the query.
+ *
+ * The first parameter has to be an array of Zend_Db_Select or
+ * sql query strings.
+ *
+ * <code>
+ * $sql1 = $db->select();
+ * $sql2 = "SELECT ...";
+ * $select = $db->select()
+ * ->union(array($sql1, $sql2))
+ * ->order("id");
+ * </code>
+ *
+ * @param array $select Array of select clauses for the union.
+ * @return Zend_Db_Select This Zend_Db_Select object.
+ */
+ public function union($select = array(), $type = self::SQL_UNION)
+ {
+ if (!is_array($select)) {
+ throw new Zend_Db_Select_Exception(
+ "union() only accepts an array of Zend_Db_Select instances of sql query strings."
+ );
+ }
+
+ if (!in_array($type, self::$_unionTypes)) {
+ throw new Zend_Db_Select_Exception("Invalid union type '{$type}'");
+ }
+
+ foreach ($select as $target) {
+ $this->_parts[self::UNION][] = array($target, $type);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Adds a JOIN table and columns to the query.
+ *
+ * The $name and $cols parameters follow the same logic
+ * as described in the from() method.
+ *
+ * @param array|string|Zend_Db_Expr $name The table name.
+ * @param string $cond Join on this condition.
+ * @param array|string $cols The columns to select from the joined table.
+ * @param string $schema The database name to specify, if any.
+ * @return Zend_Db_Select This Zend_Db_Select object.
+ */
+ public function join($name, $cond, $cols = self::SQL_WILDCARD, $schema = null)
+ {
+ return $this->joinInner($name, $cond, $cols, $schema);
+ }
+
+ /**
+ * Add an INNER JOIN table and colums to the query
+ * Rows in both tables are matched according to the expression
+ * in the $cond argument. The result set is comprised
+ * of all cases where rows from the left table match
+ * rows from the right table.
+ *
+ * The $name and $cols parameters follow the same logic
+ * as described in the from() method.
+ *
+ * @param array|string|Zend_Db_Expr $name The table name.
+ * @param string $cond Join on this condition.
+ * @param array|string $cols The columns to select from the joined table.
+ * @param string $schema The database name to specify, if any.
+ * @return Zend_Db_Select This Zend_Db_Select object.
+ */
+ public function joinInner($name, $cond, $cols = self::SQL_WILDCARD, $schema = null)
+ {
+ return $this->_join(self::INNER_JOIN, $name, $cond, $cols, $schema);
+ }
+
+ /**
+ * Add a LEFT OUTER JOIN table and colums to the query
+ * All rows from the left operand table are included,
+ * matching rows from the right operand table included,
+ * and the columns from the right operand table are filled
+ * with NULLs if no row exists matching the left table.
+ *
+ * The $name and $cols parameters follow the same logic
+ * as described in the from() method.
+ *
+ * @param array|string|Zend_Db_Expr $name The table name.
+ * @param string $cond Join on this condition.
+ * @param array|string $cols The columns to select from the joined table.
+ * @param string $schema The database name to specify, if any.
+ * @return Zend_Db_Select This Zend_Db_Select object.
+ */
+ public function joinLeft($name, $cond, $cols = self::SQL_WILDCARD, $schema = null)
+ {
+ return $this->_join(self::LEFT_JOIN, $name, $cond, $cols, $schema);
+ }
+
+ /**
+ * Add a RIGHT OUTER JOIN table and colums to the query.
+ * Right outer join is the complement of left outer join.
+ * All rows from the right operand table are included,
+ * matching rows from the left operand table included,
+ * and the columns from the left operand table are filled
+ * with NULLs if no row exists matching the right table.
+ *
+ * The $name and $cols parameters follow the same logic
+ * as described in the from() method.
+ *
+ * @param array|string|Zend_Db_Expr $name The table name.
+ * @param string $cond Join on this condition.
+ * @param array|string $cols The columns to select from the joined table.
+ * @param string $schema The database name to specify, if any.
+ * @return Zend_Db_Select This Zend_Db_Select object.
+ */
+ public function joinRight($name, $cond, $cols = self::SQL_WILDCARD, $schema = null)
+ {
+ return $this->_join(self::RIGHT_JOIN, $name, $cond, $cols, $schema);
+ }
+
+ /**
+ * Add a FULL OUTER JOIN table and colums to the query.
+ * A full outer join is like combining a left outer join
+ * and a right outer join. All rows from both tables are
+ * included, paired with each other on the same row of the
+ * result set if they satisfy the join condition, and otherwise
+ * paired with NULLs in place of columns from the other table.
+ *
+ * The $name and $cols parameters follow the same logic
+ * as described in the from() method.
+ *
+ * @param array|string|Zend_Db_Expr $name The table name.
+ * @param string $cond Join on this condition.
+ * @param array|string $cols The columns to select from the joined table.
+ * @param string $schema The database name to specify, if any.
+ * @return Zend_Db_Select This Zend_Db_Select object.
+ */
+ public function joinFull($name, $cond, $cols = self::SQL_WILDCARD, $schema = null)
+ {
+ return $this->_join(self::FULL_JOIN, $name, $cond, $cols, $schema);
+ }
+
+ /**
+ * Add a CROSS JOIN table and colums to the query.
+ * A cross join is a cartesian product; there is no join condition.
+ *
+ * The $name and $cols parameters follow the same logic
+ * as described in the from() method.
+ *
+ * @param array|string|Zend_Db_Expr $name The table name.
+ * @param array|string $cols The columns to select from the joined table.
+ * @param string $schema The database name to specify, if any.
+ * @return Zend_Db_Select This Zend_Db_Select object.
+ */
+ public function joinCross($name, $cols = self::SQL_WILDCARD, $schema = null)
+ {
+ return $this->_join(self::CROSS_JOIN, $name, null, $cols, $schema);
+ }
+
+ /**
+ * Add a NATURAL JOIN table and colums to the query.
+ * A natural join assumes an equi-join across any column(s)
+ * that appear with the same name in both tables.
+ * Only natural inner joins are supported by this API,
+ * even though SQL permits natural outer joins as well.
+ *
+ * The $name and $cols parameters follow the same logic
+ * as described in the from() method.
+ *
+ * @param array|string|Zend_Db_Expr $name The table name.
+ * @param array|string $cols The columns to select from the joined table.
+ * @param string $schema The database name to specify, if any.
+ * @return Zend_Db_Select This Zend_Db_Select object.
+ */
+ public function joinNatural($name, $cols = self::SQL_WILDCARD, $schema = null)
+ {
+ return $this->_join(self::NATURAL_JOIN, $name, null, $cols, $schema);
+ }
+
+ /**
+ * Adds a WHERE condition to the query by AND.
+ *
+ * If a value is passed as the second param, it will be quoted
+ * and replaced into the condition wherever a question-mark
+ * appears. Array values are quoted and comma-separated.
+ *
+ * <code>
+ * // simplest but non-secure
+ * $select->where("id = $id");
+ *
+ * // secure (ID is quoted but matched anyway)
+ * $select->where('id = ?', $id);
+ *
+ * // alternatively, with named binding
+ * $select->where('id = :id');
+ * </code>
+ *
+ * Note that it is more correct to use named bindings in your
+ * queries for values other than strings. When you use named
+ * bindings, don't forget to pass the values when actually
+ * making a query:
+ *
+ * <code>
+ * $db->fetchAll($select, array('id' => 5));
+ * </code>
+ *
+ * @param string $cond The WHERE condition.
+ * @param mixed $value OPTIONAL The value to quote into the condition.
+ * @param int $type OPTIONAL The type of the given value
+ * @return Zend_Db_Select This Zend_Db_Select object.
+ */
+ public function where($cond, $value = null, $type = null)
+ {
+ $this->_parts[self::WHERE][] = $this->_where($cond, $value, $type, true);
+
+ return $this;
+ }
+
+ /**
+ * Adds a WHERE condition to the query by OR.
+ *
+ * Otherwise identical to where().
+ *
+ * @param string $cond The WHERE condition.
+ * @param mixed $value OPTIONAL The value to quote into the condition.
+ * @param int $type OPTIONAL The type of the given value
+ * @return Zend_Db_Select This Zend_Db_Select object.
+ *
+ * @see where()
+ */
+ public function orWhere($cond, $value = null, $type = null)
+ {
+ $this->_parts[self::WHERE][] = $this->_where($cond, $value, $type, false);
+
+ return $this;
+ }
+
+ /**
+ * Adds grouping to the query.
+ *
+ * @param array|string $spec The column(s) to group by.
+ * @return Zend_Db_Select This Zend_Db_Select object.
+ */
+ public function group($spec)
+ {
+ if (!is_array($spec)) {
+ $spec = array($spec);
+ }
+
+ foreach ($spec as $val) {
+ // Remove comments from SQL statement
+ $noComments = preg_replace(self::REGEX_SQL_COMMENTS, '$1', (string) $val);
+ if (preg_match(self::REGEX_COLUMN_EXPR_GROUP, $noComments)) {
+ $val = new Zend_Db_Expr($val);
+ }
+ $this->_parts[self::GROUP][] = $val;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Adds a HAVING condition to the query by AND.
+ *
+ * If a value is passed as the second param, it will be quoted
+ * and replaced into the condition wherever a question-mark
+ * appears. See {@link where()} for an example
+ *
+ * @param string $cond The HAVING condition.
+ * @param mixed $value OPTIONAL The value to quote into the condition.
+ * @param int $type OPTIONAL The type of the given value
+ * @return Zend_Db_Select This Zend_Db_Select object.
+ */
+ public function having($cond, $value = null, $type = null)
+ {
+ if ($value !== null) {
+ $cond = $this->_adapter->quoteInto($cond, $value, $type);
+ }
+
+ if ($this->_parts[self::HAVING]) {
+ $this->_parts[self::HAVING][] = self::SQL_AND . " ($cond)";
+ } else {
+ $this->_parts[self::HAVING][] = "($cond)";
+ }
+
+ return $this;
+ }
+
+ /**
+ * Adds a HAVING condition to the query by OR.
+ *
+ * Otherwise identical to orHaving().
+ *
+ * @param string $cond The HAVING condition.
+ * @param mixed $value OPTIONAL The value to quote into the condition.
+ * @param int $type OPTIONAL The type of the given value
+ * @return Zend_Db_Select This Zend_Db_Select object.
+ *
+ * @see having()
+ */
+ public function orHaving($cond, $value = null, $type = null)
+ {
+ if ($value !== null) {
+ $cond = $this->_adapter->quoteInto($cond, $value, $type);
+ }
+
+ if ($this->_parts[self::HAVING]) {
+ $this->_parts[self::HAVING][] = self::SQL_OR . " ($cond)";
+ } else {
+ $this->_parts[self::HAVING][] = "($cond)";
+ }
+
+ return $this;
+ }
+
+ /**
+ * Adds a row order to the query.
+ *
+ * @param mixed $spec The column(s) and direction to order by.
+ * @return Zend_Db_Select This Zend_Db_Select object.
+ */
+ public function order($spec)
+ {
+ if (!is_array($spec)) {
+ $spec = array($spec);
+ }
+
+ // force 'ASC' or 'DESC' on each order spec, default is ASC.
+ foreach ($spec as $val) {
+ if ($val instanceof Zend_Db_Expr) {
+ $expr = $val->__toString();
+ if (empty($expr)) {
+ continue;
+ }
+ $this->_parts[self::ORDER][] = $val;
+ } else {
+ if (empty($val)) {
+ continue;
+ }
+ $direction = self::SQL_ASC;
+ if (preg_match('/(.*\W)(' . self::SQL_ASC . '|' . self::SQL_DESC . ')\b/si', $val, $matches)) {
+ $val = trim($matches[1]);
+ $direction = $matches[2];
+ }
+ // Remove comments from SQL statement
+ $noComments = preg_replace(self::REGEX_SQL_COMMENTS, '$1', (string) $val);
+ if (preg_match(self::REGEX_COLUMN_EXPR_ORDER, $noComments)) {
+ $val = new Zend_Db_Expr($val);
+ }
+ $this->_parts[self::ORDER][] = array($val, $direction);
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Sets a limit count and offset to the query.
+ *
+ * @param int $count OPTIONAL The number of rows to return.
+ * @param int $offset OPTIONAL Start returning after this many rows.
+ * @return Zend_Db_Select This Zend_Db_Select object.
+ */
+ public function limit($count = null, $offset = null)
+ {
+ $this->_parts[self::LIMIT_COUNT] = (int) $count;
+ $this->_parts[self::LIMIT_OFFSET] = (int) $offset;
+ return $this;
+ }
+
+ /**
+ * Sets the limit and count by page number.
+ *
+ * @param int $page Limit results to this page number.
+ * @param int $rowCount Use this many rows per page.
+ * @return Zend_Db_Select This Zend_Db_Select object.
+ */
+ public function limitPage($page, $rowCount)
+ {
+ $page = ($page > 0) ? $page : 1;
+ $rowCount = ($rowCount > 0) ? $rowCount : 1;
+ $this->_parts[self::LIMIT_COUNT] = (int) $rowCount;
+ $this->_parts[self::LIMIT_OFFSET] = (int) $rowCount * ($page - 1);
+ return $this;
+ }
+
+ /**
+ * Makes the query SELECT FOR UPDATE.
+ *
+ * @param bool $flag Whether or not the SELECT is FOR UPDATE (default true).
+ * @return Zend_Db_Select This Zend_Db_Select object.
+ */
+ public function forUpdate($flag = true)
+ {
+ $this->_parts[self::FOR_UPDATE] = (bool) $flag;
+ return $this;
+ }
+
+ /**
+ * Get part of the structured information for the current query.
+ *
+ * @param string $part
+ * @return mixed
+ * @throws Zend_Db_Select_Exception
+ */
+ public function getPart($part)
+ {
+ $part = strtolower($part);
+ if (!array_key_exists($part, $this->_parts)) {
+ throw new Zend_Db_Select_Exception("Invalid Select part '$part'");
+ }
+ return $this->_parts[$part];
+ }
+
+ /**
+ * Executes the current select object and returns the result
+ *
+ * @param integer $fetchMode OPTIONAL
+ * @param mixed $bind An array of data to bind to the placeholders.
+ * @return PDO_Statement|Zend_Db_Statement
+ */
+ public function query($fetchMode = null, $bind = array())
+ {
+ if (!empty($bind)) {
+ $this->bind($bind);
+ }
+
+ $stmt = $this->_adapter->query($this);
+ if ($fetchMode == null) {
+ $fetchMode = $this->_adapter->getFetchMode();
+ }
+ $stmt->setFetchMode($fetchMode);
+ return $stmt;
+ }
+
+ /**
+ * Converts this object to an SQL SELECT string.
+ *
+ * @return string|null This object as a SELECT string. (or null if a string cannot be produced.)
+ */
+ public function assemble()
+ {
+ $sql = self::SQL_SELECT;
+ foreach (array_keys(self::$_partsInit) as $part) {
+ $method = '_render' . ucfirst($part);
+ if (method_exists($this, $method)) {
+ $sql = $this->$method($sql);
+ }
+ }
+ return $sql;
+ }
+
+ /**
+ * Clear parts of the Select object, or an individual part.
+ *
+ * @param string $part OPTIONAL
+ * @return Zend_Db_Select
+ */
+ public function reset($part = null)
+ {
+ if ($part == null) {
+ $this->_parts = self::$_partsInit;
+ } elseif (array_key_exists($part, self::$_partsInit)) {
+ $this->_parts[$part] = self::$_partsInit[$part];
+ }
+ return $this;
+ }
+
+ /**
+ * Gets the Zend_Db_Adapter_Abstract for this
+ * particular Zend_Db_Select object.
+ *
+ * @return Zend_Db_Adapter_Abstract
+ */
+ public function getAdapter()
+ {
+ return $this->_adapter;
+ }
+
+ /**
+ * Populate the {@link $_parts} 'join' key
+ *
+ * Does the dirty work of populating the join key.
+ *
+ * The $name and $cols parameters follow the same logic
+ * as described in the from() method.
+ *
+ * @param null|string $type Type of join; inner, left, and null are currently supported
+ * @param array|string|Zend_Db_Expr $name Table name
+ * @param string $cond Join on this condition
+ * @param array|string $cols The columns to select from the joined table
+ * @param string $schema The database name to specify, if any.
+ * @return Zend_Db_Select This Zend_Db_Select object
+ * @throws Zend_Db_Select_Exception
+ */
+ protected function _join($type, $name, $cond, $cols, $schema = null)
+ {
+ if (!in_array($type, self::$_joinTypes) && $type != self::FROM) {
+ /**
+ * @see Zend_Db_Select_Exception
+ */
+ throw new Zend_Db_Select_Exception("Invalid join type '$type'");
+ }
+
+ if (count($this->_parts[self::UNION])) {
+ throw new Zend_Db_Select_Exception("Invalid use of table with " . self::SQL_UNION);
+ }
+
+ if (empty($name)) {
+ $correlationName = $tableName = '';
+ } elseif (is_array($name)) {
+ // Must be array($correlationName => $tableName) or array($ident, ...)
+ foreach ($name as $_correlationName => $_tableName) {
+ if (is_string($_correlationName)) {
+ // We assume the key is the correlation name and value is the table name
+ $tableName = $_tableName;
+ $correlationName = $_correlationName;
+ } else {
+ // We assume just an array of identifiers, with no correlation name
+ $tableName = $_tableName;
+ $correlationName = $this->_uniqueCorrelation($tableName);
+ }
+ break;
+ }
+ } elseif ($name instanceof Zend_Db_Expr|| $name instanceof Zend_Db_Select) {
+ $tableName = $name;
+ $correlationName = $this->_uniqueCorrelation('t');
+ } elseif (preg_match('/^(.+)\s+AS\s+(.+)$/i', $name, $m)) {
+ $tableName = $m[1];
+ $correlationName = $m[2];
+ } else {
+ $tableName = $name;
+ $correlationName = $this->_uniqueCorrelation($tableName);
+ }
+
+ // Schema from table name overrides schema argument
+ if (!is_object($tableName) && false !== strpos($tableName, '.')) {
+ list($schema, $tableName) = explode('.', $tableName);
+ }
+
+ $lastFromCorrelationName = null;
+ if (!empty($correlationName)) {
+ if (array_key_exists($correlationName, $this->_parts[self::FROM])) {
+ /**
+ * @see Zend_Db_Select_Exception
+ */
+ throw new Zend_Db_Select_Exception("You cannot define a correlation name '$correlationName' more than once");
+ }
+
+ if ($type == self::FROM) {
+ // append this from after the last from joinType
+ $tmpFromParts = $this->_parts[self::FROM];
+ $this->_parts[self::FROM] = array();
+ // move all the froms onto the stack
+ while ($tmpFromParts) {
+ $currentCorrelationName = key($tmpFromParts);
+ if ($tmpFromParts[$currentCorrelationName]['joinType'] != self::FROM) {
+ break;
+ }
+ $lastFromCorrelationName = $currentCorrelationName;
+ $this->_parts[self::FROM][$currentCorrelationName] = array_shift($tmpFromParts);
+ }
+ } else {
+ $tmpFromParts = array();
+ }
+ $this->_parts[self::FROM][$correlationName] = array(
+ 'joinType' => $type,
+ 'schema' => $schema,
+ 'tableName' => $tableName,
+ 'joinCondition' => $cond
+ );
+ while ($tmpFromParts) {
+ $currentCorrelationName = key($tmpFromParts);
+ $this->_parts[self::FROM][$currentCorrelationName] = array_shift($tmpFromParts);
+ }
+ }
+
+ // add to the columns from this joined table
+ if ($type == self::FROM && $lastFromCorrelationName == null) {
+ $lastFromCorrelationName = true;
+ }
+ $this->_tableCols($correlationName, $cols, $lastFromCorrelationName);
+
+ return $this;
+ }
+
+ /**
+ * Handle JOIN... USING... syntax
+ *
+ * This is functionality identical to the existing JOIN methods, however
+ * the join condition can be passed as a single column name. This method
+ * then completes the ON condition by using the same field for the FROM
+ * table and the JOIN table.
+ *
+ * <code>
+ * $select = $db->select()->from('table1')
+ * ->joinUsing('table2', 'column1');
+ *
+ * // SELECT * FROM table1 JOIN table2 ON table1.column1 = table2.column2
+ * </code>
+ *
+ * These joins are called by the developer simply by adding 'Using' to the
+ * method name. E.g.
+ * * joinUsing
+ * * joinInnerUsing
+ * * joinFullUsing
+ * * joinRightUsing
+ * * joinLeftUsing
+ *
+ * @return Zend_Db_Select This Zend_Db_Select object.
+ */
+ public function _joinUsing($type, $name, $cond, $cols = '*', $schema = null)
+ {
+ if (empty($this->_parts[self::FROM])) {
+ throw new Zend_Db_Select_Exception("You can only perform a joinUsing after specifying a FROM table");
+ }
+
+ $join = $this->_adapter->quoteIdentifier(key($this->_parts[self::FROM]), true);
+ $from = $this->_adapter->quoteIdentifier($this->_uniqueCorrelation($name), true);
+
+ $joinCond = array();
+ foreach ((array)$cond as $fieldName) {
+ $cond1 = $from . '.' . $fieldName;
+ $cond2 = $join . '.' . $fieldName;
+ $joinCond[] = $cond1 . ' = ' . $cond2;
+ }
+ $cond = implode(' '.self::SQL_AND.' ', $joinCond);
+
+ return $this->_join($type, $name, $cond, $cols, $schema);
+ }
+
+ /**
+ * Generate a unique correlation name
+ *
+ * @param string|array $name A qualified identifier.
+ * @return string A unique correlation name.
+ */
+ private function _uniqueCorrelation($name)
+ {
+ if (is_array($name)) {
+ $k = key($name);
+ $c = is_string($k) ? $k : end($name);
+ } else {
+ // Extract just the last name of a qualified table name
+ $dot = strrpos($name,'.');
+ $c = ($dot === false) ? $name : substr($name, $dot+1);
+ }
+ for ($i = 2; array_key_exists($c, $this->_parts[self::FROM]); ++$i) {
+ $c = $name . '_' . (string) $i;
+ }
+ return $c;
+ }
+
+ /**
+ * Adds to the internal table-to-column mapping array.
+ *
+ * @param string $tbl The table/join the columns come from.
+ * @param array|string $cols The list of columns; preferably as
+ * an array, but possibly as a string containing one column.
+ * @param bool|string True if it should be prepended, a correlation name if it should be inserted
+ * @return void
+ */
+ protected function _tableCols($correlationName, $cols, $afterCorrelationName = null)
+ {
+ if (!is_array($cols)) {
+ $cols = array($cols);
+ }
+
+ if ($correlationName == null) {
+ $correlationName = '';
+ }
+
+ $columnValues = array();
+
+ foreach (array_filter($cols) as $alias => $col) {
+ $currentCorrelationName = $correlationName;
+ if (is_string($col)) {
+ // Check for a column matching "<column> AS <alias>" and extract the alias name
+ $col = trim(str_replace("\n", ' ', $col));
+ if (preg_match('/^(.+)\s+' . self::SQL_AS . '\s+(.+)$/i', $col, $m)) {
+ $col = $m[1];
+ $alias = $m[2];
+ }
+ // Check for columns that look like functions and convert to Zend_Db_Expr
+ if (preg_match(self::REGEX_COLUMN_EXPR, (string) $col)) {
+ $col = new Zend_Db_Expr($col);
+ } elseif (preg_match('/(.+)\.(.+)/', $col, $m)) {
+ $currentCorrelationName = $m[1];
+ $col = $m[2];
+ }
+ }
+ $columnValues[] = array($currentCorrelationName, $col, is_string($alias) ? $alias : null);
+ }
+
+ if ($columnValues) {
+
+ // should we attempt to prepend or insert these values?
+ if ($afterCorrelationName === true || is_string($afterCorrelationName)) {
+ $tmpColumns = $this->_parts[self::COLUMNS];
+ $this->_parts[self::COLUMNS] = array();
+ } else {
+ $tmpColumns = array();
+ }
+
+ // find the correlation name to insert after
+ if (is_string($afterCorrelationName)) {
+ while ($tmpColumns) {
+ $this->_parts[self::COLUMNS][] = $currentColumn = array_shift($tmpColumns);
+ if ($currentColumn[0] == $afterCorrelationName) {
+ break;
+ }
+ }
+ }
+
+ // apply current values to current stack
+ foreach ($columnValues as $columnValue) {
+ array_push($this->_parts[self::COLUMNS], $columnValue);
+ }
+
+ // finish ensuring that all previous values are applied (if they exist)
+ while ($tmpColumns) {
+ array_push($this->_parts[self::COLUMNS], array_shift($tmpColumns));
+ }
+ }
+ }
+
+ /**
+ * Internal function for creating the where clause
+ *
+ * @param string $condition
+ * @param mixed $value optional
+ * @param string $type optional
+ * @param boolean $bool true = AND, false = OR
+ * @return string clause
+ */
+ protected function _where($condition, $value = null, $type = null, $bool = true)
+ {
+ if (count($this->_parts[self::UNION])) {
+ throw new Zend_Db_Select_Exception("Invalid use of where clause with " . self::SQL_UNION);
+ }
+
+ if ($value !== null) {
+ $condition = $this->_adapter->quoteInto($condition, $value, $type);
+ }
+
+ $cond = "";
+ if ($this->_parts[self::WHERE]) {
+ if ($bool === true) {
+ $cond = self::SQL_AND . ' ';
+ } else {
+ $cond = self::SQL_OR . ' ';
+ }
+ }
+
+ return $cond . "($condition)";
+ }
+
+ /**
+ * @return array
+ */
+ protected function _getDummyTable()
+ {
+ return array();
+ }
+
+ /**
+ * Return a quoted schema name
+ *
+ * @param string $schema The schema name OPTIONAL
+ * @return string|null
+ */
+ protected function _getQuotedSchema($schema = null)
+ {
+ if ($schema === null) {
+ return null;
+ }
+ return $this->_adapter->quoteIdentifier($schema, true) . '.';
+ }
+
+ /**
+ * Return a quoted table name
+ *
+ * @param string $tableName The table name
+ * @param string $correlationName The correlation name OPTIONAL
+ * @return string
+ */
+ protected function _getQuotedTable($tableName, $correlationName = null)
+ {
+ return $this->_adapter->quoteTableAs($tableName, $correlationName, true);
+ }
+
+ /**
+ * Render DISTINCT clause
+ *
+ * @param string $sql SQL query
+ * @return string
+ */
+ protected function _renderDistinct($sql)
+ {
+ if ($this->_parts[self::DISTINCT]) {
+ $sql .= ' ' . self::SQL_DISTINCT;
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Render DISTINCT clause
+ *
+ * @param string $sql SQL query
+ * @return string|null
+ */
+ protected function _renderColumns($sql)
+ {
+ if (!count($this->_parts[self::COLUMNS])) {
+ return null;
+ }
+
+ $columns = array();
+ foreach ($this->_parts[self::COLUMNS] as $columnEntry) {
+ list($correlationName, $column, $alias) = $columnEntry;
+ if ($column instanceof Zend_Db_Expr) {
+ $columns[] = $this->_adapter->quoteColumnAs($column, $alias, true);
+ } else {
+ if ($column == self::SQL_WILDCARD) {
+ $column = new Zend_Db_Expr(self::SQL_WILDCARD);
+ $alias = null;
+ }
+ if (empty($correlationName)) {
+ $columns[] = $this->_adapter->quoteColumnAs($column, $alias, true);
+ } else {
+ $columns[] = $this->_adapter->quoteColumnAs(array($correlationName, $column), $alias, true);
+ }
+ }
+ }
+
+ return $sql . ' ' . implode(', ', $columns);
+ }
+
+ /**
+ * Render FROM clause
+ *
+ * @param string $sql SQL query
+ * @return string
+ */
+ protected function _renderFrom($sql)
+ {
+ /*
+ * If no table specified, use RDBMS-dependent solution
+ * for table-less query. e.g. DUAL in Oracle.
+ */
+ if (empty($this->_parts[self::FROM])) {
+ $this->_parts[self::FROM] = $this->_getDummyTable();
+ }
+
+ $from = array();
+
+ foreach ($this->_parts[self::FROM] as $correlationName => $table) {
+ $tmp = '';
+
+ $joinType = ($table['joinType'] == self::FROM) ? self::INNER_JOIN : $table['joinType'];
+
+ // Add join clause (if applicable)
+ if (! empty($from)) {
+ $tmp .= ' ' . strtoupper($joinType) . ' ';
+ }
+
+ $tmp .= $this->_getQuotedSchema($table['schema']);
+ $tmp .= $this->_getQuotedTable($table['tableName'], $correlationName);
+
+ // Add join conditions (if applicable)
+ if (!empty($from) && ! empty($table['joinCondition'])) {
+ $tmp .= ' ' . self::SQL_ON . ' ' . $table['joinCondition'];
+ }
+
+ // Add the table name and condition add to the list
+ $from[] = $tmp;
+ }
+
+ // Add the list of all joins
+ if (!empty($from)) {
+ $sql .= ' ' . self::SQL_FROM . ' ' . implode("\n", $from);
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Render UNION query
+ *
+ * @param string $sql SQL query
+ * @return string
+ */
+ protected function _renderUnion($sql)
+ {
+ if ($this->_parts[self::UNION]) {
+ $parts = count($this->_parts[self::UNION]);
+ foreach ($this->_parts[self::UNION] as $cnt => $union) {
+ list($target, $type) = $union;
+ if ($target instanceof Zend_Db_Select) {
+ $target = $target->assemble();
+ }
+ $sql .= $target;
+ if ($cnt < $parts - 1) {
+ $sql .= ' ' . $type . ' ';
+ }
+ }
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Render WHERE clause
+ *
+ * @param string $sql SQL query
+ * @return string
+ */
+ protected function _renderWhere($sql)
+ {
+ if ($this->_parts[self::FROM] && $this->_parts[self::WHERE]) {
+ $sql .= ' ' . self::SQL_WHERE . ' ' . implode(' ', $this->_parts[self::WHERE]);
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Render GROUP clause
+ *
+ * @param string $sql SQL query
+ * @return string
+ */
+ protected function _renderGroup($sql)
+ {
+ if ($this->_parts[self::FROM] && $this->_parts[self::GROUP]) {
+ $group = array();
+ foreach ($this->_parts[self::GROUP] as $term) {
+ $group[] = $this->_adapter->quoteIdentifier($term, true);
+ }
+ $sql .= ' ' . self::SQL_GROUP_BY . ' ' . implode(",\n\t", $group);
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Render HAVING clause
+ *
+ * @param string $sql SQL query
+ * @return string
+ */
+ protected function _renderHaving($sql)
+ {
+ if ($this->_parts[self::FROM] && $this->_parts[self::HAVING]) {
+ $sql .= ' ' . self::SQL_HAVING . ' ' . implode(' ', $this->_parts[self::HAVING]);
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Render ORDER clause
+ *
+ * @param string $sql SQL query
+ * @return string
+ */
+ protected function _renderOrder($sql)
+ {
+ if ($this->_parts[self::ORDER]) {
+ $order = array();
+ foreach ($this->_parts[self::ORDER] as $term) {
+ if (is_array($term)) {
+ if(is_numeric($term[0]) && strval(intval($term[0])) == $term[0]) {
+ $order[] = (int)trim($term[0]) . ' ' . $term[1];
+ } else {
+ $order[] = $this->_adapter->quoteIdentifier($term[0], true) . ' ' . $term[1];
+ }
+ } elseif (is_numeric($term) && strval(intval($term)) == $term) {
+ $order[] = (int)trim($term);
+ } else {
+ $order[] = $this->_adapter->quoteIdentifier($term, true);
+ }
+ }
+ $sql .= ' ' . self::SQL_ORDER_BY . ' ' . implode(', ', $order);
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Render LIMIT OFFSET clause
+ *
+ * @param string $sql SQL query
+ * @return string
+ */
+ protected function _renderLimitoffset($sql)
+ {
+ $count = 0;
+ $offset = 0;
+
+ if (!empty($this->_parts[self::LIMIT_OFFSET])) {
+ $offset = (int) $this->_parts[self::LIMIT_OFFSET];
+ $count = PHP_INT_MAX;
+ }
+
+ if (!empty($this->_parts[self::LIMIT_COUNT])) {
+ $count = (int) $this->_parts[self::LIMIT_COUNT];
+ }
+
+ /*
+ * Add limits clause
+ */
+ if ($count > 0) {
+ $sql = trim($this->_adapter->limit($sql, $count, $offset));
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Render FOR UPDATE clause
+ *
+ * @param string $sql SQL query
+ * @return string
+ */
+ protected function _renderForupdate($sql)
+ {
+ if ($this->_parts[self::FOR_UPDATE]) {
+ $sql .= ' ' . self::SQL_FOR_UPDATE;
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Turn magic function calls into non-magic function calls
+ * for joinUsing syntax
+ *
+ * @param string $method
+ * @param array $args OPTIONAL Zend_Db_Table_Select query modifier
+ * @return Zend_Db_Select
+ * @throws Zend_Db_Select_Exception If an invalid method is called.
+ */
+ public function __call($method, array $args)
+ {
+ $matches = array();
+
+ /**
+ * Recognize methods for Has-Many cases:
+ * findParent<Class>()
+ * findParent<Class>By<Rule>()
+ * Use the non-greedy pattern repeat modifier e.g. \w+?
+ */
+ if (preg_match('/^join([a-zA-Z]*?)Using$/', $method, $matches)) {
+ $type = strtolower($matches[1]);
+ if ($type) {
+ $type .= ' join';
+ if (!in_array($type, self::$_joinTypes)) {
+ throw new Zend_Db_Select_Exception("Unrecognized method '$method()'");
+ }
+ if (in_array($type, array(self::CROSS_JOIN, self::NATURAL_JOIN))) {
+ throw new Zend_Db_Select_Exception("Cannot perform a joinUsing with method '$method()'");
+ }
+ } else {
+ $type = self::INNER_JOIN;
+ }
+ array_unshift($args, $type);
+ return call_user_func_array(array($this, '_joinUsing'), $args);
+ }
+
+ throw new Zend_Db_Select_Exception("Unrecognized method '$method()'");
+ }
+
+ /**
+ * Implements magic method.
+ *
+ * @return string This object as a SELECT string.
+ */
+ public function __toString()
+ {
+ try {
+ $sql = $this->assemble();
+ } catch (Exception $e) {
+ trigger_error($e->getMessage(), E_USER_WARNING);
+ $sql = '';
+ }
+ return (string)$sql;
+ }
+
+}
diff --git a/library/vendor/Zend/Db/Select/Exception.php b/library/vendor/Zend/Db/Select/Exception.php
new file mode 100644
index 0000000..6e7bfac
--- /dev/null
+++ b/library/vendor/Zend/Db/Select/Exception.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Select
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * Zend_Db_Exception
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Select
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+class Zend_Db_Select_Exception extends Zend_Db_Exception
+{
+}
+
diff --git a/library/vendor/Zend/Db/Statement.php b/library/vendor/Zend/Db/Statement.php
new file mode 100644
index 0000000..4eb761c
--- /dev/null
+++ b/library/vendor/Zend/Db/Statement.php
@@ -0,0 +1,488 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * @see Zend_Db
+ */
+
+/**
+ * @see Zend_Db_Statement_Interface
+ */
+
+/**
+ * Abstract class to emulate a PDOStatement for native database adapters.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+abstract class Zend_Db_Statement implements Zend_Db_Statement_Interface
+{
+
+ /**
+ * @var resource|object The driver level statement object/resource
+ */
+ protected $_stmt = null;
+
+ /**
+ * @var Zend_Db_Adapter_Abstract
+ */
+ protected $_adapter = null;
+
+ /**
+ * The current fetch mode.
+ *
+ * @var integer
+ */
+ protected $_fetchMode = Zend_Db::FETCH_ASSOC;
+
+ /**
+ * Attributes.
+ *
+ * @var array
+ */
+ protected $_attribute = array();
+
+ /**
+ * Column result bindings.
+ *
+ * @var array
+ */
+ protected $_bindColumn = array();
+
+ /**
+ * Query parameter bindings; covers bindParam() and bindValue().
+ *
+ * @var array
+ */
+ protected $_bindParam = array();
+
+ /**
+ * SQL string split into an array at placeholders.
+ *
+ * @var array
+ */
+ protected $_sqlSplit = array();
+
+ /**
+ * Parameter placeholders in the SQL string by position in the split array.
+ *
+ * @var array
+ */
+ protected $_sqlParam = array();
+
+ /**
+ * @var Zend_Db_Profiler_Query
+ */
+ protected $_queryId = null;
+
+ /**
+ * Constructor for a statement.
+ *
+ * @param Zend_Db_Adapter_Abstract $adapter
+ * @param mixed $sql Either a string or Zend_Db_Select.
+ */
+ public function __construct($adapter, $sql)
+ {
+ $this->_adapter = $adapter;
+ if ($sql instanceof Zend_Db_Select) {
+ $sql = $sql->assemble();
+ }
+ $this->_parseParameters($sql);
+ $this->_prepare($sql);
+
+ $this->_queryId = $this->_adapter->getProfiler()->queryStart($sql);
+ }
+
+ /**
+ * Internal method called by abstract statment constructor to setup
+ * the driver level statement
+ *
+ * @return void
+ */
+ protected function _prepare($sql)
+ {
+ return;
+ }
+
+ /**
+ * @param string $sql
+ * @return void
+ */
+ protected function _parseParameters($sql)
+ {
+ $sql = $this->_stripQuoted($sql);
+
+ // split into text and params
+ $this->_sqlSplit = empty($sql) ? [] : preg_split('/(\?|\:[a-zA-Z0-9_]+)/',
+ $sql, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
+
+ // map params
+ $this->_sqlParam = array();
+ foreach ($this->_sqlSplit as $key => $val) {
+ if ($val == '?') {
+ if ($this->_adapter->supportsParameters('positional') === false) {
+ /**
+ * @see Zend_Db_Statement_Exception
+ */
+ throw new Zend_Db_Statement_Exception("Invalid bind-variable position '$val'");
+ }
+ } else if ($val[0] == ':') {
+ if ($this->_adapter->supportsParameters('named') === false) {
+ /**
+ * @see Zend_Db_Statement_Exception
+ */
+ throw new Zend_Db_Statement_Exception("Invalid bind-variable name '$val'");
+ }
+ }
+ $this->_sqlParam[] = $val;
+ }
+
+ // set up for binding
+ $this->_bindParam = array();
+ }
+
+ /**
+ * Remove parts of a SQL string that contain quoted strings
+ * of values or identifiers.
+ *
+ * @param string $sql
+ * @return string
+ */
+ protected function _stripQuoted($sql)
+ {
+
+ // get the character for value quoting
+ // this should be '
+ $q = $this->_adapter->quote('a');
+ $q = $q[0];
+ // get the value used as an escaped quote,
+ // e.g. \' or ''
+ $qe = $this->_adapter->quote($q);
+ $qe = substr($qe, 1, 2);
+ $qe = preg_quote($qe);
+ $escapeChar = substr($qe,0,1);
+ // remove 'foo\'bar'
+ if (!empty($q)) {
+ $escapeChar = preg_quote($escapeChar);
+ if ($sql !== null) {
+ // this segfaults only after 65,000 characters instead of 9,000
+ $sql = preg_replace("/$q([^$q{$escapeChar}]*|($qe)*)*$q/s", '', $sql);
+ }
+ }
+
+ // get a version of the SQL statement with all quoted
+ // values and delimited identifiers stripped out
+ // remove "foo\"bar"
+ if ($sql !== null) {
+ $sql = preg_replace("/\"(\\\\\"|[^\"])*\"/Us", '', $sql);
+ }
+
+ // get the character for delimited id quotes,
+ // this is usually " but in MySQL is `
+ $d = $this->_adapter->quoteIdentifier('a');
+ $d = $d[0];
+ // get the value used as an escaped delimited id quote,
+ // e.g. \" or "" or \`
+ $de = $this->_adapter->quoteIdentifier($d);
+ $de = substr($de, 1, 2);
+ $de = preg_quote($de);
+ // Note: $de and $d where never used..., now they are:
+ if ($sql !== null) {
+ $sql = preg_replace("/$d($de|\\\\{2}|[^$d])*$d/Us", '', $sql);
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Bind a column of the statement result set to a PHP variable.
+ *
+ * @param string $column Name the column in the result set, either by
+ * position or by name.
+ * @param mixed $param Reference to the PHP variable containing the value.
+ * @param mixed $type OPTIONAL
+ * @return bool
+ */
+ public function bindColumn($column, &$param, $type = null)
+ {
+ $this->_bindColumn[$column] =& $param;
+ return true;
+ }
+
+ /**
+ * Binds a parameter to the specified variable name.
+ *
+ * @param mixed $parameter Name the parameter, either integer or string.
+ * @param mixed $variable Reference to PHP variable containing the value.
+ * @param mixed $type OPTIONAL Datatype of SQL parameter.
+ * @param mixed $length OPTIONAL Length of SQL parameter.
+ * @param mixed $options OPTIONAL Other options.
+ * @return bool
+ */
+ public function bindParam($parameter, &$variable, $type = null, $length = null, $options = null)
+ {
+ if (!is_int($parameter) && !is_string($parameter)) {
+ /**
+ * @see Zend_Db_Statement_Exception
+ */
+ throw new Zend_Db_Statement_Exception('Invalid bind-variable position');
+ }
+
+ $position = null;
+ if (($intval = (int) $parameter) > 0 && $this->_adapter->supportsParameters('positional')) {
+ if ($intval >= 1 || $intval <= count($this->_sqlParam)) {
+ $position = $intval;
+ }
+ } else if ($this->_adapter->supportsParameters('named')) {
+ if ($parameter[0] != ':') {
+ $parameter = ':' . $parameter;
+ }
+ if (in_array($parameter, $this->_sqlParam) !== false) {
+ $position = $parameter;
+ }
+ }
+
+ if ($position === null) {
+ /**
+ * @see Zend_Db_Statement_Exception
+ */
+ throw new Zend_Db_Statement_Exception("Invalid bind-variable position '$parameter'");
+ }
+
+ // Finally we are assured that $position is valid
+ $this->_bindParam[$position] =& $variable;
+ return $this->_bindParam($position, $variable, $type, $length, $options);
+ }
+
+ /**
+ * Binds a value to a parameter.
+ *
+ * @param mixed $parameter Name the parameter, either integer or string.
+ * @param mixed $value Scalar value to bind to the parameter.
+ * @param mixed $type OPTIONAL Datatype of the parameter.
+ * @return bool
+ */
+ public function bindValue($parameter, $value, $type = null)
+ {
+ return $this->bindParam($parameter, $value, $type);
+ }
+
+ /**
+ * Executes a prepared statement.
+ *
+ * @param array $params OPTIONAL Values to bind to parameter placeholders.
+ * @return bool
+ */
+ public function execute(array $params = null)
+ {
+ /*
+ * Simple case - no query profiler to manage.
+ */
+ if ($this->_queryId === null) {
+ return $this->_execute($params);
+ }
+
+ /*
+ * Do the same thing, but with query profiler
+ * management before and after the execute.
+ */
+ $prof = $this->_adapter->getProfiler();
+ $qp = $prof->getQueryProfile($this->_queryId);
+ if ($qp->hasEnded()) {
+ $this->_queryId = $prof->queryClone($qp);
+ $qp = $prof->getQueryProfile($this->_queryId);
+ }
+ if ($params !== null) {
+ $qp->bindParams($params);
+ } else {
+ $qp->bindParams($this->_bindParam);
+ }
+ $qp->start($this->_queryId);
+
+ $retval = $this->_execute($params);
+
+ $prof->queryEnd($this->_queryId);
+
+ return $retval;
+ }
+
+ /**
+ * Returns an array containing all of the result set rows.
+ *
+ * @param int $style OPTIONAL Fetch mode.
+ * @param int $col OPTIONAL Column number, if fetch mode is by column.
+ * @return array Collection of rows, each in a format by the fetch mode.
+ */
+ public function fetchAll($style = null, $col = null)
+ {
+ $data = array();
+ if ($style === Zend_Db::FETCH_COLUMN && $col === null) {
+ $col = 0;
+ }
+ if ($col === null) {
+ while ($row = $this->fetch($style)) {
+ $data[] = $row;
+ }
+ } else {
+ while (false !== ($val = $this->fetchColumn($col))) {
+ $data[] = $val;
+ }
+ }
+ return $data;
+ }
+
+ /**
+ * Returns a single column from the next row of a result set.
+ *
+ * @param int $col OPTIONAL Position of the column to fetch.
+ * @return string One value from the next row of result set, or false.
+ */
+ public function fetchColumn($col = 0)
+ {
+ $data = array();
+ $col = (int) $col;
+ $row = $this->fetch(Zend_Db::FETCH_NUM);
+ if (!is_array($row)) {
+ return false;
+ }
+ return $row[$col];
+ }
+
+ /**
+ * Fetches the next row and returns it as an object.
+ *
+ * @param string $class OPTIONAL Name of the class to create.
+ * @param array $config OPTIONAL Constructor arguments for the class.
+ * @return mixed One object instance of the specified class, or false.
+ */
+ public function fetchObject($class = 'stdClass', array $config = array())
+ {
+ $obj = new $class($config);
+ $row = $this->fetch(Zend_Db::FETCH_ASSOC);
+ if (!is_array($row)) {
+ return false;
+ }
+ foreach ($row as $key => $val) {
+ $obj->$key = $val;
+ }
+ return $obj;
+ }
+
+ /**
+ * Retrieve a statement attribute.
+ *
+ * @param string $key Attribute name.
+ * @return mixed Attribute value.
+ */
+ public function getAttribute($key)
+ {
+ if (array_key_exists($key, $this->_attribute)) {
+ return $this->_attribute[$key];
+ }
+ }
+
+ /**
+ * Set a statement attribute.
+ *
+ * @param string $key Attribute name.
+ * @param mixed $val Attribute value.
+ * @return bool
+ */
+ public function setAttribute($key, $val)
+ {
+ $this->_attribute[$key] = $val;
+ }
+
+ /**
+ * Set the default fetch mode for this statement.
+ *
+ * @param int $mode The fetch mode.
+ * @return bool
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function setFetchMode($mode)
+ {
+ switch ($mode) {
+ case Zend_Db::FETCH_NUM:
+ case Zend_Db::FETCH_ASSOC:
+ case Zend_Db::FETCH_BOTH:
+ case Zend_Db::FETCH_OBJ:
+ $this->_fetchMode = $mode;
+ break;
+ case Zend_Db::FETCH_BOUND:
+ default:
+ $this->closeCursor();
+ /**
+ * @see Zend_Db_Statement_Exception
+ */
+ throw new Zend_Db_Statement_Exception('invalid fetch mode');
+ break;
+ }
+ }
+
+ /**
+ * Helper function to map retrieved row
+ * to bound column variables
+ *
+ * @param array $row
+ * @return bool True
+ */
+ public function _fetchBound($row)
+ {
+ foreach ($row as $key => $value) {
+ // bindColumn() takes 1-based integer positions
+ // but fetch() returns 0-based integer indexes
+ if (is_int($key)) {
+ $key++;
+ }
+ // set results only to variables that were bound previously
+ if (isset($this->_bindColumn[$key])) {
+ $this->_bindColumn[$key] = $value;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Gets the Zend_Db_Adapter_Abstract for this
+ * particular Zend_Db_Statement object.
+ *
+ * @return Zend_Db_Adapter_Abstract
+ */
+ public function getAdapter()
+ {
+ return $this->_adapter;
+ }
+
+ /**
+ * Gets the resource or object setup by the
+ * _parse
+ * @return unknown_type
+ */
+ public function getDriverStatement()
+ {
+ return $this->_stmt;
+ }
+}
diff --git a/library/vendor/Zend/Db/Statement/Db2.php b/library/vendor/Zend/Db/Statement/Db2.php
new file mode 100644
index 0000000..b817864
--- /dev/null
+++ b/library/vendor/Zend/Db/Statement/Db2.php
@@ -0,0 +1,354 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * @see Zend_Db_Statement
+ */
+
+/**
+ * Extends for DB2 native adapter.
+ *
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Statement_Db2 extends Zend_Db_Statement
+{
+
+ /**
+ * Column names.
+ */
+ protected $_keys;
+
+ /**
+ * Fetched result values.
+ */
+ protected $_values;
+
+ /**
+ * Prepare a statement handle.
+ *
+ * @param string $sql
+ * @return void
+ * @throws Zend_Db_Statement_Db2_Exception
+ */
+ public function _prepare($sql)
+ {
+ $connection = $this->_adapter->getConnection();
+
+ // db2_prepare on i5 emits errors, these need to be
+ // suppressed so that proper exceptions can be thrown
+ $this->_stmt = @db2_prepare($connection, $sql);
+
+ if (!$this->_stmt) {
+ /**
+ * @see Zend_Db_Statement_Db2_Exception
+ */
+ throw new Zend_Db_Statement_Db2_Exception(
+ db2_stmt_errormsg(),
+ db2_stmt_error()
+ );
+ }
+ }
+
+ /**
+ * Binds a parameter to the specified variable name.
+ *
+ * @param mixed $parameter Name the parameter, either integer or string.
+ * @param mixed $variable Reference to PHP variable containing the value.
+ * @param mixed $type OPTIONAL Datatype of SQL parameter.
+ * @param mixed $length OPTIONAL Length of SQL parameter.
+ * @param mixed $options OPTIONAL Other options.
+ * @return bool
+ * @throws Zend_Db_Statement_Db2_Exception
+ */
+ public function _bindParam($parameter, &$variable, $type = null, $length = null, $options = null)
+ {
+ if ($type === null) {
+ $type = DB2_PARAM_IN;
+ }
+
+ if (isset($options['data-type'])) {
+ $datatype = $options['data-type'];
+ } else {
+ $datatype = DB2_CHAR;
+ }
+
+ if (!db2_bind_param($this->_stmt, $parameter, "variable", $type, $datatype)) {
+ /**
+ * @see Zend_Db_Statement_Db2_Exception
+ */
+ throw new Zend_Db_Statement_Db2_Exception(
+ db2_stmt_errormsg(),
+ db2_stmt_error()
+ );
+ }
+
+ return true;
+ }
+
+ /**
+ * Closes the cursor, allowing the statement to be executed again.
+ *
+ * @return bool
+ */
+ public function closeCursor()
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+ db2_free_stmt($this->_stmt);
+ $this->_stmt = false;
+ return true;
+ }
+
+
+ /**
+ * Returns the number of columns in the result set.
+ * Returns null if the statement has no result set metadata.
+ *
+ * @return int The number of columns.
+ */
+ public function columnCount()
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+ return db2_num_fields($this->_stmt);
+ }
+
+ /**
+ * Retrieves the error code, if any, associated with the last operation on
+ * the statement handle.
+ *
+ * @return string error code.
+ */
+ public function errorCode()
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+
+ $error = db2_stmt_error();
+ if ($error === '') {
+ return false;
+ }
+
+ return $error;
+ }
+
+ /**
+ * Retrieves an array of error information, if any, associated with the
+ * last operation on the statement handle.
+ *
+ * @return array
+ */
+ public function errorInfo()
+ {
+ $error = $this->errorCode();
+ if ($error === false){
+ return false;
+ }
+
+ /*
+ * Return three-valued array like PDO. But DB2 does not distinguish
+ * between SQLCODE and native RDBMS error code, so repeat the SQLCODE.
+ */
+ return array(
+ $error,
+ $error,
+ db2_stmt_errormsg()
+ );
+ }
+
+ /**
+ * Executes a prepared statement.
+ *
+ * @param array $params OPTIONAL Values to bind to parameter placeholders.
+ * @return bool
+ * @throws Zend_Db_Statement_Db2_Exception
+ */
+ public function _execute(array $params = null)
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+
+ $retval = true;
+ if ($params !== null) {
+ $retval = @db2_execute($this->_stmt, $params);
+ } else {
+ $retval = @db2_execute($this->_stmt);
+ }
+
+ if ($retval === false) {
+ /**
+ * @see Zend_Db_Statement_Db2_Exception
+ */
+ throw new Zend_Db_Statement_Db2_Exception(
+ db2_stmt_errormsg(),
+ db2_stmt_error());
+ }
+
+ $this->_keys = array();
+ if ($field_num = $this->columnCount()) {
+ for ($i = 0; $i < $field_num; $i++) {
+ $name = db2_field_name($this->_stmt, $i);
+ $this->_keys[] = $name;
+ }
+ }
+
+ $this->_values = array();
+ if ($this->_keys) {
+ $this->_values = array_fill(0, count($this->_keys), null);
+ }
+
+ return $retval;
+ }
+
+ /**
+ * Fetches a row from the result set.
+ *
+ * @param int $style OPTIONAL Fetch mode for this fetch operation.
+ * @param int $cursor OPTIONAL Absolute, relative, or other.
+ * @param int $offset OPTIONAL Number for absolute or relative cursors.
+ * @return mixed Array, object, or scalar depending on fetch mode.
+ * @throws Zend_Db_Statement_Db2_Exception
+ */
+ public function fetch($style = null, $cursor = null, $offset = null)
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+
+ if ($style === null) {
+ $style = $this->_fetchMode;
+ }
+
+ switch ($style) {
+ case Zend_Db::FETCH_NUM :
+ $row = db2_fetch_array($this->_stmt);
+ break;
+ case Zend_Db::FETCH_ASSOC :
+ $row = db2_fetch_assoc($this->_stmt);
+ break;
+ case Zend_Db::FETCH_BOTH :
+ $row = db2_fetch_both($this->_stmt);
+ break;
+ case Zend_Db::FETCH_OBJ :
+ $row = db2_fetch_object($this->_stmt);
+ break;
+ case Zend_Db::FETCH_BOUND:
+ $row = db2_fetch_both($this->_stmt);
+ if ($row !== false) {
+ return $this->_fetchBound($row);
+ }
+ break;
+ default:
+ /**
+ * @see Zend_Db_Statement_Db2_Exception
+ */
+ throw new Zend_Db_Statement_Db2_Exception("Invalid fetch mode '$style' specified");
+ break;
+ }
+
+ return $row;
+ }
+
+ /**
+ * Fetches the next row and returns it as an object.
+ *
+ * @param string $class OPTIONAL Name of the class to create.
+ * @param array $config OPTIONAL Constructor arguments for the class.
+ * @return mixed One object instance of the specified class.
+ */
+ public function fetchObject($class = 'stdClass', array $config = array())
+ {
+ $obj = $this->fetch(Zend_Db::FETCH_OBJ);
+ return $obj;
+ }
+
+ /**
+ * Retrieves the next rowset (result set) for a SQL statement that has
+ * multiple result sets. An example is a stored procedure that returns
+ * the results of multiple queries.
+ *
+ * @return bool
+ * @throws Zend_Db_Statement_Db2_Exception
+ */
+ public function nextRowset()
+ {
+ /**
+ * @see Zend_Db_Statement_Db2_Exception
+ */
+ throw new Zend_Db_Statement_Db2_Exception(__FUNCTION__ . '() is not implemented');
+ }
+
+ /**
+ * Returns the number of rows affected by the execution of the
+ * last INSERT, DELETE, or UPDATE statement executed by this
+ * statement object.
+ *
+ * @return int The number of rows affected.
+ */
+ public function rowCount()
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+
+ $num = @db2_num_rows($this->_stmt);
+
+ if ($num === false) {
+ return 0;
+ }
+
+ return $num;
+ }
+
+ /**
+ * Returns an array containing all of the result set rows.
+ *
+ * @param int $style OPTIONAL Fetch mode.
+ * @param int $col OPTIONAL Column number, if fetch mode is by column.
+ * @return array Collection of rows, each in a format by the fetch mode.
+ *
+ * Behaves like parent, but if limit()
+ * is used, the final result removes the extra column
+ * 'zend_db_rownum'
+ */
+ public function fetchAll($style = null, $col = null)
+ {
+ $data = parent::fetchAll($style, $col);
+ $results = array();
+ $remove = $this->_adapter->foldCase('ZEND_DB_ROWNUM');
+
+ foreach ($data as $row) {
+ if (is_array($row) && array_key_exists($remove, $row)) {
+ unset($row[$remove]);
+ }
+ $results[] = $row;
+ }
+ return $results;
+ }
+}
diff --git a/library/vendor/Zend/Db/Statement/Db2/Exception.php b/library/vendor/Zend/Db/Statement/Db2/Exception.php
new file mode 100644
index 0000000..d598a85
--- /dev/null
+++ b/library/vendor/Zend/Db/Statement/Db2/Exception.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * Zend_Db_Statement_Exception
+ */
+
+/**
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+class Zend_Db_Statement_Db2_Exception extends Zend_Db_Statement_Exception
+{
+ /**
+ * @var string
+ */
+ protected $code = '00000';
+
+ /**
+ * @var string
+ */
+ protected $message = 'unknown exception';
+
+ /**
+ * @param string $msg
+ * @param string $state
+ */
+ function __construct($msg = 'unknown exception', $state = '00000')
+ {
+ $this->message = $msg;
+ $this->code = $state;
+ }
+
+}
+
diff --git a/library/vendor/Zend/Db/Statement/Exception.php b/library/vendor/Zend/Db/Statement/Exception.php
new file mode 100644
index 0000000..af58699
--- /dev/null
+++ b/library/vendor/Zend/Db/Statement/Exception.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * @see Zend_Db_Exception
+ */
+
+/**
+ * Zend_Db_Statement_Exception
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Statement_Exception extends Zend_Db_Exception
+{
+ /**
+ * Check if this general exception has a specific database driver specific exception nested inside.
+ *
+ * @return bool
+ */
+ public function hasChainedException()
+ {
+ return ($this->getPrevious() !== null);
+ }
+
+ /**
+ * @return Exception|null
+ */
+ public function getChainedException()
+ {
+ return $this->getPrevious();
+ }
+}
diff --git a/library/vendor/Zend/Db/Statement/Interface.php b/library/vendor/Zend/Db/Statement/Interface.php
new file mode 100644
index 0000000..7154d91
--- /dev/null
+++ b/library/vendor/Zend/Db/Statement/Interface.php
@@ -0,0 +1,203 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * Emulates a PDOStatement for native database adapters.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+interface Zend_Db_Statement_Interface
+{
+
+ /**
+ * Bind a column of the statement result set to a PHP variable.
+ *
+ * @param string $column Name the column in the result set, either by
+ * position or by name.
+ * @param mixed $param Reference to the PHP variable containing the value.
+ * @param mixed $type OPTIONAL
+ * @return bool
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function bindColumn($column, &$param, $type = null);
+
+ /**
+ * Binds a parameter to the specified variable name.
+ *
+ * @param mixed $parameter Name the parameter, either integer or string.
+ * @param mixed $variable Reference to PHP variable containing the value.
+ * @param mixed $type OPTIONAL Datatype of SQL parameter.
+ * @param mixed $length OPTIONAL Length of SQL parameter.
+ * @param mixed $options OPTIONAL Other options.
+ * @return bool
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function bindParam($parameter, &$variable, $type = null, $length = null, $options = null);
+
+ /**
+ * Binds a value to a parameter.
+ *
+ * @param mixed $parameter Name the parameter, either integer or string.
+ * @param mixed $value Scalar value to bind to the parameter.
+ * @param mixed $type OPTIONAL Datatype of the parameter.
+ * @return bool
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function bindValue($parameter, $value, $type = null);
+
+ /**
+ * Closes the cursor, allowing the statement to be executed again.
+ *
+ * @return bool
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function closeCursor();
+
+ /**
+ * Returns the number of columns in the result set.
+ * Returns null if the statement has no result set metadata.
+ *
+ * @return int The number of columns.
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function columnCount();
+
+ /**
+ * Retrieves the error code, if any, associated with the last operation on
+ * the statement handle.
+ *
+ * @return string error code.
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function errorCode();
+
+ /**
+ * Retrieves an array of error information, if any, associated with the
+ * last operation on the statement handle.
+ *
+ * @return array
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function errorInfo();
+
+ /**
+ * Executes a prepared statement.
+ *
+ * @param array $params OPTIONAL Values to bind to parameter placeholders.
+ * @return bool
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function execute(array $params = array());
+
+ /**
+ * Fetches a row from the result set.
+ *
+ * @param int $style OPTIONAL Fetch mode for this fetch operation.
+ * @param int $cursor OPTIONAL Absolute, relative, or other.
+ * @param int $offset OPTIONAL Number for absolute or relative cursors.
+ * @return mixed Array, object, or scalar depending on fetch mode.
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function fetch($style = null, $cursor = null, $offset = null);
+
+ /**
+ * Returns an array containing all of the result set rows.
+ *
+ * @param int $style OPTIONAL Fetch mode.
+ * @param int $col OPTIONAL Column number, if fetch mode is by column.
+ * @return array Collection of rows, each in a format by the fetch mode.
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function fetchAll($style = null, $col = null);
+
+ /**
+ * Returns a single column from the next row of a result set.
+ *
+ * @param int $col OPTIONAL Position of the column to fetch.
+ * @return string
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function fetchColumn($col = 0);
+
+ /**
+ * Fetches the next row and returns it as an object.
+ *
+ * @param string $class OPTIONAL Name of the class to create.
+ * @param array $config OPTIONAL Constructor arguments for the class.
+ * @return mixed One object instance of the specified class.
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function fetchObject($class = 'stdClass', array $config = array());
+
+ /**
+ * Retrieve a statement attribute.
+ *
+ * @param string $key Attribute name.
+ * @return mixed Attribute value.
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function getAttribute($key);
+
+ /**
+ * Retrieves the next rowset (result set) for a SQL statement that has
+ * multiple result sets. An example is a stored procedure that returns
+ * the results of multiple queries.
+ *
+ * @return bool
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function nextRowset();
+
+ /**
+ * Returns the number of rows affected by the execution of the
+ * last INSERT, DELETE, or UPDATE statement executed by this
+ * statement object.
+ *
+ * @return int The number of rows affected.
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function rowCount();
+
+ /**
+ * Set a statement attribute.
+ *
+ * @param string $key Attribute name.
+ * @param mixed $val Attribute value.
+ * @return bool
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function setAttribute($key, $val);
+
+ /**
+ * Set the default fetch mode for this statement.
+ *
+ * @param int $mode The fetch mode.
+ * @return bool
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function setFetchMode($mode);
+
+}
diff --git a/library/vendor/Zend/Db/Statement/Mysqli.php b/library/vendor/Zend/Db/Statement/Mysqli.php
new file mode 100644
index 0000000..366d9bf
--- /dev/null
+++ b/library/vendor/Zend/Db/Statement/Mysqli.php
@@ -0,0 +1,356 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+
+/**
+ * @see Zend_Db_Statement
+ */
+
+
+/**
+ * Extends for Mysqli
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Statement_Mysqli extends Zend_Db_Statement
+{
+
+ /**
+ * Column names.
+ *
+ * @var array
+ */
+ protected $_keys;
+
+ /**
+ * Fetched result values.
+ *
+ * @var array
+ */
+ protected $_values;
+
+ /**
+ * @var array
+ */
+ protected $_meta = null;
+
+ /**
+ * @param string $sql
+ * @return void
+ * @throws Zend_Db_Statement_Mysqli_Exception
+ */
+ public function _prepare($sql)
+ {
+ $mysqli = $this->_adapter->getConnection();
+
+ $this->_stmt = $mysqli->prepare($sql);
+
+ if ($this->_stmt === false || $mysqli->errno) {
+ /**
+ * @see Zend_Db_Statement_Mysqli_Exception
+ */
+ throw new Zend_Db_Statement_Mysqli_Exception("Mysqli prepare error: " . $mysqli->error, $mysqli->errno);
+ }
+ }
+
+ /**
+ * Binds a parameter to the specified variable name.
+ *
+ * @param mixed $parameter Name the parameter, either integer or string.
+ * @param mixed $variable Reference to PHP variable containing the value.
+ * @param mixed $type OPTIONAL Datatype of SQL parameter.
+ * @param mixed $length OPTIONAL Length of SQL parameter.
+ * @param mixed $options OPTIONAL Other options.
+ * @return bool
+ * @throws Zend_Db_Statement_Mysqli_Exception
+ */
+ protected function _bindParam($parameter, &$variable, $type = null, $length = null, $options = null)
+ {
+ return true;
+ }
+
+ /**
+ * Closes the cursor and the statement.
+ *
+ * @return bool
+ */
+ public function close()
+ {
+ if ($this->_stmt) {
+ $r = $this->_stmt->close();
+ $this->_stmt = null;
+ return $r;
+ }
+ return false;
+ }
+
+ /**
+ * Closes the cursor, allowing the statement to be executed again.
+ *
+ * @return bool
+ */
+ public function closeCursor()
+ {
+ if ($stmt = $this->_stmt) {
+ $mysqli = $this->_adapter->getConnection();
+ while ($mysqli->more_results()) {
+ $mysqli->next_result();
+ }
+ $this->_stmt->free_result();
+ return $this->_stmt->reset();
+ }
+ return false;
+ }
+
+ /**
+ * Returns the number of columns in the result set.
+ * Returns null if the statement has no result set metadata.
+ *
+ * @return int The number of columns.
+ */
+ public function columnCount()
+ {
+ if (isset($this->_meta) && $this->_meta) {
+ return $this->_meta->field_count;
+ }
+ return 0;
+ }
+
+ /**
+ * Retrieves the error code, if any, associated with the last operation on
+ * the statement handle.
+ *
+ * @return string error code.
+ */
+ public function errorCode()
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+ return substr($this->_stmt->sqlstate, 0, 5);
+ }
+
+ /**
+ * Retrieves an array of error information, if any, associated with the
+ * last operation on the statement handle.
+ *
+ * @return array
+ */
+ public function errorInfo()
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+ return array(
+ substr($this->_stmt->sqlstate, 0, 5),
+ $this->_stmt->errno,
+ $this->_stmt->error,
+ );
+ }
+
+ /**
+ * Executes a prepared statement.
+ *
+ * @param array $params OPTIONAL Values to bind to parameter placeholders.
+ * @return bool
+ * @throws Zend_Db_Statement_Mysqli_Exception
+ */
+ public function _execute(array $params = null)
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+
+ // if no params were given as an argument to execute(),
+ // then default to the _bindParam array
+ if ($params === null) {
+ $params = $this->_bindParam;
+ }
+ // send $params as input parameters to the statement
+ if ($params) {
+ array_unshift($params, str_repeat('s', count($params)));
+ $stmtParams = array();
+ foreach ($params as $k => &$value) {
+ $stmtParams[$k] = &$value;
+ }
+ call_user_func_array(
+ array($this->_stmt, 'bind_param'),
+ $stmtParams
+ );
+ }
+
+ // execute the statement
+ $retval = $this->_stmt->execute();
+ if ($retval === false) {
+ /**
+ * @see Zend_Db_Statement_Mysqli_Exception
+ */
+ throw new Zend_Db_Statement_Mysqli_Exception("Mysqli statement execute error : " . $this->_stmt->error, $this->_stmt->errno);
+ }
+
+
+ // retain metadata
+ if ($this->_meta === null) {
+ $this->_meta = $this->_stmt->result_metadata();
+ if ($this->_stmt->errno) {
+ /**
+ * @see Zend_Db_Statement_Mysqli_Exception
+ */
+ throw new Zend_Db_Statement_Mysqli_Exception("Mysqli statement metadata error: " . $this->_stmt->error, $this->_stmt->errno);
+ }
+ }
+
+ // statements that have no result set do not return metadata
+ if ($this->_meta !== false) {
+
+ // get the column names that will result
+ $this->_keys = array();
+ foreach ($this->_meta->fetch_fields() as $col) {
+ $this->_keys[] = $this->_adapter->foldCase($col->name);
+ }
+
+ // set up a binding space for result variables
+ $this->_values = array_fill(0, count($this->_keys), null);
+
+ // set up references to the result binding space.
+ // just passing $this->_values in the call_user_func_array()
+ // below won't work, you need references.
+ $refs = array();
+ foreach ($this->_values as $i => &$f) {
+ $refs[$i] = &$f;
+ }
+
+ $this->_stmt->store_result();
+ // bind to the result variables
+ call_user_func_array(
+ array($this->_stmt, 'bind_result'),
+ $this->_values
+ );
+ }
+ return $retval;
+ }
+
+
+ /**
+ * Fetches a row from the result set.
+ *
+ * @param int $style OPTIONAL Fetch mode for this fetch operation.
+ * @param int $cursor OPTIONAL Absolute, relative, or other.
+ * @param int $offset OPTIONAL Number for absolute or relative cursors.
+ * @return mixed Array, object, or scalar depending on fetch mode.
+ * @throws Zend_Db_Statement_Mysqli_Exception
+ */
+ public function fetch($style = null, $cursor = null, $offset = null)
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+ // fetch the next result
+ $retval = $this->_stmt->fetch();
+ switch ($retval) {
+ case null: // end of data
+ case false: // error occurred
+ $this->_stmt->reset();
+ return false;
+ default:
+ // fallthrough
+ }
+
+ // make sure we have a fetch mode
+ if ($style === null) {
+ $style = $this->_fetchMode;
+ }
+
+ // dereference the result values, otherwise things like fetchAll()
+ // return the same values for every entry (because of the reference).
+ $values = array();
+ foreach ($this->_values as $key => $val) {
+ $values[] = $val;
+ }
+
+ $row = false;
+ switch ($style) {
+ case Zend_Db::FETCH_NUM:
+ $row = $values;
+ break;
+ case Zend_Db::FETCH_ASSOC:
+ $row = array_combine($this->_keys, $values);
+ break;
+ case Zend_Db::FETCH_BOTH:
+ $assoc = array_combine($this->_keys, $values);
+ $row = array_merge($values, $assoc);
+ break;
+ case Zend_Db::FETCH_OBJ:
+ $row = (object) array_combine($this->_keys, $values);
+ break;
+ case Zend_Db::FETCH_BOUND:
+ $assoc = array_combine($this->_keys, $values);
+ $row = array_merge($values, $assoc);
+ return $this->_fetchBound($row);
+ break;
+ default:
+ /**
+ * @see Zend_Db_Statement_Mysqli_Exception
+ */
+ throw new Zend_Db_Statement_Mysqli_Exception("Invalid fetch mode '$style' specified");
+ break;
+ }
+ return $row;
+ }
+
+ /**
+ * Retrieves the next rowset (result set) for a SQL statement that has
+ * multiple result sets. An example is a stored procedure that returns
+ * the results of multiple queries.
+ *
+ * @return bool
+ * @throws Zend_Db_Statement_Mysqli_Exception
+ */
+ public function nextRowset()
+ {
+ /**
+ * @see Zend_Db_Statement_Mysqli_Exception
+ */
+ throw new Zend_Db_Statement_Mysqli_Exception(__FUNCTION__.'() is not implemented');
+ }
+
+ /**
+ * Returns the number of rows affected by the execution of the
+ * last INSERT, DELETE, or UPDATE statement executed by this
+ * statement object.
+ *
+ * @return int The number of rows affected.
+ */
+ public function rowCount()
+ {
+ if (!$this->_adapter) {
+ return false;
+ }
+ $mysqli = $this->_adapter->getConnection();
+ return $mysqli->affected_rows;
+ }
+
+}
diff --git a/library/vendor/Zend/Db/Statement/Mysqli/Exception.php b/library/vendor/Zend/Db/Statement/Mysqli/Exception.php
new file mode 100644
index 0000000..89c74ec
--- /dev/null
+++ b/library/vendor/Zend/Db/Statement/Mysqli/Exception.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * Zend_Db_Statement_Exception
+ */
+
+/**
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+class Zend_Db_Statement_Mysqli_Exception extends Zend_Db_Statement_Exception
+{
+}
+
diff --git a/library/vendor/Zend/Db/Statement/Oracle.php b/library/vendor/Zend/Db/Statement/Oracle.php
new file mode 100644
index 0000000..58a6c28
--- /dev/null
+++ b/library/vendor/Zend/Db/Statement/Oracle.php
@@ -0,0 +1,561 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * @see Zend_Db_Statement
+ */
+
+/**
+ * Extends for Oracle.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Statement_Oracle extends Zend_Db_Statement
+{
+
+ /**
+ * Column names.
+ */
+ protected $_keys;
+
+ /**
+ * Fetched result values.
+ */
+ protected $_values;
+
+ /**
+ * Check if LOB field are returned as string
+ * instead of OCI-Lob object
+ *
+ * @var boolean
+ */
+ protected $_lobAsString = false;
+
+ /**
+ * Activate/deactivate return of LOB as string
+ *
+ * @param string $lob_as_string
+ * @return Zend_Db_Statement_Oracle
+ */
+ public function setLobAsString($lob_as_string)
+ {
+ $this->_lobAsString = (bool) $lob_as_string;
+ return $this;
+ }
+
+ /**
+ * Return whether or not LOB are returned as string
+ *
+ * @return boolean
+ */
+ public function getLobAsString()
+ {
+ return $this->_lobAsString;
+ }
+
+ /**
+ * Prepares statement handle
+ *
+ * @param string $sql
+ * @return void
+ * @throws Zend_Db_Statement_Oracle_Exception
+ */
+ protected function _prepare($sql)
+ {
+ $connection = $this->_adapter->getConnection();
+ $this->_stmt = @oci_parse($connection, $sql);
+ if (!$this->_stmt) {
+ /**
+ * @see Zend_Db_Statement_Oracle_Exception
+ */
+ throw new Zend_Db_Statement_Oracle_Exception(oci_error($connection));
+ }
+ }
+
+ /**
+ * Binds a parameter to the specified variable name.
+ *
+ * @param mixed $parameter Name the parameter, either integer or string.
+ * @param mixed $variable Reference to PHP variable containing the value.
+ * @param mixed $type OPTIONAL Datatype of SQL parameter.
+ * @param mixed $length OPTIONAL Length of SQL parameter.
+ * @param mixed $options OPTIONAL Other options.
+ * @return bool
+ * @throws Zend_Db_Statement_Exception
+ */
+ protected function _bindParam($parameter, &$variable, $type = null, $length = null, $options = null)
+ {
+ // default value
+ if ($type === NULL) {
+ $type = SQLT_CHR;
+ }
+
+ // default value
+ if ($length === NULL) {
+ $length = -1;
+ }
+
+ $retval = @oci_bind_by_name($this->_stmt, $parameter, $variable, $length, $type);
+ if ($retval === false) {
+ /**
+ * @see Zend_Db_Adapter_Oracle_Exception
+ */
+ throw new Zend_Db_Statement_Oracle_Exception(oci_error($this->_stmt));
+ }
+
+ return true;
+ }
+
+ /**
+ * Closes the cursor, allowing the statement to be executed again.
+ *
+ * @return bool
+ */
+ public function closeCursor()
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+
+ oci_free_statement($this->_stmt);
+ $this->_stmt = false;
+ return true;
+ }
+
+ /**
+ * Returns the number of columns in the result set.
+ * Returns null if the statement has no result set metadata.
+ *
+ * @return int The number of columns.
+ */
+ public function columnCount()
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+
+ return oci_num_fields($this->_stmt);
+ }
+
+
+ /**
+ * Retrieves the error code, if any, associated with the last operation on
+ * the statement handle.
+ *
+ * @return string error code.
+ */
+ public function errorCode()
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+
+ $error = oci_error($this->_stmt);
+
+ if (!$error) {
+ return false;
+ }
+
+ return $error['code'];
+ }
+
+
+ /**
+ * Retrieves an array of error information, if any, associated with the
+ * last operation on the statement handle.
+ *
+ * @return array
+ */
+ public function errorInfo()
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+
+ $error = oci_error($this->_stmt);
+ if (!$error) {
+ return false;
+ }
+
+ if (isset($error['sqltext'])) {
+ return array(
+ $error['code'],
+ $error['message'],
+ $error['offset'],
+ $error['sqltext'],
+ );
+ } else {
+ return array(
+ $error['code'],
+ $error['message'],
+ );
+ }
+ }
+
+
+ /**
+ * Executes a prepared statement.
+ *
+ * @param array $params OPTIONAL Values to bind to parameter placeholders.
+ * @return bool
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function _execute(array $params = null)
+ {
+ $connection = $this->_adapter->getConnection();
+
+ if (!$this->_stmt) {
+ return false;
+ }
+
+ if ($params !== null) {
+ if (!is_array($params)) {
+ $params = array($params);
+ }
+ $error = false;
+ foreach (array_keys($params) as $name) {
+ if (!$this->bindParam($name, $params[$name], null, -1)) {
+ $error = true;
+ break;
+ }
+ }
+ if ($error) {
+ /**
+ * @see Zend_Db_Adapter_Oracle_Exception
+ */
+ throw new Zend_Db_Statement_Oracle_Exception(oci_error($this->_stmt));
+ }
+ }
+
+ $retval = @oci_execute($this->_stmt, $this->_adapter->_getExecuteMode());
+ if ($retval === false) {
+ /**
+ * @see Zend_Db_Adapter_Oracle_Exception
+ */
+ throw new Zend_Db_Statement_Oracle_Exception(oci_error($this->_stmt));
+ }
+
+ $this->_keys = Array();
+ if ($field_num = oci_num_fields($this->_stmt)) {
+ for ($i = 1; $i <= $field_num; $i++) {
+ $name = oci_field_name($this->_stmt, $i);
+ $this->_keys[] = $name;
+ }
+ }
+
+ $this->_values = Array();
+ if ($this->_keys) {
+ $this->_values = array_fill(0, count($this->_keys), null);
+ }
+
+ return $retval;
+ }
+
+ /**
+ * Fetches a row from the result set.
+ *
+ * @param int $style OPTIONAL Fetch mode for this fetch operation.
+ * @param int $cursor OPTIONAL Absolute, relative, or other.
+ * @param int $offset OPTIONAL Number for absolute or relative cursors.
+ * @return mixed Array, object, or scalar depending on fetch mode.
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function fetch($style = null, $cursor = null, $offset = null)
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+
+ if ($style === null) {
+ $style = $this->_fetchMode;
+ }
+
+ $lob_as_string = $this->getLobAsString() ? OCI_RETURN_LOBS : 0;
+
+ switch ($style) {
+ case Zend_Db::FETCH_NUM:
+ $row = oci_fetch_array($this->_stmt, OCI_NUM | OCI_RETURN_NULLS | $lob_as_string);
+ break;
+ case Zend_Db::FETCH_ASSOC:
+ $row = oci_fetch_array($this->_stmt, OCI_ASSOC | OCI_RETURN_NULLS | $lob_as_string);
+ break;
+ case Zend_Db::FETCH_BOTH:
+ $row = oci_fetch_array($this->_stmt, OCI_BOTH | OCI_RETURN_NULLS | $lob_as_string);
+ break;
+ case Zend_Db::FETCH_OBJ:
+ $row = oci_fetch_object($this->_stmt);
+ break;
+ case Zend_Db::FETCH_BOUND:
+ $row = oci_fetch_array($this->_stmt, OCI_BOTH | OCI_RETURN_NULLS | $lob_as_string);
+ if ($row !== false) {
+ return $this->_fetchBound($row);
+ }
+ break;
+ default:
+ /**
+ * @see Zend_Db_Adapter_Oracle_Exception
+ */
+ throw new Zend_Db_Statement_Oracle_Exception(
+ array(
+ 'code' => 'HYC00',
+ 'message' => "Invalid fetch mode '$style' specified"
+ )
+ );
+ break;
+ }
+
+ if (! $row && $error = oci_error($this->_stmt)) {
+ /**
+ * @see Zend_Db_Adapter_Oracle_Exception
+ */
+ throw new Zend_Db_Statement_Oracle_Exception($error);
+ }
+
+ if (is_array($row) && array_key_exists('zend_db_rownum', $row)) {
+ unset($row['zend_db_rownum']);
+ }
+
+ return $row;
+ }
+
+ /**
+ * Returns an array containing all of the result set rows.
+ *
+ * @param int $style OPTIONAL Fetch mode.
+ * @param int $col OPTIONAL Column number, if fetch mode is by column.
+ * @return array Collection of rows, each in a format by the fetch mode.
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function fetchAll($style = null, $col = 0)
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+
+ // make sure we have a fetch mode
+ if ($style === null) {
+ $style = $this->_fetchMode;
+ }
+
+ $flags = OCI_FETCHSTATEMENT_BY_ROW;
+
+ switch ($style) {
+ case Zend_Db::FETCH_BOTH:
+ /**
+ * @see Zend_Db_Adapter_Oracle_Exception
+ */
+ throw new Zend_Db_Statement_Oracle_Exception(
+ array(
+ 'code' => 'HYC00',
+ 'message' => "OCI8 driver does not support fetchAll(FETCH_BOTH), use fetch() in a loop instead"
+ )
+ );
+ // notreached
+ $flags |= OCI_NUM;
+ $flags |= OCI_ASSOC;
+ break;
+ case Zend_Db::FETCH_NUM:
+ $flags |= OCI_NUM;
+ break;
+ case Zend_Db::FETCH_ASSOC:
+ $flags |= OCI_ASSOC;
+ break;
+ case Zend_Db::FETCH_OBJ:
+ break;
+ case Zend_Db::FETCH_COLUMN:
+ $flags = $flags &~ OCI_FETCHSTATEMENT_BY_ROW;
+ $flags |= OCI_FETCHSTATEMENT_BY_COLUMN;
+ $flags |= OCI_NUM;
+ break;
+ default:
+ /**
+ * @see Zend_Db_Adapter_Oracle_Exception
+ */
+ throw new Zend_Db_Statement_Oracle_Exception(
+ array(
+ 'code' => 'HYC00',
+ 'message' => "Invalid fetch mode '$style' specified"
+ )
+ );
+ break;
+ }
+
+ $result = Array();
+ if ($flags != OCI_FETCHSTATEMENT_BY_ROW) { /* not Zend_Db::FETCH_OBJ */
+ if (! ($rows = oci_fetch_all($this->_stmt, $result, 0, -1, $flags) )) {
+ if ($error = oci_error($this->_stmt)) {
+ /**
+ * @see Zend_Db_Adapter_Oracle_Exception
+ */
+ throw new Zend_Db_Statement_Oracle_Exception($error);
+ }
+ if (!$rows) {
+ return array();
+ }
+ }
+ if ($style == Zend_Db::FETCH_COLUMN) {
+ $result = $result[$col];
+ }
+ foreach ($result as &$row) {
+ if (is_array($row) && array_key_exists('zend_db_rownum', $row)) {
+ unset($row['zend_db_rownum']);
+ }
+ }
+ } else {
+ while (($row = oci_fetch_object($this->_stmt)) !== false) {
+ $result [] = $row;
+ }
+ if ($error = oci_error($this->_stmt)) {
+ /**
+ * @see Zend_Db_Adapter_Oracle_Exception
+ */
+ throw new Zend_Db_Statement_Oracle_Exception($error);
+ }
+ }
+
+ return $result;
+ }
+
+
+ /**
+ * Returns a single column from the next row of a result set.
+ *
+ * @param int $col OPTIONAL Position of the column to fetch.
+ * @return string
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function fetchColumn($col = 0)
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+
+ if (!oci_fetch($this->_stmt)) {
+ // if no error, there is simply no record
+ if (!$error = oci_error($this->_stmt)) {
+ return false;
+ }
+ /**
+ * @see Zend_Db_Adapter_Oracle_Exception
+ */
+ throw new Zend_Db_Statement_Oracle_Exception($error);
+ }
+
+ $data = oci_result($this->_stmt, $col+1); //1-based
+ if ($data === false) {
+ /**
+ * @see Zend_Db_Adapter_Oracle_Exception
+ */
+ throw new Zend_Db_Statement_Oracle_Exception(oci_error($this->_stmt));
+ }
+
+ if ($this->getLobAsString()) {
+ // instanceof doesn't allow '-', we must use a temporary string
+ $type = 'OCI-Lob';
+ if ($data instanceof $type) {
+ $data = $data->read($data->size());
+ }
+ }
+
+ return $data;
+ }
+
+ /**
+ * Fetches the next row and returns it as an object.
+ *
+ * @param string $class OPTIONAL Name of the class to create.
+ * @param array $config OPTIONAL Constructor arguments for the class.
+ * @return mixed One object instance of the specified class.
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function fetchObject($class = 'stdClass', array $config = array())
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+
+ $obj = oci_fetch_object($this->_stmt);
+
+ if ($error = oci_error($this->_stmt)) {
+ /**
+ * @see Zend_Db_Adapter_Oracle_Exception
+ */
+ throw new Zend_Db_Statement_Oracle_Exception($error);
+ }
+
+ /* @todo XXX handle parameters */
+
+ return $obj;
+ }
+
+ /**
+ * Retrieves the next rowset (result set) for a SQL statement that has
+ * multiple result sets. An example is a stored procedure that returns
+ * the results of multiple queries.
+ *
+ * @return bool
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function nextRowset()
+ {
+ /**
+ * @see Zend_Db_Statement_Oracle_Exception
+ */
+ throw new Zend_Db_Statement_Oracle_Exception(
+ array(
+ 'code' => 'HYC00',
+ 'message' => 'Optional feature not implemented'
+ )
+ );
+ }
+
+ /**
+ * Returns the number of rows affected by the execution of the
+ * last INSERT, DELETE, or UPDATE statement executed by this
+ * statement object.
+ *
+ * @return int The number of rows affected.
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function rowCount()
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+
+ $num_rows = oci_num_rows($this->_stmt);
+
+ if ($num_rows === false) {
+ /**
+ * @see Zend_Db_Adapter_Oracle_Exception
+ */
+ throw new Zend_Db_Statement_Oracle_Exception(oci_error($this->_stmt));
+ }
+
+ return $num_rows;
+ }
+
+}
diff --git a/library/vendor/Zend/Db/Statement/Oracle/Exception.php b/library/vendor/Zend/Db/Statement/Oracle/Exception.php
new file mode 100644
index 0000000..feaa4cb
--- /dev/null
+++ b/library/vendor/Zend/Db/Statement/Oracle/Exception.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * Zend_Db_Statement_Exception
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+class Zend_Db_Statement_Oracle_Exception extends Zend_Db_Statement_Exception
+{
+ protected $message = 'Unknown exception';
+ protected $code = 0;
+
+ function __construct($error = null, $code = 0)
+ {
+ if (is_array($error)) {
+ if (!isset($error['offset'])) {
+ $this->message = $error['code']." ".$error['message'];
+ } else {
+ $this->message = $error['code']." ".$error['message']." ";
+ $this->message .= substr($error['sqltext'], 0, $error['offset']);
+ $this->message .= "*";
+ $this->message .= substr($error['sqltext'], $error['offset']);
+ }
+ $this->code = $error['code'];
+ }
+ if (!$this->code && $code) {
+ $this->code = $code;
+ }
+ }
+}
+
diff --git a/library/vendor/Zend/Db/Statement/Pdo.php b/library/vendor/Zend/Db/Statement/Pdo.php
new file mode 100644
index 0000000..47f9031
--- /dev/null
+++ b/library/vendor/Zend/Db/Statement/Pdo.php
@@ -0,0 +1,426 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * @see Zend_Db_Statement
+ */
+
+/**
+ * Proxy class to wrap a PDOStatement object.
+ * Matches the interface of PDOStatement. All methods simply proxy to the
+ * matching method in PDOStatement. PDOExceptions thrown by PDOStatement
+ * are re-thrown as Zend_Db_Statement_Exception.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Statement_Pdo extends Zend_Db_Statement implements IteratorAggregate
+{
+
+ /**
+ * @var int
+ */
+ protected $_fetchMode = PDO::FETCH_ASSOC;
+
+ /**
+ * Prepare a string SQL statement and create a statement object.
+ *
+ * @param string $sql
+ * @return void
+ * @throws Zend_Db_Statement_Exception
+ */
+ protected function _prepare($sql)
+ {
+ try {
+ $this->_stmt = $this->_adapter->getConnection()->prepare($sql);
+ } catch (PDOException $e) {
+ throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * Bind a column of the statement result set to a PHP variable.
+ *
+ * @param string $column Name the column in the result set, either by
+ * position or by name.
+ * @param mixed $param Reference to the PHP variable containing the value.
+ * @param mixed $type OPTIONAL
+ * @return bool
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function bindColumn($column, &$param, $type = null)
+ {
+ try {
+ if ($type === null) {
+ return $this->_stmt->bindColumn($column, $param);
+ } else {
+ return $this->_stmt->bindColumn($column, $param, $type);
+ }
+ } catch (PDOException $e) {
+ throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * Binds a parameter to the specified variable name.
+ *
+ * @param mixed $parameter Name the parameter, either integer or string.
+ * @param mixed $variable Reference to PHP variable containing the value.
+ * @param mixed $type OPTIONAL Datatype of SQL parameter.
+ * @param mixed $length OPTIONAL Length of SQL parameter.
+ * @param mixed $options OPTIONAL Other options.
+ * @return bool
+ * @throws Zend_Db_Statement_Exception
+ */
+ protected function _bindParam($parameter, &$variable, $type = null, $length = null, $options = null)
+ {
+ try {
+ if ($type === null) {
+ if (is_bool($variable)) {
+ $type = PDO::PARAM_BOOL;
+ } elseif ($variable === null) {
+ $type = PDO::PARAM_NULL;
+ } elseif (is_integer($variable)) {
+ $type = PDO::PARAM_INT;
+ } else {
+ $type = PDO::PARAM_STR;
+ }
+ }
+ return $this->_stmt->bindParam($parameter, $variable, $type, $length, $options);
+ } catch (PDOException $e) {
+ throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * Binds a value to a parameter.
+ *
+ * @param mixed $parameter Name the parameter, either integer or string.
+ * @param mixed $value Scalar value to bind to the parameter.
+ * @param mixed $type OPTIONAL Datatype of the parameter.
+ * @return bool
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function bindValue($parameter, $value, $type = null)
+ {
+ if (is_string($parameter) && $parameter[0] != ':') {
+ $parameter = ":$parameter";
+ }
+
+ $this->_bindParam[$parameter] = $value;
+
+ try {
+ if ($type === null) {
+ return $this->_stmt->bindValue($parameter, $value);
+ } else {
+ return $this->_stmt->bindValue($parameter, $value, $type);
+ }
+ } catch (PDOException $e) {
+ throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * Closes the cursor, allowing the statement to be executed again.
+ *
+ * @return bool
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function closeCursor()
+ {
+ try {
+ return $this->_stmt->closeCursor();
+ } catch (PDOException $e) {
+ throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * Returns the number of columns in the result set.
+ * Returns null if the statement has no result set metadata.
+ *
+ * @return int The number of columns.
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function columnCount()
+ {
+ try {
+ return $this->_stmt->columnCount();
+ } catch (PDOException $e) {
+ throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * Retrieves the error code, if any, associated with the last operation on
+ * the statement handle.
+ *
+ * @return string error code.
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function errorCode()
+ {
+ try {
+ return $this->_stmt->errorCode();
+ } catch (PDOException $e) {
+ throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * Retrieves an array of error information, if any, associated with the
+ * last operation on the statement handle.
+ *
+ * @return array
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function errorInfo()
+ {
+ try {
+ return $this->_stmt->errorInfo();
+ } catch (PDOException $e) {
+ throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * Executes a prepared statement.
+ *
+ * @param array $params OPTIONAL Values to bind to parameter placeholders.
+ * @return bool
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function _execute(array $params = null)
+ {
+ try {
+ if ($params !== null) {
+ return $this->_stmt->execute($params);
+ } else {
+ return $this->_stmt->execute();
+ }
+ } catch (PDOException $e) {
+ $message = sprintf('%s, query was: %s', $e->getMessage(), $this->_stmt->queryString);
+ throw new Zend_Db_Statement_Exception($message, (int) $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * Fetches a row from the result set.
+ *
+ * @param int $style OPTIONAL Fetch mode for this fetch operation.
+ * @param int $cursor OPTIONAL Absolute, relative, or other.
+ * @param int $offset OPTIONAL Number for absolute or relative cursors.
+ * @return mixed Array, object, or scalar depending on fetch mode.
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function fetch($style = null, $cursor = null, $offset = null)
+ {
+ if ($style === null) {
+ $style = $this->_fetchMode;
+ }
+ if ($cursor === null) {
+ $cursor = PDO::FETCH_ORI_NEXT;
+ }
+ if ($offset === null) {
+ $offset = 0;
+ }
+ try {
+ return $this->_stmt->fetch($style, $cursor, $offset);
+ } catch (PDOException $e) {
+ throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * Required by IteratorAggregate interface
+ *
+ * @return IteratorIterator
+ */
+ public function getIterator(): Traversable
+ {
+ return new IteratorIterator($this->_stmt);
+ }
+
+ /**
+ * Returns an array containing all of the result set rows.
+ *
+ * @param int $style OPTIONAL Fetch mode.
+ * @param int $col OPTIONAL Column number, if fetch mode is by column.
+ * @return array Collection of rows, each in a format by the fetch mode.
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function fetchAll($style = null, $col = null)
+ {
+ if ($style === null) {
+ $style = $this->_fetchMode;
+ }
+ try {
+ if ($style == PDO::FETCH_COLUMN) {
+ if ($col === null) {
+ $col = 0;
+ }
+ return $this->_stmt->fetchAll($style, $col);
+ } else {
+ return $this->_stmt->fetchAll($style);
+ }
+ } catch (PDOException $e) {
+ throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * Returns a single column from the next row of a result set.
+ *
+ * @param int $col OPTIONAL Position of the column to fetch.
+ * @return string
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function fetchColumn($col = 0)
+ {
+ try {
+ return $this->_stmt->fetchColumn($col);
+ } catch (PDOException $e) {
+ throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * Fetches the next row and returns it as an object.
+ *
+ * @param string $class OPTIONAL Name of the class to create.
+ * @param array $config OPTIONAL Constructor arguments for the class.
+ * @return mixed One object instance of the specified class.
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function fetchObject($class = 'stdClass', array $config = array())
+ {
+ try {
+ return $this->_stmt->fetchObject($class, $config);
+ } catch (PDOException $e) {
+ throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * Retrieve a statement attribute.
+ *
+ * @param integer $key Attribute name.
+ * @return mixed Attribute value.
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function getAttribute($key)
+ {
+ try {
+ return $this->_stmt->getAttribute($key);
+ } catch (PDOException $e) {
+ throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * Returns metadata for a column in a result set.
+ *
+ * @param int $column
+ * @return mixed
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function getColumnMeta($column)
+ {
+ try {
+ return $this->_stmt->getColumnMeta($column);
+ } catch (PDOException $e) {
+ throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * Retrieves the next rowset (result set) for a SQL statement that has
+ * multiple result sets. An example is a stored procedure that returns
+ * the results of multiple queries.
+ *
+ * @return bool
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function nextRowset()
+ {
+ try {
+ return $this->_stmt->nextRowset();
+ } catch (PDOException $e) {
+ throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * Returns the number of rows affected by the execution of the
+ * last INSERT, DELETE, or UPDATE statement executed by this
+ * statement object.
+ *
+ * @return int The number of rows affected.
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function rowCount()
+ {
+ try {
+ return $this->_stmt->rowCount();
+ } catch (PDOException $e) {
+ throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * Set a statement attribute.
+ *
+ * @param string $key Attribute name.
+ * @param mixed $val Attribute value.
+ * @return bool
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function setAttribute($key, $val)
+ {
+ try {
+ return $this->_stmt->setAttribute($key, $val);
+ } catch (PDOException $e) {
+ throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * Set the default fetch mode for this statement.
+ *
+ * @param int $mode The fetch mode.
+ * @return bool
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function setFetchMode($mode)
+ {
+ $this->_fetchMode = $mode;
+ try {
+ return $this->_stmt->setFetchMode($mode);
+ } catch (PDOException $e) {
+ throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+}
diff --git a/library/vendor/Zend/Db/Statement/Pdo/Ibm.php b/library/vendor/Zend/Db/Statement/Pdo/Ibm.php
new file mode 100644
index 0000000..84f265e
--- /dev/null
+++ b/library/vendor/Zend/Db/Statement/Pdo/Ibm.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * @see Zend_Db_Statement_Pdo
+ */
+
+/**
+ * Proxy class to wrap a PDOStatement object for IBM Databases.
+ * Matches the interface of PDOStatement. All methods simply proxy to the
+ * matching method in PDOStatement. PDOExceptions thrown by PDOStatement
+ * are re-thrown as Zend_Db_Statement_Exception.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Statement_Pdo_Ibm extends Zend_Db_Statement_Pdo
+{
+ /**
+ * Returns an array containing all of the result set rows.
+ *
+ * Behaves like parent, but if limit()
+ * is used, the final result removes the extra column
+ * 'zend_db_rownum'
+ *
+ * @param int $style OPTIONAL Fetch mode.
+ * @param int $col OPTIONAL Column number, if fetch mode is by column.
+ * @return array Collection of rows, each in a format by the fetch mode.
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function fetchAll($style = null, $col = null)
+ {
+ $data = parent::fetchAll($style, $col);
+ $results = array();
+ $remove = $this->_adapter->foldCase('ZEND_DB_ROWNUM');
+
+ foreach ($data as $row) {
+ if (is_array($row) && array_key_exists($remove, $row)) {
+ unset($row[$remove]);
+ }
+ $results[] = $row;
+ }
+ return $results;
+ }
+
+ /**
+ * Binds a parameter to the specified variable name.
+ *
+ * @param mixed $parameter Name the parameter, either integer or string.
+ * @param mixed $variable Reference to PHP variable containing the value.
+ * @param mixed $type OPTIONAL Datatype of SQL parameter.
+ * @param mixed $length OPTIONAL Length of SQL parameter.
+ * @param mixed $options OPTIONAL Other options.
+ * @return bool
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function _bindParam($parameter, &$variable, $type = null, $length = null, $options = null)
+ {
+ try {
+ if (($type === null) && ($length === null) && ($options === null)) {
+ return $this->_stmt->bindParam($parameter, $variable);
+ } else {
+ return $this->_stmt->bindParam($parameter, $variable, $type, $length, $options);
+ }
+ } catch (PDOException $e) {
+ throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+}
diff --git a/library/vendor/Zend/Db/Statement/Pdo/Oci.php b/library/vendor/Zend/Db/Statement/Pdo/Oci.php
new file mode 100644
index 0000000..79334ad
--- /dev/null
+++ b/library/vendor/Zend/Db/Statement/Pdo/Oci.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * @see Zend_Db_Statement_Pdo
+ */
+
+/**
+ * Proxy class to wrap a PDOStatement object for IBM Databases.
+ * Matches the interface of PDOStatement. All methods simply proxy to the
+ * matching method in PDOStatement. PDOExceptions thrown by PDOStatement
+ * are re-thrown as Zend_Db_Statement_Exception.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Statement_Pdo_Oci extends Zend_Db_Statement_Pdo
+{
+
+ /**
+ * Returns an array containing all of the result set rows.
+ *
+ * Behaves like parent, but if limit()
+ * is used, the final result removes the extra column
+ * 'zend_db_rownum'
+ *
+ * @param int $style OPTIONAL Fetch mode.
+ * @param int $col OPTIONAL Column number, if fetch mode is by column.
+ * @return array Collection of rows, each in a format by the fetch mode.
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function fetchAll($style = null, $col = null)
+ {
+ $data = parent::fetchAll($style, $col);
+ $results = array();
+ $remove = $this->_adapter->foldCase('zend_db_rownum');
+
+ foreach ($data as $row) {
+ if (is_array($row) && array_key_exists($remove, $row)) {
+ unset($row[$remove]);
+ }
+ $results[] = $row;
+ }
+ return $results;
+ }
+
+
+ /**
+ * Fetches a row from the result set.
+ *
+ * @param int $style OPTIONAL Fetch mode for this fetch operation.
+ * @param int $cursor OPTIONAL Absolute, relative, or other.
+ * @param int $offset OPTIONAL Number for absolute or relative cursors.
+ * @return mixed Array, object, or scalar depending on fetch mode.
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function fetch($style = null, $cursor = null, $offset = null)
+ {
+ $row = parent::fetch($style, $cursor, $offset);
+
+ $remove = $this->_adapter->foldCase('zend_db_rownum');
+ if (is_array($row) && array_key_exists($remove, $row)) {
+ unset($row[$remove]);
+ }
+
+ return $row;
+ }
+}
diff --git a/library/vendor/Zend/Db/Statement/Sqlsrv.php b/library/vendor/Zend/Db/Statement/Sqlsrv.php
new file mode 100644
index 0000000..84294e8
--- /dev/null
+++ b/library/vendor/Zend/Db/Statement/Sqlsrv.php
@@ -0,0 +1,430 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * @see Zend_Db_Statement
+ */
+
+/**
+ * Extends for Microsoft SQL Server Driver for PHP
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Statement_Sqlsrv extends Zend_Db_Statement
+{
+
+ /**
+ * The connection_stmt object original string.
+ */
+ protected $_originalSQL;
+
+ /**
+ * Column names.
+ */
+ protected $_keys;
+
+ /**
+ * Query executed
+ */
+ protected $_executed = false;
+
+ /**
+ * Prepares statement handle
+ *
+ * @param string $sql
+ * @return void
+ * @throws Zend_Db_Statement_Sqlsrv_Exception
+ */
+ protected function _prepare($sql)
+ {
+ $connection = $this->_adapter->getConnection();
+
+ $this->_stmt = sqlsrv_prepare($connection, $sql);
+
+ if (!$this->_stmt) {
+ throw new Zend_Db_Statement_Sqlsrv_Exception(sqlsrv_errors());
+ }
+
+ $this->_originalSQL = $sql;
+ }
+
+ /**
+ * Binds a parameter to the specified variable name.
+ *
+ * @param mixed $parameter Name the parameter, either integer or string.
+ * @param mixed $variable Reference to PHP variable containing the value.
+ * @param mixed $type OPTIONAL Datatype of SQL parameter.
+ * @param mixed $length OPTIONAL Length of SQL parameter.
+ * @param mixed $options OPTIONAL Other options.
+ * @return bool
+ * @throws Zend_Db_Statement_Exception
+ */
+ protected function _bindParam($parameter, &$variable, $type = null, $length = null, $options = null)
+ {
+ //Sql server doesn't support bind by name
+ return true;
+ }
+
+ /**
+ * Closes the cursor, allowing the statement to be executed again.
+ *
+ * @return bool
+ */
+ public function closeCursor()
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+
+ sqlsrv_free_stmt($this->_stmt);
+ $this->_stmt = false;
+ return true;
+ }
+
+ /**
+ * Returns the number of columns in the result set.
+ * Returns null if the statement has no result set metadata.
+ *
+ * @return int The number of columns.
+ */
+ public function columnCount()
+ {
+ if ($this->_stmt && $this->_executed) {
+ return sqlsrv_num_fields($this->_stmt);
+ }
+
+ return 0;
+ }
+
+
+ /**
+ * Retrieves the error code, if any, associated with the last operation on
+ * the statement handle.
+ *
+ * @return string error code.
+ */
+ public function errorCode()
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+
+ $error = sqlsrv_errors();
+ if (!$error) {
+ return false;
+ }
+
+ return $error[0]['code'];
+ }
+
+
+ /**
+ * Retrieves an array of error information, if any, associated with the
+ * last operation on the statement handle.
+ *
+ * @return array
+ */
+ public function errorInfo()
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+
+ $error = sqlsrv_errors();
+ if (!$error) {
+ return false;
+ }
+
+ return array(
+ $error[0]['code'],
+ $error[0]['message'],
+ );
+ }
+
+
+ /**
+ * Executes a prepared statement.
+ *
+ * @param array $params OPTIONAL Values to bind to parameter placeholders.
+ * @return bool
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function _execute(array $params = null)
+ {
+ $connection = $this->_adapter->getConnection();
+ if (!$this->_stmt) {
+ return false;
+ }
+
+ if ($params !== null) {
+ if (!is_array($params)) {
+ $params = array($params);
+ }
+ $error = false;
+
+ // make all params passed by reference
+ $params_ = array();
+ $temp = array();
+ $i = 1;
+ foreach ($params as $param) {
+ $temp[$i] = $param;
+ $params_[] = &$temp[$i];
+ $i++;
+ }
+ $params = $params_;
+ }
+
+ $this->_stmt = sqlsrv_query($connection, $this->_originalSQL, $params);
+
+ if (!$this->_stmt) {
+ throw new Zend_Db_Statement_Sqlsrv_Exception(sqlsrv_errors());
+ }
+
+ $this->_executed = true;
+
+ return (!$this->_stmt);
+ }
+
+ /**
+ * Fetches a row from the result set.
+ *
+ * @param int $style OPTIONAL Fetch mode for this fetch operation.
+ * @param int $cursor OPTIONAL Absolute, relative, or other.
+ * @param int $offset OPTIONAL Number for absolute or relative cursors.
+ * @return mixed Array, object, or scalar depending on fetch mode.
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function fetch($style = null, $cursor = null, $offset = null)
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+
+ if (null === $style) {
+ $style = $this->_fetchMode;
+ }
+
+ $values = sqlsrv_fetch_array($this->_stmt, SQLSRV_FETCH_ASSOC);
+
+ if (!$values && (null !== $error = sqlsrv_errors())) {
+ throw new Zend_Db_Statement_Sqlsrv_Exception($error);
+ }
+
+ if (null === $values) {
+ return null;
+ }
+
+ if (!$this->_keys) {
+ foreach ($values as $key => $value) {
+ $this->_keys[] = $this->_adapter->foldCase($key);
+ }
+ }
+
+ $values = array_values($values);
+
+ $row = false;
+ switch ($style) {
+ case Zend_Db::FETCH_NUM:
+ $row = $values;
+ break;
+ case Zend_Db::FETCH_ASSOC:
+ $row = array_combine($this->_keys, $values);
+ break;
+ case Zend_Db::FETCH_BOTH:
+ $assoc = array_combine($this->_keys, $values);
+ $row = array_merge($values, $assoc);
+ break;
+ case Zend_Db::FETCH_OBJ:
+ $row = (object) array_combine($this->_keys, $values);
+ break;
+ case Zend_Db::FETCH_BOUND:
+ $assoc = array_combine($this->_keys, $values);
+ $row = array_merge($values, $assoc);
+ $row = $this->_fetchBound($row);
+ break;
+ default:
+ throw new Zend_Db_Statement_Sqlsrv_Exception("Invalid fetch mode '$style' specified");
+ break;
+ }
+
+ return $row;
+ }
+
+ /**
+ * Returns a single column from the next row of a result set.
+ *
+ * @param int $col OPTIONAL Position of the column to fetch.
+ * @return string
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function fetchColumn($col = 0)
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+
+ if (!sqlsrv_fetch($this->_stmt)) {
+ if (null !== $error = sqlsrv_errors()) {
+ throw new Zend_Db_Statement_Sqlsrv_Exception($error);
+ }
+
+ // If no error, there is simply no record
+ return false;
+ }
+
+ $data = sqlsrv_get_field($this->_stmt, $col); //0-based
+ if ($data === false) {
+ throw new Zend_Db_Statement_Sqlsrv_Exception(sqlsrv_errors());
+ }
+
+ return $data;
+ }
+
+ /**
+ * Fetches the next row and returns it as an object.
+ *
+ * @param string $class OPTIONAL Name of the class to create.
+ * @param array $config OPTIONAL Constructor arguments for the class.
+ * @return mixed One object instance of the specified class.
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function fetchObject($class = 'stdClass', array $config = array())
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+
+ $obj = sqlsrv_fetch_object($this->_stmt);
+
+ if ($error = sqlsrv_errors()) {
+ throw new Zend_Db_Statement_Sqlsrv_Exception($error);
+ }
+
+ /* @todo XXX handle parameters */
+
+ if (null === $obj) {
+ return false;
+ }
+
+ return $obj;
+ }
+
+ /**
+ * Returns metadata for a column in a result set.
+ *
+ * @param int $column
+ * @return mixed
+ * @throws Zend_Db_Statement_Sqlsrv_Exception
+ */
+ public function getColumnMeta($column)
+ {
+ $fields = sqlsrv_field_metadata($this->_stmt);
+
+ if (!$fields) {
+ throw new Zend_Db_Statement_Sqlsrv_Exception('Column metadata can not be fetched');
+ }
+
+ if (!isset($fields[$column])) {
+ throw new Zend_Db_Statement_Sqlsrv_Exception('Column index does not exist in statement');
+ }
+
+ return $fields[$column];
+ }
+
+ /**
+ * Retrieves the next rowset (result set) for a SQL statement that has
+ * multiple result sets. An example is a stored procedure that returns
+ * the results of multiple queries.
+ *
+ * @return bool
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function nextRowset()
+ {
+ if (sqlsrv_next_result($this->_stmt) === false) {
+ throw new Zend_Db_Statement_Sqlsrv_Exception(sqlsrv_errors());
+ }
+
+ // reset column keys
+ $this->_keys = null;
+
+ return true;
+ }
+
+ /**
+ * Returns the number of rows affected by the execution of the
+ * last INSERT, DELETE, or UPDATE statement executed by this
+ * statement object.
+ *
+ * @return int The number of rows affected.
+ * @throws Zend_Db_Statement_Exception
+ */
+ public function rowCount()
+ {
+ if (!$this->_stmt) {
+ return false;
+ }
+
+ if (!$this->_executed) {
+ return 0;
+ }
+
+ $num_rows = sqlsrv_rows_affected($this->_stmt);
+
+ // Strict check is necessary; 0 is a valid return value
+ if ($num_rows === false) {
+ throw new Zend_Db_Statement_Sqlsrv_Exception(sqlsrv_errors());
+ }
+
+ return $num_rows;
+ }
+
+ /**
+ * Returns an array containing all of the result set rows.
+ *
+ * @param int $style OPTIONAL Fetch mode.
+ * @param int $col OPTIONAL Column number, if fetch mode is by column.
+ * @return array Collection of rows, each in a format by the fetch mode.
+ *
+ * Behaves like parent, but if limit()
+ * is used, the final result removes the extra column
+ * 'zend_db_rownum'
+ */
+ public function fetchAll($style = null, $col = null)
+ {
+ $data = parent::fetchAll($style, $col);
+ $results = array();
+ $remove = $this->_adapter->foldCase('ZEND_DB_ROWNUM');
+
+ foreach ($data as $row) {
+ if (is_array($row) && array_key_exists($remove, $row)) {
+ unset($row[$remove]);
+ }
+ $results[] = $row;
+ }
+ return $results;
+ }
+}
diff --git a/library/vendor/Zend/Db/Statement/Sqlsrv/Exception.php b/library/vendor/Zend/Db/Statement/Sqlsrv/Exception.php
new file mode 100644
index 0000000..3358f3b
--- /dev/null
+++ b/library/vendor/Zend/Db/Statement/Sqlsrv/Exception.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * @see Zend_Db_Statement_Exception
+ */
+
+/**
+ * @package Zend_Db
+ * @subpackage Statement
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Statement_Sqlsrv_Exception extends Zend_Db_Statement_Exception
+{
+ /**
+ * Constructor
+ *
+ * If $message is an array, the assumption is that the return value of
+ * sqlsrv_errors() was provided. If so, it then retrieves the most recent
+ * error from that stack, and sets the message and code based on it.
+ *
+ * @param null|array|string $message
+ * @param null|int $code
+ */
+ public function __construct($message = null, $code = 0)
+ {
+ if (is_array($message)) {
+ // Error should be array of errors
+ // We only need first one (?)
+ if (isset($message[0])) {
+ $message = $message[0];
+ }
+
+ $code = (int) $message['code'];
+ $message = (string) $message['message'];
+ }
+ parent::__construct($message, $code);
+ }
+}
+
diff --git a/library/vendor/Zend/Db/Table.php b/library/vendor/Zend/Db/Table.php
new file mode 100644
index 0000000..0dbfe8c
--- /dev/null
+++ b/library/vendor/Zend/Db/Table.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Table
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * @see Zend_Db_Table_Abstract
+ */
+
+/**
+ * @see Zend_Db_Table_Definition
+ */
+
+/**
+ * Class for SQL table interface.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Table
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Table extends Zend_Db_Table_Abstract
+{
+
+ /**
+ * __construct() - For concrete implementation of Zend_Db_Table
+ *
+ * @param string|array $config string can reference a Zend_Registry key for a db adapter
+ * OR it can reference the name of a table
+ * @param array|Zend_Db_Table_Definition $definition
+ */
+ public function __construct($config = array(), $definition = null)
+ {
+ if ($definition !== null && is_array($definition)) {
+ $definition = new Zend_Db_Table_Definition($definition);
+ }
+
+ if (is_string($config)) {
+ if (Zend_Registry::isRegistered($config)) {
+ trigger_error(__CLASS__ . '::' . __METHOD__ . '(\'registryName\') is not valid usage of Zend_Db_Table, '
+ . 'try extending Zend_Db_Table_Abstract in your extending classes.',
+ E_USER_NOTICE
+ );
+ $config = array(self::ADAPTER => $config);
+ } else {
+ // process this as table with or without a definition
+ if ($definition instanceof Zend_Db_Table_Definition
+ && $definition->hasTableConfig($config)) {
+ // this will have DEFINITION_CONFIG_NAME & DEFINITION
+ $config = $definition->getTableConfig($config);
+ } else {
+ $config = array(self::NAME => $config);
+ }
+ }
+ }
+
+ parent::__construct($config);
+ }
+}
diff --git a/library/vendor/Zend/Db/Table/Abstract.php b/library/vendor/Zend/Db/Table/Abstract.php
new file mode 100644
index 0000000..ea393f2
--- /dev/null
+++ b/library/vendor/Zend/Db/Table/Abstract.php
@@ -0,0 +1,1599 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Table
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * @see Zend_Db_Adapter_Abstract
+ */
+
+/**
+ * @see Zend_Db_Adapter_Abstract
+ */
+
+/**
+ * @see Zend_Db
+ */
+
+/**
+ * Class for SQL table interface.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Table
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+abstract class Zend_Db_Table_Abstract
+{
+
+ const ADAPTER = 'db';
+ const DEFINITION = 'definition';
+ const DEFINITION_CONFIG_NAME = 'definitionConfigName';
+ const SCHEMA = 'schema';
+ const NAME = 'name';
+ const PRIMARY = 'primary';
+ const COLS = 'cols';
+ const METADATA = 'metadata';
+ const METADATA_CACHE = 'metadataCache';
+ const METADATA_CACHE_IN_CLASS = 'metadataCacheInClass';
+ const ROW_CLASS = 'rowClass';
+ const ROWSET_CLASS = 'rowsetClass';
+ const REFERENCE_MAP = 'referenceMap';
+ const DEPENDENT_TABLES = 'dependentTables';
+ const SEQUENCE = 'sequence';
+
+ const COLUMNS = 'columns';
+ const REF_TABLE_CLASS = 'refTableClass';
+ const REF_COLUMNS = 'refColumns';
+ const ON_DELETE = 'onDelete';
+ const ON_UPDATE = 'onUpdate';
+
+ const CASCADE = 'cascade';
+ const CASCADE_RECURSE = 'cascadeRecurse';
+ const RESTRICT = 'restrict';
+ const SET_NULL = 'setNull';
+
+ const DEFAULT_NONE = 'defaultNone';
+ const DEFAULT_CLASS = 'defaultClass';
+ const DEFAULT_DB = 'defaultDb';
+
+ const SELECT_WITH_FROM_PART = true;
+ const SELECT_WITHOUT_FROM_PART = false;
+
+ /**
+ * Default Zend_Db_Adapter_Abstract object.
+ *
+ * @var Zend_Db_Adapter_Abstract
+ */
+ protected static $_defaultDb;
+
+ /**
+ * Optional Zend_Db_Table_Definition object
+ *
+ * @var unknown_type
+ */
+ protected $_definition = null;
+
+ /**
+ * Optional definition config name used in concrete implementation
+ *
+ * @var string
+ */
+ protected $_definitionConfigName = null;
+
+ /**
+ * Default cache for information provided by the adapter's describeTable() method.
+ *
+ * @var Zend_Cache_Core
+ */
+ protected static $_defaultMetadataCache = null;
+
+ /**
+ * Zend_Db_Adapter_Abstract object.
+ *
+ * @var Zend_Db_Adapter_Abstract
+ */
+ protected $_db;
+
+ /**
+ * The schema name (default null means current schema)
+ *
+ * @var array
+ */
+ protected $_schema = null;
+
+ /**
+ * The table name.
+ *
+ * @var string
+ */
+ protected $_name = null;
+
+ /**
+ * The table column names derived from Zend_Db_Adapter_Abstract::describeTable().
+ *
+ * @var array
+ */
+ protected $_cols;
+
+ /**
+ * The primary key column or columns.
+ * A compound key should be declared as an array.
+ * You may declare a single-column primary key
+ * as a string.
+ *
+ * @var mixed
+ */
+ protected $_primary = null;
+
+ /**
+ * If your primary key is a compound key, and one of the columns uses
+ * an auto-increment or sequence-generated value, set _identity
+ * to the ordinal index in the $_primary array for that column.
+ * Note this index is the position of the column in the primary key,
+ * not the position of the column in the table. The primary key
+ * array is 1-based.
+ *
+ * @var integer
+ */
+ protected $_identity = 1;
+
+ /**
+ * Define the logic for new values in the primary key.
+ * May be a string, boolean true, or boolean false.
+ *
+ * @var mixed
+ */
+ protected $_sequence = true;
+
+ /**
+ * Information provided by the adapter's describeTable() method.
+ *
+ * @var array
+ */
+ protected $_metadata = array();
+
+ /**
+ * Cache for information provided by the adapter's describeTable() method.
+ *
+ * @var Zend_Cache_Core
+ */
+ protected $_metadataCache = null;
+
+ /**
+ * Flag: whether or not to cache metadata in the class
+ * @var bool
+ */
+ protected $_metadataCacheInClass = true;
+
+ /**
+ * Classname for row
+ *
+ * @var string
+ */
+ protected $_rowClass = 'Zend_Db_Table_Row';
+
+ /**
+ * Classname for rowset
+ *
+ * @var string
+ */
+ protected $_rowsetClass = 'Zend_Db_Table_Rowset';
+
+ /**
+ * Associative array map of declarative referential integrity rules.
+ * This array has one entry per foreign key in the current table.
+ * Each key is a mnemonic name for one reference rule.
+ *
+ * Each value is also an associative array, with the following keys:
+ * - columns = array of names of column(s) in the child table.
+ * - refTableClass = class name of the parent table.
+ * - refColumns = array of names of column(s) in the parent table,
+ * in the same order as those in the 'columns' entry.
+ * - onDelete = "cascade" means that a delete in the parent table also
+ * causes a delete of referencing rows in the child table.
+ * - onUpdate = "cascade" means that an update of primary key values in
+ * the parent table also causes an update of referencing
+ * rows in the child table.
+ *
+ * @var array
+ */
+ protected $_referenceMap = array();
+
+ /**
+ * Simple array of class names of tables that are "children" of the current
+ * table, in other words tables that contain a foreign key to this one.
+ * Array elements are not table names; they are class names of classes that
+ * extend Zend_Db_Table_Abstract.
+ *
+ * @var array
+ */
+ protected $_dependentTables = array();
+
+
+ protected $_defaultSource = self::DEFAULT_NONE;
+ protected $_defaultValues = array();
+
+ /**
+ * Constructor.
+ *
+ * Supported params for $config are:
+ * - db = user-supplied instance of database connector,
+ * or key name of registry instance.
+ * - name = table name.
+ * - primary = string or array of primary key(s).
+ * - rowClass = row class name.
+ * - rowsetClass = rowset class name.
+ * - referenceMap = array structure to declare relationship
+ * to parent tables.
+ * - dependentTables = array of child tables.
+ * - metadataCache = cache for information from adapter describeTable().
+ *
+ * @param mixed $config Array of user-specified config options, or just the Db Adapter.
+ * @return void
+ */
+ public function __construct($config = array())
+ {
+ /**
+ * Allow a scalar argument to be the Adapter object or Registry key.
+ */
+ if (!is_array($config)) {
+ $config = array(self::ADAPTER => $config);
+ }
+
+ if ($config) {
+ $this->setOptions($config);
+ }
+
+ $this->_setup();
+ $this->init();
+ }
+
+ /**
+ * setOptions()
+ *
+ * @param array $options
+ * @return Zend_Db_Table_Abstract
+ */
+ public function setOptions(Array $options)
+ {
+ foreach ($options as $key => $value) {
+ switch ($key) {
+ case self::ADAPTER:
+ $this->_setAdapter($value);
+ break;
+ case self::DEFINITION:
+ $this->setDefinition($value);
+ break;
+ case self::DEFINITION_CONFIG_NAME:
+ $this->setDefinitionConfigName($value);
+ break;
+ case self::SCHEMA:
+ $this->_schema = (string) $value;
+ break;
+ case self::NAME:
+ $this->_name = (string) $value;
+ break;
+ case self::PRIMARY:
+ $this->_primary = (array) $value;
+ break;
+ case self::ROW_CLASS:
+ $this->setRowClass($value);
+ break;
+ case self::ROWSET_CLASS:
+ $this->setRowsetClass($value);
+ break;
+ case self::REFERENCE_MAP:
+ $this->setReferences($value);
+ break;
+ case self::DEPENDENT_TABLES:
+ $this->setDependentTables($value);
+ break;
+ case self::METADATA_CACHE:
+ $this->_setMetadataCache($value);
+ break;
+ case self::METADATA_CACHE_IN_CLASS:
+ $this->setMetadataCacheInClass($value);
+ break;
+ case self::SEQUENCE:
+ $this->_setSequence($value);
+ break;
+ default:
+ // ignore unrecognized configuration directive
+ break;
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * setDefinition()
+ *
+ * @param Zend_Db_Table_Definition $definition
+ * @return Zend_Db_Table_Abstract
+ */
+ public function setDefinition(Zend_Db_Table_Definition $definition)
+ {
+ $this->_definition = $definition;
+ return $this;
+ }
+
+ /**
+ * getDefinition()
+ *
+ * @return Zend_Db_Table_Definition|null
+ */
+ public function getDefinition()
+ {
+ return $this->_definition;
+ }
+
+ /**
+ * setDefinitionConfigName()
+ *
+ * @param string $definition
+ * @return Zend_Db_Table_Abstract
+ */
+ public function setDefinitionConfigName($definitionConfigName)
+ {
+ $this->_definitionConfigName = $definitionConfigName;
+ return $this;
+ }
+
+ /**
+ * getDefinitionConfigName()
+ *
+ * @return string
+ */
+ public function getDefinitionConfigName()
+ {
+ return $this->_definitionConfigName;
+ }
+
+ /**
+ * @param string $classname
+ * @return Zend_Db_Table_Abstract Provides a fluent interface
+ */
+ public function setRowClass($classname)
+ {
+ $this->_rowClass = (string) $classname;
+
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getRowClass()
+ {
+ return $this->_rowClass;
+ }
+
+ /**
+ * @param string $classname
+ * @return Zend_Db_Table_Abstract Provides a fluent interface
+ */
+ public function setRowsetClass($classname)
+ {
+ $this->_rowsetClass = (string) $classname;
+
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getRowsetClass()
+ {
+ return $this->_rowsetClass;
+ }
+
+ /**
+ * Add a reference to the reference map
+ *
+ * @param string $ruleKey
+ * @param string|array $columns
+ * @param string $refTableClass
+ * @param string|array $refColumns
+ * @param string $onDelete
+ * @param string $onUpdate
+ * @return Zend_Db_Table_Abstract
+ */
+ public function addReference($ruleKey, $columns, $refTableClass, $refColumns,
+ $onDelete = null, $onUpdate = null)
+ {
+ $reference = array(self::COLUMNS => (array) $columns,
+ self::REF_TABLE_CLASS => $refTableClass,
+ self::REF_COLUMNS => (array) $refColumns);
+
+ if (!empty($onDelete)) {
+ $reference[self::ON_DELETE] = $onDelete;
+ }
+
+ if (!empty($onUpdate)) {
+ $reference[self::ON_UPDATE] = $onUpdate;
+ }
+
+ $this->_referenceMap[$ruleKey] = $reference;
+
+ return $this;
+ }
+
+ /**
+ * @param array $referenceMap
+ * @return Zend_Db_Table_Abstract Provides a fluent interface
+ */
+ public function setReferences(array $referenceMap)
+ {
+ $this->_referenceMap = $referenceMap;
+
+ return $this;
+ }
+
+ /**
+ * @param string $tableClassname
+ * @param string $ruleKey OPTIONAL
+ * @return array
+ * @throws Zend_Db_Table_Exception
+ */
+ public function getReference($tableClassname, $ruleKey = null)
+ {
+ $thisClass = get_class($this);
+ if ($thisClass === 'Zend_Db_Table') {
+ $thisClass = $this->_definitionConfigName;
+ }
+ $refMap = $this->_getReferenceMapNormalized();
+ if ($ruleKey !== null) {
+ if (!isset($refMap[$ruleKey])) {
+ throw new Zend_Db_Table_Exception("No reference rule \"$ruleKey\" from table $thisClass to table $tableClassname");
+ }
+ if ($refMap[$ruleKey][self::REF_TABLE_CLASS] != $tableClassname) {
+ throw new Zend_Db_Table_Exception("Reference rule \"$ruleKey\" does not reference table $tableClassname");
+ }
+ return $refMap[$ruleKey];
+ }
+ foreach ($refMap as $reference) {
+ if ($reference[self::REF_TABLE_CLASS] == $tableClassname) {
+ return $reference;
+ }
+ }
+ throw new Zend_Db_Table_Exception("No reference from table $thisClass to table $tableClassname");
+ }
+
+ /**
+ * @param array $dependentTables
+ * @return Zend_Db_Table_Abstract Provides a fluent interface
+ */
+ public function setDependentTables(array $dependentTables)
+ {
+ $this->_dependentTables = $dependentTables;
+
+ return $this;
+ }
+
+ /**
+ * @return array
+ */
+ public function getDependentTables()
+ {
+ return $this->_dependentTables;
+ }
+
+ /**
+ * set the defaultSource property - this tells the table class where to find default values
+ *
+ * @param string $defaultSource
+ * @return Zend_Db_Table_Abstract
+ */
+ public function setDefaultSource($defaultSource = self::DEFAULT_NONE)
+ {
+ if (!in_array($defaultSource, array(self::DEFAULT_CLASS, self::DEFAULT_DB, self::DEFAULT_NONE))) {
+ $defaultSource = self::DEFAULT_NONE;
+ }
+
+ $this->_defaultSource = $defaultSource;
+ return $this;
+ }
+
+ /**
+ * returns the default source flag that determines where defaultSources come from
+ *
+ * @return unknown
+ */
+ public function getDefaultSource()
+ {
+ return $this->_defaultSource;
+ }
+
+ /**
+ * set the default values for the table class
+ *
+ * @param array $defaultValues
+ * @return Zend_Db_Table_Abstract
+ */
+ public function setDefaultValues(Array $defaultValues)
+ {
+ foreach ($defaultValues as $defaultName => $defaultValue) {
+ if (array_key_exists($defaultName, $this->_metadata)) {
+ $this->_defaultValues[$defaultName] = $defaultValue;
+ }
+ }
+ return $this;
+ }
+
+ public function getDefaultValues()
+ {
+ return $this->_defaultValues;
+ }
+
+
+ /**
+ * Sets the default Zend_Db_Adapter_Abstract for all Zend_Db_Table objects.
+ *
+ * @param mixed $db Either an Adapter object, or a string naming a Registry key
+ * @return void
+ */
+ public static function setDefaultAdapter($db = null)
+ {
+ self::$_defaultDb = self::_setupAdapter($db);
+ }
+
+ /**
+ * Gets the default Zend_Db_Adapter_Abstract for all Zend_Db_Table objects.
+ *
+ * @return Zend_Db_Adapter_Abstract or null
+ */
+ public static function getDefaultAdapter()
+ {
+ return self::$_defaultDb;
+ }
+
+ /**
+ * @param mixed $db Either an Adapter object, or a string naming a Registry key
+ * @return Zend_Db_Table_Abstract Provides a fluent interface
+ */
+ protected function _setAdapter($db)
+ {
+ $this->_db = self::_setupAdapter($db);
+ return $this;
+ }
+
+ /**
+ * Gets the Zend_Db_Adapter_Abstract for this particular Zend_Db_Table object.
+ *
+ * @return Zend_Db_Adapter_Abstract
+ */
+ public function getAdapter()
+ {
+ return $this->_db;
+ }
+
+ /**
+ * @param mixed $db Either an Adapter object, or a string naming a Registry key
+ * @return Zend_Db_Adapter_Abstract
+ * @throws Zend_Db_Table_Exception
+ */
+ protected static function _setupAdapter($db)
+ {
+ if ($db === null) {
+ return null;
+ }
+ if (is_string($db)) {
+ $db = Zend_Registry::get($db);
+ }
+ if (!$db instanceof Zend_Db_Adapter_Abstract) {
+ throw new Zend_Db_Table_Exception('Argument must be of type Zend_Db_Adapter_Abstract, or a Registry key where a Zend_Db_Adapter_Abstract object is stored');
+ }
+ return $db;
+ }
+
+ /**
+ * Sets the default metadata cache for information returned by Zend_Db_Adapter_Abstract::describeTable().
+ *
+ * If $defaultMetadataCache is null, then no metadata cache is used by default.
+ *
+ * @param mixed $metadataCache Either a Cache object, or a string naming a Registry key
+ * @return void
+ */
+ public static function setDefaultMetadataCache($metadataCache = null)
+ {
+ self::$_defaultMetadataCache = self::_setupMetadataCache($metadataCache);
+ }
+
+ /**
+ * Gets the default metadata cache for information returned by Zend_Db_Adapter_Abstract::describeTable().
+ *
+ * @return Zend_Cache_Core or null
+ */
+ public static function getDefaultMetadataCache()
+ {
+ return self::$_defaultMetadataCache;
+ }
+
+ /**
+ * Sets the metadata cache for information returned by Zend_Db_Adapter_Abstract::describeTable().
+ *
+ * If $metadataCache is null, then no metadata cache is used. Since there is no opportunity to reload metadata
+ * after instantiation, this method need not be public, particularly because that it would have no effect
+ * results in unnecessary API complexity. To configure the metadata cache, use the metadataCache configuration
+ * option for the class constructor upon instantiation.
+ *
+ * @param mixed $metadataCache Either a Cache object, or a string naming a Registry key
+ * @return Zend_Db_Table_Abstract Provides a fluent interface
+ */
+ protected function _setMetadataCache($metadataCache)
+ {
+ $this->_metadataCache = self::_setupMetadataCache($metadataCache);
+ return $this;
+ }
+
+ /**
+ * Gets the metadata cache for information returned by Zend_Db_Adapter_Abstract::describeTable().
+ *
+ * @return Zend_Cache_Core or null
+ */
+ public function getMetadataCache()
+ {
+ return $this->_metadataCache;
+ }
+
+ /**
+ * Indicate whether metadata should be cached in the class for the duration
+ * of the instance
+ *
+ * @param bool $flag
+ * @return Zend_Db_Table_Abstract
+ */
+ public function setMetadataCacheInClass($flag)
+ {
+ $this->_metadataCacheInClass = (bool) $flag;
+ return $this;
+ }
+
+ /**
+ * Retrieve flag indicating if metadata should be cached for duration of
+ * instance
+ *
+ * @return bool
+ */
+ public function metadataCacheInClass()
+ {
+ return $this->_metadataCacheInClass;
+ }
+
+ /**
+ * @param mixed $metadataCache Either a Cache object, or a string naming a Registry key
+ * @return Zend_Cache_Core
+ * @throws Zend_Db_Table_Exception
+ */
+ protected static function _setupMetadataCache($metadataCache)
+ {
+ if ($metadataCache === null) {
+ return null;
+ }
+ if (is_string($metadataCache)) {
+ $metadataCache = Zend_Registry::get($metadataCache);
+ }
+ if (!$metadataCache instanceof Zend_Cache_Core) {
+ throw new Zend_Db_Table_Exception('Argument must be of type Zend_Cache_Core, or a Registry key where a Zend_Cache_Core object is stored');
+ }
+ return $metadataCache;
+ }
+
+ /**
+ * Sets the sequence member, which defines the behavior for generating
+ * primary key values in new rows.
+ * - If this is a string, then the string names the sequence object.
+ * - If this is boolean true, then the key uses an auto-incrementing
+ * or identity mechanism.
+ * - If this is boolean false, then the key is user-defined.
+ * Use this for natural keys, for example.
+ *
+ * @param mixed $sequence
+ * @return Zend_Db_Table_Adapter_Abstract Provides a fluent interface
+ */
+ protected function _setSequence($sequence)
+ {
+ $this->_sequence = $sequence;
+
+ return $this;
+ }
+
+ /**
+ * Turnkey for initialization of a table object.
+ * Calls other protected methods for individual tasks, to make it easier
+ * for a subclass to override part of the setup logic.
+ *
+ * @return void
+ */
+ protected function _setup()
+ {
+ $this->_setupDatabaseAdapter();
+ $this->_setupTableName();
+ }
+
+ /**
+ * Initialize database adapter.
+ *
+ * @return void
+ * @throws Zend_Db_Table_Exception
+ */
+ protected function _setupDatabaseAdapter()
+ {
+ if (! $this->_db) {
+ $this->_db = self::getDefaultAdapter();
+ if (!$this->_db instanceof Zend_Db_Adapter_Abstract) {
+ throw new Zend_Db_Table_Exception('No adapter found for ' . get_class($this));
+ }
+ }
+ }
+
+ /**
+ * Initialize table and schema names.
+ *
+ * If the table name is not set in the class definition,
+ * use the class name itself as the table name.
+ *
+ * A schema name provided with the table name (e.g., "schema.table") overrides
+ * any existing value for $this->_schema.
+ *
+ * @return void
+ */
+ protected function _setupTableName()
+ {
+ if (! $this->_name) {
+ $this->_name = get_class($this);
+ } else if (strpos($this->_name, '.')) {
+ list($this->_schema, $this->_name) = explode('.', $this->_name);
+ }
+ }
+
+ /**
+ * Initializes metadata.
+ *
+ * If metadata cannot be loaded from cache, adapter's describeTable() method is called to discover metadata
+ * information. Returns true if and only if the metadata are loaded from cache.
+ *
+ * @return boolean
+ * @throws Zend_Db_Table_Exception
+ */
+ protected function _setupMetadata()
+ {
+ if ($this->metadataCacheInClass() && (count($this->_metadata) > 0)) {
+ return true;
+ }
+
+ // Assume that metadata will be loaded from cache
+ $isMetadataFromCache = true;
+
+ // If $this has no metadata cache but the class has a default metadata cache
+ if (null === $this->_metadataCache && null !== self::$_defaultMetadataCache) {
+ // Make $this use the default metadata cache of the class
+ $this->_setMetadataCache(self::$_defaultMetadataCache);
+ }
+
+ // If $this has a metadata cache
+ if (null !== $this->_metadataCache) {
+ // Define the cache identifier where the metadata are saved
+
+ //get db configuration
+ $dbConfig = $this->_db->getConfig();
+
+ $port = isset($dbConfig['options']['port'])
+ ? ':'.$dbConfig['options']['port']
+ : (isset($dbConfig['port'])
+ ? ':'.$dbConfig['port']
+ : null);
+
+ $host = isset($dbConfig['options']['host'])
+ ? ':'.$dbConfig['options']['host']
+ : (isset($dbConfig['host'])
+ ? ':'.$dbConfig['host']
+ : null);
+
+ // Define the cache identifier where the metadata are saved
+ $cacheId = md5( // port:host/dbname:schema.table (based on availabilty)
+ $port . $host . '/'. $dbConfig['dbname'] . ':'
+ . $this->_schema. '.' . $this->_name
+ );
+ }
+
+ // If $this has no metadata cache or metadata cache misses
+ if (null === $this->_metadataCache || !($metadata = $this->_metadataCache->load($cacheId))) {
+ // Metadata are not loaded from cache
+ $isMetadataFromCache = false;
+ // Fetch metadata from the adapter's describeTable() method
+ $metadata = $this->_db->describeTable($this->_name, $this->_schema);
+ // If $this has a metadata cache, then cache the metadata
+ if (null !== $this->_metadataCache && !$this->_metadataCache->save($metadata, $cacheId)) {
+ trigger_error('Failed saving metadata to metadataCache', E_USER_NOTICE);
+ }
+ }
+
+ // Assign the metadata to $this
+ $this->_metadata = $metadata;
+
+ // Return whether the metadata were loaded from cache
+ return $isMetadataFromCache;
+ }
+
+ /**
+ * Retrieve table columns
+ *
+ * @return array
+ */
+ protected function _getCols()
+ {
+ if (null === $this->_cols) {
+ $this->_setupMetadata();
+ $this->_cols = array_keys($this->_metadata);
+ }
+ return $this->_cols;
+ }
+
+ /**
+ * Initialize primary key from metadata.
+ * If $_primary is not defined, discover primary keys
+ * from the information returned by describeTable().
+ *
+ * @return void
+ * @throws Zend_Db_Table_Exception
+ */
+ protected function _setupPrimaryKey()
+ {
+ if (!$this->_primary) {
+ $this->_setupMetadata();
+ $this->_primary = array();
+ foreach ($this->_metadata as $col) {
+ if ($col['PRIMARY']) {
+ $this->_primary[ $col['PRIMARY_POSITION'] ] = $col['COLUMN_NAME'];
+ if ($col['IDENTITY']) {
+ $this->_identity = $col['PRIMARY_POSITION'];
+ }
+ }
+ }
+ // if no primary key was specified and none was found in the metadata
+ // then throw an exception.
+ if (empty($this->_primary)) {
+ throw new Zend_Db_Table_Exception("A table must have a primary key, but none was found for table '{$this->_name}'");
+ }
+ } else if (!is_array($this->_primary)) {
+ $this->_primary = array(1 => $this->_primary);
+ } else if (isset($this->_primary[0])) {
+ array_unshift($this->_primary, null);
+ unset($this->_primary[0]);
+ }
+
+ $cols = $this->_getCols();
+ if (! array_intersect((array) $this->_primary, $cols) == (array) $this->_primary) {
+ throw new Zend_Db_Table_Exception("Primary key column(s) ("
+ . implode(',', (array) $this->_primary)
+ . ") are not columns in this table ("
+ . implode(',', $cols)
+ . ")");
+ }
+
+ $primary = (array) $this->_primary;
+ $pkIdentity = $primary[(int) $this->_identity];
+
+ /**
+ * Special case for PostgreSQL: a SERIAL key implicitly uses a sequence
+ * object whose name is "<table>_<column>_seq".
+ */
+ if ($this->_sequence === true && $this->_db instanceof Zend_Db_Adapter_Pdo_Pgsql) {
+ $this->_sequence = $this->_db->quoteIdentifier("{$this->_name}_{$pkIdentity}_seq");
+ if ($this->_schema) {
+ $this->_sequence = $this->_db->quoteIdentifier($this->_schema) . '.' . $this->_sequence;
+ }
+ }
+ }
+
+ /**
+ * Returns a normalized version of the reference map
+ *
+ * @return array
+ */
+ protected function _getReferenceMapNormalized()
+ {
+ $referenceMapNormalized = array();
+
+ foreach ($this->_referenceMap as $rule => $map) {
+
+ $referenceMapNormalized[$rule] = array();
+
+ foreach ($map as $key => $value) {
+ switch ($key) {
+
+ // normalize COLUMNS and REF_COLUMNS to arrays
+ case self::COLUMNS:
+ case self::REF_COLUMNS:
+ if (!is_array($value)) {
+ $referenceMapNormalized[$rule][$key] = array($value);
+ } else {
+ $referenceMapNormalized[$rule][$key] = $value;
+ }
+ break;
+
+ // other values are copied as-is
+ default:
+ $referenceMapNormalized[$rule][$key] = $value;
+ break;
+ }
+ }
+ }
+
+ return $referenceMapNormalized;
+ }
+
+ /**
+ * Initialize object
+ *
+ * Called from {@link __construct()} as final step of object instantiation.
+ *
+ * @return void
+ */
+ public function init()
+ {
+ }
+
+ /**
+ * Returns table information.
+ *
+ * You can elect to return only a part of this information by supplying its key name,
+ * otherwise all information is returned as an array.
+ *
+ * @param string $key The specific info part to return OPTIONAL
+ * @return mixed
+ * @throws Zend_Db_Table_Exception
+ */
+ public function info($key = null)
+ {
+ $this->_setupPrimaryKey();
+
+ $info = array(
+ self::SCHEMA => $this->_schema,
+ self::NAME => $this->_name,
+ self::COLS => $this->_getCols(),
+ self::PRIMARY => (array) $this->_primary,
+ self::METADATA => $this->_metadata,
+ self::ROW_CLASS => $this->getRowClass(),
+ self::ROWSET_CLASS => $this->getRowsetClass(),
+ self::REFERENCE_MAP => $this->_referenceMap,
+ self::DEPENDENT_TABLES => $this->_dependentTables,
+ self::SEQUENCE => $this->_sequence
+ );
+
+ if ($key === null) {
+ return $info;
+ }
+
+ if (!array_key_exists($key, $info)) {
+ throw new Zend_Db_Table_Exception('There is no table information for the key "' . $key . '"');
+ }
+
+ return $info[$key];
+ }
+
+ /**
+ * Returns an instance of a Zend_Db_Table_Select object.
+ *
+ * @param bool $withFromPart Whether or not to include the from part of the select based on the table
+ * @return Zend_Db_Table_Select
+ */
+ public function select($withFromPart = self::SELECT_WITHOUT_FROM_PART)
+ {
+ $select = new Zend_Db_Table_Select($this);
+ if ($withFromPart == self::SELECT_WITH_FROM_PART) {
+ $select->from($this->info(self::NAME), Zend_Db_Table_Select::SQL_WILDCARD, $this->info(self::SCHEMA));
+ }
+ return $select;
+ }
+
+ /**
+ * Inserts a new row.
+ *
+ * @param array $data Column-value pairs.
+ * @return mixed The primary key of the row inserted.
+ */
+ public function insert(array $data)
+ {
+ $this->_setupPrimaryKey();
+
+ /**
+ * Zend_Db_Table assumes that if you have a compound primary key
+ * and one of the columns in the key uses a sequence,
+ * it's the _first_ column in the compound key.
+ */
+ $primary = (array) $this->_primary;
+ $pkIdentity = $primary[(int)$this->_identity];
+
+
+ /**
+ * If the primary key can be generated automatically, and no value was
+ * specified in the user-supplied data, then omit it from the tuple.
+ *
+ * Note: this checks for sensible values in the supplied primary key
+ * position of the data. The following values are considered empty:
+ * null, false, true, '', array()
+ */
+ if (array_key_exists($pkIdentity, $data)) {
+ if ($data[$pkIdentity] === null // null
+ || $data[$pkIdentity] === '' // empty string
+ || is_bool($data[$pkIdentity]) // boolean
+ || (is_array($data[$pkIdentity]) && empty($data[$pkIdentity]))) { // empty array
+ unset($data[$pkIdentity]);
+ }
+ }
+
+ /**
+ * If this table uses a database sequence object and the data does not
+ * specify a value, then get the next ID from the sequence and add it
+ * to the row. We assume that only the first column in a compound
+ * primary key takes a value from a sequence.
+ */
+ if (is_string($this->_sequence) && !isset($data[$pkIdentity])) {
+ $data[$pkIdentity] = $this->_db->nextSequenceId($this->_sequence);
+ }
+
+ /**
+ * INSERT the new row.
+ */
+ $tableSpec = ($this->_schema ? $this->_schema . '.' : '') . $this->_name;
+ $this->_db->insert($tableSpec, $data);
+
+ /**
+ * Fetch the most recent ID generated by an auto-increment
+ * or IDENTITY column, unless the user has specified a value,
+ * overriding the auto-increment mechanism.
+ */
+ if ($this->_sequence === true && !isset($data[$pkIdentity])) {
+ $data[$pkIdentity] = $this->_db->lastInsertId();
+ }
+
+ /**
+ * Return the primary key value if the PK is a single column,
+ * else return an associative array of the PK column/value pairs.
+ */
+ $pkData = array_intersect_key($data, array_flip($primary));
+ if (count($primary) == 1) {
+ reset($pkData);
+ return current($pkData);
+ }
+
+ return $pkData;
+ }
+
+ /**
+ * Check if the provided column is an identity of the table
+ *
+ * @param string $column
+ * @throws Zend_Db_Table_Exception
+ * @return boolean
+ */
+ public function isIdentity($column)
+ {
+ $this->_setupPrimaryKey();
+
+ if (!isset($this->_metadata[$column])) {
+ /**
+ * @see Zend_Db_Table_Exception
+ */
+
+ throw new Zend_Db_Table_Exception('Column "' . $column . '" not found in table.');
+ }
+
+ return (bool) $this->_metadata[$column]['IDENTITY'];
+ }
+
+ /**
+ * Updates existing rows.
+ *
+ * @param array $data Column-value pairs.
+ * @param array|string $where An SQL WHERE clause, or an array of SQL WHERE clauses.
+ * @return int The number of rows updated.
+ */
+ public function update(array $data, $where)
+ {
+ $tableSpec = ($this->_schema ? $this->_schema . '.' : '') . $this->_name;
+ return $this->_db->update($tableSpec, $data, $where);
+ }
+
+ /**
+ * Called by a row object for the parent table's class during save() method.
+ *
+ * @param string $parentTableClassname
+ * @param array $oldPrimaryKey
+ * @param array $newPrimaryKey
+ * @return int
+ */
+ public function _cascadeUpdate($parentTableClassname, array $oldPrimaryKey, array $newPrimaryKey)
+ {
+ $this->_setupMetadata();
+ $rowsAffected = 0;
+ foreach ($this->_getReferenceMapNormalized() as $map) {
+ if ($map[self::REF_TABLE_CLASS] == $parentTableClassname && isset($map[self::ON_UPDATE])) {
+ switch ($map[self::ON_UPDATE]) {
+ case self::CASCADE:
+ $newRefs = array();
+ $where = array();
+ for ($i = 0; $i < count($map[self::COLUMNS]); ++$i) {
+ $col = $this->_db->foldCase($map[self::COLUMNS][$i]);
+ $refCol = $this->_db->foldCase($map[self::REF_COLUMNS][$i]);
+ if (array_key_exists($refCol, $newPrimaryKey)) {
+ $newRefs[$col] = $newPrimaryKey[$refCol];
+ }
+ $type = $this->_metadata[$col]['DATA_TYPE'];
+ $where[] = $this->_db->quoteInto(
+ $this->_db->quoteIdentifier($col, true) . ' = ?',
+ $oldPrimaryKey[$refCol], $type);
+ }
+ $rowsAffected += $this->update($newRefs, $where);
+ break;
+ default:
+ // no action
+ break;
+ }
+ }
+ }
+ return $rowsAffected;
+ }
+
+ /**
+ * Deletes existing rows.
+ *
+ * @param array|string $where SQL WHERE clause(s).
+ * @return int The number of rows deleted.
+ */
+ public function delete($where)
+ {
+ $depTables = $this->getDependentTables();
+ if (!empty($depTables)) {
+ $resultSet = $this->fetchAll($where);
+ if (count($resultSet) > 0 ) {
+ foreach ($resultSet as $row) {
+ /**
+ * Execute cascading deletes against dependent tables
+ */
+ foreach ($depTables as $tableClass) {
+ $t = self::getTableFromString($tableClass, $this);
+ $t->_cascadeDelete(
+ get_class($this), $row->getPrimaryKey()
+ );
+ }
+ }
+ }
+ }
+
+ $tableSpec = ($this->_schema ? $this->_schema . '.' : '') . $this->_name;
+ return $this->_db->delete($tableSpec, $where);
+ }
+
+ /**
+ * Called by parent table's class during delete() method.
+ *
+ * @param string $parentTableClassname
+ * @param array $primaryKey
+ * @return int Number of affected rows
+ */
+ public function _cascadeDelete($parentTableClassname, array $primaryKey)
+ {
+ // setup metadata
+ $this->_setupMetadata();
+
+ // get this class name
+ $thisClass = get_class($this);
+ if ($thisClass === 'Zend_Db_Table') {
+ $thisClass = $this->_definitionConfigName;
+ }
+
+ $rowsAffected = 0;
+
+ foreach ($this->_getReferenceMapNormalized() as $map) {
+ if ($map[self::REF_TABLE_CLASS] == $parentTableClassname && isset($map[self::ON_DELETE])) {
+
+ $where = array();
+
+ // CASCADE or CASCADE_RECURSE
+ if (in_array($map[self::ON_DELETE], array(self::CASCADE, self::CASCADE_RECURSE))) {
+ for ($i = 0; $i < count($map[self::COLUMNS]); ++$i) {
+ $col = $this->_db->foldCase($map[self::COLUMNS][$i]);
+ $refCol = $this->_db->foldCase($map[self::REF_COLUMNS][$i]);
+ $type = $this->_metadata[$col]['DATA_TYPE'];
+ $where[] = $this->_db->quoteInto(
+ $this->_db->quoteIdentifier($col, true) . ' = ?',
+ $primaryKey[$refCol], $type);
+ }
+ }
+
+ // CASCADE_RECURSE
+ if ($map[self::ON_DELETE] == self::CASCADE_RECURSE) {
+
+ /**
+ * Execute cascading deletes against dependent tables
+ */
+ $depTables = $this->getDependentTables();
+ if (!empty($depTables)) {
+ foreach ($depTables as $tableClass) {
+ $t = self::getTableFromString($tableClass, $this);
+ foreach ($this->fetchAll($where) as $depRow) {
+ $rowsAffected += $t->_cascadeDelete($thisClass, $depRow->getPrimaryKey());
+ }
+ }
+ }
+ }
+
+ // CASCADE or CASCADE_RECURSE
+ if (in_array($map[self::ON_DELETE], array(self::CASCADE, self::CASCADE_RECURSE))) {
+ $rowsAffected += $this->delete($where);
+ }
+
+ }
+ }
+ return $rowsAffected;
+ }
+
+ /**
+ * Fetches rows by primary key. The argument specifies one or more primary
+ * key value(s). To find multiple rows by primary key, the argument must
+ * be an array.
+ *
+ * This method accepts a variable number of arguments. If the table has a
+ * multi-column primary key, the number of arguments must be the same as
+ * the number of columns in the primary key. To find multiple rows in a
+ * table with a multi-column primary key, each argument must be an array
+ * with the same number of elements.
+ *
+ * The find() method always returns a Rowset object, even if only one row
+ * was found.
+ *
+ * @param mixed $key The value(s) of the primary keys.
+ * @return Zend_Db_Table_Rowset_Abstract Row(s) matching the criteria.
+ * @throws Zend_Db_Table_Exception
+ */
+ public function find()
+ {
+ $this->_setupPrimaryKey();
+ $args = func_get_args();
+ $keyNames = array_values((array) $this->_primary);
+
+ if (count($args) < count($keyNames)) {
+ throw new Zend_Db_Table_Exception("Too few columns for the primary key");
+ }
+
+ if (count($args) > count($keyNames)) {
+ throw new Zend_Db_Table_Exception("Too many columns for the primary key");
+ }
+
+ $whereList = array();
+ $numberTerms = 0;
+ foreach ($args as $keyPosition => $keyValues) {
+ $keyValuesCount = count($keyValues);
+ // Coerce the values to an array.
+ // Don't simply typecast to array, because the values
+ // might be Zend_Db_Expr objects.
+ if (!is_array($keyValues)) {
+ $keyValues = array($keyValues);
+ }
+ if ($numberTerms == 0) {
+ $numberTerms = $keyValuesCount;
+ } else if ($keyValuesCount != $numberTerms) {
+ throw new Zend_Db_Table_Exception("Missing value(s) for the primary key");
+ }
+ $keyValues = array_values($keyValues);
+ for ($i = 0; $i < $keyValuesCount; ++$i) {
+ if (!isset($whereList[$i])) {
+ $whereList[$i] = array();
+ }
+ $whereList[$i][$keyPosition] = $keyValues[$i];
+ }
+ }
+
+ $whereClause = null;
+ if (count($whereList)) {
+ $whereOrTerms = array();
+ $tableName = $this->_db->quoteTableAs($this->_name, null, true);
+ foreach ($whereList as $keyValueSets) {
+ $whereAndTerms = array();
+ foreach ($keyValueSets as $keyPosition => $keyValue) {
+ $type = $this->_metadata[$keyNames[$keyPosition]]['DATA_TYPE'];
+ $columnName = $this->_db->quoteIdentifier($keyNames[$keyPosition], true);
+ $whereAndTerms[] = $this->_db->quoteInto(
+ $tableName . '.' . $columnName . ' = ?',
+ $keyValue, $type);
+ }
+ $whereOrTerms[] = '(' . implode(' AND ', $whereAndTerms) . ')';
+ }
+ $whereClause = '(' . implode(' OR ', $whereOrTerms) . ')';
+ }
+
+ // issue ZF-5775 (empty where clause should return empty rowset)
+ if ($whereClause == null) {
+ $rowsetClass = $this->getRowsetClass();
+ if (!class_exists($rowsetClass)) {
+ Zend_Loader::loadClass($rowsetClass);
+ }
+ return new $rowsetClass(array('table' => $this, 'rowClass' => $this->getRowClass(), 'stored' => true));
+ }
+
+ return $this->fetchAll($whereClause);
+ }
+
+ /**
+ * Fetches all rows.
+ *
+ * Honors the Zend_Db_Adapter fetch mode.
+ *
+ * @param string|array|Zend_Db_Table_Select $where OPTIONAL An SQL WHERE clause or Zend_Db_Table_Select object.
+ * @param string|array $order OPTIONAL An SQL ORDER clause.
+ * @param int $count OPTIONAL An SQL LIMIT count.
+ * @param int $offset OPTIONAL An SQL LIMIT offset.
+ * @return Zend_Db_Table_Rowset_Abstract The row results per the Zend_Db_Adapter fetch mode.
+ */
+ public function fetchAll($where = null, $order = null, $count = null, $offset = null)
+ {
+ if (!($where instanceof Zend_Db_Table_Select)) {
+ $select = $this->select();
+
+ if ($where !== null) {
+ $this->_where($select, $where);
+ }
+
+ if ($order !== null) {
+ $this->_order($select, $order);
+ }
+
+ if ($count !== null || $offset !== null) {
+ $select->limit($count, $offset);
+ }
+
+ } else {
+ $select = $where;
+ }
+
+ $rows = $this->_fetch($select);
+
+ $data = array(
+ 'table' => $this,
+ 'data' => $rows,
+ 'readOnly' => $select->isReadOnly(),
+ 'rowClass' => $this->getRowClass(),
+ 'stored' => true
+ );
+
+ $rowsetClass = $this->getRowsetClass();
+ if (!class_exists($rowsetClass)) {
+ Zend_Loader::loadClass($rowsetClass);
+ }
+ return new $rowsetClass($data);
+ }
+
+ /**
+ * Fetches one row in an object of type Zend_Db_Table_Row_Abstract,
+ * or returns null if no row matches the specified criteria.
+ *
+ * @param string|array|Zend_Db_Table_Select $where OPTIONAL An SQL WHERE clause or Zend_Db_Table_Select object.
+ * @param string|array $order OPTIONAL An SQL ORDER clause.
+ * @param int $offset OPTIONAL An SQL OFFSET value.
+ * @return Zend_Db_Table_Row_Abstract|null The row results per the
+ * Zend_Db_Adapter fetch mode, or null if no row found.
+ */
+ public function fetchRow($where = null, $order = null, $offset = null)
+ {
+ if (!($where instanceof Zend_Db_Table_Select)) {
+ $select = $this->select();
+
+ if ($where !== null) {
+ $this->_where($select, $where);
+ }
+
+ if ($order !== null) {
+ $this->_order($select, $order);
+ }
+
+ $select->limit(1, ((is_numeric($offset)) ? (int) $offset : null));
+
+ } else {
+ $select = $where->limit(1, $where->getPart(Zend_Db_Select::LIMIT_OFFSET));
+ }
+
+ $rows = $this->_fetch($select);
+
+ if (count($rows) == 0) {
+ return null;
+ }
+
+ $data = array(
+ 'table' => $this,
+ 'data' => $rows[0],
+ 'readOnly' => $select->isReadOnly(),
+ 'stored' => true
+ );
+
+ $rowClass = $this->getRowClass();
+ if (!class_exists($rowClass)) {
+ Zend_Loader::loadClass($rowClass);
+ }
+ return new $rowClass($data);
+ }
+
+ /**
+ * Fetches a new blank row (not from the database).
+ *
+ * @return Zend_Db_Table_Row_Abstract
+ * @deprecated since 0.9.3 - use createRow() instead.
+ */
+ public function fetchNew()
+ {
+ return $this->createRow();
+ }
+
+ /**
+ * Fetches a new blank row (not from the database).
+ *
+ * @param array $data OPTIONAL data to populate in the new row.
+ * @param string $defaultSource OPTIONAL flag to force default values into new row
+ * @return Zend_Db_Table_Row_Abstract
+ */
+ public function createRow(array $data = array(), $defaultSource = null)
+ {
+ $cols = $this->_getCols();
+ $defaults = array_combine($cols, array_fill(0, count($cols), null));
+
+ // nothing provided at call-time, take the class value
+ if ($defaultSource == null) {
+ $defaultSource = $this->_defaultSource;
+ }
+
+ if (!in_array($defaultSource, array(self::DEFAULT_CLASS, self::DEFAULT_DB, self::DEFAULT_NONE))) {
+ $defaultSource = self::DEFAULT_NONE;
+ }
+
+ if ($defaultSource == self::DEFAULT_DB) {
+ foreach ($this->_metadata as $metadataName => $metadata) {
+ if (($metadata['DEFAULT'] != null) &&
+ ($metadata['NULLABLE'] !== true || ($metadata['NULLABLE'] === true && isset($this->_defaultValues[$metadataName]) && $this->_defaultValues[$metadataName] === true)) &&
+ (!(isset($this->_defaultValues[$metadataName]) && $this->_defaultValues[$metadataName] === false))) {
+ $defaults[$metadataName] = $metadata['DEFAULT'];
+ }
+ }
+ } elseif ($defaultSource == self::DEFAULT_CLASS && $this->_defaultValues) {
+ foreach ($this->_defaultValues as $defaultName => $defaultValue) {
+ if (array_key_exists($defaultName, $defaults)) {
+ $defaults[$defaultName] = $defaultValue;
+ }
+ }
+ }
+
+ $config = array(
+ 'table' => $this,
+ 'data' => $defaults,
+ 'readOnly' => false,
+ 'stored' => false
+ );
+
+ $rowClass = $this->getRowClass();
+ if (!class_exists($rowClass)) {
+ Zend_Loader::loadClass($rowClass);
+ }
+ $row = new $rowClass($config);
+ $row->setFromArray($data);
+ return $row;
+ }
+
+ /**
+ * Generate WHERE clause from user-supplied string or array
+ *
+ * @param string|array $where OPTIONAL An SQL WHERE clause.
+ * @return Zend_Db_Table_Select
+ */
+ protected function _where(Zend_Db_Table_Select $select, $where)
+ {
+ $where = (array) $where;
+
+ foreach ($where as $key => $val) {
+ // is $key an int?
+ if (is_int($key)) {
+ // $val is the full condition
+ $select->where($val);
+ } else {
+ // $key is the condition with placeholder,
+ // and $val is quoted into the condition
+ $select->where($key, $val);
+ }
+ }
+
+ return $select;
+ }
+
+ /**
+ * Generate ORDER clause from user-supplied string or array
+ *
+ * @param string|array $order OPTIONAL An SQL ORDER clause.
+ * @return Zend_Db_Table_Select
+ */
+ protected function _order(Zend_Db_Table_Select $select, $order)
+ {
+ if (!is_array($order)) {
+ $order = array($order);
+ }
+
+ foreach ($order as $val) {
+ $select->order($val);
+ }
+
+ return $select;
+ }
+
+ /**
+ * Support method for fetching rows.
+ *
+ * @param Zend_Db_Table_Select $select query options.
+ * @return array An array containing the row results in FETCH_ASSOC mode.
+ */
+ protected function _fetch(Zend_Db_Table_Select $select)
+ {
+ $stmt = $this->_db->query($select);
+ $data = $stmt->fetchAll(Zend_Db::FETCH_ASSOC);
+ return $data;
+ }
+
+ /**
+ * Get table gateway object from string
+ *
+ * @param string $tableName
+ * @param Zend_Db_Table_Abstract $referenceTable
+ * @throws Zend_Db_Table_Row_Exception
+ * @return Zend_Db_Table_Abstract
+ */
+ public static function getTableFromString($tableName, Zend_Db_Table_Abstract $referenceTable = null)
+ {
+ if ($referenceTable instanceof Zend_Db_Table_Abstract) {
+ $tableDefinition = $referenceTable->getDefinition();
+
+ if ($tableDefinition !== null && $tableDefinition->hasTableConfig($tableName)) {
+ return new Zend_Db_Table($tableName, $tableDefinition);
+ }
+ }
+
+ // assume the tableName is the class name
+ if (!class_exists($tableName)) {
+ try {
+ Zend_Loader::loadClass($tableName);
+ } catch (Zend_Exception $e) {
+ throw new Zend_Db_Table_Row_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+ $options = array();
+
+ if ($referenceTable instanceof Zend_Db_Table_Abstract) {
+ $options['db'] = $referenceTable->getAdapter();
+ }
+
+ if (isset($tableDefinition) && $tableDefinition !== null) {
+ $options[Zend_Db_Table_Abstract::DEFINITION] = $tableDefinition;
+ }
+
+ return new $tableName($options);
+ }
+
+}
diff --git a/library/vendor/Zend/Db/Table/Definition.php b/library/vendor/Zend/Db/Table/Definition.php
new file mode 100644
index 0000000..76265ae
--- /dev/null
+++ b/library/vendor/Zend/Db/Table/Definition.php
@@ -0,0 +1,131 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Table
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * Class for SQL table interface.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Table
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Table_Definition
+{
+
+ /**
+ * @var array
+ */
+ protected $_tableConfigs = array();
+
+ /**
+ * __construct()
+ *
+ * @param array|Zend_Config $options
+ */
+ public function __construct($options = null)
+ {
+ if ($options instanceof Zend_Config) {
+ $this->setConfig($options);
+ } elseif (is_array($options)) {
+ $this->setOptions($options);
+ }
+ }
+
+ /**
+ * setConfig()
+ *
+ * @param Zend_Config $config
+ * @return Zend_Db_Table_Definition
+ */
+ public function setConfig(Zend_Config $config)
+ {
+ $this->setOptions($config->toArray());
+ return $this;
+ }
+
+ /**
+ * setOptions()
+ *
+ * @param array $options
+ * @return Zend_Db_Table_Definition
+ */
+ public function setOptions(Array $options)
+ {
+ foreach ($options as $optionName => $optionValue) {
+ $this->setTableConfig($optionName, $optionValue);
+ }
+ return $this;
+ }
+
+ /**
+ * @param string $tableName
+ * @param array $tableConfig
+ * @return Zend_Db_Table_Definition
+ */
+ public function setTableConfig($tableName, array $tableConfig)
+ {
+ // @todo logic here
+ $tableConfig[Zend_Db_Table::DEFINITION_CONFIG_NAME] = $tableName;
+ $tableConfig[Zend_Db_Table::DEFINITION] = $this;
+
+ if (!isset($tableConfig[Zend_Db_Table::NAME])) {
+ $tableConfig[Zend_Db_Table::NAME] = $tableName;
+ }
+
+ $this->_tableConfigs[$tableName] = $tableConfig;
+ return $this;
+ }
+
+ /**
+ * getTableConfig()
+ *
+ * @param string $tableName
+ * @return array
+ */
+ public function getTableConfig($tableName)
+ {
+ return $this->_tableConfigs[$tableName];
+ }
+
+ /**
+ * removeTableConfig()
+ *
+ * @param string $tableName
+ */
+ public function removeTableConfig($tableName)
+ {
+ unset($this->_tableConfigs[$tableName]);
+ }
+
+ /**
+ * hasTableConfig()
+ *
+ * @param string $tableName
+ * @return bool
+ */
+ public function hasTableConfig($tableName)
+ {
+ return (isset($this->_tableConfigs[$tableName]));
+ }
+
+}
diff --git a/library/vendor/Zend/Db/Table/Exception.php b/library/vendor/Zend/Db/Table/Exception.php
new file mode 100644
index 0000000..e1599a0
--- /dev/null
+++ b/library/vendor/Zend/Db/Table/Exception.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Table
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * Zend_Db_Exception
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Table
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Table_Exception extends Zend_Db_Exception
+{
+}
+
diff --git a/library/vendor/Zend/Db/Table/Row.php b/library/vendor/Zend/Db/Table/Row.php
new file mode 100644
index 0000000..adf00d4
--- /dev/null
+++ b/library/vendor/Zend/Db/Table/Row.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Table
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+
+/**
+ * @see Zend_Db_Table_Row_Abstract
+ */
+
+
+/**
+ * Reference concrete class that extends Zend_Db_Table_Row_Abstract.
+ * Developers may also create their own classes that extend the abstract class.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Table
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Table_Row extends Zend_Db_Table_Row_Abstract
+{
+}
diff --git a/library/vendor/Zend/Db/Table/Row/Abstract.php b/library/vendor/Zend/Db/Table/Row/Abstract.php
new file mode 100644
index 0000000..e9c60b0
--- /dev/null
+++ b/library/vendor/Zend/Db/Table/Row/Abstract.php
@@ -0,0 +1,1160 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Table
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * @see Zend_Db
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Table
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+abstract class Zend_Db_Table_Row_Abstract implements ArrayAccess, IteratorAggregate
+{
+
+ /**
+ * The data for each column in the row (column_name => value).
+ * The keys must match the physical names of columns in the
+ * table for which this row is defined.
+ *
+ * @var array
+ */
+ protected $_data = array();
+
+ /**
+ * This is set to a copy of $_data when the data is fetched from
+ * a database, specified as a new tuple in the constructor, or
+ * when dirty data is posted to the database with save().
+ *
+ * @var array
+ */
+ protected $_cleanData = array();
+
+ /**
+ * Tracks columns where data has been updated. Allows more specific insert and
+ * update operations.
+ *
+ * @var array
+ */
+ protected $_modifiedFields = array();
+
+ /**
+ * Zend_Db_Table_Abstract parent class or instance.
+ *
+ * @var Zend_Db_Table_Abstract
+ */
+ protected $_table = null;
+
+ /**
+ * Connected is true if we have a reference to a live
+ * Zend_Db_Table_Abstract object.
+ * This is false after the Rowset has been deserialized.
+ *
+ * @var boolean
+ */
+ protected $_connected = true;
+
+ /**
+ * A row is marked read only if it contains columns that are not physically represented within
+ * the database schema (e.g. evaluated columns/Zend_Db_Expr columns). This can also be passed
+ * as a run-time config options as a means of protecting row data.
+ *
+ * @var boolean
+ */
+ protected $_readOnly = false;
+
+ /**
+ * Name of the class of the Zend_Db_Table_Abstract object.
+ *
+ * @var string
+ */
+ protected $_tableClass = null;
+
+ /**
+ * Primary row key(s).
+ *
+ * @var array
+ */
+ protected $_primary;
+
+ /**
+ * Constructor.
+ *
+ * Supported params for $config are:-
+ * - table = class name or object of type Zend_Db_Table_Abstract
+ * - data = values of columns in this row.
+ *
+ * @param array $config OPTIONAL Array of user-specified config options.
+ * @return void
+ * @throws Zend_Db_Table_Row_Exception
+ */
+ public function __construct(array $config = array())
+ {
+ if (isset($config['table']) && $config['table'] instanceof Zend_Db_Table_Abstract) {
+ $this->_table = $config['table'];
+ $this->_tableClass = get_class($this->_table);
+ } elseif ($this->_tableClass !== null) {
+ $this->_table = $this->_getTableFromString($this->_tableClass);
+ }
+
+ if (isset($config['data'])) {
+ if (!is_array($config['data'])) {
+ throw new Zend_Db_Table_Row_Exception('Data must be an array');
+ }
+ $this->_data = $config['data'];
+ }
+ if (isset($config['stored']) && $config['stored'] === true) {
+ $this->_cleanData = $this->_data;
+ }
+
+ if (isset($config['readOnly']) && $config['readOnly'] === true) {
+ $this->setReadOnly(true);
+ }
+
+ // Retrieve primary keys from table schema
+ if (($table = $this->_getTable())) {
+ $info = $table->info();
+ $this->_primary = (array) $info['primary'];
+ }
+
+ $this->init();
+ }
+
+ /**
+ * Transform a column name from the user-specified form
+ * to the physical form used in the database.
+ * You can override this method in a custom Row class
+ * to implement column name mappings, for example inflection.
+ *
+ * @param string $columnName Column name given.
+ * @return string The column name after transformation applied (none by default).
+ * @throws Zend_Db_Table_Row_Exception if the $columnName is not a string.
+ */
+ protected function _transformColumn($columnName)
+ {
+ if (!is_string($columnName)) {
+ throw new Zend_Db_Table_Row_Exception('Specified column is not a string');
+ }
+ // Perform no transformation by default
+ return $columnName;
+ }
+
+ /**
+ * Retrieve row field value
+ *
+ * @param string $columnName The user-specified column name.
+ * @return string The corresponding column value.
+ * @throws Zend_Db_Table_Row_Exception if the $columnName is not a column in the row.
+ */
+ public function __get($columnName)
+ {
+ $columnName = $this->_transformColumn($columnName);
+ if (!array_key_exists($columnName, $this->_data)) {
+ throw new Zend_Db_Table_Row_Exception("Specified column \"$columnName\" is not in the row");
+ }
+ return $this->_data[$columnName];
+ }
+
+ /**
+ * Set row field value
+ *
+ * @param string $columnName The column key.
+ * @param mixed $value The value for the property.
+ * @return void
+ * @throws Zend_Db_Table_Row_Exception
+ */
+ public function __set($columnName, $value)
+ {
+ $columnName = $this->_transformColumn($columnName);
+ if (!array_key_exists($columnName, $this->_data)) {
+ throw new Zend_Db_Table_Row_Exception("Specified column \"$columnName\" is not in the row");
+ }
+ $this->_data[$columnName] = $value;
+ $this->_modifiedFields[$columnName] = true;
+ }
+
+ /**
+ * Unset row field value
+ *
+ * @param string $columnName The column key.
+ * @return Zend_Db_Table_Row_Abstract
+ * @throws Zend_Db_Table_Row_Exception
+ */
+ public function __unset($columnName)
+ {
+ $columnName = $this->_transformColumn($columnName);
+ if (!array_key_exists($columnName, $this->_data)) {
+ throw new Zend_Db_Table_Row_Exception("Specified column \"$columnName\" is not in the row");
+ }
+ if ($this->isConnected() && in_array($columnName, $this->_table->info('primary'))) {
+ throw new Zend_Db_Table_Row_Exception("Specified column \"$columnName\" is a primary key and should not be unset");
+ }
+ unset($this->_data[$columnName]);
+ return $this;
+ }
+
+ /**
+ * Test existence of row field
+ *
+ * @param string $columnName The column key.
+ * @return boolean
+ */
+ public function __isset($columnName)
+ {
+ $columnName = $this->_transformColumn($columnName);
+ return array_key_exists($columnName, $this->_data);
+ }
+
+ /**
+ * Store table, primary key and data in serialized object
+ *
+ * @return array
+ */
+ public function __sleep()
+ {
+ return array('_tableClass', '_primary', '_data', '_cleanData', '_readOnly' ,'_modifiedFields');
+ }
+
+ /**
+ * Setup to do on wakeup.
+ * A de-serialized Row should not be assumed to have access to a live
+ * database connection, so set _connected = false.
+ *
+ * @return void
+ */
+ public function __wakeup()
+ {
+ $this->_connected = false;
+ }
+
+ /**
+ * Proxy to __isset
+ * Required by the ArrayAccess implementation
+ *
+ * @param string $offset
+ * @return boolean
+ */
+ public function offsetExists($offset)
+ {
+ return $this->__isset($offset);
+ }
+
+ /**
+ * Proxy to __get
+ * Required by the ArrayAccess implementation
+ *
+ * @param string $offset
+ * @return string
+ */
+ public function offsetGet($offset)
+ {
+ return $this->__get($offset);
+ }
+
+ /**
+ * Proxy to __set
+ * Required by the ArrayAccess implementation
+ *
+ * @param string $offset
+ * @param mixed $value
+ */
+ public function offsetSet($offset, $value)
+ {
+ $this->__set($offset, $value);
+ }
+
+ /**
+ * Proxy to __unset
+ * Required by the ArrayAccess implementation
+ *
+ * @param string $offset
+ */
+ public function offsetUnset($offset)
+ {
+ return $this->__unset($offset);
+ }
+
+ /**
+ * Initialize object
+ *
+ * Called from {@link __construct()} as final step of object instantiation.
+ *
+ * @return void
+ */
+ public function init()
+ {
+ }
+
+ /**
+ * Returns the table object, or null if this is disconnected row
+ *
+ * @return Zend_Db_Table_Abstract|null
+ */
+ public function getTable()
+ {
+ return $this->_table;
+ }
+
+ /**
+ * Set the table object, to re-establish a live connection
+ * to the database for a Row that has been de-serialized.
+ *
+ * @param Zend_Db_Table_Abstract $table
+ * @return boolean
+ * @throws Zend_Db_Table_Row_Exception
+ */
+ public function setTable(Zend_Db_Table_Abstract $table = null)
+ {
+ if ($table == null) {
+ $this->_table = null;
+ $this->_connected = false;
+ return false;
+ }
+
+ $tableClass = get_class($table);
+ if (! $table instanceof $this->_tableClass) {
+ throw new Zend_Db_Table_Row_Exception("The specified Table is of class $tableClass, expecting class to be instance of $this->_tableClass");
+ }
+
+ $this->_table = $table;
+ $this->_tableClass = $tableClass;
+
+ $info = $this->_table->info();
+
+ if ($info['cols'] != array_keys($this->_data)) {
+ throw new Zend_Db_Table_Row_Exception('The specified Table does not have the same columns as the Row');
+ }
+
+ if (! array_intersect((array) $this->_primary, $info['primary']) == (array) $this->_primary) {
+
+ throw new Zend_Db_Table_Row_Exception("The specified Table '$tableClass' does not have the same primary key as the Row");
+ }
+
+ $this->_connected = true;
+ return true;
+ }
+
+ /**
+ * Query the class name of the Table object for which this
+ * Row was created.
+ *
+ * @return string
+ */
+ public function getTableClass()
+ {
+ return $this->_tableClass;
+ }
+
+ /**
+ * Test the connected status of the row.
+ *
+ * @return boolean
+ */
+ public function isConnected()
+ {
+ return $this->_connected;
+ }
+
+ /**
+ * Test the read-only status of the row.
+ *
+ * @return boolean
+ */
+ public function isReadOnly()
+ {
+ return $this->_readOnly;
+ }
+
+ /**
+ * Set the read-only status of the row.
+ *
+ * @param boolean $flag
+ * @return boolean
+ */
+ public function setReadOnly($flag)
+ {
+ $this->_readOnly = (bool) $flag;
+ }
+
+ /**
+ * Returns an instance of the parent table's Zend_Db_Table_Select object.
+ *
+ * @return Zend_Db_Table_Select
+ */
+ public function select()
+ {
+ return $this->getTable()->select();
+ }
+
+ /**
+ * Saves the properties to the database.
+ *
+ * This performs an intelligent insert/update, and reloads the
+ * properties with fresh data from the table on success.
+ *
+ * @return mixed The primary key value(s), as an associative array if the
+ * key is compound, or a scalar if the key is single-column.
+ */
+ public function save()
+ {
+ /**
+ * If the _cleanData array is empty,
+ * this is an INSERT of a new row.
+ * Otherwise it is an UPDATE.
+ */
+ if (empty($this->_cleanData)) {
+ return $this->_doInsert();
+ } else {
+ return $this->_doUpdate();
+ }
+ }
+
+ /**
+ * @return mixed The primary key value(s), as an associative array if the
+ * key is compound, or a scalar if the key is single-column.
+ */
+ protected function _doInsert()
+ {
+ /**
+ * A read-only row cannot be saved.
+ */
+ if ($this->_readOnly === true) {
+ throw new Zend_Db_Table_Row_Exception('This row has been marked read-only');
+ }
+
+ /**
+ * Run pre-INSERT logic
+ */
+ $this->_insert();
+
+ /**
+ * Execute the INSERT (this may throw an exception)
+ */
+ $data = array_intersect_key($this->_data, $this->_modifiedFields);
+ $primaryKey = $this->_getTable()->insert($data);
+
+ /**
+ * Normalize the result to an array indexed by primary key column(s).
+ * The table insert() method may return a scalar.
+ */
+ if (is_array($primaryKey)) {
+ $newPrimaryKey = $primaryKey;
+ } else {
+ //ZF-6167 Use tempPrimaryKey temporary to avoid that zend encoding fails.
+ $tempPrimaryKey = (array) $this->_primary;
+ $newPrimaryKey = array(current($tempPrimaryKey) => $primaryKey);
+ }
+
+ /**
+ * Save the new primary key value in _data. The primary key may have
+ * been generated by a sequence or auto-increment mechanism, and this
+ * merge should be done before the _postInsert() method is run, so the
+ * new values are available for logging, etc.
+ */
+ $this->_data = array_merge($this->_data, $newPrimaryKey);
+
+ /**
+ * Run post-INSERT logic
+ */
+ $this->_postInsert();
+
+ /**
+ * Update the _cleanData to reflect that the data has been inserted.
+ */
+ $this->_refresh();
+
+ return $primaryKey;
+ }
+
+ /**
+ * @return mixed The primary key value(s), as an associative array if the
+ * key is compound, or a scalar if the key is single-column.
+ */
+ protected function _doUpdate()
+ {
+ /**
+ * A read-only row cannot be saved.
+ */
+ if ($this->_readOnly === true) {
+ throw new Zend_Db_Table_Row_Exception('This row has been marked read-only');
+ }
+
+ /**
+ * Get expressions for a WHERE clause
+ * based on the primary key value(s).
+ */
+ $where = $this->_getWhereQuery(false);
+
+ /**
+ * Run pre-UPDATE logic
+ */
+ $this->_update();
+
+ /**
+ * Compare the data to the modified fields array to discover
+ * which columns have been changed.
+ */
+ $diffData = array_intersect_key($this->_data, $this->_modifiedFields);
+
+ /**
+ * Were any of the changed columns part of the primary key?
+ */
+ $pkDiffData = array_intersect_key($diffData, array_flip((array)$this->_primary));
+
+ /**
+ * Execute cascading updates against dependent tables.
+ * Do this only if primary key value(s) were changed.
+ */
+ if (count($pkDiffData) > 0) {
+ $depTables = $this->_getTable()->getDependentTables();
+ if (!empty($depTables)) {
+ $pkNew = $this->_getPrimaryKey(true);
+ $pkOld = $this->_getPrimaryKey(false);
+ foreach ($depTables as $tableClass) {
+ $t = $this->_getTableFromString($tableClass);
+ $t->_cascadeUpdate($this->getTableClass(), $pkOld, $pkNew);
+ }
+ }
+ }
+
+ /**
+ * Execute the UPDATE (this may throw an exception)
+ * Do this only if data values were changed.
+ * Use the $diffData variable, so the UPDATE statement
+ * includes SET terms only for data values that changed.
+ */
+ if (count($diffData) > 0) {
+ $this->_getTable()->update($diffData, $where);
+ }
+
+ /**
+ * Run post-UPDATE logic. Do this before the _refresh()
+ * so the _postUpdate() function can tell the difference
+ * between changed data and clean (pre-changed) data.
+ */
+ $this->_postUpdate();
+
+ /**
+ * Refresh the data just in case triggers in the RDBMS changed
+ * any columns. Also this resets the _cleanData.
+ */
+ $this->_refresh();
+
+ /**
+ * Return the primary key value(s) as an array
+ * if the key is compound or a scalar if the key
+ * is a scalar.
+ */
+ $primaryKey = $this->_getPrimaryKey(true);
+ if (count($primaryKey) == 1) {
+ return current($primaryKey);
+ }
+
+ return $primaryKey;
+ }
+
+ /**
+ * Deletes existing rows.
+ *
+ * @return int The number of rows deleted.
+ */
+ public function delete()
+ {
+ /**
+ * A read-only row cannot be deleted.
+ */
+ if ($this->_readOnly === true) {
+ throw new Zend_Db_Table_Row_Exception('This row has been marked read-only');
+ }
+
+ $where = $this->_getWhereQuery();
+
+ /**
+ * Execute pre-DELETE logic
+ */
+ $this->_delete();
+
+ /**
+ * Execute cascading deletes against dependent tables
+ */
+ $depTables = $this->_getTable()->getDependentTables();
+ if (!empty($depTables)) {
+ $pk = $this->_getPrimaryKey();
+ foreach ($depTables as $tableClass) {
+ $t = $this->_getTableFromString($tableClass);
+ $t->_cascadeDelete($this->getTableClass(), $pk);
+ }
+ }
+
+ /**
+ * Execute the DELETE (this may throw an exception)
+ */
+ $result = $this->_getTable()->delete($where);
+
+ /**
+ * Execute post-DELETE logic
+ */
+ $this->_postDelete();
+
+ /**
+ * Reset all fields to null to indicate that the row is not there
+ */
+ $this->_data = array_combine(
+ array_keys($this->_data),
+ array_fill(0, count($this->_data), null)
+ );
+
+ return $result;
+ }
+
+ public function getIterator()
+ {
+ return new ArrayIterator((array) $this->_data);
+ }
+
+ /**
+ * Returns the column/value data as an array.
+ *
+ * @return array
+ */
+ public function toArray()
+ {
+ return (array)$this->_data;
+ }
+
+ /**
+ * Sets all data in the row from an array.
+ *
+ * @param array $data
+ * @return Zend_Db_Table_Row_Abstract Provides a fluent interface
+ */
+ public function setFromArray(array $data)
+ {
+ $data = array_intersect_key($data, $this->_data);
+
+ foreach ($data as $columnName => $value) {
+ $this->__set($columnName, $value);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Refreshes properties from the database.
+ *
+ * @return void
+ */
+ public function refresh()
+ {
+ return $this->_refresh();
+ }
+
+ /**
+ * Retrieves an instance of the parent table.
+ *
+ * @return Zend_Db_Table_Abstract
+ */
+ protected function _getTable()
+ {
+ if (!$this->_connected) {
+ throw new Zend_Db_Table_Row_Exception('Cannot save a Row unless it is connected');
+ }
+ return $this->_table;
+ }
+
+ /**
+ * Retrieves an associative array of primary keys.
+ *
+ * @param bool $useDirty
+ * @return array
+ */
+ protected function _getPrimaryKey($useDirty = true)
+ {
+ if (!is_array($this->_primary)) {
+ throw new Zend_Db_Table_Row_Exception("The primary key must be set as an array");
+ }
+
+ $primary = array_flip($this->_primary);
+ if ($useDirty) {
+ $array = array_intersect_key($this->_data, $primary);
+ } else {
+ $array = array_intersect_key($this->_cleanData, $primary);
+ }
+ if (count($primary) != count($array)) {
+ throw new Zend_Db_Table_Row_Exception("The specified Table '$this->_tableClass' does not have the same primary key as the Row");
+ }
+ return $array;
+ }
+
+ /**
+ * Retrieves an associative array of primary keys.
+ *
+ * @param bool $useDirty
+ * @return array
+ */
+ public function getPrimaryKey($useDirty = true)
+ {
+ return $this->_getPrimaryKey($useDirty);
+ }
+
+ /**
+ * Constructs where statement for retrieving row(s).
+ *
+ * @param bool $useDirty
+ * @return array
+ */
+ protected function _getWhereQuery($useDirty = true)
+ {
+ $where = array();
+ $db = $this->_getTable()->getAdapter();
+ $primaryKey = $this->_getPrimaryKey($useDirty);
+ $info = $this->_getTable()->info();
+ $metadata = $info[Zend_Db_Table_Abstract::METADATA];
+
+ // retrieve recently updated row using primary keys
+ $where = array();
+ foreach ($primaryKey as $column => $value) {
+ $tableName = $db->quoteIdentifier($info[Zend_Db_Table_Abstract::NAME], true);
+ $type = $metadata[$column]['DATA_TYPE'];
+ $columnName = $db->quoteIdentifier($column, true);
+ $where[] = $db->quoteInto("{$tableName}.{$columnName} = ?", $value, $type);
+ }
+ return $where;
+ }
+
+ /**
+ * Refreshes properties from the database.
+ *
+ * @return void
+ */
+ protected function _refresh()
+ {
+ $where = $this->_getWhereQuery();
+ $row = $this->_getTable()->fetchRow($where);
+
+ if (null === $row) {
+ throw new Zend_Db_Table_Row_Exception('Cannot refresh row as parent is missing');
+ }
+
+ $this->_data = $row->toArray();
+ $this->_cleanData = $this->_data;
+ $this->_modifiedFields = array();
+ }
+
+ /**
+ * Allows pre-insert logic to be applied to row.
+ * Subclasses may override this method.
+ *
+ * @return void
+ */
+ protected function _insert()
+ {
+ }
+
+ /**
+ * Allows post-insert logic to be applied to row.
+ * Subclasses may override this method.
+ *
+ * @return void
+ */
+ protected function _postInsert()
+ {
+ }
+
+ /**
+ * Allows pre-update logic to be applied to row.
+ * Subclasses may override this method.
+ *
+ * @return void
+ */
+ protected function _update()
+ {
+ }
+
+ /**
+ * Allows post-update logic to be applied to row.
+ * Subclasses may override this method.
+ *
+ * @return void
+ */
+ protected function _postUpdate()
+ {
+ }
+
+ /**
+ * Allows pre-delete logic to be applied to row.
+ * Subclasses may override this method.
+ *
+ * @return void
+ */
+ protected function _delete()
+ {
+ }
+
+ /**
+ * Allows post-delete logic to be applied to row.
+ * Subclasses may override this method.
+ *
+ * @return void
+ */
+ protected function _postDelete()
+ {
+ }
+
+ /**
+ * Prepares a table reference for lookup.
+ *
+ * Ensures all reference keys are set and properly formatted.
+ *
+ * @param Zend_Db_Table_Abstract $dependentTable
+ * @param Zend_Db_Table_Abstract $parentTable
+ * @param string $ruleKey
+ * @return array
+ */
+ protected function _prepareReference(Zend_Db_Table_Abstract $dependentTable, Zend_Db_Table_Abstract $parentTable, $ruleKey)
+ {
+ $parentTableName = (get_class($parentTable) === 'Zend_Db_Table') ? $parentTable->getDefinitionConfigName() : get_class($parentTable);
+ $map = $dependentTable->getReference($parentTableName, $ruleKey);
+
+ if (!isset($map[Zend_Db_Table_Abstract::REF_COLUMNS])) {
+ $parentInfo = $parentTable->info();
+ $map[Zend_Db_Table_Abstract::REF_COLUMNS] = array_values((array) $parentInfo['primary']);
+ }
+
+ $map[Zend_Db_Table_Abstract::COLUMNS] = (array) $map[Zend_Db_Table_Abstract::COLUMNS];
+ $map[Zend_Db_Table_Abstract::REF_COLUMNS] = (array) $map[Zend_Db_Table_Abstract::REF_COLUMNS];
+
+ return $map;
+ }
+
+ /**
+ * Query a dependent table to retrieve rows matching the current row.
+ *
+ * @param string|Zend_Db_Table_Abstract $dependentTable
+ * @param string OPTIONAL $ruleKey
+ * @param Zend_Db_Table_Select OPTIONAL $select
+ * @return Zend_Db_Table_Rowset_Abstract Query result from $dependentTable
+ * @throws Zend_Db_Table_Row_Exception If $dependentTable is not a table or is not loadable.
+ */
+ public function findDependentRowset($dependentTable, $ruleKey = null, Zend_Db_Table_Select $select = null)
+ {
+ $db = $this->_getTable()->getAdapter();
+
+ if (is_string($dependentTable)) {
+ $dependentTable = $this->_getTableFromString($dependentTable);
+ }
+
+ if (!$dependentTable instanceof Zend_Db_Table_Abstract) {
+ $type = gettype($dependentTable);
+ if ($type == 'object') {
+ $type = get_class($dependentTable);
+ }
+ throw new Zend_Db_Table_Row_Exception("Dependent table must be a Zend_Db_Table_Abstract, but it is $type");
+ }
+
+ // even if we are interacting between a table defined in a class and a
+ // table via extension, ensure to persist the definition
+ if (($tableDefinition = $this->_table->getDefinition()) !== null
+ && ($dependentTable->getDefinition() == null)) {
+ $dependentTable->setOptions(array(Zend_Db_Table_Abstract::DEFINITION => $tableDefinition));
+ }
+
+ if ($select === null) {
+ $select = $dependentTable->select();
+ } else {
+ $select->setTable($dependentTable);
+ }
+
+ $map = $this->_prepareReference($dependentTable, $this->_getTable(), $ruleKey);
+
+ for ($i = 0; $i < count($map[Zend_Db_Table_Abstract::COLUMNS]); ++$i) {
+ $parentColumnName = $db->foldCase($map[Zend_Db_Table_Abstract::REF_COLUMNS][$i]);
+ $value = $this->_data[$parentColumnName];
+ // Use adapter from dependent table to ensure correct query construction
+ $dependentDb = $dependentTable->getAdapter();
+ $dependentColumnName = $dependentDb->foldCase($map[Zend_Db_Table_Abstract::COLUMNS][$i]);
+ $dependentColumn = $dependentDb->quoteIdentifier($dependentColumnName, true);
+ $dependentInfo = $dependentTable->info();
+ $type = $dependentInfo[Zend_Db_Table_Abstract::METADATA][$dependentColumnName]['DATA_TYPE'];
+ $select->where("$dependentColumn = ?", $value, $type);
+ }
+
+ return $dependentTable->fetchAll($select);
+ }
+
+ /**
+ * Query a parent table to retrieve the single row matching the current row.
+ *
+ * @param string|Zend_Db_Table_Abstract $parentTable
+ * @param string OPTIONAL $ruleKey
+ * @param Zend_Db_Table_Select OPTIONAL $select
+ * @return Zend_Db_Table_Row_Abstract Query result from $parentTable
+ * @throws Zend_Db_Table_Row_Exception If $parentTable is not a table or is not loadable.
+ */
+ public function findParentRow($parentTable, $ruleKey = null, Zend_Db_Table_Select $select = null)
+ {
+ $db = $this->_getTable()->getAdapter();
+
+ if (is_string($parentTable)) {
+ $parentTable = $this->_getTableFromString($parentTable);
+ }
+
+ if (!$parentTable instanceof Zend_Db_Table_Abstract) {
+ $type = gettype($parentTable);
+ if ($type == 'object') {
+ $type = get_class($parentTable);
+ }
+ throw new Zend_Db_Table_Row_Exception("Parent table must be a Zend_Db_Table_Abstract, but it is $type");
+ }
+
+ // even if we are interacting between a table defined in a class and a
+ // table via extension, ensure to persist the definition
+ if (($tableDefinition = $this->_table->getDefinition()) !== null
+ && ($parentTable->getDefinition() == null)) {
+ $parentTable->setOptions(array(Zend_Db_Table_Abstract::DEFINITION => $tableDefinition));
+ }
+
+ if ($select === null) {
+ $select = $parentTable->select();
+ } else {
+ $select->setTable($parentTable);
+ }
+
+ $map = $this->_prepareReference($this->_getTable(), $parentTable, $ruleKey);
+
+ // iterate the map, creating the proper wheres
+ for ($i = 0; $i < count($map[Zend_Db_Table_Abstract::COLUMNS]); ++$i) {
+ $dependentColumnName = $db->foldCase($map[Zend_Db_Table_Abstract::COLUMNS][$i]);
+ $value = $this->_data[$dependentColumnName];
+ // Use adapter from parent table to ensure correct query construction
+ $parentDb = $parentTable->getAdapter();
+ $parentColumnName = $parentDb->foldCase($map[Zend_Db_Table_Abstract::REF_COLUMNS][$i]);
+ $parentColumn = $parentDb->quoteIdentifier($parentColumnName, true);
+ $parentInfo = $parentTable->info();
+
+ // determine where part
+ $type = $parentInfo[Zend_Db_Table_Abstract::METADATA][$parentColumnName]['DATA_TYPE'];
+ $nullable = $parentInfo[Zend_Db_Table_Abstract::METADATA][$parentColumnName]['NULLABLE'];
+ if ($value === null && $nullable == true) {
+ $select->where("$parentColumn IS NULL");
+ } elseif ($value === null && $nullable == false) {
+ return null;
+ } else {
+ $select->where("$parentColumn = ?", $value, $type);
+ }
+
+ }
+
+ return $parentTable->fetchRow($select);
+ }
+
+ /**
+ * @param string|Zend_Db_Table_Abstract $matchTable
+ * @param string|Zend_Db_Table_Abstract $intersectionTable
+ * @param string OPTIONAL $callerRefRule
+ * @param string OPTIONAL $matchRefRule
+ * @param Zend_Db_Table_Select OPTIONAL $select
+ * @return Zend_Db_Table_Rowset_Abstract Query result from $matchTable
+ * @throws Zend_Db_Table_Row_Exception If $matchTable or $intersectionTable is not a table class or is not loadable.
+ */
+ public function findManyToManyRowset($matchTable, $intersectionTable, $callerRefRule = null,
+ $matchRefRule = null, Zend_Db_Table_Select $select = null)
+ {
+ $db = $this->_getTable()->getAdapter();
+
+ if (is_string($intersectionTable)) {
+ $intersectionTable = $this->_getTableFromString($intersectionTable);
+ }
+
+ if (!$intersectionTable instanceof Zend_Db_Table_Abstract) {
+ $type = gettype($intersectionTable);
+ if ($type == 'object') {
+ $type = get_class($intersectionTable);
+ }
+ throw new Zend_Db_Table_Row_Exception("Intersection table must be a Zend_Db_Table_Abstract, but it is $type");
+ }
+
+ // even if we are interacting between a table defined in a class and a
+ // table via extension, ensure to persist the definition
+ if (($tableDefinition = $this->_table->getDefinition()) !== null
+ && ($intersectionTable->getDefinition() == null)) {
+ $intersectionTable->setOptions(array(Zend_Db_Table_Abstract::DEFINITION => $tableDefinition));
+ }
+
+ if (is_string($matchTable)) {
+ $matchTable = $this->_getTableFromString($matchTable);
+ }
+
+ if (! $matchTable instanceof Zend_Db_Table_Abstract) {
+ $type = gettype($matchTable);
+ if ($type == 'object') {
+ $type = get_class($matchTable);
+ }
+ throw new Zend_Db_Table_Row_Exception("Match table must be a Zend_Db_Table_Abstract, but it is $type");
+ }
+
+ // even if we are interacting between a table defined in a class and a
+ // table via extension, ensure to persist the definition
+ if (($tableDefinition = $this->_table->getDefinition()) !== null
+ && ($matchTable->getDefinition() == null)) {
+ $matchTable->setOptions(array(Zend_Db_Table_Abstract::DEFINITION => $tableDefinition));
+ }
+
+ if ($select === null) {
+ $select = $matchTable->select();
+ } else {
+ $select->setTable($matchTable);
+ }
+
+ // Use adapter from intersection table to ensure correct query construction
+ $interInfo = $intersectionTable->info();
+ $interDb = $intersectionTable->getAdapter();
+ $interName = $interInfo['name'];
+ $interSchema = isset($interInfo['schema']) ? $interInfo['schema'] : null;
+ $matchInfo = $matchTable->info();
+ $matchName = $matchInfo['name'];
+ $matchSchema = isset($matchInfo['schema']) ? $matchInfo['schema'] : null;
+
+ $matchMap = $this->_prepareReference($intersectionTable, $matchTable, $matchRefRule);
+
+ for ($i = 0; $i < count($matchMap[Zend_Db_Table_Abstract::COLUMNS]); ++$i) {
+ $interCol = $interDb->quoteIdentifier('i' . '.' . $matchMap[Zend_Db_Table_Abstract::COLUMNS][$i], true);
+ $matchCol = $interDb->quoteIdentifier('m' . '.' . $matchMap[Zend_Db_Table_Abstract::REF_COLUMNS][$i], true);
+ $joinCond[] = "$interCol = $matchCol";
+ }
+ $joinCond = implode(' AND ', $joinCond);
+
+ $select->from(array('i' => $interName), array(), $interSchema)
+ ->joinInner(array('m' => $matchName), $joinCond, Zend_Db_Select::SQL_WILDCARD, $matchSchema)
+ ->setIntegrityCheck(false);
+
+ $callerMap = $this->_prepareReference($intersectionTable, $this->_getTable(), $callerRefRule);
+
+ for ($i = 0; $i < count($callerMap[Zend_Db_Table_Abstract::COLUMNS]); ++$i) {
+ $callerColumnName = $db->foldCase($callerMap[Zend_Db_Table_Abstract::REF_COLUMNS][$i]);
+ $value = $this->_data[$callerColumnName];
+ $interColumnName = $interDb->foldCase($callerMap[Zend_Db_Table_Abstract::COLUMNS][$i]);
+ $interCol = $interDb->quoteIdentifier("i.$interColumnName", true);
+ $interInfo = $intersectionTable->info();
+ $type = $interInfo[Zend_Db_Table_Abstract::METADATA][$interColumnName]['DATA_TYPE'];
+ $select->where($interDb->quoteInto("$interCol = ?", $value, $type));
+ }
+
+ $stmt = $select->query();
+
+ $config = array(
+ 'table' => $matchTable,
+ 'data' => $stmt->fetchAll(Zend_Db::FETCH_ASSOC),
+ 'rowClass' => $matchTable->getRowClass(),
+ 'readOnly' => false,
+ 'stored' => true
+ );
+
+ $rowsetClass = $matchTable->getRowsetClass();
+ if (!class_exists($rowsetClass)) {
+ try {
+ Zend_Loader::loadClass($rowsetClass);
+ } catch (Zend_Exception $e) {
+ throw new Zend_Db_Table_Row_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+ $rowset = new $rowsetClass($config);
+ return $rowset;
+ }
+
+ /**
+ * Turn magic function calls into non-magic function calls
+ * to the above methods.
+ *
+ * @param string $method
+ * @param array $args OPTIONAL Zend_Db_Table_Select query modifier
+ * @return Zend_Db_Table_Row_Abstract|Zend_Db_Table_Rowset_Abstract
+ * @throws Zend_Db_Table_Row_Exception If an invalid method is called.
+ */
+ public function __call($method, array $args)
+ {
+ $matches = array();
+
+ if (count($args) && $args[0] instanceof Zend_Db_Table_Select) {
+ $select = $args[0];
+ } else {
+ $select = null;
+ }
+
+ /**
+ * Recognize methods for Has-Many cases:
+ * findParent<Class>()
+ * findParent<Class>By<Rule>()
+ * Use the non-greedy pattern repeat modifier e.g. \w+?
+ */
+ if (preg_match('/^findParent(\w+?)(?:By(\w+))?$/', $method, $matches)) {
+ $class = $matches[1];
+ $ruleKey1 = isset($matches[2]) ? $matches[2] : null;
+ return $this->findParentRow($class, $ruleKey1, $select);
+ }
+
+ /**
+ * Recognize methods for Many-to-Many cases:
+ * find<Class1>Via<Class2>()
+ * find<Class1>Via<Class2>By<Rule>()
+ * find<Class1>Via<Class2>By<Rule1>And<Rule2>()
+ * Use the non-greedy pattern repeat modifier e.g. \w+?
+ */
+ if (preg_match('/^find(\w+?)Via(\w+?)(?:By(\w+?)(?:And(\w+))?)?$/', $method, $matches)) {
+ $class = $matches[1];
+ $viaClass = $matches[2];
+ $ruleKey1 = isset($matches[3]) ? $matches[3] : null;
+ $ruleKey2 = isset($matches[4]) ? $matches[4] : null;
+ return $this->findManyToManyRowset($class, $viaClass, $ruleKey1, $ruleKey2, $select);
+ }
+
+ /**
+ * Recognize methods for Belongs-To cases:
+ * find<Class>()
+ * find<Class>By<Rule>()
+ * Use the non-greedy pattern repeat modifier e.g. \w+?
+ */
+ if (preg_match('/^find(\w+?)(?:By(\w+))?$/', $method, $matches)) {
+ $class = $matches[1];
+ $ruleKey1 = isset($matches[2]) ? $matches[2] : null;
+ return $this->findDependentRowset($class, $ruleKey1, $select);
+ }
+
+ throw new Zend_Db_Table_Row_Exception("Unrecognized method '$method()'");
+ }
+
+
+ /**
+ * _getTableFromString
+ *
+ * @param string $tableName
+ * @return Zend_Db_Table_Abstract
+ */
+ protected function _getTableFromString($tableName)
+ {
+ return Zend_Db_Table_Abstract::getTableFromString($tableName, $this->_table);
+ }
+
+}
diff --git a/library/vendor/Zend/Db/Table/Row/Exception.php b/library/vendor/Zend/Db/Table/Row/Exception.php
new file mode 100644
index 0000000..fe23d66
--- /dev/null
+++ b/library/vendor/Zend/Db/Table/Row/Exception.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Table
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * Zend_Db_Table_Exception
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Table
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Table_Row_Exception extends Zend_Db_Table_Exception
+{
+}
+
diff --git a/library/vendor/Zend/Db/Table/Rowset.php b/library/vendor/Zend/Db/Table/Rowset.php
new file mode 100644
index 0000000..ce20a58
--- /dev/null
+++ b/library/vendor/Zend/Db/Table/Rowset.php
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Table
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+
+/**
+ * @see Zend_Db_Table_Rowset_Abstract
+ */
+
+
+/**
+ * Reference concrete class that extends Zend_Db_Table_Rowset_Abstract.
+ * Developers may also create their own classes that extend the abstract class.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Table
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Table_Rowset extends Zend_Db_Table_Rowset_Abstract
+{
+}
diff --git a/library/vendor/Zend/Db/Table/Rowset/Abstract.php b/library/vendor/Zend/Db/Table/Rowset/Abstract.php
new file mode 100644
index 0000000..205fe1b
--- /dev/null
+++ b/library/vendor/Zend/Db/Table/Rowset/Abstract.php
@@ -0,0 +1,443 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Table
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Table
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+abstract class Zend_Db_Table_Rowset_Abstract implements SeekableIterator, Countable, ArrayAccess
+{
+ /**
+ * The original data for each row.
+ *
+ * @var array
+ */
+ protected $_data = array();
+
+ /**
+ * Zend_Db_Table_Abstract object.
+ *
+ * @var Zend_Db_Table_Abstract
+ */
+ protected $_table;
+
+ /**
+ * Connected is true if we have a reference to a live
+ * Zend_Db_Table_Abstract object.
+ * This is false after the Rowset has been deserialized.
+ *
+ * @var boolean
+ */
+ protected $_connected = true;
+
+ /**
+ * Zend_Db_Table_Abstract class name.
+ *
+ * @var string
+ */
+ protected $_tableClass;
+
+ /**
+ * Zend_Db_Table_Row_Abstract class name.
+ *
+ * @var string
+ */
+ protected $_rowClass = 'Zend_Db_Table_Row';
+
+ /**
+ * Iterator pointer.
+ *
+ * @var integer
+ */
+ protected $_pointer = 0;
+
+ /**
+ * How many data rows there are.
+ *
+ * @var integer
+ */
+ protected $_count;
+
+ /**
+ * Collection of instantiated Zend_Db_Table_Row objects.
+ *
+ * @var array
+ */
+ protected $_rows = array();
+
+ /**
+ * @var boolean
+ */
+ protected $_stored = false;
+
+ /**
+ * @var boolean
+ */
+ protected $_readOnly = false;
+
+ /**
+ * Constructor.
+ *
+ * @param array $config
+ */
+ public function __construct(array $config)
+ {
+ if (isset($config['table'])) {
+ $this->_table = $config['table'];
+ $this->_tableClass = get_class($this->_table);
+ }
+ if (isset($config['rowClass'])) {
+ $this->_rowClass = $config['rowClass'];
+ }
+ if (!class_exists($this->_rowClass)) {
+ Zend_Loader::loadClass($this->_rowClass);
+ }
+ if (isset($config['data'])) {
+ $this->_data = $config['data'];
+ }
+ if (isset($config['readOnly'])) {
+ $this->_readOnly = $config['readOnly'];
+ }
+ if (isset($config['stored'])) {
+ $this->_stored = $config['stored'];
+ }
+
+ // set the count of rows
+ $this->_count = count($this->_data);
+
+ $this->init();
+ }
+
+ /**
+ * Store data, class names, and state in serialized object
+ *
+ * @return array
+ */
+ public function __sleep()
+ {
+ return array('_data', '_tableClass', '_rowClass', '_pointer', '_count', '_rows', '_stored',
+ '_readOnly');
+ }
+
+ /**
+ * Setup to do on wakeup.
+ * A de-serialized Rowset should not be assumed to have access to a live
+ * database connection, so set _connected = false.
+ *
+ * @return void
+ */
+ public function __wakeup()
+ {
+ $this->_connected = false;
+ }
+
+ /**
+ * Initialize object
+ *
+ * Called from {@link __construct()} as final step of object instantiation.
+ *
+ * @return void
+ */
+ public function init()
+ {
+ }
+
+ /**
+ * Return the connected state of the rowset.
+ *
+ * @return boolean
+ */
+ public function isConnected()
+ {
+ return $this->_connected;
+ }
+
+ /**
+ * Returns the table object, or null if this is disconnected rowset
+ *
+ * @return Zend_Db_Table_Abstract
+ */
+ public function getTable()
+ {
+ return $this->_table;
+ }
+
+ /**
+ * Set the table object, to re-establish a live connection
+ * to the database for a Rowset that has been de-serialized.
+ *
+ * @param Zend_Db_Table_Abstract $table
+ * @return boolean
+ * @throws Zend_Db_Table_Row_Exception
+ */
+ public function setTable(Zend_Db_Table_Abstract $table)
+ {
+ $this->_table = $table;
+ $this->_connected = false;
+ // @todo This works only if we have iterated through
+ // the result set once to instantiate the rows.
+ foreach ($this as $row) {
+ $connected = $row->setTable($table);
+ if ($connected == true) {
+ $this->_connected = true;
+ }
+ }
+ $this->rewind();
+ return $this->_connected;
+ }
+
+ /**
+ * Query the class name of the Table object for which this
+ * Rowset was created.
+ *
+ * @return string
+ */
+ public function getTableClass()
+ {
+ return $this->_tableClass;
+ }
+
+ /**
+ * Rewind the Iterator to the first element.
+ * Similar to the reset() function for arrays in PHP.
+ * Required by interface Iterator.
+ *
+ * @return Zend_Db_Table_Rowset_Abstract Fluent interface.
+ */
+ public function rewind()
+ {
+ $this->_pointer = 0;
+ return $this;
+ }
+
+ /**
+ * Return the current element.
+ * Similar to the current() function for arrays in PHP
+ * Required by interface Iterator.
+ *
+ * @return Zend_Db_Table_Row_Abstract current element from the collection
+ */
+ public function current()
+ {
+ if ($this->valid() === false) {
+ return null;
+ }
+
+ // return the row object
+ return $this->_loadAndReturnRow($this->_pointer);
+ }
+
+ /**
+ * Return the identifying key of the current element.
+ * Similar to the key() function for arrays in PHP.
+ * Required by interface Iterator.
+ *
+ * @return int
+ */
+ public function key()
+ {
+ return $this->_pointer;
+ }
+
+ /**
+ * Move forward to next element.
+ * Similar to the next() function for arrays in PHP.
+ * Required by interface Iterator.
+ *
+ * @return void
+ */
+ public function next()
+ {
+ ++$this->_pointer;
+ }
+
+ /**
+ * Check if there is a current element after calls to rewind() or next().
+ * Used to check if we've iterated to the end of the collection.
+ * Required by interface Iterator.
+ *
+ * @return bool False if there's nothing more to iterate over
+ */
+ public function valid()
+ {
+ return $this->_pointer >= 0 && $this->_pointer < $this->_count;
+ }
+
+ /**
+ * Returns the number of elements in the collection.
+ *
+ * Implements Countable::count()
+ *
+ * @return int
+ */
+ public function count()
+ {
+ return $this->_count;
+ }
+
+ /**
+ * Take the Iterator to position $position
+ * Required by interface SeekableIterator.
+ *
+ * @param int $position the position to seek to
+ * @return Zend_Db_Table_Rowset_Abstract
+ * @throws Zend_Db_Table_Rowset_Exception
+ */
+ public function seek($position)
+ {
+ $position = (int) $position;
+ if ($position < 0 || $position >= $this->_count) {
+ throw new Zend_Db_Table_Rowset_Exception("Illegal index $position");
+ }
+ $this->_pointer = $position;
+ return $this;
+ }
+
+ /**
+ * Check if an offset exists
+ * Required by the ArrayAccess implementation
+ *
+ * @param string $offset
+ * @return boolean
+ */
+ public function offsetExists($offset)
+ {
+ return isset($this->_data[(int) $offset]);
+ }
+
+ /**
+ * Get the row for the given offset
+ * Required by the ArrayAccess implementation
+ *
+ * @param string $offset
+ * @return Zend_Db_Table_Row_Abstract
+ */
+ public function offsetGet($offset)
+ {
+ $offset = (int) $offset;
+ if ($offset < 0 || $offset >= $this->_count) {
+ throw new Zend_Db_Table_Rowset_Exception("Illegal index $offset");
+ }
+ $this->_pointer = $offset;
+
+ return $this->current();
+ }
+
+ /**
+ * Does nothing
+ * Required by the ArrayAccess implementation
+ *
+ * @param string $offset
+ * @param mixed $value
+ */
+ public function offsetSet($offset, $value)
+ {
+ }
+
+ /**
+ * Does nothing
+ * Required by the ArrayAccess implementation
+ *
+ * @param string $offset
+ */
+ public function offsetUnset($offset)
+ {
+ }
+
+ /**
+ * Returns a Zend_Db_Table_Row from a known position into the Iterator
+ *
+ * @param int $position the position of the row expected
+ * @param bool $seek wether or not seek the iterator to that position after
+ * @return Zend_Db_Table_Row
+ * @throws Zend_Db_Table_Rowset_Exception
+ */
+ public function getRow($position, $seek = false)
+ {
+ try {
+ $row = $this->_loadAndReturnRow($position);
+ } catch (Zend_Db_Table_Rowset_Exception $e) {
+ throw new Zend_Db_Table_Rowset_Exception('No row could be found at position ' . (int) $position, 0, $e);
+ }
+
+ if ($seek == true) {
+ $this->seek($position);
+ }
+
+ return $row;
+ }
+
+ /**
+ * Returns all data as an array.
+ *
+ * Updates the $_data property with current row object values.
+ *
+ * @return array
+ */
+ public function toArray()
+ {
+ // @todo This works only if we have iterated through
+ // the result set once to instantiate the rows.
+ foreach ($this->_rows as $i => $row) {
+ $this->_data[$i] = $row->toArray();
+ }
+ return $this->_data;
+ }
+
+ protected function _loadAndReturnRow($position)
+ {
+ if (!isset($this->_data[$position])) {
+ throw new Zend_Db_Table_Rowset_Exception("Data for provided position does not exist");
+ }
+
+ // do we already have a row object for this position?
+ if (empty($this->_rows[$position])) {
+ $this->_rows[$position] = new $this->_rowClass(
+ array(
+ 'table' => $this->_table,
+ 'data' => $this->_data[$position],
+ 'stored' => $this->_stored,
+ 'readOnly' => $this->_readOnly
+ )
+ );
+
+ if ( $this->_table instanceof Zend_Db_Table_Abstract ) {
+ $info = $this->_table->info();
+
+ if ( $this->_rows[$position] instanceof Zend_Db_Table_Row_Abstract ) {
+ if ($info['cols'] == array_keys($this->_data[$position])) {
+ $this->_rows[$position]->setTable($this->getTable());
+ }
+ }
+ } else {
+ $this->_rows[$position]->setTable(null);
+ }
+ }
+
+ // return the row object
+ return $this->_rows[$position];
+ }
+
+}
diff --git a/library/vendor/Zend/Db/Table/Rowset/Exception.php b/library/vendor/Zend/Db/Table/Rowset/Exception.php
new file mode 100644
index 0000000..9879113
--- /dev/null
+++ b/library/vendor/Zend/Db/Table/Rowset/Exception.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Table
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * Zend_Db_Table_Exception
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Table
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Table_Rowset_Exception extends Zend_Db_Table_Exception
+{
+}
diff --git a/library/vendor/Zend/Db/Table/Select.php b/library/vendor/Zend/Db/Table/Select.php
new file mode 100644
index 0000000..fade302
--- /dev/null
+++ b/library/vendor/Zend/Db/Table/Select.php
@@ -0,0 +1,221 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Select
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+
+/**
+ * @see Zend_Db_Select
+ */
+
+
+/**
+ * @see Zend_Db_Table_Abstract
+ */
+
+
+/**
+ * Class for SQL SELECT query manipulation for the Zend_Db_Table component.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Table
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Db_Table_Select extends Zend_Db_Select
+{
+ /**
+ * Table schema for parent Zend_Db_Table.
+ *
+ * @var array
+ */
+ protected $_info;
+
+ /**
+ * Table integrity override.
+ *
+ * @var array
+ */
+ protected $_integrityCheck = true;
+
+ /**
+ * Table instance that created this select object
+ *
+ * @var Zend_Db_Table_Abstract
+ */
+ protected $_table;
+
+ /**
+ * Class constructor
+ *
+ * @param Zend_Db_Table_Abstract $adapter
+ */
+ public function __construct(Zend_Db_Table_Abstract $table)
+ {
+ parent::__construct($table->getAdapter());
+
+ $this->setTable($table);
+ }
+
+ /**
+ * Return the table that created this select object
+ *
+ * @return Zend_Db_Table_Abstract
+ */
+ public function getTable()
+ {
+ return $this->_table;
+ }
+
+ /**
+ * Sets the primary table name and retrieves the table schema.
+ *
+ * @param Zend_Db_Table_Abstract $adapter
+ * @return Zend_Db_Select This Zend_Db_Select object.
+ */
+ public function setTable(Zend_Db_Table_Abstract $table)
+ {
+ $this->_adapter = $table->getAdapter();
+ $this->_info = $table->info();
+ $this->_table = $table;
+
+ return $this;
+ }
+
+ /**
+ * Sets the integrity check flag.
+ *
+ * Setting this flag to false skips the checks for table joins, allowing
+ * 'hybrid' table rows to be created.
+ *
+ * @param Zend_Db_Table_Abstract $adapter
+ * @return Zend_Db_Select This Zend_Db_Select object.
+ */
+ public function setIntegrityCheck($flag = true)
+ {
+ $this->_integrityCheck = $flag;
+ return $this;
+ }
+
+ /**
+ * Tests query to determine if expressions or aliases columns exist.
+ *
+ * @return boolean
+ */
+ public function isReadOnly()
+ {
+ $readOnly = false;
+ $fields = $this->getPart(Zend_Db_Table_Select::COLUMNS);
+ $cols = $this->_info[Zend_Db_Table_Abstract::COLS];
+
+ if (!count($fields)) {
+ return $readOnly;
+ }
+
+ foreach ($fields as $columnEntry) {
+ $column = $columnEntry[1];
+ $alias = $columnEntry[2];
+
+ if ($alias !== null) {
+ $column = $alias;
+ }
+
+ switch (true) {
+ case ($column == self::SQL_WILDCARD):
+ break;
+
+ case ($column instanceof Zend_Db_Expr):
+ case (!in_array($column, $cols)):
+ $readOnly = true;
+ break 2;
+ }
+ }
+
+ return $readOnly;
+ }
+
+ /**
+ * Adds a FROM table and optional columns to the query.
+ *
+ * The table name can be expressed
+ *
+ * @param array|string|Zend_Db_Expr|Zend_Db_Table_Abstract $name The table name or an
+ associative array relating
+ table name to correlation
+ name.
+ * @param array|string|Zend_Db_Expr $cols The columns to select from this table.
+ * @param string $schema The schema name to specify, if any.
+ * @return Zend_Db_Table_Select This Zend_Db_Table_Select object.
+ */
+ public function from($name, $cols = self::SQL_WILDCARD, $schema = null)
+ {
+ if ($name instanceof Zend_Db_Table_Abstract) {
+ $info = $name->info();
+ $name = $info[Zend_Db_Table_Abstract::NAME];
+ if (isset($info[Zend_Db_Table_Abstract::SCHEMA])) {
+ $schema = $info[Zend_Db_Table_Abstract::SCHEMA];
+ }
+ }
+
+ return $this->joinInner($name, null, $cols, $schema);
+ }
+
+ /**
+ * Performs a validation on the select query before passing back to the parent class.
+ * Ensures that only columns from the primary Zend_Db_Table are returned in the result.
+ *
+ * @return string|null This object as a SELECT string (or null if a string cannot be produced)
+ */
+ public function assemble()
+ {
+ $fields = $this->getPart(Zend_Db_Table_Select::COLUMNS);
+ $primary = $this->_info[Zend_Db_Table_Abstract::NAME];
+ $schema = $this->_info[Zend_Db_Table_Abstract::SCHEMA];
+
+
+ if (count($this->_parts[self::UNION]) == 0) {
+
+ // If no fields are specified we assume all fields from primary table
+ if (!count($fields)) {
+ $this->from($primary, self::SQL_WILDCARD, $schema);
+ $fields = $this->getPart(Zend_Db_Table_Select::COLUMNS);
+ }
+
+ $from = $this->getPart(Zend_Db_Table_Select::FROM);
+
+ if ($this->_integrityCheck !== false) {
+ foreach ($fields as $columnEntry) {
+ list($table, $column) = $columnEntry;
+
+ // Check each column to ensure it only references the primary table
+ if ($column) {
+ if (!isset($from[$table]) || $from[$table]['tableName'] != $primary) {
+ throw new Zend_Db_Table_Select_Exception('Select query cannot join with another table');
+ }
+ }
+ }
+ }
+ }
+
+ return parent::assemble();
+ }
+}
diff --git a/library/vendor/Zend/Db/Table/Select/Exception.php b/library/vendor/Zend/Db/Table/Select/Exception.php
new file mode 100644
index 0000000..7ed15be
--- /dev/null
+++ b/library/vendor/Zend/Db/Table/Select/Exception.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Select
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * Zend_Db_Exception
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage Table
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+class Zend_Db_Table_Select_Exception extends Zend_Db_Select_Exception
+{
+}
+