DAOUQueries::uAggregate()   B
last analyzed

Complexity

Conditions 8
Paths 16

Size

Total Lines 30
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 0
Metric Value
eloc 20
c 0
b 0
f 0
dl 0
loc 30
ccs 0
cts 20
cp 0
rs 8.4444
cc 8
nc 16
nop 7
crap 72
1
<?php
2
3
namespace Ubiquity\orm\traits;
4
5
use Ubiquity\orm\OrmUtils;
6
use Ubiquity\orm\parser\ConditionParser;
7
use Ubiquity\db\Database;
8
use Ubiquity\db\SqlUtils;
9
10
/**
11
 * Ubiquity\orm\traits$DAOUQueries
12
 * This class is part of Ubiquity
13
 *
14
 * @author jc
15
 * @version 1.0.3
16
 *
17
 */
18
trait DAOUQueries {
19
	protected static $annotFieldsInRelations = [];
20
21
	abstract protected static function _getAll(Database $db, $className, ConditionParser $conditionParser, $included = true, $useCache = null);
22
23
	abstract protected static function _getOne(Database $db, $className, ConditionParser $conditionParser, $included, $useCache);
24
25 11
	protected static function uParse($db, $className, &$ucondition, $quote, &$fields = null) {
26 11
		$expressions = self::uGetExpressions($ucondition);
27 11
		$condition = "";
28 11
		$aliases = [];
29 11
		foreach ($expressions as $expression) {
30 4
			$expressionArray = \explode(".", $expression);
31 4
			self::uParseExpression($db, $className, $expression, $expressionArray, $condition, $ucondition, $aliases, $quote, $fields);
32
		}
33 11
		return $condition;
34
	}
35
36 4
	protected static function uParseExpression($db, $className, $expression, &$expressionArray, &$condition, &$ucondition, &$aliases, $quote, &$fields = null) {
37 4
		$relations = self::getAnnotFieldsInRelations($className);
38 4
		$field = \array_shift($expressionArray);
39 4
		if (isset ($relations [$field])) {
40 4
			$jSQL = OrmUtils::getUJoinSQL($db, $className, $relations [$field], $field, $aliases, $quote);
41 4
			$condition .= ' ' . $jSQL ['sql'];
42 4
			if (\count($expressionArray) === 1) {
43 4
				$ucondition = \preg_replace('/(^|\s|\()' . $expression . '/', "\$1{$jSQL['alias']}." . $expressionArray [0], $ucondition);
44 4
				$fields[$expression] = $jSQL['alias'] . '.' . $expressionArray[0];
45
			} else {
46
				self::uParseExpression($db, $jSQL ['class'], $expression, $expressionArray, $condition, $ucondition, $aliases, $quote, $fields);
47
			}
48
		}
49
	}
50
51 4
	protected static function getAnnotFieldsInRelations($className) {
52 4
		if (!isset (self::$annotFieldsInRelations [$className])) {
53 1
			return self::$annotFieldsInRelations [$className] = OrmUtils::getAnnotFieldsInRelations($className);
54
		}
55 3
		return self::$annotFieldsInRelations [$className];
56
	}
57
58 11
	protected static function uGetExpressions($condition) {
59 11
		$condition = \preg_replace('@(["\']([^"\']|""|\'\')*["\'])@', "%values%", $condition);
60 11
		\preg_match_all('@[a-zA-Z_$][a-zA-Z_$0-9]*(?:\.[a-zA-Z_$\*][a-zA-Z_$0-9\*]*)+@', $condition, $matches);
61 11
		if (\count($matches) > 0) {
62 11
			return \array_unique($matches [0]);
63
		}
64
		return [];
65
	}
66
67
	/**
68
	 * Returns an array of $className objects from the database
69
	 *
70
	 * @param string $className class name of the model to load
71
	 * @param string $ucondition UQL condition
72
	 * @param boolean|array $included if true, loads associated members with associations, if array, example : ["client.*","commands"]
73
	 * @param array|null $parameters the request parameters
74
	 * @param boolean $useCache use the active cache if true
75
	 * @return array
76
	 */
77 8
	public static function uGetAll($className, $ucondition = '', $included = true, $parameters = null, $useCache = null) {
78 8
		$db = self::getDb($className);
79 8
		$firstPart = self::uParse($db, $className, $ucondition, $db->quote);
80 8
		return self::_getAll($db, $className, new ConditionParser ($ucondition, $firstPart, $parameters), $included, $useCache);
81
	}
82
83
	/**
84
	 * Returns the number of objects of $className from the database respecting the condition possibly passed as parameter
85
	 *
86
	 * @param string $className complete classname of the model to load
87
	 * @param string $ucondition Part following the WHERE of an SQL statement
88
	 * @param array|null $parameters The query parameters
89
	 * @return int|boolean count of objects
90
	 */
91 2
	public static function uCount($className, $ucondition = '', $parameters = null) {
92 2
		$db = self::getDb($className);
93 2
		$quote = $db->quote;
94 2
		$condition = self::uParse($db, $className, $ucondition, $quote);
95 2
		$tableName = OrmUtils::getTableName($className);
96 2
		if ($ucondition != '') {
97 2
			$ucondition = SqlUtils::checkWhere($ucondition);
98
		}
99 2
		return $db->prepareAndFetchColumn("SELECT COUNT(*) FROM {$quote}{$tableName}{$quote} " . $condition . $ucondition, $parameters, 0);
100
	}
101
102
	
103
	/**
104
	 * @param string $className
105
	 * @param string $ucondition
106
	 * @param array|null $parameters
107
	 * @param array|null $groupBy
108
	 * @param string $function
109
	 * @param string $field
110
	 * @param bool $distinct
111
	 * @return array
112
	 */
113
	public static function uAggregate(string $className, string $ucondition = '', ?array $parameters = null, ?array $groupBy = null, string $function = 'COUNT', string $field = '*', bool $distinct = false): array {
114
		$db = self::getDb($className);
115
		$quote = $db->quote;
116
117
		if (\is_array($groupBy)) {
118
			$ucondition .= ' GROUP BY ' . \implode(', ', $groupBy);
119
		}
120
		$fieldsMap = [];
121
		$firstPart = self::uParse($db, $className, $ucondition, $quote, $fieldsMap);
122
123
		$field = $fieldsMap[$field] ?? $field;
124
		if ($distinct) {
125
			$field = 'DISTINCT ' . $field;
126
		}
127
		$fieldsInSelect = $function . "($field) AS result";
128
129
		if (\is_array($groupBy)) {
130
			foreach ($groupBy as $index => $field) {
131
				if (\is_int($index)) {
132
					$fieldsInSelect .= ',' . ($fieldsMap[$field] ?? $field);
133
				} else {
134
					$fieldsInSelect .= ',' . ($fieldsMap[$field] ?? $field) . " AS {$quote}{$index}{$quote}";
135
				}
136
			}
137
		}
138
		$tableName = OrmUtils::getTableName($className);
139
		if ($ucondition != '' && !\str_starts_with($ucondition, ' GROUP BY')) {
140
			$ucondition = SqlUtils::checkWhere($ucondition);
141
		}
142
		return $db->prepareAndFetchAll("SELECT {$fieldsInSelect} FROM {$quote}{$tableName}{$quote} " . $firstPart . $ucondition, $parameters, 0);
143
	}
144
145
	/**
146
	 * @param string $className
147
	 * @param string $ucondition
148
	 * @param array|null $parameters
149
	 * @param array|null $groupBy
150
	 * @param string $countField
151
	 * @param bool $distinct
152
	 * @return array
153
	 */
154
	public static function uCountGroupBy(string $className, string $ucondition = '', ?array $parameters = null, ?array $groupBy = null, string $countField = '*', bool $distinct = false): array {
155
		return self::uAggregate($className, $ucondition, $parameters, $groupBy, 'COUNT', $countField, $distinct);
156
	}
157
158
	/**
159
	 * @param string $className
160
	 * @param string $avgField
161
	 * @param string $ucondition
162
	 * @param array|null $parameters
163
	 * @param array|null $groupBy
164
	 * @return array
165
	 */
166
	public static function uAvgGroupBy(string $className, string $avgField, string $ucondition = '', ?array $parameters = null, ?array $groupBy = null) {
167
		return self::uAggregate($className, $ucondition, $parameters, $groupBy, 'AVG', $avgField, false);
168
	}
169
170
	/**
171
	 * @param string $className
172
	 * @param string $sumField
173
	 * @param string $ucondition
174
	 * @param array|null $parameters
175
	 * @param array|null $groupBy
176
	 * @return array
177
	 */
178
	public static function uSumGroupBy(string $className, string $sumField, string $ucondition = '', ?array $parameters = null, ?array $groupBy = null) {
179
		return self::uAggregate($className, $ucondition, $parameters, $groupBy, 'SUM', $sumField, false);
180
	}
181
182
	/**
183
	 * @param string $className
184
	 * @param string $minField
185
	 * @param string $ucondition
186
	 * @param array|null $parameters
187
	 * @param array|null $groupBy
188
	 * @return array
189
	 */
190
	public static function uMinGroupBy(string $className, string $minField, string $ucondition = '', ?array $parameters = null, ?array $groupBy = null) {
191
		return self::uAggregate($className, $ucondition, $parameters, $groupBy, 'MIN', $minField, false);
192
	}
193
194
	/**
195
	 * @param string $className
196
	 * @param string $maxField
197
	 * @param string $ucondition
198
	 * @param array|null $parameters
199
	 * @param array|null $groupBy
200
	 * @return array
201
	 */
202
	public static function uMaxGroupBy(string $className, string $maxField, string $ucondition = '', ?array $parameters = null, ?array $groupBy = null) {
203
		return self::uAggregate($className, $ucondition, $parameters, $groupBy, 'MAX', $maxField, false);
204
	}
205
206
	/**
207
	 * Returns an instance of $className from the database, from $keyvalues values of the primary key
208
	 *
209
	 * @param String $className complete classname of the model to load
210
	 * @param Array|string $ucondition primary key values or condition (UQL)
211
	 * @param boolean|array $included if true, charges associated members with association
212
	 * @param array|null $parameters the request parameters
213
	 * @param boolean $useCache use cache if true
214
	 * @return object the instance loaded or null if not found
215
	 */
216 1
	public static function uGetOne($className, $ucondition, $included = true, $parameters = null, $useCache = null) {
217 1
		$db = self::getDb($className);
218 1
		$condition = self::uParse($db, $className, $ucondition, $db->quote);
219 1
		$conditionParser = new ConditionParser ($ucondition, $condition);
220 1
		if (\is_array($parameters)) {
221 1
			$conditionParser->setParams($parameters);
222
		}
223 1
		return self::_getOne($db, $className, $conditionParser, $included, $useCache);
224
	}
225
}
226
227