diff --git a/README.md b/README.md index b8e9085..60fc1b7 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/src/MySQL.php b/src/MySQL.php index c2da55c..a34bcdf 100644 --- a/src/MySQL.php +++ b/src/MySQL.php @@ -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 diff --git a/src/Operators.php b/src/Operators.php new file mode 100644 index 0000000..23f53dd --- /dev/null +++ b/src/Operators.php @@ -0,0 +1,46 @@ +"; + 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 = "^-="; + } \ No newline at end of file