Skip to content

Commit 86e1e66

Browse files
committed
Fixed support for comparing data types with or operator for fql syntax
1 parent d194fc3 commit 86e1e66

File tree

7 files changed

+56
-33
lines changed

7 files changed

+56
-33
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## [2.0.7]
4+
5+
- Fixed support for comparing data types with `IS` or `IS_NOT` operator for fql syntax
6+
37
## [2.0.6]
48

59
- Fiquela conditions support compare values between row fields

docs/file-query-language.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,13 @@ LEFT JOIN
297297
```sql
298298
logical_operator:
299299
AND | OR | XOR
300-
300+
301+
compare_type_value:
302+
BOOLEAN | TRUE | FALSE | NUMBER | INT | DOUBLE | STRING | NULL | ARRAY | OBJECT
303+
304+
value_type:
305+
string | float | int | array | null | bool
306+
301307
where_condition:
302308
expr OR expr
303309
| expr XOR expr
@@ -312,7 +318,7 @@ field_expr:
312318
comparison_operator: = | >= | > | <= | < | <> | != | !== | == | LIKE | NOT LIKE | IS | IS NOT | IN | NOT IN
313319

314320
value_expr:
315-
string | number | boolean | NULL | ARRAY | OBJECT | ENUM
321+
value_type | compare_type_value
316322

317323
[[WHERE | HAVING]
318324
where_condition

docs/fluent-api.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -254,22 +254,22 @@ Operators are enums that represent the comparison operators used in the conditio
254254
use FQL\Enum\Operator;
255255
```
256256

257-
| Operator | Description |
258-
|-------------------------|-------------|
259-
| `EQUAL` | `=` |
260-
| `EQUAL_STRICT` | `==` |
261-
| `NOT_EQUAL` | `!=` |
262-
| `NOT_EQUAL_STRICT` | `!==` |
263-
| `GREATER_THAN` | `>` |
264-
| `GREATER_THAN_OR_EQUAL` | `>=` |
265-
| `LESS_THAN` | `<` |
266-
| `LESS_THAN_OR_EQUAL` | `<=` |
267-
| `IN` | `IN` |
268-
| `NOT_IN` | `NOT IN` |
269-
| `LIKE` | `LIKE` |
270-
| `NOT_LIKE` | `NOT LIKE` |
271-
| `IS` | `IS` |
272-
| `NOT_IS` | `IS NOT` |
257+
| Enum constant | Operator | Description |
258+
|-------------------------|------------|-------------------------------------------------------------------------------------------------------------|
259+
| `EQUAL` | `=` | |
260+
| `EQUAL_STRICT` | `==` | |
261+
| `NOT_EQUAL` | `!=` | |
262+
| `NOT_EQUAL_STRICT` | `!==` | |
263+
| `GREATER_THAN` | `>` | |
264+
| `GREATER_THAN_OR_EQUAL` | `>=` | |
265+
| `LESS_THAN` | `<` | |
266+
| `LESS_THAN_OR_EQUAL` | `<=` | |
267+
| `IN` | `IN` | Compare if field is in array list. |
268+
| `NOT_IN` | `NOT IN` | Same as `IN` operator but with oposite result. |
269+
| `LIKE` | `LIKE` | Fully compatible `LIKE` in MYSQL databases. Supports `_` and `%`. |
270+
| `NOT_LIKE` | `NOT LIKE` | Same as `LIKE` operator but with oposite result. |
271+
| `IS` | `IS` | Supported types: `BOOLEAN`, `TRUE`, `FALSE`, `NUMBER`, `INT`, `DOUBLE`, `STRING`, `NULL`, `ARRAY`, `OBJECT` |
272+
| `NOT_IS` | `IS NOT` | Same as `IS` operator but with oposite result. |
273273

274274
**Example:**
275275

