/** * @param string $rql * @param string $exceptionMessage * @return void * * @dataProvider dataSyntaxError() */ public function testSyntaxError($rql, $exceptionMessage) { $this->setExpectedException(SyntaxErrorException::class, $exceptionMessage); $lexer = new Lexer(); $parser = new Parser(); $parser->parse($lexer->tokenize($rql)); }
/** * @param string $rql * @param string $exceptionMessage * @return void * * @covers Parser::parse() * @dataProvider dataSyntaxError() */ public function testSyntaxError($rql, $exceptionMessage) { $this->setExpectedException('Xiag\\Rql\\Parser\\Exception\\SyntaxErrorException', $exceptionMessage); $lexer = new Lexer(); $parser = Parser::createDefault(); $parser->parse($lexer->tokenize($rql)); }
public function execute(Request $request, Response $response, callable $next = null) { $collectionname = $request->getAttribute('collectionname'); $collection = new TableGateway($collectionname, $this->boot()->db); $range = $request->getHeader('Range'); $lexer = new \Xiag\Rql\Parser\Lexer(); $tokens = $lexer->tokenize($request->getUri()->getQuery()); $parser = \Xiag\Rql\Parser\Parser::createDefault(); //file_put_contents('xxxx', print_r($parser->parse($tokens), true)); $rql = $parser->parse($tokens); $select = $collection->getSql()->select(); $sort = $rql->getSort(); if ($sort) { foreach ($sort->getFields() as $field => $descending) { //file_put_contents('xxxx', print_r($field, true)); $select->order("{$field} " . ($descending > 0 ? 'ASC' : 'DESC')); } } $result = $collection->selectWith($select); return $response->withHeader('Content-Type', 'application/json')->withBody($this->toJsonStream($result->toArray())); }
/** * execute a query againts the test db * * @param string $query query to execute * @param MongoOdm $visitor visitor we are testing * * @return array */ private function runTestQuery($query, $visitor) { $lexer = new Lexer(); $parser = RqlParser::createDefault(); $rqlQuery = $parser->parse($lexer->tokenize($query)); $builder = $visitor->visit($rqlQuery); $results = []; foreach ($builder->getQuery()->execute() as $doc) { $results[] = $doc; } return $results; }
{ return $tokenStream->test(Token::T_OPERATOR, 'elemMatch'); } public function parse(TokenStream $tokenStream) { $tokenStream->expect(Token::T_OPERATOR, 'elemMatch'); $tokenStream->expect(Token::T_OPEN_PARENTHESIS); $field = $tokenStream->expect(Token::T_STRING)->getValue(); $tokenStream->expect(Token::T_COMMA); $query = $this->queryParser->parse($tokenStream); if (!$query instanceof AbstractQueryNode) { throw new SyntaxErrorException(sprintf('"elemMatch" operator expects parameter "query" to be instance of "%s", "%s" given', AbstractQueryNode::class, get_class($query))); } $tokenStream->expect(Token::T_CLOSE_PARENTHESIS); return new ElemMatchNode($field, $query); } } // create node parser $scalarParser = (new ValueParser\ScalarParser())->registerTypeCaster('string', new TypeCaster\StringTypeCaster())->registerTypeCaster('integer', new TypeCaster\IntegerTypeCaster())->registerTypeCaster('float', new TypeCaster\FloatTypeCaster())->registerTypeCaster('boolean', new TypeCaster\BooleanTypeCaster()); $arrayParser = new ValueParser\ArrayParser($scalarParser); $globParser = new ValueParser\GlobParser(); $fieldParser = new ValueParser\FieldParser(); $integerParser = new ValueParser\IntegerParser(); $queryNodeParser = new NodeParser\QueryNodeParser(); $queryNodeParser->addNodeParser(new NodeParser\Query\GroupNodeParser($queryNodeParser))->addNodeParser(new NodeParser\Query\LogicalOperator\AndNodeParser($queryNodeParser))->addNodeParser(new NodeParser\Query\LogicalOperator\OrNodeParser($queryNodeParser))->addNodeParser(new NodeParser\Query\LogicalOperator\NotNodeParser($queryNodeParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Rql\InNodeParser($fieldParser, $arrayParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Rql\OutNodeParser($fieldParser, $arrayParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Rql\EqNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Rql\NeNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Rql\LtNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Rql\GtNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Rql\LeNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Rql\GeNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Rql\LikeNodeParser($fieldParser, $globParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\InNodeParser($fieldParser, $arrayParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\OutNodeParser($fieldParser, $arrayParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\EqNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\NeNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\LtNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\GtNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\LeNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\GeNodeParser($fieldParser, $scalarParser))->addNodeParser(new NodeParser\Query\ComparisonOperator\Fiql\LikeNodeParser($fieldParser, $globParser))->addNodeParser(new BetweenTokenParser($scalarParser))->addNodeParser(new ElemMatchNodeParser($queryNodeParser)); $nodeParser = (new NodeParserChain())->addNodeParser($queryNodeParser)->addNodeParser(new NodeParser\SelectNodeParser($fieldParser))->addNodeParser(new NodeParser\SortNodeParser($fieldParser))->addNodeParser(new NodeParser\LimitNodeParser($integerParser)); // parse $lexer = new Lexer(); $parser = new Parser($nodeParser); $tokenStream = $lexer->tokenize('between(x,1,2)&elemMatch(array,(between(x,3,4)&a=b&(c!=d|e!=f)¬(le(g,h))))'); var_dump($parser->parse($tokenStream));
<?php namespace Xiag\Rql\ParserExample01; use Xiag\Rql\Parser\Lexer; use Xiag\Rql\Parser\Parser; use Xiag\Rql\Parser\ExpressionParser; use Xiag\Rql\Parser\TokenParserGroup; use Xiag\Rql\Parser\TokenParser\Query\GroupTokenParser; use Xiag\Rql\Parser\TokenParser\Query\Fiql; require __DIR__ . '/../vendor/autoload.php'; $queryTokenParser = new TokenParserGroup(); $queryTokenParser->addTokenParser(new GroupTokenParser($queryTokenParser))->addTokenParser(new Fiql\ArrayOperator\InTokenParser())->addTokenParser(new Fiql\ArrayOperator\OutTokenParser())->addTokenParser(new Fiql\ScalarOperator\EqTokenParser())->addTokenParser(new Fiql\ScalarOperator\NeTokenParser())->addTokenParser(new Fiql\ScalarOperator\LtTokenParser())->addTokenParser(new Fiql\ScalarOperator\GtTokenParser())->addTokenParser(new Fiql\ScalarOperator\LeTokenParser())->addTokenParser(new Fiql\ScalarOperator\GeTokenParser()); $parser = new Parser(new ExpressionParser()); $parser->addTokenParser($queryTokenParser); $lexer = new Lexer(); // ok $tokenStream = $lexer->tokenize('((a==true|b!=str)&c>=10&d=in=(1,value,null))'); var_dump($parser->parse($tokenStream)); // error $tokenStream = $lexer->tokenize('or(eq(a,true),ne(b,str))>e(c,10)&in(d,(1,value,null))'); var_dump($parser->parse($tokenStream));
private function visitLogicalNode(Node\Query\AbstractLogicalOperatorNode $node, SqlBuilder $sqlBuilder) { if ($node->getNodeName() === 'not') { $operator = ' AND '; $sqlBuilder->addRawWhere('NOT'); } elseif ($node->getNodeName() === 'and') { $operator = ' AND '; } elseif ($node->getNodeName() === 'or') { $operator = ' OR '; } else { throw new \LogicException(sprintf('Unknown logical node "%s"', $node->getNodeName())); } $sqlBuilder->addRawWhere('('); foreach ($node->getQueries() as $index => $query) { $this->visitQueryNode($query, $sqlBuilder); if ($index !== count($node->getQueries()) - 1) { $sqlBuilder->addRawWhere($operator); } } $sqlBuilder->addRawWhere(')'); } } // parse $lexer = new Lexer(); $parser = new Parser(); $query = $parser->parse($lexer->tokenize(implode('&', ['select(a,b,c)', 'ne(a,b)', '(not(c=d)|e=f)&out(c,(1,2))', 'in(d,(true(),false(),null(),empty()))', 'ge(e,2016-06-30T12:09:44Z)', 'like(f,*sea?rch?)', 'sort(-a,+b)', 'limit(1,0)']))); // traversing $sqlBuilder = new SqlBuilder(); $nodeVisitor = new SqlNodeVisitor(); $nodeVisitor->visit($query, $sqlBuilder); var_dump($sqlBuilder->createQuery());
/** * @param string $value * @return Glob */ private function getGlob($value) { $lexer = new Lexer(); $parser = new Parser(); $rql = 'like(field,' . $value . ')'; $stream = $lexer->tokenize($rql); $query = $parser->parse($stream); /** @var LikeNode $like */ $like = $query->getQuery(); $this->assertInstanceOf(LikeNode::class, $like); /** @var Glob $glob */ $glob = $like->getValue(); $this->assertInstanceOf(Glob::class, $glob); return $glob; }
/** * Parses given RQL string into an abstract syntax tree (AST). * * @param \Xiag\Rql\Parser\Parser $parser * @param string $rql * * @return \Xiag\Rql\Parser\Query * @author Andreas Glaser */ public static function parse(Xiag\Parser $parser, $rql) { $lexer = new Lexer(); return $parser->parse($lexer->tokenize($rql)); }