You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
236 lines
6.3 KiB
236 lines
6.3 KiB
<?php namespace Majestic\Model;
|
|
/**
|
|
* @copyright NetMonsters <team@netmonsters.ru>
|
|
* @link http://netmonsters.ru
|
|
* @package Majestic
|
|
* @subpackage db
|
|
* @since 2011-11-11
|
|
*/
|
|
|
|
abstract class SqlDbDriver extends DbDriver
|
|
{
|
|
|
|
protected $identifier_quote = '`';
|
|
|
|
|
|
|
|
public function beginTransaction()
|
|
{
|
|
$this->connect();
|
|
$this->driverBeginTransaction();
|
|
return $this;
|
|
}
|
|
|
|
public function commit()
|
|
{
|
|
$this->connect();
|
|
$this->driverCommitTransaction();
|
|
return $this;
|
|
}
|
|
|
|
public function rollback()
|
|
{
|
|
$this->connect();
|
|
$this->driverRollbackTransaction();
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param string $table
|
|
* @param mixed $data
|
|
* @param mixed $on_duplicate
|
|
* @return int Affected rows count
|
|
*/
|
|
public function insert($table, $data, $on_duplicate = array())
|
|
{
|
|
$columns = array();
|
|
foreach ($data as $col => $val) {
|
|
$columns[] = $this->quoteIdentifier($col);
|
|
}
|
|
$values = array_values($data);
|
|
|
|
$sql = 'INSERT INTO ' . $this->quoteIdentifier($table)
|
|
. ' (' . implode(', ', $columns) . ') VALUES (' . $this->quote($values) . ')';
|
|
return $this->query($sql)->affectedRows();
|
|
}
|
|
|
|
/**
|
|
* @param string $table
|
|
* @param array $data
|
|
* @param mixed $condition
|
|
* @return int Number of updated rows
|
|
*/
|
|
public function update($table, $data, $condition = '')
|
|
{
|
|
$set = array();
|
|
foreach ($data as $col => $val) {
|
|
$set[] = $this->quoteIdentifier($col) . '=' . $this->quote($val);
|
|
}
|
|
$where = $this->whereExpr($condition);
|
|
$sql = 'UPDATE ' . $this->quoteIdentifier($table) . ' SET ' . implode(', ', $set)
|
|
. (($where) ? (' WHERE ' . $where) : '');
|
|
return $this->query($sql)->affectedRows();
|
|
}
|
|
|
|
/**
|
|
* @param string $table
|
|
* @param mixed $condition
|
|
* @return int
|
|
*/
|
|
public function delete($table, $condition = '')
|
|
{
|
|
$where = $this->whereExpr($condition);
|
|
$sql = 'DELETE FROM ' . $this->quoteIdentifier($table) . (($where) ? (' WHERE ' . $where) : '');
|
|
return $this->query($sql)->affectedRows();
|
|
}
|
|
|
|
/**
|
|
* @param mixed $value
|
|
* @return string
|
|
*/
|
|
public function quote($value)
|
|
{
|
|
if ($value instanceof DbExpr) {
|
|
return (string) $value;
|
|
}
|
|
if (is_array($value)) {
|
|
foreach ($value as &$val) {
|
|
$val = $this->quote($val);
|
|
}
|
|
return implode(', ', $value);
|
|
}
|
|
return $this->driverQuote($value);
|
|
}
|
|
|
|
/**
|
|
* @param string $ident
|
|
* @return string
|
|
*/
|
|
public function quoteIdentifier($ident)
|
|
{
|
|
$ident = explode('.', $ident);
|
|
foreach ($ident as &$segment) {
|
|
if (!preg_match('/^(\?|:[A-z][A-z0-9_]*+|\*)$/u', $segment)) {
|
|
$segment = $this->identifier_quote . $segment . $this->identifier_quote;
|
|
}
|
|
}
|
|
return implode('.', $ident);
|
|
}
|
|
|
|
public function quoteInto($text, $value)
|
|
{
|
|
$pos = mb_strpos($text, '?');
|
|
if ($pos === false) {
|
|
return $text;
|
|
}
|
|
return mb_substr($text, 0, $pos) . $this->quote($value) . mb_substr($text, $pos + 1);
|
|
}
|
|
|
|
/**
|
|
* @param mixed $where
|
|
* @return string
|
|
* @throws \ErrorException
|
|
*/
|
|
public function whereExpr($where)
|
|
{
|
|
if (empty($where)) {
|
|
return $where;
|
|
}
|
|
|
|
if (!is_array($where)) {
|
|
$where = array($where);
|
|
}
|
|
foreach ($where as $cond => &$term) {
|
|
if (is_int($cond)) {
|
|
if (is_int($term)) {
|
|
throw new \ErrorException('Condition in where expression as integer. ' . $term);
|
|
}
|
|
if ($term instanceof DbExpr) {
|
|
$term = (string) $term;
|
|
}
|
|
} else {
|
|
if (is_array($term)) {
|
|
foreach ($term as &$val) {
|
|
$val = $this->driverQuote($val);
|
|
}
|
|
$term = new DbExpr('(' . implode(',', $term) . ')');
|
|
}
|
|
$term = $this->quoteInto($cond, $term);
|
|
}
|
|
}
|
|
return implode(' AND ', $where);
|
|
}
|
|
|
|
/**
|
|
* @param mixed $group_by
|
|
* @return string
|
|
* @throws \ErrorException
|
|
*/
|
|
public function groupByExpr($group_by)
|
|
{
|
|
if (empty($group_by)) {
|
|
return $group_by;
|
|
}
|
|
|
|
if (!is_array($group_by)) {
|
|
$group_by = array($group_by);
|
|
}
|
|
foreach ($group_by as &$term) {
|
|
if ($term instanceof DbExpr) {
|
|
$term = (string) $term;
|
|
} else {
|
|
$term = $this->quoteIdentifier($term);
|
|
}
|
|
}
|
|
return implode(',', $group_by);
|
|
}
|
|
|
|
/**
|
|
* @param $select array
|
|
* @param $distinct string|bool
|
|
* @return string
|
|
*/
|
|
public function selectExpr($select, $distinct = false)
|
|
{
|
|
if (empty($distinct) && empty($select)) {
|
|
return '*';
|
|
}
|
|
if (!is_array($select)) {
|
|
$select = array($select);
|
|
}
|
|
if ($distinct) {
|
|
$distinct = ((is_bool($distinct)) ? '*' : $this->quoteIdentifier($distinct));
|
|
array_unshift($select, new DbExpr('DISTINCT ' . $distinct));
|
|
}
|
|
foreach ($select as $field => &$term) {
|
|
if (is_int($field)) {
|
|
if ($term instanceof DbExpr) {
|
|
$term = (string) $term;
|
|
} else {
|
|
$term = $this->quoteIdentifier($term);
|
|
}
|
|
} else {
|
|
$term = $this->quoteIdentifier($field) . ' as ' . $this->quoteIdentifier($term);
|
|
}
|
|
}
|
|
return implode(',', $select);
|
|
}
|
|
|
|
public function limitExpr($limit)
|
|
{
|
|
if (empty($limit)) {
|
|
return $limit;
|
|
}
|
|
return implode(',',array_map(function($item){return intval($item);},explode(',',$limit)));
|
|
}
|
|
|
|
abstract protected function driverQuote($value);
|
|
|
|
abstract protected function driverBeginTransaction();
|
|
|
|
abstract protected function driverCommitTransaction();
|
|
|
|
abstract protected function driverRollbackTransaction();
|
|
|
|
}
|
|
|