File: /www/exchange0old/exchange/Bin/Db/Builder.php
<?php
/**
* Created by PhpStorm.
* User: MisterX
* Date: 24.05.2016
* Time: 14:00
*/
class Bin_Db_Builder
{
const SELECT = 0;
const DELETE = 1;
const UPDATE = 2;
const INSERT = 3;
/*
* The builder states.
*/
const STATE_DIRTY = 0;
const STATE_CLEAN = 1;
/**
* @var array The array of SQL parts collected.
*/
private $sqlParts = array(
'select' => array(),
'from' => array(),
'join' => array(),
'set' => array(),
'where' => null,
'groupBy' => array(),
'having' => null,
'orderBy' => array(),
'values' => array(),
);
protected $connection;
/**
* The complete SQL string for this query.
*
* @var string
*/
private $sql;
/**
* The type of query this is. Can be select, update or delete.
*
* @var integer
*/
private $type = self::SELECT;
/**
* The state of the query object. Can be dirty or clean.
*
* @var integer
*/
private $state = self::STATE_CLEAN;
public function __construct(Bin_Db $connection)
{
$this->connection = $connection;
}
public function getSQL()
{
if ($this->sql !== null && $this->state === self::STATE_CLEAN) {
return $this->sql;
}
switch ($this->type) {
case self::INSERT:
$sql = $this->getSQLForInsert();
break;
// case self::DELETE:
// $sql = $this->getSQLForDelete();
// break;
// case self::UPDATE:
// $sql = $this->getSQLForUpdate();
// break;
// case self::SELECT:
// default:
// $sql = $this->getSQLForSelect();
// break;
}
$this->state = self::STATE_CLEAN;
$this->sql = $sql;
return $sql;
}
/**
* Either appends to or replaces a single, generic query part.
*
* The available parts are: 'select', 'from', 'set', 'where',
* 'groupBy', 'having' and 'orderBy'.
*
* @param string $sqlPartName
* @param string $sqlPart
* @param boolean $append
*
* @return self
*/
protected function add($sqlPartName, $sqlPart, $append = false)
{
$isArray = is_array($sqlPart);
$isMultiple = is_array($this->sqlParts[$sqlPartName]);
if ($isMultiple && !$isArray) {
$sqlPart = array($sqlPart);
}
$this->state = self::STATE_DIRTY;
if ($append) {
if ($sqlPartName == "orderBy" || $sqlPartName == "groupBy" || $sqlPartName == "select" || $sqlPartName == "set") {
foreach ($sqlPart as $part) {
$this->sqlParts[$sqlPartName][] = $part;
}
} elseif ($isArray && is_array($sqlPart[key($sqlPart)])) {
$key = key($sqlPart);
$this->sqlParts[$sqlPartName][$key][] = $sqlPart[$key];
} elseif ($isMultiple) {
$this->sqlParts[$sqlPartName][] = $sqlPart;
} else {
$this->sqlParts[$sqlPartName] = $sqlPart;
}
return $this;
}
$this->sqlParts[$sqlPartName] = $sqlPart;
return $this;
}
/**
* Turns the query being built into an insert query that inserts into
* a certain table
* @param string $table The table into which the rows should be inserted.
* @return $this
*/
public function insert($table = null)
{
$this->type = self::INSERT;
if ( ! $table) {
return $this;
}
return $this->add('from', array(
'table' => $table
));
}
/**
* Specifies values for an insert query indexed by column names.
* @param array $values The values to specify for the insert query indexed by column names.
* @return $this
*/
public function values(array $values)
{
return $this->add('values', $values);
}
/**
* Sets a value for a column in an insert query.
* @param string $column The column into which the value should be inserted.
* @param string $value The value that should be inserted into the column.
* @return $this
*/
public function setValue($column, $value)
{
$this->sqlParts['values'][$column] = $value;
return $this;
}
public function from($table, $alias = null)
{
return $this->add('from', array(
'table' => $table,
'alias' => $alias
), true);
}
/**
* Converts this instance into an INSERT string in SQL.
*
* @return string
*/
private function getSQLForInsert()
{
$table = $this->connection->escapeIdentifier($this->sqlParts['from']['table']);
$fields = array_map(array($this->connection,'escapeIdentifier'),array_keys($this->sqlParts['values']));
$values = array_map(array($this->connection,'escapeValue'),$this->sqlParts['values']);
return 'INSERT INTO ' . $table .' (' . implode(', ', $fields) . ') VALUES (' . implode(', ', $values) . ')';
}
public function execute() {
return $this->connection->query($this->getSQL());
}
}