Subversion-Projekte lars-tiefland.prado

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
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 &copy; 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
?>