summaryrefslogtreecommitdiff
path: root/framework/Data/SqlMap/Configuration/TInlineParameterMapParser.php
blob: 56e29299614bbb4d79ca351f9fc8de280b204d5c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<?php
/**
 * TInlineParameterMapParser class file.
 *
 * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
 * @link https://github.com/pradosoft/prado
 * @copyright Copyright &copy; 2005-2016 The PRADO Group
 * @license https://github.com/pradosoft/prado/blob/master/COPYRIGHT
 * @package System.Data.SqlMap.Configuration
 */

/**
 * TInlineParameterMapParser class.
 *
 * The inline parameter map syntax lets you embed the property name,
 * the property type, the column type, and a null value replacement into a
 * parametrized SQL statement.
 *
 * @author Wei Zhuo <weizho[at]gmail[dot]com>
 * @package System.Data.SqlMap.Configuration
 * @since 3.1
 */
class TInlineParameterMapParser
{
	/**
	 * Regular expression for parsing inline parameter maps.
	 */
	const PARAMETER_TOKEN_REGEXP = '/#([^#]+)#/';

	/**
	 * Parse the sql text for inline parameters.
	 * @param string sql text
	 * @param array file and node details for exception message.
	 * @return array 'sql' and 'parameters' name value pairs.
	 */
	public function parse($sqlText, $scope)
	{
		$matches = array();
		$mappings = array();
		preg_match_all(self::PARAMETER_TOKEN_REGEXP, $sqlText, $matches);

		for($i = 0, $k=count($matches[1]); $i<$k; $i++)
		{
			$mappings[] = $this->parseMapping($matches[1][$i], $scope);
			$sqlText = str_replace($matches[0][$i], '?', $sqlText);
		}
		return array('sql'=>$sqlText, 'parameters'=>$mappings);
	}

	/**
	 * Parse inline parameter with syntax as
	 * #propertyName,type=string,dbype=Varchar,nullValue=N/A,handler=string#
	 * @param string parameter token
	 * @param array file and node details for exception message.
	 */
	protected function parseMapping($token, $scope)
	{
		$mapping = new TParameterProperty;
		$properties = explode(',', $token);
		$mapping->setProperty(trim(array_shift($properties)));
		foreach($properties as $property)
		{
			$prop = explode('=',$property);
			$name = trim($prop[0]); $value=trim($prop[1]);
			if($mapping->canSetProperty($name))
				$mapping->{'set'.$name}($value);
			else
			{
				throw new TSqlMapUndefinedException(
						'sqlmap_undefined_property_inline_map',
						$name, $scope['file'], $scope['node'], $token);
			}
		}
		return $mapping;
	}
}