/** * 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; }
$g1->setType(ClauseGroup::BOOLEAN_AND); $t->ok($result->equal($g1), 'decode a valid bracketed string containing ANDs and ORs'); $clause1 = "person.age IN (17,18,19,20)"; $clause2 = "person.height IN (100, 101)"; $result = $ca->analyse($clause1); $rClause1 = $result->getFirstSubclause(); $g = new ClauseGroup(); $g->addSubclause($rClause1); $t->ok($result->equal($g), 'decode a simple IN statement'); try { $clause = $clause1 . ' OR ' . $clause2; $result = $ca->analyse($clause); $clauses = $result->getSubclauses(); $g->addSubclause($clauses[1]); $g->setType(ClauseGroup::BOOLEAN_OR); $ok = $result->equal($g); } catch (Exception $e) { $ok = false; } $t->ok($ok, 'decode a two IN statements'); $clause = "person.name IN ('person.age IN (1, 2, 3)')"; try { $result = $ca->analyse($clause); $rClause = $result->getFirstSubclause(); $g = new ClauseGroup(); $g->addSubclause($rClause); $ok = $result->equal($g); } catch (Exception $e) { $ok = false; } $t->ok($ok, 'decode a simple IN statement containing a misleading IN string');