Browse Source

Refactoring SqlCriteria, SqlModel. Add SqlResultProvider.fetchField().

namespace
Alexander Demidov 11 years ago
parent
commit
dff9c0b2af
  1. 45
      model/SqlCriteria.php
  2. 49
      model/SqlDbDriver.php
  3. 75
      model/SqlModel.php
  4. 5
      model/SqlResultProvider.php

45
model/SqlCriteria.php

@ -17,12 +17,20 @@ class SqlCriteria
*/
private $model;
private $sql_expression;
private $sql_expression_params = array();
/**
* @param $model SqlModel
* @param $sql_expression string|null Sql expression with SELECT and FROM operators. If fetched, then SqlCriteria::select(), SqlCriteria::distinct() disabled for use.
* @param $sql_expression_params array additional params to be replaced in sql expression
*/
public function __construct($model)
public function __construct($model, $sql_expression = null, $sql_expression_params = array())
{
$this->model = $model;
$this->sql_expression = $sql_expression;
$this->sql_expression_params = $sql_expression_params;
}
/**
@ -30,22 +38,45 @@ class SqlCriteria
*/
public function find()
{
return $this->model->find($this->select, $this->distinct, $this->where, $this->order, $this->limit);
return $this->model->find($this->select, $this->distinct, $this->where, $this->order, $this->limit, null, null, $this->sql_expression, $this->sql_expression_params);
}
public function count()
{
return $this->model->find(new DbExpr('COUNT(*) as count'), '', $this->where, null, null, null, null, $this->sql_expression, $this->sql_expression_params)->fetchField('count');
}
/**
* @param $cond string Condition with "?" placeholder @ex 'field=?'
* @param $value string|array|DbExpr Value. Array transformed to DbExpr(implode(',' Array)) All elements in the array mast be integer
* @param $cond string|array Condition with "?" placeholder @ex 'field=?' or 'field=1' or array('field=?' => 1', 'field=1')
* @param $value string|array|DbExpr|null Value. Array transformed to DbExpr(implode(',' Array)) All elements in the array mast be integer
* @return SqlCriteria
* @desc Allow multiple calls
*/
public function where($cond, $value)
public function where($cond, $value = null)
{
$this->where[$cond] = $value;
if (is_null($value)) {
if (is_array($cond)) {
$this->where = $this->where + $cond;
} else {
$this->where[] = $cond;
}
} else {
$this->where[$cond] = $value;
}
return $this;
}
/**
* @param $field string
* @param $value array
* @return SqlCriteria
*/
public function whereIn($field, $value)
{
return $this->where($field . ' in ?', $value);
}
/**
* @param $field string Field @ex 'field'
* @param $order_desc bool Descendant sort direction
* @return SqlCriteria
@ -85,7 +116,7 @@ class SqlCriteria
}
/**
* @param $field string
* @param $field string|bool If true then distinct by *
* @return SqlCriteria
*/
public function distinct($field)

49
model/SqlDbDriver.php

