2023-03-11 12:04:29 +03:00
|
|
|
<?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)
|
2023-03-11 12:04:29 +03:00
|
|
|
* @license http://framework.zend.com/license/new-bsd New BSD License
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace Zend\Db\Sql;
|
|
|
|
|
|
|
|
use Zend\Db\Adapter\ParameterContainer;
|
|
|
|
use Zend\Db\Adapter\Platform\PlatformInterface;
|
2023-04-01 09:03:34 +03:00
|
|
|
use Zend\Db\Adapter\Driver\DriverInterface;
|
2023-03-11 12:04:29 +03:00
|
|
|
|
2023-04-01 09:03:34 +03:00
|
|
|
class Insert extends AbstractPreparableSql
|
2023-03-11 12:04:29 +03:00
|
|
|
{
|
|
|
|
/**#@+
|
|
|
|
* Constants
|
|
|
|
*
|
|
|
|
* @const
|
|
|
|
*/
|
|
|
|
const SPECIFICATION_INSERT = 'insert';
|
|
|
|
const SPECIFICATION_SELECT = 'select';
|
|
|
|
const VALUES_MERGE = 'merge';
|
|
|
|
const VALUES_SET = 'set';
|
|
|
|
/**#@-*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var array Specification array
|
|
|
|
*/
|
|
|
|
protected $specifications = array(
|
|
|
|
self::SPECIFICATION_INSERT => 'INSERT INTO %1$s (%2$s) VALUES (%3$s)',
|
|
|
|
self::SPECIFICATION_SELECT => 'INSERT INTO %1$s %2$s %3$s',
|
|
|
|
);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string|TableIdentifier
|
|
|
|
*/
|
|
|
|
protected $table = null;
|
|
|
|
protected $columns = array();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var array|Select
|
|
|
|
*/
|
2023-04-01 09:03:34 +03:00
|
|
|
protected $select = null;
|
2023-03-11 12:04:29 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*
|
|
|
|
* @param null|string|TableIdentifier $table
|
|
|
|
*/
|
|
|
|
public function __construct($table = null)
|
|
|
|
{
|
|
|
|
if ($table) {
|
|
|
|
$this->into($table);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create INTO clause
|
|
|
|
*
|
|
|
|
* @param string|TableIdentifier $table
|
|
|
|
* @return Insert
|
|
|
|
*/
|
|
|
|
public function into($table)
|
|
|
|
{
|
|
|
|
$this->table = $table;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Specify columns
|
|
|
|
*
|
|
|
|
* @param array $columns
|
|
|
|
* @return Insert
|
|
|
|
*/
|
|
|
|
public function columns(array $columns)
|
|
|
|
{
|
2023-04-01 09:03:34 +03:00
|
|
|
$this->columns = array_flip($columns);
|
2023-03-11 12:04:29 +03:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Specify values to insert
|
|
|
|
*
|
|
|
|
* @param array|Select $values
|
|
|
|
* @param string $flag one of VALUES_MERGE or VALUES_SET; defaults to VALUES_SET
|
|
|
|
* @throws Exception\InvalidArgumentException
|
|
|
|
* @return Insert
|
|
|
|
*/
|
|
|
|
public function values($values, $flag = self::VALUES_SET)
|
|
|
|
{
|
|
|
|
if ($values instanceof Select) {
|
2023-04-01 09:03:34 +03:00
|
|
|
if ($flag == self::VALUES_MERGE) {
|
2023-03-11 12:04:29 +03:00
|
|
|
throw new Exception\InvalidArgumentException(
|
2023-04-01 09:03:34 +03:00
|
|
|
'A Zend\Db\Sql\Select instance cannot be provided with the merge flag'
|
2023-03-11 12:04:29 +03:00
|
|
|
);
|
|
|
|
}
|
2023-04-01 09:03:34 +03:00
|
|
|
$this->select = $values;
|
2023-03-11 12:04:29 +03:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2023-04-01 09:03:34 +03:00
|
|
|
if (!is_array($values)) {
|
|
|
|
throw new Exception\InvalidArgumentException(
|
|
|
|
'values() expects an array of values or Zend\Db\Sql\Select instance'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if ($this->select && $flag == self::VALUES_MERGE) {
|
2023-03-11 12:04:29 +03:00
|
|
|
throw new Exception\InvalidArgumentException(
|
2023-04-01 09:03:34 +03:00
|
|
|
'An array of values cannot be provided with the merge flag when a Zend\Db\Sql\Select instance already exists as the value source'
|
2023-03-11 12:04:29 +03:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2023-04-01 09:03:34 +03:00
|
|
|
if ($flag == self::VALUES_SET) {
|
|
|
|
$this->columns = $values;
|
|
|
|
} else {
|
|
|
|
foreach ($values as $column=>$value) {
|
|
|
|
$this->columns[$column] = $value;
|
2023-03-11 12:04:29 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create INTO SELECT clause
|
|
|
|
*
|
|
|
|
* @param Select $select
|
|
|
|
* @return self
|
|
|
|
*/
|
|
|
|
public function select(Select $select)
|
|
|
|
{
|
|
|
|
return $this->values($select);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get raw state
|
|
|
|
*
|
|
|
|
* @param string $key
|
|
|
|
* @return mixed
|
|
|
|
*/
|
|
|
|
public function getRawState($key = null)
|
|
|
|
{
|
|
|
|
$rawState = array(
|
|
|
|
'table' => $this->table,
|
2023-04-01 09:03:34 +03:00
|
|
|
'columns' => array_keys($this->columns),
|
|
|
|
'values' => array_values($this->columns)
|
2023-03-11 12:04:29 +03:00
|
|
|
);
|
|
|
|
return (isset($key) && array_key_exists($key, $rawState)) ? $rawState[$key] : $rawState;
|
|
|
|
}
|
|
|
|
|
2023-04-01 09:03:34 +03:00
|
|
|
protected function processInsert(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null)
|
2023-03-11 12:04:29 +03:00
|
|
|
{
|
2023-04-01 09:03:34 +03:00
|
|
|
if ($this->select) {
|
|
|
|
return;
|
2023-03-11 12:04:29 +03:00
|
|
|
}
|
2023-04-01 09:03:34 +03:00
|
|
|
if (!$this->columns) {
|
|
|
|
throw new Exception\InvalidArgumentException('values or select should be present');
|
2023-03-11 12:04:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
$columns = array();
|
|
|
|
$values = array();
|
2023-04-01 09:03:34 +03:00
|
|
|
foreach ($this->columns as $column=>$value) {
|
|
|
|
$columns[] = $platform->quoteIdentifier($column);
|
|
|
|
if (is_scalar($value) && $parameterContainer) {
|
|
|
|
$values[] = $driver->formatParameterName($column);
|
|
|
|
$parameterContainer->offsetSet($column, $value);
|
|
|
|
} else {
|
|
|
|
$values[] = $this->resolveColumnValue(
|
|
|
|
$value,
|
|
|
|
$platform,
|
|
|
|
$driver,
|
|
|
|
$parameterContainer
|
|
|
|
);
|
2023-03-11 12:04:29 +03:00
|
|
|
}
|
|
|
|
}
|
2023-04-01 09:03:34 +03:00
|
|
|
return sprintf(
|
|
|
|
$this->specifications[static::SPECIFICATION_INSERT],
|
|
|
|
$this->resolveTable($this->table, $platform, $driver, $parameterContainer),
|
|
|
|
implode(', ', $columns),
|
|
|
|
implode(', ', $values)
|
|
|
|
);
|
2023-03-11 12:04:29 +03:00
|
|
|
}
|
|
|
|
|
2023-04-01 09:03:34 +03:00
|
|
|
protected function processSelect(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null)
|
2023-03-11 12:04:29 +03:00
|
|
|
{
|
2023-04-01 09:03:34 +03:00
|
|
|
if (!$this->select) {
|
|
|
|
return;
|
2023-03-11 12:04:29 +03:00
|
|
|
}
|
2023-04-01 09:03:34 +03:00
|
|
|
$selectSql = $this->processSubSelect($this->select, $platform, $driver, $parameterContainer);
|
2023-03-11 12:04:29 +03:00
|
|
|
|
2023-04-01 09:03:34 +03:00
|
|
|
$columns = array_map(array($platform, 'quoteIdentifier'), array_keys($this->columns));
|
2023-03-11 12:04:29 +03:00
|
|
|
$columns = implode(', ', $columns);
|
|
|
|
|
2023-04-01 09:03:34 +03:00
|
|
|
return sprintf(
|
|
|
|
$this->specifications[static::SPECIFICATION_SELECT],
|
|
|
|
$this->resolveTable($this->table, $platform, $driver, $parameterContainer),
|
|
|
|
$columns ? "($columns)" : "",
|
|
|
|
$selectSql
|
|
|
|
);
|
2023-03-11 12:04:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Overloading: variable setting
|
|
|
|
*
|
|
|
|
* Proxies to values, using VALUES_MERGE strategy
|
|
|
|
*
|
|
|
|
* @param string $name
|
|
|
|
* @param mixed $value
|
|
|
|
* @return Insert
|
|
|
|
*/
|
|
|
|
public function __set($name, $value)
|
|
|
|
{
|
2023-04-01 09:03:34 +03:00
|
|
|
$this->columns[$name] = $value;
|
2023-03-11 12:04:29 +03:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Overloading: variable unset
|
|
|
|
*
|
|
|
|
* Proxies to values and columns
|
|
|
|
*
|
|
|
|
* @param string $name
|
|
|
|
* @throws Exception\InvalidArgumentException
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function __unset($name)
|
|
|
|
{
|
2023-04-01 09:03:34 +03:00
|
|
|
if (!isset($this->columns[$name])) {
|
2023-03-11 12:04:29 +03:00
|
|
|
throw new Exception\InvalidArgumentException('The key ' . $name . ' was not found in this objects column list');
|
|
|
|
}
|
|
|
|
|
2023-04-01 09:03:34 +03:00
|
|
|
unset($this->columns[$name]);
|
2023-03-11 12:04:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Overloading: variable isset
|
|
|
|
*
|
|
|
|
* Proxies to columns; does a column of that name exist?
|
|
|
|
*
|
|
|
|
* @param string $name
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function __isset($name)
|
|
|
|
{
|
2023-04-01 09:03:34 +03:00
|
|
|
return isset($this->columns[$name]);
|
2023-03-11 12:04:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Overloading: variable retrieval
|
|
|
|
*
|
|
|
|
* Retrieves value by column name
|
|
|
|
*
|
|
|
|
* @param string $name
|
|
|
|
* @throws Exception\InvalidArgumentException
|
|
|
|
* @return mixed
|
|
|
|
*/
|
|
|
|
public function __get($name)
|
|
|
|
{
|
2023-04-01 09:03:34 +03:00
|
|
|
if (!isset($this->columns[$name])) {
|
2023-03-11 12:04:29 +03:00
|
|
|
throw new Exception\InvalidArgumentException('The key ' . $name . ' was not found in this objects column list');
|
|
|
|
}
|
2023-04-01 09:03:34 +03:00
|
|
|
return $this->columns[$name];
|
2023-03-11 12:04:29 +03:00
|
|
|
}
|
|
|
|
}
|