_prepareBinaryExpression()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 7
c 1
b 0
f 0
dl 0
loc 12
ccs 0
cts 8
cp 0
rs 10
cc 2
nc 2
nop 3
crap 6
1
<?php
2
3
namespace POData\Providers\Expression;
4
5
6
use POData\UriProcessor\QueryProcessor\ExpressionParser\Expressions\ExpressionType;
7
use POData\Providers\Metadata\Type\IType;
8
use POData\Common\ODataConstants;
9
use POData\Providers\Expression\IExpressionProvider;
10
use POData\Providers\Metadata\ResourceType;
11
use POData\UriProcessor\QueryProcessor\ExpressionParser\Expressions\PropertyAccessExpression;
12
use POData\UriProcessor\QueryProcessor\FunctionDescription;
13
14
class MySQLExpressionProvider implements IExpressionProvider
15
{
16
    const ADD                   = '+';
17
    const CLOSE_BRACKET         = ')';
18
    const COMMA                 = ',';
19
    const DIVIDE                = '/';
20
    const SUBTRACT              = '-';
21
    const EQUAL                 = '=';
22
    const GREATER_THAN          = '>';
23
    const GREATER_THAN_OR_EQUAL = '>=';
24
    const LESS_THAN             = '<';
25
    const LESS_THAN_OR_EQUAL    = '<=';
26
    const LOGICAL_AND           = '&&';
27
    const LOGICAL_NOT           = '!';
28
    const LOGICAL_OR            = '||';
29
    const MEMBER_ACCESS         = '';
30
    const MODULO                = '%';
31
    const MULTIPLY              = '*';
32
    const NEGATE                = '-';
33
    const NOT_EQUAL             = '!=';
34
    const OPEN_BRACKET = '(';
35
    
36
    /**
37
     * The type of the resource pointed by the resource path segment
38
     *
39
     * @var ResourceType
40
     */
41
    private $resourceType;
42
43
    private $entityMapping;
44
45
    /**
46
     * Constructs new instance of MySQLExpressionProvider
47
     *    
48
     */
49
    public function __construct()
50
    {
51
        $this->entityMapping = array();
52
    }
53
54
55
    /**
56
     * Get the name of the iterator
57
     * 
58
     * @return string
59
     */
60
    public function getIteratorName()
61
    {
62
        return null;
63
    }
64
65
    /**
66
     * call-back for setting the resource type.
67
     *
68
     * @param ResourceType $resourceType The resource type on which the filter is going to be applied.
69
     *
70
     */
71
    public function setResourceType(ResourceType $resourceType)
72
    {
73
        $this->resourceType = $resourceType;
74
    }
75
76
    /**
77
     * Call-back for logical expression
78
     * 
79
     * @param ExpressionType $expressionType The type of logical expression.
80
     * @param string         $left           The left expression.
81
     * @param string         $right          The left expression.
82
     * 
83
     * @return string
84
     */
85
    public function onLogicalExpression($expressionType, $left, $right)
86
    {
87
        switch ($expressionType) {
88
            case ExpressionType::AND_LOGICAL:
89
                return $this->_prepareBinaryExpression(self::LOGICAL_AND, $left, $right);
90
91
            case ExpressionType::OR_LOGICAL:
92
                return $this->_prepareBinaryExpression(self::LOGICAL_OR, $left, $right);
93
94
            default:
95
                throw new \InvalidArgumentException('onLogicalExpression');
96
        }
97
    }
98
99
    /**
100
     * Call-back for arithmetic expression
101
     * 
102
     * @param ExpressionType $expressionType The type of arithmetic expression.
103
     * @param string         $left           The left expression.
104
     * @param string         $right          The left expression.
105
     * 
106
     * @return string
107
     */
108
    public function onArithmeticExpression($expressionType, $left, $right)
109
    {
110
        switch ($expressionType) {
111
            case ExpressionType::MULTIPLY:
112
                return $this->_prepareBinaryExpression(self::MULTIPLY, $left, $right);
113
114
            case ExpressionType::DIVIDE:
115
                return $this->_prepareBinaryExpression(self::DIVIDE, $left, $right);
116
117
            case ExpressionType::MODULO:
118
                return $this->_prepareBinaryExpression(self::MODULO, $left, $right);
119
120
            case ExpressionType::ADD:
121
                return $this->_prepareBinaryExpression(self::ADD, $left, $right);
122
123
            case ExpressionType::SUBTRACT:
124
                return $this->_prepareBinaryExpression(self::SUBTRACT, $left, $right);
125
126
            default:
127
                throw new \InvalidArgumentException('onArithmeticExpression');
128
        }
129
    }
130
131
    /**
132
     * Call-back for relational expression
133
     * 
134
     * @param ExpressionType $expressionType The type of relation expression
135
     * @param string         $left           The left expression
136
     * @param string         $right          The left expression
137
     * 
138
     * @return string
139
     */
140
    public function onRelationalExpression($expressionType, $left, $right)
141
    {
142
        switch ($expressionType) {
143
            case ExpressionType::GREATERTHAN:
144
                return $this->_prepareBinaryExpression(self::GREATER_THAN, $left, $right);
145
146
            case ExpressionType::GREATERTHAN_OR_EQUAL:
147
                return $this->_prepareBinaryExpression(self::GREATER_THAN_OR_EQUAL, $left, $right);
148
149
            case ExpressionType::LESSTHAN:
150
                return $this->_prepareBinaryExpression(self::LESS_THAN, $left, $right);
151
152
            case ExpressionType::LESSTHAN_OR_EQUAL:
153
                return $this->_prepareBinaryExpression(self::LESS_THAN_OR_EQUAL, $left, $right);
154
155
            case ExpressionType::EQUAL:
156
                return $this->_prepareBinaryExpression(self::EQUAL, $left, $right);
157
158
            case ExpressionType::NOTEQUAL:
159
                return $this->_prepareBinaryExpression(self::NOT_EQUAL, $left, $right);
160
161
            default:
162
                throw new \InvalidArgumentException('onArithmeticExpression');
163
        }
164
    }
165
166
    /**
167
     * Call-back for unary expression
168
     * 
169
     * @param ExpressionType $expressionType The type of unary expression
170
     * @param string         $child          The child expression
171
     * 
172
     * @return string
173
     */
174
    public function onUnaryExpression($expressionType, $child)
175
    {
176
        switch ($expressionType) {
177
            case ExpressionType::NEGATE:
178
                return $this->_prepareUnaryExpression(self::NEGATE, $child);
179
180
            case ExpressionType::NOT_LOGICAL:
181
                return $this->_prepareUnaryExpression(self::LOGICAL_NOT, $child);
182
183
            default:
184
                throw new \InvalidArgumentException('onUnaryExpression');
185
        }
186
    }
187
188
    /**
189
     * Call-back for constant expression
190
     * 
191
     * @param IType  $type  The type of constant
192
     * @param mixed $value The value of the constant
193
     * 
194
     * @return string
195
     */
196
    public function onConstantExpression(IType $type, $value)
197
    {
198
        if (is_bool($value)) {
199
            return var_export($value, true);
200
        } else if (is_null($value)) {
201
            return var_export(null, true);
202
        }
203
204
        return $value;
205
    }
206
207
    /**
208
     * Call-back for property access expression
209
     * 
210
     * @param PropertyAccessExpression $expression The property access expression
211
     * 
212
     * @return string
213
     */
214
215
    public function onPropertyAccessExpression($expression)
216
    {
217
        $parent = $expression;
218
        $variable = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $variable is dead and can be removed.
Loading history...
219
        $entityTypeName = $this->resourceType->getName();
220
        $propertyName = $parent->getResourceProperty()->getName();
221
        if (is_array($this->entityMapping)) {
0 ignored issues
show
introduced by
The condition is_array($this->entityMapping) is always true.
Loading history...
222
            if (array_key_exists($entityTypeName, $this->entityMapping)) {
223
                if (array_key_exists($propertyName, $this->entityMapping[$entityTypeName])) {
224
                    return $this->entityMapping[$entityTypeName][$propertyName];
225
                }
226
            }
227
        }
228
     
229
        return $propertyName;
230
    }
231
232
    /**
233
     * Call-back for function call expression
234
     * 
235
     * @param FunctionDescription $functionDescription Description of the function.
236
     * @param array<string>       $params              Paameters to the function.
237
     * 
238
     * @return string
239
     */
240
    public function onFunctionCallExpression($functionDescription, $params)
241
    {
242
        switch ($functionDescription->name) {
243
            case ODataConstants::STRFUN_COMPARE:
244
                return "STRCMP($params[0], $params[1])";
245
246
            case ODataConstants::STRFUN_ENDSWITH:
247
                return "(STRCMP($params[1],RIGHT($params[0],LENGTH($params[1]))) = 0)";
248
249
            case ODataConstants::STRFUN_INDEXOF:
250
                return "INSTR($params[0], $params[1]) - 1";
251
252
            case ODataConstants::STRFUN_REPLACE:
253
                return "REPLACE($params[0],$params[1],$params[2])";
254
255
            case ODataConstants::STRFUN_STARTSWITH:
256
                return "(STRCMP($params[1],LEFT($params[0],LENGTH($params[1]))) = 0)";
257
258
            case ODataConstants::STRFUN_TOLOWER:
259
                return "LOWER($params[0])";
260
261
            case ODataConstants::STRFUN_TOUPPER:
262
                return "UPPER($params[0])";
263
264
            case ODataConstants::STRFUN_TRIM:
265
                return "TRIM($params[0])";
266
267
            case ODataConstants::STRFUN_SUBSTRING:
268
                return count($params) == 3 ?
269
                    "SUBSTRING($params[0], $params[1] + 1, $params[2])" : "SUBSTRING($params[0], $params[1] + 1)";
270
271
            case ODataConstants::STRFUN_SUBSTRINGOF:
272
                return "(LOCATE($params[0], $params[1]) > 0)";
273
274
            case ODataConstants::STRFUN_CONCAT:
275
                return "CONCAT($params[0],$params[1])";
276
277
            case ODataConstants::STRFUN_LENGTH:
278
                return "LENGTH($params[0])";
279
280
            case ODataConstants::GUIDFUN_EQUAL:
281
                return "STRCMP($params[0], $params[1])";
282
283
            case ODataConstants::DATETIME_COMPARE:
284
                return "DATETIMECMP($params[0]; $params[1])";
285
286
            case ODataConstants::DATETIME_YEAR:
287
                return "EXTRACT(YEAR from " . $params[0] . ")";
288
289
            case ODataConstants::DATETIME_MONTH:
290
                return "EXTRACT(MONTH from " . $params[0] . ")";
291
292
            case ODataConstants::DATETIME_DAY:
293
                return "EXTRACT(DAY from " . $params[0] . ")";
294
295
            case ODataConstants::DATETIME_HOUR:
296
                return "EXTRACT(HOUR from " . $params[0] . ")";
297
298
            case ODataConstants::DATETIME_MINUTE:
299
                return "EXTRACT(MINUTE from " . $params[0] . ")";
300
301
            case ODataConstants::DATETIME_SECOND:
302
                return "EXTRACT(SECOND from " . $params[0] . ")";
303
304
            case ODataConstants::MATHFUN_ROUND:
305
                return "ROUND($params[0])";
306
307
            case ODataConstants::MATHFUN_CEILING:
308
                return "CEIL($params[0])";
309
310
            case ODataConstants::MATHFUN_FLOOR:
311
                return "FLOOR($params[0])";
312
313
            case ODataConstants::BINFUL_EQUAL:
314
                return "($params[0] = $params[1])";
315
316
            case 'is_null':
317
                return "is_null($params[0])";
318
319
            default:
320
                throw new \InvalidArgumentException('onFunctionCallExpression');
321
        }
322
    }
323
324
    /**
325
     * To format binary expression
326
     * 
327
     * @param string $operator The binary operator.
328
     * @param string $left     The left operand.
329
     * @param string $right    The right operand.
330
     * 
331
     * @return string
332
     */
333
    private function _prepareBinaryExpression($operator, $left, $right)
334
    {
335
        //DATETIMECMP
336
        if (!substr_compare($left, "DATETIMECMP", 0, 11)) {
337
            $str = explode(';', $left, 2);
338
            $str[0] = str_replace('DATETIMECMP', '', $str[0]);
339
            return self::OPEN_BRACKET
340
                . $str[0] . ' ' . $operator
341
                . ' ' . $str[1] . self::CLOSE_BRACKET;
342
        }
343
344
        return self::OPEN_BRACKET . $left . ' ' . $operator . ' ' . $right . self::CLOSE_BRACKET;
345
    }
346
347
    /**
348
     * To format unary expression
349
     * 
350
     * @param string $operator The unary operator.
351
     * @param string $child    The operand.
352
     * 
353
     * @return string
354
     */
355
    private function _prepareUnaryExpression($operator, $child)
356
    {
357
        return $operator . self::OPEN_BRACKET . $child . self::CLOSE_BRACKET;
358
    }
359
360
	public function clear() {}
361
}