torrentpier-lts/library/Zend/Db/TableGateway/AbstractTableGateway.php

526 lines
13 KiB
PHP
Raw Normal View History

<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
2023-04-01 09:03:34 +03:00
* @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\TableGateway;
use Zend\Db\Adapter\AdapterInterface;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\ResultSet\ResultSetInterface;
use Zend\Db\Sql\Delete;
use Zend\Db\Sql\Insert;
use Zend\Db\Sql\Select;
use Zend\Db\Sql\Sql;
use Zend\Db\Sql\TableIdentifier;
use Zend\Db\Sql\Update;
use Zend\Db\Sql\Where;
2023-04-01 09:03:34 +03:00
use Zend\Db\TableGateway\Feature\EventFeature;
/**
*
* @property AdapterInterface $adapter
* @property int $lastInsertValue
* @property string $table
*/
abstract class AbstractTableGateway implements TableGatewayInterface
{
/**
* @var bool
*/
protected $isInitialized = false;
/**
* @var AdapterInterface
*/
protected $adapter = null;
/**
2023-04-01 09:03:34 +03:00
* @var string|array|TableIdentifier
*/
protected $table = null;
/**
* @var array
*/
protected $columns = array();
/**
* @var Feature\FeatureSet
*/
protected $featureSet = null;
/**
* @var ResultSetInterface
*/
protected $resultSetPrototype = null;
/**
* @var Sql
*/
protected $sql = null;
/**
*
* @var int
*/
protected $lastInsertValue = null;
/**
* @return bool
*/
public function isInitialized()
{
return $this->isInitialized;
}
/**
* Initialize
*
* @throws Exception\RuntimeException
* @return null
*/
public function initialize()
{
if ($this->isInitialized) {
return;
}
if (!$this->featureSet instanceof Feature\FeatureSet) {
$this->featureSet = new Feature\FeatureSet;
}
$this->featureSet->setTableGateway($this);
2023-04-01 09:03:34 +03:00
$this->featureSet->apply(EventFeature::EVENT_PRE_INITIALIZE, array());
if (!$this->adapter instanceof AdapterInterface) {
throw new Exception\RuntimeException('This table does not have an Adapter setup');
}
2023-04-01 09:03:34 +03:00
if (!is_string($this->table) && !$this->table instanceof TableIdentifier && !is_array($this->table)) {
throw new Exception\RuntimeException('This table object does not have a valid table set.');
}
if (!$this->resultSetPrototype instanceof ResultSetInterface) {
$this->resultSetPrototype = new ResultSet;
}
if (!$this->sql instanceof Sql) {
$this->sql = new Sql($this->adapter, $this->table);
}
2023-04-01 09:03:34 +03:00
$this->featureSet->apply(EventFeature::EVENT_POST_INITIALIZE, array());
$this->isInitialized = true;
}
/**
* Get table name
*
* @return string
*/
public function getTable()
{
return $this->table;
}
/**
* Get adapter
*
* @return AdapterInterface
*/
public function getAdapter()
{
return $this->adapter;
}
/**
* @return array
*/
public function getColumns()
{
return $this->columns;
}
/**
* @return Feature\FeatureSet
*/
public function getFeatureSet()
{
return $this->featureSet;
}
/**
* Get select result prototype
*
* @return ResultSet
*/
public function getResultSetPrototype()
{
return $this->resultSetPrototype;
}
/**
* @return Sql
*/
public function getSql()
{
return $this->sql;
}
/**
* Select
*
* @param Where|\Closure|string|array $where
* @return ResultSet
*/
public function select($where = null)
{
if (!$this->isInitialized) {
$this->initialize();
}
$select = $this->sql->select();
if ($where instanceof \Closure) {
$where($select);
} elseif ($where !== null) {
$select->where($where);
}
return $this->selectWith($select);
}
/**
* @param Select $select
* @return null|ResultSetInterface
* @throws \RuntimeException
*/
public function selectWith(Select $select)
{
if (!$this->isInitialized) {
$this->initialize();
}
return $this->executeSelect($select);
}
/**
* @param Select $select
* @return ResultSet
* @throws Exception\RuntimeException
*/
protected function executeSelect(Select $select)
{
$selectState = $select->getRawState();
2023-04-01 09:03:34 +03:00
if ($selectState['table'] != $this->table
&& (is_array($selectState['table'])
&& end($selectState['table']) != $this->table)
) {
throw new Exception\RuntimeException(
'The table name of the provided select object must match that of the table'
);
}
if ($selectState['columns'] == array(Select::SQL_STAR)
&& $this->columns !== array()) {
$select->columns($this->columns);
}
// apply preSelect features
2023-04-01 09:03:34 +03:00
$this->featureSet->apply(EventFeature::EVENT_PRE_SELECT, array($select));
// prepare and execute
$statement = $this->sql->prepareStatementForSqlObject($select);
$result = $statement->execute();
// build result set
$resultSet = clone $this->resultSetPrototype;
$resultSet->initialize($result);
// apply postSelect features
2023-04-01 09:03:34 +03:00
$this->featureSet->apply(EventFeature::EVENT_POST_SELECT, array($statement, $result, $resultSet));
return $resultSet;
}
/**
* Insert
*
* @param array $set
* @return int
*/
public function insert($set)
{
if (!$this->isInitialized) {
$this->initialize();
}
$insert = $this->sql->insert();
$insert->values($set);
return $this->executeInsert($insert);
}
/**
* @param Insert $insert
* @return mixed
*/
public function insertWith(Insert $insert)
{
if (!$this->isInitialized) {
$this->initialize();
}
return $this->executeInsert($insert);
}
/**
* @todo add $columns support
*
* @param Insert $insert
* @return mixed
* @throws Exception\RuntimeException
*/
protected function executeInsert(Insert $insert)
{
$insertState = $insert->getRawState();
if ($insertState['table'] != $this->table) {
2023-04-01 09:03:34 +03:00
throw new Exception\RuntimeException(
'The table name of the provided Insert object must match that of the table'
);
}
// apply preInsert features
2023-04-01 09:03:34 +03:00
$this->featureSet->apply(EventFeature::EVENT_PRE_INSERT, array($insert));
// Most RDBMS solutions do not allow using table aliases in INSERTs
// See https://github.com/zendframework/zf2/issues/7311
$unaliasedTable = false;
if (is_array($insertState['table'])) {
$tableData = array_values($insertState['table']);
$unaliasedTable = array_shift($tableData);
$insert->into($unaliasedTable);
}
$statement = $this->sql->prepareStatementForSqlObject($insert);
$result = $statement->execute();
$this->lastInsertValue = $this->adapter->getDriver()->getConnection()->getLastGeneratedValue();
// apply postInsert features
2023-04-01 09:03:34 +03:00
$this->featureSet->apply(EventFeature::EVENT_POST_INSERT, array($statement, $result));
2023-04-01 09:03:34 +03:00
// Reset original table information in Insert instance, if necessary
if ($unaliasedTable) {
$insert->into($insertState['table']);
}
$return = $result->getAffectedRows();
return $return;
}
/**
* Update
*
* @param array $set
* @param string|array|\Closure $where
* @return int
*/
public function update($set, $where = null)
{
if (!$this->isInitialized) {
$this->initialize();
}
$sql = $this->sql;
$update = $sql->update();
$update->set($set);
if ($where !== null) {
$update->where($where);
}
return $this->executeUpdate($update);
}
/**
* @param \Zend\Db\Sql\Update $update
* @return mixed
*/
public function updateWith(Update $update)
{
if (!$this->isInitialized) {
$this->initialize();
}
return $this->executeUpdate($update);
}
/**
* @todo add $columns support
*
* @param Update $update
* @return mixed
* @throws Exception\RuntimeException
*/
protected function executeUpdate(Update $update)
{
$updateState = $update->getRawState();
if ($updateState['table'] != $this->table) {
2023-04-01 09:03:34 +03:00
throw new Exception\RuntimeException(
'The table name of the provided Update object must match that of the table'
);
}
// apply preUpdate features
2023-04-01 09:03:34 +03:00
$this->featureSet->apply(EventFeature::EVENT_PRE_UPDATE, array($update));
$statement = $this->sql->prepareStatementForSqlObject($update);
$result = $statement->execute();
// apply postUpdate features
2023-04-01 09:03:34 +03:00
$this->featureSet->apply(EventFeature::EVENT_POST_UPDATE, array($statement, $result));
return $result->getAffectedRows();
}
/**
* Delete
*
* @param Where|\Closure|string|array $where
* @return int
*/
public function delete($where)
{
if (!$this->isInitialized) {
$this->initialize();
}
$delete = $this->sql->delete();
if ($where instanceof \Closure) {
$where($delete);
} else {
$delete->where($where);
}
return $this->executeDelete($delete);
}
/**
* @param Delete $delete
* @return mixed
*/
public function deleteWith(Delete $delete)
{
$this->initialize();
return $this->executeDelete($delete);
}
/**
* @todo add $columns support
*
* @param Delete $delete
* @return mixed
* @throws Exception\RuntimeException
*/
protected function executeDelete(Delete $delete)
{
$deleteState = $delete->getRawState();
if ($deleteState['table'] != $this->table) {
2023-04-01 09:03:34 +03:00
throw new Exception\RuntimeException(
'The table name of the provided Update object must match that of the table'
);
}
// pre delete update
2023-04-01 09:03:34 +03:00
$this->featureSet->apply(EventFeature::EVENT_PRE_DELETE, array($delete));
$statement = $this->sql->prepareStatementForSqlObject($delete);
$result = $statement->execute();
// apply postDelete features
2023-04-01 09:03:34 +03:00
$this->featureSet->apply(EventFeature::EVENT_POST_DELETE, array($statement, $result));
return $result->getAffectedRows();
}
/**
* Get last insert value
*
* @return int
*/
public function getLastInsertValue()
{
return $this->lastInsertValue;
}
/**
* __get
*
* @param string $property
* @throws Exception\InvalidArgumentException
* @return mixed
*/
public function __get($property)
{
switch (strtolower($property)) {
case 'lastinsertvalue':
return $this->lastInsertValue;
case 'adapter':
return $this->adapter;
case 'table':
return $this->table;
}
if ($this->featureSet->canCallMagicGet($property)) {
return $this->featureSet->callMagicGet($property);
}
throw new Exception\InvalidArgumentException('Invalid magic property access in ' . __CLASS__ . '::__get()');
}
/**
* @param string $property
* @param mixed $value
* @return mixed
* @throws Exception\InvalidArgumentException
*/
public function __set($property, $value)
{
if ($this->featureSet->canCallMagicSet($property)) {
return $this->featureSet->callMagicSet($property, $value);
}
throw new Exception\InvalidArgumentException('Invalid magic property access in ' . __CLASS__ . '::__set()');
}
/**
* @param $method
* @param $arguments
* @return mixed
* @throws Exception\InvalidArgumentException
*/
public function __call($method, $arguments)
{
if ($this->featureSet->canCallMagicCall($method)) {
return $this->featureSet->callMagicCall($method, $arguments);
}
2023-04-01 09:03:34 +03:00
throw new Exception\InvalidArgumentException(sprintf(
'Invalid method (%s) called, caught by %s::__call()',
$method,
__CLASS__
));
}
/**
* __clone
*/
public function __clone()
{
$this->resultSetPrototype = (isset($this->resultSetPrototype)) ? clone $this->resultSetPrototype : null;
$this->sql = clone $this->sql;
if (is_object($this->table)) {
$this->table = clone $this->table;
2023-04-01 09:03:34 +03:00
} elseif (
is_array($this->table)
&& count($this->table) == 1
&& is_object(reset($this->table))
) {
foreach ($this->table as $alias => &$tableObject) {
$tableObject = clone $tableObject;
}
}
}
}