examples/data/products-array.json

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,29 @@
22
{
33
"id": 1,
44
"name": "Product A",
5-
"price": 100
5+
"price": 100,
6+
"code": "A1B2C3",
7+
"isAvailable": true
68
},
79
{
810
"id": 2,
911
"name": "Product B",
10-
"price": 200
12+
"price": 200,
13+
"code": "Z1B2C4",
14+
"isAvailable": false
1115
},
1216
{
1317
"id": 3,
1418
"name": "Product C",
15-
"price": 300
19+
"price": 300,
20+
"code": null,
21+
"isAvailable": true
1622
},
1723
{
1824
"id": 4,
1925
"name": "Product D",
20-
"price": 400
26+
"price": 400,
27+
"code": null,
28+
"isAvailable": false
2129
}
2230
]

src/Enum/Operator.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,12 @@ public function render(mixed $value, mixed $right): string
5858
return match ($this) {
5959
self::IN, self::NOT_IN => sprintf('%s %s (%s)', $value, $this->value, implode(', ', $right)),
6060
self::LIKE, self::NOT_LIKE => sprintf('%s %s "%s"', $value, $this->value, $right),
61-
default => sprintf('%s %s %s', $value, $this->value, is_string($right) ? "'$right'" : $right),
61+
default => sprintf(
62+
'%s %s %s',
63+
$value,
64+
$this->value,
65+
is_string($right) ? "'$right'" : ($right instanceof Type ? strtoupper($right->value) : $right)
66+
),
6267
};
6368
}
6469

src/Enum/Type.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
enum Type: string
88
{
99
case BOOLEAN = 'boolean';
10-
case TRUE = 'TRUE';
11-
case FALSE = 'FALSE';
10+
case TRUE = 'true';
11+
case FALSE = 'false';
1212

1313
case NUMBER = 'number';
1414
case INTEGER = 'int';
1515
case FLOAT = 'double';
1616

1717
case STRING = 'string';
18-
case NULL = 'NULL';
18+
case NULL = 'null';
1919

2020
case ARRAY = 'array';
2121
case OBJECT = 'object';
@@ -25,7 +25,7 @@ enum Type: string
2525
case RESOURCE = 'resource';
2626
case RESOURCE_CLOSED = 'resource (closed)';
2727

28-
case UNKNOWN = 'unknown type';
28+
case UNKNOWN = 'unknown';
2929

3030
public static function castValue(mixed $value, ?Type $type = null): mixed
3131
{
@@ -70,12 +70,12 @@ public static function match(mixed $value): self
7070
public static function matchByString(string $value): mixed
7171
{
7272
// Null
73-
if (in_array($value, ['null', self::NULL->value])) {
73+
if (in_array($value, ['null', 'NULL'])) {
7474
return null;
7575
}
7676

7777
// Boolean
78-
if (in_array($value, ['true', self::TRUE->value, 'false', self::FALSE->value], true)) {
78+
if (in_array($value, ['true', 'TRUE', 'false', 'FALSE'], true)) {
7979
return self::castValue(strtolower($value) === 'true' ? 1 : 0, self::BOOLEAN);
8080
}
8181

src/Sql/Sql.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -345,10 +345,10 @@ private function parseConditions(Interface\Query $query, string $context): void
345345
}
346346

347347
$operator = Enum\Operator::fromOrFail($operator);
348-
$value = Enum\Type::matchByString($this->nextToken());
349-
$value = $operator === Enum\Operator::IS
350-
? Enum\Type::match($value)
351-
: $value;
348+
$value = $this->nextToken();
349+
$value = $operator === Enum\Operator::IS || $operator === Enum\Operator::NOT_IS
350+
? Enum\Type::from(strtolower($value))
351+
: Enum\Type::matchByString($value);
352352
if ($firstIter && $context === Condition::WHERE && $logicalOperator === Enum\LogicalOperator::AND) {
353353
$query->where($field, $operator, $value);
354354
$firstIter = false;

0 commit comments

Comments
 (0)