Subversion-Projekte lars-tiefland.prado

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * TResultProperty 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: TResultProperty.php 2541 2008-10-21 15:05:13Z qiang.xue $
10
 * @package System.Data.SqlMap.Configuration
11
 */
12
 
13
/**
14
 * TResultProperty corresponds a <property> tags inside a <resultMap> tag.
15
 *
16
 * The {@link NullValue setNullValue()} attribute can be set to any valid
17
 * value (based on property type). The {@link NullValue setNullValue()} attribute
18
 * is used to specify an outgoing null value replacement. What this means is
19
 * that when a null value is detected in the result, the corresponding value of
20
 * the {@link NullValue getNullValue()} will be used instead.
21
 *
22
 * The {@link Select setSelect()} property is used to describe a relationship
23
 * between objects and to automatically load complex (i.e. user defined)
24
 * property types. The value of the {@link Select setSelect()} property must be
25
 * the name of another mapped statement. The value of the database
26
 * {@link Column setColumn()} that is defined in the same property element as
27
 * this statement attribute will be passed to the related mapped statement as
28
 * the parameter. The {@link LazyLoad setLayLoad()} attribute can be specified
29
 * with the {@link Select setSelect()} .
30
 *
31
 * @author Wei Zhuo <weizho[at]gmail[dot]com>
32
 * @version $Id: TResultProperty.php 2541 2008-10-21 15:05:13Z qiang.xue $
33
 * @package System.Data.SqlMap.Configuration
34
 * @since 3.1
35
 */
