feat: define custom MySQL WHERE operators (#38)

* feat: add MySQL operators enum

* feat(doc): add custom operators to README
This commit is contained in:
Victor Westerlund 2024-04-16 14:31:38 +00:00 committed by GitHub
parent 51d62e1763
commit a26db46aae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 100 additions and 16 deletions

View file

@ -210,6 +210,8 @@ In most cases you probably want to UPDATE against a constaint. Chain a [`where()
Filter a [`MySQL->select()`](#select) or [`MySQL->update()`](#update) method by chaining the `MySQL->where()` method anywhere before it. The [`MySQL->delete()`](#delete) executor method also uses the same syntax for its arguments.
Each key, value pair will be `AND` constrained against each other.
```php
MySQL->where(
?array ...$conditions
@ -233,9 +235,7 @@ $coffee = MySQL->for("beverages")->where(["beverage_type" => "coffee"])->select(
]
```
## Advanced filtering
You can do more detailed filtering by passing more constraints into the same array, or even futher by passing multiple arrays each with filters.
## Capture groups
### AND
@ -272,6 +272,25 @@ MySQL->where($filter1, $filter2, ...);
WHERE (beverage_type = 'coffee' AND beverage_size = 15) OR (beverage_type = 'tea' AND beverage_name = 'black')
```
## Define custom operators
By default, all values in an the assoc array passed to `where()` will be treated as an `EQUALS` (=) operator.
```php
MySQL->where(["column" => "euqals_this_value"]);
```
Setting the value of any key to another assoc array will allow for more "advanced" filtering by defining your own [`Operators`](https://github.com/VictorWesterlund/php-libmysqldriver/blob/master/src/Operators.php).
The key of this subarray can be any MySQL operator string, or the **->value** of any case in the [`Operators`](https://github.com/VictorWesterlund/php-libmysqldriver/blob/master/src/Operators.php) enum.
```php
MySQL->where([
"beverage_name" => [
Operators::LIKE->value => "%wildcard_contains%"
]
]);
```
# ORDER BY

View file

@ -2,11 +2,15 @@
namespace libmysqldriver;
use \Exception;
use Exception;
use \mysqli;
use \mysqli_stmt;
use \mysqli_result;
use mysqli;
use mysqli_stmt;
use mysqli_result;
use libmysqldriver\Operators;
require_once "Operators.php";
// Interface for MySQL_Driver with abstractions for data manipulation
class MySQL extends mysqli {
@ -121,21 +125,36 @@
}
// Create SQL string and append values to array for prepared statement
foreach ($condition as $col => $value) {
foreach ($condition as $col => $operation) {
if ($this->model && !$this->in_model($col)) {
continue;
}
// Value is null so it does not need to be added to the prepared statement
if (is_null($value)) {
$filter[] = "`{$col}` IS NULL";
continue;
// Assume we want an equals comparison if value is not an array
if (!is_array($operation)) {
$operation = [Operators::EQUALS->value => $operation];
}
// Create SQL for prepared statement
$filter[] = "`{$col}` = ?";
// Append value to array with all other values
$values[] = $value;
// Resolve all operator enum values in inner array
foreach ($operation as $operator => $value) {
// Null values have special syntax
if (is_null($value)) {
// Treat anything that isn't an equals operator as falsy
if ($operator !== Operators::EQUALS->value) {
$filter[] = "`{$col}` IS NOT NULL";
continue;
}
$filter[] = "`{$col}` IS NULL";
continue;
}
// Create SQL for prepared statement
$filter[] = "`{$col}` {$operator} ?";
// Append value to array with all other values
$values[] = $value;
}
}
// AND together all conditions into a group

46
src/Operators.php Normal file
View file

@ -0,0 +1,46 @@
<?php
namespace libmysqldriver;
enum Operators: string {
// Logical
case ALL = "ALL";
case AND = "AND";
case ANY = "ANY";
case BETWEEN = "BETWEEN";
case EXISTS = "EXISTS";
case IN = "IN";
case LIKE = "LIKE";
case NOT = "NOT";
case OR = "OR";
case SOME = "SOME";
// Comparison
case EQUALS = "=";
case GT = ">";
case LT = "<";
case GTE = ">=";
case LTE = "<=";
case NOTE = "<>";
// Arithmetic
case ADD = "+";
case SUBTRACT = "-";
case MULTIPLY = "*";
case DIVIDE = "/";
case MODULO = "%";
// Bitwise
case BS_AND = "&";
case BS_OR = "|";
case BS_XOR = "^";
// Compound
case ADDE = "+=";
case SUBE = "-=";
case DIVE = "/=";
case MODE = "%=";
case BS_ANDE = "&=";
case BS_ORE = "|*=";
case BS_XORE = "^-=";
}