forked from utopia-php/database
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathQuery.php
More file actions
179 lines (148 loc) · 4.11 KB
/
Query.php
File metadata and controls
179 lines (148 loc) · 4.11 KB
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
<?php
namespace Utopia\Database;
class Query
{
/**
* @var string
*/
protected $attribute = '';
/**
* @var string
*/
protected $operator = '';
/**
* @var (mixed)[]
*/
protected $values;
/**
* Construct.
*
* Construct a new query object
*
* @param string $attribute
* @param string $operator
* @param array $values
*/
public function __construct(string $attribute, string $operator, array $values)
{
$this->attribute = $attribute;
$this->operator = $operator;
$this->values = $values;
}
/**
* Get attribute
*
* @return string
*/
public function getAttribute(): string
{
return $this->attribute;
}
/**
* Get operator
*
* @return string
*/
public function getOperator(): string
{
return $this->operator;
}
/**
* Get operand
*
* @return mixed
*/
public function getValues()
{
return $this->values;
}
/**
* Get all query details as array
*
* @return array
*/
public function getQuery(): array
{
return [
'attribute' => $this->attribute,
'operator' => $this->operator,
'values' => $this->values,
];
}
/**
* Parse query filter
*
* @param string $filter
*
* @return Query
* */
public static function parse(string $filter): Query
{
// get index of open parentheses
$end = mb_strpos($filter, '(');
// count stanzas by only counting '.' that come before open parentheses
$stanzas = mb_substr_count(mb_substr($filter, 0, $end), ".") + 1;
// TODO@kodumbeats handle relations between collections, e.g. if($stanzas > 2)
switch ($stanzas) {
case 2:
// use limit param to ignore '.' in $expression
$input = explode('.', $filter, $stanzas);
$attribute = $input[0];
$expression = $input[1];
[$operator, $values] = self::parseExpression($expression);
break;
}
return new Query($attribute, $operator, $values);
}
/**
* Get attribute key-value from query expression
* $expression: string with format 'operator(value)'
*
* @param string $expression
*
* @return (string|array)[]
*/
protected static function parseExpression(string $expression): array
{
//find location of parentheses in expression
/** @var int */
$start = mb_strpos($expression, '(');
/** @var int */
$end = mb_strrpos($expression, ')');
//extract the query method
/** @var string */
$operator = mb_substr($expression, 0, $start);
//grab everything inside parentheses
/** @var mixed */
$value = mb_substr($expression,
($start + 1), /* exclude open paren*/
($end - $start - 1) /* exclude closed paren*/
);
// Explode comma-separated values
$values = explode(',', $value);
// Cast $value type
$values = array_map(function ($value) {
// Trim whitespace from around $value
$value = trim($value);
switch (true) {
// type casted to int or float by "+" operator
case is_numeric($value):
return $value + 0;
// since (bool)"false" returns true, check bools manually
case $value === 'true':
return true;
case $value === 'false':
return false;
// need special case to cast (null) as null, not string
case $value === 'null':
return null;
default:
// strip escape characters
$value = stripslashes($value);
// trim leading and tailing quotes
return trim($value, '\'"');
}
}, $values);
return [$operator, $values];
}
}