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

[ZF3] refactor sql #30

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
b328d08
fix CS
turrsis Jul 30, 2015
298b1ae
architecture 01: change namespaces
turrsis Jul 9, 2015
fc7fc46
architecture 02: create SqlObject builders
turrsis Jul 9, 2015
9166f51
architecture 03: create Expression builders
turrsis Jul 9, 2015
42c0096
architecture 04: optimize tests for Builders
turrsis Jul 9, 2015
8b34b45
architecture 05: refactor AbstractBuilder::createSqlFromSpecification…
turrsis Jul 9, 2015
e384a6c
architecture fix 06: LIMIT and OFFSET builders
turrsis Jul 12, 2015
ab3bef3
architecture fix 07: use TableIdentifier in all SqlObjects
turrsis Jul 29, 2015
d64c0ba
architecture fix 08: Column builder
turrsis Jul 12, 2015
7a22fce
architecture fix 09: AbstractSqlBuilder::resolveColumnValue()
turrsis Jul 12, 2015
8b5b9fd
architecture 10: move functionality from AbstractSqlBuilder to Builde…
turrsis Jul 12, 2015
70c484e
architecture 10.1: unprotect builded methods, because protected is no…
turrsis Nov 27, 2015
5d77e28
fix 11: SelectBuilder for Combine
turrsis Jul 31, 2015
5a76ed4
fix 12: remove $prefixColumnsWithTable from Select::columns() method
turrsis Jul 12, 2015
6b11aa9
fix 13: build empty predicate
turrsis Jul 31, 2015
039d30d
fix 14: Sql\Insert add multiple values
turrsis Aug 6, 2015
6ce22b5
fix 15: DropTable add 'IF EXISTS'
turrsis Aug 6, 2015
c9590a8
fix 16: Sql\Ddl\Column\Boolean can be nullable
turrsis Aug 10, 2015
3533842
fix 17: add Ddl\Sql object
turrsis Aug 10, 2015
9520725
fix 18: rename joins
turrsis Apr 21, 2016
628b17e
fix 19: combine in select
turrsis May 24, 2016
ad9055c
fix 20: Sql\Builder\Builder add Factory
turrsis Sep 7, 2016
1a8a9a2
refactor docs
turrsis May 24, 2016
e60f49e
fix 21: fix namespaces
turrsis Nov 1, 2016
2277e66
fix 22: add 'charset' mysql option to ColumnBuilder
turrsis Nov 1, 2016
63d9ef2
fix 23: rename 'Config' to 'config' (for ServiceManager 3.0)
turrsis Nov 2, 2016
8be0cb2
fix 24: remove @deprecated
turrsis Nov 3, 2016
84ce3a5
fix 25: remove $lastPreparedStatement property because it never using
turrsis Nov 3, 2016
c0f7f5b
fix 26: remove __get() method because it is excess
turrsis Nov 3, 2016
a5d195e
fix 27: allow to use SqlObject in Adapter directly.
turrsis Nov 3, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions doc/book/sql-ddl.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,13 @@ use Zend\Db\Sql\Sql;
$sql = new Sql($adapter);

$adapter->query(
$sql->getSqlStringForSqlObject($ddl),
$sql->buildSqlString($ddl),
$adapter::QUERY_MODE_EXECUTE
);
```

By passing the `$ddl` object through the `$sql` instance's
`getSqlStringForSqlObject()` method, we ensure that any platform specific
`buildSqlString()` method, we ensure that any platform specific
specializations/modifications are utilized to create a platform specific SQL
statement.

Expand Down
88 changes: 60 additions & 28 deletions doc/book/sql.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ $select = $sql->select();
$select->from('foo');
$select->where(['id' => 2]);

$statement = $sql->prepareStatementForSqlObject($select);
$statement = $sql->prepareSqlStatement($select);
$results = $statement->execute();
```

Expand Down Expand Up @@ -78,19 +78,16 @@ $select->where(['id' => 2]); // $select already has from('foo') applied
Each of these objects implements the following two interfaces:

```php
interface PreparableSqlInterface
interface SelectableInterface
{
public function prepareStatement(Adapter $adapter, StatementInterface $statement) : void;
}

interface SqlInterface
interface PreparableSqlInterface
{
public function getSqlString(PlatformInterface $adapterPlatform = null) : string;
}
```

Use these functions to produce either (a) a prepared statement, or (b) a string
to execute.
Use these interfaces for create user defined sql objects.

## Select

Expand All @@ -113,22 +110,33 @@ Once you have a valid `Select` object, the following API can be used to further
specify various select statement parts:

