aboutsummaryrefslogtreecommitdiff
path: root/includes/vendor/aura/sql/src
diff options
context:
space:
mode:
authors1n <[email protected]>2020-03-28 10:36:41 -0700
committers1n <[email protected]>2020-03-28 10:36:41 -0700
commit25b7d2aab61ae6421398d3abae5da6ffe590333d (patch)
tree611985ec78bb2d94099c9fd5dd687f5c9cee6f3e /includes/vendor/aura/sql/src
parentInitial commit (diff)
downloadcrack.cf-backup-master.tar.xz
crack.cf-backup-master.zip
3/28/2020, 10:36HEADmaster
Diffstat (limited to 'includes/vendor/aura/sql/src')
-rw-r--r--includes/vendor/aura/sql/src/ConnectionLocator.php315
-rw-r--r--includes/vendor/aura/sql/src/ConnectionLocatorInterface.php91
-rw-r--r--includes/vendor/aura/sql/src/Exception.php20
-rw-r--r--includes/vendor/aura/sql/src/Exception/CannotBindValue.php23
-rw-r--r--includes/vendor/aura/sql/src/Exception/CannotDisconnect.php23
-rw-r--r--includes/vendor/aura/sql/src/Exception/ConnectionNotFound.php22
-rw-r--r--includes/vendor/aura/sql/src/Exception/MissingParameter.php22
-rw-r--r--includes/vendor/aura/sql/src/ExtendedPdo.php1138
-rw-r--r--includes/vendor/aura/sql/src/ExtendedPdoInterface.php267
-rw-r--r--includes/vendor/aura/sql/src/Iterator/AbstractIterator.php114
-rw-r--r--includes/vendor/aura/sql/src/Iterator/AllIterator.php46
-rw-r--r--includes/vendor/aura/sql/src/Iterator/AssocIterator.php49
-rw-r--r--includes/vendor/aura/sql/src/Iterator/ColIterator.php49
-rw-r--r--includes/vendor/aura/sql/src/Iterator/ObjectsIterator.php60
-rw-r--r--includes/vendor/aura/sql/src/Iterator/PairsIterator.php50
-rw-r--r--includes/vendor/aura/sql/src/PdoInterface.php196
-rw-r--r--includes/vendor/aura/sql/src/Profiler.php129
-rw-r--r--includes/vendor/aura/sql/src/ProfilerInterface.php80
-rw-r--r--includes/vendor/aura/sql/src/Rebuilder.php280
19 files changed, 2974 insertions, 0 deletions
diff --git a/includes/vendor/aura/sql/src/ConnectionLocator.php b/includes/vendor/aura/sql/src/ConnectionLocator.php
new file mode 100644
index 0000000..5afaf51
--- /dev/null
+++ b/includes/vendor/aura/sql/src/ConnectionLocator.php
@@ -0,0 +1,315 @@
+<?php
+/**
+ *
+ * This file is part of Aura for PHP.
+ *
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ *
+ */
+namespace Aura\Sql;
+
+/**
+ *
+ * Manages PDO connection objects for default, read, and write connections.
+ *
+ * @package Aura.Sql
+ *
+ */
+class ConnectionLocator implements ConnectionLocatorInterface
+{
+ /**
+ *
+ * A registry of PDO connection entries.
+ *
+ * @var array
+ *
+ */
+ protected $registry = array(
+ 'default' => null,
+ 'read' => array(),
+ 'write' => array(),
+ );
+
+ /**
+ *
+ * Whether or not registry entries have been converted to objects.
+ *
+ * @var array
+ *
+ */
+ protected $converted = array(
+ 'default' => false,
+ 'read' => array(),
+ 'write' => array(),
+ );
+
+ /**
+ *
+ * Whether or not to turn on profiling when retrieving a connection.
+ *
+ * @var bool
+ *
+ */
+ protected $profiling = false;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param callable $default A callable to create a default connection.
+ *
+ * @param array $read An array of callables to create read connections.
+ *
+ * @param array $write An array of callables to create write connections.
+ *
+ */
+ public function __construct(
+ $default = null,
+ array $read = array(),
+ array $write = array()
+ ) {
+ if ($default) {
+ $this->setDefault($default);
+ }
+ foreach ($read as $name => $callable) {
+ $this->setRead($name, $callable);
+ }
+ foreach ($write as $name => $callable) {
+ $this->setWrite($name, $callable);
+ }
+ }
+
+ /**
+ *
+ * Sets the default connection registry entry.
+ *
+ * @param callable $callable The registry entry.
+ *
+ * @return null
+ *
+ */
+ public function setDefault($callable)
+ {
+ $this->registry['default'] = $callable;
+ $this->converted['default'] = false;
+ }
+
+ /**
+ *
+ * Returns the default connection object.
+ *
+ * @return ExtendedPdoInterface
+ *
+ */
+ public function getDefault()
+ {
+ if (! $this->converted['default']) {
+ $callable = $this->registry['default'];
+ $this->registry['default'] = call_user_func($callable);
+ $this->converted['default'] = true;
+ }
+
+ $connection = $this->registry['default'];
+ $this->setProfiler($connection);
+ return $connection;
+ }
+
+ /**
+ *
+ * Sets a read connection registry entry by name.
+ *
+ * @param string $name The name of the registry entry.
+ *
+ * @param callable $callable The registry entry.
+ *
+ * @return null
+ *
+ */
+ public function setRead($name, $callable)
+ {
+ $this->registry['read'][$name] = $callable;
+ $this->converted['read'][$name] = false;
+ }
+
+ /**
+ *
+ * Returns a read connection by name; if no name is given, picks a
+ * random connection; if no read connections are present, returns the
+ * default connection.
+ *
+ * @param string $name The read connection name to return.
+ *
+ * @return ExtendedPdoInterface
+ *
+ */
+ public function getRead($name = null)
+ {
+ return $this->getConnection('read', $name);
+ }
+
+ /**
+ *
+ * Sets a write connection registry entry by name.
+ *
+ * @param string $name The name of the registry entry.
+ *
+ * @param callable $callable The registry entry.
+ *
+ * @return null
+ *
+ */
+ public function setWrite($name, $callable)
+ {
+ $this->registry['write'][$name] = $callable;
+ $this->converted['write'][$name] = false;
+ }
+
+ /**
+ *
+ * Returns a write connection by name; if no name is given, picks a
+ * random connection; if no write connections are present, returns the
+ * default connection.
+ *
+ * @param string $name The write connection name to return.
+ *
+ * @return ExtendedPdoInterface
+ *
+ */
+ public function getWrite($name = null)
+ {
+ return $this->getConnection('write', $name);
+ }
+
+ /**
+ *
+ * Returns a connection by name.
+ *
+ * @param string $type The connection type ('read' or 'write').
+ *
+ * @param string $name The name of the connection.
+ *
+ * @return ExtendedPdoInterface
+ *
+ * @throws Exception\ConnectionNotFound
+ */
+ protected function getConnection($type, $name)
+ {
+ if (! $this->registry[$type]) {
+ return $this->getDefault();
+ }
+
+ if (! $name) {
+ $name = array_rand($this->registry[$type]);
+ }
+
+ if (! isset($this->registry[$type][$name])) {
+ throw new Exception\ConnectionNotFound("{$type}:{$name}");
+ }
+
+ if (! $this->converted[$type][$name]) {
+ $callable = $this->registry[$type][$name];
+ $this->registry[$type][$name] = call_user_func($callable);
+ $this->converted[$type][$name] = true;
+ }
+
+ $connection = $this->registry[$type][$name];
+ $this->setProfiler($connection);
+ return $connection;
+ }
+
+ /**
+ *
+ * Given a connection, enable or disable profiling on it. If a profiler has
+ * not been set into the connection, this will instantiate and set one.
+ *
+ * @param ExtendedPdo $connection The connection.
+ *
+ * @return null
+ *
+ */
+ protected function setProfiler(ExtendedPdo $connection)
+ {
+ $profiler = $connection->getProfiler();
+
+ if (! $this->profiling && ! $profiler) {
+ return;
+ }
+
+ if (! $profiler) {
+ $profiler = new Profiler();
+ $connection->setProfiler($profiler);
+ }
+
+ $profiler->setActive($this->profiling);
+ }
+
+ /**
+ *
+ * Set profiling on all connections at retrieval time?
+ *
+ * @param bool $profiling True to enable, or false to disable, profiling on
+ * each connection as it is retrieved.
+ *
+ * @return null
+ *
+ */
+ public function setProfiling($profiling = true)
+ {
+ $this->profiling = (bool) $profiling;
+ }
+
+ /**
+ *
+ * Gets the profiles from all connections.
+ *
+ * @return array
+ *
+ */
+ public function getProfiles()
+ {
+ $profiles = array();
+
+ if ($this->converted['default']) {
+ $connection = $this->registry['default'];
+ $this->addProfiles('default', $connection, $profiles);
+ }
+
+ foreach (array('read', 'write') as $type) {
+ foreach ($this->registry[$type] as $name) {
+ if ($this->converted[$type][$name]) {
+ $connection = $this->registry[$type][$name];
+ $this->addProfiles("{$type}:{$name}", $connection, $profiles);
+ }
+ }
+ }
+
+ ksort($profiles);
+ return $profiles;
+ }
+
+ /**
+ *
+ * Adds profiles from a connection, with a label for the connection name.
+ *
+ * @param string $label The connection label.
+ *
+ * @param ExtendedPdo $connection The connection.
+ *
+ * @param array &$profiles Add the connection profiles to this array, in
+ * place.
+ *
+ * @return null
+ */
+ protected function addProfiles($label, ExtendedPdo $connection, &$profiles)
+ {
+ $profiler = $connection->getProfiler();
+ if (! $profiler) {
+ return;
+ }
+
+ foreach ($profiler->getProfiles() as $key => $profile) {
+ $profile = array('connection' => $label) + $profile;
+ $profiles[$key] = $profile;
+ }
+ }
+}
diff --git a/includes/vendor/aura/sql/src/ConnectionLocatorInterface.php b/includes/vendor/aura/sql/src/ConnectionLocatorInterface.php
new file mode 100644
index 0000000..558a953
--- /dev/null
+++ b/includes/vendor/aura/sql/src/ConnectionLocatorInterface.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ *
+ * This file is part of Aura for PHP.
+ *
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ *
+ */
+namespace Aura\Sql;
+
+/**
+ *
+ * Locates PDO connections for default, read, and write databases.
+ *
+ * @package Aura.Sql
+ *
+ */
+interface ConnectionLocatorInterface
+{
+ /**
+ *
+ * Sets the default connection registry entry.
+ *
+ * @param callable $callable The registry entry.
+ *
+ * @return null
+ *
+ */
+ public function setDefault($callable);
+
+ /**
+ *
+ * Returns the default connection object.
+ *
+ * @return ExtendedPdoInterface
+ *
+ */
+ public function getDefault();
+
+ /**
+ *
+ * Sets a read connection registry entry by name.
+ *
+ * @param string $name The name of the registry entry.
+ *
+ * @param callable $callable The registry entry.
+ *
+ * @return null
+ *
+ */
+ public function setRead($name, $callable);
+
+ /**
+ *
+ * Returns a read connection by name; if no name is given, picks a
+ * random connection; if no read connections are present, returns the
+ * default connection.
+ *
+ * @param string $name The read connection name to return.
+ *
+ * @return ExtendedPdoInterface
+ *
+ */
+ public function getRead($name = null);
+
+ /**
+ *
+ * Sets a write connection registry entry by name.
+ *
+ * @param string $name The name of the registry entry.
+ *
+ * @param callable $callable The registry entry.
+ *
+ * @return null
+ *
+ */
+ public function setWrite($name, $callable);
+
+ /**
+ *
+ * Returns a write connection by name; if no name is given, picks a
+ * random connection; if no write connections are present, returns the
+ * default connection.
+ *
+ * @param string $name The write connection name to return.
+ *
+ * @return ExtendedPdoInterface
+ *
+ */
+ public function getWrite($name = null);
+}
diff --git a/includes/vendor/aura/sql/src/Exception.php b/includes/vendor/aura/sql/src/Exception.php
new file mode 100644
index 0000000..4430df2
--- /dev/null
+++ b/includes/vendor/aura/sql/src/Exception.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ *
+ * This file is part of Aura for PHP.
+ *
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ *
+ */
+namespace Aura\Sql;
+
+/**
+ *
+ * Base Exception class for Aura Sql
+ *
+ * @package Aura.Sql
+ *
+ */
+class Exception extends \Exception
+{
+}
diff --git a/includes/vendor/aura/sql/src/Exception/CannotBindValue.php b/includes/vendor/aura/sql/src/Exception/CannotBindValue.php
new file mode 100644
index 0000000..336ddd2
--- /dev/null
+++ b/includes/vendor/aura/sql/src/Exception/CannotBindValue.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ *
+ * This file is part of Aura for PHP.
+ *
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ *
+ */
+namespace Aura\Sql\Exception;
+
+use Aura\Sql\Exception;
+
+/**
+ *
+ * Could not bind a value to a placeholder in a statement, generally because
+ * the value is an array, object, or resource.
+ *
+ * @package Aura.Sql
+ *
+ */
+class CannotBindValue extends Exception
+{
+}
diff --git a/includes/vendor/aura/sql/src/Exception/CannotDisconnect.php b/includes/vendor/aura/sql/src/Exception/CannotDisconnect.php
new file mode 100644
index 0000000..3f1cf2d
--- /dev/null
+++ b/includes/vendor/aura/sql/src/Exception/CannotDisconnect.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ *
+ * This file is part of Aura for PHP.
+ *
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ *
+ */
+namespace Aura\Sql\Exception;
+
+use Aura\Sql\Exception;
+
+/**
+ *
+ * ExtendedPdo could not disconnect; e.g., because its PDO connection was
+ * created externally and then injected.
+ *
+ * @package Aura.Sql
+ *
+ */
+class CannotDisconnect extends Exception
+{
+}
diff --git a/includes/vendor/aura/sql/src/Exception/ConnectionNotFound.php b/includes/vendor/aura/sql/src/Exception/ConnectionNotFound.php
new file mode 100644
index 0000000..b6a15a4
--- /dev/null
+++ b/includes/vendor/aura/sql/src/Exception/ConnectionNotFound.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ *
+ * This file is part of Aura for PHP.
+ *
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ *
+ */
+namespace Aura\Sql\Exception;
+
+use Aura\Sql\Exception;
+
+/**
+ *
+ * Locator could not find a named connection.
+ *
+ * @package Aura.Sql
+ *
+ */
+class ConnectionNotFound extends Exception
+{
+}
diff --git a/includes/vendor/aura/sql/src/Exception/MissingParameter.php b/includes/vendor/aura/sql/src/Exception/MissingParameter.php
new file mode 100644
index 0000000..2a16c9a
--- /dev/null
+++ b/includes/vendor/aura/sql/src/Exception/MissingParameter.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ *
+ * This file is part of Aura for PHP.
+ *
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ *
+ */
+namespace Aura\Sql\Exception;
+
+use Aura\Sql\Exception;
+
+/**
+ *
+ * Missing a parameter in the values bound to a statement
+ *
+ * @package Aura.Sql
+ *
+ */
+class MissingParameter extends Exception
+{
+}
diff --git a/includes/vendor/aura/sql/src/ExtendedPdo.php b/includes/vendor/aura/sql/src/ExtendedPdo.php
new file mode 100644
index 0000000..d3668ac
--- /dev/null
+++ b/includes/vendor/aura/sql/src/ExtendedPdo.php
@@ -0,0 +1,1138 @@
+<?php
+/**
+ *
+ * This file is part of Aura for PHP.
+ *
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ *
+ */
+namespace Aura\Sql;
+
+use Aura\Sql\Exception;
+use PDO;
+use PDOStatement;
+
+/**
+ *
+ * This extended decorator for PDO provides lazy connection, array quoting, a
+ * new `perform()` method, and new `fetch*()` methods.
+ *
+ * @package Aura.Sql
+ *
+ */
+class ExtendedPdo extends PDO implements ExtendedPdoInterface
+{
+ /**
+ *
+ * The PDO connection itself.
+ *
+ * @var PDO
+ *
+ */
+ protected $pdo;
+
+ /**
+ *
+ * The attributes for a lazy connection.
+ *
+ * @var array
+ *
+ */
+ protected $attributes = array(
+ self::ATTR_ERRMODE => self::ERRMODE_EXCEPTION,
+ );
+
+ /**
+ *
+ * Was the PDO connection injected at construction time?
+ *
+ * @var PDO
+ *
+ */
+ protected $injected = false;
+
+ /**
+ *
+ * The DSN for a lazy connection.
+ *
+ * @var string
+ *
+ */
+ protected $dsn;
+
+ /**
+ *
+ * PDO options for a lazy connection.
+ *
+ * @var array
+ *
+ */
+ protected $options = array();
+
+ /**
+ *
+ * The password for a lazy connection.
+ *
+ * @var string
+ *
+ */
+ protected $password;
+
+ /**
+ *
+ * The current profile information.
+ *
+ * @var array
+ *
+ */
+ protected $profile = array();
+
+ /**
+ *
+ * A query profiler.
+ *
+ * @var ProfilerInterface
+ *
+ */
+ protected $profiler;
+
+ /**
+ *
+ * The username for a lazy connection.
+ *
+ * @var string
+ *
+ */
+ protected $username;
+
+ /**
+ *
+ * A specialized statement preparer.
+ *
+ * @var Rebuilder
+ *
+ */
+ protected $rebuilder;
+
+ /**
+ *
+ * This constructor is pseudo-polymorphic. You may pass a normal set of PDO
+ * constructor parameters, and ExtendedPdo will use them for a lazy
+ * connection. Alternatively, if the `$dsn` parameter is an existing PDO
+ * instance, that instance will be decorated by ExtendedPdo; the remaining
+ * parameters will be ignored.
+ *
+ * @param PDO|string $dsn The data source name for a lazy PDO connection,
+ * or an existing instance of PDO. If the latter, the remaining params are
+ * ignored.
+ *
+ * @param string $username The username for a lazy connection.
+ *
+ * @param string $password The password for a lazy connection.
+ *
+ * @param array $options Driver-specific options for a lazy connection.
+ *
+ * @param array $attributes Attributes to set after a lazy connection.
+ *
+ * @see http://php.net/manual/en/pdo.construct.php
+ *
+ */
+ public function __construct(
+ $dsn,
+ $username = null,
+ $password = null,
+ array $options = array(),
+ array $attributes = array()
+ ) {
+ if ($dsn instanceof PDO) {
+ $this->pdo = $dsn;
+ $this->injected = true;
+ } else {
+ $this->dsn = $dsn;
+ $this->username = $username;
+ $this->password = $password;
+ $this->options = $options;
+ $this->attributes = array_replace($this->attributes, $attributes);
+ }
+ }
+
+ /**
+ *
+ * Begins a transaction and turns off autocommit mode.
+ *
+ * @return bool True on success, false on failure.
+ *
+ * @see http://php.net/manual/en/pdo.begintransaction.php
+ *
+ */
+ public function beginTransaction()
+ {
+ $this->connect();
+ $this->beginProfile(__FUNCTION__);
+ $result = $this->pdo->beginTransaction();
+ $this->endProfile();
+ return $result;
+ }
+
+ /**
+ *
+ * Commits the existing transaction and restores autocommit mode.
+ *
+ * @return bool True on success, false on failure.
+ *
+ * @see http://php.net/manual/en/pdo.commit.php
+ *
+ */
+ public function commit()
+ {
+ $this->connect();
+ $this->beginProfile(__FUNCTION__);
+ $result = $this->pdo->commit();
+ $this->endProfile();
+ return $result;
+ }
+
+ /**
+ *
+ * Connects to the database and sets PDO attributes.
+ *
+ * @return null
+ *
+ * @throws \PDOException if the connection fails.
+ *
+ */
+ public function connect()
+ {
+ // don't connect twice
+ if ($this->pdo) {
+ return;
+ }
+
+ // connect to the database
+ $this->beginProfile(__FUNCTION__);
+ $this->pdo = new PDO(
+ $this->dsn,
+ $this->username,
+ $this->password,
+ $this->options
+ );
+ $this->endProfile();
+
+ // set attributes
+ foreach ($this->attributes as $attribute => $value) {
+ $this->setAttribute($attribute, $value);
+ }
+ }
+
+ /**
+ *
+ * Explicitly disconnect by unsetting the PDO instance; does not prevent
+ * later reconnection, whether implicit or explicit.
+ *
+ * @return null
+ *
+ * @throws Exception\CannotDisconnect when the PDO instance was injected
+ * for decoration; manage the lifecycle of that PDO instance elsewhere.
+ *
+ */
+ public function disconnect()
+ {
+ if ($this->injected) {
+ $message = "Cannot disconnect an injected PDO instance.";
+ throw new Exception\CannotDisconnect($message);
+ }
+ $this->pdo = null;
+ }
+
+ /**
+ *
+ * Gets the most recent error code.
+ *
+ * @return mixed
+ *
+ */
+ public function errorCode()
+ {
+ $this->connect();
+ return $this->pdo->errorCode();
+ }
+
+ /**
+ *
+ * Gets the most recent error info.
+ *
+ * @return array
+ *
+ */
+ public function errorInfo()
+ {
+ $this->connect();
+ return $this->pdo->errorInfo();
+ }
+
+ /**
+ *
+ * Executes an SQL statement and returns the number of affected rows.
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @return int The number of affected rows.
+ *
+ * @see http://php.net/manual/en/pdo.exec.php
+ *
+ */
+ public function exec($statement)
+ {
+ $this->connect();
+ $this->beginProfile(__FUNCTION__);
+ $affected_rows = $this->pdo->exec($statement);
+ $this->endProfile($statement);
+ return $affected_rows;
+ }
+
+ /**
+ *
+ * Performs a statement and returns the number of affected rows.
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @return int
+ *
+ */
+ public function fetchAffected($statement, array $values = array())
+ {
+ $sth = $this->perform($statement, $values);
+ return $sth->rowCount();
+ }
+
+ /**
+ *
+ * Fetches a sequential array of rows from the database; the rows
+ * are returned as associative arrays.
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @param callable $callable A callable to be applied to each of the rows
+ * to be returned.
+ *
+ * @return array
+ *
+ */
+ public function fetchAll(
+ $statement,
+ array $values = array(),
+ $callable = null
+ ) {
+ return $this->fetchAllWithCallable(
+ self::FETCH_ASSOC,
+ $statement,
+ $values,
+ $callable
+ );
+ }
+
+ /**
+ *
+ * Support for fetchAll() and fetchCol().
+ *
+ * @param string $fetch_type A PDO FETCH_* constant.
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @param callable $callable A callable to be applied to each of the rows
+ * to be returned.
+ *
+ * @return array
+ *
+ */
+ protected function fetchAllWithCallable(
+ $fetch_type,
+ $statement,
+ array $values = array(),
+ $callable = null
+ ) {
+ $sth = $this->perform($statement, $values);
+ if ($fetch_type == self::FETCH_COLUMN) {
+ $data = $sth->fetchAll($fetch_type, 0);
+ } else {
+ $data = $sth->fetchAll($fetch_type);
+ }
+ return $this->applyCallableToFetchAll($callable, $data);
+ }
+
+ /**
+ *
+ * Applies a callable to a data set.
+ *
+ * @param callable|null $callable The callable to apply, if any.
+ *
+ * @param array $data The data set.
+ *
+ * @return array
+ *
+ */
+ protected function applyCallableToFetchAll($callable, $data)
+ {
+ if ($callable) {
+ foreach ($data as $key => $row) {
+ $data[$key] = call_user_func($callable, $row);
+ }
+ }
+ return $data;
+ }
+
+ /**
+ *
+ * Fetches an associative array of rows from the database; the rows
+ * are returned as associative arrays, and the array of rows is keyed
+ * on the first column of each row.
+ *
+ * N.b.: If multiple rows have the same first column value, the last
+ * row with that value will override earlier rows.
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @param callable $callable A callable to be applied to each of the rows
+ * to be returned.
+ *
+ * @return array
+ *
+ */
+ public function fetchAssoc(
+ $statement,
+ array $values = array(),
+ $callable = null
+ ) {
+ $sth = $this->perform($statement, $values);
+
+ if (! $callable) {
+ $callable = function ($row) { return $row; };
+ }
+
+ $data = array();
+ while ($row = $sth->fetch(self::FETCH_ASSOC)) {
+ $key = current($row);
+ $data[$key] = call_user_func($callable, $row);
+ }
+
+ return $data;
+ }
+
+ /**
+ *
+ * Fetches the first column of rows as a sequential array.
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @param callable $callable A callable to be applied to each of the rows
+ * to be returned.
+ *
+ * @return array
+ *
+ */
+ public function fetchCol(
+ $statement,
+ array $values = array(),
+ $callable = null
+ ) {
+ return $this->fetchAllWithCallable(
+ self::FETCH_COLUMN,
+ $statement,
+ $values,
+ $callable
+ );
+ }
+
+ /**
+ *
+ * Fetches one row from the database as an object where the column values
+ * are mapped to object properties.
+ *
+ * Warning: PDO "injects property-values BEFORE invoking the constructor -
+ * in other words, if your class initializes property-values to defaults
+ * in the constructor, you will be overwriting the values injected by
+ * fetchObject() !"
+ * <http://www.php.net/manual/en/pdostatement.fetchobject.php#111744>
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @param string $class_name The name of the class to create.
+ *
+ * @param array $ctor_args Arguments to pass to the object constructor.
+ *
+ * @return object|false
+ *
+ */
+ public function fetchObject(
+ $statement,
+ array $values = array(),
+ $class_name = 'StdClass',
+ array $ctor_args = array()
+ ) {
+ $sth = $this->perform($statement, $values);
+
+ if ($ctor_args) {
+ return $sth->fetchObject($class_name, $ctor_args);
+ }
+
+ return $sth->fetchObject($class_name);
+ }
+
+ /**
+ *
+ * Fetches a sequential array of rows from the database; the rows
+ * are returned as objects where the column values are mapped to
+ * object properties.
+ *
+ * Warning: PDO "injects property-values BEFORE invoking the constructor -
+ * in other words, if your class initializes property-values to defaults
+ * in the constructor, you will be overwriting the values injected by
+ * fetchObject() !"
+ * <http://www.php.net/manual/en/pdostatement.fetchobject.php#111744>
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @param string $class_name The name of the class to create from each
+ * row.
+ *
+ * @param array $ctor_args Arguments to pass to each object constructor.
+ *
+ * @return array
+ *
+ */
+ public function fetchObjects(
+ $statement,
+ array $values = array(),
+ $class_name = 'StdClass',
+ array $ctor_args = array()
+ ) {
+ $sth = $this->perform($statement, $values);
+
+ if ($ctor_args) {
+ return $sth->fetchAll(self::FETCH_CLASS, $class_name, $ctor_args);
+ }
+
+ return $sth->fetchAll(self::FETCH_CLASS, $class_name);
+ }
+
+ /**
+ *
+ * Fetches one row from the database as an associative array.
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @return array|false
+ *
+ */
+ public function fetchOne($statement, array $values = array())
+ {
+ $sth = $this->perform($statement, $values);
+ return $sth->fetch(self::FETCH_ASSOC);
+ }
+
+ /**
+ *
+ * Fetches an associative array of rows as key-value pairs (first
+ * column is the key, second column is the value).
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @param callable $callable A callable to be applied to each of the rows
+ * to be returned.
+ *
+ * @return array
+ *
+ */
+ public function fetchPairs(
+ $statement,
+ array $values = array(),
+ $callable = null
+ ) {
+ $sth = $this->perform($statement, $values);
+ if ($callable) {
+ $data = array();
+ while ($row = $sth->fetch(self::FETCH_NUM)) {
+ // apply the callback first so the key can be modified
+ $row = call_user_func($callable, $row);
+ // now retain the data
+ $data[$row[0]] = $row[1];
+ }
+ } else {
+ $data = $sth->fetchAll(self::FETCH_KEY_PAIR);
+ }
+ return $data;
+ }
+
+ /**
+ *
+ * Fetches the very first value (i.e., first column of the first row).
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @return mixed
+ *
+ */
+ public function fetchValue($statement, array $values = array())
+ {
+ $sth = $this->perform($statement, $values);
+ return $sth->fetchColumn(0);
+ }
+
+ /**
+ *
+ * Fetches multiple from the database as an associative array.
+ * The first column will be the index
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @param int $style a fetch style defaults to PDO::FETCH_COLUMN for single
+ * values, use PDO::FETCH_NAMED when fetching a multiple columns
+ *
+ * @return array
+ *
+ */
+ public function fetchGroup(
+ $statement,
+ array $values = array(),
+ $style = self::FETCH_COLUMN
+ ) {
+ $sth = $this->perform($statement, $values);
+ return $sth->fetchAll(self::FETCH_GROUP | $style);
+ }
+
+ /**
+ *
+ * Gets a PDO attribute value.
+ *
+ * @param mixed $attribute The PDO::ATTR_* constant.
+ *
+ * @return mixed The value for the attribute.
+ *
+ */
+ public function getAttribute($attribute)
+ {
+ $this->connect();
+ return $this->pdo->getAttribute($attribute);
+ }
+
+ /**
+ *
+ * Returns the DSN for a lazy connection; if the underlying PDO instance
+ * was injected at construction time, this will be null.
+ *
+ * @return string|null
+ *
+ */
+ public function getDsn()
+ {
+ return $this->dsn;
+ }
+
+ /**
+ *
+ * Returns the underlying PDO connection object.
+ *
+ * @return PDO
+ *
+ */
+ public function getPdo()
+ {
+ $this->connect();
+ return $this->pdo;
+ }
+
+ /**
+ *
+ * Returns the profiler object.
+ *
+ * @return ProfilerInterface
+ *
+ */
+ public function getProfiler()
+ {
+ return $this->profiler;
+ }
+
+ /**
+ *
+ * Is a transaction currently active?
+ *
+ * @return bool
+ *
+ * @see http://php.net/manual/en/pdo.intransaction.php
+ *
+ */
+ public function inTransaction()
+ {
+ $this->connect();
+ $this->beginProfile(__FUNCTION__);
+ $result = $this->pdo->inTransaction();
+ $this->endProfile();
+ return $result;
+ }
+
+ /**
+ *
+ * Is this instance connected to a database?
+ *
+ * @return bool
+ *
+ */
+ public function isConnected()
+ {
+ return isset($this->pdo);
+ }
+
+ /**
+ *
+ * Returns the last inserted autoincrement sequence value.
+ *
+ * @param string $name The name of the sequence to check; typically needed
+ * only for PostgreSQL, where it takes the form of `<table>_<column>_seq`.
+ *
+ * @return int
+ *
+ * @see http://php.net/manual/en/pdo.lastinsertid.php
+ *
+ */
+ public function lastInsertId($name = null)
+ {
+ $this->connect();
+ $this->beginProfile(__FUNCTION__);
+ $result = $this->pdo->lastInsertId($name);
+ $this->endProfile();
+ return $result;
+ }
+
+ /**
+ *
+ * Performs a query with bound values and returns the resulting
+ * PDOStatement; array values will be passed through `quote()` and their
+ * respective placeholders will be replaced in the query string.
+ *
+ * @param string $statement The SQL statement to perform.
+ *
+ * @param array $values Values to bind to the query
+ *
+ * @return PDOStatement
+ *
+ * @see quote()
+ *
+ */
+ public function perform($statement, array $values = array())
+ {
+ $sth = $this->prepareWithValues($statement, $values);
+ $this->beginProfile(__FUNCTION__);
+ $sth->execute();
+ $this->endProfile($statement, $values);
+ return $sth;
+ }
+
+ /**
+ *
+ * Prepares an SQL statement for execution.
+ *
+ * @param string $statement The SQL statement to prepare for execution.
+ *
+ * @param array $options Set these attributes on the returned
+ * PDOStatement.
+ *
+ * @return PDOStatement
+ *
+ * @see http://php.net/manual/en/pdo.prepare.php
+ *
+ */
+ public function prepare($statement, $options = array())
+ {
+ $this->connect();
+ $this->beginProfile(__FUNCTION__);
+ $sth = $this->pdo->prepare($statement, $options);
+ $this->endProfile($statement, $options);
+ return $sth;
+ }
+
+ /**
+ *
+ * Queries the database and returns a PDOStatement.
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param int $fetch_mode The `PDO::FETCH_*` type to set on the returned
+ * `PDOStatement::setFetchMode()`.
+ *
+ * @param mixed $fetch_arg1 The first additional argument to send to
+ * `PDOStatement::setFetchMode()`.
+ *
+ * @param mixed $fetch_arg2 The second additional argument to send to
+ * `PDOStatement::setFetchMode()`.
+ *
+ * @return PDOStatement
+ *
+ * @see http://php.net/manual/en/pdo.query.php
+ *
+ */
+ public function query($statement)
+ {
+ $this->connect();
+ $this->beginProfile(__FUNCTION__);
+
+ // remove empty constructor params list if it exists
+ $args = func_get_args();
+ if (count($args) === 4 && $args[3] === array()) {
+ unset($args[3]);
+ }
+
+ $sth = call_user_func_array(array($this->pdo, 'query'), $args);
+
+ $this->endProfile($sth->queryString);
+ return $sth;
+ }
+
+ /**
+ *
+ * Quotes a value for use in an SQL statement.
+ *
+ * This differs from `PDO::quote()` in that it will convert an array into
+ * a string of comma-separated quoted values.
+ *
+ * @param mixed $value The value to quote.
+ *
+ * @param int $parameter_type A data type hint for the database driver.
+ *
+ * @return mixed The quoted value.
+ *
+ * @see http://php.net/manual/en/pdo.quote.php
+ *
+ */
+ public function quote($value, $parameter_type = self::PARAM_STR)
+ {
+ $this->connect();
+
+ // non-array quoting
+ if (! is_array($value)) {
+ return $this->pdo->quote($value, $parameter_type);
+ }
+
+ // quote array values, not keys, then combine with commas
+ foreach ($value as $k => $v) {
+ $value[$k] = $this->pdo->quote($v, $parameter_type);
+ }
+ return implode(', ', $value);
+ }
+
+ /**
+ *
+ * Rolls back the current transaction, and restores autocommit mode.
+ *
+ * @return bool True on success, false on failure.
+ *
+ * @see http://php.net/manual/en/pdo.rollback.php
+ *
+ */
+ public function rollBack()
+ {
+ $this->connect();
+ $this->beginProfile(__FUNCTION__);
+ $result = $this->pdo->rollBack();
+ $this->endProfile();
+
+ return $result;
+ }
+
+ /**
+ *
+ * Sets a PDO attribute value.
+ *
+ * @param mixed $attribute The PDO::ATTR_* constant.
+ *
+ * @param mixed $value The value for the attribute.
+ *
+ * @return bool True on success, false on failure. Note that if PDO has not
+ * not connected, all calls will be treated as successful.
+ *
+ */
+ public function setAttribute($attribute, $value)
+ {
+ if ($this->pdo) {
+ return $this->pdo->setAttribute($attribute, $value);
+ }
+
+ $this->attributes[$attribute] = $value;
+ return true;
+ }
+
+ /**
+ *
+ * Sets the profiler object.
+ *
+ * @param ProfilerInterface $profiler
+ *
+ * @return null
+ *
+ */
+ public function setProfiler(ProfilerInterface $profiler)
+ {
+ $this->profiler = $profiler;
+ }
+
+ /**
+ *
+ * Begins a profile entry.
+ *
+ * @param string $function The function starting the profile entry.
+ *
+ * @return null
+ *
+ */
+ protected function beginProfile($function)
+ {
+ // if there's no profiler, can't profile
+ if (! $this->profiler) {
+ return;
+ }
+
+ // retain starting profile info
+ $this->profile['time'] = microtime(true);
+ $this->profile['function'] = $function;
+ }
+
+ /**
+ *
+ * Ends and records a profile entry.
+ *
+ * @param string $statement The statement being profiled, if any.
+ *
+ * @param array $values The values bound to the statement, if any.
+ *
+ * @return null
+ *
+ */
+ protected function endProfile($statement = null, array $values = array())
+ {
+ // is there a profiler in place?
+ if ($this->profiler) {
+ // add an entry to the profiler
+ $this->profiler->addProfile(
+ microtime(true) - $this->profile['time'],
+ $this->profile['function'],
+ $statement,
+ $values
+ );
+ }
+
+ // clear the starting profile info
+ $this->profile = array();
+ }
+
+ /**
+ *
+ * Prepares an SQL statement with bound values.
+ *
+ * This method only binds values that have placeholders in the
+ * statement, thereby avoiding errors from PDO regarding too many bound
+ * values. It also binds all sequential (question-mark) placeholders.
+ *
+ * If a placeholder value is an array, the array is converted to a string
+ * of comma-separated quoted values; e.g., for an `IN (...)` condition.
+ * The quoted string is replaced directly into the statement instead of
+ * using `PDOStatement::bindValue()` proper.
+ *
+ * @param string $statement The SQL statement to prepare for execution.
+ *
+ * @param array $values The values to bind to the statement, if any.
+ *
+ * @return PDOStatement
+ *
+ * @see http://php.net/manual/en/pdo.prepare.php
+ *
+ */
+ public function prepareWithValues($statement, array $values = array())
+ {
+ // if there are no values to bind ...
+ if (! $values) {
+ // ... use the normal preparation
+ return $this->prepare($statement);
+ }
+
+ // rebuild the statement and values
+ $rebuilder = new Rebuilder($this);
+ list($statement, $values) = $rebuilder->__invoke($statement, $values);
+
+ // prepare the statement
+ $sth = $this->prepare($statement);
+
+ // for the placeholders we found, bind the corresponding data values
+ foreach ($values as $key => $val) {
+ $this->bindValue($sth, $key, $val);
+ }
+
+ // done
+ return $sth;
+ }
+
+ /**
+ *
+ * Yields rows from the database.
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @return Iterator\AllIterator
+ *
+ */
+ public function yieldAll($statement, array $values = array())
+ {
+ $sth = $this->perform($statement, $values);
+ return new Iterator\AllIterator($sth);
+ }
+
+ /**
+ *
+ * Yields rows from the database keyed on the first column of each row.
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @return Iterator\AssocIterator
+ *
+ */
+ public function yieldAssoc($statement, array $values = array())
+ {
+ $sth = $this->perform($statement, $values);
+ return new Iterator\AssocIterator($sth);
+ }
+
+ /**
+ *
+ * Yields the first column of each row.
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @return Iterator\ColIterator
+ *
+ */
+ public function yieldCol($statement, array $values = array())
+ {
+ $sth = $this->perform($statement, $values);
+ return new Iterator\ColIterator($sth);
+ }
+
+ /**
+ *
+ * Yields objects where the column values are mapped to object properties.
+ *
+ * Warning: PDO "injects property-values BEFORE invoking the constructor -
+ * in other words, if your class initializes property-values to defaults
+ * in the constructor, you will be overwriting the values injected by
+ * fetchObject() !"
+ * <http://www.php.net/manual/en/pdostatement.fetchobject.php#111744>
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @param string $class_name The name of the class to create from each
+ * row.
+ *
+ * @param array $ctor_args Arguments to pass to each object constructor.
+ *
+ * @return Iterator\ObjectsIterator
+ *
+ */
+ public function yieldObjects(
+ $statement,
+ array $values = array(),
+ $class_name = 'stdClass',
+ array $ctor_args = array()
+ ) {
+ $sth = $this->perform($statement, $values);
+ return new Iterator\ObjectsIterator($sth, $class_name, $ctor_args);
+ }
+
+ /**
+ *
+ * Yields key-value pairs (first column is the key, second column is the
+ * value).
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @return Iterator\PairsIterator
+ *
+ */
+ public function yieldPairs($statement, array $values = array())
+ {
+ $sth = $this->perform($statement, $values);
+ return new Iterator\PairsIterator($sth);
+ }
+
+ /**
+ *
+ * Bind a value using the proper PDO::PARAM_* type.
+ *
+ * @param PDOStatement $sth The statement to bind to.
+ *
+ * @param mixed $key The placeholder key.
+ *
+ * @param mixed $val The value to bind to the statement.
+ *
+ * @return null
+ *
+ * @throws Exception\CannotBindValue when the value to be bound is not
+ * bindable (e.g., array, object, or resource).
+ *
+ */
+ protected function bindValue(PDOStatement $sth, $key, $val)
+ {
+ if (is_int($val)) {
+ return $sth->bindValue($key, $val, self::PARAM_INT);
+ }
+
+ if (is_bool($val)) {
+ // bind booleans as string '1' or string '0'.
+ // cf. https://bugs.php.net/bug.php?id=49255
+ $val = $val ? '1' : '0';
+ return $sth->bindValue($key, $val, self::PARAM_BOOL);
+ }
+
+ if (is_null($val)) {
+ return $sth->bindValue($key, $val, self::PARAM_NULL);
+ }
+
+ if (! is_scalar($val)) {
+ $type = gettype($val);
+ throw new Exception\CannotBindValue(
+ "Cannot bind value of type '{$type}' to placeholder '{$key}'"
+ );
+ }
+
+ $sth->bindValue($key, $val);
+ }
+}
diff --git a/includes/vendor/aura/sql/src/ExtendedPdoInterface.php b/includes/vendor/aura/sql/src/ExtendedPdoInterface.php
new file mode 100644
index 0000000..77e49b1
--- /dev/null
+++ b/includes/vendor/aura/sql/src/ExtendedPdoInterface.php
@@ -0,0 +1,267 @@
+<?php
+/**
+ *
+ * This file is part of Aura for PHP.
+ *
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ *
+ */
+namespace Aura\Sql;
+
+/**
+ *
+ * An interface to the Aura.Sql extended PDO object.
+ *
+ * @package Aura.Sql
+ *
+ * @method Iterator\AllIterator yieldAll(string $statment, array $values = array()) Yields rows from the database keyed on the first column of each row.
+ * @method Iterator\AssocIterator yieldAssoc(string $statment, array $values = array()) Yields rows from the database keyed on the first column of each row.
+ * @method Iterator\ColIterator yieldCol(string $statment, array $values = array()) Yields the first column of each row.
+ * @method Iterator\ObjectsIterator yieldObjects(string $statment, array $values = array(), $class_name = 'stdClass', array $ctor_args = array()) Yields objects where the column values are mapped to object properties.
+ * @method Iterator\PairsIterator yieldPairs(string $statment, array $values = array()) Yields key-value pairs (first column is the key, second column is the value).
+ */
+interface ExtendedPdoInterface extends PdoInterface
+{
+ /**
+ *
+ * Connects to the database and sets PDO attributes.
+ *
+ * @return null
+ *
+ * @throws \PDOException if the connection fails.
+ *
+ */
+ public function connect();
+
+ /**
+ *
+ * Performs a statement and returns the number of affected rows.
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @return array
+ *
+ */
+ public function fetchAffected($statement, array $values = array());
+
+ /**
+ *
+ * Fetches a sequential array of rows from the database; the rows
+ * are represented as associative arrays.
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @param callable $callable A callable to be applied to each of the rows
+ * to be returned.
+ *
+ * @return array
+ *
+ */
+ public function fetchAll($statement, array $values = array(), $callable = null);
+
+ /**
+ *
+ * Fetches an associative array of rows from the database; the rows
+ * are represented as associative arrays. The array of rows is keyed
+ * on the first column of each row.
+ *
+ * N.b.: if multiple rows have the same first column value, the last
+ * row with that value will override earlier rows.
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @param callable $callable A callable to be applied to each of the rows
+ * to be returned.
+ *
+ * @return array
+ *
+ */
+ public function fetchAssoc($statement, array $values = array(), $callable = null);
+
+ /**
+ *
+ * Fetches the first column of rows as a sequential array.
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @param callable $callable A callable to be applied to each of the rows
+ * to be returned.
+ *
+ * @return array
+ *
+ */
+ public function fetchCol($statement, array $values = array(), $callable = null);
+
+ /**
+ *
+ * Fetches one row from the database as an object, mapping column values
+ * to object properties.
+ *
+ * Warning: PDO "injects property-values BEFORE invoking the constructor -
+ * in other words, if your class initializes property-values to defaults
+ * in the constructor, you will be overwriting the values injected by
+ * fetchObject() !"
+ * <http://www.php.net/manual/en/pdostatement.fetchobject.php#111744>
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @param string $class_name The name of the class to create.
+ *
+ * @param array $ctor_args Arguments to pass to the object constructor.
+ *
+ * @return object|false
+ *
+ */
+ public function fetchObject(
+ $statement,
+ array $values = array(),
+ $class_name = 'StdClass',
+ array $ctor_args = array()
+ );
+
+ /**
+ *
+ * Fetches a sequential array of rows from the database; the rows
+ * are represented as objects, where the column values are mapped to
+ * object properties.
+ *
+ * Warning: PDO "injects property-values BEFORE invoking the constructor -
+ * in other words, if your class initializes property-values to defaults
+ * in the constructor, you will be overwriting the values injected by
+ * fetchObject() !"
+ * <http://www.php.net/manual/en/pdostatement.fetchobject.php#111744>
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @param string $class_name The name of the class to create from each
+ * row.
+ *
+ * @param array $ctor_args Arguments to pass to each object constructor.
+ *
+ * @return array
+ *
+ */
+ public function fetchObjects(
+ $statement,
+ array $values = array(),
+ $class_name = 'StdClass',
+ array $ctor_args = array()
+ );
+
+ /**
+ *
+ * Fetches one row from the database as an associative array.
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @return array|false
+ *
+ */
+ public function fetchOne($statement, array $values = array());
+
+ /**
+ *
+ * Fetches an associative array of rows as key-value pairs (first
+ * column is the key, second column is the value).
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @param callable $callable A callable to be applied to each of the rows
+ * to be returned.
+ *
+ * @return array
+ *
+ */
+ public function fetchPairs($statement, array $values = array(), $callable = null);
+
+ /**
+ *
+ * Fetches the very first value (i.e., first column of the first row).
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @return mixed
+ *
+ */
+ public function fetchValue($statement, array $values = array());
+
+ /**
+ *
+ * Returns the DSN for a lazy connection; if the underlying PDO instance
+ * was injected at construction time, this will be null.
+ *
+ * @return string|null
+ *
+ */
+ public function getDsn();
+
+ /**
+ *
+ * Returns the underlying PDO connection object.
+ *
+ * @return PDO or Null if connection was manually disconnected
+ *
+ */
+ public function getPdo();
+
+ /**
+ *
+ * Returns the profiler object.
+ *
+ * @return ProfilerInterface
+ *
+ */
+ public function getProfiler();
+
+ /**
+ *
+ * Is the instance connected to a database?
+ *
+ * @return bool
+ *
+ */
+ public function isConnected();
+
+ /**
+ *
+ * Performs a query after preparing the statement with bound values, then
+ * returns the result as a PDOStatement.
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param array $values Values to bind to the query.
+ *
+ * @return \PDOStatement
+ *
+ */
+ public function perform($statement, array $values = array());
+
+ /**
+ *
+ * Sets the profiler object.
+ *
+ * @param ProfilerInterface $profiler
+ *
+ * @return null
+ *
+ */
+ public function setProfiler(ProfilerInterface $profiler);
+}
diff --git a/includes/vendor/aura/sql/src/Iterator/AbstractIterator.php b/includes/vendor/aura/sql/src/Iterator/AbstractIterator.php
new file mode 100644
index 0000000..895fd4e
--- /dev/null
+++ b/includes/vendor/aura/sql/src/Iterator/AbstractIterator.php
@@ -0,0 +1,114 @@
+<?php
+/**
+ *
+ * This file is part of Aura for PHP.
+ *
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ *
+ */
+namespace Aura\Sql\Iterator;
+
+use Iterator;
+use PDOStatement;
+
+/**
+ *
+ * A base class for iterators.
+ *
+ * @package Aura.Sql
+ *
+ */
+abstract class AbstractIterator implements Iterator
+{
+ /**
+ *
+ * PDO statement.
+ *
+ * @var PDOStatement
+ *
+ */
+ protected $statement;
+
+ /**
+ *
+ * Current row value.
+ *
+ * @var mixed
+ *
+ */
+ protected $row;
+
+ /**
+ *
+ * Current key.
+ *
+ * @var mixed
+ *
+ */
+ protected $key = -1;
+
+ /**
+ *
+ * Frees memory when object is destroyed.
+ *
+ */
+ public function __destruct()
+ {
+ $this->statement->closeCursor();
+ unset($this->statement);
+ }
+
+ /**
+ *
+ * Moves row set pointer to first element.
+ *
+ */
+ public function rewind()
+ {
+ $this->key = -1;
+ $this->next();
+ }
+
+ /**
+ *
+ * Returns value at current position.
+ *
+ * @return mixed
+ *
+ */
+ public function current()
+ {
+ return $this->row;
+ }
+
+ /**
+ *
+ * Returns key at current position.
+ *
+ * @return mixed
+ *
+ */
+ public function key()
+ {
+ return $this->key;
+ }
+
+ /**
+ *
+ * Fetches next row from statement.
+ *
+ */
+ abstract public function next();
+
+ /**
+ *
+ * Detects if iterator state is valid.
+ *
+ * @return bool
+ *
+ */
+ public function valid()
+ {
+ return $this->row !== false;
+ }
+}
diff --git a/includes/vendor/aura/sql/src/Iterator/AllIterator.php b/includes/vendor/aura/sql/src/Iterator/AllIterator.php
new file mode 100644
index 0000000..9d56a24
--- /dev/null
+++ b/includes/vendor/aura/sql/src/Iterator/AllIterator.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * This file is part of Aura for PHP.
+ *
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ *
+ */
+namespace Aura\Sql\Iterator;
+
+use PDO;
+use PDOStatement;
+
+/**
+ *
+ * The iterator equivalent of `fetchAll()`.
+ *
+ * @package Aura.Sql
+ *
+ */
+class AllIterator extends AbstractIterator
+{
+ /**
+ *
+ * Constructor.
+ *
+ * @param PDOStatement $statement PDO statement.
+ *
+ */
+ public function __construct(PDOStatement $statement)
+ {
+ $this->statement = $statement;
+ $this->statement->setFetchMode(PDO::FETCH_ASSOC);
+ }
+
+ /**
+ *
+ * Fetches next row from statement.
+ *
+ */
+ public function next()
+ {
+ $this->row = $this->statement->fetch();
+ $this->key ++;
+ }
+}
diff --git a/includes/vendor/aura/sql/src/Iterator/AssocIterator.php b/includes/vendor/aura/sql/src/Iterator/AssocIterator.php
new file mode 100644
index 0000000..ea77a7a
--- /dev/null
+++ b/includes/vendor/aura/sql/src/Iterator/AssocIterator.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * This file is part of Aura for PHP.
+ *
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ *
+ */
+namespace Aura\Sql\Iterator;
+
+use PDO;
+use PDOStatement;
+
+/**
+ *
+ * The iterator equivalent of `fetchAssoc()`.
+ *
+ * @package Aura.Sql
+ *
+ */
+class AssocIterator extends AbstractIterator
+{
+ /**
+ *
+ * Constructor.
+ *
+ * @param PDOStatement $statement PDO statement.
+ *
+ */
+ public function __construct(PDOStatement $statement)
+ {
+ $this->statement = $statement;
+ $this->statement->setFetchMode(PDO::FETCH_ASSOC);
+ }
+
+ /**
+ *
+ * Fetches next row from statement.
+ *
+ */
+ public function next()
+ {
+ $this->row = $this->statement->fetch();
+ $this->key = false;
+ if ($this->row !== false) {
+ $this->key = current($this->row);
+ }
+ }
+}
diff --git a/includes/vendor/aura/sql/src/Iterator/ColIterator.php b/includes/vendor/aura/sql/src/Iterator/ColIterator.php
new file mode 100644
index 0000000..7be66e8
--- /dev/null
+++ b/includes/vendor/aura/sql/src/Iterator/ColIterator.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * This file is part of Aura for PHP.
+ *
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ *
+ */
+namespace Aura\Sql\Iterator;
+
+use PDO;
+use PDOStatement;
+
+/**
+ *
+ * The iterator equivalent of `fetchCol()`.
+ *
+ * @package Aura.Sql
+ *
+ */
+class ColIterator extends AbstractIterator
+{
+ /**
+ *
+ * Constructor.
+ *
+ * @param PDOStatement $statement PDO statement.
+ *
+ */
+ public function __construct(PDOStatement $statement)
+ {
+ $this->statement = $statement;
+ $this->statement->setFetchMode(PDO::FETCH_NUM);
+ }
+
+ /**
+ *
+ * Fetches next row from statement.
+ *
+ */
+ public function next()
+ {
+ $this->row = $this->statement->fetch();
+ if ($this->row !== false) {
+ $this->row = $this->row[0];
+ }
+ $this->key ++;
+ }
+}
diff --git a/includes/vendor/aura/sql/src/Iterator/ObjectsIterator.php b/includes/vendor/aura/sql/src/Iterator/ObjectsIterator.php
new file mode 100644
index 0000000..bbd08fc
--- /dev/null
+++ b/includes/vendor/aura/sql/src/Iterator/ObjectsIterator.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ *
+ * This file is part of Aura for PHP.
+ *
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ *
+ */
+namespace Aura\Sql\Iterator;
+
+use PDO;
+use PDOStatement;
+
+/**
+ *
+ * The iterator equivalent of `fetchObjects()`.
+ *
+ * @package Aura.Sql
+ *
+ */
+class ObjectsIterator extends AbstractIterator
+{
+ /**
+ *
+ * Constructor.
+ *
+ * @param PDOStatement $statement PDO statement.
+ *
+ * @param string $class_name The name of the class to create.
+ *
+ * @param array $ctor_args Arguments to pass to the object constructor.
+ *
+ */
+ public function __construct(
+ PDOStatement $statement,
+ $class_name = 'StdClass',
+ array $ctor_args = array()
+ ) {
+ $this->statement = $statement;
+ $this->statement->setFetchMode(PDO::FETCH_CLASS, $class_name);
+ if ($ctor_args) {
+ $this->statement->setFetchMode(
+ PDO::FETCH_CLASS,
+ $class_name,
+ $ctor_args
+ );
+ }
+ }
+
+ /**
+ *
+ * Fetches next row from statement.
+ *
+ */
+ public function next()
+ {
+ $this->row = $this->statement->fetch();
+ $this->key ++;
+ }
+}
diff --git a/includes/vendor/aura/sql/src/Iterator/PairsIterator.php b/includes/vendor/aura/sql/src/Iterator/PairsIterator.php
new file mode 100644
index 0000000..20c1a13
--- /dev/null
+++ b/includes/vendor/aura/sql/src/Iterator/PairsIterator.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * This file is part of Aura for PHP.
+ *
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ *
+ */
+namespace Aura\Sql\Iterator;
+
+use PDO;
+use PDOStatement;
+
+/**
+ *
+ * The iterator equivalent of `fetchPairs()`.
+ *
+ * @package Aura.Sql
+ *
+ */
+class PairsIterator extends AbstractIterator
+{
+ /**
+ *
+ * Constructor.
+ *
+ * @param PDOStatement $statement PDO statement.
+ *
+ */
+ public function __construct(PDOStatement $statement)
+ {
+ $this->statement = $statement;
+ $this->statement->setFetchMode(PDO::FETCH_NUM);
+ }
+
+ /**
+ *
+ * Fetches next row from statement.
+ *
+ */
+ public function next()
+ {
+ $this->key = false;
+ $this->row = $this->statement->fetch();
+ if ($this->row !== false) {
+ $this->key = $this->row[0];
+ $this->row = $this->row[1];
+ }
+ }
+}
diff --git a/includes/vendor/aura/sql/src/PdoInterface.php b/includes/vendor/aura/sql/src/PdoInterface.php
new file mode 100644
index 0000000..5987ee4
--- /dev/null
+++ b/includes/vendor/aura/sql/src/PdoInterface.php
@@ -0,0 +1,196 @@
+<?php
+/**
+ *
+ * This file is part of Aura for PHP.
+ *
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ *
+ */
+namespace Aura\Sql;
+
+use PDO;
+
+/**
+ *
+ * An interface to the native PDO object.
+ *
+ * @package Aura.Sql
+ *
+ */
+interface PdoInterface
+{
+ /**
+ *
+ * Begins a transaction and turns off autocommit mode.
+ *
+ * @return bool True on success, false on failure.
+ *
+ * @see http://php.net/manual/en/pdo.begintransaction.php
+ *
+ */
+ public function beginTransaction();
+
+ /**
+ *
+ * Commits the existing transaction and restores autocommit mode.
+ *
+ * @return bool True on success, false on failure.
+ *
+ * @see http://php.net/manual/en/pdo.commit.php
+ *
+ */
+ public function commit();
+
+ /**
+ *
+ * Gets the most recent error code.
+ *
+ * @return mixed
+ *
+ */
+ public function errorCode();
+
+ /**
+ *
+ * Gets the most recent error info.
+ *
+ * @return array
+ *
+ */
+ public function errorInfo();
+
+ /**
+ *
+ * Executes an SQL statement and returns the number of affected rows.
+ *
+ * @param string $statement The SQL statement to execute.
+ *
+ * @return int The number of rows affected.
+ *
+ * @see http://php.net/manual/en/pdo.exec.php
+ *
+ */
+ public function exec($statement);
+
+ /**
+ *
+ * Gets a PDO attribute value.
+ *
+ * @param mixed $attribute The PDO::ATTR_* constant.
+ *
+ * @return mixed The value for the attribute.
+ *
+ */
+ public function getAttribute($attribute);
+
+ /**
+ *
+ * Is a transaction currently active?
+ *
+ * @return bool
+ *
+ * @see http://php.net/manual/en/pdo.intransaction.php
+ *
+ */
+ public function inTransaction();
+
+ /**
+ *
+ * Returns the last inserted autoincrement sequence value.
+ *
+ * @param string $name The name of the sequence to check; typically needed
+ * only for PostgreSQL, where it takes the form of `<table>_<column>_seq`.
+ *
+ * @return int
+ *
+ * @see http://php.net/manual/en/pdo.lastinsertid.php
+ *
+ */
+ public function lastInsertId($name = null);
+
+ /**
+ *
+ * Prepares an SQL statement for execution.
+ *
+ * @param string $statement The SQL statement to prepare for execution.
+ *
+ * @param array $options Set these attributes on the returned
+ * PDOStatement.
+ *
+ * @return \PDOStatement
+ *
+ * @see http://php.net/manual/en/pdo.prepare.php
+ *
+ */
+ public function prepare($statement, $options = null);
+
+ /**
+ *
+ * Queries the database and returns a PDOStatement.
+ *
+ * @param string $statement The SQL statement to prepare and execute.
+ *
+ * @param int $fetch_mode The `PDO::FETCH_*` type to set on the returned
+ * `PDOStatement::setFetchMode()`.
+ *
+ * @param mixed $fetch_arg1 The first additional argument to send to
+ * `PDOStatement::setFetchMode()`.
+ *
+ * @param mixed $fetch_arg2 The second additional argument to send to
+ * `PDOStatement::setFetchMode()`.
+ *
+ * @return \PDOStatement
+ *
+ * @see http://php.net/manual/en/pdo.query.php
+ *
+ */
+ public function query($statement);
+
+ /**
+ *
+ * Quotes a value for use in an SQL statement.
+ *
+ * @param mixed $value The value to quote.
+ *
+ * @param int $parameter_type A data type hint for the database driver.
+ *
+ * @return mixed The quoted value.
+ *
+ * @see http://php.net/manual/en/pdo.quote.php
+ *
+ */
+ public function quote($value, $parameter_type = PDO::PARAM_STR);
+
+ /**
+ *
+ * Rolls back the current transaction and restores autocommit mode.
+ *
+ * @return bool True on success, false on failure.
+ *
+ * @see http://php.net/manual/en/pdo.rollback.php
+ *
+ */
+ public function rollBack();
+
+ /**
+ *
+ * Sets a PDO attribute value.
+ *
+ * @param mixed $attribute The PDO::ATTR_* constant.
+ *
+ * @param mixed $value The value for the attribute.
+ *
+ * @return bool
+ *
+ */
+ public function setAttribute($attribute, $value);
+
+ /**
+ *
+ * Returns all currently available PDO drivers.
+ *
+ * @return array
+ *
+ */
+ public static function getAvailableDrivers();
+}
diff --git a/includes/vendor/aura/sql/src/Profiler.php b/includes/vendor/aura/sql/src/Profiler.php
new file mode 100644
index 0000000..93a1c9e
--- /dev/null
+++ b/includes/vendor/aura/sql/src/Profiler.php
@@ -0,0 +1,129 @@
+<?php
+/**
+ *
+ * This file is part of Aura for PHP.
+ *
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ *
+ */
+namespace Aura\Sql;
+
+/**
+ *
+ * Retains query profiles.
+ *
+ * @package Aura.Sql
+ *
+ */
+class Profiler implements ProfilerInterface
+{
+ /**
+ *
+ * Is the profiler active?
+ *
+ * @var bool
+ *
+ */
+ protected $active = false;
+
+ /**
+ *
+ * Retained profiles.
+ *
+ * @var array
+ *
+ */
+ protected $profiles = array();
+
+ protected static $count = 0;
+
+ /**
+ *
+ * Turns the profiler on and off.
+ *
+ * @param bool $active True to turn on, false to turn off.
+ *
+ * @return null
+ *
+ */
+ public function setActive($active)
+ {
+ $this->active = (bool) $active;
+ }
+
+ /**
+ *
+ * Is the profiler active?
+ *
+ * @return bool
+ *
+ */
+ public function isActive()
+ {
+ return (bool) $this->active;
+ }
+
+ /**
+ *
+ * Adds a profile entry.
+ *
+ * @param float $duration The query duration.
+ *
+ * @param string $function The PDO method that made the entry.
+ *
+ * @param string $statement The SQL query statement.
+ *
+ * @param array $bind_values The values bound to the statement.
+ *
+ * @return null
+ *
+ */
+ public function addProfile(
+ $duration,
+ $function,
+ $statement,
+ array $bind_values = array()
+ ) {
+ if (! $this->isActive()) {
+ return;
+ }
+
+ $e = new \Exception;
+
+ // this allows for multiple profilers getting inter-sorted later
+ $k = self::$count ++;
+
+ $this->profiles[$k] = array(
+ 'duration' => $duration,
+ 'function' => $function,
+ 'statement' => $statement,
+ 'bind_values' => $bind_values,
+ 'trace' => $e->getTraceAsString(),
+ );
+ }
+
+ /**
+ *
+ * Returns all the profile entries.
+ *
+ * @return array
+ *
+ */
+ public function getProfiles()
+ {
+ return $this->profiles;
+ }
+
+ /**
+ *
+ * Reset all the profiles
+ *
+ * @return null
+ *
+ */
+ public function resetProfiles()
+ {
+ $this->profiles = array();
+ self::$count = 0;
+ }
+}
diff --git a/includes/vendor/aura/sql/src/ProfilerInterface.php b/includes/vendor/aura/sql/src/ProfilerInterface.php
new file mode 100644
index 0000000..f3ae0d8
--- /dev/null
+++ b/includes/vendor/aura/sql/src/ProfilerInterface.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ *
+ * This file is part of Aura for PHP.
+ *
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ *
+ */
+namespace Aura\Sql;
+
+/**
+ *
+ * Interface for query profilers.
+ *
+ * @package Aura.Sql
+ *
+ */
+interface ProfilerInterface
+{
+ /**
+ *
+ * Turns the profiler on and off.
+ *
+ * @param bool $active True to turn on, false to turn off.
+ *
+ * @return null
+ *
+ */
+ public function setActive($active);
+
+ /**
+ *
+ * Is the profiler active?
+ *
+ * @return bool
+ *
+ */
+ public function isActive();
+
+ /**
+ *
+ * Adds a profile entry.
+ *
+ * @param float $duration The query duration.
+ *
+ * @param string $function The PDO method that made the entry.
+ *
+ * @param string $statement The SQL query statement.
+ *
+ * @param array $bind_values The values bound to the statement.
+ *
+ * @return null
+ *
+ */
+ public function addProfile(
+ $duration,
+ $function,
+ $statement,
+ array $bind_values
+ );
+
+ /**
+ *
+ * Returns all the profiles.
+ *
+ * @return array
+ *
+ */
+ public function getProfiles();
+
+
+ /**
+ *
+ * Reset all the profiles
+ *
+ * @return null
+ *
+ */
+ public function resetProfiles();
+}
diff --git a/includes/vendor/aura/sql/src/Rebuilder.php b/includes/vendor/aura/sql/src/Rebuilder.php
new file mode 100644
index 0000000..997beff
--- /dev/null
+++ b/includes/vendor/aura/sql/src/Rebuilder.php
@@ -0,0 +1,280 @@
+<?php
+/**
+ *
+ * This file is part of Aura for PHP.
+ *
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ *
+ */
+namespace Aura\Sql;
+
+use Aura\Sql\Exception\MissingParameter;
+
+/**
+ *
+ * This support class for ExtendedPdo rebuilds an SQL statement for automatic
+ * binding of values.
+ *
+ * @package Aura.Sql
+ *
+ */
+class Rebuilder
+{
+ /**
+ *
+ * The calling ExtendedPdo object.
+ *
+ * @var ExtendedPdo
+ *
+ */
+ protected $xpdo;
+
+ /**
+ *
+ * How many numbered placeholders in the original statement.
+ *
+ * @var int
+ *
+ */
+ protected $num = 0;
+
+ /**
+ *
+ * How many numbered placeholders to actually be bound; this may
+ * differ from 'num' in that some numbered placeholders may get
+ * replaced with quoted CSV strings
+ *
+ * @var int
+ *
+ */
+ protected $count = 0;
+
+ /**
+ *
+ * The initial values to be bound.
+ *
+ * @var array
+ *
+ */
+ protected $values = array();
+
+ /**
+ *
+ * Named and numbered placeholders to bind at the end.
+ *
+ * @var array
+ *
+ */
+ protected $final_values = array();
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param ExtendedPdo $xpdo The calling ExtendedPdo object.
+ *
+ */
+ public function __construct(ExtendedPdo $xpdo)
+ {
+ $this->xpdo = $xpdo;
+ }
+
+ /**
+ *
+ * Rebuilds a statement with array values replaced into placeholders.
+ *
+ * @param string $statement The statement to rebuild.
+ *
+ * @param array $values The values to bind and/or replace into a statement.
+ *
+ * @return array An array where element 0 is the rebuilt statement and
+ * element 1 is the rebuilt array of values.
+ *
+ */
+ public function __invoke($statement, $values)
+ {
+ // match standard PDO execute() behavior of zero-indexed arrays
+ if (array_key_exists(0, $values)) {
+ array_unshift($values, null);
+ }
+
+ $this->values = $values;
+ $statement = $this->rebuildStatement($statement);
+ return array($statement, $this->final_values);
+ }
+
+ /**
+ *
+ * Given a statement, rebuilds it with array values embedded.
+ *
+ * @param string $statement The SQL statement.
+ *
+ * @return string The rebuilt statement.
+ *
+ */
+ protected function rebuildStatement($statement)
+ {
+ // find all parts not inside quotes or backslashed-quotes
+ $apos = "'";
+ $quot = '"';
+ $parts = preg_split(
+ "/(($apos+|$quot+|\\$apos+|\\$quot+).*?)\\2/m",
+ $statement,
+ -1,
+ PREG_SPLIT_DELIM_CAPTURE
+ );
+ return $this->rebuildParts($parts);
+ }
+
+ /**
+ *
+ * Given an array of statement parts, rebuilds each part.
+ *
+ * @param array $parts The statement parts.
+ *
+ * @return string The rebuilt statement.
+ *
+ */
+ protected function rebuildParts($parts)
+ {
+ // loop through the non-quoted parts (0, 3, 6, 9, etc.)
+ $k = count($parts);
+ for ($i = 0; $i <= $k; $i += 3) {
+ $parts[$i] = $this->rebuildPart($parts[$i]);
+ }
+ return implode('', $parts);
+ }
+
+ /**
+ *
+ * Rebuilds a single statement part.
+ *
+ * @param string $part The statement part.
+ *
+ * @return string The rebuilt statement.
+ *
+ */
+ protected function rebuildPart($part)
+ {
+ // split into subparts by ":name" and "?"
+ $subs = preg_split(
+ "/(:[a-zA-Z_][a-zA-Z0-9_]*)|(\?)/m",
+ $part,
+ -1,
+ PREG_SPLIT_DELIM_CAPTURE
+ );
+
+ // check subparts to convert bound arrays to quoted CSV strings
+ $subs = $this->prepareValuePlaceholders($subs);
+
+ // reassemble
+ return implode('', $subs);
+ }
+
+ /**
+ *
+ * Prepares the sub-parts of a query with placeholders.
+ *
+ * @param array $subs The query subparts.
+ *
+ * @return array The prepared subparts.
+ *
+ */
+ protected function prepareValuePlaceholders(array $subs)
+ {
+ foreach ($subs as $i => $sub) {
+
+ // is the subpart a ?-mark?
+ if ($sub == '?') {
+ // prepare as numbered placeholder
+ $subs[$i] = $this->prepareNumberedPlaceholder($sub);
+ }
+
+ // is the subpart only a colon?
+ if ($sub == ':') {
+ // ignore it
+ continue;
+ }
+
+ // does the subpart begin with a colon?
+ $char = substr($sub, 0, 1);
+ if ($char != ':') {
+ // no, so cannot be named placeholder
+ continue;
+ }
+
+ // does previous subpart (if there is one) end in a colon?
+ if ($i > 0 && substr($subs[$i - 1], -1) == ':') {
+ // prev ended in ':', and current begins with ':', making it a
+ // double-colon, so ignore it
+ continue;
+ }
+
+ // begins with colon, previous did not end with colon, so prepare
+ // as a named placeholder
+ $subs[$i] = $this->prepareNamedPlaceholder($sub);
+ }
+
+ return $subs;
+ }
+
+ /**
+ *
+ * Bind or quote a numbered placeholder in a query subpart.
+ *
+ * @param string $sub The query subpart.
+ *
+ * @return string The prepared query subpart.
+ *
+ * @throws MissingParameter
+ */
+ protected function prepareNumberedPlaceholder($sub)
+ {
+ // what numbered placeholder is this in the original statement?
+ $this->num ++;
+
+ // is the corresponding data element an array?
+ $bind_array = isset($this->values[$this->num])
+ && is_array($this->values[$this->num]);
+ if ($bind_array) {
+ // PDO won't bind an array; quote and replace directly
+ $sub = $this->xpdo->quote($this->values[$this->num]);
+ } else {
+ // increase the count of numbered placeholders to be bound
+ $this->count ++;
+ if (array_key_exists($this->num, $this->values) === false) {
+ throw new MissingParameter('Parameter ' . $this->num . ' is missing from the bound values');
+ }
+ $this->final_values[$this->count] = $this->values[$this->num];
+ }
+
+ return $sub;
+ }
+
+ /**
+ *
+ * Bind or quote a named placeholder in a query subpart.
+ *
+ * @param string $sub The query subpart.
+ *
+ * @return string The prepared query subpart.
+ *
+ */
+ protected function prepareNamedPlaceholder($sub)
+ {
+ $name = substr($sub, 1);
+
+ // is the corresponding data element an array?
+ $bind_array = isset($this->values[$name])
+ && is_array($this->values[$name]);
+ if ($bind_array) {
+ // PDO won't bind an array; quote and replace directly
+ $sub = $this->xpdo->quote($this->values[$name]);
+ } else {
+ // not an array, retain the placeholder for later
+ $this->final_values[$name] = $this->values[$name];
+ }
+
+ return $sub;
+ }
+} \ No newline at end of file