36
class TResultProperty extends TComponent
37
{
38
	private $_nullValue;
39
	private $_propertyName;
40
	private $_columnName;
41
	private $_columnIndex=-1;
42
	private $_nestedResultMapName;
43
	private $_nestedResultMap;
44
	private $_valueType;
45
	private $_typeHandler;
46
	private $_isLazyLoad=false;
47
	private $_select;
48
 
49
	private $_hostResultMapID='inplicit internal mapping';
50
 
51
	const LIST_TYPE = 0;
52
	const ARRAY_TYPE = 1;
53
 
54
	/**
55
	 * Gets the containing result map ID.
56
	 * @param TResultMap containing result map.
57
	 */
58
	public function __construct($resultMap=null)
59
	{
60
		if($resultMap instanceof TResultMap)
61
			$this->_hostResultMapID = $resultMap->getID();
62
	}
63
 
64
	/**
65
	 * @return mixed null value replacement.
66
	 */
67
	public function getNullValue()
68
	{
69
		return $this->_nullValue;
70
	}
71
 
72
	/**
73
	 * @param mixed null value replacement.
74
	 */
75
	public function setNullValue($value)
76
	{
77
		$this->_nullValue = $value;
78
	}
79
 
80
	/**
81
	 * @return string name of a property of the result object that will be set to.
82
	 */
83
	public function getProperty()
84
	{
85
		return $this->_propertyName;
86
	}
87
 
88
	/**
89
	 * @param string name of a property of the result object that will be set to.
90
	 */
91
	public function setProperty($value)
92
	{
93
		$this->_propertyName = $value;
94
	}
95
 
96
	/**
97
	 * @return string name of the column in the result set from which the value
98
	 * will be used to populate the property.
99
	 */
100
	public function getColumn()
101
	{
102
		return $this->_columnName;
103
	}
104
 
105
	/**
106
	 * @param string name of the column in the result set from which the value
107
	 * will be used to populate the property.
108
	 */
109
	public function setColumn($value)
110
	{
111
		$this->_columnName = $value;
112
	}
113
 
114
	/**
115
	 * @return int index of the column in the ResultSet from which the value will
116
	 * be used to populate the object property
117
	 */
118
	public function getColumnIndex()
119
	{
120
		return $this->_columnIndex;
121
	}
122
 
123
	/**
124
	 * @param int index of the column in the ResultSet from which the value will
125
	 * be used to populate the object property
126
	 */
127
	public function setColumnIndex($value)
128
	{
129
		$this->_columnIndex = TPropertyValue::ensureInteger($value);
130
	}
131
 
132
	/**
133
	 * @return string ID of another <resultMap> used to fill the property.
134
	 */
135
	public function getResultMapping()
136
	{
137
		return $this->_nestedResultMapName;
138
	}
139
 
140
	/**
141
	 * @parma string ID of another <resultMap> used to fill the property.
142
	 */
143
	public function setResultMapping($value)
144
	{
145
		$this->_nestedResultMapName = $value;
146
	}
147
 
148
	/**
149
	 * @return TResultMap nested result map.
150
	 */
151
	public function getNestedResultMap()
152
	{
153
		return $this->_nestedResultMap;
154
	}
155
 
156
	/**
157
	 * @param TResult nested result map.
158
	 */
159
	public function setNestedResultMap($value)
160
	{
161
		$this->_nestedResultMap = $value;
162
	}
163
 
164
	/**
165
	 * @return string property type of the object property to be set.
166
	 */
167
	public function getType()
168
	{
169
		return $this->_valueType;
170
	}
171
 
172
	/**
173
	 * @param string property type of the object property to be set.
174
	 */
175
	public function setType($value)
176
	{
177
		$this->_valueType = $value;
178
	}
179
 
180
	/**
181
	 * @return string custom type handler class name (may use namespace).
182
	 */
183
	public function getTypeHandler()
184
	{
185
		return $this->_typeHandler;
186
	}
187
 
188
	/**
189
	 * @param string custom type handler class name (may use namespace).
190
	 */
191
	public function setTypeHandler($value)
192
	{
193
		$this->_typeHandler = $value;
194
	}
195
 
196
	/**
197
	 * @return string name of another mapped statement
198
	 */
199
	public function getSelect()
200
	{
201
		return $this->_select;
202
	}
203
 
204
	/**
205
	 * The select property is used to describe a relationship between objects
206
	 * and to automatically load complex (i.e. user defined) property types.
207
	 * @param string name of another mapped statement.
208
	 */
209
	public function setSelect($value)
210
	{
211
		$this->_select = $value;
212
	}
213
 
214
	/**
215
	 * @return boolean indicate whether or not the select statement's results should be lazy loaded
216
	 */
217
	public function getLazyLoad()
218
	{
219
		return $this->_isLazyLoad;
220
	}
221
 
222
	/**
223
	 * @param boolean indicate whether or not the select statement's results should be lazy loaded
224
	 */
225
	public function setLazyLoad($value)
226
	{
227
		$this->_isLazyLoad = TPropertyValue::ensureBoolean($value,false);
228
	}
229
 
230
	/**
231
	 * Gets the value for the current property, converts to applicable type if necessary.
232
	 * @param TSqlMapTypeHandlerRegistry type handler registry
233
	 * @param array result row
234
	 * @return mixed property value.
235
	 */
236
	public function getPropertyValue($registry,$row)
237
	{
238
		$value = null;
239
		$index = $this->getColumnIndex();
240
		$name = $this->getColumn();
241
		if($index > 0 && isset($row[$index]))
242
			$value = $this->getTypedValue($registry,$row[$index]);
243
		else if(isset($row[$name]))
244
			$value = $this->getTypedValue($registry,$row[$name]);
245
		if(is_null($value) && !is_null($this->getNullValue()))
246
			$value = $this->getTypedValue($registry,$this->getNullValue());
247
		return $value;
248
	}
249
 
250
	/**
251
	 * @param TSqlMapTypeHandlerRegistry type handler registry
252
	 * @param mixed raw property value
253
	 * @return mixed property value casted to specific type.
254
	 */
255
	protected function getTypedValue($registry,$value)
256
	{
257
		if(($handler = $this->createTypeHandler($registry))!==null)
258
			return $handler->getResult($value);
259
		else
260
			return $registry->convertToType($this->getType(), $value);
261
	}
262
 
263
	/**
264
	 * Create type handler from {@link Type setType()} or {@link TypeHandler setTypeHandler}.
265
	 * @param TSqlMapTypeHandlerRegistry type handler registry
266
	 * @return TSqlMapTypeHandler type handler.
267
	 */
268
	protected function createTypeHandler($registry)
269
	{
270
		$type=$this->getTypeHandler() ? $this->getTypeHandler() : $this->getType();
271
		$handler=$registry->getTypeHandler($type);
272
		if($handler===null && $this->getTypeHandler())
273
			$handler = Prado::createComponent($type);
274
		return $handler;
275
	}
276
 
277
	/**
278
	 * Determines if the type is an instance of ArrayAccess, TList or an array.
279
	 * @return int TResultProperty::LIST_TYPE or TResultProperty::ARRAY_TYPE
280
	 */
281
	protected function getPropertyValueType()
282
	{
283
		if(class_exists($type = $this->getType(), false)) //NO force autoloading
284
		{
285
			if($type==='TList')
286
				return self::LIST_TYPE;
287
			$class = new ReflectionClass($type);
288
			if($class->isSubclassOf('TList'))
289
				return self::LIST_TYPE;
290
			if($class->implementsInterface('ArrayAccess'))
291
				return self::ARRAY_TYPE;
292
		}
293
		if(strtolower($type) == 'array')
294
			return self::ARRAY_TYPE;
295
	}
296
 
297
	/**
298
	 * Returns true if the result property {@link Type getType()} is of TList type
299
	 * or that the actual result object is an instance of TList.
300
	 * @param object result object
301
	 * @return boolean true if the result object is an instance of TList
302
	 */
303
	public function instanceOfListType($target)
304
	{
305
		if(is_null($this->getType()))
306
			return  TPropertyAccess::get($target,$this->getProperty()) instanceof TList;
307
		return $this->getPropertyValueType() == self::LIST_TYPE;
308
	}
309
 
310
	/**
311
	 * Returns true if the result property {@link Type getType()} is of ArrayAccess
312
	 * or that the actual result object is an array or implements ArrayAccess
313
	 * @param object result object
314
	 * @return boolean true if the result object is an instance of ArrayAccess or is an array.
315
	 */
316
	public function instanceOfArrayType($target)
317
	{
318
		if(is_null($this->getType()))
319
		{
320
			$prop = TPropertyAccess::get($target,$this->getProperty());
321
			if(is_object($prop))
322
				return $prop instanceof ArrayAccess;
323
			return is_array($prop);
324
		}
325
		return $this->getPropertyValueType() == self::ARRAY_TYPE;
326
	}
327
}
328