/** * Parses a non-bracketed expression * * Returns a ClauseGroup for a multi-part expression, or returns a string for an * expression containing just one (<col> <test> <value>) part */ private function parse($clause) { // If the input string is essentially empty then return null if (trim($clause) == '') { return null; } // Ensure that ANDs and ORs are not mixed $strAnd = ClauseGroup::BOOLEAN_AND; $strOr = ClauseGroup::BOOLEAN_OR; $boolAnd = strpos($clause, " {$strAnd} ") !== false; $boolOr = strpos($clause, " {$strOr} ") !== false; if ($boolAnd && $boolOr) { throw new SyntaxError("Need to bracket ANDs and ORs to indicate precedence in clause <{$clause}>"); } if ($boolOr) { $split = $strOr; } elseif ($boolAnd) { $split = $strAnd; } else { $split = null; } // If applicable, split the clause into subclauses and decide the type if ($split) { $subClauses = explode(" {$split} ", $clause); } else { $subClauses = array($clause); } $group = new ClauseGroup(); $group->setType($split); // Then add all the subclauses in foreach ($subClauses as $subClause) { if (trim($subClause) != '') { QuotedStringParser::insertStrings($subClause, $this->strings); $group->addSubclause($subClause); } } // If there is only one subclause, return a string rather than a ClauseGroup /* $subClauseArray = $group->getSubclauses(); if (count($subClauseArray) == 1) { return $subClauseArray[0]; } else { return $group; }*/ return $group; }
$t->diag('QuotedStringParser::replace'); $subject = 'person.age = 18'; $result = QuotedStringParser::replace($subject, 'Hello', 'Goodbye'); $t->ok($subject === $result, "Search for something that doesn't exist in a non-quoted string"); $result = QuotedStringParser::replace($subject, '=', '!='); $ok = $result === 'person.age != 18'; $t->ok($ok, "Search for something that exists in a non-quoted string"); $subject = "rule.cond = 'LIKE'"; $result = QuotedStringParser::replace($subject, 'LIKE', 'HATE'); $t->ok($subject === $result, "Search for something that exists only within a quoted string"); $result = QuotedStringParser::replace($subject, 'WIBBLE', 'BLAH'); $t->ok($subject === $result, "Search for something that does not exist at all in a quoted string"); $result = QuotedStringParser::replace($subject, '=', '<>'); $ok = $result === "rule.cond <> 'LIKE'"; $t->ok($ok, "Search for something that exists outside of a quoted string"); $subject = "(person.name > 21 AND name='(not sure)')"; $result = QuotedStringParser::replace($subject, '\\(', ''); $result = QuotedStringParser::replace($result, '\\)', ''); $ok = $result === "person.name > 21 AND name='(not sure)'"; $t->ok($ok, "Remove brackets, but not in string"); $t = new lime_test(3, new lime_output_color()); $t->diag('QuotedStringParser::extractStrings'); $subject = "person.location IN ('Brum','Coventry')"; $strs = array(); QuotedStringParser::extractStrings($subject, $strs); $t->ok($subject == "person.location IN (%%0,%%1)", 'Extract strings from an IN clause'); $subject = "person.name = '%%0'"; $strs = array(); QuotedStringParser::extractStrings($subject, $strs); $t->ok($subject == "person.name = %%0", "Check that tokens don't confuse string extraction"); $t->ok($strs[0] == "'%%0'", "Check that strings are correctly saved");