add composer autoloader and libs
This commit is contained in:
parent
d9211d2c40
commit
e63be19fe5
7
bundled-libs/autoload.php
Normal file
7
bundled-libs/autoload.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
// autoload.php generated by Composer
|
||||
|
||||
require_once __DIR__ . '/composer' . '/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInit3146f05565d9c8136a7e59e2a511ce14::getLoader();
|
246
bundled-libs/composer/ClassLoader.php
Normal file
246
bundled-libs/composer/ClassLoader.php
Normal file
@ -0,0 +1,246 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
/**
|
||||
* ClassLoader implements a PSR-0 class loader
|
||||
*
|
||||
* See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
|
||||
*
|
||||
* $loader = new \Composer\Autoload\ClassLoader();
|
||||
*
|
||||
* // register classes with namespaces
|
||||
* $loader->add('Symfony\Component', __DIR__.'/component');
|
||||
* $loader->add('Symfony', __DIR__.'/framework');
|
||||
*
|
||||
* // activate the autoloader
|
||||
* $loader->register();
|
||||
*
|
||||
* // to enable searching the include path (eg. for PEAR packages)
|
||||
* $loader->setUseIncludePath(true);
|
||||
*
|
||||
* In this example, if you try to use a class in the Symfony\Component
|
||||
* namespace or one of its children (Symfony\Component\Console for instance),
|
||||
* the autoloader will first look for the class under the component/
|
||||
* directory, and it will then fallback to the framework/ directory if not
|
||||
* found before giving up.
|
||||
*
|
||||
* This class is loosely based on the Symfony UniversalClassLoader.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
private $prefixes = array();
|
||||
private $fallbackDirs = array();
|
||||
private $useIncludePath = false;
|
||||
private $classMap = array();
|
||||
|
||||
public function getPrefixes()
|
||||
{
|
||||
return call_user_func_array('array_merge', $this->prefixes);
|
||||
}
|
||||
|
||||
public function getFallbackDirs()
|
||||
{
|
||||
return $this->fallbackDirs;
|
||||
}
|
||||
|
||||
public function getClassMap()
|
||||
{
|
||||
return $this->classMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $classMap Class to filename map
|
||||
*/
|
||||
public function addClassMap(array $classMap)
|
||||
{
|
||||
if ($this->classMap) {
|
||||
$this->classMap = array_merge($this->classMap, $classMap);
|
||||
} else {
|
||||
$this->classMap = $classMap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of classes, merging with any others previously set.
|
||||
*
|
||||
* @param string $prefix The classes prefix
|
||||
* @param array|string $paths The location(s) of the classes
|
||||
* @param bool $prepend Prepend the location(s)
|
||||
*/
|
||||
public function add($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
if ($prepend) {
|
||||
$this->fallbackDirs = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirs
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirs = array_merge(
|
||||
$this->fallbackDirs,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$first = $prefix[0];
|
||||
if (!isset($this->prefixes[$first][$prefix])) {
|
||||
$this->prefixes[$first][$prefix] = (array) $paths;
|
||||
|
||||
return;
|
||||
}
|
||||
if ($prepend) {
|
||||
$this->prefixes[$first][$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixes[$first][$prefix]
|
||||
);
|
||||
} else {
|
||||
$this->prefixes[$first][$prefix] = array_merge(
|
||||
$this->prefixes[$first][$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of classes, replacing any others previously set.
|
||||
*
|
||||
* @param string $prefix The classes prefix
|
||||
* @param array|string $paths The location(s) of the classes
|
||||
*/
|
||||
public function set($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirs = (array) $paths;
|
||||
|
||||
return;
|
||||
}
|
||||
$this->prefixes[substr($prefix, 0, 1)][$prefix] = (array) $paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on searching the include path for class files.
|
||||
*
|
||||
* @param bool $useIncludePath
|
||||
*/
|
||||
public function setUseIncludePath($useIncludePath)
|
||||
{
|
||||
$this->useIncludePath = $useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to check if the autoloader uses the include path to check
|
||||
* for classes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getUseIncludePath()
|
||||
{
|
||||
return $this->useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this instance as an autoloader.
|
||||
*
|
||||
* @param bool $prepend Whether to prepend the autoloader or not
|
||||
*/
|
||||
public function register($prepend = false)
|
||||
{
|
||||
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters this instance as an autoloader.
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
spl_autoload_unregister(array($this, 'loadClass'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given class or interface.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
* @return bool|null True if loaded, null otherwise
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
include $file;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the path to the file where the class is defined.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
*
|
||||
* @return string|false The path if found, false otherwise
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
// work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
|
||||
if ('\\' == $class[0]) {
|
||||
$class = substr($class, 1);
|
||||
}
|
||||
|
||||
if (isset($this->classMap[$class])) {
|
||||
return $this->classMap[$class];
|
||||
}
|
||||
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
// namespaced class name
|
||||
$classPath = strtr(substr($class, 0, $pos), '\\', DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
|
||||
$className = substr($class, $pos + 1);
|
||||
} else {
|
||||
// PEAR-like class name
|
||||
$classPath = null;
|
||||
$className = $class;
|
||||
}
|
||||
|
||||
$classPath .= strtr($className, '_', DIRECTORY_SEPARATOR) . '.php';
|
||||
|
||||
$first = $class[0];
|
||||
if (isset($this->prefixes[$first])) {
|
||||
foreach ($this->prefixes[$first] as $prefix => $dirs) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($dirs as $dir) {
|
||||
if (file_exists($dir . DIRECTORY_SEPARATOR . $classPath)) {
|
||||
return $dir . DIRECTORY_SEPARATOR . $classPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->fallbackDirs as $dir) {
|
||||
if (file_exists($dir . DIRECTORY_SEPARATOR . $classPath)) {
|
||||
return $dir . DIRECTORY_SEPARATOR . $classPath;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->useIncludePath && $file = stream_resolve_include_path($classPath)) {
|
||||
return $file;
|
||||
}
|
||||
|
||||
return $this->classMap[$class] = false;
|
||||
}
|
||||
}
|
9
bundled-libs/composer/autoload_classmap.php
Normal file
9
bundled-libs/composer/autoload_classmap.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
// autoload_classmap.php generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
);
|
10
bundled-libs/composer/autoload_namespaces.php
Normal file
10
bundled-libs/composer/autoload_namespaces.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
// autoload_namespaces.php generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Zend\\Db\\' => array($vendorDir . '/zendframework/zend-db'),
|
||||
);
|
43
bundled-libs/composer/autoload_real.php
Normal file
43
bundled-libs/composer/autoload_real.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
// autoload_real.php generated by Composer
|
||||
|
||||
class ComposerAutoloaderInit3146f05565d9c8136a7e59e2a511ce14
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
public static function loadClassLoader($class)
|
||||
{
|
||||
if ('Composer\Autoload\ClassLoader' === $class) {
|
||||
require __DIR__ . '/ClassLoader.php';
|
||||
}
|
||||
}
|
||||
|
||||
public static function getLoader()
|
||||
{
|
||||
if (null !== self::$loader) {
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInit3146f05565d9c8136a7e59e2a511ce14', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit3146f05565d9c8136a7e59e2a511ce14', 'loadClassLoader'));
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
$map = require __DIR__ . '/autoload_namespaces.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->set($namespace, $path);
|
||||
}
|
||||
|
||||
$classMap = require __DIR__ . '/autoload_classmap.php';
|
||||
if ($classMap) {
|
||||
$loader->addClassMap($classMap);
|
||||
}
|
||||
|
||||
$loader->register(true);
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
50
bundled-libs/composer/installed.json
Normal file
50
bundled-libs/composer/installed.json
Normal file
@ -0,0 +1,50 @@
|
||||
[
|
||||
{
|
||||
"name": "zendframework/zend-db",
|
||||
"version": "2.2.2",
|
||||
"version_normalized": "2.2.2.0",
|
||||
"target-dir": "Zend/Db",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zendframework/Component_ZendDb.git",
|
||||
"reference": "release-2.2.2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://packages.zendframework.com/composer/zendframework-zend-db-2.2.2-release-2.2.2-6ab69c.zip",
|
||||
"reference": "2.2.2",
|
||||
"shasum": "8bc0c8d19bfd75f9a65a4b332f556c2571424c09"
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"suggest": {
|
||||
"zendframework/zend-stdlib": "2.2.2"
|
||||
},
|
||||
"time": "2013-06-20 18:00:57",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.2-dev",
|
||||
"dev-develop": "2.3-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Zend\\Db\\": ""
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"description": " ",
|
||||
"keywords": [
|
||||
"db",
|
||||
"zf2"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/zendframework/Component_ZendDb/tree/release-2.2.2"
|
||||
}
|
||||
}
|
||||
]
|
388
bundled-libs/zendframework/zend-db/Zend/Db/Adapter/Adapter.php
Normal file
388
bundled-libs/zendframework/zend-db/Zend/Db/Adapter/Adapter.php
Normal file
@ -0,0 +1,388 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter;
|
||||
|
||||
use Zend\Db\ResultSet;
|
||||
|
||||
/**
|
||||
* @property Driver\DriverInterface $driver
|
||||
* @property Platform\PlatformInterface $platform
|
||||
*/
|
||||
class Adapter implements AdapterInterface, Profiler\ProfilerAwareInterface
|
||||
{
|
||||
/**
|
||||
* Query Mode Constants
|
||||
*/
|
||||
const QUERY_MODE_EXECUTE = 'execute';
|
||||
const QUERY_MODE_PREPARE = 'prepare';
|
||||
|
||||
/**
|
||||
* Prepare Type Constants
|
||||
*/
|
||||
const PREPARE_TYPE_POSITIONAL = 'positional';
|
||||
const PREPARE_TYPE_NAMED = 'named';
|
||||
|
||||
const FUNCTION_FORMAT_PARAMETER_NAME = 'formatParameterName';
|
||||
const FUNCTION_QUOTE_IDENTIFIER = 'quoteIdentifier';
|
||||
const FUNCTION_QUOTE_VALUE = 'quoteValue';
|
||||
|
||||
const VALUE_QUOTE_SEPARATOR = 'quoteSeparator';
|
||||
|
||||
/**
|
||||
* @var Driver\DriverInterface
|
||||
*/
|
||||
protected $driver = null;
|
||||
|
||||
/**
|
||||
* @var Platform\PlatformInterface
|
||||
*/
|
||||
protected $platform = null;
|
||||
|
||||
/**
|
||||
* @var Profiler\ProfilerInterface
|
||||
*/
|
||||
protected $profiler = null;
|
||||
|
||||
/**
|
||||
* @var ResultSet\ResultSetInterface
|
||||
*/
|
||||
protected $queryResultSetPrototype = null;
|
||||
|
||||
/**
|
||||
* @var Driver\StatementInterface
|
||||
*/
|
||||
protected $lastPreparedStatement = null;
|
||||
|
||||
/**
|
||||
* @param Driver\DriverInterface|array $driver
|
||||
* @param Platform\PlatformInterface $platform
|
||||
* @param ResultSet\ResultSetInterface $queryResultPrototype
|
||||
* @param Profiler\ProfilerInterface $profiler
|
||||
* @throws Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct($driver, Platform\PlatformInterface $platform = null, ResultSet\ResultSetInterface $queryResultPrototype = null, Profiler\ProfilerInterface $profiler = null)
|
||||
{
|
||||
// first argument can be an array of parameters
|
||||
$parameters = array();
|
||||
|
||||
if (is_array($driver)) {
|
||||
$parameters = $driver;
|
||||
if ($profiler === null && isset($parameters['profiler'])) {
|
||||
$profiler = $this->createProfiler($parameters);
|
||||
}
|
||||
$driver = $this->createDriver($parameters);
|
||||
} elseif (!$driver instanceof Driver\DriverInterface) {
|
||||
throw new Exception\InvalidArgumentException(
|
||||
'The supplied or instantiated driver object does not implement Zend\Db\Adapter\Driver\DriverInterface'
|
||||
);
|
||||
}
|
||||
|
||||
$driver->checkEnvironment();
|
||||
$this->driver = $driver;
|
||||
|
||||
if ($platform == null) {
|
||||
$platform = $this->createPlatform($parameters);
|
||||
}
|
||||
|
||||
$this->platform = $platform;
|
||||
$this->queryResultSetPrototype = ($queryResultPrototype) ?: new ResultSet\ResultSet();
|
||||
|
||||
if ($profiler) {
|
||||
$this->setProfiler($profiler);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Profiler\ProfilerInterface $profiler
|
||||
* @return Adapter
|
||||
*/
|
||||
public function setProfiler(Profiler\ProfilerInterface $profiler)
|
||||
{
|
||||
$this->profiler = $profiler;
|
||||
if ($this->driver instanceof Profiler\ProfilerAwareInterface) {
|
||||
$this->driver->setProfiler($profiler);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|Profiler\ProfilerInterface
|
||||
*/
|
||||
public function getProfiler()
|
||||
{
|
||||
return $this->profiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* getDriver()
|
||||
*
|
||||
* @throws Exception\RuntimeException
|
||||
* @return Driver\DriverInterface
|
||||
*/
|
||||
public function getDriver()
|
||||
{
|
||||
if ($this->driver == null) {
|
||||
throw new Exception\RuntimeException('Driver has not been set or configured for this adapter.');
|
||||
}
|
||||
return $this->driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Platform\PlatformInterface
|
||||
*/
|
||||
public function getPlatform()
|
||||
{
|
||||
return $this->platform;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ResultSet\ResultSetInterface
|
||||
*/
|
||||
public function getQueryResultSetPrototype()
|
||||
{
|
||||
return $this->queryResultSetPrototype;
|
||||
}
|
||||
|
||||
public function getCurrentSchema()
|
||||
{
|
||||
return $this->driver->getConnection()->getCurrentSchema();
|
||||
}
|
||||
|
||||
/**
|
||||
* query() is a convenience function
|
||||
*
|
||||
* @param string $sql
|
||||
* @param string|array|ParameterContainer $parametersOrQueryMode
|
||||
* @throws Exception\InvalidArgumentException
|
||||
* @return Driver\StatementInterface|ResultSet\ResultSet
|
||||
*/
|
||||
public function query($sql, $parametersOrQueryMode = self::QUERY_MODE_PREPARE)
|
||||
{
|
||||
if (is_string($parametersOrQueryMode) && in_array($parametersOrQueryMode, array(self::QUERY_MODE_PREPARE, self::QUERY_MODE_EXECUTE))) {
|
||||
$mode = $parametersOrQueryMode;
|
||||
$parameters = null;
|
||||
} elseif (is_array($parametersOrQueryMode) || $parametersOrQueryMode instanceof ParameterContainer) {
|
||||
$mode = self::QUERY_MODE_PREPARE;
|
||||
$parameters = $parametersOrQueryMode;
|
||||
} else {
|
||||
throw new Exception\InvalidArgumentException('Parameter 2 to this method must be a flag, an array, or ParameterContainer');
|
||||
}
|
||||
|
||||
if ($mode == self::QUERY_MODE_PREPARE) {
|
||||
$this->lastPreparedStatement = null;
|
||||
$this->lastPreparedStatement = $this->driver->createStatement($sql);
|
||||
$this->lastPreparedStatement->prepare();
|
||||
if (is_array($parameters) || $parameters instanceof ParameterContainer) {
|
||||
$this->lastPreparedStatement->setParameterContainer((is_array($parameters)) ? new ParameterContainer($parameters) : $parameters);
|
||||
$result = $this->lastPreparedStatement->execute();
|
||||
} else {
|
||||
return $this->lastPreparedStatement;
|
||||
}
|
||||
} else {
|
||||
$result = $this->driver->getConnection()->execute($sql);
|
||||
}
|
||||
|
||||
if ($result instanceof Driver\ResultInterface && $result->isQueryResult()) {
|
||||
$resultSet = clone $this->queryResultSetPrototype;
|
||||
$resultSet->initialize($result);
|
||||
return $resultSet;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create statement
|
||||
*
|
||||
* @param string $initialSql
|
||||
* @param ParameterContainer $initialParameters
|
||||
* @return Driver\StatementInterface
|
||||
*/
|
||||
public function createStatement($initialSql = null, $initialParameters = null)
|
||||
{
|
||||
$statement = $this->driver->createStatement($initialSql);
|
||||
if ($initialParameters == null || !$initialParameters instanceof ParameterContainer && is_array($initialParameters)) {
|
||||
$initialParameters = new ParameterContainer((is_array($initialParameters) ? $initialParameters : array()));
|
||||
}
|
||||
$statement->setParameterContainer($initialParameters);
|
||||
return $statement;
|
||||
}
|
||||
|
||||
public function getHelpers(/* $functions */)
|
||||
{
|
||||
$functions = array();
|
||||
$platform = $this->platform;
|
||||
foreach (func_get_args() as $arg) {
|
||||
switch ($arg) {
|
||||
case self::FUNCTION_QUOTE_IDENTIFIER:
|
||||
$functions[] = function ($value) use ($platform) { return $platform->quoteIdentifier($value); };
|
||||
break;
|
||||
case self::FUNCTION_QUOTE_VALUE:
|
||||
$functions[] = function ($value) use ($platform) { return $platform->quoteValue($value); };
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @throws Exception\InvalidArgumentException
|
||||
* @return Driver\DriverInterface|Platform\PlatformInterface
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch (strtolower($name)) {
|
||||
case 'driver':
|
||||
return $this->driver;
|
||||
case 'platform':
|
||||
return $this->platform;
|
||||
default:
|
||||
throw new Exception\InvalidArgumentException('Invalid magic property on adapter');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $parameters
|
||||
* @return Driver\DriverInterface
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws Exception\InvalidArgumentException
|
||||
*/
|
||||
protected function createDriver($parameters)
|
||||
{
|
||||
if (!isset($parameters['driver'])) {
|
||||
throw new Exception\InvalidArgumentException(__FUNCTION__ . ' expects a "driver" key to be present inside the parameters');
|
||||
}
|
||||
|
||||
if ($parameters['driver'] instanceof Driver\DriverInterface) {
|
||||
return $parameters['driver'];
|
||||
}
|
||||
|
||||
if (!is_string($parameters['driver'])) {
|
||||
throw new Exception\InvalidArgumentException(__FUNCTION__ . ' expects a "driver" to be a string or instance of DriverInterface');
|
||||
}
|
||||
|
||||
$options = array();
|
||||
if (isset($parameters['options'])) {
|
||||
$options = (array) $parameters['options'];
|
||||
unset($parameters['options']);
|
||||
}
|
||||
|
||||
$driverName = strtolower($parameters['driver']);
|
||||
switch ($driverName) {
|
||||
case 'mysqli':
|
||||
$driver = new Driver\Mysqli\Mysqli($parameters, null, null, $options);
|
||||
break;
|
||||
case 'sqlsrv':
|
||||
$driver = new Driver\Sqlsrv\Sqlsrv($parameters);
|
||||
break;
|
||||
case 'oci8':
|
||||
$driver = new Driver\Oci8\Oci8($parameters);
|
||||
break;
|
||||
case 'pgsql':
|
||||
$driver = new Driver\Pgsql\Pgsql($parameters);
|
||||
break;
|
||||
case 'ibmdb2':
|
||||
$driver = new Driver\IbmDb2\IbmDb2($parameters);
|
||||
break;
|
||||
case 'pdo':
|
||||
default:
|
||||
if ($driverName == 'pdo' || strpos($driverName, 'pdo') === 0) {
|
||||
$driver = new Driver\Pdo\Pdo($parameters);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($driver) || !$driver instanceof Driver\DriverInterface) {
|
||||
throw new Exception\InvalidArgumentException('DriverInterface expected', null, null);
|
||||
}
|
||||
|
||||
return $driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Driver\DriverInterface $driver
|
||||
* @return Platform\PlatformInterface
|
||||
*/
|
||||
protected function createPlatform($parameters)
|
||||
{
|
||||
if (isset($parameters['platform'])) {
|
||||
$platformName = $parameters['platform'];
|
||||
} elseif ($this->driver instanceof Driver\DriverInterface) {
|
||||
$platformName = $this->driver->getDatabasePlatformName(Driver\DriverInterface::NAME_FORMAT_CAMELCASE);
|
||||
} else {
|
||||
throw new Exception\InvalidArgumentException('A platform could not be determined from the provided configuration');
|
||||
}
|
||||
|
||||
// currently only supported by the IbmDb2 & Oracle concrete implementations
|
||||
$options = (isset($parameters['platform_options'])) ? $parameters['platform_options'] : array();
|
||||
|
||||
switch ($platformName) {
|
||||
case 'Mysql':
|
||||
// mysqli or pdo_mysql driver
|
||||
$driver = ($this->driver instanceof Driver\Mysqli\Mysqli || $this->driver instanceof Driver\Pdo\Pdo) ? $this->driver : null;
|
||||
return new Platform\Mysql($driver);
|
||||
case 'SqlServer':
|
||||
// PDO is only supported driver for quoting values in this platform
|
||||
return new Platform\SqlServer(($this->driver instanceof Driver\Pdo\Pdo) ? $this->driver : null);
|
||||
case 'Oracle':
|
||||
// oracle does not accept a driver as an option, no driver specific quoting available
|
||||
return new Platform\Oracle($options);
|
||||
case 'Sqlite':
|
||||
// PDO is only supported driver for quoting values in this platform
|
||||
return new Platform\Sqlite(($this->driver instanceof Driver\Pdo\Pdo) ? $this->driver : null);
|
||||
case 'Postgresql':
|
||||
// pgsql or pdo postgres driver
|
||||
$driver = ($this->driver instanceof Driver\Pgsql\Pgsql || $this->driver instanceof Driver\Pdo\Pdo) ? $this->driver : null;
|
||||
return new Platform\Postgresql($driver);
|
||||
case 'IbmDb2':
|
||||
// ibm_db2 driver escaping does not need an action connection
|
||||
return new Platform\IbmDb2($options);
|
||||
default:
|
||||
return new Platform\Sql92();
|
||||
}
|
||||
}
|
||||
|
||||
protected function createProfiler($parameters)
|
||||
{
|
||||
if ($parameters['profiler'] instanceof Profiler\ProfilerInterface) {
|
||||
$profiler = $parameters['profiler'];
|
||||
} elseif (is_bool($parameters['profiler'])) {
|
||||
$profiler = ($parameters['profiler'] == true) ? new Profiler\Profiler : null;
|
||||
} else {
|
||||
throw new Exception\InvalidArgumentException(
|
||||
'"profiler" parameter must be an instance of ProfilerInterface or a boolean'
|
||||
);
|
||||
}
|
||||
return $profiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $parameters
|
||||
* @return Driver\DriverInterface
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws Exception\InvalidArgumentException
|
||||
* @deprecated
|
||||
*/
|
||||
protected function createDriverFromParameters(array $parameters)
|
||||
{
|
||||
return $this->createDriver($parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Driver\DriverInterface $driver
|
||||
* @return Platform\PlatformInterface
|
||||
* @deprecated
|
||||
*/
|
||||
protected function createPlatformFromDriver(Driver\DriverInterface $driver)
|
||||
{
|
||||
return $this->createPlatform($driver);
|
||||
}
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter;
|
||||
|
||||
use Zend\ServiceManager\AbstractFactoryInterface;
|
||||
use Zend\ServiceManager\ServiceLocatorInterface;
|
||||
|
||||
/**
|
||||
* Database adapter abstract service factory.
|
||||
*
|
||||
* Allows configuring several database instances (such as writer and reader).
|
||||
*/
|
||||
class AdapterAbstractServiceFactory implements AbstractFactoryInterface
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* Can we create an adapter by the requested name?
|
||||
*
|
||||
* @param ServiceLocatorInterface $services
|
||||
* @param string $name
|
||||
* @param string $requestedName
|
||||
* @return bool
|
||||
*/
|
||||
public function canCreateServiceWithName(ServiceLocatorInterface $services, $name, $requestedName)
|
||||
{
|
||||
$config = $this->getConfig($services);
|
||||
if (empty($config)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
isset($config[$requestedName])
|
||||
&& is_array($config[$requestedName])
|
||||
&& !empty($config[$requestedName])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a DB adapter
|
||||
*
|
||||
* @param ServiceLocatorInterface $services
|
||||
* @param string $name
|
||||
* @param string $requestedName
|
||||
* @return Adapter
|
||||
*/
|
||||
public function createServiceWithName(ServiceLocatorInterface $services, $name, $requestedName)
|
||||
{
|
||||
$config = $this->getConfig($services);
|
||||
return new Adapter($config[$requestedName]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get db configuration, if any
|
||||
*
|
||||
* @param ServiceLocatorInterface $services
|
||||
* @return array
|
||||
*/
|
||||
protected function getConfig(ServiceLocatorInterface $services)
|
||||
{
|
||||
if ($this->config !== null) {
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
if (!$services->has('Config')) {
|
||||
$this->config = array();
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
$config = $services->get('Config');
|
||||
if (!isset($config['db'])
|
||||
|| !is_array($config['db'])
|
||||
) {
|
||||
$this->config = array();
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
$config = $config['db'];
|
||||
if (!isset($config['adapters'])
|
||||
|| !is_array($config['adapters'])
|
||||
) {
|
||||
$this->config = array();
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
$this->config = $config['adapters'];
|
||||
return $this->config;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter;
|
||||
|
||||
interface AdapterAwareInterface
|
||||
{
|
||||
/**
|
||||
* Set db adapter
|
||||
*
|
||||
* @param Adapter $adapter
|
||||
* @return AdapterAwareInterface
|
||||
*/
|
||||
public function setDbAdapter(Adapter $adapter);
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter;
|
||||
|
||||
use Zend\Db\Adapter\Adapter;
|
||||
|
||||
trait AdapterAwareTrait
|
||||
{
|
||||
/**
|
||||
* @var Adapter
|
||||
*/
|
||||
protected $adapter = null;
|
||||
|
||||
/**
|
||||
* Set db adapter
|
||||
*
|
||||
* @param Adapter $adapter
|
||||
* @return mixed
|
||||
*/
|
||||
public function setDbAdapter(Adapter $adapter)
|
||||
{
|
||||
$this->adapter = $adapter;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @property Driver\DriverInterface $driver
|
||||
* @property Platform\PlatformInterface $platform
|
||||
*/
|
||||
interface AdapterInterface
|
||||
{
|
||||
/**
|
||||
* @return Driver\DriverInterface
|
||||
*/
|
||||
public function getDriver();
|
||||
|
||||
/**
|
||||
* @return Platform\PlatformInterface
|
||||
*/
|
||||
public function getPlatform();
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter;
|
||||
|
||||
use Zend\ServiceManager\FactoryInterface;
|
||||
use Zend\ServiceManager\ServiceLocatorInterface;
|
||||
|
||||
class AdapterServiceFactory implements FactoryInterface
|
||||
{
|
||||
/**
|
||||
* Create db adapter service
|
||||
*
|
||||
* @param ServiceLocatorInterface $serviceLocator
|
||||
* @return Adapter
|
||||
*/
|
||||
public function createService(ServiceLocatorInterface $serviceLocator)
|
||||
{
|
||||
$config = $serviceLocator->get('Config');
|
||||
return new Adapter($config['db']);
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver;
|
||||
|
||||
interface ConnectionInterface
|
||||
{
|
||||
/**
|
||||
* Get current schema
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCurrentSchema();
|
||||
|
||||
/**
|
||||
* Get resource
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResource();
|
||||
|
||||
/**
|
||||
* Connect
|
||||
*
|
||||
* @return ConnectionInterface
|
||||
*/
|
||||
public function connect();
|
||||
|
||||
/**
|
||||
* Is connected
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isConnected();
|
||||
|
||||
/**
|
||||
* Disconnect
|
||||
*
|
||||
* @return ConnectionInterface
|
||||
*/
|
||||
public function disconnect();
|
||||
|
||||
/**
|
||||
* Begin transaction
|
||||
*
|
||||
* @return ConnectionInterface
|
||||
*/
|
||||
public function beginTransaction();
|
||||
|
||||
/**
|
||||
* Commit
|
||||
*
|
||||
* @return ConnectionInterface
|
||||
*/
|
||||
public function commit();
|
||||
|
||||
/**
|
||||
* Rollback
|
||||
*
|
||||
* @return ConnectionInterface
|
||||
*/
|
||||
public function rollback();
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @param string $sql
|
||||
* @return ResultInterface
|
||||
*/
|
||||
public function execute($sql);
|
||||
|
||||
/**
|
||||
* Get last generated id
|
||||
*
|
||||
* @param null $name Ignored
|
||||
* @return int
|
||||
*/
|
||||
public function getLastGeneratedValue($name = null);
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver;
|
||||
|
||||
interface DriverInterface
|
||||
{
|
||||
const PARAMETERIZATION_POSITIONAL = 'positional';
|
||||
const PARAMETERIZATION_NAMED = 'named';
|
||||
const NAME_FORMAT_CAMELCASE = 'camelCase';
|
||||
const NAME_FORMAT_NATURAL = 'natural';
|
||||
|
||||
/**
|
||||
* Get database platform name
|
||||
*
|
||||
* @param string $nameFormat
|
||||
* @return string
|
||||
*/
|
||||
public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE);
|
||||
|
||||
/**
|
||||
* Check environment
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function checkEnvironment();
|
||||
|
||||
/**
|
||||
* Get connection
|
||||
*
|
||||
* @return ConnectionInterface
|
||||
*/
|
||||
public function getConnection();
|
||||
|
||||
/**
|
||||
* Create statement
|
||||
*
|
||||
* @param string|resource $sqlOrResource
|
||||
* @return StatementInterface
|
||||
*/
|
||||
public function createStatement($sqlOrResource = null);
|
||||
|
||||
/**
|
||||
* Create result
|
||||
*
|
||||
* @param resource $resource
|
||||
* @return ResultInterface
|
||||
*/
|
||||
public function createResult($resource);
|
||||
|
||||
/**
|
||||
* Get prepare type
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPrepareType();
|
||||
|
||||
/**
|
||||
* Format parameter name
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $type
|
||||
* @return string
|
||||
*/
|
||||
public function formatParameterName($name, $type = null);
|
||||
|
||||
/**
|
||||
* Get last generated value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getLastGeneratedValue();
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Feature;
|
||||
|
||||
use Zend\Db\Adapter\Driver\DriverInterface;
|
||||
|
||||
abstract class AbstractFeature
|
||||
{
|
||||
|
||||
/**
|
||||
* @var DriverInterface
|
||||
*/
|
||||
protected $driver = null;
|
||||
|
||||
/**
|
||||
* Set driver
|
||||
*
|
||||
* @param DriverInterface $driver
|
||||
* @return void
|
||||
*/
|
||||
public function setDriver(DriverInterface $driver)
|
||||
{
|
||||
$this->driver = $driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function getName();
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Feature;
|
||||
|
||||
interface DriverFeatureInterface
|
||||
{
|
||||
/**
|
||||
* Setup the default features for Pdo
|
||||
*
|
||||
* @return DriverFeatureInterface
|
||||
*/
|
||||
public function setupDefaultFeatures();
|
||||
|
||||
/**
|
||||
* Add feature
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $feature
|
||||
* @return DriverFeatureInterface
|
||||
*/
|
||||
public function addFeature($name, $feature);
|
||||
|
||||
/**
|
||||
* Get feature
|
||||
*
|
||||
* @param $name
|
||||
* @return mixed|false
|
||||
*/
|
||||
public function getFeature($name);
|
||||
}
|
@ -0,0 +1,284 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\IbmDb2;
|
||||
|
||||
use Zend\Db\Adapter\Driver\ConnectionInterface;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
use Zend\Db\Adapter\Profiler;
|
||||
|
||||
class Connection implements ConnectionInterface, Profiler\ProfilerAwareInterface
|
||||
{
|
||||
/** @var IbmDb2 */
|
||||
protected $driver = null;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $connectionParameters = null;
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
protected $resource = null;
|
||||
|
||||
/**
|
||||
* @var Profiler\ProfilerInterface
|
||||
*/
|
||||
protected $profiler = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array|resource|null $connectionParameters (ibm_db2 connection resource)
|
||||
* @throws Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct($connectionParameters = null)
|
||||
{
|
||||
if (is_array($connectionParameters)) {
|
||||
$this->setConnectionParameters($connectionParameters);
|
||||
} elseif (is_resource($connectionParameters)) {
|
||||
$this->setResource($connectionParameters);
|
||||
} elseif (null !== $connectionParameters) {
|
||||
throw new Exception\InvalidArgumentException(
|
||||
'$connection must be an array of parameters, a db2 connection resource or null'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set driver
|
||||
*
|
||||
* @param IbmDb2 $driver
|
||||
* @return Connection
|
||||
*/
|
||||
public function setDriver(IbmDb2 $driver)
|
||||
{
|
||||
$this->driver = $driver;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Profiler\ProfilerInterface $profiler
|
||||
* @return Connection
|
||||
*/
|
||||
public function setProfiler(Profiler\ProfilerInterface $profiler)
|
||||
{
|
||||
$this->profiler = $profiler;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|Profiler\ProfilerInterface
|
||||
*/
|
||||
public function getProfiler()
|
||||
{
|
||||
return $this->profiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $connectionParameters
|
||||
* @return Connection
|
||||
*/
|
||||
public function setConnectionParameters(array $connectionParameters)
|
||||
{
|
||||
$this->connectionParameters = $connectionParameters;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getConnectionParameters()
|
||||
{
|
||||
return $this->connectionParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource $resource DB2 resource
|
||||
* @return Connection
|
||||
*/
|
||||
public function setResource($resource)
|
||||
{
|
||||
if (!is_resource($resource) || get_resource_type($resource) !== 'DB2 Connection') {
|
||||
throw new Exception\InvalidArgumentException('The resource provided must be of type "DB2 Connection"');
|
||||
}
|
||||
$this->resource = $resource;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current schema
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCurrentSchema()
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
$info = db2_server_info($this->resource);
|
||||
return (isset($info->DB_NAME) ? $info->DB_NAME : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get resource
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect
|
||||
*
|
||||
* @return ConnectionInterface
|
||||
*/
|
||||
public function connect()
|
||||
{
|
||||
if (is_resource($this->resource)) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
// localize
|
||||
$p = $this->connectionParameters;
|
||||
|
||||
// given a list of key names, test for existence in $p
|
||||
$findParameterValue = function(array $names) use ($p) {
|
||||
foreach ($names as $name) {
|
||||
if (isset($p[$name])) {
|
||||
return $p[$name];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
$connection = array();
|
||||
$connection['database'] = $findParameterValue(array('database', 'db'));
|
||||
$connection['username'] = $findParameterValue(array('username', 'uid', 'UID'));
|
||||
$connection['password'] = $findParameterValue(array('password', 'pwd', 'PWD'));
|
||||
$connection['options'] = (isset($p['driver_options']) ? $p['driver_options'] : array());
|
||||
|
||||
$this->resource = db2_connect(
|
||||
$connection['database'],
|
||||
$connection['username'],
|
||||
$connection['password'],
|
||||
$connection['options']
|
||||
);
|
||||
|
||||
if ($this->resource === false) {
|
||||
throw new Exception\RuntimeException(sprintf(
|
||||
'%s: Unable to connect to database',
|
||||
__METHOD__
|
||||
));
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is connected
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isConnected()
|
||||
{
|
||||
return ($this->resource !== null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect
|
||||
*
|
||||
* @return ConnectionInterface
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
if ($this->resource) {
|
||||
db2_close($this->resource);
|
||||
$this->resource = null;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin transaction
|
||||
*
|
||||
* @return ConnectionInterface
|
||||
*/
|
||||
public function beginTransaction()
|
||||
{
|
||||
// TODO: Implement beginTransaction() method.
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit
|
||||
*
|
||||
* @return ConnectionInterface
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
// TODO: Implement commit() method.
|
||||
}
|
||||
|
||||
/**
|
||||
* Rollback
|
||||
*
|
||||
* @return ConnectionInterface
|
||||
*/
|
||||
public function rollback()
|
||||
{
|
||||
// TODO: Implement rollback() method.
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @param string $sql
|
||||
* @return Result
|
||||
*/
|
||||
public function execute($sql)
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
if ($this->profiler) {
|
||||
$this->profiler->profilerStart($sql);
|
||||
}
|
||||
|
||||
set_error_handler(function () {}, E_WARNING); // suppress warnings
|
||||
$resultResource = db2_exec($this->resource, $sql);
|
||||
restore_error_handler();
|
||||
|
||||
if ($this->profiler) {
|
||||
$this->profiler->profilerFinish($sql);
|
||||
}
|
||||
|
||||
// if the returnValue is something other than a pg result resource, bypass wrapping it
|
||||
if ($resultResource === false) {
|
||||
throw new Exception\InvalidQueryException(db2_stmt_errormsg());
|
||||
}
|
||||
|
||||
$resultPrototype = $this->driver->createResult(($resultResource === true) ? $this->resource : $resultResource);
|
||||
return $resultPrototype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last generated id
|
||||
*
|
||||
* @param null $name Ignored
|
||||
* @return int
|
||||
*/
|
||||
public function getLastGeneratedValue($name = null)
|
||||
{
|
||||
return db2_last_insert_id($this->resource);
|
||||
}
|
||||
}
|
@ -0,0 +1,214 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\IbmDb2;
|
||||
|
||||
use Zend\Db\Adapter\Driver\DriverInterface;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
use Zend\Db\Adapter\Profiler;
|
||||
|
||||
class IbmDb2 implements DriverInterface, Profiler\ProfilerAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var Connection
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/** @var Statement */
|
||||
protected $statementPrototype;
|
||||
|
||||
/** @var Result */
|
||||
protected $resultPrototype;
|
||||
|
||||
/**
|
||||
* @var Profiler\ProfilerInterface
|
||||
*/
|
||||
protected $profiler;
|
||||
|
||||
/**
|
||||
* @param array|Connection|resource $connection
|
||||
* @param null|Statement $statementPrototype
|
||||
* @param null|Result $resultPrototype
|
||||
*/
|
||||
public function __construct($connection, Statement $statementPrototype = null, Result $resultPrototype = null)
|
||||
{
|
||||
if (!$connection instanceof Connection) {
|
||||
$connection = new Connection($connection);
|
||||
}
|
||||
|
||||
$this->registerConnection($connection);
|
||||
$this->registerStatementPrototype(($statementPrototype) ?: new Statement());
|
||||
$this->registerResultPrototype(($resultPrototype) ?: new Result());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Profiler\ProfilerInterface $profiler
|
||||
* @return IbmDb2
|
||||
*/
|
||||
public function setProfiler(Profiler\ProfilerInterface $profiler)
|
||||
{
|
||||
$this->profiler = $profiler;
|
||||
if ($this->connection instanceof Profiler\ProfilerAwareInterface) {
|
||||
$this->connection->setProfiler($profiler);
|
||||
}
|
||||
if ($this->statementPrototype instanceof Profiler\ProfilerAwareInterface) {
|
||||
$this->statementPrototype->setProfiler($profiler);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|Profiler\ProfilerInterface
|
||||
*/
|
||||
public function getProfiler()
|
||||
{
|
||||
return $this->profiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Connection $connection
|
||||
* @return IbmDb2
|
||||
*/
|
||||
public function registerConnection(Connection $connection)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
$this->connection->setDriver($this);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Statement $statementPrototype
|
||||
* @return IbmDb2
|
||||
*/
|
||||
public function registerStatementPrototype(Statement $statementPrototype)
|
||||
{
|
||||
$this->statementPrototype = $statementPrototype;
|
||||
$this->statementPrototype->setDriver($this);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Result $resultPrototype
|
||||
* @return IbmDb2
|
||||
*/
|
||||
public function registerResultPrototype(Result $resultPrototype)
|
||||
{
|
||||
$this->resultPrototype = $resultPrototype;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get database platform name
|
||||
*
|
||||
* @param string $nameFormat
|
||||
* @return string
|
||||
*/
|
||||
public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE)
|
||||
{
|
||||
if ($nameFormat == self::NAME_FORMAT_CAMELCASE) {
|
||||
return 'IbmDb2';
|
||||
} else {
|
||||
return 'IBM DB2';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check environment
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function checkEnvironment()
|
||||
{
|
||||
if (!extension_loaded('ibm_db2')) {
|
||||
throw new Exception\RuntimeException('The ibm_db2 extension is required by this driver.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get connection
|
||||
*
|
||||
* @return Connection
|
||||
*/
|
||||
public function getConnection()
|
||||
{
|
||||
return $this->connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create statement
|
||||
*
|
||||
* @param string|resource $sqlOrResource
|
||||
* @return Statement
|
||||
*/
|
||||
public function createStatement($sqlOrResource = null)
|
||||
{
|
||||
$statement = clone $this->statementPrototype;
|
||||
if (is_resource($sqlOrResource) && get_resource_type($sqlOrResource) == 'DB2 Statement') {
|
||||
$statement->setResource($sqlOrResource);
|
||||
} else {
|
||||
if (is_string($sqlOrResource)) {
|
||||
$statement->setSql($sqlOrResource);
|
||||
} elseif ($sqlOrResource !== null) {
|
||||
throw new Exception\InvalidArgumentException(
|
||||
__FUNCTION__ . ' only accepts an SQL string or a ibm_db2 resource'
|
||||
);
|
||||
}
|
||||
if (!$this->connection->isConnected()) {
|
||||
$this->connection->connect();
|
||||
}
|
||||
$statement->initialize($this->connection->getResource());
|
||||
}
|
||||
return $statement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create result
|
||||
*
|
||||
* @param resource $resource
|
||||
* @return Result
|
||||
*/
|
||||
public function createResult($resource)
|
||||
{
|
||||
$result = clone $this->resultPrototype;
|
||||
$result->initialize($resource, $this->connection->getLastGeneratedValue());
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get prepare type
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPrepareType()
|
||||
{
|
||||
return self::PARAMETERIZATION_POSITIONAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format parameter name
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $type
|
||||
* @return string
|
||||
*/
|
||||
public function formatParameterName($name, $type = null)
|
||||
{
|
||||
return '?';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last generated value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getLastGeneratedValue()
|
||||
{
|
||||
return $this->connection->getLastGeneratedValue();
|
||||
}
|
||||
}
|
@ -0,0 +1,192 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\IbmDb2;
|
||||
|
||||
use Zend\Db\Adapter\Driver\ResultInterface;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
|
||||
class Result implements ResultInterface
|
||||
{
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
protected $resource;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $position = 0;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $currentComplete = false;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
protected $currentData = null;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
protected $generatedValue = null;
|
||||
|
||||
/**
|
||||
* @param resource $resource
|
||||
* @param mixed $generatedValue
|
||||
* @return Result
|
||||
*/
|
||||
public function initialize($resource, $generatedValue = null)
|
||||
{
|
||||
$this->resource = $resource;
|
||||
$this->generatedValue = $generatedValue;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* (PHP 5 >= 5.0.0)<br/>
|
||||
* Return the current element
|
||||
* @link http://php.net/manual/en/iterator.current.php
|
||||
* @return mixed Can return any type.
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
if ($this->currentComplete) {
|
||||
return $this->currentData;
|
||||
}
|
||||
|
||||
$this->currentData = db2_fetch_assoc($this->resource);
|
||||
return $this->currentData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
$this->currentData = db2_fetch_assoc($this->resource);
|
||||
$this->currentComplete = true;
|
||||
$this->position++;
|
||||
return $this->currentData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|string
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return ($this->currentData !== false);
|
||||
}
|
||||
|
||||
/**
|
||||
* (PHP 5 >= 5.0.0)<br/>
|
||||
* Rewind the Iterator to the first element
|
||||
* @link http://php.net/manual/en/iterator.rewind.php
|
||||
* @return void Any returned value is ignored.
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
if ($this->position > 0) {
|
||||
throw new Exception\RuntimeException(
|
||||
'This result is a forward only result set, calling rewind() after moving forward is not supported'
|
||||
);
|
||||
}
|
||||
$this->currentData = db2_fetch_assoc($this->resource);
|
||||
$this->currentComplete = true;
|
||||
$this->position = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force buffering
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function buffer()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if is buffered
|
||||
*
|
||||
* @return bool|null
|
||||
*/
|
||||
public function isBuffered()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is query result?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isQueryResult()
|
||||
{
|
||||
return (db2_num_fields($this->resource) > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get affected rows
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getAffectedRows()
|
||||
{
|
||||
return db2_num_rows($this->resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get generated value
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getGeneratedValue()
|
||||
{
|
||||
return $this->generatedValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the resource
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field count
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getFieldCount()
|
||||
{
|
||||
return db2_num_fields($this->resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,240 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\IbmDb2;
|
||||
|
||||
use Zend\Db\Adapter\Driver\StatementInterface;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
use Zend\Db\Adapter\ParameterContainer;
|
||||
use Zend\Db\Adapter\Profiler;
|
||||
|
||||
class Statement implements StatementInterface, Profiler\ProfilerAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
protected $db2 = null;
|
||||
|
||||
/**
|
||||
* @var IbmDb2
|
||||
*/
|
||||
protected $driver = null;
|
||||
|
||||
/**
|
||||
* @var Profiler\ProfilerInterface
|
||||
*/
|
||||
protected $profiler = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $sql = '';
|
||||
|
||||
/**
|
||||
* @var ParameterContainer
|
||||
*/
|
||||
protected $parameterContainer = null;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $isPrepared = false;
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
protected $resource = null;
|
||||
|
||||
/**
|
||||
* @param $resource
|
||||
* @return Statement
|
||||
*/
|
||||
public function initialize($resource)
|
||||
{
|
||||
$this->db2 = $resource;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IbmDb2 $driver
|
||||
* @return Statement
|
||||
*/
|
||||
public function setDriver(IbmDb2 $driver)
|
||||
{
|
||||
$this->driver = $driver;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Profiler\ProfilerInterface $profiler
|
||||
* @return Statement
|
||||
*/
|
||||
public function setProfiler(Profiler\ProfilerInterface $profiler)
|
||||
{
|
||||
$this->profiler = $profiler;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|Profiler\ProfilerInterface
|
||||
*/
|
||||
public function getProfiler()
|
||||
{
|
||||
return $this->profiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set sql
|
||||
*
|
||||
* @param $sql
|
||||
* @return mixed
|
||||
*/
|
||||
public function setSql($sql)
|
||||
{
|
||||
$this->sql = $sql;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sql
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getSql()
|
||||
{
|
||||
return $this->sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set parameter container
|
||||
*
|
||||
* @param ParameterContainer $parameterContainer
|
||||
* @return mixed
|
||||
*/
|
||||
public function setParameterContainer(ParameterContainer $parameterContainer)
|
||||
{
|
||||
$this->parameterContainer = $parameterContainer;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get parameter container
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getParameterContainer()
|
||||
{
|
||||
return $this->parameterContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $resource
|
||||
* @throws \Zend\Db\Adapter\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function setResource($resource)
|
||||
{
|
||||
if (get_resource_type($resource) !== 'DB2 Statement') {
|
||||
throw new Exception\InvalidArgumentException('Resource must be of type DB2 Statement');
|
||||
}
|
||||
$this->resource = $resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get resource
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare sql
|
||||
*
|
||||
* @param string|null $sql
|
||||
* @return Statement
|
||||
*/
|
||||
public function prepare($sql = null)
|
||||
{
|
||||
if ($this->isPrepared) {
|
||||
throw new Exception\RuntimeException('This statement has been prepared already');
|
||||
}
|
||||
|
||||
if ($sql == null) {
|
||||
$sql = $this->sql;
|
||||
}
|
||||
|
||||
$this->resource = db2_prepare($this->db2, $sql);
|
||||
|
||||
if ($this->resource === false) {
|
||||
throw new Exception\RuntimeException(db2_stmt_errormsg(), db2_stmt_error());
|
||||
}
|
||||
|
||||
$this->isPrepared = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if is prepared
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPrepared()
|
||||
{
|
||||
return $this->isPrepared;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @param null $parameters
|
||||
* @return Result
|
||||
*/
|
||||
public function execute($parameters = null)
|
||||
{
|
||||
if (!$this->isPrepared) {
|
||||
$this->prepare();
|
||||
}
|
||||
|
||||
/** START Standard ParameterContainer Merging Block */
|
||||
if (!$this->parameterContainer instanceof ParameterContainer) {
|
||||
if ($parameters instanceof ParameterContainer) {
|
||||
$this->parameterContainer = $parameters;
|
||||
$parameters = null;
|
||||
} else {
|
||||
$this->parameterContainer = new ParameterContainer();
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($parameters)) {
|
||||
$this->parameterContainer->setFromArray($parameters);
|
||||
}
|
||||
/** END Standard ParameterContainer Merging Block */
|
||||
|
||||
if ($this->profiler) {
|
||||
$this->profiler->profilerStart($this);
|
||||
}
|
||||
|
||||
set_error_handler(function () {}, E_WARNING); // suppress warnings
|
||||
$response = db2_execute($this->resource, $this->parameterContainer->getPositionalArray());
|
||||
restore_error_handler();
|
||||
|
||||
if ($this->profiler) {
|
||||
$this->profiler->profilerFinish();
|
||||
}
|
||||
|
||||
if ($response === false) {
|
||||
throw new Exception\RuntimeException(db2_stmt_errormsg($this->resource));
|
||||
}
|
||||
|
||||
$result = $this->driver->createResult($this->resource);
|
||||
return $result;
|
||||
}
|
||||
}
|
@ -0,0 +1,337 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Mysqli;
|
||||
|
||||
use Zend\Db\Adapter\Driver\ConnectionInterface;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
use Zend\Db\Adapter\Profiler;
|
||||
|
||||
class Connection implements ConnectionInterface, Profiler\ProfilerAwareInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Mysqli
|
||||
*/
|
||||
protected $driver = null;
|
||||
|
||||
/**
|
||||
* @var Profiler\ProfilerInterface
|
||||
*/
|
||||
protected $profiler = null;
|
||||
|
||||
/**
|
||||
* Connection parameters
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $connectionParameters = array();
|
||||
|
||||
/**
|
||||
* @var \mysqli
|
||||
*/
|
||||
protected $resource = null;
|
||||
|
||||
/**
|
||||
* In transaction
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $inTransaction = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array|mysqli|null $connectionInfo
|
||||
* @throws \Zend\Db\Adapter\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct($connectionInfo = null)
|
||||
{
|
||||
if (is_array($connectionInfo)) {
|
||||
$this->setConnectionParameters($connectionInfo);
|
||||
} elseif ($connectionInfo instanceof \mysqli) {
|
||||
$this->setResource($connectionInfo);
|
||||
} elseif (null !== $connectionInfo) {
|
||||
throw new Exception\InvalidArgumentException('$connection must be an array of parameters, a mysqli object or null');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Mysqli $driver
|
||||
* @return Connection
|
||||
*/
|
||||
public function setDriver(Mysqli $driver)
|
||||
{
|
||||
$this->driver = $driver;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Profiler\ProfilerInterface $profiler
|
||||
* @return Connection
|
||||
*/
|
||||
public function setProfiler(Profiler\ProfilerInterface $profiler)
|
||||
{
|
||||
$this->profiler = $profiler;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|Profiler\ProfilerInterface
|
||||
*/
|
||||
public function getProfiler()
|
||||
{
|
||||
return $this->profiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set connection parameters
|
||||
*
|
||||
* @param array $connectionParameters
|
||||
* @return Connection
|
||||
*/
|
||||
public function setConnectionParameters(array $connectionParameters)
|
||||
{
|
||||
$this->connectionParameters = $connectionParameters;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get connection parameters
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getConnectionParameters()
|
||||
{
|
||||
return $this->connectionParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current schema
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCurrentSchema()
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
/** @var $result \mysqli_result */
|
||||
$result = $this->resource->query('SELECT DATABASE()');
|
||||
$r = $result->fetch_row();
|
||||
return $r[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set resource
|
||||
*
|
||||
* @param \mysqli $resource
|
||||
* @return Connection
|
||||
*/
|
||||
public function setResource(\mysqli $resource)
|
||||
{
|
||||
$this->resource = $resource;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get resource
|
||||
*
|
||||
* @return \mysqli
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
$this->connect();
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect
|
||||
*
|
||||
* @throws Exception\RuntimeException
|
||||
* @return Connection
|
||||
*/
|
||||
public function connect()
|
||||
{
|
||||
if ($this->resource instanceof \mysqli) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
// localize
|
||||
$p = $this->connectionParameters;
|
||||
|
||||
// given a list of key names, test for existence in $p
|
||||
$findParameterValue = function (array $names) use ($p) {
|
||||
foreach ($names as $name) {
|
||||
if (isset($p[$name])) {
|
||||
return $p[$name];
|
||||
}
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
$hostname = $findParameterValue(array('hostname', 'host'));
|
||||
$username = $findParameterValue(array('username', 'user'));
|
||||
$password = $findParameterValue(array('password', 'passwd', 'pw'));
|
||||
$database = $findParameterValue(array('database', 'dbname', 'db', 'schema'));
|
||||
$port = (isset($p['port'])) ? (int) $p['port'] : null;
|
||||
$socket = (isset($p['socket'])) ? $p['socket'] : null;
|
||||
|
||||
$this->resource = new \mysqli();
|
||||
$this->resource->init();
|
||||
|
||||
if (!empty($p['driver_options'])) {
|
||||
foreach ($p['driver_options'] as $option => $value) {
|
||||
if (is_string($option)) {
|
||||
$option = strtoupper($option);
|
||||
if (!defined($option)) {
|
||||
continue;
|
||||
}
|
||||
$option = constant($option);
|
||||
}
|
||||
$this->resource->options($option, $value);
|
||||
}
|
||||
}
|
||||
|
||||
$this->resource->real_connect($hostname, $username, $password, $database, $port, $socket);
|
||||
|
||||
if ($this->resource->connect_error) {
|
||||
throw new Exception\RuntimeException(
|
||||
'Connection error',
|
||||
null,
|
||||
new Exception\ErrorException($this->resource->connect_error, $this->resource->connect_errno)
|
||||
);
|
||||
}
|
||||
|
||||
if (!empty($p['charset'])) {
|
||||
$this->resource->set_charset($p['charset']);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is connected
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isConnected()
|
||||
{
|
||||
return ($this->resource instanceof \mysqli);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
if ($this->resource instanceof \mysqli) {
|
||||
$this->resource->close();
|
||||
}
|
||||
unset($this->resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin transaction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function beginTransaction()
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
$this->resource->autocommit(false);
|
||||
$this->inTransaction = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
if (!$this->resource) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
$this->resource->commit();
|
||||
$this->inTransaction = false;
|
||||
$this->resource->autocommit(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rollback
|
||||
*
|
||||
* @throws Exception\RuntimeException
|
||||
* @return Connection
|
||||
*/
|
||||
public function rollback()
|
||||
{
|
||||
if (!$this->resource) {
|
||||
throw new Exception\RuntimeException('Must be connected before you can rollback.');
|
||||
}
|
||||
|
||||
if (!$this->inTransaction) {
|
||||
throw new Exception\RuntimeException('Must call commit() before you can rollback.');
|
||||
}
|
||||
|
||||
$this->resource->rollback();
|
||||
$this->resource->autocommit(true);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @param string $sql
|
||||
* @throws Exception\InvalidQueryException
|
||||
* @return Result
|
||||
*/
|
||||
public function execute($sql)
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
if ($this->profiler) {
|
||||
$this->profiler->profilerStart($sql);
|
||||
}
|
||||
|
||||
$resultResource = $this->resource->query($sql);
|
||||
|
||||
if ($this->profiler) {
|
||||
$this->profiler->profilerFinish($sql);
|
||||
}
|
||||
|
||||
// if the returnValue is something other than a mysqli_result, bypass wrapping it
|
||||
if ($resultResource === false) {
|
||||
throw new Exception\InvalidQueryException($this->resource->error);
|
||||
}
|
||||
|
||||
$resultPrototype = $this->driver->createResult(($resultResource === true) ? $this->resource : $resultResource);
|
||||
return $resultPrototype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last generated id
|
||||
*
|
||||
* @param null $name Ignored
|
||||
* @return int
|
||||
*/
|
||||
public function getLastGeneratedValue($name = null)
|
||||
{
|
||||
return $this->resource->insert_id;
|
||||
}
|
||||
}
|
@ -0,0 +1,257 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Mysqli;
|
||||
|
||||
use mysqli_stmt;
|
||||
use Zend\Db\Adapter\Driver\DriverInterface;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
use Zend\Db\Adapter\Profiler;
|
||||
|
||||
class Mysqli implements DriverInterface, Profiler\ProfilerAwareInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Connection
|
||||
*/
|
||||
protected $connection = null;
|
||||
|
||||
/**
|
||||
* @var Statement
|
||||
*/
|
||||
protected $statementPrototype = null;
|
||||
|
||||
/**
|
||||
* @var Result
|
||||
*/
|
||||
protected $resultPrototype = null;
|
||||
|
||||
/**
|
||||
* @var Profiler\ProfilerInterface
|
||||
*/
|
||||
protected $profiler = null;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $options = array(
|
||||
'buffer_results' => false
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array|Connection|\mysqli $connection
|
||||
* @param null|Statement $statementPrototype
|
||||
* @param null|Result $resultPrototype
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct($connection, Statement $statementPrototype = null, Result $resultPrototype = null, array $options = array())
|
||||
{
|
||||
if (!$connection instanceof Connection) {
|
||||
$connection = new Connection($connection);
|
||||
}
|
||||
|
||||
$options = array_intersect_key(array_merge($this->options, $options), $this->options);
|
||||
|
||||
$this->registerConnection($connection);
|
||||
$this->registerStatementPrototype(($statementPrototype) ?: new Statement($options['buffer_results']));
|
||||
$this->registerResultPrototype(($resultPrototype) ?: new Result());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Profiler\ProfilerInterface $profiler
|
||||
* @return Mysqli
|
||||
*/
|
||||
public function setProfiler(Profiler\ProfilerInterface $profiler)
|
||||
{
|
||||
$this->profiler = $profiler;
|
||||
if ($this->connection instanceof Profiler\ProfilerAwareInterface) {
|
||||
$this->connection->setProfiler($profiler);
|
||||
}
|
||||
if ($this->statementPrototype instanceof Profiler\ProfilerAwareInterface) {
|
||||
$this->statementPrototype->setProfiler($profiler);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|Profiler\ProfilerInterface
|
||||
*/
|
||||
public function getProfiler()
|
||||
{
|
||||
return $this->profiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register connection
|
||||
*
|
||||
* @param Connection $connection
|
||||
* @return Mysqli
|
||||
*/
|
||||
public function registerConnection(Connection $connection)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
$this->connection->setDriver($this); // needs access to driver to createStatement()
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register statement prototype
|
||||
*
|
||||
* @param Statement $statementPrototype
|
||||
*/
|
||||
public function registerStatementPrototype(Statement $statementPrototype)
|
||||
{
|
||||
$this->statementPrototype = $statementPrototype;
|
||||
$this->statementPrototype->setDriver($this); // needs access to driver to createResult()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get statement prototype
|
||||
*
|
||||
* @return null|Statement
|
||||
*/
|
||||
public function getStatementPrototype()
|
||||
{
|
||||
return $this->statementPrototype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register result prototype
|
||||
*
|
||||
* @param Result $resultPrototype
|
||||
*/
|
||||
public function registerResultPrototype(Result $resultPrototype)
|
||||
{
|
||||
$this->resultPrototype = $resultPrototype;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|Result
|
||||
*/
|
||||
public function getResultPrototype()
|
||||
{
|
||||
return $this->resultPrototype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get database platform name
|
||||
*
|
||||
* @param string $nameFormat
|
||||
* @return string
|
||||
*/
|
||||
public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE)
|
||||
{
|
||||
if ($nameFormat == self::NAME_FORMAT_CAMELCASE) {
|
||||
return 'Mysql';
|
||||
}
|
||||
|
||||
return 'MySQL';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check environment
|
||||
*
|
||||
* @throws Exception\RuntimeException
|
||||
* @return void
|
||||
*/
|
||||
public function checkEnvironment()
|
||||
{
|
||||
if (!extension_loaded('mysqli')) {
|
||||
throw new Exception\RuntimeException('The Mysqli extension is required for this adapter but the extension is not loaded');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get connection
|
||||
*
|
||||
* @return Connection
|
||||
*/
|
||||
public function getConnection()
|
||||
{
|
||||
return $this->connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create statement
|
||||
*
|
||||
* @param string $sqlOrResource
|
||||
* @return Statement
|
||||
*/
|
||||
public function createStatement($sqlOrResource = null)
|
||||
{
|
||||
/**
|
||||
* @todo Resource tracking
|
||||
if (is_resource($sqlOrResource) && !in_array($sqlOrResource, $this->resources, true)) {
|
||||
$this->resources[] = $sqlOrResource;
|
||||
}
|
||||
*/
|
||||
|
||||
$statement = clone $this->statementPrototype;
|
||||
if ($sqlOrResource instanceof mysqli_stmt) {
|
||||
$statement->setResource($sqlOrResource);
|
||||
} else {
|
||||
if (is_string($sqlOrResource)) {
|
||||
$statement->setSql($sqlOrResource);
|
||||
}
|
||||
if (!$this->connection->isConnected()) {
|
||||
$this->connection->connect();
|
||||
}
|
||||
$statement->initialize($this->connection->getResource());
|
||||
}
|
||||
return $statement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create result
|
||||
*
|
||||
* @param resource $resource
|
||||
* @param null|bool $isBuffered
|
||||
* @return Result
|
||||
*/
|
||||
public function createResult($resource, $isBuffered = null)
|
||||
{
|
||||
$result = clone $this->resultPrototype;
|
||||
$result->initialize($resource, $this->connection->getLastGeneratedValue(), $isBuffered);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get prepare type
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPrepareType()
|
||||
{
|
||||
return self::PARAMETERIZATION_POSITIONAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format parameter name
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $type
|
||||
* @return string
|
||||
*/
|
||||
public function formatParameterName($name, $type = null)
|
||||
{
|
||||
return '?';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last generated value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getLastGeneratedValue()
|
||||
{
|
||||
return $this->getConnection()->getLastGeneratedValue();
|
||||
}
|
||||
}
|
@ -0,0 +1,342 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Mysqli;
|
||||
|
||||
use Iterator;
|
||||
use Zend\Db\Adapter\Driver\ResultInterface;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
|
||||
class Result implements
|
||||
Iterator,
|
||||
ResultInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var \mysqli|\mysqli_result|\mysqli_stmt
|
||||
*/
|
||||
protected $resource = null;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $isBuffered = null;
|
||||
|
||||
/**
|
||||
* Cursor position
|
||||
* @var int
|
||||
*/
|
||||
protected $position = 0;
|
||||
|
||||
/**
|
||||
* Number of known rows
|
||||
* @var int
|
||||
*/
|
||||
protected $numberOfRows = -1;
|
||||
|
||||
/**
|
||||
* Is the current() operation already complete for this pointer position?
|
||||
* @var bool
|
||||
*/
|
||||
protected $currentComplete = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $nextComplete = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $currentData = false;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $statementBindValues = array('keys' => null, 'values' => array());
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
protected $generatedValue = null;
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*
|
||||
* @param mixed $resource
|
||||
* @param mixed $generatedValue
|
||||
* @param bool|null $isBuffered
|
||||
* @throws Exception\InvalidArgumentException
|
||||
* @return Result
|
||||
*/
|
||||
public function initialize($resource, $generatedValue, $isBuffered = null)
|
||||
{
|
||||
if (!$resource instanceof \mysqli && !$resource instanceof \mysqli_result && !$resource instanceof \mysqli_stmt) {
|
||||
throw new Exception\InvalidArgumentException('Invalid resource provided.');
|
||||
}
|
||||
|
||||
if ($isBuffered !== null) {
|
||||
$this->isBuffered = $isBuffered;
|
||||
} else {
|
||||
if ($resource instanceof \mysqli || $resource instanceof \mysqli_result
|
||||
|| $resource instanceof \mysqli_stmt && $resource->num_rows != 0) {
|
||||
$this->isBuffered = true;
|
||||
}
|
||||
}
|
||||
|
||||
$this->resource = $resource;
|
||||
$this->generatedValue = $generatedValue;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force buffering
|
||||
*
|
||||
* @throws Exception\RuntimeException
|
||||
*/
|
||||
public function buffer()
|
||||
{
|
||||
if ($this->resource instanceof \mysqli_stmt && $this->isBuffered !== true) {
|
||||
if ($this->position > 0) {
|
||||
throw new Exception\RuntimeException('Cannot buffer a result set that has started iteration.');
|
||||
}
|
||||
$this->resource->store_result();
|
||||
$this->isBuffered = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if is buffered
|
||||
*
|
||||
* @return bool|null
|
||||
*/
|
||||
public function isBuffered()
|
||||
{
|
||||
return $this->isBuffered;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the resource
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is query result?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isQueryResult()
|
||||
{
|
||||
return ($this->resource->field_count > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get affected rows
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getAffectedRows()
|
||||
{
|
||||
if ($this->resource instanceof \mysqli || $this->resource instanceof \mysqli_stmt) {
|
||||
return $this->resource->affected_rows;
|
||||
}
|
||||
|
||||
return $this->resource->num_rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Current
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
if ($this->currentComplete) {
|
||||
return $this->currentData;
|
||||
}
|
||||
|
||||
if ($this->resource instanceof \mysqli_stmt) {
|
||||
$this->loadDataFromMysqliStatement();
|
||||
return $this->currentData;
|
||||
} else {
|
||||
$this->loadFromMysqliResult();
|
||||
return $this->currentData;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mysqli's binding and returning of statement values
|
||||
*
|
||||
* Mysqli requires you to bind variables to the extension in order to
|
||||
* get data out. These values have to be references:
|
||||
* @see http://php.net/manual/en/mysqli-stmt.bind-result.php
|
||||
*
|
||||
* @throws Exception\RuntimeException
|
||||
* @return bool
|
||||
*/
|
||||
protected function loadDataFromMysqliStatement()
|
||||
{
|
||||
$data = null;
|
||||
// build the default reference based bind structure, if it does not already exist
|
||||
if ($this->statementBindValues['keys'] === null) {
|
||||
$this->statementBindValues['keys'] = array();
|
||||
$resultResource = $this->resource->result_metadata();
|
||||
foreach ($resultResource->fetch_fields() as $col) {
|
||||
$this->statementBindValues['keys'][] = $col->name;
|
||||
}
|
||||
$this->statementBindValues['values'] = array_fill(0, count($this->statementBindValues['keys']), null);
|
||||
$refs = array();
|
||||
foreach ($this->statementBindValues['values'] as $i => &$f) {
|
||||
$refs[$i] = &$f;
|
||||
}
|
||||
call_user_func_array(array($this->resource, 'bind_result'), $this->statementBindValues['values']);
|
||||
}
|
||||
|
||||
if (($r = $this->resource->fetch()) === null) {
|
||||
if (!$this->isBuffered) {
|
||||
$this->resource->close();
|
||||
}
|
||||
return false;
|
||||
} elseif ($r === false) {
|
||||
throw new Exception\RuntimeException($this->resource->error);
|
||||
}
|
||||
|
||||
// dereference
|
||||
for ($i = 0, $count = count($this->statementBindValues['keys']); $i < $count; $i++) {
|
||||
$this->currentData[$this->statementBindValues['keys'][$i]] = $this->statementBindValues['values'][$i];
|
||||
}
|
||||
$this->currentComplete = true;
|
||||
$this->nextComplete = true;
|
||||
$this->position++;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load from mysqli result
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function loadFromMysqliResult()
|
||||
{
|
||||
$this->currentData = null;
|
||||
|
||||
if (($data = $this->resource->fetch_assoc()) === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->position++;
|
||||
$this->currentData = $data;
|
||||
$this->currentComplete = true;
|
||||
$this->nextComplete = true;
|
||||
$this->position++;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Next
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
$this->currentComplete = false;
|
||||
|
||||
if ($this->nextComplete == false) {
|
||||
$this->position++;
|
||||
}
|
||||
|
||||
$this->nextComplete = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Key
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewind
|
||||
*
|
||||
* @throws Exception\RuntimeException
|
||||
* @return void
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
if ($this->position !== 0) {
|
||||
if ($this->isBuffered === false) {
|
||||
throw new Exception\RuntimeException('Unbuffered results cannot be rewound for multiple iterations');
|
||||
}
|
||||
}
|
||||
$this->resource->data_seek(0); // works for both mysqli_result & mysqli_stmt
|
||||
$this->currentComplete = false;
|
||||
$this->position = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Valid
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
if ($this->currentComplete) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->resource instanceof \mysqli_stmt) {
|
||||
return $this->loadDataFromMysqliStatement();
|
||||
}
|
||||
|
||||
return $this->loadFromMysqliResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* Count
|
||||
*
|
||||
* @throws Exception\RuntimeException
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
if ($this->isBuffered === false) {
|
||||
throw new Exception\RuntimeException('Row count is not available in unbuffered result sets.');
|
||||
}
|
||||
return $this->resource->num_rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field count
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getFieldCount()
|
||||
{
|
||||
return $this->resource->field_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get generated value
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getGeneratedValue()
|
||||
{
|
||||
return $this->generatedValue;
|
||||
}
|
||||
}
|
@ -0,0 +1,316 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Mysqli;
|
||||
|
||||
use Zend\Db\Adapter\Driver\StatementInterface;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
use Zend\Db\Adapter\ParameterContainer;
|
||||
use Zend\Db\Adapter\Profiler;
|
||||
|
||||
class Statement implements StatementInterface, Profiler\ProfilerAwareInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var \mysqli
|
||||
*/
|
||||
protected $mysqli = null;
|
||||
|
||||
/**
|
||||
* @var Mysqli
|
||||
*/
|
||||
protected $driver = null;
|
||||
|
||||
/**
|
||||
* @var Profiler\ProfilerInterface
|
||||
*/
|
||||
protected $profiler = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $sql = '';
|
||||
|
||||
/**
|
||||
* Parameter container
|
||||
*
|
||||
* @var ParameterContainer
|
||||
*/
|
||||
protected $parameterContainer = null;
|
||||
|
||||
/**
|
||||
* @var \mysqli_stmt
|
||||
*/
|
||||
protected $resource = null;
|
||||
|
||||
/**
|
||||
* Is prepared
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isPrepared = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $bufferResults = false;
|
||||
|
||||
/**
|
||||
* @param bool $bufferResults
|
||||
*/
|
||||
public function __construct($bufferResults = false)
|
||||
{
|
||||
$this->bufferResults = (bool) $bufferResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set driver
|
||||
*
|
||||
* @param Mysqli $driver
|
||||
* @return Statement
|
||||
*/
|
||||
public function setDriver(Mysqli $driver)
|
||||
{
|
||||
$this->driver = $driver;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Profiler\ProfilerInterface $profiler
|
||||
* @return Statement
|
||||
*/
|
||||
public function setProfiler(Profiler\ProfilerInterface $profiler)
|
||||
{
|
||||
$this->profiler = $profiler;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|Profiler\ProfilerInterface
|
||||
*/
|
||||
public function getProfiler()
|
||||
{
|
||||
return $this->profiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*
|
||||
* @param \mysqli $mysqli
|
||||
* @return Statement
|
||||
*/
|
||||
public function initialize(\mysqli $mysqli)
|
||||
{
|
||||
$this->mysqli = $mysqli;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set sql
|
||||
*
|
||||
* @param string $sql
|
||||
* @return Statement
|
||||
*/
|
||||
public function setSql($sql)
|
||||
{
|
||||
$this->sql = $sql;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Parameter container
|
||||
*
|
||||
* @param ParameterContainer $parameterContainer
|
||||
* @return Statement
|
||||
*/
|
||||
public function setParameterContainer(ParameterContainer $parameterContainer)
|
||||
{
|
||||
$this->parameterContainer = $parameterContainer;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get resource
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set resource
|
||||
*
|
||||
* @param \mysqli_stmt $mysqliStatement
|
||||
* @return Statement
|
||||
*/
|
||||
public function setResource(\mysqli_stmt $mysqliStatement)
|
||||
{
|
||||
$this->resource = $mysqliStatement;
|
||||
$this->isPrepared = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sql
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSql()
|
||||
{
|
||||
return $this->sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get parameter count
|
||||
*
|
||||
* @return ParameterContainer
|
||||
*/
|
||||
public function getParameterContainer()
|
||||
{
|
||||
return $this->parameterContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is prepared
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPrepared()
|
||||
{
|
||||
return $this->isPrepared;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare
|
||||
*
|
||||
* @param string $sql
|
||||
* @throws Exception\InvalidQueryException
|
||||
* @throws Exception\RuntimeException
|
||||
* @return Statement
|
||||
*/
|
||||
public function prepare($sql = null)
|
||||
{
|
||||
if ($this->isPrepared) {
|
||||
throw new Exception\RuntimeException('This statement has already been prepared');
|
||||
}
|
||||
|
||||
$sql = ($sql) ?: $this->sql;
|
||||
|
||||
$this->resource = $this->mysqli->prepare($this->sql);
|
||||
if (!$this->resource instanceof \mysqli_stmt) {
|
||||
throw new Exception\InvalidQueryException(
|
||||
'Statement couldn\'t be produced with sql: ' . $sql,
|
||||
null,
|
||||
new Exception\ErrorException($this->mysqli->error, $this->mysqli->errno)
|
||||
);
|
||||
}
|
||||
|
||||
$this->isPrepared = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @param ParameterContainer|array $parameters
|
||||
* @throws Exception\RuntimeException
|
||||
* @return mixed
|
||||
*/
|
||||
public function execute($parameters = null)
|
||||
{
|
||||
if (!$this->isPrepared) {
|
||||
$this->prepare();
|
||||
}
|
||||
|
||||
/** START Standard ParameterContainer Merging Block */
|
||||
if (!$this->parameterContainer instanceof ParameterContainer) {
|
||||
if ($parameters instanceof ParameterContainer) {
|
||||
$this->parameterContainer = $parameters;
|
||||
$parameters = null;
|
||||
} else {
|
||||
$this->parameterContainer = new ParameterContainer();
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($parameters)) {
|
||||
$this->parameterContainer->setFromArray($parameters);
|
||||
}
|
||||
|
||||
if ($this->parameterContainer->count() > 0) {
|
||||
$this->bindParametersFromContainer();
|
||||
}
|
||||
/** END Standard ParameterContainer Merging Block */
|
||||
|
||||
if ($this->profiler) {
|
||||
$this->profiler->profilerStart($this);
|
||||
}
|
||||
|
||||
$return = $this->resource->execute();
|
||||
|
||||
if ($this->profiler) {
|
||||
$this->profiler->profilerFinish();
|
||||
}
|
||||
|
||||
if ($return === false) {
|
||||
throw new Exception\RuntimeException($this->resource->error);
|
||||
}
|
||||
|
||||
if ($this->bufferResults === true) {
|
||||
$this->resource->store_result();
|
||||
$this->isPrepared = false;
|
||||
$buffered = true;
|
||||
} else {
|
||||
$buffered = false;
|
||||
}
|
||||
|
||||
$result = $this->driver->createResult($this->resource, $buffered);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind parameters from container
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function bindParametersFromContainer()
|
||||
{
|
||||
$parameters = $this->parameterContainer->getNamedArray();
|
||||
$type = '';
|
||||
$args = array();
|
||||
|
||||
foreach ($parameters as $name => &$value) {
|
||||
if ($this->parameterContainer->offsetHasErrata($name)) {
|
||||
switch ($this->parameterContainer->offsetGetErrata($name)) {
|
||||
case ParameterContainer::TYPE_DOUBLE:
|
||||
$type .= 'd';
|
||||
break;
|
||||
case ParameterContainer::TYPE_NULL:
|
||||
$value = null; // as per @see http://www.php.net/manual/en/mysqli-stmt.bind-param.php#96148
|
||||
case ParameterContainer::TYPE_INTEGER:
|
||||
$type .= 'i';
|
||||
break;
|
||||
case ParameterContainer::TYPE_STRING:
|
||||
default:
|
||||
$type .= 's';
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$type .= 's';
|
||||
}
|
||||
$args[] = &$value;
|
||||
}
|
||||
|
||||
if ($args) {
|
||||
array_unshift($args, $type);
|
||||
call_user_func_array(array($this->resource, 'bind_param'), $args);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,345 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Oci8;
|
||||
|
||||
use Zend\Db\Adapter\Driver\ConnectionInterface;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
use Zend\Db\Adapter\Profiler;
|
||||
|
||||
class Connection implements ConnectionInterface, Profiler\ProfilerAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var Oci8
|
||||
*/
|
||||
protected $driver = null;
|
||||
|
||||
/**
|
||||
* @var Profiler\ProfilerInterface
|
||||
*/
|
||||
protected $profiler = null;
|
||||
|
||||
/**
|
||||
* Connection parameters
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $connectionParameters = array();
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
protected $resource = null;
|
||||
|
||||
/**
|
||||
* In transaction
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $inTransaction = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array|resource|null $connectionInfo
|
||||
* @throws \Zend\Db\Adapter\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct($connectionInfo = null)
|
||||
{
|
||||
if (is_array($connectionInfo)) {
|
||||
$this->setConnectionParameters($connectionInfo);
|
||||
} elseif ($connectionInfo instanceof \oci8) {
|
||||
$this->setResource($connectionInfo);
|
||||
} elseif (null !== $connectionInfo) {
|
||||
throw new Exception\InvalidArgumentException('$connection must be an array of parameters, a oci8 resource or null');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Oci8 $driver
|
||||
* @return Connection
|
||||
*/
|
||||
public function setDriver(Oci8 $driver)
|
||||
{
|
||||
$this->driver = $driver;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Profiler\ProfilerInterface $profiler
|
||||
* @return Connection
|
||||
*/
|
||||
public function setProfiler(Profiler\ProfilerInterface $profiler)
|
||||
{
|
||||
$this->profiler = $profiler;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|Profiler\ProfilerInterface
|
||||
*/
|
||||
public function getProfiler()
|
||||
{
|
||||
return $this->profiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set connection parameters
|
||||
*
|
||||
* @param array $connectionParameters
|
||||
* @return Connection
|
||||
*/
|
||||
public function setConnectionParameters(array $connectionParameters)
|
||||
{
|
||||
$this->connectionParameters = $connectionParameters;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get connection parameters
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getConnectionParameters()
|
||||
{
|
||||
return $this->connectionParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current schema
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCurrentSchema()
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
$query = "SELECT sys_context('USERENV', 'CURRENT_SCHEMA') as \"current_schema\" FROM DUAL";
|
||||
$stmt = oci_parse($this->resource, $query);
|
||||
oci_execute($stmt);
|
||||
$dbNameArray = oci_fetch_array($stmt, OCI_ASSOC);
|
||||
return $dbNameArray['current_schema'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set resource
|
||||
*
|
||||
* @param resource $resource
|
||||
* @return Connection
|
||||
*/
|
||||
public function setResource($resource)
|
||||
{
|
||||
if (!is_resource($resource) || get_resource_type($resource) !== 'oci8 connection') {
|
||||
throw new Exception\InvalidArgumentException('A resource of type "oci8 connection" was expected');
|
||||
}
|
||||
$this->resource = $resource;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get resource
|
||||
*
|
||||
* @return \oci8
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
$this->connect();
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect
|
||||
*
|
||||
* @return Connection
|
||||
*/
|
||||
public function connect()
|
||||
{
|
||||
if (is_resource($this->resource)) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
// localize
|
||||
$p = $this->connectionParameters;
|
||||
|
||||
// given a list of key names, test for existence in $p
|
||||
$findParameterValue = function(array $names) use ($p) {
|
||||
foreach ($names as $name) {
|
||||
if (isset($p[$name])) {
|
||||
return $p[$name];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
// http://www.php.net/manual/en/function.oci-connect.php
|
||||
$username = $findParameterValue(array('username'));
|
||||
$password = $findParameterValue(array('password'));
|
||||
$connectionString = $findParameterValue(array('connection_string', 'connectionstring', 'connection', 'hostname', 'instance'));
|
||||
$characterSet = $findParameterValue(array('character_set', 'charset', 'encoding'));
|
||||
|
||||
// connection modifiers
|
||||
$isUnique = $findParameterValue(array('unique'));
|
||||
$isPersistent = $findParameterValue(array('persistent'));
|
||||
|
||||
if ($isUnique == true) {
|
||||
$this->resource = oci_new_connect($username, $password, $connectionString, $characterSet);
|
||||
} elseif ($isPersistent == true) {
|
||||
$this->resource = oci_pconnect($username, $password, $connectionString, $characterSet);
|
||||
} else {
|
||||
$this->resource = oci_connect($username, $password, $connectionString, $characterSet);
|
||||
}
|
||||
|
||||
if (!$this->resource) {
|
||||
$e = oci_error();
|
||||
throw new Exception\RuntimeException(
|
||||
'Connection error',
|
||||
null,
|
||||
new Exception\ErrorException($e['message'], $e['code'])
|
||||
);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is connected
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isConnected()
|
||||
{
|
||||
return (is_resource($this->resource));
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
if (is_resource($this->resource)) {
|
||||
oci_close($this->resource);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin transaction
|
||||
*/
|
||||
public function beginTransaction()
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
// A transaction begins when the first SQL statement that changes data is executed with oci_execute() using the OCI_NO_AUTO_COMMIT flag.
|
||||
$this->inTransaction = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* In transaction
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function inTransaction()
|
||||
{
|
||||
return $this->inTransaction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
if (!$this->resource) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
if ($this->inTransaction) {
|
||||
$valid = oci_commit($this->resource);
|
||||
if ($valid === false) {
|
||||
$e = oci_error($this->resource);
|
||||
throw new Exception\InvalidQueryException($e['message'], $e['code']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rollback
|
||||
*
|
||||
* @return Connection
|
||||
*/
|
||||
public function rollback()
|
||||
{
|
||||
if (!$this->resource) {
|
||||
throw new Exception\RuntimeException('Must be connected before you can rollback.');
|
||||
}
|
||||
|
||||
if (!$this->inTransaction) {
|
||||
throw new Exception\RuntimeException('Must call commit() before you can rollback.');
|
||||
}
|
||||
|
||||
$valid = oci_rollback($this->resource);
|
||||
if ($valid === false) {
|
||||
$e = oci_error($this->resource);
|
||||
throw new Exception\InvalidQueryException($e['message'], $e['code']);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @param string $sql
|
||||
* @return Result
|
||||
*/
|
||||
public function execute($sql)
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
if ($this->profiler) {
|
||||
$this->profiler->profilerStart($sql);
|
||||
}
|
||||
|
||||
$ociStmt = oci_parse($this->resource, $sql);
|
||||
|
||||
if ($this->inTransaction) {
|
||||
$valid = @oci_execute($ociStmt, OCI_NO_AUTO_COMMIT);
|
||||
} else {
|
||||
$valid = @oci_execute($ociStmt, OCI_COMMIT_ON_SUCCESS);
|
||||
}
|
||||
|
||||
if ($this->profiler) {
|
||||
$this->profiler->profilerFinish($sql);
|
||||
}
|
||||
|
||||
if ($valid === false) {
|
||||
$e = oci_error($ociStmt);
|
||||
throw new Exception\InvalidQueryException($e['message'], $e['code']);
|
||||
}
|
||||
|
||||
$resultPrototype = $this->driver->createResult($ociStmt);
|
||||
return $resultPrototype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last generated id
|
||||
*
|
||||
* @param null $name Ignored
|
||||
* @return int
|
||||
*/
|
||||
public function getLastGeneratedValue($name = null)
|
||||
{
|
||||
// @todo Get Last Generated Value in Connection (this might not apply)
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,235 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Oci8;
|
||||
|
||||
use Zend\Db\Adapter\Driver\DriverInterface;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
use Zend\Db\Adapter\Profiler;
|
||||
|
||||
class Oci8 implements DriverInterface, Profiler\ProfilerAwareInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Connection
|
||||
*/
|
||||
protected $connection = null;
|
||||
|
||||
/**
|
||||
* @var Statement
|
||||
*/
|
||||
protected $statementPrototype = null;
|
||||
|
||||
/**
|
||||
* @var Result
|
||||
*/
|
||||
protected $resultPrototype = null;
|
||||
|
||||
/**
|
||||
* @var Profiler\ProfilerInterface
|
||||
*/
|
||||
protected $profiler = null;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $options = array(
|
||||
|
||||
);
|
||||
|
||||
/**
|
||||
* @param array|Connection|\oci8 $connection
|
||||
* @param null|Statement $statementPrototype
|
||||
* @param null|Result $resultPrototype
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct($connection, Statement $statementPrototype = null, Result $resultPrototype = null, array $options = array())
|
||||
{
|
||||
if (!$connection instanceof Connection) {
|
||||
$connection = new Connection($connection);
|
||||
}
|
||||
|
||||
$options = array_intersect_key(array_merge($this->options, $options), $this->options);
|
||||
|
||||
$this->registerConnection($connection);
|
||||
$this->registerStatementPrototype(($statementPrototype) ?: new Statement());
|
||||
$this->registerResultPrototype(($resultPrototype) ?: new Result());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Profiler\ProfilerInterface $profiler
|
||||
* @return Oci8
|
||||
*/
|
||||
public function setProfiler(Profiler\ProfilerInterface $profiler)
|
||||
{
|
||||
$this->profiler = $profiler;
|
||||
if ($this->connection instanceof Profiler\ProfilerAwareInterface) {
|
||||
$this->connection->setProfiler($profiler);
|
||||
}
|
||||
if ($this->statementPrototype instanceof Profiler\ProfilerAwareInterface) {
|
||||
$this->statementPrototype->setProfiler($profiler);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|Profiler\ProfilerInterface
|
||||
*/
|
||||
public function getProfiler()
|
||||
{
|
||||
return $this->profiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register connection
|
||||
*
|
||||
* @param Connection $connection
|
||||
* @return Oci8
|
||||
*/
|
||||
public function registerConnection(Connection $connection)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
$this->connection->setDriver($this); // needs access to driver to createStatement()
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register statement prototype
|
||||
*
|
||||
* @param Statement $statementPrototype
|
||||
* @return Oci8
|
||||
*/
|
||||
public function registerStatementPrototype(Statement $statementPrototype)
|
||||
{
|
||||
$this->statementPrototype = $statementPrototype;
|
||||
$this->statementPrototype->setDriver($this); // needs access to driver to createResult()
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|Statement
|
||||
*/
|
||||
public function getStatementPrototype()
|
||||
{
|
||||
return $this->statementPrototype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register result prototype
|
||||
*
|
||||
* @param Result $resultPrototype
|
||||
* @return Oci8
|
||||
*/
|
||||
public function registerResultPrototype(Result $resultPrototype)
|
||||
{
|
||||
$this->resultPrototype = $resultPrototype;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|Result
|
||||
*/
|
||||
public function getResultPrototype()
|
||||
{
|
||||
return $this->resultPrototype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get database platform name
|
||||
*
|
||||
* @param string $nameFormat
|
||||
* @return string
|
||||
*/
|
||||
public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE)
|
||||
{
|
||||
return 'Oracle';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check environment
|
||||
*/
|
||||
public function checkEnvironment()
|
||||
{
|
||||
if (!extension_loaded('oci8')) {
|
||||
throw new Exception\RuntimeException('The Oci8 extension is required for this adapter but the extension is not loaded');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Connection
|
||||
*/
|
||||
public function getConnection()
|
||||
{
|
||||
return $this->connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sqlOrResource
|
||||
* @return Statement
|
||||
*/
|
||||
public function createStatement($sqlOrResource = null)
|
||||
{
|
||||
$statement = clone $this->statementPrototype;
|
||||
if (is_resource($sqlOrResource) && get_resource_type($sqlOrResource) == 'oci8 statement') {
|
||||
$statement->setResource($sqlOrResource);
|
||||
} else {
|
||||
if (is_string($sqlOrResource)) {
|
||||
$statement->setSql($sqlOrResource);
|
||||
} elseif ($sqlOrResource !== null) {
|
||||
throw new Exception\InvalidArgumentException(
|
||||
'Oci8 only accepts an SQL string or a oci8 resource in ' . __FUNCTION__
|
||||
);
|
||||
}
|
||||
if (!$this->connection->isConnected()) {
|
||||
$this->connection->connect();
|
||||
}
|
||||
$statement->initialize($this->connection->getResource());
|
||||
}
|
||||
return $statement;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource $resource
|
||||
* @param null $isBuffered
|
||||
* @return Result
|
||||
*/
|
||||
public function createResult($resource, $isBuffered = null)
|
||||
{
|
||||
$result = clone $this->resultPrototype;
|
||||
$result->initialize($resource, $this->connection->getLastGeneratedValue(), $isBuffered);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPrepareType()
|
||||
{
|
||||
return self::PARAMETERIZATION_NAMED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $type
|
||||
* @return string
|
||||
*/
|
||||
public function formatParameterName($name, $type = null)
|
||||
{
|
||||
return ':' . $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getLastGeneratedValue()
|
||||
{
|
||||
return $this->getConnection()->getLastGeneratedValue();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,226 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Oci8;
|
||||
|
||||
use Iterator;
|
||||
use Zend\Db\Adapter\Driver\ResultInterface;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
|
||||
class Result implements Iterator, ResultInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
protected $resource = null;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $isBuffered = null;
|
||||
|
||||
/**
|
||||
* Cursor position
|
||||
* @var int
|
||||
*/
|
||||
protected $position = 0;
|
||||
|
||||
/**
|
||||
* Number of known rows
|
||||
* @var int
|
||||
*/
|
||||
protected $numberOfRows = -1;
|
||||
|
||||
/**
|
||||
* Is the current() operation already complete for this pointer position?
|
||||
* @var bool
|
||||
*/
|
||||
protected $currentComplete = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $currentData = false;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $statementBindValues = array('keys' => null, 'values' => array());
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
protected $generatedValue = null;
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
* @param resource $resource
|
||||
* @return Result
|
||||
*/
|
||||
public function initialize($resource /*, $generatedValue, $isBuffered = null*/)
|
||||
{
|
||||
if (!is_resource($resource) && get_resource_type($resource) !== 'oci8 statement') {
|
||||
throw new Exception\InvalidArgumentException('Invalid resource provided.');
|
||||
}
|
||||
$this->resource = $resource;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force buffering at driver level
|
||||
*
|
||||
* Oracle does not support this, to my knowledge (@ralphschindler)
|
||||
*
|
||||
* @throws Exception\RuntimeException
|
||||
*/
|
||||
public function buffer()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the result buffered?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isBuffered()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the resource
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is query result?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isQueryResult()
|
||||
{
|
||||
return (oci_num_fields($this->resource) > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get affected rows
|
||||
* @return int
|
||||
*/
|
||||
public function getAffectedRows()
|
||||
{
|
||||
return oci_num_rows($this->resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Current
|
||||
* @return mixed
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
if ($this->currentComplete == false) {
|
||||
if ($this->loadData() === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->currentData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load from oci8 result
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function loadData()
|
||||
{
|
||||
$this->currentComplete = true;
|
||||
$this->currentData = oci_fetch_assoc($this->resource);
|
||||
|
||||
if ($this->currentData !== false) {
|
||||
$this->position++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Next
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
return $this->loadData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Key
|
||||
* @return mixed
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewind
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
if ($this->position > 0) {
|
||||
throw new Exception\RuntimeException('Oci8 results cannot be rewound for multiple iterations');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Valid
|
||||
* @return bool
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
if ($this->currentComplete) {
|
||||
return ($this->currentData !== false);
|
||||
}
|
||||
|
||||
return $this->loadData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Count
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
// @todo OCI8 row count in Driver Result
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getFieldCount()
|
||||
{
|
||||
return oci_num_fields($this->resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getGeneratedValue()
|
||||
{
|
||||
// @todo OCI8 generated value in Driver Result
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,307 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Oci8;
|
||||
|
||||
use Zend\Db\Adapter\Driver\StatementInterface;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
use Zend\Db\Adapter\ParameterContainer;
|
||||
use Zend\Db\Adapter\Profiler;
|
||||
|
||||
class Statement implements StatementInterface, Profiler\ProfilerAwareInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
protected $oci8 = null;
|
||||
|
||||
/**
|
||||
* @var Oci8
|
||||
*/
|
||||
protected $driver = null;
|
||||
|
||||
/**
|
||||
* @var Profiler\ProfilerInterface
|
||||
*/
|
||||
protected $profiler = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $sql = '';
|
||||
|
||||
/**
|
||||
* Parameter container
|
||||
*
|
||||
* @var ParameterContainer
|
||||
*/
|
||||
protected $parameterContainer = null;
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
protected $resource = null;
|
||||
|
||||
/**
|
||||
* Is prepared
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isPrepared = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $bufferResults = false;
|
||||
|
||||
/**
|
||||
* Set driver
|
||||
*
|
||||
* @param Oci8 $driver
|
||||
* @return Statement
|
||||
*/
|
||||
public function setDriver($driver)
|
||||
{
|
||||
$this->driver = $driver;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Profiler\ProfilerInterface $profiler
|
||||
* @return Statement
|
||||
*/
|
||||
public function setProfiler(Profiler\ProfilerInterface $profiler)
|
||||
{
|
||||
$this->profiler = $profiler;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|Profiler\ProfilerInterface
|
||||
*/
|
||||
public function getProfiler()
|
||||
{
|
||||
return $this->profiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*
|
||||
* @param resource $oci8
|
||||
* @return Statement
|
||||
*/
|
||||
public function initialize($oci8)
|
||||
{
|
||||
$this->oci8 = $oci8;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set sql
|
||||
*
|
||||
* @param string $sql
|
||||
* @return Statement
|
||||
*/
|
||||
public function setSql($sql)
|
||||
{
|
||||
$this->sql = $sql;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Parameter container
|
||||
*
|
||||
* @param ParameterContainer $parameterContainer
|
||||
* @return Statement
|
||||
*/
|
||||
public function setParameterContainer(ParameterContainer $parameterContainer)
|
||||
{
|
||||
$this->parameterContainer = $parameterContainer;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get resource
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set resource
|
||||
*
|
||||
* @param resource $oci8Statement
|
||||
* @return Statement
|
||||
*/
|
||||
public function setResource($oci8Statement)
|
||||
{
|
||||
$type = oci_statement_type($oci8Statement);
|
||||
if (false === $type || 'UNKNOWN' == $type) {
|
||||
throw new Exception\InvalidArgumentException(sprintf(
|
||||
'Invalid statement provided to %s',
|
||||
__METHOD__
|
||||
));
|
||||
}
|
||||
$this->resource = $oci8Statement;
|
||||
$this->isPrepared = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sql
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSql()
|
||||
{
|
||||
return $this->sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ParameterContainer
|
||||
*/
|
||||
public function getParameterContainer()
|
||||
{
|
||||
return $this->parameterContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isPrepared()
|
||||
{
|
||||
return $this->isPrepared;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sql
|
||||
* @return Statement
|
||||
*/
|
||||
public function prepare($sql = null)
|
||||
{
|
||||
if ($this->isPrepared) {
|
||||
throw new Exception\RuntimeException('This statement has already been prepared');
|
||||
}
|
||||
|
||||
$sql = ($sql) ?: $this->sql;
|
||||
|
||||
// get oci8 statement resource
|
||||
$this->resource = oci_parse($this->oci8, $sql);
|
||||
|
||||
if (!$this->resource) {
|
||||
$e = oci_error($this->oci8);
|
||||
throw new Exception\InvalidQueryException(
|
||||
'Statement couldn\'t be produced with sql: ' . $sql,
|
||||
null,
|
||||
new Exception\ErrorException($e['message'], $e['code'])
|
||||
);
|
||||
}
|
||||
|
||||
$this->isPrepared = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @param ParameterContainer $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
public function execute($parameters = null)
|
||||
{
|
||||
if (!$this->isPrepared) {
|
||||
$this->prepare();
|
||||
}
|
||||
|
||||
/** START Standard ParameterContainer Merging Block */
|
||||
if (!$this->parameterContainer instanceof ParameterContainer) {
|
||||
if ($parameters instanceof ParameterContainer) {
|
||||
$this->parameterContainer = $parameters;
|
||||
$parameters = null;
|
||||
} else {
|
||||
$this->parameterContainer = new ParameterContainer();
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($parameters)) {
|
||||
$this->parameterContainer->setFromArray($parameters);
|
||||
}
|
||||
|
||||
if ($this->parameterContainer->count() > 0) {
|
||||
$this->bindParametersFromContainer();
|
||||
}
|
||||
/** END Standard ParameterContainer Merging Block */
|
||||
|
||||
if ($this->profiler) {
|
||||
$this->profiler->profilerStart($this);
|
||||
}
|
||||
|
||||
if ($this->driver->getConnection()->inTransaction()) {
|
||||
$ret = @oci_execute($this->resource, OCI_NO_AUTO_COMMIT);
|
||||
} else {
|
||||
$ret = @oci_execute($this->resource, OCI_COMMIT_ON_SUCCESS);
|
||||
}
|
||||
|
||||
if ($this->profiler) {
|
||||
$this->profiler->profilerFinish();
|
||||
}
|
||||
|
||||
if ($ret === false) {
|
||||
$e = oci_error($this->resource);
|
||||
throw new Exception\RuntimeException($e['message'], $e['code']);
|
||||
}
|
||||
|
||||
$result = $this->driver->createResult($this->resource);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind parameters from container
|
||||
*
|
||||
* @param ParameterContainer $pContainer
|
||||
*/
|
||||
protected function bindParametersFromContainer()
|
||||
{
|
||||
$parameters = $this->parameterContainer->getNamedArray();
|
||||
|
||||
foreach ($parameters as $name => &$value) {
|
||||
if ($this->parameterContainer->offsetHasErrata($name)) {
|
||||
switch ($this->parameterContainer->offsetGetErrata($name)) {
|
||||
case ParameterContainer::TYPE_NULL:
|
||||
$type = null;
|
||||
$value = null;
|
||||
break;
|
||||
case ParameterContainer::TYPE_DOUBLE:
|
||||
case ParameterContainer::TYPE_INTEGER:
|
||||
$type = SQLT_INT;
|
||||
if (is_string($value)) {
|
||||
$value = (int) $value;
|
||||
}
|
||||
break;
|
||||
case ParameterContainer::TYPE_BINARY:
|
||||
$type = SQLT_BIN;
|
||||
break;
|
||||
case ParameterContainer::TYPE_STRING:
|
||||
default:
|
||||
$type = SQLT_CHR;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$type = SQLT_CHR;
|
||||
}
|
||||
|
||||
oci_bind_by_name($this->resource, $name, $value, -1, $type);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,437 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Pdo;
|
||||
|
||||
use Zend\Db\Adapter\Driver\ConnectionInterface;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
use Zend\Db\Adapter\Profiler;
|
||||
|
||||
class Connection implements ConnectionInterface, Profiler\ProfilerAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var Pdo
|
||||
*/
|
||||
protected $driver = null;
|
||||
|
||||
/**
|
||||
* @var Profiler\ProfilerInterface
|
||||
*/
|
||||
protected $profiler = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $driverName = null;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $connectionParameters = array();
|
||||
|
||||
/**
|
||||
* @var \PDO
|
||||
*/
|
||||
protected $resource = null;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $inTransaction = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array|\PDO|null $connectionParameters
|
||||
* @throws Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct($connectionParameters = null)
|
||||
{
|
||||
if (is_array($connectionParameters)) {
|
||||
$this->setConnectionParameters($connectionParameters);
|
||||
} elseif ($connectionParameters instanceof \PDO) {
|
||||
$this->setResource($connectionParameters);
|
||||
} elseif (null !== $connectionParameters) {
|
||||
throw new Exception\InvalidArgumentException('$connection must be an array of parameters, a PDO object or null');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set driver
|
||||
*
|
||||
* @param Pdo $driver
|
||||
* @return Connection
|
||||
*/
|
||||
public function setDriver(Pdo $driver)
|
||||
{
|
||||
$this->driver = $driver;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Profiler\ProfilerInterface $profiler
|
||||
* @return Connection
|
||||
*/
|
||||
public function setProfiler(Profiler\ProfilerInterface $profiler)
|
||||
{
|
||||
$this->profiler = $profiler;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|Profiler\ProfilerInterface
|
||||
*/
|
||||
public function getProfiler()
|
||||
{
|
||||
return $this->profiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get driver name
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getDriverName()
|
||||
{
|
||||
return $this->driverName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set connection parameters
|
||||
*
|
||||
* @param array $connectionParameters
|
||||
* @return void
|
||||
*/
|
||||
public function setConnectionParameters(array $connectionParameters)
|
||||
{
|
||||
$this->connectionParameters = $connectionParameters;
|
||||
if (isset($connectionParameters['dsn'])) {
|
||||
$this->driverName = substr($connectionParameters['dsn'], 0,
|
||||
strpos($connectionParameters['dsn'], ':')
|
||||
);
|
||||
} elseif (isset($connectionParameters['pdodriver'])) {
|
||||
$this->driverName = strtolower($connectionParameters['pdodriver']);
|
||||
} elseif (isset($connectionParameters['driver'])) {
|
||||
$this->driverName = strtolower(substr(
|
||||
str_replace(array('-', '_', ' '), '', $connectionParameters['driver']),
|
||||
3
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get connection parameters
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getConnectionParameters()
|
||||
{
|
||||
return $this->connectionParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current schema
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCurrentSchema()
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
switch ($this->driverName) {
|
||||
case 'mysql':
|
||||
$sql = 'SELECT DATABASE()';
|
||||
break;
|
||||
case 'sqlite':
|
||||
return 'main';
|
||||
case 'pgsql':
|
||||
default:
|
||||
$sql = 'SELECT CURRENT_SCHEMA';
|
||||
break;
|
||||
}
|
||||
|
||||
/** @var $result \PDOStatement */
|
||||
$result = $this->resource->query($sql);
|
||||
if ($result instanceof \PDOStatement) {
|
||||
return $result->fetchColumn();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set resource
|
||||
*
|
||||
* @param \PDO $resource
|
||||
* @return Connection
|
||||
*/
|
||||
public function setResource(\PDO $resource)
|
||||
{
|
||||
$this->resource = $resource;
|
||||
$this->driverName = strtolower($this->resource->getAttribute(\PDO::ATTR_DRIVER_NAME));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get resource
|
||||
*
|
||||
* @return \PDO
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect
|
||||
*
|
||||
* @return Connection
|
||||
* @throws Exception\InvalidConnectionParametersException
|
||||
* @throws Exception\RuntimeException
|
||||
*/
|
||||
public function connect()
|
||||
{
|
||||
if ($this->resource) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$dsn = $username = $password = $hostname = $database = null;
|
||||
$options = array();
|
||||
foreach ($this->connectionParameters as $key => $value) {
|
||||
switch (strtolower($key)) {
|
||||
case 'dsn':
|
||||
$dsn = $value;
|
||||
break;
|
||||
case 'driver':
|
||||
$value = strtolower($value);
|
||||
if (strpos($value, 'pdo') === 0) {
|
||||
$pdoDriver = strtolower(substr(str_replace(array('-', '_', ' '), '', $value), 3));
|
||||
}
|
||||
break;
|
||||
case 'pdodriver':
|
||||
$pdoDriver = (string) $value;
|
||||
break;
|
||||
case 'user':
|
||||
case 'username':
|
||||
$username = (string) $value;
|
||||
break;
|
||||
case 'pass':
|
||||
case 'password':
|
||||
$password = (string) $value;
|
||||
break;
|
||||
case 'host':
|
||||
case 'hostname':
|
||||
$hostname = (string) $value;
|
||||
break;
|
||||
case 'port':
|
||||
$port = (int) $value;
|
||||
break;
|
||||
case 'database':
|
||||
case 'dbname':
|
||||
$database = (string) $value;
|
||||
break;
|
||||
case 'driver_options':
|
||||
case 'options':
|
||||
$value = (array) $value;
|
||||
$options = array_diff_key($options, $value) + $value;
|
||||
break;
|
||||
default:
|
||||
$options[$key] = $value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($dsn) && isset($pdoDriver)) {
|
||||
$dsn = array();
|
||||
switch ($pdoDriver) {
|
||||
case 'sqlite':
|
||||
$dsn[] = $database;
|
||||
break;
|
||||
default:
|
||||
if (isset($database)) {
|
||||
$dsn[] = "dbname={$database}";
|
||||
}
|
||||
if (isset($hostname)) {
|
||||
$dsn[] = "host={$hostname}";
|
||||
}
|
||||
if (isset($port)) {
|
||||
$dsn[] = "port={$port}";
|
||||
}
|
||||
break;
|
||||
}
|
||||
$dsn = $pdoDriver . ':' . implode(';', $dsn);
|
||||
} elseif (!isset($dsn)) {
|
||||
throw new Exception\InvalidConnectionParametersException(
|
||||
'A dsn was not provided or could not be constructed from your parameters',
|
||||
$this->connectionParameters
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->resource = new \PDO($dsn, $username, $password, $options);
|
||||
$this->resource->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||
$this->driverName = strtolower($this->resource->getAttribute(\PDO::ATTR_DRIVER_NAME));
|
||||
} catch (\PDOException $e) {
|
||||
$code = $e->getCode();
|
||||
if (!is_long($code)) {
|
||||
$code = null;
|
||||
}
|
||||
throw new Exception\RuntimeException('Connect Error: ' . $e->getMessage(), $code, $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is connected
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isConnected()
|
||||
{
|
||||
return ($this->resource instanceof \PDO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect
|
||||
*
|
||||
* @return Connection
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
if ($this->isConnected()) {
|
||||
$this->resource = null;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin transaction
|
||||
*
|
||||
* @return Connection
|
||||
*/
|
||||
public function beginTransaction()
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
$this->resource->beginTransaction();
|
||||
$this->inTransaction = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit
|
||||
*
|
||||
* @return Connection
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
$this->resource->commit();
|
||||
$this->inTransaction = false;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rollback
|
||||
*
|
||||
* @return Connection
|
||||
* @throws Exception\RuntimeException
|
||||
*/
|
||||
public function rollback()
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
throw new Exception\RuntimeException('Must be connected before you can rollback');
|
||||
}
|
||||
|
||||
if (!$this->inTransaction) {
|
||||
throw new Exception\RuntimeException('Must call beginTransaction() before you can rollback');
|
||||
}
|
||||
|
||||
$this->resource->rollBack();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @param $sql
|
||||
* @return Result
|
||||
* @throws Exception\InvalidQueryException
|
||||
*/
|
||||
public function execute($sql)
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
if ($this->profiler) {
|
||||
$this->profiler->profilerStart($sql);
|
||||
}
|
||||
|
||||
$resultResource = $this->resource->query($sql);
|
||||
|
||||
if ($this->profiler) {
|
||||
$this->profiler->profilerFinish($sql);
|
||||
}
|
||||
|
||||
if ($resultResource === false) {
|
||||
$errorInfo = $this->resource->errorInfo();
|
||||
throw new Exception\InvalidQueryException($errorInfo[2]);
|
||||
}
|
||||
|
||||
$result = $this->driver->createResult($resultResource, $sql);
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare
|
||||
*
|
||||
* @param string $sql
|
||||
* @return Statement
|
||||
*/
|
||||
public function prepare($sql)
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
$statement = $this->driver->createStatement($sql);
|
||||
return $statement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last generated id
|
||||
*
|
||||
* @param string $name
|
||||
* @return int|null|false
|
||||
*/
|
||||
public function getLastGeneratedValue($name = null)
|
||||
{
|
||||
if ($name === null && $this->driverName == 'pgsql') {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return $this->resource->lastInsertId($name);
|
||||
} catch (\Exception $e) {
|
||||
// do nothing
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Pdo\Feature;
|
||||
|
||||
use Zend\Db\Adapter\Driver\Feature\AbstractFeature;
|
||||
use Zend\Db\Adapter\Driver\Pdo;
|
||||
|
||||
/**
|
||||
* OracleRowCounter
|
||||
*/
|
||||
class OracleRowCounter extends AbstractFeature
|
||||
{
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'OracleRowCounter';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Zend\Db\Adapter\Driver\Pdo\Statement $statement
|
||||
* @return int
|
||||
*/
|
||||
public function getCountForStatement(Pdo\Statement $statement)
|
||||
{
|
||||
$countStmt = clone $statement;
|
||||
$sql = $statement->getSql();
|
||||
if ($sql == '' || stripos($sql, 'select') === false) {
|
||||
return null;
|
||||
}
|
||||
$countSql = 'SELECT COUNT(*) as "count" FROM (' . $sql . ')';
|
||||
$countStmt->prepare($countSql);
|
||||
$result = $countStmt->execute();
|
||||
$countRow = $result->getResource()->fetch(\PDO::FETCH_ASSOC);
|
||||
unset($statement, $result);
|
||||
return $countRow['count'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sql
|
||||
* @return null|int
|
||||
*/
|
||||
public function getCountForSql($sql)
|
||||
{
|
||||
if (!stripos($sql, 'select')) {
|
||||
return null;
|
||||
}
|
||||
$countSql = 'SELECT COUNT(*) as count FROM (' . $sql . ')';
|
||||
/** @var $pdo \PDO */
|
||||
$pdo = $this->pdoDriver->getConnection()->getResource();
|
||||
$result = $pdo->query($countSql);
|
||||
$countRow = $result->fetch(\PDO::FETCH_ASSOC);
|
||||
return $countRow['count'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $context
|
||||
* @return closure
|
||||
*/
|
||||
public function getRowCountClosure($context)
|
||||
{
|
||||
$oracleRowCounter = $this;
|
||||
return function () use ($oracleRowCounter, $context) {
|
||||
/** @var $oracleRowCounter OracleRowCounter */
|
||||
return ($context instanceof Pdo\Statement)
|
||||
? $oracleRowCounter->getCountForStatement($context)
|
||||
: $oracleRowCounter->getCountForSql($context);
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Pdo\Feature;
|
||||
|
||||
use Zend\Db\Adapter\Driver\Feature\AbstractFeature;
|
||||
use Zend\Db\Adapter\Driver\Pdo;
|
||||
|
||||
/**
|
||||
* SqliteRowCounter
|
||||
*/
|
||||
class SqliteRowCounter extends AbstractFeature
|
||||
{
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'SqliteRowCounter';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Zend\Db\Adapter\Driver\Pdo\Statement $statement
|
||||
* @return int
|
||||
*/
|
||||
public function getCountForStatement(Pdo\Statement $statement)
|
||||
{
|
||||
$countStmt = clone $statement;
|
||||
$sql = $statement->getSql();
|
||||
if ($sql == '' || stripos($sql, 'select') === false) {
|
||||
return null;
|
||||
}
|
||||
$countSql = 'SELECT COUNT(*) as "count" FROM (' . $sql . ')';
|
||||
$countStmt->prepare($countSql);
|
||||
$result = $countStmt->execute();
|
||||
$countRow = $result->getResource()->fetch(\PDO::FETCH_ASSOC);
|
||||
unset($statement, $result);
|
||||
return $countRow['count'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sql
|
||||
* @return null|int
|
||||
*/
|
||||
public function getCountForSql($sql)
|
||||
{
|
||||
if (!stripos($sql, 'select')) {
|
||||
return null;
|
||||
}
|
||||
$countSql = 'SELECT COUNT(*) as count FROM (' . $sql . ')';
|
||||
/** @var $pdo \PDO */
|
||||
$pdo = $this->pdoDriver->getConnection()->getResource();
|
||||
$result = $pdo->query($countSql);
|
||||
$countRow = $result->fetch(\PDO::FETCH_ASSOC);
|
||||
return $countRow['count'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $context
|
||||
* @return closure
|
||||
*/
|
||||
public function getRowCountClosure($context)
|
||||
{
|
||||
$sqliteRowCounter = $this;
|
||||
return function () use ($sqliteRowCounter, $context) {
|
||||
/** @var $sqliteRowCounter SqliteRowCounter */
|
||||
return ($context instanceof Pdo\Statement)
|
||||
? $sqliteRowCounter->getCountForStatement($context)
|
||||
: $sqliteRowCounter->getCountForSql($context);
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,309 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Pdo;
|
||||
|
||||
use PDOStatement;
|
||||
use Zend\Db\Adapter\Driver\DriverInterface;
|
||||
use Zend\Db\Adapter\Driver\Feature\AbstractFeature;
|
||||
use Zend\Db\Adapter\Driver\Feature\DriverFeatureInterface;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
use Zend\Db\Adapter\Profiler;
|
||||
|
||||
class Pdo implements DriverInterface, DriverFeatureInterface, Profiler\ProfilerAwareInterface
|
||||
{
|
||||
/**
|
||||
* @const
|
||||
*/
|
||||
const FEATURES_DEFAULT = 'default';
|
||||
|
||||
/**
|
||||
* @var Connection
|
||||
*/
|
||||
protected $connection = null;
|
||||
|
||||
/**
|
||||
* @var Statement
|
||||
*/
|
||||
protected $statementPrototype = null;
|
||||
|
||||
/**
|
||||
* @var Result
|
||||
*/
|
||||
protected $resultPrototype = null;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $features = array();
|
||||
|
||||
/**
|
||||
* @param array|Connection|\PDO $connection
|
||||
* @param null|Statement $statementPrototype
|
||||
* @param null|Result $resultPrototype
|
||||
* @param string $features
|
||||
*/
|
||||
public function __construct($connection, Statement $statementPrototype = null, Result $resultPrototype = null, $features = self::FEATURES_DEFAULT)
|
||||
{
|
||||
if (!$connection instanceof Connection) {
|
||||
$connection = new Connection($connection);
|
||||
}
|
||||
|
||||
$this->registerConnection($connection);
|
||||
$this->registerStatementPrototype(($statementPrototype) ?: new Statement());
|
||||
$this->registerResultPrototype(($resultPrototype) ?: new Result());
|
||||
if (is_array($features)) {
|
||||
foreach ($features as $name => $feature) {
|
||||
$this->addFeature($name, $feature);
|
||||
}
|
||||
} elseif ($features instanceof AbstractFeature) {
|
||||
$this->addFeature($features->getName(), $features);
|
||||
} elseif ($features === self::FEATURES_DEFAULT) {
|
||||
$this->setupDefaultFeatures();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Profiler\ProfilerInterface $profiler
|
||||
* @return Pdo
|
||||
*/
|
||||
public function setProfiler(Profiler\ProfilerInterface $profiler)
|
||||
{
|
||||
$this->profiler = $profiler;
|
||||
if ($this->connection instanceof Profiler\ProfilerAwareInterface) {
|
||||
$this->connection->setProfiler($profiler);
|
||||
}
|
||||
if ($this->statementPrototype instanceof Profiler\ProfilerAwareInterface) {
|
||||
$this->statementPrototype->setProfiler($profiler);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|Profiler\ProfilerInterface
|
||||
*/
|
||||
public function getProfiler()
|
||||
{
|
||||
return $this->profiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register connection
|
||||
*
|
||||
* @param Connection $connection
|
||||
* @return Pdo
|
||||
*/
|
||||
public function registerConnection(Connection $connection)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
$this->connection->setDriver($this);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register statement prototype
|
||||
*
|
||||
* @param Statement $statementPrototype
|
||||
*/
|
||||
public function registerStatementPrototype(Statement $statementPrototype)
|
||||
{
|
||||
$this->statementPrototype = $statementPrototype;
|
||||
$this->statementPrototype->setDriver($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register result prototype
|
||||
*
|
||||
* @param Result $resultPrototype
|
||||
*/
|
||||
public function registerResultPrototype(Result $resultPrototype)
|
||||
{
|
||||
$this->resultPrototype = $resultPrototype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add feature
|
||||
*
|
||||
* @param string $name
|
||||
* @param AbstractFeature $feature
|
||||
* @return Pdo
|
||||
*/
|
||||
public function addFeature($name, $feature)
|
||||
{
|
||||
if ($feature instanceof AbstractFeature) {
|
||||
$name = $feature->getName(); // overwrite the name, just in case
|
||||
$feature->setDriver($this);
|
||||
}
|
||||
$this->features[$name] = $feature;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the default features for Pdo
|
||||
*
|
||||
* @return Pdo
|
||||
*/
|
||||
public function setupDefaultFeatures()
|
||||
{
|
||||
$driverName = $this->connection->getDriverName();
|
||||
if ($driverName == 'sqlite') {
|
||||
$this->addFeature(null, new Feature\SqliteRowCounter);
|
||||
} elseif ($driverName == 'oci') {
|
||||
$this->addFeature(null, new Feature\OracleRowCounter);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get feature
|
||||
*
|
||||
* @param $name
|
||||
* @return AbstractFeature|false
|
||||
*/
|
||||
public function getFeature($name)
|
||||
{
|
||||
if (isset($this->features[$name])) {
|
||||
return $this->features[$name];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get database platform name
|
||||
*
|
||||
* @param string $nameFormat
|
||||
* @return string
|
||||
*/
|
||||
public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE)
|
||||
{
|
||||
$name = $this->getConnection()->getDriverName();
|
||||
if ($nameFormat == self::NAME_FORMAT_CAMELCASE) {
|
||||
switch ($name) {
|
||||
case 'pgsql':
|
||||
return 'Postgresql';
|
||||
case 'oci':
|
||||
return 'Oracle';
|
||||
|
||||
default:
|
||||
return ucfirst($name);
|
||||
}
|
||||
} else {
|
||||
switch ($name) {
|
||||
case 'sqlite':
|
||||
return 'SQLite';
|
||||
case 'mysql':
|
||||
return 'MySQL';
|
||||
case 'pgsql':
|
||||
return 'PostgreSQL';
|
||||
case 'oci':
|
||||
return 'Oracle';
|
||||
default:
|
||||
return ucfirst($name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check environment
|
||||
*/
|
||||
public function checkEnvironment()
|
||||
{
|
||||
if (!extension_loaded('PDO')) {
|
||||
throw new Exception\RuntimeException('The PDO extension is required for this adapter but the extension is not loaded');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Connection
|
||||
*/
|
||||
public function getConnection()
|
||||
{
|
||||
return $this->connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|PDOStatement $sqlOrResource
|
||||
* @return Statement
|
||||
*/
|
||||
public function createStatement($sqlOrResource = null)
|
||||
{
|
||||
$statement = clone $this->statementPrototype;
|
||||
if ($sqlOrResource instanceof PDOStatement) {
|
||||
$statement->setResource($sqlOrResource);
|
||||
} else {
|
||||
if (is_string($sqlOrResource)) {
|
||||
$statement->setSql($sqlOrResource);
|
||||
}
|
||||
if (!$this->connection->isConnected()) {
|
||||
$this->connection->connect();
|
||||
}
|
||||
$statement->initialize($this->connection->getResource());
|
||||
}
|
||||
return $statement;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource $resource
|
||||
* @param mixed $context
|
||||
* @return Result
|
||||
*/
|
||||
public function createResult($resource, $context = null)
|
||||
{
|
||||
$result = clone $this->resultPrototype;
|
||||
$rowCount = null;
|
||||
|
||||
// special feature, sqlite PDO counter
|
||||
if ($this->connection->getDriverName() == 'sqlite'
|
||||
&& ($sqliteRowCounter = $this->getFeature('SqliteRowCounter'))
|
||||
&& $resource->columnCount() > 0) {
|
||||
$rowCount = $sqliteRowCounter->getRowCountClosure($context);
|
||||
}
|
||||
|
||||
// special feature, oracle PDO counter
|
||||
if ($this->connection->getDriverName() == 'oci'
|
||||
&& ($oracleRowCounter = $this->getFeature('OracleRowCounter'))
|
||||
&& $resource->columnCount() > 0) {
|
||||
$rowCount = $oracleRowCounter->getRowCountClosure($context);
|
||||
}
|
||||
|
||||
|
||||
$result->initialize($resource, $this->connection->getLastGeneratedValue(), $rowCount);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPrepareType()
|
||||
{
|
||||
return self::PARAMETERIZATION_NAMED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string|null $type
|
||||
* @return string
|
||||
*/
|
||||
public function formatParameterName($name, $type = null)
|
||||
{
|
||||
if ($type == null && !is_numeric($name) || $type == self::PARAMETERIZATION_NAMED) {
|
||||
return ':' . $name;
|
||||
}
|
||||
|
||||
return '?';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getLastGeneratedValue($name = null)
|
||||
{
|
||||
return $this->connection->getLastGeneratedValue($name);
|
||||
}
|
||||
}
|
@ -0,0 +1,225 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Pdo;
|
||||
|
||||
use Iterator;
|
||||
use PDOStatement;
|
||||
use Zend\Db\Adapter\Driver\ResultInterface;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
|
||||
class Result implements Iterator, ResultInterface
|
||||
{
|
||||
|
||||
const STATEMENT_MODE_SCROLLABLE = 'scrollable';
|
||||
const STATEMENT_MODE_FORWARD = 'forward';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $statementMode = self::STATEMENT_MODE_FORWARD;
|
||||
|
||||
/**
|
||||
* @var \PDOStatement
|
||||
*/
|
||||
protected $resource = null;
|
||||
|
||||
/**
|
||||
* @var array Result options
|
||||
*/
|
||||
protected $options;
|
||||
|
||||
/**
|
||||
* Is the current complete?
|
||||
* @var bool
|
||||
*/
|
||||
protected $currentComplete = false;
|
||||
|
||||
/**
|
||||
* Track current item in recordset
|
||||
* @var mixed
|
||||
*/
|
||||
protected $currentData = null;
|
||||
|
||||
/**
|
||||
* Current position of scrollable statement
|
||||
* @var int
|
||||
*/
|
||||
protected $position = -1;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
protected $generatedValue = null;
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
protected $rowCount = null;
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*
|
||||
* @param PDOStatement $resource
|
||||
* @param $generatedValue
|
||||
* @param int $rowCount
|
||||
* @return Result
|
||||
*/
|
||||
public function initialize(PDOStatement $resource, $generatedValue, $rowCount = null)
|
||||
{
|
||||
$this->resource = $resource;
|
||||
$this->generatedValue = $generatedValue;
|
||||
$this->rowCount = $rowCount;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
public function buffer()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool|null
|
||||
*/
|
||||
public function isBuffered()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get resource
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data
|
||||
* @return array
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
if ($this->currentComplete) {
|
||||
return $this->currentData;
|
||||
}
|
||||
|
||||
$this->currentData = $this->resource->fetch(\PDO::FETCH_ASSOC);
|
||||
return $this->currentData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Next
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
$this->currentData = $this->resource->fetch(\PDO::FETCH_ASSOC);
|
||||
$this->currentComplete = true;
|
||||
$this->position++;
|
||||
return $this->currentData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Key
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception\RuntimeException
|
||||
* @return void
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
if ($this->statementMode == self::STATEMENT_MODE_FORWARD && $this->position > 0) {
|
||||
throw new Exception\RuntimeException(
|
||||
'This result is a forward only result set, calling rewind() after moving forward is not supported'
|
||||
);
|
||||
}
|
||||
$this->currentData = $this->resource->fetch(\PDO::FETCH_ASSOC);
|
||||
$this->currentComplete = true;
|
||||
$this->position = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Valid
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return ($this->currentData !== false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
if (is_int($this->rowCount)) {
|
||||
return $this->rowCount;
|
||||
}
|
||||
if ($this->rowCount instanceof \Closure) {
|
||||
$this->rowCount = (int) call_user_func($this->rowCount);
|
||||
} else {
|
||||
$this->rowCount = (int) $this->resource->rowCount();
|
||||
}
|
||||
return $this->rowCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getFieldCount()
|
||||
{
|
||||
return $this->resource->columnCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is query result
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isQueryResult()
|
||||
{
|
||||
return ($this->resource->columnCount() > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get affected rows
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getAffectedRows()
|
||||
{
|
||||
return $this->resource->rowCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getGeneratedValue()
|
||||
{
|
||||
return $this->generatedValue;
|
||||
}
|
||||
}
|
@ -0,0 +1,306 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Pdo;
|
||||
|
||||
use Zend\Db\Adapter\Driver\StatementInterface;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
use Zend\Db\Adapter\ParameterContainer;
|
||||
use Zend\Db\Adapter\Profiler;
|
||||
|
||||
class Statement implements StatementInterface, Profiler\ProfilerAwareInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var \PDO
|
||||
*/
|
||||
protected $pdo = null;
|
||||
|
||||
/**
|
||||
* @var Profiler\ProfilerInterface
|
||||
*/
|
||||
protected $profiler = null;
|
||||
|
||||
/**
|
||||
* @var Pdo
|
||||
*/
|
||||
protected $driver = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $sql = '';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isQuery = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var ParameterContainer
|
||||
*/
|
||||
protected $parameterContainer = null;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $parametersBound = false;
|
||||
|
||||
/**
|
||||
* @var \PDOStatement
|
||||
*/
|
||||
protected $resource = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isPrepared = false;
|
||||
|
||||
/**
|
||||
* Set driver
|
||||
*
|
||||
* @param Pdo $driver
|
||||
* @return Statement
|
||||
*/
|
||||
public function setDriver(Pdo $driver)
|
||||
{
|
||||
$this->driver = $driver;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Profiler\ProfilerInterface $profiler
|
||||
* @return Statement
|
||||
*/
|
||||
public function setProfiler(Profiler\ProfilerInterface $profiler)
|
||||
{
|
||||
$this->profiler = $profiler;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|Profiler\ProfilerInterface
|
||||
*/
|
||||
public function getProfiler()
|
||||
{
|
||||
return $this->profiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*
|
||||
* @param \PDO $connectionResource
|
||||
* @return Statement
|
||||
*/
|
||||
public function initialize(\PDO $connectionResource)
|
||||
{
|
||||
$this->pdo = $connectionResource;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set resource
|
||||
*
|
||||
* @param \PDOStatement $pdoStatement
|
||||
* @return Statement
|
||||
*/
|
||||
public function setResource(\PDOStatement $pdoStatement)
|
||||
{
|
||||
$this->resource = $pdoStatement;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get resource
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set sql
|
||||
*
|
||||
* @param string $sql
|
||||
* @return Statement
|
||||
*/
|
||||
public function setSql($sql)
|
||||
{
|
||||
$this->sql = $sql;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sql
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSql()
|
||||
{
|
||||
return $this->sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ParameterContainer $parameterContainer
|
||||
* @return Statement
|
||||
*/
|
||||
public function setParameterContainer(ParameterContainer $parameterContainer)
|
||||
{
|
||||
$this->parameterContainer = $parameterContainer;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ParameterContainer
|
||||
*/
|
||||
public function getParameterContainer()
|
||||
{
|
||||
return $this->parameterContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sql
|
||||
* @throws Exception\RuntimeException
|
||||
*/
|
||||
public function prepare($sql = null)
|
||||
{
|
||||
if ($this->isPrepared) {
|
||||
throw new Exception\RuntimeException('This statement has been prepared already');
|
||||
}
|
||||
|
||||
if ($sql == null) {
|
||||
$sql = $this->sql;
|
||||
}
|
||||
|
||||
$this->resource = $this->pdo->prepare($sql);
|
||||
|
||||
if ($this->resource === false) {
|
||||
$error = $this->pdo->errorInfo();
|
||||
throw new Exception\RuntimeException($error[2]);
|
||||
}
|
||||
|
||||
$this->isPrepared = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isPrepared()
|
||||
{
|
||||
return $this->isPrepared;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $parameters
|
||||
* @throws Exception\InvalidQueryException
|
||||
* @return Result
|
||||
*/
|
||||
public function execute($parameters = null)
|
||||
{
|
||||
if (!$this->isPrepared) {
|
||||
$this->prepare();
|
||||
}
|
||||
|
||||
/** START Standard ParameterContainer Merging Block */
|
||||
if (!$this->parameterContainer instanceof ParameterContainer) {
|
||||
if ($parameters instanceof ParameterContainer) {
|
||||
$this->parameterContainer = $parameters;
|
||||
$parameters = null;
|
||||
} else {
|
||||
$this->parameterContainer = new ParameterContainer();
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($parameters)) {
|
||||
$this->parameterContainer->setFromArray($parameters);
|
||||
}
|
||||
|
||||
if ($this->parameterContainer->count() > 0) {
|
||||
$this->bindParametersFromContainer();
|
||||
}
|
||||
/** END Standard ParameterContainer Merging Block */
|
||||
|
||||
if ($this->profiler) {
|
||||
$this->profiler->profilerStart($this);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->resource->execute();
|
||||
} catch (\PDOException $e) {
|
||||
if ($this->profiler) {
|
||||
$this->profiler->profilerFinish();
|
||||
}
|
||||
throw new Exception\InvalidQueryException('Statement could not be executed', null, $e);
|
||||
}
|
||||
|
||||
if ($this->profiler) {
|
||||
$this->profiler->profilerFinish();
|
||||
}
|
||||
|
||||
$result = $this->driver->createResult($this->resource, $this);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind parameters from container
|
||||
*/
|
||||
protected function bindParametersFromContainer()
|
||||
{
|
||||
if ($this->parametersBound) {
|
||||
return;
|
||||
}
|
||||
|
||||
$parameters = $this->parameterContainer->getNamedArray();
|
||||
foreach ($parameters as $name => &$value) {
|
||||
$type = \PDO::PARAM_STR;
|
||||
if ($this->parameterContainer->offsetHasErrata($name)) {
|
||||
switch ($this->parameterContainer->offsetGetErrata($name)) {
|
||||
case ParameterContainer::TYPE_INTEGER:
|
||||
$type = \PDO::PARAM_INT;
|
||||
break;
|
||||
case ParameterContainer::TYPE_NULL:
|
||||
$type = \PDO::PARAM_NULL;
|
||||
break;
|
||||
case ParameterContainer::TYPE_LOB:
|
||||
$type = \PDO::PARAM_LOB;
|
||||
break;
|
||||
case (is_bool($value)):
|
||||
$type = \PDO::PARAM_BOOL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// parameter is named or positional, value is reference
|
||||
$parameter = is_int($name) ? ($name + 1) : $name;
|
||||
$this->resource->bindParam($parameter, $value, $type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a deep clone
|
||||
* @return Statement A cloned statement
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$this->isPrepared = false;
|
||||
$this->parametersBound = false;
|
||||
$this->resource = null;
|
||||
if ($this->parameterContainer) {
|
||||
$this->parameterContainer = clone $this->parameterContainer;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,303 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Pgsql;
|
||||
|
||||
use Zend\Db\Adapter\Driver\ConnectionInterface;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
use Zend\Db\Adapter\Profiler;
|
||||
|
||||
class Connection implements ConnectionInterface, Profiler\ProfilerAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var Pgsql
|
||||
*/
|
||||
protected $driver = null;
|
||||
|
||||
/**
|
||||
* @var Profiler\ProfilerInterface
|
||||
*/
|
||||
protected $profiler = null;
|
||||
|
||||
/**
|
||||
* Connection parameters
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $connectionParameters = array();
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
protected $resource = null;
|
||||
|
||||
/**
|
||||
* In transaction
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $inTransaction = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param resource|array|null $connectionInfo
|
||||
*/
|
||||
public function __construct($connectionInfo = null)
|
||||
{
|
||||
if (is_array($connectionInfo)) {
|
||||
$this->setConnectionParameters($connectionInfo);
|
||||
} elseif (is_resource($connectionInfo)) {
|
||||
$this->setResource($connectionInfo);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set connection parameters
|
||||
*
|
||||
* @param array $connectionParameters
|
||||
* @return Connection
|
||||
*/
|
||||
public function setConnectionParameters(array $connectionParameters)
|
||||
{
|
||||
$this->connectionParameters = $connectionParameters;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set driver
|
||||
*
|
||||
* @param Pgsql $driver
|
||||
* @return Connection
|
||||
*/
|
||||
public function setDriver(Pgsql $driver)
|
||||
{
|
||||
$this->driver = $driver;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Profiler\ProfilerInterface $profiler
|
||||
* @return Connection
|
||||
*/
|
||||
public function setProfiler(Profiler\ProfilerInterface $profiler)
|
||||
{
|
||||
$this->profiler = $profiler;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|Profiler\ProfilerInterface
|
||||
*/
|
||||
public function getProfiler()
|
||||
{
|
||||
return $this->profiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set resource
|
||||
*
|
||||
* @param resource $resource
|
||||
* @return Connection
|
||||
*/
|
||||
public function setResource($resource)
|
||||
{
|
||||
$this->resource = $resource;
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current schema
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getCurrentSchema()
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
$result = pg_query($this->resource, 'SELECT CURRENT_SCHEMA AS "currentschema"');
|
||||
if ($result == false) {
|
||||
return null;
|
||||
}
|
||||
return pg_fetch_result($result, 0, 'currentschema');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get resource
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to the database
|
||||
*
|
||||
* @return Connection
|
||||
* @throws Exception\RuntimeException on failure
|
||||
*/
|
||||
public function connect()
|
||||
{
|
||||
if (is_resource($this->resource)) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
// localize
|
||||
$p = $this->connectionParameters;
|
||||
|
||||
// given a list of key names, test for existence in $p
|
||||
$findParameterValue = function (array $names) use ($p) {
|
||||
foreach ($names as $name) {
|
||||
if (isset($p[$name])) {
|
||||
return $p[$name];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
$connection = array();
|
||||
$connection['host'] = $findParameterValue(array('hostname', 'host'));
|
||||
$connection['user'] = $findParameterValue(array('username', 'user'));
|
||||
$connection['password'] = $findParameterValue(array('password', 'passwd', 'pw'));
|
||||
$connection['dbname'] = $findParameterValue(array('database', 'dbname', 'db', 'schema'));
|
||||
$connection['port'] = (isset($p['port'])) ? (int) $p['port'] : null;
|
||||
$connection['socket'] = (isset($p['socket'])) ? $p['socket'] : null;
|
||||
|
||||
$connection = array_filter($connection); // remove nulls
|
||||
$connection = http_build_query($connection, null, ' '); // @link http://php.net/pg_connect
|
||||
|
||||
set_error_handler(function ($number, $string) {
|
||||
throw new Exception\RuntimeException(
|
||||
__METHOD__ . ': Unable to connect to database', null, new Exception\ErrorException($string, $number)
|
||||
);
|
||||
});
|
||||
$this->resource = pg_connect($connection);
|
||||
restore_error_handler();
|
||||
|
||||
if ($this->resource === false) {
|
||||
throw new Exception\RuntimeException(sprintf(
|
||||
'%s: Unable to connect to database',
|
||||
__METHOD__
|
||||
));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isConnected()
|
||||
{
|
||||
return (is_resource($this->resource));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
pg_close($this->resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function beginTransaction()
|
||||
{
|
||||
if ($this->inTransaction) {
|
||||
throw new Exception\RuntimeException('Nested transactions are not supported');
|
||||
}
|
||||
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
pg_query($this->resource, 'BEGIN');
|
||||
$this->inTransaction = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
if (!$this->inTransaction) {
|
||||
return; // We ignore attempts to commit non-existing transaction
|
||||
}
|
||||
|
||||
pg_query($this->resource, 'COMMIT');
|
||||
$this->inTransaction = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function rollback()
|
||||
{
|
||||
if (!$this->inTransaction) {
|
||||
return;
|
||||
}
|
||||
|
||||
pg_query($this->resource, 'ROLLBACK');
|
||||
$this->inTransaction = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sql
|
||||
* @throws Exception\InvalidQueryException
|
||||
* @return resource|\Zend\Db\ResultSet\ResultSetInterface
|
||||
*/
|
||||
public function execute($sql)
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
if ($this->profiler) {
|
||||
$this->profiler->profilerStart($sql);
|
||||
}
|
||||
|
||||
$resultResource = pg_query($this->resource, $sql);
|
||||
|
||||
if ($this->profiler) {
|
||||
$this->profiler->profilerFinish($sql);
|
||||
}
|
||||
|
||||
//var_dump(pg_result_status($resultResource));
|
||||
|
||||
// if the returnValue is something other than a pg result resource, bypass wrapping it
|
||||
if ($resultResource === false) {
|
||||
throw new Exception\InvalidQueryException(pg_errormessage());
|
||||
}
|
||||
|
||||
$resultPrototype = $this->driver->createResult(($resultResource === true) ? $this->resource : $resultResource);
|
||||
return $resultPrototype;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null $name Ignored
|
||||
* @return string
|
||||
*/
|
||||
public function getLastGeneratedValue($name = null)
|
||||
{
|
||||
if ($name == null) {
|
||||
return null;
|
||||
}
|
||||
$result = pg_query($this->resource, 'SELECT CURRVAL(\'' . str_replace('\'', '\\\'', $name) . '\') as "currval"');
|
||||
return pg_fetch_result($result, 0, 'currval');
|
||||
}
|
||||
}
|
@ -0,0 +1,226 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Pgsql;
|
||||
|
||||
use Zend\Db\Adapter\Driver\DriverInterface;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
use Zend\Db\Adapter\Profiler;
|
||||
|
||||
class Pgsql implements DriverInterface, Profiler\ProfilerAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var Connection
|
||||
*/
|
||||
protected $connection = null;
|
||||
|
||||
/**
|
||||
* @var Statement
|
||||
*/
|
||||
protected $statementPrototype = null;
|
||||
|
||||
/**
|
||||
* @var Result
|
||||
*/
|
||||
protected $resultPrototype = null;
|
||||
|
||||
/**
|
||||
* @var null|Profiler\ProfilerInterface
|
||||
*/
|
||||
protected $profiler = null;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $options = array(
|
||||
'buffer_results' => false
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array|Connection|resource $connection
|
||||
* @param null|Statement $statementPrototype
|
||||
* @param null|Result $resultPrototype
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct($connection, Statement $statementPrototype = null, Result $resultPrototype = null, $options = null)
|
||||
{
|
||||
if (!$connection instanceof Connection) {
|
||||
$connection = new Connection($connection);
|
||||
}
|
||||
|
||||
$this->registerConnection($connection);
|
||||
$this->registerStatementPrototype(($statementPrototype) ?: new Statement());
|
||||
$this->registerResultPrototype(($resultPrototype) ?: new Result());
|
||||
}
|
||||
|
||||
public function setProfiler(Profiler\ProfilerInterface $profiler)
|
||||
{
|
||||
$this->profiler = $profiler;
|
||||
if ($this->connection instanceof Profiler\ProfilerAwareInterface) {
|
||||
$this->connection->setProfiler($profiler);
|
||||
}
|
||||
if ($this->statementPrototype instanceof Profiler\ProfilerAwareInterface) {
|
||||
$this->statementPrototype->setProfiler($profiler);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|Profiler\ProfilerInterface
|
||||
*/
|
||||
public function getProfiler()
|
||||
{
|
||||
return $this->profiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register connection
|
||||
*
|
||||
* @param Connection $connection
|
||||
* @return Pgsql
|
||||
*/
|
||||
public function registerConnection(Connection $connection)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
$this->connection->setDriver($this);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register statement prototype
|
||||
*
|
||||
* @param Statement $statement
|
||||
* @return Pgsql
|
||||
*/
|
||||
public function registerStatementPrototype(Statement $statement)
|
||||
{
|
||||
$this->statementPrototype = $statement;
|
||||
$this->statementPrototype->setDriver($this); // needs access to driver to createResult()
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register result prototype
|
||||
*
|
||||
* @param Result $result
|
||||
* @return Pgsql
|
||||
*/
|
||||
public function registerResultPrototype(Result $result)
|
||||
{
|
||||
$this->resultPrototype = $result;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get database platform name
|
||||
*
|
||||
* @param string $nameFormat
|
||||
* @return string
|
||||
*/
|
||||
public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE)
|
||||
{
|
||||
if ($nameFormat == self::NAME_FORMAT_CAMELCASE) {
|
||||
return 'Postgresql';
|
||||
}
|
||||
|
||||
return 'PostgreSQL';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check environment
|
||||
*
|
||||
* @throws Exception\RuntimeException
|
||||
* @return bool
|
||||
*/
|
||||
public function checkEnvironment()
|
||||
{
|
||||
if (!extension_loaded('pgsql')) {
|
||||
throw new Exception\RuntimeException('The PostgreSQL (pgsql) extension is required for this adapter but the extension is not loaded');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get connection
|
||||
*
|
||||
* @return Connection
|
||||
*/
|
||||
public function getConnection()
|
||||
{
|
||||
return $this->connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create statement
|
||||
*
|
||||
* @param string|null $sqlOrResource
|
||||
* @return Statement
|
||||
*/
|
||||
public function createStatement($sqlOrResource = null)
|
||||
{
|
||||
$statement = clone $this->statementPrototype;
|
||||
|
||||
if (is_string($sqlOrResource)) {
|
||||
$statement->setSql($sqlOrResource);
|
||||
}
|
||||
|
||||
if (!$this->connection->isConnected()) {
|
||||
$this->connection->connect();
|
||||
}
|
||||
|
||||
$statement->initialize($this->connection->getResource());
|
||||
return $statement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create result
|
||||
*
|
||||
* @param resource $resource
|
||||
* @return Result
|
||||
*/
|
||||
public function createResult($resource)
|
||||
{
|
||||
$result = clone $this->resultPrototype;
|
||||
$result->initialize($resource, $this->connection->getLastGeneratedValue());
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get prepare Type
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPrepareType()
|
||||
{
|
||||
return self::PARAMETERIZATION_POSITIONAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format parameter name
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $type
|
||||
* @return string
|
||||
*/
|
||||
public function formatParameterName($name, $type = null)
|
||||
{
|
||||
return '$#';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last generated value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getLastGeneratedValue()
|
||||
{
|
||||
return $this->connection->getLastGeneratedValue();
|
||||
}
|
||||
}
|
@ -0,0 +1,193 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Pgsql;
|
||||
|
||||
use Zend\Db\Adapter\Driver\ResultInterface;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
|
||||
class Result implements ResultInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
protected $resource = null;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $position = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $count = 0;
|
||||
|
||||
/**
|
||||
* @var null|mixed
|
||||
*/
|
||||
protected $generatedValue = null;
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*
|
||||
* @param $resource
|
||||
* @param $generatedValue
|
||||
* @return void
|
||||
* @throws Exception\InvalidArgumentException
|
||||
*/
|
||||
public function initialize($resource, $generatedValue)
|
||||
{
|
||||
if (!is_resource($resource) || get_resource_type($resource) != 'pgsql result') {
|
||||
throw new Exception\InvalidArgumentException('Resource not of the correct type.');
|
||||
}
|
||||
|
||||
$this->resource = $resource;
|
||||
$this->count = pg_num_rows($this->resource);
|
||||
$this->generatedValue = $generatedValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Current
|
||||
*
|
||||
* @return array|bool|mixed
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
if ($this->count === 0) {
|
||||
return false;
|
||||
}
|
||||
return pg_fetch_assoc($this->resource, $this->position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Next
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
$this->position++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Key
|
||||
*
|
||||
* @return int|mixed
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Valid
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return ($this->position < $this->count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewind
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->position = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Buffer
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function buffer()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is buffered
|
||||
*
|
||||
* @return false
|
||||
*/
|
||||
public function isBuffered()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is query result
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isQueryResult()
|
||||
{
|
||||
return (pg_num_fields($this->resource) > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get affected rows
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getAffectedRows()
|
||||
{
|
||||
return pg_affected_rows($this->resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get generated value
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getGeneratedValue()
|
||||
{
|
||||
return $this->generatedValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get resource
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
// TODO: Implement getResource() method.
|
||||
}
|
||||
|
||||
/**
|
||||
* Count
|
||||
*
|
||||
* (PHP 5 >= 5.1.0)<br/>
|
||||
* Count elements of an object
|
||||
* @link http://php.net/manual/en/countable.count.php
|
||||
* @return int The custom count as an integer.
|
||||
* </p>
|
||||
* <p>
|
||||
* The return value is cast to an integer.
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return $this->count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field count
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getFieldCount()
|
||||
{
|
||||
return pg_num_fields($this->resource);
|
||||
}
|
||||
}
|
@ -0,0 +1,241 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Pgsql;
|
||||
|
||||
use Zend\Db\Adapter\Driver\StatementInterface;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
use Zend\Db\Adapter\ParameterContainer;
|
||||
use Zend\Db\Adapter\Profiler;
|
||||
|
||||
class Statement implements StatementInterface, Profiler\ProfilerAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected static $statementIndex = 0;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $statementName = '';
|
||||
|
||||
/**
|
||||
* @var Pgsql
|
||||
*/
|
||||
protected $driver = null;
|
||||
|
||||
/**
|
||||
* @var Profiler\ProfilerInterface
|
||||
*/
|
||||
protected $profiler = null;
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
protected $pgsql = null;
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
protected $resource = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $sql;
|
||||
|
||||
/**
|
||||
* @var ParameterContainer
|
||||
*/
|
||||
protected $parameterContainer;
|
||||
|
||||
/**
|
||||
* @param Pgsql $driver
|
||||
* @return Statement
|
||||
*/
|
||||
public function setDriver(Pgsql $driver)
|
||||
{
|
||||
$this->driver = $driver;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Profiler\ProfilerInterface $profiler
|
||||
* @return Statement
|
||||
*/
|
||||
public function setProfiler(Profiler\ProfilerInterface $profiler)
|
||||
{
|
||||
$this->profiler = $profiler;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|Profiler\ProfilerInterface
|
||||
*/
|
||||
public function getProfiler()
|
||||
{
|
||||
return $this->profiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*
|
||||
* @param resource $pgsql
|
||||
* @return void
|
||||
* @throws Exception\RuntimeException for invalid or missing postgresql connection
|
||||
*/
|
||||
public function initialize($pgsql)
|
||||
{
|
||||
if (!is_resource($pgsql) || get_resource_type($pgsql) !== 'pgsql link') {
|
||||
throw new Exception\RuntimeException(sprintf(
|
||||
'%s: Invalid or missing postgresql connection; received "%s"',
|
||||
__METHOD__,
|
||||
get_resource_type($pgsql)
|
||||
));
|
||||
}
|
||||
$this->pgsql = $pgsql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get resource
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
// TODO: Implement getResource() method.
|
||||
}
|
||||
|
||||
/**
|
||||
* Set sql
|
||||
*
|
||||
* @param string $sql
|
||||
* @return Statement
|
||||
*/
|
||||
public function setSql($sql)
|
||||
{
|
||||
$this->sql = $sql;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sql
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSql()
|
||||
{
|
||||
return $this->sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set parameter container
|
||||
*
|
||||
* @param ParameterContainer $parameterContainer
|
||||
* @return Statement
|
||||
*/
|
||||
public function setParameterContainer(ParameterContainer $parameterContainer)
|
||||
{
|
||||
$this->parameterContainer = $parameterContainer;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get parameter container
|
||||
*
|
||||
* @return ParameterContainer
|
||||
*/
|
||||
public function getParameterContainer()
|
||||
{
|
||||
return $this->parameterContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare
|
||||
*
|
||||
* @param string $sql
|
||||
*/
|
||||
public function prepare($sql = null)
|
||||
{
|
||||
$sql = ($sql) ?: $this->sql;
|
||||
|
||||
$pCount = 1;
|
||||
$sql = preg_replace_callback(
|
||||
'#\$\##', function ($foo) use (&$pCount) {
|
||||
return '$' . $pCount++;
|
||||
},
|
||||
$sql
|
||||
);
|
||||
|
||||
$this->sql = $sql;
|
||||
$this->statementName = 'statement' . ++static::$statementIndex;
|
||||
$this->resource = pg_prepare($this->pgsql, $this->statementName, $sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is prepared
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPrepared()
|
||||
{
|
||||
return isset($this->resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @param ParameterContainer|null $parameters
|
||||
* @throws Exception\InvalidQueryException
|
||||
* @return Result
|
||||
*/
|
||||
public function execute($parameters = null)
|
||||
{
|
||||
if (!$this->isPrepared()) {
|
||||
$this->prepare();
|
||||
}
|
||||
|
||||
/** START Standard ParameterContainer Merging Block */
|
||||
if (!$this->parameterContainer instanceof ParameterContainer) {
|
||||
if ($parameters instanceof ParameterContainer) {
|
||||
$this->parameterContainer = $parameters;
|
||||
$parameters = null;
|
||||
} else {
|
||||
$this->parameterContainer = new ParameterContainer();
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($parameters)) {
|
||||
$this->parameterContainer->setFromArray($parameters);
|
||||
}
|
||||
|
||||
if ($this->parameterContainer->count() > 0) {
|
||||
$parameters = $this->parameterContainer->getPositionalArray();
|
||||
}
|
||||
/** END Standard ParameterContainer Merging Block */
|
||||
|
||||
if ($this->profiler) {
|
||||
$this->profiler->profilerStart($this);
|
||||
}
|
||||
|
||||
$resultResource = pg_execute($this->pgsql, $this->statementName, (array) $parameters);
|
||||
|
||||
if ($this->profiler) {
|
||||
$this->profiler->profilerFinish();
|
||||
}
|
||||
|
||||
if ($resultResource === false) {
|
||||
throw new Exception\InvalidQueryException(pg_last_error());
|
||||
}
|
||||
|
||||
$result = $this->driver->createResult($resultResource);
|
||||
return $result;
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver;
|
||||
|
||||
use Countable;
|
||||
use Iterator;
|
||||
|
||||
interface ResultInterface extends
|
||||
Countable,
|
||||
Iterator
|
||||
{
|
||||
/**
|
||||
* Force buffering
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function buffer();
|
||||
|
||||
/**
|
||||
* Check if is buffered
|
||||
*
|
||||
* @return bool|null
|
||||
*/
|
||||
public function isBuffered();
|
||||
|
||||
/**
|
||||
* Is query result?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isQueryResult();
|
||||
|
||||
/**
|
||||
* Get affected rows
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getAffectedRows();
|
||||
|
||||
/**
|
||||
* Get generated value
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getGeneratedValue();
|
||||
|
||||
/**
|
||||
* Get the resource
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResource();
|
||||
|
||||
/**
|
||||
* Get field count
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getFieldCount();
|
||||
}
|
@ -0,0 +1,354 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Sqlsrv;
|
||||
|
||||
use Zend\Db\Adapter\Driver\ConnectionInterface;
|
||||
use Zend\Db\Adapter\Driver\Sqlsrv\Exception\ErrorException;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
use Zend\Db\Adapter\Profiler;
|
||||
|
||||
class Connection implements ConnectionInterface, Profiler\ProfilerAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var Sqlsrv
|
||||
*/
|
||||
protected $driver = null;
|
||||
|
||||
/**
|
||||
* @var Profiler\ProfilerInterface
|
||||
*/
|
||||
protected $profiler = null;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $connectionParameters = array();
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
protected $resource = null;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $inTransaction = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array|resource $connectionInfo
|
||||
* @throws \Zend\Db\Adapter\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct($connectionInfo)
|
||||
{
|
||||
if (is_array($connectionInfo)) {
|
||||
$this->setConnectionParameters($connectionInfo);
|
||||
} elseif (is_resource($connectionInfo)) {
|
||||
$this->setResource($connectionInfo);
|
||||
} else {
|
||||
throw new Exception\InvalidArgumentException('$connection must be an array of parameters or a resource');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set driver
|
||||
*
|
||||
* @param Sqlsrv $driver
|
||||
* @return Connection
|
||||
*/
|
||||
public function setDriver(Sqlsrv $driver)
|
||||
{
|
||||
$this->driver = $driver;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Profiler\ProfilerInterface $profiler
|
||||
* @return Connection
|
||||
*/
|
||||
public function setProfiler(Profiler\ProfilerInterface $profiler)
|
||||
{
|
||||
$this->profiler = $profiler;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|Profiler\ProfilerInterface
|
||||
*/
|
||||
public function getProfiler()
|
||||
{
|
||||
return $this->profiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set connection parameters
|
||||
*
|
||||
* @param array $connectionParameters
|
||||
* @return Connection
|
||||
*/
|
||||
public function setConnectionParameters(array $connectionParameters)
|
||||
{
|
||||
$this->connectionParameters = $connectionParameters;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get connection parameters
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getConnectionParameters()
|
||||
{
|
||||
return $this->connectionParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current schema
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCurrentSchema()
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
$result = sqlsrv_query($this->resource, 'SELECT SCHEMA_NAME()');
|
||||
$r = sqlsrv_fetch_array($result);
|
||||
return $r[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set resource
|
||||
*
|
||||
* @param resource $resource
|
||||
* @throws Exception\InvalidArgumentException
|
||||
* @return Connection
|
||||
*/
|
||||
public function setResource($resource)
|
||||
{
|
||||
if (get_resource_type($resource) !== 'SQL Server Connection') {
|
||||
throw new Exception\InvalidArgumentException('Resource provided was not of type SQL Server Connection');
|
||||
}
|
||||
$this->resource = $resource;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return resource
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect
|
||||
*
|
||||
* @throws Exception\RuntimeException
|
||||
* @return Connection
|
||||
*/
|
||||
public function connect()
|
||||
{
|
||||
if ($this->resource) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$serverName = '.';
|
||||
$params = array(
|
||||
'ReturnDatesAsStrings' => true
|
||||
);
|
||||
foreach ($this->connectionParameters as $key => $value) {
|
||||
switch (strtolower($key)) {
|
||||
case 'hostname':
|
||||
case 'servername':
|
||||
$serverName = (string) $value;
|
||||
break;
|
||||
case 'username':
|
||||
case 'uid':
|
||||
$params['UID'] = (string) $value;
|
||||
break;
|
||||
case 'password':
|
||||
case 'pwd':
|
||||
$params['PWD'] = (string) $value;
|
||||
break;
|
||||
case 'database':
|
||||
case 'dbname':
|
||||
$params['Database'] = (string) $value;
|
||||
break;
|
||||
case 'driver_options':
|
||||
case 'options':
|
||||
$params = array_merge($params, (array) $value);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$this->resource = sqlsrv_connect($serverName, $params);
|
||||
|
||||
if (!$this->resource) {
|
||||
throw new Exception\RuntimeException(
|
||||
'Connect Error',
|
||||
null,
|
||||
new ErrorException(sqlsrv_errors())
|
||||
);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is connected
|
||||
* @return bool
|
||||
*/
|
||||
public function isConnected()
|
||||
{
|
||||
return (is_resource($this->resource));
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
sqlsrv_close($this->resource);
|
||||
$this->resource = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin transaction
|
||||
*/
|
||||
public function beginTransaction()
|
||||
{
|
||||
// http://msdn.microsoft.com/en-us/library/cc296151.aspx
|
||||
/*
|
||||
$this->resource->autocommit(false);
|
||||
$this->inTransaction = true;
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
// http://msdn.microsoft.com/en-us/library/cc296194.aspx
|
||||
/*
|
||||
if (!$this->resource) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
$this->resource->commit();
|
||||
|
||||
$this->inTransaction = false;
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Rollback
|
||||
*/
|
||||
public function rollback()
|
||||
{
|
||||
// http://msdn.microsoft.com/en-us/library/cc296176.aspx
|
||||
/*
|
||||
if (!$this->resource) {
|
||||
throw new \Exception('Must be connected before you can rollback.');
|
||||
}
|
||||
|
||||
if (!$this->_inCommit) {
|
||||
throw new \Exception('Must call commit() before you can rollback.');
|
||||
}
|
||||
|
||||
$this->resource->rollback();
|
||||
return $this;
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @param string $sql
|
||||
* @throws Exception\RuntimeException
|
||||
* @return mixed
|
||||
*/
|
||||
public function execute($sql)
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
if (!$this->driver instanceof Sqlsrv) {
|
||||
throw new Exception\RuntimeException('Connection is missing an instance of Sqlsrv');
|
||||
}
|
||||
|
||||
if ($this->profiler) {
|
||||
$this->profiler->profilerStart($sql);
|
||||
}
|
||||
|
||||
$returnValue = sqlsrv_query($this->resource, $sql);
|
||||
|
||||
if ($this->profiler) {
|
||||
$this->profiler->profilerFinish($sql);
|
||||
}
|
||||
|
||||
// if the returnValue is something other than a Sqlsrv_result, bypass wrapping it
|
||||
if ($returnValue === false) {
|
||||
$errors = sqlsrv_errors();
|
||||
// ignore general warnings
|
||||
if ($errors[0]['SQLSTATE'] != '01000') {
|
||||
throw new Exception\RuntimeException(
|
||||
'An exception occurred while trying to execute the provided $sql',
|
||||
null,
|
||||
new ErrorException($errors)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$result = $this->driver->createResult($returnValue);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare
|
||||
*
|
||||
* @param string $sql
|
||||
* @return string
|
||||
*/
|
||||
public function prepare($sql)
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
$statement = $this->driver->createStatement($sql);
|
||||
return $statement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last generated id
|
||||
*
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function getLastGeneratedValue($name = null)
|
||||
{
|
||||
if (!$this->resource) {
|
||||
$this->connect();
|
||||
}
|
||||
$sql = 'SELECT @@IDENTITY as Current_Identity';
|
||||
$result = sqlsrv_query($this->resource, $sql);
|
||||
$row = sqlsrv_fetch_array($result);
|
||||
return $row['Current_Identity'];
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Sqlsrv\Exception;
|
||||
|
||||
use Zend\Db\Adapter\Exception;
|
||||
|
||||
class ErrorException extends Exception\ErrorException implements ExceptionInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Errors
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $errors = array();
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param bool $errors
|
||||
*/
|
||||
public function __construct($errors = false)
|
||||
{
|
||||
$this->errors = ($errors === false) ? sqlsrv_errors() : $errors;
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Sqlsrv\Exception;
|
||||
|
||||
use Zend\Db\Adapter\Exception;
|
||||
|
||||
interface ExceptionInterface extends Exception\ExceptionInterface
|
||||
{
|
||||
}
|
@ -0,0 +1,209 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Sqlsrv;
|
||||
|
||||
use Iterator;
|
||||
use Zend\Db\Adapter\Driver\ResultInterface;
|
||||
|
||||
class Result implements Iterator, ResultInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
protected $resource = null;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $currentData = false;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $currentComplete = false;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $position = -1;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
protected $generatedValue = null;
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*
|
||||
* @param resource $resource
|
||||
* @param mixed $generatedValue
|
||||
* @return Result
|
||||
*/
|
||||
public function initialize($resource, $generatedValue = null)
|
||||
{
|
||||
$this->resource = $resource;
|
||||
$this->generatedValue = $generatedValue;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
public function buffer()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isBuffered()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get resource
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Current
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
if ($this->currentComplete) {
|
||||
return $this->currentData;
|
||||
}
|
||||
|
||||
$this->load();
|
||||
return $this->currentData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Next
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
$this->load();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load
|
||||
*
|
||||
* @param int $row
|
||||
* @return mixed
|
||||
*/
|
||||
protected function load($row = SQLSRV_SCROLL_NEXT)
|
||||
{
|
||||
$this->currentData = sqlsrv_fetch_array($this->resource, SQLSRV_FETCH_ASSOC, $row);
|
||||
$this->currentComplete = true;
|
||||
$this->position++;
|
||||
return $this->currentData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Key
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewind
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->position = 0;
|
||||
$this->load(SQLSRV_SCROLL_FIRST);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Valid
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
if ($this->currentComplete && $this->currentData) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->load();
|
||||
}
|
||||
|
||||
/**
|
||||
* Count
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return sqlsrv_num_rows($this->resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool|int
|
||||
*/
|
||||
public function getFieldCount()
|
||||
{
|
||||
return sqlsrv_num_fields($this->resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is query result
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isQueryResult()
|
||||
{
|
||||
if (is_bool($this->resource)) {
|
||||
return false;
|
||||
}
|
||||
return (sqlsrv_num_fields($this->resource) > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get affected rows
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getAffectedRows()
|
||||
{
|
||||
return sqlsrv_rows_affected($this->resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getGeneratedValue()
|
||||
{
|
||||
return $this->generatedValue;
|
||||
}
|
||||
}
|
@ -0,0 +1,212 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Sqlsrv;
|
||||
|
||||
use Zend\Db\Adapter\Driver\DriverInterface;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
use Zend\Db\Adapter\Profiler;
|
||||
|
||||
class Sqlsrv implements DriverInterface, Profiler\ProfilerAwareInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Connection
|
||||
*/
|
||||
protected $connection = null;
|
||||
|
||||
/**
|
||||
* @var Statement
|
||||
*/
|
||||
protected $statementPrototype = null;
|
||||
|
||||
/**
|
||||
* @var Result
|
||||
*/
|
||||
protected $resultPrototype = null;
|
||||
|
||||
/**
|
||||
* @var null|Profiler\ProfilerInterface
|
||||
*/
|
||||
protected $profiler = null;
|
||||
|
||||
/**
|
||||
* @param array|Connection|resource $connection
|
||||
* @param null|Statement $statementPrototype
|
||||
* @param null|Result $resultPrototype
|
||||
*/
|
||||
public function __construct($connection, Statement $statementPrototype = null, Result $resultPrototype = null)
|
||||
{
|
||||
if (!$connection instanceof Connection) {
|
||||
$connection = new Connection($connection);
|
||||
}
|
||||
|
||||
$this->registerConnection($connection);
|
||||
$this->registerStatementPrototype(($statementPrototype) ?: new Statement());
|
||||
$this->registerResultPrototype(($resultPrototype) ?: new Result());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Profiler\ProfilerInterface $profiler
|
||||
* @return Sqlsrv
|
||||
*/
|
||||
public function setProfiler(Profiler\ProfilerInterface $profiler)
|
||||
{
|
||||
$this->profiler = $profiler;
|
||||
if ($this->connection instanceof Profiler\ProfilerAwareInterface) {
|
||||
$this->connection->setProfiler($profiler);
|
||||
}
|
||||
if ($this->statementPrototype instanceof Profiler\ProfilerAwareInterface) {
|
||||
$this->statementPrototype->setProfiler($profiler);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|Profiler\ProfilerInterface
|
||||
*/
|
||||
public function getProfiler()
|
||||
{
|
||||
return $this->profiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register connection
|
||||
*
|
||||
* @param Connection $connection
|
||||
* @return Sqlsrv
|
||||
*/
|
||||
public function registerConnection(Connection $connection)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
$this->connection->setDriver($this);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register statement prototype
|
||||
*
|
||||
* @param Statement $statementPrototype
|
||||
* @return Sqlsrv
|
||||
*/
|
||||
public function registerStatementPrototype(Statement $statementPrototype)
|
||||
{
|
||||
$this->statementPrototype = $statementPrototype;
|
||||
$this->statementPrototype->setDriver($this);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register result prototype
|
||||
*
|
||||
* @param Result $resultPrototype
|
||||
* @return Sqlsrv
|
||||
*/
|
||||
public function registerResultPrototype(Result $resultPrototype)
|
||||
{
|
||||
$this->resultPrototype = $resultPrototype;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get database paltform name
|
||||
*
|
||||
* @param string $nameFormat
|
||||
* @return string
|
||||
*/
|
||||
public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE)
|
||||
{
|
||||
if ($nameFormat == self::NAME_FORMAT_CAMELCASE) {
|
||||
return 'SqlServer';
|
||||
}
|
||||
|
||||
return 'SQLServer';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check environment
|
||||
*
|
||||
* @throws Exception\RuntimeException
|
||||
* @return void
|
||||
*/
|
||||
public function checkEnvironment()
|
||||
{
|
||||
if (!extension_loaded('sqlsrv')) {
|
||||
throw new Exception\RuntimeException('The Sqlsrv extension is required for this adapter but the extension is not loaded');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Connection
|
||||
*/
|
||||
public function getConnection()
|
||||
{
|
||||
return $this->connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|resource $sqlOrResource
|
||||
* @return Statement
|
||||
*/
|
||||
public function createStatement($sqlOrResource = null)
|
||||
{
|
||||
$statement = clone $this->statementPrototype;
|
||||
if (is_resource($sqlOrResource)) {
|
||||
$statement->initialize($sqlOrResource);
|
||||
} else {
|
||||
if (!$this->connection->isConnected()) {
|
||||
$this->connection->connect();
|
||||
}
|
||||
$statement->initialize($this->connection->getResource());
|
||||
if (is_string($sqlOrResource)) {
|
||||
$statement->setSql($sqlOrResource);
|
||||
} elseif ($sqlOrResource != null) {
|
||||
throw new Exception\InvalidArgumentException('createStatement() only accepts an SQL string or a Sqlsrv resource');
|
||||
}
|
||||
}
|
||||
return $statement;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource $resource
|
||||
* @return Result
|
||||
*/
|
||||
public function createResult($resource)
|
||||
{
|
||||
$result = clone $this->resultPrototype;
|
||||
$result->initialize($resource, $this->connection->getLastGeneratedValue());
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPrepareType()
|
||||
{
|
||||
return self::PARAMETERIZATION_POSITIONAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $type
|
||||
* @return string
|
||||
*/
|
||||
public function formatParameterName($name, $type = null)
|
||||
{
|
||||
return '?';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getLastGeneratedValue()
|
||||
{
|
||||
return $this->getConnection()->getLastGeneratedValue();
|
||||
}
|
||||
}
|
@ -0,0 +1,289 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver\Sqlsrv;
|
||||
|
||||
use Zend\Db\Adapter\Driver\StatementInterface;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
use Zend\Db\Adapter\ParameterContainer;
|
||||
use Zend\Db\Adapter\Profiler;
|
||||
|
||||
class Statement implements StatementInterface, Profiler\ProfilerAwareInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
protected $sqlsrv = null;
|
||||
|
||||
/**
|
||||
* @var Sqlsrv
|
||||
*/
|
||||
protected $driver = null;
|
||||
|
||||
/**
|
||||
* @var Profiler\ProfilerInterface
|
||||
*/
|
||||
protected $profiler = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $sql = null;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $isQuery = null;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $parameterReferences = array();
|
||||
|
||||
/**
|
||||
* @var ParameterContainer
|
||||
*/
|
||||
protected $parameterContainer = null;
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
protected $resource = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isPrepared = false;
|
||||
|
||||
/**
|
||||
* Set driver
|
||||
*
|
||||
* @param Sqlsrv $driver
|
||||
* @return Statement
|
||||
*/
|
||||
public function setDriver(Sqlsrv $driver)
|
||||
{
|
||||
$this->driver = $driver;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Profiler\ProfilerInterface $profiler
|
||||
* @return Statement
|
||||
*/
|
||||
public function setProfiler(Profiler\ProfilerInterface $profiler)
|
||||
{
|
||||
$this->profiler = $profiler;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|Profiler\ProfilerInterface
|
||||
*/
|
||||
public function getProfiler()
|
||||
{
|
||||
return $this->profiler;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* One of two resource types will be provided here:
|
||||
* a) "SQL Server Connection" when a prepared statement needs to still be produced
|
||||
* b) "SQL Server Statement" when a prepared statement has been already produced
|
||||
* (there will need to already be a bound param set if it applies to this query)
|
||||
*
|
||||
* @param resource $resource
|
||||
* @throws Exception\InvalidArgumentException
|
||||
* @return Statement
|
||||
*/
|
||||
public function initialize($resource)
|
||||
{
|
||||
$resourceType = get_resource_type($resource);
|
||||
|
||||
if ($resourceType == 'SQL Server Connection') {
|
||||
$this->sqlsrv = $resource;
|
||||
} elseif ($resourceType == 'SQL Server Statement') {
|
||||
$this->resource = $resource;
|
||||
$this->isPrepared = true;
|
||||
} else {
|
||||
throw new Exception\InvalidArgumentException('Invalid resource provided to ' . __CLASS__);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set parameter container
|
||||
*
|
||||
* @param ParameterContainer $parameterContainer
|
||||
* @return Statement
|
||||
*/
|
||||
public function setParameterContainer(ParameterContainer $parameterContainer)
|
||||
{
|
||||
$this->parameterContainer = $parameterContainer;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ParameterContainer
|
||||
*/
|
||||
public function getParameterContainer()
|
||||
{
|
||||
return $this->parameterContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $resource
|
||||
* @return Statement
|
||||
*/
|
||||
public function setResource($resource)
|
||||
{
|
||||
$this->resource = $resource;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get resource
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sql
|
||||
* @return Statement
|
||||
*/
|
||||
public function setSql($sql)
|
||||
{
|
||||
$this->sql = $sql;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sql
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSql()
|
||||
{
|
||||
return $this->sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sql
|
||||
* @throws Exception\RuntimeException
|
||||
* @return Statement
|
||||
*/
|
||||
public function prepare($sql = null)
|
||||
{
|
||||
if ($this->isPrepared) {
|
||||
throw new Exception\RuntimeException('Already prepared');
|
||||
}
|
||||
$sql = ($sql) ?: $this->sql;
|
||||
|
||||
$pRef = &$this->parameterReferences;
|
||||
for ($position = 0, $count = substr_count($sql, '?'); $position < $count; $position++) {
|
||||
$pRef[$position] = array('', SQLSRV_PARAM_IN, null, null);
|
||||
}
|
||||
|
||||
$this->resource = sqlsrv_prepare($this->sqlsrv, $sql, $pRef);
|
||||
|
||||
$this->isPrepared = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isPrepared()
|
||||
{
|
||||
return $this->isPrepared;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @param array|ParameterContainer $parameters
|
||||
* @throws Exception\RuntimeException
|
||||
* @return Result
|
||||
*/
|
||||
public function execute($parameters = null)
|
||||
{
|
||||
if (!$this->isPrepared) {
|
||||
$this->prepare();
|
||||
}
|
||||
|
||||
/** START Standard ParameterContainer Merging Block */
|
||||
if (!$this->parameterContainer instanceof ParameterContainer) {
|
||||
if ($parameters instanceof ParameterContainer) {
|
||||
$this->parameterContainer = $parameters;
|
||||
$parameters = null;
|
||||
} else {
|
||||
$this->parameterContainer = new ParameterContainer();
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($parameters)) {
|
||||
$this->parameterContainer->setFromArray($parameters);
|
||||
}
|
||||
|
||||
if ($this->parameterContainer->count() > 0) {
|
||||
$this->bindParametersFromContainer();
|
||||
}
|
||||
/** END Standard ParameterContainer Merging Block */
|
||||
|
||||
if ($this->profiler) {
|
||||
$this->profiler->profilerStart($this);
|
||||
}
|
||||
|
||||
$resultValue = sqlsrv_execute($this->resource);
|
||||
|
||||
if ($this->profiler) {
|
||||
$this->profiler->profilerFinish();
|
||||
}
|
||||
|
||||
if ($resultValue === false) {
|
||||
$errors = sqlsrv_errors();
|
||||
// ignore general warnings
|
||||
if ($errors[0]['SQLSTATE'] != '01000') {
|
||||
throw new Exception\RuntimeException($errors[0]['message']);
|
||||
}
|
||||
}
|
||||
|
||||
$result = $this->driver->createResult($this->resource);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind parameters from container
|
||||
*
|
||||
*/
|
||||
protected function bindParametersFromContainer()
|
||||
{
|
||||
$values = $this->parameterContainer->getPositionalArray();
|
||||
$position = 0;
|
||||
foreach ($values as $value) {
|
||||
$this->parameterReferences[$position++][0] = $value;
|
||||
}
|
||||
|
||||
// @todo bind errata
|
||||
//foreach ($this->parameterContainer as $name => &$value) {
|
||||
// $p[$position][0] = $value;
|
||||
// $position++;
|
||||
// if ($this->parameterContainer->offsetHasErrata($name)) {
|
||||
// $p[$position][3] = $this->parameterContainer->offsetGetErrata($name);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Driver;
|
||||
|
||||
use Zend\Db\Adapter\StatementContainerInterface;
|
||||
|
||||
interface StatementInterface extends StatementContainerInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Get resource
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
public function getResource();
|
||||
|
||||
/**
|
||||
* Prepare sql
|
||||
*
|
||||
* @param string $sql
|
||||
*/
|
||||
public function prepare($sql = null);
|
||||
|
||||
/**
|
||||
* Check if is prepared
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPrepared();
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @param null $parameters
|
||||
* @return ResultInterface
|
||||
*/
|
||||
public function execute($parameters = null);
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Exception;
|
||||
|
||||
use Zend\Db\Exception;
|
||||
|
||||
class ErrorException extends Exception\ErrorException implements ExceptionInterface
|
||||
{
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Exception;
|
||||
|
||||
use Zend\Db\Exception;
|
||||
|
||||
interface ExceptionInterface extends Exception\ExceptionInterface
|
||||
{
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Exception;
|
||||
|
||||
use Zend\Db\Exception;
|
||||
|
||||
class InvalidArgumentException extends Exception\InvalidArgumentException implements ExceptionInterface
|
||||
{
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Exception;
|
||||
|
||||
class InvalidConnectionParametersException extends RuntimeException implements ExceptionInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $parameters;
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param int $parameters
|
||||
*/
|
||||
public function __construct($message, $parameters)
|
||||
{
|
||||
parent::__construct($message);
|
||||
$this->parameters = $parameters;
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Exception;
|
||||
|
||||
class InvalidQueryException extends UnexpectedValueException implements ExceptionInterface
|
||||
{
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Exception;
|
||||
|
||||
use Zend\Db\Exception;
|
||||
|
||||
class RuntimeException extends Exception\RuntimeException implements ExceptionInterface
|
||||
{
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Exception;
|
||||
|
||||
use Zend\Db\Exception;
|
||||
|
||||
class UnexpectedValueException extends Exception\UnexpectedValueException implements ExceptionInterface
|
||||
{
|
||||
}
|
@ -0,0 +1,336 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter;
|
||||
|
||||
use ArrayAccess;
|
||||
use Countable;
|
||||
use Iterator;
|
||||
|
||||
class ParameterContainer implements Iterator, ArrayAccess, Countable
|
||||
{
|
||||
|
||||
const TYPE_AUTO = 'auto';
|
||||
const TYPE_NULL = 'null';
|
||||
const TYPE_DOUBLE = 'double';
|
||||
const TYPE_INTEGER = 'integer';
|
||||
const TYPE_BINARY = 'binary';
|
||||
const TYPE_STRING = 'string';
|
||||
const TYPE_LOB = 'lob';
|
||||
|
||||
/**
|
||||
* Data
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $data = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $positions = array();
|
||||
|
||||
/**
|
||||
* Errata
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $errata = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $data
|
||||
*/
|
||||
public function __construct(array $data = array())
|
||||
{
|
||||
if ($data) {
|
||||
$this->setFromArray($data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset exists
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists($name)
|
||||
{
|
||||
return (isset($this->data[$name]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset get
|
||||
*
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetGet($name)
|
||||
{
|
||||
return (isset($this->data[$name])) ? $this->data[$name] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $from
|
||||
*/
|
||||
public function offsetSetReference($name, $from)
|
||||
{
|
||||
$this->data[$name] =& $this->data[$from];
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset set
|
||||
*
|
||||
* @param string|int $name
|
||||
* @param mixed $value
|
||||
* @param mixed $errata
|
||||
*/
|
||||
public function offsetSet($name, $value, $errata = null)
|
||||
{
|
||||
$position = false;
|
||||
|
||||
// if integer, get name for this position
|
||||
if (is_int($name)) {
|
||||
if (isset($this->positions[$name])) {
|
||||
$position = $name;
|
||||
$name = $this->positions[$name];
|
||||
} else {
|
||||
$name = (string) $name;
|
||||
}
|
||||
} elseif (is_string($name)) {
|
||||
// is a string:
|
||||
$currentNames = array_keys($this->data);
|
||||
$position = array_search($name, $currentNames, true);
|
||||
} elseif ($name === null) {
|
||||
$name = (string) count($this->data);
|
||||
} else {
|
||||
throw new Exception\InvalidArgumentException('Keys must be string, integer or null');
|
||||
}
|
||||
|
||||
if ($position === false) {
|
||||
$this->positions[] = $name;
|
||||
}
|
||||
|
||||
$this->data[$name] = $value;
|
||||
|
||||
if ($errata) {
|
||||
$this->offsetSetErrata($name, $errata);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset unset
|
||||
*
|
||||
* @param string $name
|
||||
* @return ParameterContainer
|
||||
*/
|
||||
public function offsetUnset($name)
|
||||
{
|
||||
if (is_int($name) && isset($this->positions[$name])) {
|
||||
$name = $this->positions[$name];
|
||||
}
|
||||
unset($this->data[$name]);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set from array
|
||||
*
|
||||
* @param array $data
|
||||
* @return ParameterContainer
|
||||
*/
|
||||
public function setFromArray(Array $data)
|
||||
{
|
||||
foreach ($data as $n => $v) {
|
||||
$this->offsetSet($n, $v);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset set errata
|
||||
*
|
||||
* @param string|int $name
|
||||
* @param mixed $errata
|
||||
*/
|
||||
public function offsetSetErrata($name, $errata)
|
||||
{
|
||||
if (is_int($name)) {
|
||||
$name = $this->positions[$name];
|
||||
}
|
||||
$this->errata[$name] = $errata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset get errata
|
||||
*
|
||||
* @param string|int $name
|
||||
* @throws Exception\InvalidArgumentException
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetGetErrata($name)
|
||||
{
|
||||
if (is_int($name)) {
|
||||
$name = $this->positions[$name];
|
||||
}
|
||||
if (!array_key_exists($name, $this->data)) {
|
||||
throw new Exception\InvalidArgumentException('Data does not exist for this name/position');
|
||||
}
|
||||
return $this->errata[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset has errata
|
||||
*
|
||||
* @param string|int $name
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetHasErrata($name)
|
||||
{
|
||||
if (is_int($name)) {
|
||||
$name = $this->positions[$name];
|
||||
}
|
||||
return (isset($this->errata[$name]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset unset errata
|
||||
*
|
||||
* @param string|int $name
|
||||
* @throws Exception\InvalidArgumentException
|
||||
*/
|
||||
public function offsetUnsetErrata($name)
|
||||
{
|
||||
if (is_int($name)) {
|
||||
$name = $this->positions[$name];
|
||||
}
|
||||
if (!array_key_exists($name, $this->errata)) {
|
||||
throw new Exception\InvalidArgumentException('Data does not exist for this name/position');
|
||||
}
|
||||
$this->errata[$name] = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get errata iterator
|
||||
*
|
||||
* @return \ArrayIterator
|
||||
*/
|
||||
public function getErrataIterator()
|
||||
{
|
||||
return new \ArrayIterator($this->errata);
|
||||
}
|
||||
|
||||
/**
|
||||
* getNamedArray
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getNamedArray()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* getNamedArray
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPositionalArray()
|
||||
{
|
||||
return array_values($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* count
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Current
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return current($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Next
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
return next($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Key
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return key($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Valid
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return (current($this->data) !== false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewind
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
reset($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|ParameterContainer $parameters
|
||||
* @throws Exception\InvalidArgumentException
|
||||
* @return ParameterContainer
|
||||
*/
|
||||
public function merge($parameters)
|
||||
{
|
||||
if (!is_array($parameters) && !$parameters instanceof ParameterContainer) {
|
||||
throw new Exception\InvalidArgumentException('$parameters must be an array or an instance of ParameterContainer');
|
||||
}
|
||||
|
||||
if (count($parameters) == 0) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($parameters instanceof ParameterContainer) {
|
||||
$parameters = $parameters->getNamedArray();
|
||||
}
|
||||
|
||||
foreach ($parameters as $key => $value) {
|
||||
if (is_int($key)) {
|
||||
$key = null;
|
||||
}
|
||||
$this->offsetSet($key, $value);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,209 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Platform;
|
||||
|
||||
class IbmDb2 implements PlatformInterface
|
||||
{
|
||||
|
||||
protected $quoteValueAllowed = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $quoteIdentifiers = true;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $identifierSeparator = '.';
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct($options = array())
|
||||
{
|
||||
if (isset($options['quote_identifiers'])
|
||||
&& ($options['quote_identifiers'] == false
|
||||
|| $options['quote_identifiers'] === 'false')
|
||||
) {
|
||||
$this->quoteIdentifiers = false;
|
||||
}
|
||||
|
||||
if (isset($options['identifier_separator'])) {
|
||||
$this->identifierSeparator = $options['identifier_separator'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'IBM DB2';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get quote indentifier symbol
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQuoteIdentifierSymbol()
|
||||
{
|
||||
return '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote identifier
|
||||
*
|
||||
* @param string $identifier
|
||||
* @return string
|
||||
*/
|
||||
public function quoteIdentifier($identifier)
|
||||
{
|
||||
if ($this->quoteIdentifiers === false) {
|
||||
return $identifier;
|
||||
}
|
||||
return '"' . str_replace('"', '\\' . '"', $identifier) . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote identifier chain
|
||||
*
|
||||
* @param string|string[] $identifierChain
|
||||
* @return string
|
||||
*/
|
||||
public function quoteIdentifierChain($identifierChain)
|
||||
{
|
||||
if ($this->quoteIdentifiers === false) {
|
||||
return (is_array($identifierChain)) ? implode($this->identifierSeparator, $identifierChain) : $identifierChain;
|
||||
}
|
||||
$identifierChain = str_replace('"', '\\"', $identifierChain);
|
||||
if (is_array($identifierChain)) {
|
||||
$identifierChain = implode('"' . $this->identifierSeparator . '"', $identifierChain);
|
||||
}
|
||||
return '"' . $identifierChain . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get quote value symbol
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQuoteValueSymbol()
|
||||
{
|
||||
return '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote value
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValue($value)
|
||||
{
|
||||
if (function_exists('db2_escape_string')) {
|
||||
return '\'' . db2_escape_string($value) . '\'';
|
||||
}
|
||||
trigger_error(
|
||||
'Attempting to quote a value in ' . __CLASS__ . ' without extension/driver support '
|
||||
. 'can introduce security vulnerabilities in a production environment.'
|
||||
);
|
||||
return '\'' . str_replace("'", "''", $value) . '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote Trusted Value
|
||||
*
|
||||
* The ability to quote values without notices
|
||||
*
|
||||
* @param $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function quoteTrustedValue($value)
|
||||
{
|
||||
if (function_exists('db2_escape_string')) {
|
||||
return '\'' . db2_escape_string($value) . '\'';
|
||||
}
|
||||
return '\'' . str_replace("'", "''", $value) . '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote value list
|
||||
*
|
||||
* @param string|string[] $valueList
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValueList($valueList)
|
||||
{
|
||||
if (!is_array($valueList)) {
|
||||
return $this->quoteValue($valueList);
|
||||
}
|
||||
|
||||
$value = reset($valueList);
|
||||
do {
|
||||
$valueList[key($valueList)] = $this->quoteValue($value);
|
||||
} while ($value = next($valueList));
|
||||
return implode(', ', $valueList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get identifier separator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifierSeparator()
|
||||
{
|
||||
return $this->identifierSeparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote identifier in fragment
|
||||
*
|
||||
* @param string $identifier
|
||||
* @param array $safeWords
|
||||
* @return string
|
||||
*/
|
||||
public function quoteIdentifierInFragment($identifier, array $safeWords = array())
|
||||
{
|
||||
if ($this->quoteIdentifiers === false) {
|
||||
return $identifier;
|
||||
}
|
||||
$parts = preg_split('#([\.\s\W])#', $identifier, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
if ($safeWords) {
|
||||
$safeWords = array_flip($safeWords);
|
||||
$safeWords = array_change_key_case($safeWords, CASE_LOWER);
|
||||
}
|
||||
foreach ($parts as $i => $part) {
|
||||
if ($safeWords && isset($safeWords[strtolower($part)])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ($part) {
|
||||
case ' ':
|
||||
case '.':
|
||||
case '*':
|
||||
case 'AS':
|
||||
case 'As':
|
||||
case 'aS':
|
||||
case 'as':
|
||||
break;
|
||||
default:
|
||||
$parts[$i] = '"' . str_replace('"', '\\' . '"', $part) . '"';
|
||||
}
|
||||
}
|
||||
|
||||
return implode('', $parts);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,214 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Platform;
|
||||
|
||||
use Zend\Db\Adapter\Driver\DriverInterface;
|
||||
use Zend\Db\Adapter\Driver\Mysqli;
|
||||
use Zend\Db\Adapter\Driver\Pdo;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
|
||||
class Mysql implements PlatformInterface
|
||||
{
|
||||
/** @var \mysqli|\PDO */
|
||||
protected $resource = null;
|
||||
|
||||
public function __construct($driver = null)
|
||||
{
|
||||
if ($driver) {
|
||||
$this->setDriver($driver);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Zend\Db\Adapter\Driver\Mysqli\Mysqli|\Zend\Db\Adapter\Driver\Pdo\Pdo||\mysqli|\PDO $driver
|
||||
* @throws \Zend\Db\Adapter\Exception\InvalidArgumentException
|
||||
* @return $this
|
||||
*/
|
||||
public function setDriver($driver)
|
||||
{
|
||||
// handle Zend\Db drivers
|
||||
if ($driver instanceof Mysqli\Mysqli
|
||||
|| ($driver instanceof Pdo\Pdo && $driver->getDatabasePlatformName() == 'Mysql')
|
||||
|| ($driver instanceof \mysqli)
|
||||
|| ($driver instanceof \PDO && $driver->getAttribute(\PDO::ATTR_DRIVER_NAME) == 'mysql')
|
||||
) {
|
||||
$this->resource = $driver;
|
||||
return $this;
|
||||
}
|
||||
|
||||
throw new Exception\InvalidArgumentException('$driver must be a Mysqli or Mysql PDO Zend\Db\Adapter\Driver, Mysqli instance or MySQL PDO instance');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'MySQL';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get quote identifier symbol
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQuoteIdentifierSymbol()
|
||||
{
|
||||
return '`';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote identifier
|
||||
*
|
||||
* @param string $identifier
|
||||
* @return string
|
||||
*/
|
||||
public function quoteIdentifier($identifier)
|
||||
{
|
||||
return '`' . str_replace('`', '``', $identifier) . '`';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote identifier chain
|
||||
*
|
||||
* @param string|string[] $identifierChain
|
||||
* @return string
|
||||
*/
|
||||
public function quoteIdentifierChain($identifierChain)
|
||||
{
|
||||
$identifierChain = str_replace('`', '``', $identifierChain);
|
||||
if (is_array($identifierChain)) {
|
||||
$identifierChain = implode('`.`', $identifierChain);
|
||||
}
|
||||
return '`' . $identifierChain . '`';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get quote value symbol
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQuoteValueSymbol()
|
||||
{
|
||||
return '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote value
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValue($value)
|
||||
{
|
||||
if ($this->resource instanceof DriverInterface) {
|
||||
$this->resource = $this->resource->getConnection()->getResource();
|
||||
}
|
||||
if ($this->resource instanceof \mysqli) {
|
||||
return '\'' . $this->resource->real_escape_string($value) . '\'';
|
||||
}
|
||||
if ($this->resource instanceof \PDO) {
|
||||
return $this->resource->quote($value);
|
||||
}
|
||||
trigger_error(
|
||||
'Attempting to quote a value in ' . __CLASS__ . ' without extension/driver support '
|
||||
. 'can introduce security vulnerabilities in a production environment.'
|
||||
);
|
||||
return '\'' . addcslashes($value, "\x00\n\r\\'\"\x1a") . '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote Trusted Value
|
||||
*
|
||||
* The ability to quote values without notices
|
||||
*
|
||||
* @param $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function quoteTrustedValue($value)
|
||||
{
|
||||
if ($this->resource instanceof DriverInterface) {
|
||||
$this->resource = $this->resource->getConnection()->getResource();
|
||||
}
|
||||
if ($this->resource instanceof \mysqli) {
|
||||
return '\'' . $this->resource->real_escape_string($value) . '\'';
|
||||
}
|
||||
if ($this->resource instanceof \PDO) {
|
||||
return $this->resource->quote($value);
|
||||
}
|
||||
return '\'' . addcslashes($value, "\x00\n\r\\'\"\x1a") . '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote value list
|
||||
*
|
||||
* @param string|string[] $valueList
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValueList($valueList)
|
||||
{
|
||||
if (!is_array($valueList)) {
|
||||
return $this->quoteValue($valueList);
|
||||
}
|
||||
|
||||
$value = reset($valueList);
|
||||
do {
|
||||
$valueList[key($valueList)] = $this->quoteValue($value);
|
||||
} while ($value = next($valueList));
|
||||
return implode(', ', $valueList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get identifier separator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifierSeparator()
|
||||
{
|
||||
return '.';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote identifier in fragment
|
||||
*
|
||||
* @param string $identifier
|
||||
* @param array $safeWords
|
||||
* @return string
|
||||
*/
|
||||
public function quoteIdentifierInFragment($identifier, array $safeWords = array())
|
||||
{
|
||||
// regex taken from @link http://dev.mysql.com/doc/refman/5.0/en/identifiers.html
|
||||
$parts = preg_split('#([^0-9,a-z,A-Z$_])#', $identifier, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
|
||||
if ($safeWords) {
|
||||
$safeWords = array_flip($safeWords);
|
||||
$safeWords = array_change_key_case($safeWords, CASE_LOWER);
|
||||
}
|
||||
foreach ($parts as $i => $part) {
|
||||
if ($safeWords && isset($safeWords[strtolower($part)])) {
|
||||
continue;
|
||||
}
|
||||
switch ($part) {
|
||||
case ' ':
|
||||
case '.':
|
||||
case '*':
|
||||
case 'AS':
|
||||
case 'As':
|
||||
case 'aS':
|
||||
case 'as':
|
||||
break;
|
||||
default:
|
||||
$parts[$i] = '`' . str_replace('`', '``', $part) . '`';
|
||||
}
|
||||
}
|
||||
return implode('', $parts);
|
||||
}
|
||||
}
|
@ -0,0 +1,189 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Platform;
|
||||
|
||||
class Oracle implements PlatformInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $quoteIdentifiers = true;
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct($options = array())
|
||||
{
|
||||
if (isset($options['quote_identifiers'])
|
||||
&& ($options['quote_identifiers'] == false
|
||||
|| $options['quote_identifiers'] === 'false')
|
||||
) {
|
||||
$this->quoteIdentifiers = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Oracle';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get quote identifier symbol
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQuoteIdentifierSymbol()
|
||||
{
|
||||
return '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote identifier
|
||||
*
|
||||
* @param string $identifier
|
||||
* @return string
|
||||
*/
|
||||
public function quoteIdentifier($identifier)
|
||||
{
|
||||
if ($this->quoteIdentifiers === false) {
|
||||
return $identifier;
|
||||
}
|
||||
return '"' . str_replace('"', '\\' . '"', $identifier) . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote identifier chain
|
||||
*
|
||||
* @param string|string[] $identifierChain
|
||||
* @return string
|
||||
*/
|
||||
public function quoteIdentifierChain($identifierChain)
|
||||
{
|
||||
if ($this->quoteIdentifiers === false) {
|
||||
return (is_array($identifierChain)) ? implode('.', $identifierChain) : $identifierChain;
|
||||
}
|
||||
$identifierChain = str_replace('"', '\\"', $identifierChain);
|
||||
if (is_array($identifierChain)) {
|
||||
$identifierChain = implode('"."', $identifierChain);
|
||||
}
|
||||
return '"' . $identifierChain . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get quote value symbol
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQuoteValueSymbol()
|
||||
{
|
||||
return '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote value
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValue($value)
|
||||
{
|
||||
trigger_error(
|
||||
'Attempting to quote a value in ' . __CLASS__ . ' without extension/driver support '
|
||||
. 'can introduce security vulnerabilities in a production environment.'
|
||||
);
|
||||
return '\'' . addcslashes($value, "\x00\n\r\\'\"\x1a") . '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote Trusted Value
|
||||
*
|
||||
* The ability to quote values without notices
|
||||
*
|
||||
* @param $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function quoteTrustedValue($value)
|
||||
{
|
||||
return '\'' . addcslashes($value, "\x00\n\r\\'\"\x1a") . '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote value list
|
||||
*
|
||||
* @param string|string[] $valueList
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValueList($valueList)
|
||||
{
|
||||
if (!is_array($valueList)) {
|
||||
return $this->quoteValue($valueList);
|
||||
}
|
||||
|
||||
$value = reset($valueList);
|
||||
do {
|
||||
$valueList[key($valueList)] = $this->quoteValue($value);
|
||||
} while ($value = next($valueList));
|
||||
return implode(', ', $valueList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get identifier separator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifierSeparator()
|
||||
{
|
||||
return '.';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote identifier in fragment
|
||||
*
|
||||
* @param string $identifier
|
||||
* @param array $safeWords
|
||||
* @return string
|
||||
*/
|
||||
public function quoteIdentifierInFragment($identifier, array $safeWords = array())
|
||||
{
|
||||
if ($this->quoteIdentifiers === false) {
|
||||
return $identifier;
|
||||
}
|
||||
$parts = preg_split('#([\.\s\W])#', $identifier, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
|
||||
if ($safeWords) {
|
||||
$safeWords = array_flip($safeWords);
|
||||
$safeWords = array_change_key_case($safeWords, CASE_LOWER);
|
||||
}
|
||||
foreach ($parts as $i => $part) {
|
||||
if ($safeWords && isset($safeWords[strtolower($part)])) {
|
||||
continue;
|
||||
}
|
||||
switch ($part) {
|
||||
case ' ':
|
||||
case '.':
|
||||
case '*':
|
||||
case 'AS':
|
||||
case 'As':
|
||||
case 'aS':
|
||||
case 'as':
|
||||
break;
|
||||
default:
|
||||
$parts[$i] = '"' . str_replace('"', '\\' . '"', $part) . '"';
|
||||
}
|
||||
}
|
||||
return implode('', $parts);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Platform;
|
||||
|
||||
interface PlatformInterface
|
||||
{
|
||||
/**
|
||||
* Get name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName();
|
||||
|
||||
/**
|
||||
* Get quote identifier symbol
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQuoteIdentifierSymbol();
|
||||
|
||||
/**
|
||||
* Quote identifier
|
||||
*
|
||||
* @param string $identifier
|
||||
* @return string
|
||||
*/
|
||||
public function quoteIdentifier($identifier);
|
||||
|
||||
/**
|
||||
* Quote identifier chain
|
||||
*
|
||||
* @param string|string[] $identifierChain
|
||||
* @return string
|
||||
*/
|
||||
public function quoteIdentifierChain($identifierChain);
|
||||
|
||||
/**
|
||||
* Get quote value symbol
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQuoteValueSymbol();
|
||||
|
||||
/**
|
||||
* Quote value
|
||||
*
|
||||
* Will throw a notice when used in a workflow that can be considered "unsafe"
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValue($value);
|
||||
|
||||
/**
|
||||
* Quote Trusted Value
|
||||
*
|
||||
* The ability to quote values without notices
|
||||
*
|
||||
* @param $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function quoteTrustedValue($value);
|
||||
|
||||
/**
|
||||
* Quote value list
|
||||
*
|
||||
* @param string|string[] $valueList
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValueList($valueList);
|
||||
|
||||
/**
|
||||
* Get identifier separator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifierSeparator();
|
||||
|
||||
/**
|
||||
* Quote identifier in fragment
|
||||
*
|
||||
* @param string $identifier
|
||||
* @param array $additionalSafeWords
|
||||
* @return string
|
||||
*/
|
||||
public function quoteIdentifierInFragment($identifier, array $additionalSafeWords = array());
|
||||
}
|
@ -0,0 +1,213 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Platform;
|
||||
|
||||
use Zend\Db\Adapter\Driver\DriverInterface;
|
||||
use Zend\Db\Adapter\Driver\Pdo;
|
||||
use Zend\Db\Adapter\Driver\Pgsql;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
|
||||
class Postgresql implements PlatformInterface
|
||||
{
|
||||
/** @var resource|\PDO */
|
||||
protected $resource = null;
|
||||
|
||||
public function __construct($driver = null)
|
||||
{
|
||||
if ($driver) {
|
||||
$this->setDriver($driver);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Zend\Db\Adapter\Driver\Pgsql\Pgsql|\Zend\Db\Adapter\Driver\Pdo\Pdo|resource|\PDO $driver
|
||||
* @throws \Zend\Db\Adapter\Exception\InvalidArgumentException
|
||||
* @return $this
|
||||
*/
|
||||
public function setDriver($driver)
|
||||
{
|
||||
if ($driver instanceof Pgsql\Pgsql
|
||||
|| ($driver instanceof Pdo\Pdo && $driver->getDatabasePlatformName() == 'Postgresql')
|
||||
|| (is_resource($driver) && (in_array(get_resource_type($driver), array('pgsql link', 'pgsql link persistent'))))
|
||||
|| ($driver instanceof \PDO && $driver->getAttribute(\PDO::ATTR_DRIVER_NAME) == 'pgsql')
|
||||
) {
|
||||
$this->resource = $driver;
|
||||
return $this;
|
||||
}
|
||||
|
||||
throw new Exception\InvalidArgumentException('$driver must be a Pgsql or Postgresql PDO Zend\Db\Adapter\Driver, pgsql link resource or Postgresql PDO instance');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'PostgreSQL';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get quote indentifier symbol
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQuoteIdentifierSymbol()
|
||||
{
|
||||
return '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote identifier
|
||||
*
|
||||
* @param string $identifier
|
||||
* @return string
|
||||
*/
|
||||
public function quoteIdentifier($identifier)
|
||||
{
|
||||
return '"' . str_replace('"', '\\' . '"', $identifier) . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote identifier chain
|
||||
*
|
||||
* @param string|string[] $identifierChain
|
||||
* @return string
|
||||
*/
|
||||
public function quoteIdentifierChain($identifierChain)
|
||||
{
|
||||
$identifierChain = str_replace('"', '\\"', $identifierChain);
|
||||
if (is_array($identifierChain)) {
|
||||
$identifierChain = implode('"."', $identifierChain);
|
||||
}
|
||||
return '"' . $identifierChain . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get quote value symbol
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQuoteValueSymbol()
|
||||
{
|
||||
return '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote value
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValue($value)
|
||||
{
|
||||
if ($this->resource instanceof DriverInterface) {
|
||||
$this->resource = $this->resource->getConnection()->getResource();
|
||||
}
|
||||
if (is_resource($this->resource)) {
|
||||
return '\'' . pg_escape_string($this->resource, $value) . '\'';
|
||||
}
|
||||
if ($this->resource instanceof \PDO) {
|
||||
return $this->resource->quote($value);
|
||||
}
|
||||
trigger_error(
|
||||
'Attempting to quote a value in ' . __CLASS__ . ' without extension/driver support '
|
||||
. 'can introduce security vulnerabilities in a production environment.'
|
||||
);
|
||||
return '\'' . addcslashes($value, "\x00\n\r\\'\"\x1a") . '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote Trusted Value
|
||||
*
|
||||
* The ability to quote values without notices
|
||||
*
|
||||
* @param $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function quoteTrustedValue($value)
|
||||
{
|
||||
if ($this->resource instanceof DriverInterface) {
|
||||
$this->resource = $this->resource->getConnection()->getResource();
|
||||
}
|
||||
if (is_resource($this->resource)) {
|
||||
return '\'' . pg_escape_string($this->resource, $value) . '\'';
|
||||
}
|
||||
if ($this->resource instanceof \PDO) {
|
||||
return $this->resource->quote($value);
|
||||
}
|
||||
return '\'' . addcslashes($value, "\x00\n\r\\'\"\x1a") . '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote value list
|
||||
*
|
||||
* @param string|string[] $valueList
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValueList($valueList)
|
||||
{
|
||||
if (!is_array($valueList)) {
|
||||
return $this->quoteValue($valueList);
|
||||
}
|
||||
|
||||
$value = reset($valueList);
|
||||
do {
|
||||
$valueList[key($valueList)] = $this->quoteValue($value);
|
||||
} while ($value = next($valueList));
|
||||
return implode(', ', $valueList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get identifier separator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifierSeparator()
|
||||
{
|
||||
return '.';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote identifier in fragment
|
||||
*
|
||||
* @param string $identifier
|
||||
* @param array $safeWords
|
||||
* @return string
|
||||
*/
|
||||
public function quoteIdentifierInFragment($identifier, array $safeWords = array())
|
||||
{
|
||||
$parts = preg_split('#([\.\s\W])#', $identifier, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
|
||||
if ($safeWords) {
|
||||
$safeWords = array_flip($safeWords);
|
||||
$safeWords = array_change_key_case($safeWords, CASE_LOWER);
|
||||
}
|
||||
foreach ($parts as $i => $part) {
|
||||
if ($safeWords && isset($safeWords[strtolower($part)])) {
|
||||
continue;
|
||||
}
|
||||
switch ($part) {
|
||||
case ' ':
|
||||
case '.':
|
||||
case '*':
|
||||
case 'AS':
|
||||
case 'As':
|
||||
case 'aS':
|
||||
case 'as':
|
||||
break;
|
||||
default:
|
||||
$parts[$i] = '"' . str_replace('"', '\\' . '"', $part) . '"';
|
||||
}
|
||||
}
|
||||
return implode('', $parts);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,162 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Platform;
|
||||
|
||||
class Sql92 implements PlatformInterface
|
||||
{
|
||||
/**
|
||||
* Get name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'SQL92';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get quote indentifier symbol
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQuoteIdentifierSymbol()
|
||||
{
|
||||
return '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote identifier
|
||||
*
|
||||
* @param string $identifier
|
||||
* @return string
|
||||
*/
|
||||
public function quoteIdentifier($identifier)
|
||||
{
|
||||
return '"' . str_replace('"', '\\' . '"', $identifier) . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote identifier chain
|
||||
*
|
||||
* @param string|string[] $identifierChain
|
||||
* @return string
|
||||
*/
|
||||
public function quoteIdentifierChain($identifierChain)
|
||||
{
|
||||
$identifierChain = str_replace('"', '\\"', $identifierChain);
|
||||
if (is_array($identifierChain)) {
|
||||
$identifierChain = implode('"."', $identifierChain);
|
||||
}
|
||||
return '"' . $identifierChain . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get quote value symbol
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQuoteValueSymbol()
|
||||
{
|
||||
return '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote value
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValue($value)
|
||||
{
|
||||
trigger_error(
|
||||
'Attempting to quote a value without specific driver level support can introduce security vulnerabilities in a production environment.'
|
||||
);
|
||||
return '\'' . addcslashes($value, "\x00\n\r\\'\"\x1a") . '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote Trusted Value
|
||||
*
|
||||
* The ability to quote values without notices
|
||||
*
|
||||
* @param $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function quoteTrustedValue($value)
|
||||
{
|
||||
return '\'' . addcslashes($value, "\x00\n\r\\'\"\x1a") . '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote value list
|
||||
*
|
||||
* @param string|string[] $valueList
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValueList($valueList)
|
||||
{
|
||||
if (!is_array($valueList)) {
|
||||
return $this->quoteValue($valueList);
|
||||
}
|
||||
|
||||
$value = reset($valueList);
|
||||
do {
|
||||
$valueList[key($valueList)] = $this->quoteValue($value);
|
||||
} while ($value = next($valueList));
|
||||
return implode(', ', $valueList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get identifier separator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifierSeparator()
|
||||
{
|
||||
return '.';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote identifier in fragment
|
||||
*
|
||||
* @param string $identifier
|
||||
* @param array $safeWords
|
||||
* @return string
|
||||
*/
|
||||
public function quoteIdentifierInFragment($identifier, array $safeWords = array())
|
||||
{
|
||||
$parts = preg_split('#([\.\s\W])#', $identifier, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
|
||||
if ($safeWords) {
|
||||
$safeWords = array_flip($safeWords);
|
||||
$safeWords = array_change_key_case($safeWords, CASE_LOWER);
|
||||
}
|
||||
foreach ($parts as $i => $part) {
|
||||
if ($safeWords && isset($safeWords[strtolower($part)])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ($part) {
|
||||
case ' ':
|
||||
case '.':
|
||||
case '*':
|
||||
case 'AS':
|
||||
case 'As':
|
||||
case 'aS':
|
||||
case 'as':
|
||||
break;
|
||||
default:
|
||||
$parts[$i] = '"' . str_replace('"', '\\' . '"', $part) . '"';
|
||||
}
|
||||
}
|
||||
|
||||
return implode('', $parts);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,204 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Platform;
|
||||
|
||||
use Zend\Db\Adapter\Driver\DriverInterface;
|
||||
use Zend\Db\Adapter\Driver\Pdo;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
|
||||
class SqlServer implements PlatformInterface
|
||||
{
|
||||
|
||||
/** @var resource|\PDO */
|
||||
protected $resource = null;
|
||||
|
||||
public function __construct($driver = null)
|
||||
{
|
||||
if ($driver) {
|
||||
$this->setDriver($driver);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Zend\Db\Adapter\Driver\Sqlsrv\Sqlsrv|\Zend\Db\Adapter\Driver\Pdo\Pdo||resource|\PDO $driver
|
||||
* @throws \Zend\Db\Adapter\Exception\InvalidArgumentException
|
||||
* @return $this
|
||||
*/
|
||||
public function setDriver($driver)
|
||||
{
|
||||
// handle Zend_Db drivers
|
||||
if (($driver instanceof Pdo\Pdo && in_array($driver->getDatabasePlatformName(), array('Sqlsrv', 'Dblib')))
|
||||
|| (($driver instanceof \PDO && in_array($driver->getAttribute(\PDO::ATTR_DRIVER_NAME), array('sqlsrv', 'dblib'))))
|
||||
) {
|
||||
$this->resource = $driver;
|
||||
return $this;
|
||||
}
|
||||
|
||||
throw new Exception\InvalidArgumentException('$driver must be a Sqlsrv PDO Zend\Db\Adapter\Driver or Sqlsrv PDO instance');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'SQLServer';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get quote identifier symbol
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQuoteIdentifierSymbol()
|
||||
{
|
||||
return array('[', ']');
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote identifier
|
||||
*
|
||||
* @param string $identifier
|
||||
* @return string
|
||||
*/
|
||||
public function quoteIdentifier($identifier)
|
||||
{
|
||||
return '[' . $identifier . ']';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote identifier chain
|
||||
*
|
||||
* @param string|string[] $identifierChain
|
||||
* @return string
|
||||
*/
|
||||
public function quoteIdentifierChain($identifierChain)
|
||||
{
|
||||
if (is_array($identifierChain)) {
|
||||
$identifierChain = implode('].[', $identifierChain);
|
||||
}
|
||||
return '[' . $identifierChain . ']';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get quote value symbol
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQuoteValueSymbol()
|
||||
{
|
||||
return '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote value
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValue($value)
|
||||
{
|
||||
if ($this->resource instanceof DriverInterface) {
|
||||
$this->resource = $this->resource->getConnection()->getResource();
|
||||
}
|
||||
if ($this->resource instanceof \PDO) {
|
||||
return $this->resource->quote($value);
|
||||
}
|
||||
trigger_error(
|
||||
'Attempting to quote a value in ' . __CLASS__ . ' without extension/driver support '
|
||||
. 'can introduce security vulnerabilities in a production environment.'
|
||||
);
|
||||
return '\'' . str_replace('\'', '\'\'', $value) . '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote Trusted Value
|
||||
*
|
||||
* The ability to quote values without notices
|
||||
*
|
||||
* @param $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function quoteTrustedValue($value)
|
||||
{
|
||||
if ($this->resource instanceof DriverInterface) {
|
||||
$this->resource = $this->resource->getConnection()->getResource();
|
||||
}
|
||||
if ($this->resource instanceof \PDO) {
|
||||
return $this->resource->quote($value);
|
||||
}
|
||||
return '\'' . str_replace('\'', '\'\'', $value) . '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote value list
|
||||
*
|
||||
* @param string|string[] $valueList
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValueList($valueList)
|
||||
{
|
||||
if (!is_array($valueList)) {
|
||||
return $this->quoteValue($valueList);
|
||||
}
|
||||
$value = reset($valueList);
|
||||
do {
|
||||
$valueList[key($valueList)] = $this->quoteValue($value);
|
||||
} while ($value = next($valueList));
|
||||
return implode(', ', $valueList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get identifier separator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifierSeparator()
|
||||
{
|
||||
return '.';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote identifier in fragment
|
||||
*
|
||||
* @param string $identifier
|
||||
* @param array $safeWords
|
||||
* @return string
|
||||
*/
|
||||
public function quoteIdentifierInFragment($identifier, array $safeWords = array())
|
||||
{
|
||||
$parts = preg_split('#([\.\s\W])#', $identifier, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
|
||||
if ($safeWords) {
|
||||
$safeWords = array_flip($safeWords);
|
||||
$safeWords = array_change_key_case($safeWords, CASE_LOWER);
|
||||
}
|
||||
foreach ($parts as $i => $part) {
|
||||
if ($safeWords && isset($safeWords[strtolower($part)])) {
|
||||
continue;
|
||||
}
|
||||
switch ($part) {
|
||||
case ' ':
|
||||
case '.':
|
||||
case '*':
|
||||
case 'AS':
|
||||
case 'As':
|
||||
case 'aS':
|
||||
case 'as':
|
||||
break;
|
||||
default:
|
||||
$parts[$i] = '[' . $part . ']';
|
||||
}
|
||||
}
|
||||
return implode('', $parts);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,204 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter\Platform;
|
||||
|
||||
use Zend\Db\Adapter\Driver\DriverInterface;
|
||||
use Zend\Db\Adapter\Driver\Pdo;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
|
||||
class Sqlite implements PlatformInterface
|
||||
{
|
||||
|
||||
/** @var \PDO */
|
||||
protected $resource = null;
|
||||
|
||||
public function __construct($driver = null)
|
||||
{
|
||||
if ($driver) {
|
||||
$this->setDriver($driver);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Zend\Db\Adapter\Driver\Pdo\Pdo||\PDO $driver
|
||||
* @throws \Zend\Db\Adapter\Exception\InvalidArgumentException
|
||||
* @return $this
|
||||
*/
|
||||
public function setDriver($driver)
|
||||
{
|
||||
if (($driver instanceof \PDO && $driver->getAttribute(\PDO::ATTR_DRIVER_NAME) == 'sqlite')
|
||||
|| ($driver instanceof Pdo\Pdo && $driver->getDatabasePlatformName() == 'Sqlite')
|
||||
) {
|
||||
$this->resource = $driver;
|
||||
return $this;
|
||||
}
|
||||
|
||||
throw new Exception\InvalidArgumentException('$driver must be a Sqlite PDO Zend\Db\Adapter\Driver, Sqlite PDO instance');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'SQLite';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get quote identifier symbol
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQuoteIdentifierSymbol()
|
||||
{
|
||||
return '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote identifier
|
||||
*
|
||||
* @param string $identifier
|
||||
* @return string
|
||||
*/
|
||||
public function quoteIdentifier($identifier)
|
||||
{
|
||||
return '"' . str_replace('"', '\\' . '"', $identifier) . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote identifier chain
|
||||
*
|
||||
* @param string|string[] $identifierChain
|
||||
* @return string
|
||||
*/
|
||||
public function quoteIdentifierChain($identifierChain)
|
||||
{
|
||||
$identifierChain = str_replace('"', '\\"', $identifierChain);
|
||||
if (is_array($identifierChain)) {
|
||||
$identifierChain = implode('"."', $identifierChain);
|
||||
}
|
||||
return '"' . $identifierChain . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get quote value symbol
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQuoteValueSymbol()
|
||||
{
|
||||
return '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote value
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValue($value)
|
||||
{
|
||||
if ($this->resource instanceof DriverInterface) {
|
||||
$this->resource = $this->resource->getConnection()->getResource();
|
||||
}
|
||||
if ($this->resource instanceof \PDO) {
|
||||
return $this->resource->quote($value);
|
||||
}
|
||||
trigger_error(
|
||||
'Attempting to quote a value in ' . __CLASS__ . ' without extension/driver support '
|
||||
. 'can introduce security vulnerabilities in a production environment.'
|
||||
);
|
||||
return '\'' . addcslashes($value, "\x00\n\r\\'\"\x1a") . '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote Trusted Value
|
||||
*
|
||||
* The ability to quote values without notices
|
||||
*
|
||||
* @param $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function quoteTrustedValue($value)
|
||||
{
|
||||
if ($this->resource instanceof DriverInterface) {
|
||||
$this->resource = $this->resource->getConnection()->getResource();
|
||||
}
|
||||
if ($this->resource instanceof \PDO) {
|
||||
return $this->resource->quote($value);
|
||||
}
|
||||
return '\'' . addcslashes($value, "\x00\n\r\\'\"\x1a") . '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote value list
|
||||
*
|
||||
* @param string|string[] $valueList
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValueList($valueList)
|
||||
{
|
||||
if (!is_array($valueList)) {
|
||||
return $this->quoteValue($valueList);
|
||||
}
|
||||
$value = reset($valueList);
|
||||
do {
|
||||
$valueList[key($valueList)] = $this->quoteValue($value);
|
||||
} while ($value = next($valueList));
|
||||
return implode(', ', $valueList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get identifier separator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifierSeparator()
|
||||
{
|
||||
return '.';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote identifier in fragment
|
||||
*
|
||||
* @param string $identifier
|
||||
* @param array $safeWords
|
||||
* @return string
|
||||
*/
|
||||
public function quoteIdentifierInFragment($identifier, array $safeWords = array())
|
||||
{
|
||||
$parts = preg_split('#([\.\s\W])#', $identifier, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
|
||||
if ($safeWords) {
|
||||
$safeWords = array_flip($safeWords);
|
||||
$safeWords = array_change_key_case($safeWords, CASE_LOWER);
|
||||
}
|
||||
foreach ($parts as $i => $part) {
|
||||
if ($safeWords && isset($safeWords[strtolower($part)])) {
|
||||
continue;
|
||||
}
|
||||
switch ($part) {
|
||||
case ' ':
|
||||
case '.':
|
||||
case '*':
|
||||
case 'AS':
|
||||
case 'As':
|
||||
case 'aS':
|
||||
case 'as':
|
||||
break;
|
||||
default:
|
||||
$parts[$i] = '"' . str_replace('"', '\\' . '"', $part) . '"';
|
||||
}
|
||||
}
|
||||
return implode('', $parts);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace Zend\Db\Adapter\Profiler;
|
||||
|
||||
use Zend\Db\Adapter\StatementContainerInterface;
|
||||
use Zend\Db\Adapter\Exception;
|
||||
|
||||
class Profiler implements ProfilerInterface
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $profiles = array();
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
protected $currentIndex = 0;
|
||||
|
||||
/**
|
||||
* @param string|StatementContainerInterface $target
|
||||
* @throws \Zend\Db\Adapter\Exception\InvalidArgumentException
|
||||
* @return Profiler
|
||||
*/
|
||||
public function profilerStart($target)
|
||||
{
|
||||
$profileInformation = array(
|
||||
'sql' => '',
|
||||
'parameters' => null,
|
||||
'start' => microtime(true),
|
||||
'end' => null,
|
||||
'elapse' => null
|
||||
);
|
||||
if ($target instanceof StatementContainerInterface) {
|
||||
$profileInformation['sql'] = $target->getSql();
|
||||
$profileInformation['parameters'] = clone $target->getParameterContainer();
|
||||
} elseif (is_string($target)) {
|
||||
$profileInformation['sql'] = $target;
|
||||
} else {
|
||||
throw new Exception\InvalidArgumentException(__FUNCTION__ . ' takes either a StatementContainer or a string');
|
||||
}
|
||||
|
||||
$this->profiles[$this->currentIndex] = $profileInformation;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Profiler
|
||||
*/
|
||||
public function profilerFinish()
|
||||
{
|
||||
if (!isset($this->profiles[$this->currentIndex])) {
|
||||
throw new Exception\RuntimeException('A profile must be started before ' . __FUNCTION__ . ' can be called.');
|
||||
}
|
||||
$current = &$this->profiles[$this->currentIndex];
|
||||
$current['end'] = microtime(true);
|
||||
$current['elapse'] = $current['end'] - $current['start'];
|
||||
$this->currentIndex++;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
public function getLastProfile()
|
||||
{
|
||||
return end($this->profiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getProfiles()
|
||||
{
|
||||
return $this->profiles;
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Zend\Db\Adapter\Profiler;
|
||||
|
||||
interface ProfilerAwareInterface
|
||||
{
|
||||
public function setProfiler(ProfilerInterface $profiler);
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Zend\Db\Adapter\Profiler;
|
||||
|
||||
interface ProfilerInterface
|
||||
{
|
||||
/**
|
||||
* @param string|\Zend\Db\Adapter\StatementContainerInterface $target
|
||||
* @return mixed
|
||||
*/
|
||||
public function profilerStart($target);
|
||||
public function profilerFinish();
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter;
|
||||
|
||||
class StatementContainer implements StatementContainerInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $sql = '';
|
||||
|
||||
/**
|
||||
* @var ParameterContainer
|
||||
*/
|
||||
protected $parameterContainer = null;
|
||||
|
||||
/**
|
||||
* @param string|null $sql
|
||||
* @param ParameterContainer|null $parameterContainer
|
||||
*/
|
||||
public function __construct($sql = null, ParameterContainer $parameterContainer = null)
|
||||
{
|
||||
if ($sql) {
|
||||
$this->setSql($sql);
|
||||
}
|
||||
$this->parameterContainer = ($parameterContainer) ?: new ParameterContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sql
|
||||
* @return StatementContainer
|
||||
*/
|
||||
public function setSql($sql)
|
||||
{
|
||||
$this->sql = $sql;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSql()
|
||||
{
|
||||
return $this->sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ParameterContainer $parameterContainer
|
||||
* @return StatementContainer
|
||||
*/
|
||||
public function setParameterContainer(ParameterContainer $parameterContainer)
|
||||
{
|
||||
$this->parameterContainer = $parameterContainer;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|ParameterContainer
|
||||
*/
|
||||
public function getParameterContainer()
|
||||
{
|
||||
return $this->parameterContainer;
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Adapter;
|
||||
|
||||
interface StatementContainerInterface
|
||||
{
|
||||
/**
|
||||
* Set sql
|
||||
*
|
||||
* @param $sql
|
||||
* @return mixed
|
||||
*/
|
||||
public function setSql($sql);
|
||||
|
||||
/**
|
||||
* Get sql
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getSql();
|
||||
|
||||
/**
|
||||
* Set parameter container
|
||||
*
|
||||
* @param ParameterContainer $parameterContainer
|
||||
* @return mixed
|
||||
*/
|
||||
public function setParameterContainer(ParameterContainer $parameterContainer);
|
||||
|
||||
/**
|
||||
* Get parameter container
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getParameterContainer();
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Exception;
|
||||
|
||||
class ErrorException extends \Exception implements ExceptionInterface
|
||||
{
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Exception;
|
||||
|
||||
interface ExceptionInterface
|
||||
{
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Exception;
|
||||
|
||||
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
|
||||
{
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Exception;
|
||||
|
||||
class RuntimeException extends \RuntimeException implements ExceptionInterface
|
||||
{
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Exception;
|
||||
|
||||
class UnexpectedValueException extends \UnexpectedValueException implements ExceptionInterface
|
||||
{
|
||||
}
|
249
bundled-libs/zendframework/zend-db/Zend/Db/Metadata/Metadata.php
Normal file
249
bundled-libs/zendframework/zend-db/Zend/Db/Metadata/Metadata.php
Normal file
@ -0,0 +1,249 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Metadata;
|
||||
|
||||
use Zend\Db\Adapter\Adapter;
|
||||
|
||||
class Metadata implements MetadataInterface
|
||||
{
|
||||
/**
|
||||
* Adapter
|
||||
*
|
||||
* @var Adapter
|
||||
*/
|
||||
protected $adapter = null;
|
||||
|
||||
/**
|
||||
* @var MetadataInterface
|
||||
*/
|
||||
protected $source = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Adapter $adapter
|
||||
*/
|
||||
public function __construct(Adapter $adapter)
|
||||
{
|
||||
$this->adapter = $adapter;
|
||||
$this->source = $this->createSourceFromAdapter($adapter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create source from adapter
|
||||
*
|
||||
* @param Adapter $adapter
|
||||
* @return Source\AbstractSource
|
||||
*/
|
||||
protected function createSourceFromAdapter(Adapter $adapter)
|
||||
{
|
||||
switch ($adapter->getPlatform()->getName()) {
|
||||
case 'MySQL':
|
||||
return new Source\MysqlMetadata($adapter);
|
||||
case 'SQLServer':
|
||||
return new Source\SqlServerMetadata($adapter);
|
||||
case 'SQLite':
|
||||
return new Source\SqliteMetadata($adapter);
|
||||
case 'PostgreSQL':
|
||||
return new Source\PostgresqlMetadata($adapter);
|
||||
}
|
||||
|
||||
throw new \Exception('cannot create source from adapter');
|
||||
}
|
||||
|
||||
// @todo methods
|
||||
|
||||
/**
|
||||
* Get base tables and views
|
||||
*
|
||||
* @param string $schema
|
||||
* @param bool $includeViews
|
||||
* @return Object\TableObject[]
|
||||
*/
|
||||
public function getTables($schema = null, $includeViews = false)
|
||||
{
|
||||
return $this->source->getTables($schema, $includeViews);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get base tables and views
|
||||
*
|
||||
* @param string $schema
|
||||
* @return Object\TableObject[]
|
||||
*/
|
||||
public function getViews($schema = null)
|
||||
{
|
||||
return $this->source->getViews($schema);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get triggers
|
||||
*
|
||||
* @param string $schema
|
||||
* @return array
|
||||
*/
|
||||
public function getTriggers($schema = null)
|
||||
{
|
||||
return $this->source->getTriggers($schema);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get constraints
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $schema
|
||||
* @return array
|
||||
*/
|
||||
public function getConstraints($table, $schema = null)
|
||||
{
|
||||
return $this->source->getConstraints($table, $schema);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get columns
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $schema
|
||||
* @return array
|
||||
*/
|
||||
public function getColumns($table, $schema = null)
|
||||
{
|
||||
return $this->source->getColumns($table, $schema);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get constraint keys
|
||||
*
|
||||
* @param string $constraint
|
||||
* @param string $table
|
||||
* @param string $schema
|
||||
* @return array
|
||||
*/
|
||||
public function getConstraintKeys($constraint, $table, $schema = null)
|
||||
{
|
||||
return $this->source->getConstraintKeys($constraint, $table, $schema);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get constraints
|
||||
*
|
||||
* @param string $constraintName
|
||||
* @param string $table
|
||||
* @param string $schema
|
||||
* @return Object\ConstraintObject
|
||||
*/
|
||||
public function getConstraint($constraintName, $table, $schema = null)
|
||||
{
|
||||
return $this->source->getConstraint($constraintName, $table, $schema);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get schemas
|
||||
*/
|
||||
public function getSchemas()
|
||||
{
|
||||
return $this->source->getSchemas();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get table names
|
||||
*
|
||||
* @param string $schema
|
||||
* @param bool $includeViews
|
||||
* @return array
|
||||
*/
|
||||
public function getTableNames($schema = null, $includeViews = false)
|
||||
{
|
||||
return $this->source->getTableNames($schema, $includeViews);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get table
|
||||
*
|
||||
* @param string $tableName
|
||||
* @param string $schema
|
||||
* @return Object\TableObject
|
||||
*/
|
||||
public function getTable($tableName, $schema = null)
|
||||
{
|
||||
return $this->source->getTable($tableName, $schema);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get views names
|
||||
*
|
||||
* @param string $schema
|
||||
* @return \Zend\Db\Metadata\Object\TableObject
|
||||
*/
|
||||
public function getViewNames($schema = null)
|
||||
{
|
||||
return $this->source->getTable($schema);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get view
|
||||
*
|
||||
* @param string $viewName
|
||||
* @param string $schema
|
||||
* @return \Zend\Db\Metadata\Object\TableObject
|
||||
*/
|
||||
public function getView($viewName, $schema = null)
|
||||
{
|
||||
return $this->source->getView($viewName, $schema);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get trigger names
|
||||
*
|
||||
* @param string $schema
|
||||
* @return array
|
||||
*/
|
||||
public function getTriggerNames($schema = null)
|
||||
{
|
||||
return $this->source->getTriggerNames($schema);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get trigger
|
||||
*
|
||||
* @param string $triggerName
|
||||
* @param string $schema
|
||||
* @return \Zend\Db\Metadata\Object\TriggerObject
|
||||
*/
|
||||
public function getTrigger($triggerName, $schema = null)
|
||||
{
|
||||
return $this->source->getTrigger($triggerName, $schema);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column names
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $schema
|
||||
* @return array
|
||||
*/
|
||||
public function getColumnNames($table, $schema = null)
|
||||
{
|
||||
return $this->source->getColumnNames($table, $schema);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column
|
||||
*
|
||||
* @param string $columnName
|
||||
* @param string $table
|
||||
* @param string $schema
|
||||
* @return \Zend\Db\Metadata\Object\ColumnObject
|
||||
*/
|
||||
public function getColumn($columnName, $table, $schema = null)
|
||||
{
|
||||
return $this->source->getColumn($columnName, $table, $schema);
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Metadata;
|
||||
|
||||
interface MetadataInterface
|
||||
{
|
||||
public function getSchemas();
|
||||
|
||||
public function getTableNames($schema = null, $includeViews = false);
|
||||
public function getTables($schema = null, $includeViews = false);
|
||||
public function getTable($tableName, $schema = null);
|
||||
|
||||
public function getViewNames($schema = null);
|
||||
public function getViews($schema = null);
|
||||
public function getView($viewName, $schema = null);
|
||||
|
||||
public function getColumnNames($table, $schema = null);
|
||||
public function getColumns($table, $schema = null);
|
||||
public function getColumn($columnName, $table, $schema = null);
|
||||
|
||||
public function getConstraints($table, $schema = null);
|
||||
public function getConstraint($constraintName, $table, $schema = null);
|
||||
public function getConstraintKeys($constraint, $table, $schema = null);
|
||||
|
||||
public function getTriggerNames($schema = null);
|
||||
public function getTriggers($schema = null);
|
||||
public function getTrigger($triggerName, $schema = null);
|
||||
|
||||
}
|
@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Metadata\Object;
|
||||
|
||||
abstract class AbstractTableObject
|
||||
{
|
||||
|
||||
/*
|
||||
protected $catalogName = null;
|
||||
protected $schemaName = null;
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $type = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $columns = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $constraints = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct($name)
|
||||
{
|
||||
if ($name) {
|
||||
$this->setName($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set columns
|
||||
*
|
||||
* @param array $columns
|
||||
*/
|
||||
public function setColumns(array $columns)
|
||||
{
|
||||
$this->columns = $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get columns
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getColumns()
|
||||
{
|
||||
return $this->columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set constraints
|
||||
*
|
||||
* @param array $constraints
|
||||
*/
|
||||
public function setConstraints($constraints)
|
||||
{
|
||||
$this->constraints = $constraints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get constraints
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getConstraints()
|
||||
{
|
||||
return $this->constraints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set name
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
}
|
@ -0,0 +1,389 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Metadata\Object;
|
||||
|
||||
class ColumnObject
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $tableName = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $schemaName = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var
|
||||
*/
|
||||
protected $ordinalPosition = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $columnDefault = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isNullable = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $dataType = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $characterMaximumLength = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $characterOctetLength = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $numericPrecision = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $numericScale = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $numericUnsigned = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $errata = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $tableName
|
||||
* @param string $schemaName
|
||||
*/
|
||||
public function __construct($name, $tableName, $schemaName = null)
|
||||
{
|
||||
$this->setName($name);
|
||||
$this->setTableName($tableName);
|
||||
$this->setSchemaName($schemaName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set name
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get table name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTableName()
|
||||
{
|
||||
return $this->tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set table name
|
||||
*
|
||||
* @param string $tableName
|
||||
* @return ColumnObject
|
||||
*/
|
||||
public function setTableName($tableName)
|
||||
{
|
||||
$this->tableName = $tableName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set schema name
|
||||
*
|
||||
* @param string $schemaName
|
||||
*/
|
||||
public function setSchemaName($schemaName)
|
||||
{
|
||||
$this->schemaName = $schemaName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get schema name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSchemaName()
|
||||
{
|
||||
return $this->schemaName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int $ordinalPosition
|
||||
*/
|
||||
public function getOrdinalPosition()
|
||||
{
|
||||
return $this->ordinalPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $ordinalPosition to set
|
||||
* @return ColumnObject
|
||||
*/
|
||||
public function setOrdinalPosition($ordinalPosition)
|
||||
{
|
||||
$this->ordinalPosition = $ordinalPosition;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|string the $columnDefault
|
||||
*/
|
||||
public function getColumnDefault()
|
||||
{
|
||||
return $this->columnDefault;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $columnDefault to set
|
||||
* @return ColumnObject
|
||||
*/
|
||||
public function setColumnDefault($columnDefault)
|
||||
{
|
||||
$this->columnDefault = $columnDefault;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool $isNullable
|
||||
*/
|
||||
public function getIsNullable()
|
||||
{
|
||||
return $this->isNullable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $isNullable to set
|
||||
* @return ColumnObject
|
||||
*/
|
||||
public function setIsNullable($isNullable)
|
||||
{
|
||||
$this->isNullable = $isNullable;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool $isNullable
|
||||
*/
|
||||
public function isNullable()
|
||||
{
|
||||
return $this->isNullable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|string the $dataType
|
||||
*/
|
||||
public function getDataType()
|
||||
{
|
||||
return $this->dataType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $dataType the $dataType to set
|
||||
* @return ColumnObject
|
||||
*/
|
||||
public function setDataType($dataType)
|
||||
{
|
||||
$this->dataType = $dataType;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|null the $characterMaximumLength
|
||||
*/
|
||||
public function getCharacterMaximumLength()
|
||||
{
|
||||
return $this->characterMaximumLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $characterMaximumLength the $characterMaximumLength to set
|
||||
* @return ColumnObject
|
||||
*/
|
||||
public function setCharacterMaximumLength($characterMaximumLength)
|
||||
{
|
||||
$this->characterMaximumLength = $characterMaximumLength;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|null the $characterOctetLength
|
||||
*/
|
||||
public function getCharacterOctetLength()
|
||||
{
|
||||
return $this->characterOctetLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $characterOctetLength the $characterOctetLength to set
|
||||
* @return ColumnObject
|
||||
*/
|
||||
public function setCharacterOctetLength($characterOctetLength)
|
||||
{
|
||||
$this->characterOctetLength = $characterOctetLength;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int the $numericPrecision
|
||||
*/
|
||||
public function getNumericPrecision()
|
||||
{
|
||||
return $this->numericPrecision;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $numericPrecision the $numericPrevision to set
|
||||
* @return ColumnObject
|
||||
*/
|
||||
public function setNumericPrecision($numericPrecision)
|
||||
{
|
||||
$this->numericPrecision = $numericPrecision;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int the $numericScale
|
||||
*/
|
||||
public function getNumericScale()
|
||||
{
|
||||
return $this->numericScale;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $numericScale the $numericScale to set
|
||||
* @return ColumnObject
|
||||
*/
|
||||
public function setNumericScale($numericScale)
|
||||
{
|
||||
$this->numericScale = $numericScale;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getNumericUnsigned()
|
||||
{
|
||||
return $this->numericUnsigned;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $numericUnsigned
|
||||
* @return ColumnObject
|
||||
*/
|
||||
public function setNumericUnsigned($numericUnsigned)
|
||||
{
|
||||
$this->numericUnsigned = $numericUnsigned;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isNumericUnsigned()
|
||||
{
|
||||
return $this->numericUnsigned;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array the $errata
|
||||
*/
|
||||
public function getErratas()
|
||||
{
|
||||
return $this->errata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $erratas
|
||||
* @return ColumnObject
|
||||
*/
|
||||
public function setErratas(array $erratas)
|
||||
{
|
||||
foreach ($erratas as $name => $value) {
|
||||
$this->setErrata($name, $value);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $errataName
|
||||
* @return mixed
|
||||
*/
|
||||
public function getErrata($errataName)
|
||||
{
|
||||
if (array_key_exists($errataName, $this->errata)) {
|
||||
return $this->errata[$errataName];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $errataName
|
||||
* @param mixed $errataValue
|
||||
* @return ColumnObject
|
||||
*/
|
||||
public function setErrata($errataName, $errataValue)
|
||||
{
|
||||
$this->errata[$errataName] = $errataValue;
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,411 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Metadata\Object;
|
||||
|
||||
class ConstraintObject
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $tableName = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $schemaName = null;
|
||||
|
||||
/**
|
||||
* One of "PRIMARY KEY", "UNIQUE", "FOREIGN KEY", or "CHECK"
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $type = null;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $columns = array();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $referencedTableSchema;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $referencedTableName;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $referencedColumns;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $matchOption;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $updateRule;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $deleteRule;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $checkClause;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $tableName
|
||||
* @param string $schemaName
|
||||
*/
|
||||
public function __construct($name, $tableName, $schemaName = null)
|
||||
{
|
||||
$this->setName($name);
|
||||
$this->setTableName($tableName);
|
||||
$this->setSchemaName($schemaName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set name
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set schema name
|
||||
*
|
||||
* @param string $schemaName
|
||||
*/
|
||||
public function setSchemaName($schemaName)
|
||||
{
|
||||
$this->schemaName = $schemaName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get schema name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSchemaName()
|
||||
{
|
||||
return $this->schemaName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get table name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTableName()
|
||||
{
|
||||
return $this->tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set table name
|
||||
*
|
||||
* @param string $tableName
|
||||
* @return ConstraintObject
|
||||
*/
|
||||
public function setTableName($tableName)
|
||||
{
|
||||
$this->tableName = $tableName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set type
|
||||
*
|
||||
* @param string $type
|
||||
*/
|
||||
public function setType($type)
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function hasColumns()
|
||||
{
|
||||
return (!empty($this->columns));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Columns.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getColumns()
|
||||
{
|
||||
return $this->columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Columns.
|
||||
*
|
||||
* @param string[] $columns
|
||||
* @return ConstraintObject
|
||||
*/
|
||||
public function setColumns(array $columns)
|
||||
{
|
||||
$this->columns = $columns;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Referenced Table Schema.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getReferencedTableSchema()
|
||||
{
|
||||
return $this->referencedTableSchema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Referenced Table Schema.
|
||||
*
|
||||
* @param string $referencedTableSchema
|
||||
* @return ConstraintObject
|
||||
*/
|
||||
public function setReferencedTableSchema($referencedTableSchema)
|
||||
{
|
||||
$this->referencedTableSchema = $referencedTableSchema;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Referenced Table Name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getReferencedTableName()
|
||||
{
|
||||
return $this->referencedTableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Referenced Table Name.
|
||||
*
|
||||
* @param string $referencedTableName
|
||||
* @return ConstraintObject
|
||||
*/
|
||||
public function setReferencedTableName($referencedTableName)
|
||||
{
|
||||
$this->referencedTableName = $referencedTableName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Referenced Columns.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getReferencedColumns()
|
||||
{
|
||||
return $this->referencedColumns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Referenced Columns.
|
||||
*
|
||||
* @param string[] $referencedColumns
|
||||
* @return ConstraintObject
|
||||
*/
|
||||
public function setReferencedColumns(array $referencedColumns)
|
||||
{
|
||||
$this->referencedColumns = $referencedColumns;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Match Option.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMatchOption()
|
||||
{
|
||||
return $this->matchOption;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Match Option.
|
||||
*
|
||||
* @param string $matchOption
|
||||
* @return ConstraintObject
|
||||
*/
|
||||
public function setMatchOption($matchOption)
|
||||
{
|
||||
$this->matchOption = $matchOption;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Update Rule.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUpdateRule()
|
||||
{
|
||||
return $this->updateRule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Update Rule.
|
||||
*
|
||||
* @param string $updateRule
|
||||
* @return ConstraintObject
|
||||
*/
|
||||
public function setUpdateRule($updateRule)
|
||||
{
|
||||
$this->updateRule = $updateRule;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Delete Rule.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDeleteRule()
|
||||
{
|
||||
return $this->deleteRule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Delete Rule.
|
||||
*
|
||||
* @param string $deleteRule
|
||||
* @return ConstraintObject
|
||||
*/
|
||||
public function setDeleteRule($deleteRule)
|
||||
{
|
||||
$this->deleteRule = $deleteRule;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Check Clause.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCheckClause()
|
||||
{
|
||||
return $this->checkClause;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Check Clause.
|
||||
*
|
||||
* @param string $checkClause
|
||||
* @return ConstraintObject
|
||||
*/
|
||||
public function setCheckClause($checkClause)
|
||||
{
|
||||
$this->checkClause = $checkClause;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is primary key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPrimaryKey()
|
||||
{
|
||||
return ('PRIMARY KEY' == $this->type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is unique key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isUnique()
|
||||
{
|
||||
return ('UNIQUE' == $this->type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is foreign key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isForeignKey()
|
||||
{
|
||||
return ('FOREIGN KEY' == $this->type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is foreign key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isCheck()
|
||||
{
|
||||
return ('CHECK' == $this->type);
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Metadata\Object;
|
||||
|
||||
class TableObject extends AbstractTableObject
|
||||
{
|
||||
}
|
@ -0,0 +1,448 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Metadata\Object;
|
||||
|
||||
class TriggerObject
|
||||
{
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $eventManipulation;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $eventObjectCatalog;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $eventObjectSchema;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $eventObjectTable;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $actionOrder;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $actionCondition;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $actionStatement;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $actionOrientation;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $actionTiming;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $actionReferenceOldTable;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $actionReferenceNewTable;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $actionReferenceOldRow;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $actionReferenceNewRow;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var \DateTime
|
||||
*/
|
||||
protected $created;
|
||||
|
||||
/**
|
||||
* Get Name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Name.
|
||||
*
|
||||
* @param string $name
|
||||
* @return TriggerObject
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Event Manipulation.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getEventManipulation()
|
||||
{
|
||||
return $this->eventManipulation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Event Manipulation.
|
||||
*
|
||||
* @param string $eventManipulation
|
||||
* @return TriggerObject
|
||||
*/
|
||||
public function setEventManipulation($eventManipulation)
|
||||
{
|
||||
$this->eventManipulation = $eventManipulation;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Event Object Catalog.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getEventObjectCatalog()
|
||||
{
|
||||
return $this->eventObjectCatalog;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Event Object Catalog.
|
||||
*
|
||||
* @param string $eventObjectCatalog
|
||||
* @return TriggerObject
|
||||
*/
|
||||
public function setEventObjectCatalog($eventObjectCatalog)
|
||||
{
|
||||
$this->eventObjectCatalog = $eventObjectCatalog;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Event Object Schema.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getEventObjectSchema()
|
||||
{
|
||||
return $this->eventObjectSchema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Event Object Schema.
|
||||
*
|
||||
* @param string $eventObjectSchema
|
||||
* @return TriggerObject
|
||||
*/
|
||||
public function setEventObjectSchema($eventObjectSchema)
|
||||
{
|
||||
$this->eventObjectSchema = $eventObjectSchema;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Event Object Table.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getEventObjectTable()
|
||||
{
|
||||
return $this->eventObjectTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Event Object Table.
|
||||
*
|
||||
* @param string $eventObjectTable
|
||||
* @return TriggerObject
|
||||
*/
|
||||
public function setEventObjectTable($eventObjectTable)
|
||||
{
|
||||
$this->eventObjectTable = $eventObjectTable;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Action Order.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getActionOrder()
|
||||
{
|
||||
return $this->actionOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Action Order.
|
||||
*
|
||||
* @param string $actionOrder
|
||||
* @return TriggerObject
|
||||
*/
|
||||
public function setActionOrder($actionOrder)
|
||||
{
|
||||
$this->actionOrder = $actionOrder;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Action Condition.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getActionCondition()
|
||||
{
|
||||
return $this->actionCondition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Action Condition.
|
||||
*
|
||||
* @param string $actionCondition
|
||||
* @return TriggerObject
|
||||
*/
|
||||
public function setActionCondition($actionCondition)
|
||||
{
|
||||
$this->actionCondition = $actionCondition;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Action Statement.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getActionStatement()
|
||||
{
|
||||
return $this->actionStatement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Action Statement.
|
||||
*
|
||||
* @param string $actionStatement
|
||||
* @return TriggerObject
|
||||
*/
|
||||
public function setActionStatement($actionStatement)
|
||||
{
|
||||
$this->actionStatement = $actionStatement;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Action Orientation.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getActionOrientation()
|
||||
{
|
||||
return $this->actionOrientation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Action Orientation.
|
||||
*
|
||||
* @param string $actionOrientation
|
||||
* @return TriggerObject
|
||||
*/
|
||||
public function setActionOrientation($actionOrientation)
|
||||
{
|
||||
$this->actionOrientation = $actionOrientation;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Action Timing.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getActionTiming()
|
||||
{
|
||||
return $this->actionTiming;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Action Timing.
|
||||
*
|
||||
* @param string $actionTiming
|
||||
* @return TriggerObject
|
||||
*/
|
||||
public function setActionTiming($actionTiming)
|
||||
{
|
||||
$this->actionTiming = $actionTiming;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Action Reference Old Table.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getActionReferenceOldTable()
|
||||
{
|
||||
return $this->actionReferenceOldTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Action Reference Old Table.
|
||||
*
|
||||
* @param string $actionReferenceOldTable
|
||||
* @return TriggerObject
|
||||
*/
|
||||
public function setActionReferenceOldTable($actionReferenceOldTable)
|
||||
{
|
||||
$this->actionReferenceOldTable = $actionReferenceOldTable;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Action Reference New Table.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getActionReferenceNewTable()
|
||||
{
|
||||
return $this->actionReferenceNewTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Action Reference New Table.
|
||||
*
|
||||
* @param string $actionReferenceNewTable
|
||||
* @return TriggerObject
|
||||
*/
|
||||
public function setActionReferenceNewTable($actionReferenceNewTable)
|
||||
{
|
||||
$this->actionReferenceNewTable = $actionReferenceNewTable;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Action Reference Old Row.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getActionReferenceOldRow()
|
||||
{
|
||||
return $this->actionReferenceOldRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Action Reference Old Row.
|
||||
*
|
||||
* @param string $actionReferenceOldRow
|
||||
* @return TriggerObject
|
||||
*/
|
||||
public function setActionReferenceOldRow($actionReferenceOldRow)
|
||||
{
|
||||
$this->actionReferenceOldRow = $actionReferenceOldRow;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Action Reference New Row.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getActionReferenceNewRow()
|
||||
{
|
||||
return $this->actionReferenceNewRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Action Reference New Row.
|
||||
*
|
||||
* @param string $actionReferenceNewRow
|
||||
* @return TriggerObject
|
||||
*/
|
||||
public function setActionReferenceNewRow($actionReferenceNewRow)
|
||||
{
|
||||
$this->actionReferenceNewRow = $actionReferenceNewRow;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Created.
|
||||
*
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getCreated()
|
||||
{
|
||||
return $this->created;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Created.
|
||||
*
|
||||
* @param \DateTime $created
|
||||
* @return TriggerObject
|
||||
*/
|
||||
public function setCreated($created)
|
||||
{
|
||||
$this->created = $created;
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Metadata\Object;
|
||||
|
||||
class ViewObject extends AbstractTableObject
|
||||
{
|
||||
protected $viewDefinition;
|
||||
protected $checkOption;
|
||||
protected $isUpdatable;
|
||||
|
||||
/**
|
||||
* @return string $viewDefinition
|
||||
*/
|
||||
public function getViewDefinition()
|
||||
{
|
||||
return $this->viewDefinition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $viewDefinition to set
|
||||
* @return ViewObject
|
||||
*/
|
||||
public function setViewDefinition($viewDefinition)
|
||||
{
|
||||
$this->viewDefinition = $viewDefinition;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string $checkOption
|
||||
*/
|
||||
public function getCheckOption()
|
||||
{
|
||||
return $this->checkOption;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $checkOption to set
|
||||
* @return ViewObject
|
||||
*/
|
||||
public function setCheckOption($checkOption)
|
||||
{
|
||||
$this->checkOption = $checkOption;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool $isUpdatable
|
||||
*/
|
||||
public function getIsUpdatable()
|
||||
{
|
||||
return $this->isUpdatable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $isUpdatable to set
|
||||
* @return ViewObject
|
||||
*/
|
||||
public function setIsUpdatable($isUpdatable)
|
||||
{
|
||||
$this->isUpdatable = $isUpdatable;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isUpdatable()
|
||||
{
|
||||
return $this->isUpdatable;
|
||||
}
|
||||
}
|
@ -0,0 +1,602 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Metadata\Source;
|
||||
|
||||
use Zend\Db\Adapter\Adapter;
|
||||
use Zend\Db\Metadata\MetadataInterface;
|
||||
use Zend\Db\Metadata\Object;
|
||||
|
||||
abstract class AbstractSource implements MetadataInterface
|
||||
{
|
||||
const DEFAULT_SCHEMA = '__DEFAULT_SCHEMA__';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Adapter
|
||||
*/
|
||||
protected $adapter = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $defaultSchema = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $data = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Adapter $adapter
|
||||
*/
|
||||
public function __construct(Adapter $adapter)
|
||||
{
|
||||
$this->adapter = $adapter;
|
||||
$this->defaultSchema = ($adapter->getCurrentSchema()) ?: self::DEFAULT_SCHEMA;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get schemas
|
||||
*
|
||||
*/
|
||||
public function getSchemas()
|
||||
{
|
||||
$this->loadSchemaData();
|
||||
|
||||
return $this->data['schemas'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get table names
|
||||
*
|
||||
* @param string $schema
|
||||
* @param bool $includeViews
|
||||
* @return string[]
|
||||
*/
|
||||
public function getTableNames($schema = null, $includeViews = false)
|
||||
{
|
||||
if ($schema === null) {
|
||||
$schema = $this->defaultSchema;
|
||||
}
|
||||
|
||||
$this->loadTableNameData($schema);
|
||||
|
||||
if ($includeViews) {
|
||||
return array_keys($this->data['table_names'][$schema]);
|
||||
}
|
||||
|
||||
$tableNames = array();
|
||||
foreach ($this->data['table_names'][$schema] as $tableName => $data) {
|
||||
if ('BASE TABLE' == $data['table_type']) {
|
||||
$tableNames[] = $tableName;
|
||||
}
|
||||
}
|
||||
return $tableNames;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tables
|
||||
*
|
||||
* @param string $schema
|
||||
* @param bool $includeViews
|
||||
* @return Object\TableObject[]
|
||||
*/
|
||||
public function getTables($schema = null, $includeViews = false)
|
||||
{
|
||||
if ($schema === null) {
|
||||
$schema = $this->defaultSchema;
|
||||
}
|
||||
|
||||
$tables = array();
|
||||
foreach ($this->getTableNames($schema, $includeViews) as $tableName) {
|
||||
$tables[] = $this->getTable($tableName, $schema);
|
||||
}
|
||||
return $tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get table
|
||||
*
|
||||
* @param string $tableName
|
||||
* @param string $schema
|
||||
* @return Object\TableObject
|
||||
*/
|
||||
public function getTable($tableName, $schema = null)
|
||||
{
|
||||
if ($schema === null) {
|
||||
$schema = $this->defaultSchema;
|
||||
}
|
||||
|
||||
$this->loadTableNameData($schema);
|
||||
|
||||
if (!isset($this->data['table_names'][$schema][$tableName])) {
|
||||
throw new \Exception('Table "' . $tableName . '" does not exist');
|
||||
}
|
||||
|
||||
$data = $this->data['table_names'][$schema][$tableName];
|
||||
switch ($data['table_type']) {
|
||||
case 'BASE TABLE':
|
||||
$table = new Object\TableObject($tableName);
|
||||
break;
|
||||
case 'VIEW':
|
||||
$table = new Object\ViewObject($tableName);
|
||||
$table->setViewDefinition($data['view_definition']);
|
||||
$table->setCheckOption($data['check_option']);
|
||||
$table->setIsUpdatable($data['is_updatable']);
|
||||
break;
|
||||
default:
|
||||
throw new \Exception('Table "' . $tableName . '" is of an unsupported type "' . $data['table_type'] . '"');
|
||||
}
|
||||
$table->setColumns($this->getColumns($tableName, $schema));
|
||||
$table->setConstraints($this->getConstraints($tableName, $schema));
|
||||
return $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get view names
|
||||
*
|
||||
* @param string $schema
|
||||
* @return array
|
||||
*/
|
||||
public function getViewNames($schema = null)
|
||||
{
|
||||
if ($schema === null) {
|
||||
$schema = $this->defaultSchema;
|
||||
}
|
||||
|
||||
$this->loadTableNameData($schema);
|
||||
|
||||
$viewNames = array();
|
||||
foreach ($this->data['table_names'][$schema] as $tableName => $data) {
|
||||
if ('VIEW' == $data['table_type']) {
|
||||
$viewNames[] = $tableName;
|
||||
}
|
||||
}
|
||||
return $viewNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get views
|
||||
*
|
||||
* @param string $schema
|
||||
* @return array
|
||||
*/
|
||||
public function getViews($schema = null)
|
||||
{
|
||||
if ($schema === null) {
|
||||
$schema = $this->defaultSchema;
|
||||
}
|
||||
|
||||
$views = array();
|
||||
foreach ($this->getViewNames($schema) as $tableName) {
|
||||
$views[] = $this->getTable($tableName, $schema);
|
||||
}
|
||||
return $views;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get view
|
||||
*
|
||||
* @param string $viewName
|
||||
* @param string $schema
|
||||
* @return \Zend\Db\Metadata\Object\TableObject
|
||||
*/
|
||||
public function getView($viewName, $schema = null)
|
||||
{
|
||||
if ($schema === null) {
|
||||
$schema = $this->defaultSchema;
|
||||
}
|
||||
|
||||
$this->loadTableNameData($schema);
|
||||
|
||||
$tableNames = $this->data['table_names'][$schema];
|
||||
if (isset($tableNames[$viewName]) && 'VIEW' == $tableNames[$viewName]['table_type']) {
|
||||
return $this->getTable($viewName, $schema);
|
||||
}
|
||||
throw new \Exception('View "' . $viewName . '" does not exist');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gt column names
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $schema
|
||||
* @return array
|
||||
*/
|
||||
public function getColumnNames($table, $schema = null)
|
||||
{
|
||||
if ($schema === null) {
|
||||
$schema = $this->defaultSchema;
|
||||
}
|
||||
|
||||
$this->loadColumnData($table, $schema);
|
||||
|
||||
if (!isset($this->data['columns'][$schema][$table])) {
|
||||
throw new \Exception('"' . $table . '" does not exist');
|
||||
}
|
||||
|
||||
return array_keys($this->data['columns'][$schema][$table]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get columns
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $schema
|
||||
* @return array
|
||||
*/
|
||||
public function getColumns($table, $schema = null)
|
||||
{
|
||||
if ($schema === null) {
|
||||
$schema = $this->defaultSchema;
|
||||
}
|
||||
|
||||
$this->loadColumnData($table, $schema);
|
||||
|
||||
$columns = array();
|
||||
foreach ($this->getColumnNames($table, $schema) as $columnName) {
|
||||
$columns[] = $this->getColumn($columnName, $table, $schema);
|
||||
}
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column
|
||||
*
|
||||
* @param string $columnName
|
||||
* @param string $table
|
||||
* @param string $schema
|
||||
* @return Object\ColumnObject
|
||||
*/
|
||||
public function getColumn($columnName, $table, $schema = null)
|
||||
{
|
||||
if ($schema === null) {
|
||||
$schema = $this->defaultSchema;
|
||||
}
|
||||
|
||||
$this->loadColumnData($table, $schema);
|
||||
|
||||
if (!isset($this->data['columns'][$schema][$table][$columnName])) {
|
||||
throw new \Exception('A column by that name was not found.');
|
||||
}
|
||||
|
||||
$info = $this->data['columns'][$schema][$table][$columnName];
|
||||
|
||||
$column = new Object\ColumnObject($columnName, $table, $schema);
|
||||
$props = array(
|
||||
'ordinal_position', 'column_default', 'is_nullable',
|
||||
'data_type', 'character_maximum_length', 'character_octet_length',
|
||||
'numeric_precision', 'numeric_scale', 'numeric_unsigned',
|
||||
'erratas'
|
||||
);
|
||||
foreach ($props as $prop) {
|
||||
if (isset($info[$prop])) {
|
||||
$column->{'set' . str_replace('_', '', $prop)}($info[$prop]);
|
||||
}
|
||||
}
|
||||
|
||||
$column->setOrdinalPosition($info['ordinal_position']);
|
||||
$column->setColumnDefault($info['column_default']);
|
||||
$column->setIsNullable($info['is_nullable']);
|
||||
$column->setDataType($info['data_type']);
|
||||
$column->setCharacterMaximumLength($info['character_maximum_length']);
|
||||
$column->setCharacterOctetLength($info['character_octet_length']);
|
||||
$column->setNumericPrecision($info['numeric_precision']);
|
||||
$column->setNumericScale($info['numeric_scale']);
|
||||
$column->setNumericUnsigned($info['numeric_unsigned']);
|
||||
$column->setErratas($info['erratas']);
|
||||
|
||||
return $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get constraints
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $schema
|
||||
* @return array
|
||||
*/
|
||||
public function getConstraints($table, $schema = null)
|
||||
{
|
||||
if ($schema === null) {
|
||||
$schema = $this->defaultSchema;
|
||||
}
|
||||
|
||||
$this->loadConstraintData($table, $schema);
|
||||
|
||||
$constraints = array();
|
||||
foreach (array_keys($this->data['constraints'][$schema][$table]) as $constraintName) {
|
||||
$constraints[] = $this->getConstraint($constraintName, $table, $schema);
|
||||
}
|
||||
|
||||
return $constraints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get constraint
|
||||
*
|
||||
* @param string $constraintName
|
||||
* @param string $table
|
||||
* @param string $schema
|
||||
* @return Object\ConstraintObject
|
||||
*/
|
||||
public function getConstraint($constraintName, $table, $schema = null)
|
||||
{
|
||||
if ($schema === null) {
|
||||
$schema = $this->defaultSchema;
|
||||
}
|
||||
|
||||
$this->loadConstraintData($table, $schema);
|
||||
|
||||
if (!isset($this->data['constraints'][$schema][$table][$constraintName])) {
|
||||
throw new \Exception('Cannot find a constraint by that name in this table');
|
||||
}
|
||||
|
||||
$info = $this->data['constraints'][$schema][$table][$constraintName];
|
||||
$constraint = new Object\ConstraintObject($constraintName, $table, $schema);
|
||||
|
||||
foreach (array(
|
||||
'constraint_type' => 'setType',
|
||||
'match_option' => 'setMatchOption',
|
||||
'update_rule' => 'setUpdateRule',
|
||||
'delete_rule' => 'setDeleteRule',
|
||||
'columns' => 'setColumns',
|
||||
'referenced_table_schema' => 'setReferencedTableSchema',
|
||||
'referenced_table_name' => 'setReferencedTableName',
|
||||
'referenced_columns' => 'setReferencedColumns',
|
||||
'check_clause' => 'setCheckClause',
|
||||
) as $key => $setMethod) {
|
||||
if (isset($info[$key])) {
|
||||
$constraint->{$setMethod}($info[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
return $constraint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get constraint keys
|
||||
*
|
||||
* @param string $constraint
|
||||
* @param string $table
|
||||
* @param string $schema
|
||||
* @return array
|
||||
*/
|
||||
public function getConstraintKeys($constraint, $table, $schema = null)
|
||||
{
|
||||
if ($schema === null) {
|
||||
$schema = $this->defaultSchema;
|
||||
}
|
||||
|
||||
$this->loadConstraintReferences($table, $schema);
|
||||
|
||||
// organize references first
|
||||
$references = array();
|
||||
foreach ($this->data['constraint_references'][$schema] as $refKeyInfo) {
|
||||
if ($refKeyInfo['constraint_name'] == $constraint) {
|
||||
$references[$refKeyInfo['constraint_name']] = $refKeyInfo;
|
||||
}
|
||||
}
|
||||
|
||||
$this->loadConstraintDataKeys($schema);
|
||||
|
||||
$keys = array();
|
||||
foreach ($this->data['constraint_keys'][$schema] as $constraintKeyInfo) {
|
||||
if ($constraintKeyInfo['table_name'] == $table && $constraintKeyInfo['constraint_name'] === $constraint) {
|
||||
$keys[] = $key = new Object\ConstraintKeyObject($constraintKeyInfo['column_name']);
|
||||
$key->setOrdinalPosition($constraintKeyInfo['ordinal_position']);
|
||||
if (isset($references[$constraint])) {
|
||||
//$key->setReferencedTableSchema($constraintKeyInfo['referenced_table_schema']);
|
||||
$key->setForeignKeyUpdateRule($references[$constraint]['update_rule']);
|
||||
$key->setForeignKeyDeleteRule($references[$constraint]['delete_rule']);
|
||||
//$key->setReferencedTableSchema($references[$constraint]['referenced_table_schema']);
|
||||
$key->setReferencedTableName($references[$constraint]['referenced_table_name']);
|
||||
$key->setReferencedColumnName($references[$constraint]['referenced_column_name']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get trigger names
|
||||
*
|
||||
* @param string $schema
|
||||
* @return array
|
||||
*/
|
||||
public function getTriggerNames($schema = null)
|
||||
{
|
||||
if ($schema === null) {
|
||||
$schema = $this->defaultSchema;
|
||||
}
|
||||
|
||||
$this->loadTriggerData($schema);
|
||||
|
||||
return array_keys($this->data['triggers'][$schema]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get triggers
|
||||
*
|
||||
* @param string $schema
|
||||
* @return array
|
||||
*/
|
||||
public function getTriggers($schema = null)
|
||||
{
|
||||
if ($schema === null) {
|
||||
$schema = $this->defaultSchema;
|
||||
}
|
||||
|
||||
$triggers = array();
|
||||
foreach ($this->getTriggerNames($schema) as $triggerName) {
|
||||
$triggers[] = $this->getTrigger($triggerName, $schema);
|
||||
}
|
||||
return $triggers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get trigger
|
||||
*
|
||||
* @param string $triggerName
|
||||
* @param string $schema
|
||||
* @return Object\TriggerObject
|
||||
*/
|
||||
public function getTrigger($triggerName, $schema = null)
|
||||
{
|
||||
if ($schema === null) {
|
||||
$schema = $this->defaultSchema;
|
||||
}
|
||||
|
||||
$this->loadTriggerData($schema);
|
||||
|
||||
if (!isset($this->data['triggers'][$schema][$triggerName])) {
|
||||
throw new \Exception('Trigger "' . $triggerName . '" does not exist');
|
||||
}
|
||||
|
||||
$info = $this->data['triggers'][$schema][$triggerName];
|
||||
|
||||
$trigger = new Object\TriggerObject();
|
||||
|
||||
$trigger->setName($triggerName);
|
||||
$trigger->setEventManipulation($info['event_manipulation']);
|
||||
$trigger->setEventObjectCatalog($info['event_object_catalog']);
|
||||
$trigger->setEventObjectSchema($info['event_object_schema']);
|
||||
$trigger->setEventObjectTable($info['event_object_table']);
|
||||
$trigger->setActionOrder($info['action_order']);
|
||||
$trigger->setActionCondition($info['action_condition']);
|
||||
$trigger->setActionStatement($info['action_statement']);
|
||||
$trigger->setActionOrientation($info['action_orientation']);
|
||||
$trigger->setActionTiming($info['action_timing']);
|
||||
$trigger->setActionReferenceOldTable($info['action_reference_old_table']);
|
||||
$trigger->setActionReferenceNewTable($info['action_reference_new_table']);
|
||||
$trigger->setActionReferenceOldRow($info['action_reference_old_row']);
|
||||
$trigger->setActionReferenceNewRow($info['action_reference_new_row']);
|
||||
$trigger->setCreated($info['created']);
|
||||
|
||||
return $trigger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare data hierarchy
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $key ...
|
||||
*/
|
||||
protected function prepareDataHierarchy($type)
|
||||
{
|
||||
$data = &$this->data;
|
||||
foreach (func_get_args() as $key) {
|
||||
if (!isset($data[$key])) {
|
||||
$data[$key] = array();
|
||||
}
|
||||
$data = &$data[$key];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load schema data
|
||||
*/
|
||||
protected function loadSchemaData()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Load table name data
|
||||
*
|
||||
* @param string $schema
|
||||
*/
|
||||
protected function loadTableNameData($schema)
|
||||
{
|
||||
if (isset($this->data['table_names'][$schema])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->prepareDataHierarchy('table_names', $schema);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load column data
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $schema
|
||||
*/
|
||||
protected function loadColumnData($table, $schema)
|
||||
{
|
||||
if (isset($this->data['columns'][$schema][$table])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->prepareDataHierarchy('columns', $schema, $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load constraint data
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $schema
|
||||
*/
|
||||
protected function loadConstraintData($table, $schema)
|
||||
{
|
||||
if (isset($this->data['constraints'][$schema])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->prepareDataHierarchy('constraints', $schema);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load constraint data keys
|
||||
*
|
||||
* @param string $schema
|
||||
*/
|
||||
protected function loadConstraintDataKeys($schema)
|
||||
{
|
||||
if (isset($this->data['constraint_keys'][$schema])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->prepareDataHierarchy('constraint_keys', $schema);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load constraint references
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $schema
|
||||
*/
|
||||
protected function loadConstraintReferences($table, $schema)
|
||||
{
|
||||
if (isset($this->data['constraint_references'][$schema])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->prepareDataHierarchy('constraint_references', $schema);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load trigger data
|
||||
*
|
||||
* @param string $schema
|
||||
*/
|
||||
protected function loadTriggerData($schema)
|
||||
{
|
||||
if (isset($this->data['triggers'][$schema])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->prepareDataHierarchy('triggers', $schema);
|
||||
}
|
||||
}
|
@ -0,0 +1,493 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Metadata\Source;
|
||||
|
||||
use Zend\Db\Adapter\Adapter;
|
||||
|
||||
class MysqlMetadata extends AbstractSource
|
||||
{
|
||||
protected function loadSchemaData()
|
||||
{
|
||||
if (isset($this->data['schemas'])) {
|
||||
return;
|
||||
}
|
||||
$this->prepareDataHierarchy('schemas');
|
||||
|
||||
$p = $this->adapter->getPlatform();
|
||||
|
||||
$sql = 'SELECT ' . $p->quoteIdentifier('SCHEMA_NAME')
|
||||
. ' FROM ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'SCHEMATA'))
|
||||
. ' WHERE ' . $p->quoteIdentifier('SCHEMA_NAME')
|
||||
. ' != \'INFORMATION_SCHEMA\'';
|
||||
|
||||
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
|
||||
|
||||
$schemas = array();
|
||||
foreach ($results->toArray() as $row) {
|
||||
$schemas[] = $row['SCHEMA_NAME'];
|
||||
}
|
||||
|
||||
$this->data['schemas'] = $schemas;
|
||||
}
|
||||
|
||||
protected function loadTableNameData($schema)
|
||||
{
|
||||
if (isset($this->data['table_names'][$schema])) {
|
||||
return;
|
||||
}
|
||||
$this->prepareDataHierarchy('table_names', $schema);
|
||||
|
||||
$p = $this->adapter->getPlatform();
|
||||
|
||||
$isColumns = array(
|
||||
array('T', 'TABLE_NAME'),
|
||||
array('T', 'TABLE_TYPE'),
|
||||
array('V', 'VIEW_DEFINITION'),
|
||||
array('V', 'CHECK_OPTION'),
|
||||
array('V', 'IS_UPDATABLE'),
|
||||
);
|
||||
|
||||
array_walk($isColumns, function (&$c) use ($p) { $c = $p->quoteIdentifierChain($c); });
|
||||
|
||||
$sql = 'SELECT ' . implode(', ', $isColumns)
|
||||
. ' FROM ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'TABLES')) . 'T'
|
||||
|
||||
. ' LEFT JOIN ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'VIEWS')) . ' V'
|
||||
. ' ON ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('V', 'TABLE_SCHEMA'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_NAME'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('V', 'TABLE_NAME'))
|
||||
|
||||
. ' WHERE ' . $p->quoteIdentifierChain(array('T', 'TABLE_TYPE'))
|
||||
. ' IN (\'BASE TABLE\', \'VIEW\')';
|
||||
|
||||
if ($schema != self::DEFAULT_SCHEMA) {
|
||||
$sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' = ' . $p->quoteTrustedValue($schema);
|
||||
} else {
|
||||
$sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' != \'INFORMATION_SCHEMA\'';
|
||||
}
|
||||
|
||||
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
|
||||
|
||||
$tables = array();
|
||||
foreach ($results->toArray() as $row) {
|
||||
$tables[$row['TABLE_NAME']] = array(
|
||||
'table_type' => $row['TABLE_TYPE'],
|
||||
'view_definition' => $row['VIEW_DEFINITION'],
|
||||
'check_option' => $row['CHECK_OPTION'],
|
||||
'is_updatable' => ('YES' == $row['IS_UPDATABLE']),
|
||||
);
|
||||
}
|
||||
|
||||
$this->data['table_names'][$schema] = $tables;
|
||||
}
|
||||
|
||||
protected function loadColumnData($table, $schema)
|
||||
{
|
||||
if (isset($this->data['columns'][$schema][$table])) {
|
||||
return;
|
||||
}
|
||||
$this->prepareDataHierarchy('columns', $schema, $table);
|
||||
$p = $this->adapter->getPlatform();
|
||||
|
||||
$isColumns = array(
|
||||
array('C', 'ORDINAL_POSITION'),
|
||||
array('C', 'COLUMN_DEFAULT'),
|
||||
array('C', 'IS_NULLABLE'),
|
||||
array('C', 'DATA_TYPE'),
|
||||
array('C', 'CHARACTER_MAXIMUM_LENGTH'),
|
||||
array('C', 'CHARACTER_OCTET_LENGTH'),
|
||||
array('C', 'NUMERIC_PRECISION'),
|
||||
array('C', 'NUMERIC_SCALE'),
|
||||
array('C', 'COLUMN_NAME'),
|
||||
array('C', 'COLUMN_TYPE'),
|
||||
);
|
||||
|
||||
array_walk($isColumns, function (&$c) use ($p) { $c = $p->quoteIdentifierChain($c); });
|
||||
|
||||
$sql = 'SELECT ' . implode(', ', $isColumns)
|
||||
. ' FROM ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'TABLES')) . 'T'
|
||||
. ' INNER JOIN ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'COLUMNS')) . 'C'
|
||||
. ' ON ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('C', 'TABLE_SCHEMA'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_NAME'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('C', 'TABLE_NAME'))
|
||||
. ' WHERE ' . $p->quoteIdentifierChain(array('T', 'TABLE_TYPE'))
|
||||
. ' IN (\'BASE TABLE\', \'VIEW\')'
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_NAME'))
|
||||
. ' = ' . $p->quoteTrustedValue($table);
|
||||
|
||||
if ($schema != self::DEFAULT_SCHEMA) {
|
||||
$sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' = ' . $p->quoteTrustedValue($schema);
|
||||
} else {
|
||||
$sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' != \'INFORMATION_SCHEMA\'';
|
||||
}
|
||||
|
||||
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
|
||||
$columns = array();
|
||||
foreach ($results->toArray() as $row) {
|
||||
$erratas = array();
|
||||
$matches = array();
|
||||
if (preg_match('/^(?:enum|set)\((.+)\)$/i', $row['COLUMN_TYPE'], $matches)) {
|
||||
$permittedValues = $matches[1];
|
||||
if (preg_match_all("/\\s*'((?:[^']++|'')*+)'\\s*(?:,|\$)/", $permittedValues, $matches, PREG_PATTERN_ORDER)) {
|
||||
$permittedValues = str_replace("''", "'", $matches[1]);
|
||||
} else {
|
||||
$permittedValues = array($permittedValues);
|
||||
}
|
||||
$erratas['permitted_values'] = $permittedValues;
|
||||
}
|
||||
$columns[$row['COLUMN_NAME']] = array(
|
||||
'ordinal_position' => $row['ORDINAL_POSITION'],
|
||||
'column_default' => $row['COLUMN_DEFAULT'],
|
||||
'is_nullable' => ('YES' == $row['IS_NULLABLE']),
|
||||
'data_type' => $row['DATA_TYPE'],
|
||||
'character_maximum_length' => $row['CHARACTER_MAXIMUM_LENGTH'],
|
||||
'character_octet_length' => $row['CHARACTER_OCTET_LENGTH'],
|
||||
'numeric_precision' => $row['NUMERIC_PRECISION'],
|
||||
'numeric_scale' => $row['NUMERIC_SCALE'],
|
||||
'numeric_unsigned' => (false !== strpos($row['COLUMN_TYPE'], 'unsigned')),
|
||||
'erratas' => $erratas,
|
||||
);
|
||||
}
|
||||
|
||||
$this->data['columns'][$schema][$table] = $columns;
|
||||
}
|
||||
|
||||
protected function loadConstraintData($table, $schema)
|
||||
{
|
||||
if (isset($this->data['constraints'][$schema][$table])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->prepareDataHierarchy('constraints', $schema, $table);
|
||||
|
||||
$isColumns = array(
|
||||
array('T', 'TABLE_NAME'),
|
||||
array('TC', 'CONSTRAINT_NAME'),
|
||||
array('TC', 'CONSTRAINT_TYPE'),
|
||||
array('KCU', 'COLUMN_NAME'),
|
||||
array('RC', 'MATCH_OPTION'),
|
||||
array('RC', 'UPDATE_RULE'),
|
||||
array('RC', 'DELETE_RULE'),
|
||||
array('KCU', 'REFERENCED_TABLE_SCHEMA'),
|
||||
array('KCU', 'REFERENCED_TABLE_NAME'),
|
||||
array('KCU', 'REFERENCED_COLUMN_NAME'),
|
||||
);
|
||||
|
||||
$p = $this->adapter->getPlatform();
|
||||
|
||||
array_walk($isColumns, function (&$c) use ($p) {
|
||||
$c = $p->quoteIdentifierChain($c);
|
||||
});
|
||||
|
||||
$sql = 'SELECT ' . implode(', ', $isColumns)
|
||||
. ' FROM ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'TABLES')) . ' T'
|
||||
|
||||
. ' INNER JOIN ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'TABLE_CONSTRAINTS')) . ' TC'
|
||||
. ' ON ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('TC', 'TABLE_SCHEMA'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_NAME'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('TC', 'TABLE_NAME'))
|
||||
|
||||
. ' LEFT JOIN ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'KEY_COLUMN_USAGE')) . ' KCU'
|
||||
. ' ON ' . $p->quoteIdentifierChain(array('TC', 'TABLE_SCHEMA'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('KCU', 'TABLE_SCHEMA'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('TC', 'TABLE_NAME'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('KCU', 'TABLE_NAME'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('TC', 'CONSTRAINT_NAME'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('KCU', 'CONSTRAINT_NAME'))
|
||||
|
||||
. ' LEFT JOIN ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'REFERENTIAL_CONSTRAINTS')) . ' RC'
|
||||
. ' ON ' . $p->quoteIdentifierChain(array('TC', 'CONSTRAINT_SCHEMA'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('RC', 'CONSTRAINT_SCHEMA'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('TC', 'CONSTRAINT_NAME'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('RC', 'CONSTRAINT_NAME'))
|
||||
|
||||
. ' WHERE ' . $p->quoteIdentifierChain(array('T', 'TABLE_NAME'))
|
||||
. ' = ' . $p->quoteTrustedValue($table)
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_TYPE'))
|
||||
. ' IN (\'BASE TABLE\', \'VIEW\')';
|
||||
|
||||
if ($schema != self::DEFAULT_SCHEMA) {
|
||||
$sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' = ' . $p->quoteTrustedValue($schema);
|
||||
} else {
|
||||
$sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' != \'INFORMATION_SCHEMA\'';
|
||||
}
|
||||
|
||||
$sql .= ' ORDER BY CASE ' . $p->quoteIdentifierChain(array('TC', 'CONSTRAINT_TYPE'))
|
||||
. " WHEN 'PRIMARY KEY' THEN 1"
|
||||
. " WHEN 'UNIQUE' THEN 2"
|
||||
. " WHEN 'FOREIGN KEY' THEN 3"
|
||||
. " ELSE 4 END"
|
||||
|
||||
. ', ' . $p->quoteIdentifierChain(array('TC', 'CONSTRAINT_NAME'))
|
||||
. ', ' . $p->quoteIdentifierChain(array('KCU', 'ORDINAL_POSITION'));
|
||||
|
||||
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
|
||||
|
||||
$realName = null;
|
||||
$constraints = array();
|
||||
foreach ($results->toArray() as $row) {
|
||||
if ($row['CONSTRAINT_NAME'] !== $realName) {
|
||||
$realName = $row['CONSTRAINT_NAME'];
|
||||
$isFK = ('FOREIGN KEY' == $row['CONSTRAINT_TYPE']);
|
||||
if ($isFK) {
|
||||
$name = $realName;
|
||||
} else {
|
||||
$name = '_zf_' . $row['TABLE_NAME'] . '_' . $realName;
|
||||
}
|
||||
$constraints[$name] = array(
|
||||
'constraint_name' => $name,
|
||||
'constraint_type' => $row['CONSTRAINT_TYPE'],
|
||||
'table_name' => $row['TABLE_NAME'],
|
||||
'columns' => array(),
|
||||
);
|
||||
if ($isFK) {
|
||||
$constraints[$name]['referenced_table_schema'] = $row['REFERENCED_TABLE_SCHEMA'];
|
||||
$constraints[$name]['referenced_table_name'] = $row['REFERENCED_TABLE_NAME'];
|
||||
$constraints[$name]['referenced_columns'] = array();
|
||||
$constraints[$name]['match_option'] = $row['MATCH_OPTION'];
|
||||
$constraints[$name]['update_rule'] = $row['UPDATE_RULE'];
|
||||
$constraints[$name]['delete_rule'] = $row['DELETE_RULE'];
|
||||
}
|
||||
}
|
||||
$constraints[$name]['columns'][] = $row['COLUMN_NAME'];
|
||||
if ($isFK) {
|
||||
$constraints[$name]['referenced_columns'][] = $row['REFERENCED_COLUMN_NAME'];
|
||||
}
|
||||
}
|
||||
|
||||
$this->data['constraints'][$schema][$table] = $constraints;
|
||||
}
|
||||
|
||||
protected function loadConstraintDataNames($schema)
|
||||
{
|
||||
if (isset($this->data['constraint_names'][$schema])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->prepareDataHierarchy('constraint_names', $schema);
|
||||
|
||||
$p = $this->adapter->getPlatform();
|
||||
|
||||
$isColumns = array(
|
||||
array('TC', 'TABLE_NAME'),
|
||||
array('TC', 'CONSTRAINT_NAME'),
|
||||
array('TC', 'CONSTRAINT_TYPE'),
|
||||
);
|
||||
|
||||
array_walk($isColumns, function (&$c) use ($p) {
|
||||
$c = $p->quoteIdentifierChain($c);
|
||||
});
|
||||
|
||||
$sql = 'SELECT ' . implode(', ', $isColumns)
|
||||
. ' FROM ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'TABLES')) . 'T'
|
||||
. ' INNER JOIN ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'TABLE_CONSTRAINTS')) . 'TC'
|
||||
. ' ON ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('TC', 'TABLE_SCHEMA'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_NAME'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('TC', 'TABLE_NAME'))
|
||||
. ' WHERE ' . $p->quoteIdentifierChain(array('T', 'TABLE_TYPE'))
|
||||
. ' IN (\'BASE TABLE\', \'VIEW\')';
|
||||
|
||||
if ($schema != self::DEFAULT_SCHEMA) {
|
||||
$sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' = ' . $p->quoteTrustedValue($schema);
|
||||
} else {
|
||||
$sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' != \'INFORMATION_SCHEMA\'';
|
||||
}
|
||||
|
||||
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
|
||||
|
||||
$data = array();
|
||||
foreach ($results->toArray() as $row) {
|
||||
$data[] = array_change_key_case($row, CASE_LOWER);
|
||||
}
|
||||
|
||||
$this->data['constraint_names'][$schema] = $data;
|
||||
}
|
||||
|
||||
protected function loadConstraintDataKeys($schema)
|
||||
{
|
||||
if (isset($this->data['constraint_keys'][$schema])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->prepareDataHierarchy('constraint_keys', $schema);
|
||||
|
||||
$p = $this->adapter->getPlatform();
|
||||
|
||||
$isColumns = array(
|
||||
array('T', 'TABLE_NAME'),
|
||||
array('KCU', 'CONSTRAINT_NAME'),
|
||||
array('KCU', 'COLUMN_NAME'),
|
||||
array('KCU', 'ORDINAL_POSITION'),
|
||||
);
|
||||
|
||||
array_walk($isColumns, function (&$c) use ($p) {
|
||||
$c = $p->quoteIdentifierChain($c);
|
||||
});
|
||||
|
||||
$sql = 'SELECT ' . implode(', ', $isColumns)
|
||||
. ' FROM ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'TABLES')) . 'T'
|
||||
|
||||
. ' INNER JOIN ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'KEY_COLUMN_USAGE')) . 'KCU'
|
||||
. ' ON ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('KCU', 'TABLE_SCHEMA'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_NAME'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('KCU', 'TABLE_NAME'))
|
||||
|
||||
. ' WHERE ' . $p->quoteIdentifierChain(array('T', 'TABLE_TYPE'))
|
||||
. ' IN (\'BASE TABLE\', \'VIEW\')';
|
||||
|
||||
if ($schema != self::DEFAULT_SCHEMA) {
|
||||
$sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' = ' . $p->quoteTrustedValue($schema);
|
||||
} else {
|
||||
$sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' != \'INFORMATION_SCHEMA\'';
|
||||
}
|
||||
|
||||
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
|
||||
|
||||
$data = array();
|
||||
foreach ($results->toArray() as $row) {
|
||||
$data[] = array_change_key_case($row, CASE_LOWER);
|
||||
}
|
||||
|
||||
$this->data['constraint_keys'][$schema] = $data;
|
||||
}
|
||||
|
||||
protected function loadConstraintReferences($table, $schema)
|
||||
{
|
||||
parent::loadConstraintReferences($table, $schema);
|
||||
|
||||
$p = $this->adapter->getPlatform();
|
||||
|
||||
$isColumns = array(
|
||||
array('RC', 'TABLE_NAME'),
|
||||
array('RC', 'CONSTRAINT_NAME'),
|
||||
array('RC', 'UPDATE_RULE'),
|
||||
array('RC', 'DELETE_RULE'),
|
||||
array('KCU', 'REFERENCED_TABLE_SCHEMA'),
|
||||
array('KCU', 'REFERENCED_TABLE_NAME'),
|
||||
array('KCU', 'REFERENCED_COLUMN_NAME'),
|
||||
);
|
||||
|
||||
array_walk($isColumns, function (&$c) use ($p) {
|
||||
$c = $p->quoteIdentifierChain($c);
|
||||
});
|
||||
|
||||
$sql = 'SELECT ' . implode(', ', $isColumns)
|
||||
. 'FROM ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'TABLES')) . 'T'
|
||||
|
||||
. ' INNER JOIN ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'REFERENTIAL_CONSTRAINTS')) . 'RC'
|
||||
. ' ON ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('RC', 'CONSTRAINT_SCHEMA'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_NAME'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('RC', 'TABLE_NAME'))
|
||||
|
||||
. ' INNER JOIN ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'KEY_COLUMN_USAGE')) . 'KCU'
|
||||
. ' ON ' . $p->quoteIdentifierChain(array('RC', 'CONSTRAINT_SCHEMA'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('KCU', 'TABLE_SCHEMA'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('RC', 'TABLE_NAME'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('KCU', 'TABLE_NAME'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('RC', 'CONSTRAINT_NAME'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('KCU', 'CONSTRAINT_NAME'))
|
||||
|
||||
. 'WHERE ' . $p->quoteIdentifierChain(array('T', 'TABLE_TYPE'))
|
||||
. ' IN (\'BASE TABLE\', \'VIEW\')';
|
||||
|
||||
if ($schema != self::DEFAULT_SCHEMA) {
|
||||
$sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' = ' . $p->quoteTrustedValue($schema);
|
||||
} else {
|
||||
$sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' != \'INFORMATION_SCHEMA\'';
|
||||
}
|
||||
|
||||
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
|
||||
|
||||
$data = array();
|
||||
foreach ($results->toArray() as $row) {
|
||||
$data[] = array_change_key_case($row, CASE_LOWER);
|
||||
}
|
||||
|
||||
$this->data['constraint_references'][$schema] = $data;
|
||||
}
|
||||
|
||||
protected function loadTriggerData($schema)
|
||||
{
|
||||
if (isset($this->data['triggers'][$schema])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->prepareDataHierarchy('triggers', $schema);
|
||||
|
||||
$p = $this->adapter->getPlatform();
|
||||
|
||||
$isColumns = array(
|
||||
// 'TRIGGER_CATALOG',
|
||||
// 'TRIGGER_SCHEMA',
|
||||
'TRIGGER_NAME',
|
||||
'EVENT_MANIPULATION',
|
||||
'EVENT_OBJECT_CATALOG',
|
||||
'EVENT_OBJECT_SCHEMA',
|
||||
'EVENT_OBJECT_TABLE',
|
||||
'ACTION_ORDER',
|
||||
'ACTION_CONDITION',
|
||||
'ACTION_STATEMENT',
|
||||
'ACTION_ORIENTATION',
|
||||
'ACTION_TIMING',
|
||||
'ACTION_REFERENCE_OLD_TABLE',
|
||||
'ACTION_REFERENCE_NEW_TABLE',
|
||||
'ACTION_REFERENCE_OLD_ROW',
|
||||
'ACTION_REFERENCE_NEW_ROW',
|
||||
'CREATED',
|
||||
);
|
||||
|
||||
array_walk($isColumns, function (&$c) use ($p) {
|
||||
$c = $p->quoteIdentifier($c);
|
||||
});
|
||||
|
||||
$sql = 'SELECT ' . implode(', ', $isColumns)
|
||||
. ' FROM ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'TRIGGERS'))
|
||||
. ' WHERE ';
|
||||
|
||||
if ($schema != self::DEFAULT_SCHEMA) {
|
||||
$sql .= $p->quoteIdentifier('TRIGGER_SCHEMA')
|
||||
. ' = ' . $p->quoteTrustedValue($schema);
|
||||
} else {
|
||||
$sql .= $p->quoteIdentifier('TRIGGER_SCHEMA')
|
||||
. ' != \'INFORMATION_SCHEMA\'';
|
||||
}
|
||||
|
||||
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
|
||||
|
||||
$data = array();
|
||||
foreach ($results->toArray() as $row) {
|
||||
$row = array_change_key_case($row, CASE_LOWER);
|
||||
if (null !== $row['created']) {
|
||||
$row['created'] = new \DateTime($row['created']);
|
||||
}
|
||||
$data[$row['trigger_name']] = $row;
|
||||
}
|
||||
|
||||
$this->data['triggers'][$schema] = $data;
|
||||
}
|
||||
}
|
@ -0,0 +1,348 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Metadata\Source;
|
||||
|
||||
use Zend\Db\Adapter\Adapter;
|
||||
|
||||
class PostgresqlMetadata extends AbstractSource
|
||||
{
|
||||
|
||||
protected function loadSchemaData()
|
||||
{
|
||||
if (isset($this->data['schemas'])) {
|
||||
return;
|
||||
}
|
||||
$this->prepareDataHierarchy('schemas');
|
||||
|
||||
$p = $this->adapter->getPlatform();
|
||||
|
||||
$sql = 'SELECT ' . $p->quoteIdentifier('schema_name')
|
||||
. ' FROM ' . $p->quoteIdentifierChain(array('information_schema', 'schemata'))
|
||||
. ' WHERE ' . $p->quoteIdentifier('schema_name')
|
||||
. ' != \'information_schema\''
|
||||
. ' AND ' . $p->quoteIdentifier('schema_name') . " NOT LIKE 'pg_%'";
|
||||
|
||||
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
|
||||
|
||||
$schemas = array();
|
||||
foreach ($results->toArray() as $row) {
|
||||
$schemas[] = $row['schema_name'];
|
||||
}
|
||||
|
||||
$this->data['schemas'] = $schemas;
|
||||
}
|
||||
|
||||
protected function loadTableNameData($schema)
|
||||
{
|
||||
if (isset($this->data['table_names'][$schema])) {
|
||||
return;
|
||||
}
|
||||
$this->prepareDataHierarchy('table_names', $schema);
|
||||
|
||||
$p = $this->adapter->getPlatform();
|
||||
|
||||
$isColumns = array(
|
||||
array('t', 'table_name'),
|
||||
array('t', 'table_type'),
|
||||
array('v', 'view_definition'),
|
||||
array('v', 'check_option'),
|
||||
array('v', 'is_updatable'),
|
||||
);
|
||||
|
||||
array_walk($isColumns, function (&$c) use ($p) { $c = $p->quoteIdentifierChain($c); });
|
||||
|
||||
$sql = 'SELECT ' . implode(', ', $isColumns)
|
||||
. ' FROM ' . $p->quoteIdentifierChain(array('information_schema', 'tables')) . ' t'
|
||||
|
||||
. ' LEFT JOIN ' . $p->quoteIdentifierChain(array('information_schema', 'views')) . ' v'
|
||||
. ' ON ' . $p->quoteIdentifierChain(array('t', 'table_schema'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('v', 'table_schema'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('t', 'table_name'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('v', 'table_name'))
|
||||
|
||||
. ' WHERE ' . $p->quoteIdentifierChain(array('t', 'table_type'))
|
||||
. ' IN (\'BASE TABLE\', \'VIEW\')';
|
||||
|
||||
if ($schema != self::DEFAULT_SCHEMA) {
|
||||
$sql .= ' AND ' . $p->quoteIdentifierChain(array('t', 'table_schema'))
|
||||
. ' = ' . $p->quoteTrustedValue($schema);
|
||||
} else {
|
||||
$sql .= ' AND ' . $p->quoteIdentifierChain(array('t', 'table_schema'))
|
||||
. ' != \'information_schema\'';
|
||||
}
|
||||
|
||||
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
|
||||
|
||||
$tables = array();
|
||||
foreach ($results->toArray() as $row) {
|
||||
$tables[$row['table_name']] = array(
|
||||
'table_type' => $row['table_type'],
|
||||
'view_definition' => $row['view_definition'],
|
||||
'check_option' => $row['check_option'],
|
||||
'is_updatable' => ('YES' == $row['is_updatable']),
|
||||
);
|
||||
}
|
||||
|
||||
$this->data['table_names'][$schema] = $tables;
|
||||
}
|
||||
|
||||
protected function loadColumnData($table, $schema)
|
||||
{
|
||||
if (isset($this->data['columns'][$schema][$table])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->prepareDataHierarchy('columns', $schema, $table);
|
||||
|
||||
$platform = $this->adapter->getPlatform();
|
||||
|
||||
$isColumns = array(
|
||||
'table_name',
|
||||
'column_name',
|
||||
'ordinal_position',
|
||||
'column_default',
|
||||
'is_nullable',
|
||||
'data_type',
|
||||
'character_maximum_length',
|
||||
'character_octet_length',
|
||||
'numeric_precision',
|
||||
'numeric_scale',
|
||||
);
|
||||
|
||||
array_walk($isColumns, function (&$c) use ($platform) { $c = $platform->quoteIdentifier($c); });
|
||||
|
||||
$sql = 'SELECT ' . implode(', ', $isColumns)
|
||||
. ' FROM ' . $platform->quoteIdentifier('information_schema')
|
||||
. $platform->getIdentifierSeparator() . $platform->quoteIdentifier('columns')
|
||||
. ' WHERE ' . $platform->quoteIdentifier('table_schema')
|
||||
. ' != \'information\''
|
||||
. ' AND ' . $platform->quoteIdentifier('table_name')
|
||||
. ' = ' . $platform->quoteTrustedValue($table);
|
||||
|
||||
if ($schema != '__DEFAULT_SCHEMA__') {
|
||||
$sql .= ' AND ' . $platform->quoteIdentifier('table_schema')
|
||||
. ' = ' . $platform->quoteTrustedValue($schema);
|
||||
}
|
||||
|
||||
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
|
||||
$columns = array();
|
||||
foreach ($results->toArray() as $row) {
|
||||
$columns[$row['column_name']] = array(
|
||||
'ordinal_position' => $row['ordinal_position'],
|
||||
'column_default' => $row['column_default'],
|
||||
'is_nullable' => ('YES' == $row['is_nullable']),
|
||||
'data_type' => $row['data_type'],
|
||||
'character_maximum_length' => $row['character_maximum_length'],
|
||||
'character_octet_length' => $row['character_octet_length'],
|
||||
'numeric_precision' => $row['numeric_precision'],
|
||||
'numeric_scale' => $row['numeric_scale'],
|
||||
'numeric_unsigned' => null,
|
||||
'erratas' => array(),
|
||||
);
|
||||
}
|
||||
|
||||
$this->data['columns'][$schema][$table] = $columns;
|
||||
}
|
||||
|
||||
protected function loadConstraintData($table, $schema)
|
||||
{
|
||||
if (isset($this->data['constraints'][$schema][$table])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->prepareDataHierarchy('constraints', $schema, $table);
|
||||
|
||||
$isColumns = array(
|
||||
array('t', 'table_name'),
|
||||
array('tc', 'constraint_name'),
|
||||
array('tc', 'constraint_type'),
|
||||
array('kcu', 'column_name'),
|
||||
array('cc', 'check_clause'),
|
||||
array('rc', 'match_option'),
|
||||
array('rc', 'update_rule'),
|
||||
array('rc', 'delete_rule'),
|
||||
array('referenced_table_schema' => 'kcu2', 'table_schema'),
|
||||
array('referenced_table_name' => 'kcu2', 'table_name'),
|
||||
array('referenced_column_name' => 'kcu2', 'column_name'),
|
||||
);
|
||||
|
||||
$p = $this->adapter->getPlatform();
|
||||
|
||||
array_walk($isColumns, function (&$c) use ($p) {
|
||||
$alias = key($c);
|
||||
$c = $p->quoteIdentifierChain($c);
|
||||
if (is_string($alias)) {
|
||||
$c .= ' ' . $p->quoteIdentifier($alias);
|
||||
}
|
||||
});
|
||||
|
||||
$sql = 'SELECT ' . implode(', ', $isColumns)
|
||||
. ' FROM ' . $p->quoteIdentifierChain(array('information_schema', 'tables')) . ' t'
|
||||
|
||||
. ' INNER JOIN ' . $p->quoteIdentifierChain(array('information_schema', 'table_constraints')) . ' tc'
|
||||
. ' ON ' . $p->quoteIdentifierChain(array('t', 'table_schema'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('tc', 'table_schema'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('t', 'table_name'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('tc', 'table_name'))
|
||||
|
||||
. ' LEFT JOIN ' . $p->quoteIdentifierChain(array('information_schema', 'key_column_usage')) . ' kcu'
|
||||
. ' ON ' . $p->quoteIdentifierChain(array('tc', 'table_schema'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('kcu', 'table_schema'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('tc', 'table_name'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('kcu', 'table_name'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('tc', 'constraint_name'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('kcu', 'constraint_name'))
|
||||
|
||||
. ' LEFT JOIN ' . $p->quoteIdentifierChain(array('information_schema', 'check_constraints')) . ' cc'
|
||||
. ' ON ' . $p->quoteIdentifierChain(array('tc', 'constraint_schema'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('cc', 'constraint_schema'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('tc', 'constraint_name'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('cc', 'constraint_name'))
|
||||
|
||||
. ' LEFT JOIN ' . $p->quoteIdentifierChain(array('information_schema', 'referential_constraints')) . ' rc'
|
||||
. ' ON ' . $p->quoteIdentifierChain(array('tc', 'constraint_schema'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('rc', 'constraint_schema'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('tc', 'constraint_name'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('rc', 'constraint_name'))
|
||||
|
||||
. ' LEFT JOIN ' . $p->quoteIdentifierChain(array('information_schema', 'key_column_usage')) . ' kcu2'
|
||||
. ' ON ' . $p->quoteIdentifierChain(array('rc', 'unique_constraint_schema'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('kcu2', 'constraint_schema'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('rc', 'unique_constraint_name'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('kcu2', 'constraint_name'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('kcu', 'position_in_unique_constraint'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('kcu2', 'ordinal_position'))
|
||||
|
||||
. ' WHERE ' . $p->quoteIdentifierChain(array('t', 'table_name'))
|
||||
. ' = ' . $p->quoteTrustedValue($table)
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('t', 'table_type'))
|
||||
. ' IN (\'BASE TABLE\', \'VIEW\')';
|
||||
|
||||
if ($schema != self::DEFAULT_SCHEMA) {
|
||||
$sql .= ' AND ' . $p->quoteIdentifierChain(array('t', 'table_schema'))
|
||||
. ' = ' . $p->quoteTrustedValue($schema);
|
||||
} else {
|
||||
$sql .= ' AND ' . $p->quoteIdentifierChain(array('t', 'table_schema'))
|
||||
. ' != \'information_schema\'';
|
||||
}
|
||||
|
||||
$sql .= ' ORDER BY CASE ' . $p->quoteIdentifierChain(array('tc', 'constraint_type'))
|
||||
. " WHEN 'PRIMARY KEY' THEN 1"
|
||||
. " WHEN 'UNIQUE' THEN 2"
|
||||
. " WHEN 'FOREIGN KEY' THEN 3"
|
||||
. " WHEN 'CHECK' THEN 4"
|
||||
. " ELSE 5 END"
|
||||
. ', ' . $p->quoteIdentifierChain(array('tc', 'constraint_name'))
|
||||
. ', ' . $p->quoteIdentifierChain(array('kcu', 'ordinal_position'));
|
||||
|
||||
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
|
||||
|
||||
$name = null;
|
||||
$constraints = array();
|
||||
foreach ($results->toArray() as $row) {
|
||||
if ($row['constraint_name'] !== $name) {
|
||||
$name = $row['constraint_name'];
|
||||
$constraints[$name] = array(
|
||||
'constraint_name' => $name,
|
||||
'constraint_type' => $row['constraint_type'],
|
||||
'table_name' => $row['table_name'],
|
||||
);
|
||||
if ('CHECK' == $row['constraint_type']) {
|
||||
$constraints[$name]['check_clause'] = $row['check_clause'];
|
||||
continue;
|
||||
}
|
||||
$constraints[$name]['columns'] = array();
|
||||
$isFK = ('FOREIGN KEY' == $row['constraint_type']);
|
||||
if ($isFK) {
|
||||
$constraints[$name]['referenced_table_schema'] = $row['referenced_table_schema'];
|
||||
$constraints[$name]['referenced_table_name'] = $row['referenced_table_name'];
|
||||
$constraints[$name]['referenced_columns'] = array();
|
||||
$constraints[$name]['match_option'] = $row['match_option'];
|
||||
$constraints[$name]['update_rule'] = $row['update_rule'];
|
||||
$constraints[$name]['delete_rule'] = $row['delete_rule'];
|
||||
}
|
||||
}
|
||||
$constraints[$name]['columns'][] = $row['column_name'];
|
||||
if ($isFK) {
|
||||
$constraints[$name]['referenced_columns'][] = $row['referenced_column_name'];
|
||||
}
|
||||
}
|
||||
|
||||
$this->data['constraints'][$schema][$table] = $constraints;
|
||||
}
|
||||
|
||||
protected function loadTriggerData($schema)
|
||||
{
|
||||
if (isset($this->data['triggers'][$schema])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->prepareDataHierarchy('triggers', $schema);
|
||||
|
||||
$p = $this->adapter->getPlatform();
|
||||
|
||||
$isColumns = array(
|
||||
'trigger_name',
|
||||
'event_manipulation',
|
||||
'event_object_catalog',
|
||||
'event_object_schema',
|
||||
'event_object_table',
|
||||
'action_order',
|
||||
'action_condition',
|
||||
'action_statement',
|
||||
'action_orientation',
|
||||
array('action_timing' => 'condition_timing'),
|
||||
array('action_reference_old_table' => 'condition_reference_old_table'),
|
||||
array('action_reference_new_table' => 'condition_reference_new_table'),
|
||||
'created',
|
||||
);
|
||||
|
||||
array_walk($isColumns, function (&$c) use ($p) {
|
||||
if (is_array($c)) {
|
||||
$alias = key($c);
|
||||
$c = $p->quoteIdentifierChain($c);
|
||||
if (is_string($alias)) {
|
||||
$c .= ' ' . $p->quoteIdentifier($alias);
|
||||
}
|
||||
} else {
|
||||
$c = $p->quoteIdentifier($c);
|
||||
}
|
||||
});
|
||||
|
||||
$sql = 'SELECT ' . implode(', ', $isColumns)
|
||||
. ' FROM ' . $p->quoteIdentifierChain(array('information_schema', 'triggers'))
|
||||
. ' WHERE ';
|
||||
|
||||
if ($schema != self::DEFAULT_SCHEMA) {
|
||||
$sql .= $p->quoteIdentifier('trigger_schema')
|
||||
. ' = ' . $p->quoteTrustedValue($schema);
|
||||
} else {
|
||||
$sql .= $p->quoteIdentifier('trigger_schema')
|
||||
. ' != \'information_schema\'';
|
||||
}
|
||||
|
||||
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
|
||||
|
||||
$data = array();
|
||||
foreach ($results->toArray() as $row) {
|
||||
$row = array_change_key_case($row, CASE_LOWER);
|
||||
$row['action_reference_old_row'] = 'OLD';
|
||||
$row['action_reference_new_row'] = 'NEW';
|
||||
if (null !== $row['created']) {
|
||||
$row['created'] = new \DateTime($row['created']);
|
||||
}
|
||||
$data[$row['trigger_name']] = $row;
|
||||
}
|
||||
|
||||
$this->data['triggers'][$schema] = $data;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,343 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Metadata\Source;
|
||||
|
||||
use Zend\Db\Adapter\Adapter;
|
||||
|
||||
class SqlServerMetadata extends AbstractSource
|
||||
{
|
||||
|
||||
|
||||
protected function loadSchemaData()
|
||||
{
|
||||
if (isset($this->data['schemas'])) {
|
||||
return;
|
||||
}
|
||||
$this->prepareDataHierarchy('schemas');
|
||||
|
||||
$p = $this->adapter->getPlatform();
|
||||
|
||||
$sql = 'SELECT ' . $p->quoteIdentifier('SCHEMA_NAME')
|
||||
. ' FROM ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'SCHEMATA'))
|
||||
. ' WHERE ' . $p->quoteIdentifier('SCHEMA_NAME')
|
||||
. ' != \'INFORMATION_SCHEMA\'';
|
||||
|
||||
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
|
||||
|
||||
$schemas = array();
|
||||
foreach ($results->toArray() as $row) {
|
||||
$schemas[] = $row['SCHEMA_NAME'];
|
||||
}
|
||||
|
||||
$this->data['schemas'] = $schemas;
|
||||
}
|
||||
|
||||
protected function loadTableNameData($schema)
|
||||
{
|
||||
if (isset($this->data['table_names'][$schema])) {
|
||||
return;
|
||||
}
|
||||
$this->prepareDataHierarchy('table_names', $schema);
|
||||
|
||||
$p = $this->adapter->getPlatform();
|
||||
|
||||
$isColumns = array(
|
||||
array('T', 'TABLE_NAME'),
|
||||
array('T', 'TABLE_TYPE'),
|
||||
array('V', 'VIEW_DEFINITION'),
|
||||
array('V', 'CHECK_OPTION'),
|
||||
array('V', 'IS_UPDATABLE'),
|
||||
);
|
||||
|
||||
array_walk($isColumns, function (&$c) use ($p) { $c = $p->quoteIdentifierChain($c); });
|
||||
|
||||
$sql = 'SELECT ' . implode(', ', $isColumns)
|
||||
. ' FROM ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'TABLES')) . ' t'
|
||||
|
||||
. ' LEFT JOIN ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'VIEWS')) . ' v'
|
||||
. ' ON ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('V', 'TABLE_SCHEMA'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_NAME'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('V', 'TABLE_NAME'))
|
||||
|
||||
. ' WHERE ' . $p->quoteIdentifierChain(array('T', 'TABLE_TYPE'))
|
||||
. ' IN (\'BASE TABLE\', \'VIEW\')';
|
||||
|
||||
if ($schema != self::DEFAULT_SCHEMA) {
|
||||
$sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' = ' . $p->quoteTrustedValue($schema);
|
||||
} else {
|
||||
$sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' != \'INFORMATION_SCHEMA\'';
|
||||
}
|
||||
|
||||
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
|
||||
|
||||
$tables = array();
|
||||
foreach ($results->toArray() as $row) {
|
||||
$tables[$row['TABLE_NAME']] = array(
|
||||
'table_type' => $row['TABLE_TYPE'],
|
||||
'view_definition' => $row['VIEW_DEFINITION'],
|
||||
'check_option' => $row['CHECK_OPTION'],
|
||||
'is_updatable' => ('YES' == $row['IS_UPDATABLE']),
|
||||
);
|
||||
}
|
||||
|
||||
$this->data['table_names'][$schema] = $tables;
|
||||
}
|
||||
|
||||
protected function loadColumnData($table, $schema)
|
||||
{
|
||||
if (isset($this->data['columns'][$schema][$table])) {
|
||||
return;
|
||||
}
|
||||
$this->prepareDataHierarchy('columns', $schema, $table);
|
||||
$p = $this->adapter->getPlatform();
|
||||
|
||||
$isColumns = array(
|
||||
array('C', 'ORDINAL_POSITION'),
|
||||
array('C', 'COLUMN_DEFAULT'),
|
||||
array('C', 'IS_NULLABLE'),
|
||||
array('C', 'DATA_TYPE'),
|
||||
array('C', 'CHARACTER_MAXIMUM_LENGTH'),
|
||||
array('C', 'CHARACTER_OCTET_LENGTH'),
|
||||
array('C', 'NUMERIC_PRECISION'),
|
||||
array('C', 'NUMERIC_SCALE'),
|
||||
array('C', 'COLUMN_NAME'),
|
||||
);
|
||||
|
||||
array_walk($isColumns, function (&$c) use ($p) { $c = $p->quoteIdentifierChain($c); });
|
||||
|
||||
$sql = 'SELECT ' . implode(', ', $isColumns)
|
||||
. ' FROM ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'TABLES')) . 'T'
|
||||
. ' INNER JOIN ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'COLUMNS')) . 'C'
|
||||
. ' ON ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('C', 'TABLE_SCHEMA'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_NAME'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('C', 'TABLE_NAME'))
|
||||
. ' WHERE ' . $p->quoteIdentifierChain(array('T', 'TABLE_TYPE'))
|
||||
. ' IN (\'BASE TABLE\', \'VIEW\')'
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_NAME'))
|
||||
. ' = ' . $p->quoteTrustedValue($table);
|
||||
|
||||
if ($schema != self::DEFAULT_SCHEMA) {
|
||||
$sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' = ' . $p->quoteTrustedValue($schema);
|
||||
} else {
|
||||
$sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' != \'INFORMATION_SCHEMA\'';
|
||||
}
|
||||
|
||||
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
|
||||
$columns = array();
|
||||
foreach ($results->toArray() as $row) {
|
||||
$columns[$row['COLUMN_NAME']] = array(
|
||||
'ordinal_position' => $row['ORDINAL_POSITION'],
|
||||
'column_default' => $row['COLUMN_DEFAULT'],
|
||||
'is_nullable' => ('YES' == $row['IS_NULLABLE']),
|
||||
'data_type' => $row['DATA_TYPE'],
|
||||
'character_maximum_length' => $row['CHARACTER_MAXIMUM_LENGTH'],
|
||||
'character_octet_length' => $row['CHARACTER_OCTET_LENGTH'],
|
||||
'numeric_precision' => $row['NUMERIC_PRECISION'],
|
||||
'numeric_scale' => $row['NUMERIC_SCALE'],
|
||||
'numeric_unsigned' => null,
|
||||
'erratas' => array(),
|
||||
);
|
||||
}
|
||||
|
||||
$this->data['columns'][$schema][$table] = $columns;
|
||||
}
|
||||
|
||||
protected function loadConstraintData($table, $schema)
|
||||
{
|
||||
if (isset($this->data['constraints'][$schema][$table])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->prepareDataHierarchy('constraints', $schema, $table);
|
||||
|
||||
$isColumns = array(
|
||||
array('T', 'TABLE_NAME'),
|
||||
array('TC', 'CONSTRAINT_NAME'),
|
||||
array('TC', 'CONSTRAINT_TYPE'),
|
||||
array('KCU', 'COLUMN_NAME'),
|
||||
array('CC', 'CHECK_CLAUSE'),
|
||||
array('RC', 'MATCH_OPTION'),
|
||||
array('RC', 'UPDATE_RULE'),
|
||||
array('RC', 'DELETE_RULE'),
|
||||
array('REFERENCED_TABLE_SCHEMA' => 'KCU2', 'TABLE_SCHEMA'),
|
||||
array('REFERENCED_TABLE_NAME' => 'KCU2', 'TABLE_NAME'),
|
||||
array('REFERENCED_COLUMN_NAME' => 'KCU2', 'COLUMN_NAME'),
|
||||
);
|
||||
|
||||
$p = $this->adapter->getPlatform();
|
||||
|
||||
array_walk($isColumns, function (&$c) use ($p) {
|
||||
$alias = key($c);
|
||||
$c = $p->quoteIdentifierChain($c);
|
||||
if (is_string($alias)) {
|
||||
$c .= ' ' . $p->quoteIdentifier($alias);
|
||||
}
|
||||
});
|
||||
|
||||
$sql = 'SELECT ' . implode(', ', $isColumns)
|
||||
. ' FROM ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'TABLES')) . ' T'
|
||||
|
||||
. ' INNER JOIN ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'TABLE_CONSTRAINTS')) . ' TC'
|
||||
. ' ON ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('TC', 'TABLE_SCHEMA'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_NAME'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('TC', 'TABLE_NAME'))
|
||||
|
||||
. ' LEFT JOIN ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'KEY_COLUMN_USAGE')) . ' KCU'
|
||||
. ' ON ' . $p->quoteIdentifierChain(array('TC', 'TABLE_SCHEMA'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('KCU', 'TABLE_SCHEMA'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('TC', 'TABLE_NAME'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('KCU', 'TABLE_NAME'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('TC', 'CONSTRAINT_NAME'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('KCU', 'CONSTRAINT_NAME'))
|
||||
|
||||
. ' LEFT JOIN ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'CHECK_CONSTRAINTS')) . ' CC'
|
||||
. ' ON ' . $p->quoteIdentifierChain(array('TC', 'CONSTRAINT_SCHEMA'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('CC', 'CONSTRAINT_SCHEMA'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('TC', 'CONSTRAINT_NAME'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('CC', 'CONSTRAINT_NAME'))
|
||||
|
||||
. ' LEFT JOIN ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'REFERENTIAL_CONSTRAINTS')) . ' RC'
|
||||
. ' ON ' . $p->quoteIdentifierChain(array('TC', 'CONSTRAINT_SCHEMA'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('RC', 'CONSTRAINT_SCHEMA'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('TC', 'CONSTRAINT_NAME'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('RC', 'CONSTRAINT_NAME'))
|
||||
|
||||
. ' LEFT JOIN ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'KEY_COLUMN_USAGE')) . ' KCU2'
|
||||
. ' ON ' . $p->quoteIdentifierChain(array('RC', 'UNIQUE_CONSTRAINT_SCHEMA'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('KCU2', 'CONSTRAINT_SCHEMA'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('RC', 'UNIQUE_CONSTRAINT_NAME'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('KCU2', 'CONSTRAINT_NAME'))
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('KCU', 'ORDINAL_POSITION'))
|
||||
. ' = ' . $p->quoteIdentifierChain(array('KCU2', 'ORDINAL_POSITION'))
|
||||
|
||||
. ' WHERE ' . $p->quoteIdentifierChain(array('T', 'TABLE_NAME'))
|
||||
. ' = ' . $p->quoteTrustedValue($table)
|
||||
. ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_TYPE'))
|
||||
. ' IN (\'BASE TABLE\', \'VIEW\')';
|
||||
|
||||
if ($schema != self::DEFAULT_SCHEMA) {
|
||||
$sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' = ' . $p->quoteTrustedValue($schema);
|
||||
} else {
|
||||
$sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
|
||||
. ' != \'INFORMATION_SCHEMA\'';
|
||||
}
|
||||
|
||||
$sql .= ' ORDER BY CASE ' . $p->quoteIdentifierChain(array('TC', 'CONSTRAINT_TYPE'))
|
||||
. " WHEN 'PRIMARY KEY' THEN 1"
|
||||
. " WHEN 'UNIQUE' THEN 2"
|
||||
. " WHEN 'FOREIGN KEY' THEN 3"
|
||||
. " WHEN 'CHECK' THEN 4"
|
||||
. " ELSE 5 END"
|
||||
. ', ' . $p->quoteIdentifierChain(array('TC', 'CONSTRAINT_NAME'))
|
||||
. ', ' . $p->quoteIdentifierChain(array('KCU', 'ORDINAL_POSITION'));
|
||||
|
||||
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
|
||||
|
||||
$name = null;
|
||||
$constraints = array();
|
||||
$isFK = false;
|
||||
foreach ($results->toArray() as $row) {
|
||||
if ($row['CONSTRAINT_NAME'] !== $name) {
|
||||
$name = $row['CONSTRAINT_NAME'];
|
||||
$constraints[$name] = array(
|
||||
'constraint_name' => $name,
|
||||
'constraint_type' => $row['CONSTRAINT_TYPE'],
|
||||
'table_name' => $row['TABLE_NAME'],
|
||||
);
|
||||
if ('CHECK' == $row['CONSTRAINT_TYPE']) {
|
||||
$constraints[$name]['check_clause'] = $row['CHECK_CLAUSE'];
|
||||
continue;
|
||||
}
|
||||
$constraints[$name]['columns'] = array();
|
||||
$isFK = ('FOREIGN KEY' == $row['CONSTRAINT_TYPE']);
|
||||
if ($isFK) {
|
||||
$constraints[$name]['referenced_table_schema'] = $row['REFERENCED_TABLE_SCHEMA'];
|
||||
$constraints[$name]['referenced_table_name'] = $row['REFERENCED_TABLE_NAME'];
|
||||
$constraints[$name]['referenced_columns'] = array();
|
||||
$constraints[$name]['match_option'] = $row['MATCH_OPTION'];
|
||||
$constraints[$name]['update_rule'] = $row['UPDATE_RULE'];
|
||||
$constraints[$name]['delete_rule'] = $row['DELETE_RULE'];
|
||||
}
|
||||
}
|
||||
$constraints[$name]['columns'][] = $row['COLUMN_NAME'];
|
||||
if ($isFK) {
|
||||
$constraints[$name]['referenced_columns'][] = $row['REFERENCED_COLUMN_NAME'];
|
||||
}
|
||||
}
|
||||
|
||||
$this->data['constraints'][$schema][$table] = $constraints;
|
||||
}
|
||||
|
||||
protected function loadTriggerData($schema)
|
||||
{
|
||||
if (isset($this->data['triggers'][$schema])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->prepareDataHierarchy('triggers', $schema);
|
||||
|
||||
$p = $this->adapter->getPlatform();
|
||||
|
||||
$isColumns = array(
|
||||
'TRIGGER_NAME',
|
||||
'EVENT_MANIPULATION',
|
||||
'EVENT_OBJECT_CATALOG',
|
||||
'EVENT_OBJECT_SCHEMA',
|
||||
'EVENT_OBJECT_TABLE',
|
||||
'ACTION_ORDER',
|
||||
'ACTION_CONDITION',
|
||||
'ACTION_STATEMENT',
|
||||
'ACTION_ORIENTATION',
|
||||
'ACTION_TIMING',
|
||||
'ACTION_REFERENCE_OLD_TABLE',
|
||||
'ACTION_REFERENCE_NEW_TABLE',
|
||||
'ACTION_REFERENCE_OLD_ROW',
|
||||
'ACTION_REFERENCE_NEW_ROW',
|
||||
'CREATED',
|
||||
);
|
||||
|
||||
array_walk($isColumns, function (&$c) use ($p) {
|
||||
$c = $p->quoteIdentifier($c);
|
||||
});
|
||||
|
||||
$sql = 'SELECT ' . implode(', ', $isColumns)
|
||||
. ' FROM ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'TRIGGERS'))
|
||||
. ' WHERE ';
|
||||
|
||||
if ($schema != self::DEFAULT_SCHEMA) {
|
||||
$sql .= $p->quoteIdentifier('TRIGGER_SCHEMA')
|
||||
. ' = ' . $p->quoteTrustedValue($schema);
|
||||
} else {
|
||||
$sql .= $p->quoteIdentifier('TRIGGER_SCHEMA')
|
||||
. ' != \'INFORMATION_SCHEMA\'';
|
||||
}
|
||||
|
||||
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
|
||||
|
||||
$data = array();
|
||||
foreach ($results->toArray() as $row) {
|
||||
$row = array_change_key_case($row, CASE_LOWER);
|
||||
if (null !== $row['created']) {
|
||||
$row['created'] = new \DateTime($row['created']);
|
||||
}
|
||||
$data[$row['trigger_name']] = $row;
|
||||
}
|
||||
|
||||
$this->data['triggers'][$schema] = $data;
|
||||
}
|
||||
}
|
@ -0,0 +1,392 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\Metadata\Source;
|
||||
|
||||
use Zend\Db\Adapter\Adapter;
|
||||
use Zend\Db\ResultSet\ResultSetInterface;
|
||||
|
||||
class SqliteMetadata extends AbstractSource
|
||||
{
|
||||
protected function loadSchemaData()
|
||||
{
|
||||
if (isset($this->data['schemas'])) {
|
||||
return;
|
||||
}
|
||||
$this->prepareDataHierarchy('schemas');
|
||||
|
||||
$results = $this->fetchPragma('database_list');
|
||||
foreach ($results as $row) {
|
||||
$schemas[] = $row['name'];
|
||||
}
|
||||
$this->data['schemas'] = $schemas;
|
||||
}
|
||||
|
||||
protected function loadTableNameData($schema)
|
||||
{
|
||||
if (isset($this->data['table_names'][$schema])) {
|
||||
return;
|
||||
}
|
||||
$this->prepareDataHierarchy('table_names', $schema);
|
||||
|
||||
// FEATURE: Filename?
|
||||
|
||||
$p = $this->adapter->getPlatform();
|
||||
|
||||
$sql = 'SELECT "name", "type", "sql" FROM ' . $p->quoteIdentifierChain(array($schema, 'sqlite_master'))
|
||||
. ' WHERE "type" IN (\'table\',\'view\') AND "name" NOT LIKE \'sqlite_%\'';
|
||||
|
||||
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
|
||||
$tables = array();
|
||||
foreach ($results->toArray() as $row) {
|
||||
if ('table' == $row['type']) {
|
||||
$table = array(
|
||||
'table_type' => 'BASE TABLE',
|
||||
'view_definition' => null, // VIEW only
|
||||
'check_option' => null, // VIEW only
|
||||
'is_updatable' => null, // VIEW only
|
||||
);
|
||||
} else {
|
||||
$table = array(
|
||||
'table_type' => 'VIEW',
|
||||
'view_definition' => null,
|
||||
'check_option' => 'NONE',
|
||||
'is_updatable' => false,
|
||||
);
|
||||
|
||||
// Parse out extra data
|
||||
if (null !== ($data = $this->parseView($row['sql']))) {
|
||||
$table = array_merge($table, $data);
|
||||
}
|
||||
}
|
||||
$tables[$row['name']] = $table;
|
||||
}
|
||||
$this->data['table_names'][$schema] = $tables;
|
||||
}
|
||||
|
||||
protected function loadColumnData($table, $schema)
|
||||
{
|
||||
if (isset($this->data['columns'][$schema][$table])) {
|
||||
return;
|
||||
}
|
||||
$this->prepareDataHierarchy('columns', $schema, $table);
|
||||
$this->prepareDataHierarchy('sqlite_columns', $schema, $table);
|
||||
|
||||
$p = $this->adapter->getPlatform();
|
||||
|
||||
|
||||
$results = $this->fetchPragma('table_info', $table, $schema);
|
||||
|
||||
$columns = array();
|
||||
|
||||
foreach ($results as $row) {
|
||||
$columns[$row['name']] = array(
|
||||
// cid appears to be zero-based, ordinal position needs to be one-based
|
||||
'ordinal_position' => $row['cid'] + 1,
|
||||
'column_default' => $row['dflt_value'],
|
||||
'is_nullable' => !((bool) $row['notnull']),
|
||||
'data_type' => $row['type'],
|
||||
'character_maximum_length' => null,
|
||||
'character_octet_length' => null,
|
||||
'numeric_precision' => null,
|
||||
'numeric_scale' => null,
|
||||
'numeric_unsigned' => null,
|
||||
'erratas' => array(),
|
||||
);
|
||||
// TODO: populate character_ and numeric_values with correct info
|
||||
}
|
||||
|
||||
$this->data['columns'][$schema][$table] = $columns;
|
||||
$this->data['sqlite_columns'][$schema][$table] = $results;
|
||||
}
|
||||
|
||||
protected function loadConstraintData($table, $schema)
|
||||
{
|
||||
if (isset($this->data['constraints'][$schema][$table])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->prepareDataHierarchy('constraints', $schema, $table);
|
||||
|
||||
$this->loadColumnData($table, $schema);
|
||||
$primaryKey = array();
|
||||
|
||||
foreach ($this->data['sqlite_columns'][$schema][$table] as $col) {
|
||||
if ((bool) $col['pk']) {
|
||||
$primaryKey[] = $col['name'];
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($primaryKey)) {
|
||||
$primaryKey = null;
|
||||
}
|
||||
$constraints = array();
|
||||
$indexes = $this->fetchPragma('index_list', $table, $schema);
|
||||
foreach ($indexes as $index) {
|
||||
if (!((bool) $index['unique'])) {
|
||||
continue;
|
||||
}
|
||||
$constraint = array(
|
||||
'constraint_name' => $index['name'],
|
||||
'constraint_type' => 'UNIQUE',
|
||||
'table_name' => $table,
|
||||
'columns' => array(),
|
||||
);
|
||||
|
||||
$info = $this->fetchPragma('index_info', $index['name'], $schema);
|
||||
|
||||
foreach ($info as $column) {
|
||||
$constraint['columns'][] = $column['name'];
|
||||
}
|
||||
if ($primaryKey === $constraint['columns']) {
|
||||
$constraint['constraint_type'] = 'PRIMARY KEY';
|
||||
$primaryKey = null;
|
||||
}
|
||||
$constraints[$constraint['constraint_name']] = $constraint;
|
||||
}
|
||||
|
||||
if (null !== $primaryKey) {
|
||||
$constraintName = '_zf_' . $table . '_PRIMARY';
|
||||
$constraints[$constraintName] = array(
|
||||
'constraint_name' => $constraintName,
|
||||
'constraint_type' => 'PRIMARY KEY',
|
||||
'table_name' => $table,
|
||||
'columns' => $primaryKey,
|
||||
);
|
||||
}
|
||||
|
||||
$foreignKeys = $this->fetchPragma('foreign_key_list', $table, $schema);
|
||||
|
||||
$id = $name = null;
|
||||
foreach ($foreignKeys as $fk) {
|
||||
if ($id !== $fk['id']) {
|
||||
$id = $fk['id'];
|
||||
$name = '_zf_' . $table . '_FOREIGN_KEY_' . ($id + 1);
|
||||
$constraints[$name] = array(
|
||||
'constraint_name' => $name,
|
||||
'constraint_type' => 'FOREIGN KEY',
|
||||
'table_name' => $table,
|
||||
'columns' => array(),
|
||||
'referenced_table_schema' => $schema,
|
||||
'referenced_table_name' => $fk['table'],
|
||||
'referenced_columns' => array(),
|
||||
// TODO: Verify match, on_update, and on_delete values conform to SQL Standard
|
||||
'match_option' => strtoupper($fk['match']),
|
||||
'update_rule' => strtoupper($fk['on_update']),
|
||||
'delete_rule' => strtoupper($fk['on_delete']),
|
||||
);
|
||||
}
|
||||
$constraints[$name]['columns'][] = $fk['from'];
|
||||
$constraints[$name]['referenced_columns'][] = $fk['to'];
|
||||
}
|
||||
|
||||
$this->data['constraints'][$schema][$table] = $constraints;
|
||||
}
|
||||
|
||||
protected function loadTriggerData($schema)
|
||||
{
|
||||
if (isset($this->data['triggers'][$schema])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->prepareDataHierarchy('triggers', $schema);
|
||||
|
||||
$p = $this->adapter->getPlatform();
|
||||
|
||||
$sql = 'SELECT "name", "tbl_name", "sql" FROM '
|
||||
. $p->quoteIdentifierChain(array($schema, 'sqlite_master'))
|
||||
. ' WHERE "type" = \'trigger\'';
|
||||
|
||||
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
|
||||
$triggers = array();
|
||||
foreach ($results->toArray() as $row) {
|
||||
$trigger = array(
|
||||
'trigger_name' => $row['name'],
|
||||
'event_manipulation' => null, // in $row['sql']
|
||||
'event_object_catalog' => null,
|
||||
'event_object_schema' => $schema,
|
||||
'event_object_table' => $row['tbl_name'],
|
||||
'action_order' => 0,
|
||||
'action_condition' => null, // in $row['sql']
|
||||
'action_statement' => null, // in $row['sql']
|
||||
'action_orientation' => 'ROW',
|
||||
'action_timing' => null, // in $row['sql']
|
||||
'action_reference_old_table' => null,
|
||||
'action_reference_new_table' => null,
|
||||
'action_reference_old_row' => 'OLD',
|
||||
'action_reference_new_row' => 'NEW',
|
||||
'created' => null,
|
||||
);
|
||||
|
||||
// Parse out extra data
|
||||
if (null !== ($data = $this->parseTrigger($row['sql']))) {
|
||||
$trigger = array_merge($trigger, $data);
|
||||
}
|
||||
$triggers[$trigger['trigger_name']] = $trigger;
|
||||
}
|
||||
|
||||
$this->data['triggers'][$schema] = $triggers;
|
||||
}
|
||||
|
||||
protected function fetchPragma($name, $value = null, $schema = null)
|
||||
{
|
||||
$p = $this->adapter->getPlatform();
|
||||
|
||||
$sql = 'PRAGMA ';
|
||||
|
||||
if (null !== $schema) {
|
||||
$sql .= $p->quoteIdentifier($schema) . '.';
|
||||
}
|
||||
$sql .= $name;
|
||||
|
||||
if (null !== $value) {
|
||||
$sql .= '(' . $p->quoteTrustedValue($value) . ')';
|
||||
}
|
||||
|
||||
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
|
||||
if ($results instanceof ResultSetInterface) {
|
||||
return $results->toArray();
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
protected function parseView($sql)
|
||||
{
|
||||
static $re = null;
|
||||
if (null === $re) {
|
||||
$identifier = $this->getIdentifierRegularExpression();
|
||||
$identifierList = $this->getIdentifierListRegularExpression();
|
||||
$identifierChain = $this->getIdentifierChainRegularExpression();
|
||||
$re = $this->buildRegularExpression(array(
|
||||
'CREATE',
|
||||
array('TEMP|TEMPORARY'),
|
||||
'VIEW',
|
||||
array('IF', 'NOT', 'EXISTS'),
|
||||
$identifierChain,
|
||||
'AS',
|
||||
'(?<view_definition>.+)',
|
||||
array(';'),
|
||||
));
|
||||
}
|
||||
|
||||
if (!preg_match($re, $sql, $matches)) {
|
||||
return null;
|
||||
}
|
||||
return array(
|
||||
'view_definition' => $matches['view_definition'],
|
||||
);
|
||||
}
|
||||
|
||||
protected function parseTrigger($sql)
|
||||
{
|
||||
static $re = null;
|
||||
if (null === $re) {
|
||||
$identifier = $this->getIdentifierRegularExpression();
|
||||
$identifierList = $this->getIdentifierListRegularExpression();
|
||||
$identifierChain = $this->getIdentifierChainRegularExpression();
|
||||
$re = $this->buildRegularExpression(array(
|
||||
'CREATE',
|
||||
array('TEMP|TEMPORARY'),
|
||||
'TRIGGER',
|
||||
array('IF', 'NOT', 'EXISTS'),
|
||||
$identifierChain,
|
||||
array('(?<action_timing>BEFORE|AFTER|INSTEAD\\s+OF)',),
|
||||
'(?<event_manipulation>DELETE|INSERT|UPDATE)',
|
||||
array('OF', '(?<column_usage>' . $identifierList . ')'),
|
||||
'ON',
|
||||
'(?<event_object_table>' . $identifier . ')',
|
||||
array('FOR', 'EACH', 'ROW'),
|
||||
array('WHEN', '(?<action_condition>.+)'),
|
||||
'(?<action_statement>BEGIN',
|
||||
'.+',
|
||||
'END)',
|
||||
array(';'),
|
||||
));
|
||||
}
|
||||
|
||||
if (!preg_match($re, $sql, $matches)) {
|
||||
return null;
|
||||
}
|
||||
$data = array();
|
||||
|
||||
foreach ($matches as $key => $value) {
|
||||
if (is_string($key)) {
|
||||
$data[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// Normalize data and populate defaults, if necessary
|
||||
|
||||
$data['event_manipulation'] = strtoupper($data['event_manipulation']);
|
||||
if (empty($data['action_condition'])) {
|
||||
$data['action_condition'] = null;
|
||||
}
|
||||
if (!empty($data['action_timing'])) {
|
||||
$data['action_timing'] = strtoupper($data['action_timing']);
|
||||
if ('I' == $data['action_timing'][0]) {
|
||||
// normalize the white-space between the two words
|
||||
$data['action_timing'] = 'INSTEAD OF';
|
||||
}
|
||||
} else {
|
||||
$data['action_timing'] = 'AFTER';
|
||||
}
|
||||
unset($data['column_usage']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function buildRegularExpression(array $re)
|
||||
{
|
||||
foreach ($re as &$value) {
|
||||
if (is_array($value)) {
|
||||
$value = '(?:' . implode('\\s*+', $value) . '\\s*+)?';
|
||||
} else {
|
||||
$value .= '\\s*+';
|
||||
}
|
||||
}
|
||||
unset($value);
|
||||
$re = '/^' . implode('\\s*+', $re) . '$/';
|
||||
return $re;
|
||||
}
|
||||
|
||||
protected function getIdentifierRegularExpression()
|
||||
{
|
||||
static $re = null;
|
||||
if (null === $re) {
|
||||
$re = '(?:' . implode('|', array(
|
||||
'"(?:[^"\\\\]++|\\\\.)*+"',
|
||||
'`(?:[^`]++|``)*+`',
|
||||
'\\[[^\\]]+\\]',
|
||||
'[^\\s\\.]+',
|
||||
)) . ')';
|
||||
}
|
||||
|
||||
return $re;
|
||||
}
|
||||
|
||||
protected function getIdentifierChainRegularExpression()
|
||||
{
|
||||
static $re = null;
|
||||
if (null === $re) {
|
||||
$identifier = $this->getIdentifierRegularExpression();
|
||||
$re = $identifier . '(?:\\s*\\.\\s*' . $identifier . ')*+';
|
||||
}
|
||||
return $re;
|
||||
}
|
||||
|
||||
protected function getIdentifierListRegularExpression()
|
||||
{
|
||||
static $re = null;
|
||||
if (null === $re) {
|
||||
$identifier = $this->getIdentifierRegularExpression();
|
||||
$re = $identifier . '(?:\\s*,\\s*' . $identifier . ')*+';
|
||||
}
|
||||
return $re;
|
||||
}
|
||||
}
|
15
bundled-libs/zendframework/zend-db/Zend/Db/README.md
Normal file
15
bundled-libs/zendframework/zend-db/Zend/Db/README.md
Normal file
@ -0,0 +1,15 @@
|
||||
DB Component from ZF2
|
||||
=====================
|
||||
|
||||
This is the DB component for ZF2.
|
||||
|
||||
- File issues at https://github.com/zendframework/zf2/issues
|
||||
- Create pull requests against https://github.com/zendframework/zf2
|
||||
- Documentation is at http://framework.zend.com/docs
|
||||
|
||||
LICENSE
|
||||
-------
|
||||
|
||||
The files in this archive are released under the [Zend Framework
|
||||
license](http://framework.zend.com/license), which is a 3-clause BSD license.
|
||||
|
@ -0,0 +1,281 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\ResultSet;
|
||||
|
||||
use ArrayIterator;
|
||||
use ArrayObject;
|
||||
use Countable;
|
||||
use Iterator;
|
||||
use IteratorAggregate;
|
||||
use Zend\Db\Adapter\Driver\ResultInterface;
|
||||
|
||||
abstract class AbstractResultSet implements Iterator, ResultSetInterface
|
||||
{
|
||||
/**
|
||||
* if -1, datasource is already buffered
|
||||
* if -2, implicitly disabling buffering in ResultSet
|
||||
* if false, explicitly disabled
|
||||
* if null, default state - nothing, but can buffer until iteration started
|
||||
* if array, already buffering
|
||||
* @var mixed
|
||||
*/
|
||||
protected $buffer = null;
|
||||
|
||||
/**
|
||||
* @var null|int
|
||||
*/
|
||||
protected $count = null;
|
||||
|
||||
/**
|
||||
* @var Iterator|IteratorAggregate|ResultInterface
|
||||
*/
|
||||
protected $dataSource = null;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $fieldCount = null;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $position = 0;
|
||||
|
||||
/**
|
||||
* Set the data source for the result set
|
||||
*
|
||||
* @param Iterator|IteratorAggregate|ResultInterface $dataSource
|
||||
* @return ResultSet
|
||||
* @throws Exception\InvalidArgumentException
|
||||
*/
|
||||
public function initialize($dataSource)
|
||||
{
|
||||
// reset buffering
|
||||
if (is_array($this->buffer)) {
|
||||
$this->buffer = array();
|
||||
}
|
||||
|
||||
if ($dataSource instanceof ResultInterface) {
|
||||
$this->count = $dataSource->count();
|
||||
$this->fieldCount = $dataSource->getFieldCount();
|
||||
$this->dataSource = $dataSource;
|
||||
if ($dataSource->isBuffered()) {
|
||||
$this->buffer = -1;
|
||||
}
|
||||
if (is_array($this->buffer)) {
|
||||
$this->dataSource->rewind();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (is_array($dataSource)) {
|
||||
// its safe to get numbers from an array
|
||||
$first = current($dataSource);
|
||||
reset($dataSource);
|
||||
$this->count = count($dataSource);
|
||||
$this->fieldCount = count($first);
|
||||
$this->dataSource = new ArrayIterator($dataSource);
|
||||
$this->buffer = -1; // array's are a natural buffer
|
||||
} elseif ($dataSource instanceof IteratorAggregate) {
|
||||
$this->dataSource = $dataSource->getIterator();
|
||||
} elseif ($dataSource instanceof Iterator) {
|
||||
$this->dataSource = $dataSource;
|
||||
} else {
|
||||
throw new Exception\InvalidArgumentException('DataSource provided is not an array, nor does it implement Iterator or IteratorAggregate');
|
||||
}
|
||||
|
||||
if ($this->count == null && $this->dataSource instanceof Countable) {
|
||||
$this->count = $this->dataSource->count();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function buffer()
|
||||
{
|
||||
if ($this->buffer === -2) {
|
||||
throw new Exception\RuntimeException('Buffering must be enabled before iteration is started');
|
||||
} elseif ($this->buffer === null) {
|
||||
$this->buffer = array();
|
||||
if ($this->dataSource instanceof ResultInterface) {
|
||||
$this->dataSource->rewind();
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isBuffered()
|
||||
{
|
||||
if ($this->buffer === -1 || is_array($this->buffer)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data source used to create the result set
|
||||
*
|
||||
* @return null|Iterator
|
||||
*/
|
||||
public function getDataSource()
|
||||
{
|
||||
return $this->dataSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve count of fields in individual rows of the result set
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getFieldCount()
|
||||
{
|
||||
if (null !== $this->fieldCount) {
|
||||
return $this->fieldCount;
|
||||
}
|
||||
|
||||
$dataSource = $this->getDataSource();
|
||||
if (null === $dataSource) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$dataSource->rewind();
|
||||
if (!$dataSource->valid()) {
|
||||
$this->fieldCount = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
$row = $dataSource->current();
|
||||
if (is_object($row) && $row instanceof Countable) {
|
||||
$this->fieldCount = $row->count();
|
||||
return $this->fieldCount;
|
||||
}
|
||||
|
||||
$row = (array) $row;
|
||||
$this->fieldCount = count($row);
|
||||
return $this->fieldCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator: move pointer to next item
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
if ($this->buffer === null) {
|
||||
$this->buffer = -2; // implicitly disable buffering from here on
|
||||
}
|
||||
$this->dataSource->next();
|
||||
$this->position++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator: retrieve current key
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator: get current item
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
if ($this->buffer === null) {
|
||||
$this->buffer = -2; // implicitly disable buffering from here on
|
||||
} elseif (is_array($this->buffer) && isset($this->buffer[$this->position])) {
|
||||
return $this->buffer[$this->position];
|
||||
}
|
||||
$data = $this->dataSource->current();
|
||||
if (is_array($this->buffer)) {
|
||||
$this->buffer[$this->position] = $data;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator: is pointer valid?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
if (is_array($this->buffer) && isset($this->buffer[$this->position])) {
|
||||
return true;
|
||||
}
|
||||
if ($this->dataSource instanceof Iterator) {
|
||||
return $this->dataSource->valid();
|
||||
} else {
|
||||
$key = key($this->dataSource);
|
||||
return ($key !== null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator: rewind
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
if (!is_array($this->buffer)) {
|
||||
if ($this->dataSource instanceof Iterator) {
|
||||
$this->dataSource->rewind();
|
||||
} else {
|
||||
reset($this->dataSource);
|
||||
}
|
||||
}
|
||||
$this->position = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Countable: return count of rows
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
if ($this->count !== null) {
|
||||
return $this->count;
|
||||
}
|
||||
$this->count = count($this->dataSource);
|
||||
return $this->count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast result set to array of arrays
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception\RuntimeException if any row is not castable to an array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
$return = array();
|
||||
foreach ($this as $row) {
|
||||
if (is_array($row)) {
|
||||
$return[] = $row;
|
||||
} elseif (method_exists($row, 'toArray')) {
|
||||
$return[] = $row->toArray();
|
||||
} elseif ($row instanceof ArrayObject) {
|
||||
$return[] = $row->getArrayCopy();
|
||||
} else {
|
||||
throw new Exception\RuntimeException(
|
||||
'Rows as part of this DataSource, with type ' . gettype($row) . ' cannot be cast to an array'
|
||||
);
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\ResultSet\Exception;
|
||||
|
||||
use Zend\Db\Exception;
|
||||
|
||||
interface ExceptionInterface extends Exception\ExceptionInterface
|
||||
{
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\ResultSet\Exception;
|
||||
|
||||
use Zend\Db\Exception;
|
||||
|
||||
class InvalidArgumentException extends Exception\InvalidArgumentException implements ExceptionInterface
|
||||
{
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\ResultSet\Exception;
|
||||
|
||||
use Zend\Db\Exception;
|
||||
|
||||
class RuntimeException extends Exception\RuntimeException implements ExceptionInterface
|
||||
{
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\ResultSet;
|
||||
|
||||
use ArrayObject;
|
||||
use Zend\Stdlib\Hydrator\ArraySerializable;
|
||||
use Zend\Stdlib\Hydrator\HydratorInterface;
|
||||
|
||||
class HydratingResultSet extends AbstractResultSet
|
||||
{
|
||||
/**
|
||||
* @var HydratorInterface
|
||||
*/
|
||||
protected $hydrator = null;
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
protected $objectPrototype = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param null|HydratorInterface $hydrator
|
||||
* @param null|object $objectPrototype
|
||||
*/
|
||||
public function __construct(HydratorInterface $hydrator = null, $objectPrototype = null)
|
||||
{
|
||||
$this->setHydrator(($hydrator) ?: new ArraySerializable);
|
||||
$this->setObjectPrototype(($objectPrototype) ?: new ArrayObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the row object prototype
|
||||
*
|
||||
* @param object $objectPrototype
|
||||
* @throws Exception\InvalidArgumentException
|
||||
* @return ResultSet
|
||||
*/
|
||||
public function setObjectPrototype($objectPrototype)
|
||||
{
|
||||
if (!is_object($objectPrototype)) {
|
||||
throw new Exception\InvalidArgumentException(
|
||||
'An object must be set as the object prototype, a ' . gettype($objectPrototype) . ' was provided.'
|
||||
);
|
||||
}
|
||||
$this->objectPrototype = $objectPrototype;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the hydrator to use for each row object
|
||||
*
|
||||
* @param HydratorInterface $hydrator
|
||||
* @return HydratingResultSet
|
||||
*/
|
||||
public function setHydrator(HydratorInterface $hydrator)
|
||||
{
|
||||
$this->hydrator = $hydrator;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the hydrator to use for each row object
|
||||
*
|
||||
* @return HydratorInterface
|
||||
*/
|
||||
public function getHydrator()
|
||||
{
|
||||
return $this->hydrator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator: get current item
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
if ($this->buffer === null) {
|
||||
$this->buffer = -2; // implicitly disable buffering from here on
|
||||
} elseif (is_array($this->buffer) && isset($this->buffer[$this->position])) {
|
||||
return $this->buffer[$this->position];
|
||||
}
|
||||
$data = $this->dataSource->current();
|
||||
$object = is_array($data) ? $this->hydrator->hydrate($data, clone $this->objectPrototype) : false;
|
||||
|
||||
if (is_array($this->buffer)) {
|
||||
$this->buffer[$this->position] = $object;
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast result set to array of arrays
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception\RuntimeException if any row is not castable to an array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
$return = array();
|
||||
foreach ($this as $row) {
|
||||
$return[] = $this->getHydrator()->extract($row);
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\ResultSet;
|
||||
|
||||
use ArrayObject;
|
||||
|
||||
class ResultSet extends AbstractResultSet
|
||||
{
|
||||
const TYPE_ARRAYOBJECT = 'arrayobject';
|
||||
const TYPE_ARRAY = 'array';
|
||||
|
||||
/**
|
||||
* Allowed return types
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $allowedReturnTypes = array(
|
||||
self::TYPE_ARRAYOBJECT,
|
||||
self::TYPE_ARRAY,
|
||||
);
|
||||
|
||||
/**
|
||||
* @var ArrayObject
|
||||
*/
|
||||
protected $arrayObjectPrototype = null;
|
||||
|
||||
/**
|
||||
* Return type to use when returning an object from the set
|
||||
*
|
||||
* @var ResultSet::TYPE_ARRAYOBJECT|ResultSet::TYPE_ARRAY
|
||||
*/
|
||||
protected $returnType = self::TYPE_ARRAYOBJECT;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $returnType
|
||||
* @param null|ArrayObject $arrayObjectPrototype
|
||||
*/
|
||||
public function __construct($returnType = self::TYPE_ARRAYOBJECT, $arrayObjectPrototype = null)
|
||||
{
|
||||
$this->returnType = (in_array($returnType, array(self::TYPE_ARRAY, self::TYPE_ARRAYOBJECT))) ? $returnType : self::TYPE_ARRAYOBJECT;
|
||||
if ($this->returnType === self::TYPE_ARRAYOBJECT) {
|
||||
$this->setArrayObjectPrototype(($arrayObjectPrototype) ?: new ArrayObject(array(), ArrayObject::ARRAY_AS_PROPS));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the row object prototype
|
||||
*
|
||||
* @param ArrayObject $arrayObjectPrototype
|
||||
* @throws Exception\InvalidArgumentException
|
||||
* @return ResultSet
|
||||
*/
|
||||
public function setArrayObjectPrototype($arrayObjectPrototype)
|
||||
{
|
||||
if (!is_object($arrayObjectPrototype)
|
||||
|| (!$arrayObjectPrototype instanceof ArrayObject && !method_exists($arrayObjectPrototype, 'exchangeArray'))
|
||||
|
||||
) {
|
||||
throw new Exception\InvalidArgumentException('Object must be of type ArrayObject, or at least implement exchangeArray');
|
||||
}
|
||||
$this->arrayObjectPrototype = $arrayObjectPrototype;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the row object prototype
|
||||
*
|
||||
* @return ArrayObject
|
||||
*/
|
||||
public function getArrayObjectPrototype()
|
||||
{
|
||||
return $this->arrayObjectPrototype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the return type to use when returning objects from the set
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getReturnType()
|
||||
{
|
||||
return $this->returnType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|\ArrayObject|null
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
$data = parent::current();
|
||||
|
||||
if ($this->returnType === self::TYPE_ARRAYOBJECT && is_array($data)) {
|
||||
/** @var $ao ArrayObject */
|
||||
$ao = clone $this->arrayObjectPrototype;
|
||||
if ($ao instanceof ArrayObject || method_exists($ao, 'exchangeArray')) {
|
||||
$ao->exchangeArray($data);
|
||||
}
|
||||
return $ao;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\ResultSet;
|
||||
|
||||
interface ResultSetInterface extends \Traversable, \Countable
|
||||
{
|
||||
/**
|
||||
* Can be anything traversable|array
|
||||
* @abstract
|
||||
* @param $dataSource
|
||||
* @return mixed
|
||||
*/
|
||||
public function initialize($dataSource);
|
||||
|
||||
/**
|
||||
* Field terminology is more correct as information coming back
|
||||
* from the database might be a column, and/or the result of an
|
||||
* operation or intersection of some data
|
||||
* @abstract
|
||||
* @return mixed
|
||||
*/
|
||||
public function getFieldCount();
|
||||
}
|
@ -0,0 +1,352 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\RowGateway;
|
||||
|
||||
use ArrayAccess;
|
||||
use Countable;
|
||||
use Zend\Db\Sql\Sql;
|
||||
use Zend\Db\Sql\TableIdentifier;
|
||||
|
||||
abstract class AbstractRowGateway implements ArrayAccess, Countable, RowGatewayInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $isInitialized = false;
|
||||
|
||||
/**
|
||||
* @var string|TableIdentifier
|
||||
*/
|
||||
protected $table = null;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $primaryKeyColumn = null;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $primaryKeyData = null;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $data = array();
|
||||
|
||||
/**
|
||||
* @var Sql
|
||||
*/
|
||||
protected $sql = null;
|
||||
|
||||
/**
|
||||
* @var Feature\FeatureSet
|
||||
*/
|
||||
protected $featureSet = null;
|
||||
|
||||
/**
|
||||
* initialize()
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
if ($this->isInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$this->featureSet instanceof Feature\FeatureSet) {
|
||||
$this->featureSet = new Feature\FeatureSet;
|
||||
}
|
||||
|
||||
$this->featureSet->setRowGateway($this);
|
||||
$this->featureSet->apply('preInitialize', array());
|
||||
|
||||
if (!is_string($this->table) && !$this->table instanceof TableIdentifier) {
|
||||
throw new Exception\RuntimeException('This row object does not have a valid table set.');
|
||||
}
|
||||
|
||||
if ($this->primaryKeyColumn == null) {
|
||||
throw new Exception\RuntimeException('This row object does not have a primary key column set.');
|
||||
} elseif (is_string($this->primaryKeyColumn)) {
|
||||
$this->primaryKeyColumn = (array) $this->primaryKeyColumn;
|
||||
}
|
||||
|
||||
if (!$this->sql instanceof Sql) {
|
||||
throw new Exception\RuntimeException('This row object does not have a Sql object set.');
|
||||
}
|
||||
|
||||
$this->featureSet->apply('postInitialize', array());
|
||||
|
||||
$this->isInitialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate Data
|
||||
*
|
||||
* @param array $rowData
|
||||
* @param bool $rowExistsInDatabase
|
||||
* @return AbstractRowGateway
|
||||
*/
|
||||
public function populate(array $rowData, $rowExistsInDatabase = false)
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
$this->data = $rowData;
|
||||
if ($rowExistsInDatabase == true) {
|
||||
$this->processPrimaryKeyData();
|
||||
} else {
|
||||
$this->primaryKeyData = null;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $array
|
||||
* @return array|void
|
||||
*/
|
||||
public function exchangeArray($array)
|
||||
{
|
||||
return $this->populate($array, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
if ($this->rowExistsInDatabase()) {
|
||||
|
||||
// UPDATE
|
||||
|
||||
$data = $this->data;
|
||||
$where = array();
|
||||
|
||||
// primary key is always an array even if its a single column
|
||||
foreach ($this->primaryKeyColumn as $pkColumn) {
|
||||
$where[$pkColumn] = $this->primaryKeyData[$pkColumn];
|
||||
if ($data[$pkColumn] == $this->primaryKeyData[$pkColumn]) {
|
||||
unset($data[$pkColumn]);
|
||||
}
|
||||
}
|
||||
|
||||
$statement = $this->sql->prepareStatementForSqlObject($this->sql->update()->set($data)->where($where));
|
||||
$result = $statement->execute();
|
||||
$rowsAffected = $result->getAffectedRows();
|
||||
unset($statement, $result); // cleanup
|
||||
|
||||
} else {
|
||||
|
||||
// INSERT
|
||||
$insert = $this->sql->insert();
|
||||
$insert->values($this->data);
|
||||
|
||||
$statement = $this->sql->prepareStatementForSqlObject($insert);
|
||||
|
||||
$result = $statement->execute();
|
||||
if (($primaryKeyValue = $result->getGeneratedValue()) && count($this->primaryKeyColumn) == 1) {
|
||||
$this->primaryKeyData = array($this->primaryKeyColumn[0] => $primaryKeyValue);
|
||||
} else {
|
||||
// make primary key data available so that $where can be complete
|
||||
$this->processPrimaryKeyData();
|
||||
}
|
||||
$rowsAffected = $result->getAffectedRows();
|
||||
unset($statement, $result); // cleanup
|
||||
|
||||
$where = array();
|
||||
// primary key is always an array even if its a single column
|
||||
foreach ($this->primaryKeyColumn as $pkColumn) {
|
||||
$where[$pkColumn] = $this->primaryKeyData[$pkColumn];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// refresh data
|
||||
$statement = $this->sql->prepareStatementForSqlObject($this->sql->select()->where($where));
|
||||
$result = $statement->execute();
|
||||
$rowData = $result->current();
|
||||
unset($statement, $result); // cleanup
|
||||
|
||||
// make sure data and original data are in sync after save
|
||||
$this->populate($rowData, true);
|
||||
|
||||
// return rows affected
|
||||
return $rowsAffected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
$where = array();
|
||||
// primary key is always an array even if its a single column
|
||||
foreach ($this->primaryKeyColumn as $pkColumn) {
|
||||
$where[$pkColumn] = $this->primaryKeyData[$pkColumn];
|
||||
}
|
||||
|
||||
// @todo determine if we need to do a select to ensure 1 row will be affected
|
||||
|
||||
$statement = $this->sql->prepareStatementForSqlObject($this->sql->delete()->where($where));
|
||||
$result = $statement->execute();
|
||||
|
||||
$affectedRows = $result->getAffectedRows();
|
||||
if ($affectedRows == 1) {
|
||||
// detach from database
|
||||
$this->primaryKeyData = null;
|
||||
}
|
||||
|
||||
return $affectedRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset Exists
|
||||
*
|
||||
* @param string $offset
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return array_key_exists($offset, $this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset get
|
||||
*
|
||||
* @param string $offset
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->data[$offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset set
|
||||
*
|
||||
* @param string $offset
|
||||
* @param mixed $value
|
||||
* @return RowGateway
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->data[$offset] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset unset
|
||||
*
|
||||
* @param string $offset
|
||||
* @return AbstractRowGateway
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
$this->data[$offset] = null;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* To array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* __get
|
||||
*
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
if (array_key_exists($name, $this->data)) {
|
||||
return $this->data[$name];
|
||||
} else {
|
||||
throw new \InvalidArgumentException('Not a valid column in this row: ' . $name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* __set
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
{
|
||||
$this->offsetSet($name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* __isset
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public function __isset($name)
|
||||
{
|
||||
return $this->offsetExists($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* __unset
|
||||
*
|
||||
* @param string $name
|
||||
* @return void
|
||||
*/
|
||||
public function __unset($name)
|
||||
{
|
||||
$this->offsetUnset($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function rowExistsInDatabase()
|
||||
{
|
||||
return ($this->primaryKeyData !== null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception\RuntimeException
|
||||
*/
|
||||
protected function processPrimaryKeyData()
|
||||
{
|
||||
$this->primaryKeyData = array();
|
||||
foreach ($this->primaryKeyColumn as $column) {
|
||||
if (!isset($this->data[$column])) {
|
||||
throw new Exception\RuntimeException('While processing primary key data, a known key ' . $column . ' was not found in the data array');
|
||||
}
|
||||
$this->primaryKeyData[$column] = $this->data[$column];
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\RowGateway\Exception;
|
||||
|
||||
use Zend\Db\Exception;
|
||||
|
||||
interface ExceptionInterface extends Exception\ExceptionInterface
|
||||
{
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\RowGateway\Exception;
|
||||
|
||||
use Zend\Db\Exception;
|
||||
|
||||
class InvalidArgumentException extends Exception\InvalidArgumentException implements ExceptionInterface
|
||||
{
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\RowGateway\Exception;
|
||||
|
||||
use Zend\Db\Exception;
|
||||
|
||||
class RuntimeException extends Exception\RuntimeException implements ExceptionInterface
|
||||
{
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\RowGateway\Feature;
|
||||
|
||||
use Zend\Db\RowGateway\AbstractRowGateway;
|
||||
use Zend\Db\RowGateway\Exception;
|
||||
|
||||
abstract class AbstractFeature extends AbstractRowGateway
|
||||
{
|
||||
|
||||
/**
|
||||
* @var AbstractRowGateway
|
||||
*/
|
||||
protected $rowGateway = null;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $sharedData = array();
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return get_class($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AbstractRowGateway $rowGateway
|
||||
*/
|
||||
public function setRowGateway(AbstractRowGateway $rowGateway)
|
||||
{
|
||||
$this->rowGateway = $rowGateway;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Zend\Db\RowGateway\Exception\RuntimeException
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
throw new Exception\RuntimeException('This method is not intended to be called on this object.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMagicMethodSpecifications()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
}
|
@ -0,0 +1,149 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\RowGateway\Feature;
|
||||
|
||||
use Zend\Db\RowGateway\AbstractRowGateway;
|
||||
|
||||
class FeatureSet
|
||||
{
|
||||
const APPLY_HALT = 'halt';
|
||||
|
||||
/**
|
||||
* @var AbstractRowGateway
|
||||
*/
|
||||
protected $rowGateway = null;
|
||||
|
||||
/**
|
||||
* @var AbstractFeature[]
|
||||
*/
|
||||
protected $features = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $magicSpecifications = array();
|
||||
|
||||
/**
|
||||
* @param array $features
|
||||
*/
|
||||
public function __construct(array $features = array())
|
||||
{
|
||||
if ($features) {
|
||||
$this->addFeatures($features);
|
||||
}
|
||||
}
|
||||
|
||||
public function setRowGateway(AbstractRowGateway $rowGateway)
|
||||
{
|
||||
$this->rowGateway = $rowGateway;
|
||||
foreach ($this->features as $feature) {
|
||||
$feature->setRowGateway($this->rowGateway);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getFeatureByClassName($featureClassName)
|
||||
{
|
||||
$feature = false;
|
||||
foreach ($this->features as $potentialFeature) {
|
||||
if ($potentialFeature instanceof $featureClassName) {
|
||||
$feature = $potentialFeature;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $feature;
|
||||
}
|
||||
|
||||
public function addFeatures(array $features)
|
||||
{
|
||||
foreach ($features as $feature) {
|
||||
$this->addFeature($feature);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addFeature(AbstractFeature $feature)
|
||||
{
|
||||
$this->features[] = $feature;
|
||||
$feature->setRowGateway($feature);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function apply($method, $args)
|
||||
{
|
||||
foreach ($this->features as $feature) {
|
||||
if (method_exists($feature, $method)) {
|
||||
$return = call_user_func_array(array($feature, $method), $args);
|
||||
if ($return === self::APPLY_HALT) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property
|
||||
* @return bool
|
||||
*/
|
||||
public function canCallMagicGet($property)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property
|
||||
* @return mixed
|
||||
*/
|
||||
public function callMagicGet($property)
|
||||
{
|
||||
$return = null;
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property
|
||||
* @return bool
|
||||
*/
|
||||
public function canCallMagicSet($property)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $property
|
||||
* @param $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function callMagicSet($property, $value)
|
||||
{
|
||||
$return = null;
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @return bool
|
||||
*/
|
||||
public function canCallMagicCall($method)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @param array $arguments
|
||||
* @return mixed
|
||||
*/
|
||||
public function callMagicCall($method, $arguments)
|
||||
{
|
||||
$return = null;
|
||||
return $return;
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Db\RowGateway;
|
||||
|
||||
use Zend\Db\Adapter\Adapter;
|
||||
use Zend\Db\Sql\Sql;
|
||||
|
||||
class RowGateway extends AbstractRowGateway
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $primaryKeyColumn
|
||||
* @param string|\Zend\Db\Sql\TableIdentifier $table
|
||||
* @param Adapter|Sql $adapterOrSql
|
||||
* @throws Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct($primaryKeyColumn, $table, $adapterOrSql = null)
|
||||
{
|
||||
// setup primary key
|
||||
$this->primaryKeyColumn = (array) $primaryKeyColumn;
|
||||
|
||||
// set table
|
||||
$this->table = $table;
|
||||
|
||||
// set Sql object
|
||||
if ($adapterOrSql instanceof Sql) {
|
||||
$this->sql = $adapterOrSql;
|
||||
} elseif ($adapterOrSql instanceof Adapter) {
|
||||
$this->sql = new Sql($adapterOrSql, $this->table);
|
||||
} else {
|
||||
throw new Exception\InvalidArgumentException('A valid Sql object was not provided.');
|
||||
}
|
||||
|
||||
if ($this->sql->getTable() !== $this->table) {
|
||||
throw new Exception\InvalidArgumentException('The Sql object provided does not have a table that matches this row object');
|
||||
}
|
||||
|
||||
$this->initialize();
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user