@ -127,9 +127,9 @@ abstract class SqlDbDriver extends DbDriver
/**
* @param mixed $where
* @return string
* TODO: Если cond Это int и term Это тоже int - кидать Exception (иначе эта ошибка повлечет обновление всех записей в таблице
* @throws ErrorException
*/
protected function whereExpr($where)
public function whereExpr($where)
{
if (empty($where)) {
return $where;
@ -140,16 +140,61 @@ abstract class SqlDbDriver extends DbDriver
}
foreach ($where as $cond => &$term) {
if (is_int($cond)) {
if (is_int($term)) {
throw new ErrorException('Condition in where expression as integer. Dangerous. ' . $term);
}
if ($term instanceof DbExpr) {
$term = (string) $term;
}
} else {
if (is_array($term)) {
$term = new DbExpr('(' . implode(',', array_map(function($item){return intval($item);}, $term)) . ')');
}
$term = $this->quoteInto($cond, $term);
}
}
return implode(' AND ', $where);
}
/**
* @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();

75
model/SqlModel.php

@ -50,8 +50,8 @@ abstract class SqlModel extends Model
*/
public function update($data, $where)
{
if (is_int($where) || $where === (string) (int) $where) {
$where = $this->identify($this->key) . '=' . (int) $where;
if (is_int($where) || $where === (string)(int)$where) {
$where = $this->identify($this->key) . '=' . (int)$where;
}
return parent::update($data, $where);
}
@ -62,7 +62,7 @@ abstract class SqlModel extends Model
*/
public function delete($id)
{
$where = $this->identify($this->key) . '=' . (int) $id;
$where = $this->identify($this->key) . '=' . (int)$id;
return $this->db->delete($this->table(), $where);
}
@ -87,7 +87,7 @@ abstract class SqlModel extends Model
for ($i = 0; $i < count($params['sort']); $i++) {
$order = (isset($params['order'][$params['sort'][$i]]) && $params['order'][$params['sort'][$i]] == 'desc') ? 'DESC' : 'ASC';
if (in_array($params['sort'][$i], $sortable)) {
$order_list[] = $this->identify($params['sort'][$i]) . ' ' . $order;
$order_list[] = $this->identify($params['sort'][$i]) . ' ' . $order;
}
}
if ($order_list) {
@ -112,7 +112,7 @@ abstract class SqlModel extends Model
if ($table_prefix) {
$sql = $table_prefix . '.';
}
$sql .= $this->identify($params['qt']) . ' LIKE ' . $this->quote('%' . $params['q'] . '%');
$sql .= $this->identify($params['qt']) . ' LIKE ' . $this->quote('%' . $params['q'] . '%');
}
return $sql;
}
@ -189,48 +189,43 @@ abstract class SqlModel extends Model
return $result;
}
public function find($select, $distinct, $where, $order, $limit)
/**
* @param $select array
* @param $distinct string|bool
* @param $where array @ex array('field=?' => $value, 'field=1')
* @param $order array @ex array('sort' => array('field1', 'field2'), 'order' => array('field2' => 'desc'))
* @param $limit string @ex '30' or '30,30'
* @param $heaving TODO
* @param $group_by TODO
* @param $sql_expression null|string
* @param $sql_expression_params array
* @param $cache_key CacheKey|null
* @return SqlResultProvider
*/
public function find($select, $distinct, $where, $order, $limit, $heaving = null, $group_by = null, $sql_expression = null, $sql_expression_params = array(), $cache_key = null)
{
if (!$select) {
$select = array(new DbExpr('*'));
}
foreach ($select as $field => &$term) {
if (is_int($field)) {
if ($term instanceof DbExpr) {
$term = (string) $term;
} else {
$term = $this->db->quoteIdentifier($term);
}
} else {
$term = $this->db->quoteIdentifier($field) . ' as ' . $this->db->quoteIdentifier($term);
}
}
foreach ($where as $cond => &$term) {
if (is_array($term)) {
$term = new DbExpr('(' . implode(',', array_map(function($item){return intval($item);}, $term)) . ')');
}
$term = $this->db->quoteInto($cond, $term);
}
if ($distinct != '') {
$distinct = 'DISTINCT ' . $this->db->quoteIdentifier($distinct);
}
if ($limit != '') {
$limit = implode(',',array_map(function($item){return intval($item);},explode(',',$limit)));
}
$result_items = parent::fetchAll('SELECT ' . (($distinct) ? $distinct : implode(',', $select))
. ' FROM ' . $this->table()
. (($where) ? (' WHERE ' . implode(' AND ', $where)) : '')
. (($order) ? ($this->order($order, $order['sort'])) : '')
. (($limit) ? (' LIMIT ' . $limit) : ''));
$select = $this->db->selectExpr($select, $distinct);
$where = $this->db->whereExpr($where);
$order = isset($order['sort']) ? $this->order($order, $order['sort']) : false;
$limit = $this->db->limitExpr($limit);
$result_items = parent::fetchAll(
(($sql_expression) ? $sql_expression : ('SELECT ' . $select . ' FROM ' . $this->table()))
. (($where) ? (' WHERE ' . $where) : '')
. (($order) ? ($order) : '')
. (($limit) ? (' LIMIT ' . $limit) : ''),
$sql_expression_params,
$cache_key
);
return new SqlResultProvider($result_items);
}
/**
* @param $sql_expression null
* @param $sql_expression_params array
* @return SqlCriteria
*/
public function criteria()
public function criteria($sql_expression = null, $sql_expression_params = array())
{
return new SqlCriteria();
return new SqlCriteria($this, $sql_expression, $sql_expression_params);
}
}

5
model/SqlResultProvider.php

@ -64,6 +64,11 @@ class SqlResultProvider
return $this->result_items[$key];
}
public function fetchField($field)
{
return current($this->result_items)->{$field};
}
public function fetch()
{
return current($this->result_items);

Loading…
Cancel
Save