now expressions with database fields on both sides of the operator are compiled into Closures and hence are valid
This commit is contained in:
		
							parent
							
								
									d78b636212
								
							
						
					
					
						commit
						5b2cc0b8f4
					
				@ -1,5 +1,14 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
class FieldName {
 | 
			
		||||
    public string $fieldName;
 | 
			
		||||
 | 
			
		||||
    public function __construct(string $fieldName)
 | 
			
		||||
    {
 | 
			
		||||
        $this->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.
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user