Skip to content
This repository has been archived by the owner on Jan 8, 2020. It is now read-only.

Commit

Permalink
Merge 68b2994 into a97fc91
Browse files Browse the repository at this point in the history
  • Loading branch information
desenvuno committed Apr 16, 2015
2 parents a97fc91 + 68b2994 commit 40b3145
Show file tree
Hide file tree
Showing 9 changed files with 357 additions and 57 deletions.
4 changes: 2 additions & 2 deletions library/Zend/Db/Adapter/Adapter.php
Expand Up @@ -333,8 +333,8 @@ protected function createPlatform($parameters)
// 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);
$driver = ($this->driver instanceof Driver\Oci8\Oci8 || $this->driver instanceof Driver\Pdo\Pdo) ? $this->driver : null;
return new Platform\Oracle($options, $driver);
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);
Expand Down
76 changes: 76 additions & 0 deletions library/Zend/Db/Adapter/Driver/Oci8/Feature/RowCounter.php
@@ -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-2015 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\Feature;

use Zend\Db\Adapter\Driver\Feature\AbstractFeature;
use Zend\Db\Adapter\Driver\Oci8\Statement;

/**
* RowCounter
*/
class RowCounter extends AbstractFeature
{

/**
* @return string
*/
public function getName()
{
return 'RowCounter';
}

/**
* @param \Zend\Db\Adapter\Driver\Oci8\Statement $statement
* @return null|int
*/
public function getCountForStatement(Statement $statement)
{
$countStmt = clone $statement;
$sql = $statement->getSql();
if ($sql == '' || stripos(strtolower($sql), 'select') === false) {
return;
}
$countSql = 'SELECT COUNT(*) as "count" FROM (' . $sql . ')';
$countStmt->prepare($countSql);
$result = $countStmt->execute();
$countRow = $result->current();
return $countRow['count'];
}

/**
* @param string $sql
* @return null|int
*/
public function getCountForSql($sql)
{
if (stripos(strtolower($sql), 'select') === false) {
return;
}
$countSql = 'SELECT COUNT(*) as "count" FROM (' . $sql . ')';
$result = $this->driver->getConnection()->execute($countSql);
$countRow = $result->current();
return $countRow['count'];
}

/**
* @param \Zend\Db\Adapter\Driver\Oci8\Statement|string $context
* @return closure
*/
public function getRowCountClosure($context)
{
$rowCounter = $this;
return function () use ($rowCounter, $context) {
/** @var $rowCounter RowCounter */
return ($context instanceof Statement)
? $rowCounter->getCountForStatement($context)
: $rowCounter->getCountForSql($context);
};
}
}
94 changes: 75 additions & 19 deletions library/Zend/Db/Adapter/Driver/Oci8/Oci8.php
Expand Up @@ -12,9 +12,16 @@
use Zend\Db\Adapter\Driver\DriverInterface;
use Zend\Db\Adapter\Exception;
use Zend\Db\Adapter\Profiler;
use Zend\Db\Adapter\Driver\Feature\AbstractFeature;
use Zend\Db\Adapter\Driver\Feature\DriverFeatureInterface;

class Oci8 implements DriverInterface, Profiler\ProfilerAwareInterface
class Oci8 implements DriverInterface, DriverFeatureInterface, Profiler\ProfilerAwareInterface
{
/**
* @const
*/
const FEATURES_DEFAULT = 'default';

/**
* @var Connection
*/
Expand All @@ -34,23 +41,40 @@ class Oci8 implements DriverInterface, Profiler\ProfilerAwareInterface
* @var Profiler\ProfilerInterface
*/
protected $profiler = null;
/**
* @var array
*/
protected $options = array();
/**
* @var array
*/
protected $features = 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)
public function __construct($connection, Statement $statementPrototype = null, Result $resultPrototype = null, array $options = array(), $features = self::FEATURES_DEFAULT)
{
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());
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 Oci8
Expand All @@ -66,15 +90,13 @@ public function setProfiler(Profiler\ProfilerInterface $profiler)
}
return $this;
}

/**
* @return null|Profiler\ProfilerInterface
*/
public function getProfiler()
{
return $this->profiler;
}

/**
* Register connection
*
Expand All @@ -87,7 +109,6 @@ public function registerConnection(Connection $connection)
$this->connection->setDriver($this); // needs access to driver to createStatement()
return $this;
}

/**
* Register statement prototype
*
Expand All @@ -100,15 +121,13 @@ public function registerStatementPrototype(Statement $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
*
Expand All @@ -120,15 +139,52 @@ public function registerResultPrototype(Result $resultPrototype)
$this->resultPrototype = $resultPrototype;
return $this;
}

/**
* @return null|Result
*/
public function getResultPrototype()
{
return $this->resultPrototype;
}

