diff --git a/class/ExpressionBuilder.php b/class/ExpressionBuilder.php index cfedfec..47ab51d 100644 --- a/class/ExpressionBuilder.php +++ b/class/ExpressionBuilder.php @@ -1,5 +1,14 @@ fieldName = $fieldName; + } +} + class ExpressionBuilder { // Automatic typecast. @@ -11,13 +20,15 @@ class ExpressionBuilder } else { // is it a float? return (double)$rval; } - } else { // it's a string + } else if (str_starts_with($rval, '"') && str_ends_with($rval, '"')){ // it's a string return substr($rval, 1, strlen($rval) - 2); // strip leading and trailing quotes + } else { // it must be a column name + return new FieldName($rval); } } // Divide expression into operands and operators. - static function splitCriterion(string $crstr): array + static function splitCriterion(string $crstr): array|Closure { preg_match("/([<>=!]+|LIKE|NOT LIKE|IN|NOT IN|CONTAINS|NOT CONTAINS|BETWEEN|NOT BETWEEN|EXISTS)/", $crstr, $matches, PREG_OFFSET_CAPTURE); @@ -44,7 +55,38 @@ class ExpressionBuilder $right = self::automaticTypecast($right); } - return [$left, $op, $right]; + // handle "default" criteria and closures + if (is_a($right, FieldName::class)) { // field name + return function($a) use ($left, $right, $op): bool { + $X = &$a[$left]; + $Y = &$a[$right->fieldName]; + switch ($op) { + case "=": { + return $X == $Y; + } + case "!=": { + return $X != $Y; + } + case "<": { + return $X < $Y; + } + case ">": { + return $X > $Y; + } + case "<=": { + return $X <= $Y; + } + case ">=": { + return $X >= $Y; + } + default: { + return false; + } + } + }; + } else { // default critera + return [$left, $op, $right]; + } } // Build SleekDB query expression. Processes encapsulated expressions recursively as well.