| 1 |
lars |
1 |
<?php
|
|
|
2 |
/**
|
|
|
3 |
* TDbSqlCriteria class file.
|
|
|
4 |
*
|
|
|
5 |
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
|
|
|
6 |
* @link http://www.pradosoft.com/
|
|
|
7 |
* @copyright Copyright © 2005-2008 PradoSoft
|
|
|
8 |
* @license http://www.pradosoft.com/license/
|
|
|
9 |
* @version $Id: TDbSqlCriteria.php 1835 2007-04-03 01:38:15Z wei $
|
|
|
10 |
* @package System.Data.DataGateway
|
|
|
11 |
*/
|
|
|
12 |
|
|
|
13 |
/**
|
|
|
14 |
* Search criteria for TDbDataGateway.
|
|
|
15 |
*
|
|
|
16 |
* Criteria object for data gateway finder methods. Usage:
|
|
|
17 |
* <code>
|
|
|
18 |
* $criteria = new TSqlCriteria();
|
|
|
19 |
* $criteria->Parameters[':name'] = 'admin';
|
|
|
20 |
* $criteria->Parameters[':pass'] = 'prado';
|
|
|
21 |
* $criteria->OrdersBy['level'] = 'desc';
|
|
|
22 |
* $criteria->OrdersBy['name'] = 'asc';
|
|
|
23 |
* $criteria->Limit = 10;
|
|
|
24 |
* $criteria->Offset = 20;
|
|
|
25 |
* </code>
|
|
|
26 |
*
|
|
|
27 |
* @author Wei Zhuo <weizho[at]gmail[dot]com>
|
|
|
28 |
* @version $Id: TDbSqlCriteria.php 1835 2007-04-03 01:38:15Z wei $
|
|
|
29 |
* @package System.Data.DataGateway
|
|
|
30 |
* @since 3.1
|
|
|
31 |
*/
|
|
|
32 |
class TSqlCriteria extends TComponent
|
|
|
33 |
{
|
|
|
34 |
private $_condition;
|
|
|
35 |
private $_parameters;
|
|
|
36 |
private $_ordersBy;
|
|
|
37 |
private $_limit;
|
|
|
38 |
private $_offset;
|
|
|
39 |
|
|
|
40 |
/**
|
|
|
41 |
* Creates a new criteria with given condition;
|
|
|
42 |
* @param string sql string after the WHERE stanza
|
|
|
43 |
* @param mixed named or indexed parameters, accepts as multiple arguments.
|
|
|
44 |
*/
|
|
|
45 |
public function __construct($condition=null, $parameters=array())
|
|
|
46 |
{
|
|
|
47 |
if(!is_array($parameters) && func_num_args() > 1)
|
|
|
48 |
$parameters = array_slice(func_get_args(),1);
|
|
|
49 |
$this->_parameters=new TAttributeCollection;
|
|
|
50 |
$this->_parameters->setCaseSensitive(true);
|
|
|
51 |
$this->_parameters->copyFrom((array)$parameters);
|
|
|
52 |
$this->_ordersBy=new TAttributeCollection;
|
|
|
53 |
$this->_ordersBy->setCaseSensitive(true);
|
|
|
54 |
|
|
|
55 |
$this->setCondition($condition);
|
|
|
56 |
}
|
|
|
57 |
|
|
|
58 |
/**
|
|
|
59 |
* @return string search conditions.
|
|
|
60 |
*/
|
|
|
61 |
public function getCondition()
|
|
|
62 |
{
|
|
|
63 |
return $this->_condition;
|
|
|
64 |
}
|
|
|
65 |
|
|
|
66 |
/**
|
|
|
67 |
* Sets the search conditions to be placed after the WHERE clause in the SQL.
|
|
|
68 |
* @param string search conditions.
|
|
|
69 |
*/
|
|
|
70 |
public function setCondition($value)
|
|
|
71 |
{
|
|
|
72 |
if(empty($value)) {
|
|
|
73 |
return;
|
|
|
74 |
}
|
|
|
75 |
|
|
|
76 |
// supporting the following SELECT-syntax:
|
|
|
77 |
// [ORDER BY {col_name | expr | position}
|
|
|
78 |
// [ASC | DESC], ...]
|
|
|
79 |
// [LIMIT {[offset,] row_count | row_count OFFSET offset}]
|
|
|
80 |
// See: http://dev.mysql.com/doc/refman/5.0/en/select.html
|
|
|
81 |
|
|
|
82 |
if(preg_match('/ORDER\s+BY\s+(.*?)(?=LIMIT)|ORDER\s+BY\s+(.*?)$/i', $value, $matches) > 0) {
|
|
|
83 |
// condition contains ORDER BY
|
|
|
84 |
$value = str_replace($matches[0], '', $value);
|
|
|
85 |
if(strlen($matches[1]) > 0) {
|
|
|
86 |
$this->setOrdersBy($matches[1]);
|
|
|
87 |
} else if(strlen($matches[2]) > 0) {
|
|
|
88 |
$this->setOrdersBy($matches[2]);
|
|
|
89 |
}
|
|
|
90 |
}
|
|
|
91 |
|
|
|
92 |
if(preg_match('/LIMIT\s+([\d\s,]+)/i', $value, $matches) > 0) {
|
|
|
93 |
// condition contains limit
|
|
|
94 |
$value = str_replace($matches[0], '', $value); // remove limit from query
|
|
|
95 |
if(strpos($matches[1], ',')) { // both offset and limit given
|
|
|
96 |
list($offset, $limit) = explode(',', $matches[1]);
|
|
|
97 |
$this->_limit = (int)$limit;
|
|
|
98 |
$this->_offset = (int)$offset;
|
|
|
99 |
} else { // only limit given
|
|
|
100 |
$this->_limit = (int)$matches[1];
|
|
|
101 |
}
|
|
|
102 |
}
|
|
|
103 |
|
|
|
104 |
if(preg_match('/OFFSET\s+(\d+)/i', $value, $matches) > 0) {
|
|
|
105 |
// condition contains offset
|
|
|
106 |
$value = str_replace($matches[0], '', $value); // remove offset from query
|
|
|
107 |
$this->_offset = (int)$matches[1]; // set offset in criteria
|
|
|
108 |
}
|
|
|
109 |
|
|
|
110 |
$this->_condition = trim($value);
|
|
|
111 |
}
|
|
|
112 |
|
|
|
113 |
/**
|
|
|
114 |
* @return TAttributeCollection list of named parameters and values.
|
|
|
115 |
*/
|
|
|
116 |
public function getParameters()
|
|
|
117 |
{
|
|
|
118 |
return $this->_parameters;
|
|
|
119 |
}
|
|
|
120 |
|
|
|
121 |
/**
|
|
|
122 |
* @param ArrayAccess named parameters.
|
|
|
123 |
*/
|
|
|
124 |
public function setParameters($value)
|
|
|
125 |
{
|
|
|
126 |
if(!(is_array($value) || $value instanceof ArrayAccess))
|
|
|
127 |
throw new TException('value must be array or ArrayAccess');
|
|
|
128 |
$this->_parameters->copyFrom($value);
|
|
|
129 |
}
|
|
|
130 |
|
|
|
131 |
/**
|
|
|
132 |
* @return boolean true if the parameter index are string base, false otherwise.
|
|
|
133 |
*/
|
|
|
134 |
public function getIsNamedParameters()
|
|
|
135 |
{
|
|
|
136 |
foreach($this->getParameters() as $k=>$v)
|
|
|
137 |
return is_string($k);
|
|
|
138 |
}
|
|
|
139 |
|
|
|
140 |
/**
|
|
|
141 |
* @return TAttributeCollection ordering clause.
|
|
|
142 |
*/
|
|
|
143 |
public function getOrdersBy()
|
|
|
144 |
{
|
|
|
145 |
return $this->_ordersBy;
|
|
|
146 |
}
|
|
|
147 |
|
|
|
148 |
/**
|
|
|
149 |
* @param mixed ordering clause.
|
|
|
150 |
*/
|
|
|
151 |
public function setOrdersBy($value)
|
|
|
152 |
{
|
|
|
153 |
if(is_array($value) || $value instanceof Traversable)
|
|
|
154 |
$this->_ordersBy->copyFrom($value);
|
|
|
155 |
else
|
|
|
156 |
{
|
|
|
157 |
$value=trim(preg_replace('/\s+/',' ',(string)$value));
|
|
|
158 |
$orderBys=array();
|
|
|
159 |
foreach(explode(',',$value) as $orderBy)
|
|
|
160 |
{
|
|
|
161 |
$vs=explode(' ',trim($orderBy));
|
|
|
162 |
$orderBys[$vs[0]]=isset($vs[1])?$vs[1]:'asc';
|
|
|
163 |
}
|
|
|
164 |
$this->_ordersBy->copyFrom($orderBys);
|
|
|
165 |
}
|
|
|
166 |
}
|
|
|
167 |
|
|
|
168 |
/**
|
|
|
169 |
* @return int maximum number of records to return.
|
|
|
170 |
*/
|
|
|
171 |
public function getLimit()
|
|
|
172 |
{
|
|
|
173 |
return $this->_limit;
|
|
|
174 |
}
|
|
|
175 |
|
|
|
176 |
/**
|
|
|
177 |
* @param int maximum number of records to return.
|
|
|
178 |
*/
|
|
|
179 |
public function setLimit($value)
|
|
|
180 |
{
|
|
|
181 |
$this->_limit=$value;
|
|
|
182 |
}
|
|
|
183 |
|
|
|
184 |
/**
|
|
|
185 |
* @return int record offset.
|
|
|
186 |
*/
|
|
|
187 |
public function getOffset()
|
|
|
188 |
{
|
|
|
189 |
return $this->_offset;
|
|
|
190 |
}
|
|
|
191 |
|
|
|
192 |
/**
|
|
|
193 |
* @param int record offset.
|
|
|
194 |
*/
|
|
|
195 |
public function setOffset($value)
|
|
|
196 |
{
|
|
|
197 |
$this->_offset=$value;
|
|
|
198 |
}
|
|
|
199 |
|
|
|
200 |
/**
|
|
|
201 |
* @return string string representation of the parameters. Useful for debugging.
|
|
|
202 |
*/
|
|
|
203 |
public function __toString()
|
|
|
204 |
{
|
|
|
205 |
$str = '';
|
|
|
206 |
if(strlen((string)$this->getCondition()) > 0)
|
|
|
207 |
$str .= '"'.(string)$this->getCondition().'"';
|
|
|
208 |
$params = array();
|
|
|
209 |
foreach($this->getParameters() as $k=>$v)
|
|
|
210 |
$params[] = "{$k} => ${v}";
|
|
|
211 |
if(count($params) > 0)
|
|
|
212 |
$str .= ', "'.implode(', ',$params).'"';
|
|
|
213 |
$orders = array();
|
|
|
214 |
foreach($this->getOrdersBy() as $k=>$v)
|
|
|
215 |
$orders[] = "{$k} => ${v}";
|
|
|
216 |
if(count($orders) > 0)
|
|
|
217 |
$str .= ', "'.implode(', ',$orders).'"';
|
|
|
218 |
if($this->_limit !==null)
|
|
|
219 |
$str .= ', '.$this->_limit;
|
|
|
220 |
if($this->_offset !== null)
|
|
|
221 |
$str .= ', '.$this->_offset;
|
|
|
222 |
return $str;
|
|
|
223 |
}
|
|
|
224 |
}
|
|
|
225 |
|
|
|
226 |
?>
|