```php
class Select extends AbstractSql implements SqlInterface, PreparableSqlInterface
class Select extends AbstractSql implements PreparableSqlInterface, SelectableInterface
{
const JOIN_INNER = 'inner';
const JOIN_OUTER = 'outer';
const JOIN_LEFT = 'left';
const JOIN_RIGHT = 'right';
const QUANTIFIER_DISTINCT = 'DISTINCT';
const QUANTIFIER_ALL = 'ALL';
const SQL_STAR = '*';
const ORDER_ASCENDING = 'ASC';
const ORDER_DESCENDING = 'DESC';

public $table // @param TableSource $table
public $quantifier; // @param string|Expression $quantifier DISTINCT|ALL
public $columns; // @param array $columns
public $joins; // @param $joins
public $where; // @param Where $where

public function __construct(string|array|TableIdentifier $table = null);
public function from(string|array|TableIdentifier $table) : self;
public function columns(array $columns, bool $prefixColumnsWithTable = true) : self;
public function join(string|array $name, string $on, string|array $columns = self::SQL_STAR, string $type = self::JOIN_INNER) : self;
public $order; // @param string|array $order
public $group; // @param $group
public $having; // @param Having $having
public $limit; // @param int $limit
public $offset; // @param int $offset
public $combine; // @param $combine
public $prefixColumnsWithTable; // @param $prefixColumnsWithTable

public function __construct(null|string|array|TableIdentifier|TableSource $table = null);
public function from(string|array|TableIdentifier|TableSource $table) : self;
public function quantifier(string|ExpressionInterface $quantifier) :self;
public function columns(array $columns) : self;
public function setPrefixColumnsWithTable(bool $flag) :self;
public function join(string|array|TableIdentifier|TableSource $name, string $on, string|array $columns = self::SQL_STAR, string $type = Joins::JOIN_INNER) : self;
public function where(Where|callable|string|array|PredicateInterface $predicate, string $combination = Predicate\PredicateSet::OP_AND) : self;
public function group(string|array $group);
public function having(Having|callable|string|array $predicate, string $combination = Predicate\PredicateSet::OP_AND) : self;
Expand All @@ -148,9 +156,17 @@ $select->from('foo');
// (produces SELECT "t".* FROM "table" AS "t")
$select->from(['t' => 'table']);

// As an array to specify an alias and schema
// (produces SELECT "t".* FROM "schema"."table" AS "t")
$select->from(['t' => ['schema', 'table']]);

// Using a Sql\TableIdentifier:
// (same output as above)
// (produces SELECT "t".* FROM "table" AS "t")
$select->from(new TableIdentifier(['t' => 'table']));

// Using a Sql\TableSource:
// (produces SELECT "t".* FROM "table" AS "t")
$select->from(new TableSource('table', 't'));
```

### columns()
Expand Down Expand Up @@ -286,15 +302,20 @@ $select->offset(10); // similarly takes an integer/numeric
The Insert API:

```php
class Insert implements SqlInterface, PreparableSqlInterface
class Insert extends AbstractSql implements PreparableSqlInterface
{
const VALUES_MERGE = 'merge';
const VALUES_SET = 'set';

public function __construct(string|TableIdentifier $table = null);
public function into(string|TableIdentifier $table) : self;
public $table // @param TableSource $table
public $columns // @param array $columns
public $values // @param array|SelectableInterface $values

public function __construct(null|string|array|TableIdentifier|TableSource $table = null);
public function into(string|array|TableIdentifier|TableSource $table) : self;
public function columns(array $columns) : self;
public function values(array $values, string $flag = self::VALUES_SET) : self;
public function values(array|SelectableInterface $values, string $flag = self::VALUES_SET) : self;
public function select(SelectableInterface $select) : self;
}
```