/**
* Add feature
*
* @param string $name
* @param AbstractFeature $feature
* @return self
*/
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 self
*/
public function setupDefaultFeatures()
{
$this->addFeature(null, new Feature\RowCounter());
return $this;
}
/**
* Get feature
*
* @param string $name
* @return AbstractFeature|false
*/
public function getFeature($name)
{
if (isset($this->features[$name])) {
return $this->features[$name];
}
return false;
}
/**
* Get database platform name
*
Expand All @@ -139,7 +195,6 @@ public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCAS
{
return 'Oracle';
}

/**
* Check environment
*/
Expand All @@ -149,15 +204,13 @@ public function checkEnvironment()
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
Expand All @@ -182,19 +235,22 @@ public function createStatement($sqlOrResource = null)
}
return $statement;
}

/**
* @param resource $resource
* @param null $isBuffered
* @param null $context
* @return Result
*/
public function createResult($resource, $isBuffered = null)
public function createResult($resource, $context = null)
{
$result = clone $this->resultPrototype;
$result->initialize($resource, $this->connection->getLastGeneratedValue(), $isBuffered);
$rowCount = null;
// special feature, oracle Oci counter
if ($context && ($rowCounter = $this->getFeature('RowCounter')) && oci_num_fields($resource) > 0) {
$rowCount = $rowCounter->getRowCountClosure($context);
}
$result->initialize($resource, $this->connection->getLastGeneratedValue(), $rowCount);
return $result;
}

/**
* @return array
*/
Expand Down
22 changes: 16 additions & 6 deletions library/Zend/Db/Adapter/Driver/Oci8/Result.php
Expand Up @@ -21,9 +21,9 @@ class Result implements Iterator, ResultInterface
protected $resource = null;

/**
* @var bool
* @var null
*/
protected $isBuffered = null;
protected $rowCount = null;

/**
* Cursor position
Expand Down Expand Up @@ -62,14 +62,18 @@ class Result implements Iterator, ResultInterface
/**
* Initialize
* @param resource $resource
* @param null|int $generatedValue
* @param null|int $rowCount
* @return Result
*/
public function initialize($resource /*, $generatedValue, $isBuffered = null*/)
public function initialize($resource, $generatedValue = null, $rowCount = null)
{
if (!is_resource($resource) && get_resource_type($resource) !== 'oci8 statement') {
throw new Exception\InvalidArgumentException('Invalid resource provided.');
}
$this->resource = $resource;
$this->generatedValue = $generatedValue;
$this->rowCount = $rowCount;
return $this;
}

Expand Down Expand Up @@ -197,11 +201,17 @@ public function valid()

/**
* Count
* @return int
* @return null|int
*/
public function count()
{
// @todo OCI8 row count in Driver Result
if (is_int($this->rowCount)) {
return $this->rowCount;
}
if ($this->rowCount instanceof \Closure) {
$this->rowCount = (int) call_user_func($this->rowCount);
return $this->rowCount;
}
return;
}

Expand All @@ -214,7 +224,7 @@ public function getFieldCount()
}

/**
* @return mixed|null
* @return null
*/
public function getGeneratedValue()
{
Expand Down
16 changes: 13 additions & 3 deletions library/Zend/Db/Adapter/Driver/Oci8/Statement.php
Expand Up @@ -260,7 +260,7 @@ public function execute($parameters = null)
throw new Exception\RuntimeException($e['message'], $e['code']);
}

$result = $this->driver->createResult($this->resource);
$result = $this->driver->createResult($this->resource, $this);
return $result;
}

Expand All @@ -272,7 +272,6 @@ public function execute($parameters = null)
protected function bindParametersFromContainer()
{
$parameters = $this->parameterContainer->getNamedArray();

foreach ($parameters as $name => &$value) {
if ($this->parameterContainer->offsetHasErrata($name)) {
switch ($this->parameterContainer->offsetGetErrata($name)) {
Expand Down Expand Up @@ -309,8 +308,19 @@ protected function bindParametersFromContainer()
if ($this->parameterContainer->offsetHasMaxLength($name)) {
$maxLength = $this->parameterContainer->offsetGetMaxLength($name);
}

oci_bind_by_name($this->resource, $name, $value, $maxLength, $type);
}
}
/**
* Perform a deep clone
*/
public function __clone()
{
$this->isPrepared = false;
$this->parametersBound = false;
$this->resource = null;
if ($this->parameterContainer) {
$this->parameterContainer = clone $this->parameterContainer;
}
}
}

0 comments on commit 40b3145

Please sign in to comment.