add composer autoloader and libs

This commit is contained in:
onli 2013-08-18 12:46:45 +02:00
parent d9211d2c40
commit e63be19fe5
180 changed files with 23609 additions and 0 deletions

View File

@ -0,0 +1,7 @@
<?php
// autoload.php generated by Composer
require_once __DIR__ . '/composer' . '/autoload_real.php';
return ComposerAutoloaderInit3146f05565d9c8136a7e59e2a511ce14::getLoader();

View 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;
}
}

View File

@ -0,0 +1,9 @@
<?php
// autoload_classmap.php generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
);

View 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'),
);

View 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;
}
}

View 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"
}
}
]

View 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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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();
}

View File

@ -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']);
}
}

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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 &gt;= 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 &gt;= 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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View File

@ -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);
};
}
}

View File

@ -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);
};
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -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');
}
}

View File

@ -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();
}
}

View File

@ -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 &gt;= 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);
}
}

View File

@ -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;
}
}

View File

@ -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();
}

View File

@ -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'];
}
}

View File

@ -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;
}
}

View File

@ -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
{
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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);
// }
//}
}
}

View File

@ -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);
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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;
}
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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());
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,8 @@
<?php
namespace Zend\Db\Adapter\Profiler;
interface ProfilerAwareInterface
{
public function setProfiler(ProfilerInterface $profiler);
}

View File

@ -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();
}

View File

@ -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;
}
}

View File

@ -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();
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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
{
}

View 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);
}
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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
{
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View 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.

View File

@ -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;
}
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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();
}

View File

@ -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];
}
}
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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