Expand Down Expand Up @@ -323,17 +344,27 @@ $insert->values([
$insert->values(['col_2' => 'value2'], $insert::VALUES_MERGE);
```

```php
// To use `Select` for values:
$insert->values(new Select('foo');
// or
$insert->select(new Select('foo');
```

## Update

```php
class Update
class Update extends AbstractSql implements PreparableSqlInterface
{
const VALUES_MERGE = 'merge';
const VALUES_SET = 'set';

public $table // @param TableSource $table
public $set // @param PriorityList $set
public $where; // @param Where $where
public function __construct(string|TableIdentifier $table = null);
public function table(string|TableIdentifier $table) : self;

public function __construct(null|string|array|TableIdentifier|TableSource $table = null);
public function table(string|array|TableIdentifier|TableSource $table) : self;
public function set(array $values, string $flag = self::VALUES_SET) : self;
public function where(Where|callable|string|array|PredicateInterface $predicate, string $combination = Predicate\PredicateSet::OP_AND) : self;
}
Expand All @@ -352,12 +383,13 @@ See the [section on Where and Having](#where-and-having).
## Delete

```php
class Delete
class Delete extends AbstractSql implements PreparableSqlInterface
{
public $table // @param TableSource $table
public $where; // @param Where $where

public function __construct(string|TableIdentifier $table = null);
public function from(string|TableIdentifier $table);
public function __construct(null|string|array|TableIdentifier|TableSource $table = null);
public function from(string|array|TableIdentifier|TableSource $table);
public function where(Where|callable|string|array|PredicateInterface $predicate, string $combination = Predicate\PredicateSet::OP_AND) : self;
}
```
Expand Down
96 changes: 44 additions & 52 deletions src/Adapter/Adapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@

use Zend\Db\ResultSet;

/**
* @property Driver\DriverInterface $driver
* @property Platform\PlatformInterface $platform
*/
class Adapter implements AdapterInterface, Profiler\ProfilerAwareInterface
{
/**
Expand Down Expand Up @@ -56,9 +52,9 @@ class Adapter implements AdapterInterface, Profiler\ProfilerAwareInterface
protected $queryResultSetPrototype = null;

/**
* @var Driver\StatementInterface
* @var SqlBuilderInterface
*/
protected $lastPreparedStatement = null;
protected $sqlBuilder;

/**
* @param Driver\DriverInterface|array $driver
Expand All @@ -74,6 +70,9 @@ public function __construct($driver, Platform\PlatformInterface $platform = null

if (is_array($driver)) {
$parameters = $driver;
if (isset($parameters['sql_builder'])) {
$this->setSqlBuilder($parameters['sql_builder']);
}
if ($profiler === null && isset($parameters['profiler'])) {
$profiler = $this->createProfiler($parameters);
}
Expand Down Expand Up @@ -155,6 +154,24 @@ public function getCurrentSchema()
return $this->driver->getConnection()->getCurrentSchema();
}

/**
* @return SqlBuilderInterface
*/
public function getSqlBuilder()
{
return $this->sqlBuilder;
}

/**
* @param SqlBuilderInterface $sqlBuilder
* @return self
*/
public function setSqlBuilder(SqlBuilderInterface $sqlBuilder)
{
$this->sqlBuilder = $sqlBuilder;
return $this;
}

/**
* query() is a convenience function
*
Expand All @@ -176,17 +193,31 @@ public function query($sql, $parametersOrQueryMode = self::QUERY_MODE_PREPARE, R
throw new Exception\InvalidArgumentException('Parameter 2 to this method must be a flag, an array, or ParameterContainer');
}

$sqlIsString = is_string($sql) || (is_object($sql) && method_exists($sql, '__toString'));

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();
if ($sqlIsString) {
$preparedStatement = $this->driver->createStatement($sql);
} else {
return $this->lastPreparedStatement;
if (!$this->sqlBuilder) {
throw new Exception\RuntimeException('sqlBuilder must be set for non string sql');
}
$preparedStatement = $this->sqlBuilder->prepareSqlStatement($sql, $this);
}
$preparedStatement->prepare();
if ($parameters !== null) {
$preparedStatement->setParameterContainer((is_array($parameters)) ? new ParameterContainer($parameters) : $parameters);
$result = $preparedStatement->execute();
} else {
return $preparedStatement;
}
} else {
if (!$sqlIsString) {
if (!$this->sqlBuilder) {
throw new Exception\RuntimeException('sqlBuilder must be set for non string sql');
}
$sql = $this->sqlBuilder->buildSqlString($sql, $this);
}
$result = $this->driver->getConnection()->execute($sql);
}

Expand Down Expand Up @@ -233,23 +264,6 @@ public function getHelpers(/* $functions */)
}
}

/**
* @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
Expand Down Expand Up @@ -369,26 +383,4 @@ protected function createProfiler($parameters)
}
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);
}
}
3 changes: 3 additions & 0 deletions src/Adapter/AdapterAbstractServiceFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$config = $this->getConfig($container);
if (isset($config[$requestedName]['sql_builder'])) {
$config[$requestedName]['sql_builder'] = $container->get($config[$requestedName]['sql_builder']);
}
return new Adapter($config[$requestedName]);
}

Expand Down
5 changes: 0 additions & 5 deletions src/Adapter/AdapterInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,6 @@

namespace Zend\Db\Adapter;

/**
*
* @property Driver\DriverInterface $driver
* @property Platform\PlatformInterface $platform
*/
interface AdapterInterface
{
/**
Expand Down
3 changes: 3 additions & 0 deletions src/Adapter/AdapterServiceFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ class AdapterServiceFactory implements FactoryInterface
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$config = $container->get('config');
if (isset($config['db']['sql_builder'])) {
$config['db']['sql_builder'] = $container->get($config['db']['sql_builder']);
}
return new Adapter($config['db']);
}

Expand Down
27 changes: 27 additions & 0 deletions src/Adapter/SqlBuilderInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace Zend\Db\Adapter;

interface SqlBuilderInterface
{
/**
* @param mixed $object
* @param null|AdapterInterface $adapter
* @return string
*/
public function buildSqlString($object, AdapterInterface $adapter = null);

/**
* @param mixed $object
* @param null|AdapterInterface $adapter
* @return Driver\StatementInterface
*/
public function prepareSqlStatement($object, AdapterInterface $adapter = null);
}
1 change: 1 addition & 0 deletions src/ConfigProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public function getDependencyConfig()
],
'factories' => [
Adapter\AdapterInterface::class => Adapter\AdapterServiceFactory::class,
Adapter\SqlBuilderInterface::class => Sql\Builder\BuilderServiceFactory::class,
],
'aliases' => [
Adapter\Adapter::class => Adapter\AdapterInterface::class,
Expand Down
Loading