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

<?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();
}