Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
doctrine-dbal
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Tomáš Trávníček
doctrine-dbal
Commits
97b4eb3f
Commit
97b4eb3f
authored
Dec 10, 2007
by
jepso
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added new dql parser to draft folder
parent
efa43480
Changes
42
Hide whitespace changes
Inline
Side-by-side
Showing
42 changed files
with
1415 additions
and
0 deletions
+1415
-0
Parser.php
draft/Doctrine/Query/Parser.php
+156
-0
Exception.php
draft/Doctrine/Query/Parser/Exception.php
+4
-0
Printer.php
draft/Doctrine/Query/Printer.php
+30
-0
Production.php
draft/Doctrine/Query/Production.php
+65
-0
Atom.php
draft/Doctrine/Query/Production/Atom.php
+23
-0
BetweenExpression.php
draft/Doctrine/Query/Production/BetweenExpression.php
+18
-0
ComparisonExpression.php
draft/Doctrine/Query/Production/ComparisonExpression.php
+27
-0
ComparisonOperator.php
draft/Doctrine/Query/Production/ComparisonOperator.php
+31
-0
ConditionalExpression.php
draft/Doctrine/Query/Production/ConditionalExpression.php
+16
-0
ConditionalFactor.php
draft/Doctrine/Query/Production/ConditionalFactor.php
+15
-0
ConditionalPrimary.php
draft/Doctrine/Query/Production/ConditionalPrimary.php
+17
-0
ConditionalTerm.php
draft/Doctrine/Query/Production/ConditionalTerm.php
+16
-0
DeleteClause.php
draft/Doctrine/Query/Production/DeleteClause.php
+13
-0
DeleteStatement.php
draft/Doctrine/Query/Production/DeleteStatement.php
+23
-0
Expression.php
draft/Doctrine/Query/Production/Expression.php
+20
-0
Factor.php
draft/Doctrine/Query/Production/Factor.php
+17
-0
FromClause.php
draft/Doctrine/Query/Production/FromClause.php
+18
-0
GroupByClause.php
draft/Doctrine/Query/Production/GroupByClause.php
+19
-0
GroupByItem.php
draft/Doctrine/Query/Production/GroupByItem.php
+11
-0
HavingClause.php
draft/Doctrine/Query/Production/HavingClause.php
+13
-0
IdentificationVariableDeclaration.php
...ne/Query/Production/IdentificationVariableDeclaration.php
+17
-0
Join.php
draft/Doctrine/Query/Production/Join.php
+27
-0
OrderByClause.php
draft/Doctrine/Query/Production/OrderByClause.php
+19
-0
OrderByItem.php
draft/Doctrine/Query/Production/OrderByItem.php
+17
-0
PathExpression.php
draft/Doctrine/Query/Production/PathExpression.php
+16
-0
Primary.php
draft/Doctrine/Query/Production/Primary.php
+55
-0
QuantifiedExpression.php
draft/Doctrine/Query/Production/QuantifiedExpression.php
+27
-0
QueryLanguage.php
draft/Doctrine/Query/Production/QueryLanguage.php
+24
-0
RangeVariableDeclaration.php
draft/Doctrine/Query/Production/RangeVariableDeclaration.php
+18
-0
SelectClause.php
draft/Doctrine/Query/Production/SelectClause.php
+22
-0
SelectExpression.php
draft/Doctrine/Query/Production/SelectExpression.php
+24
-0
SelectStatement.php
draft/Doctrine/Query/Production/SelectStatement.php
+36
-0
SimpleConditionalExpression.php
...Doctrine/Query/Production/SimpleConditionalExpression.php
+50
-0
Term.php
draft/Doctrine/Query/Production/Term.php
+20
-0
UpdateClause.php
draft/Doctrine/Query/Production/UpdateClause.php
+19
-0
UpdateStatement.php
draft/Doctrine/Query/Production/UpdateStatement.php
+23
-0
WhereClause.php
draft/Doctrine/Query/Production/WhereClause.php
+13
-0
Scanner.php
draft/Doctrine/Query/Scanner.php
+173
-0
Token.php
draft/Doctrine/Query/Token.php
+61
-0
query-language.txt
draft/query-language.txt
+75
-0
test.php
draft/test.php
+20
-0
ScannerTest.php
draft/tests/ScannerTest.php
+107
-0
No files found.
draft/Doctrine/Query/Parser.php
0 → 100644
View file @
97b4eb3f
<?php
class
Doctrine_Query_Parser
{
/**
* The minimum number of tokens read after last detected error before
* another error can be reported.
*
* @var int
*/
const
MIN_ERROR_DISTANCE
=
2
;
/**
* A scanner object.
*
* @var Doctrine_Query_Scanner
*/
protected
$_scanner
;
/**
* An array of production objects with their names as keys.
*
* @var array
*/
protected
$_productions
=
array
();
/**
* The next token in the query string.
*
* @var Doctrine_Query_Token
*/
public
$lookahead
;
/**
* Array containing syntax and semantical errors detected in the query
* string during parsing process.
*
* @var array
*/
protected
$_errors
=
array
();
/**
* The number of tokens read since last error in the input string
*
* @var int
*/
protected
$_errorDistance
=
self
::
MIN_ERROR_DISTANCE
;
/**
* A query printer object used to print a parse tree from the input string.
*
* @var Doctrine_Query_Printer
*/
protected
$_printer
;
/**
* Creates a new query parser object.
*
* @param string $input query string to be parsed
*/
public
function
__construct
(
$input
)
{
$this
->
_scanner
=
new
Doctrine_Query_Scanner
(
$input
);
$this
->
_printer
=
new
Doctrine_Query_Printer
(
true
);
}
public
function
getProduction
(
$name
)
{
if
(
!
isset
(
$this
->
_productions
[
$name
]))
{
$class
=
'Doctrine_Query_Production_'
.
$name
;
$this
->
_productions
[
$name
]
=
new
$class
(
$this
);
}
return
$this
->
_productions
[
$name
];
}
/**
* Attempts to match the given token with the current lookahead token.
*
* If they match, updates the lookahead token; otherwise raises a syntax
* error.
*
* @param int|string token type or value
*/
public
function
match
(
$token
)
{
if
(
is_string
(
$token
))
{
$isMatch
=
(
$this
->
lookahead
[
'value'
]
===
$token
);
}
else
{
$isMatch
=
(
$this
->
lookahead
[
'type'
]
===
$token
);
}
if
(
$isMatch
)
{
//$this->_printer->println($this->lookahead['value']);
$this
->
lookahead
=
$this
->
_scanner
->
scan
();
$this
->
_errorDistance
++
;
}
else
{
$this
->
syntaxError
();
}
}
public
function
syntaxError
()
{
$this
->
_error
(
'Unexpected "'
.
$this
->
lookahead
[
'value'
]
.
'"'
);
}
public
function
semanticalError
(
$message
)
{
$this
->
_error
(
$message
);
}
protected
function
_error
(
$message
)
{
if
(
$this
->
_errorDistance
>=
self
::
MIN_ERROR_DISTANCE
)
{
$message
.=
'at line '
.
$this
->
lookahead
[
'line'
]
.
', column '
.
$this
->
lookahead
[
'column'
];
$this
->
_errors
[]
=
$message
;
}
$this
->
_errorDistance
=
0
;
}
/**
* Returns the scanner object associated with this object.
*
* @return Doctrine_Query_Scanner
*/
public
function
getScanner
()
{
return
$this
->
_scanner
;
}
public
function
getPrinter
()
{
return
$this
->
_printer
;
}
/**
* Parses a query string.
*
* @throws Doctrine_Query_Parser_Exception if errors were detected in the query string
*/
public
function
parse
()
{
$this
->
lookahead
=
$this
->
_scanner
->
scan
();
$this
->
getProduction
(
'QueryLanguage'
)
->
execute
();
$this
->
match
(
Doctrine_Query_Token
::
T_EOS
);
if
(
count
(
$this
->
_errors
))
{
$msg
=
'Query string parsing failed ('
.
implode
(
'; '
,
$this
->
_errors
)
.
').'
;
throw
new
Doctrine_Query_Parser_Exception
(
$msg
);
}
}
}
draft/Doctrine/Query/Parser/Exception.php
0 → 100644
View file @
97b4eb3f
<?php
class
Doctrine_Query_Parser_Exception
extends
Exception
{
}
draft/Doctrine/Query/Printer.php
0 → 100644
View file @
97b4eb3f
<?php
class
Doctrine_Query_Printer
{
protected
$_indent
=
0
;
protected
$_silent
;
public
function
__construct
(
$silent
=
false
)
{
$this
->
_silent
=
$silent
;
}
public
function
startProduction
(
$name
)
{
$this
->
println
(
'('
.
$name
);
$this
->
_indent
++
;
}
public
function
endProduction
()
{
$this
->
_indent
--
;
$this
->
println
(
')'
);
}
public
function
println
(
$str
)
{
if
(
!
$this
->
_silent
)
{
echo
str_repeat
(
' '
,
$this
->
_indent
),
$str
,
"
\n
"
;
}
}
}
draft/Doctrine/Query/Production.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* An abstract base class that all query parser productions extend.
*/
abstract
class
Doctrine_Query_Production
{
/**
* a parser object
*
* @var Doctrine_Query_Parser
*/
protected
$_parser
;
/**
* Creates a new production object.
*
* @param Doctrine_Query_Parser $parser a parser object
*/
public
function
__construct
(
Doctrine_Query_Parser
$parser
)
{
$this
->
_parser
=
$parser
;
}
protected
function
_isNextToken
(
$token
)
{
$la
=
$this
->
_parser
->
lookahead
;
return
(
$la
[
'type'
]
===
$token
||
$la
[
'value'
]
===
$token
);
}
/**
* Executes a production with specified name and parameters.
*
* @param string $name production name
* @param array $params an associative array containing parameter names and
* their values
* @return mixed
*/
public
function
__call
(
$method
,
$args
)
{
return
$this
->
_parser
->
getProduction
(
$method
)
->
execute
(
$args
);
$this
->
_parser
->
getPrinter
()
->
startProduction
(
$name
);
$retval
=
$this
->
_parser
->
getProduction
(
$method
)
->
execute
(
$args
);
$this
->
_parser
->
getPrinter
()
->
endProduction
();
return
$retval
;
}
/**
* Executes this production using the specified parameters.
*
* @param array $params an associative array containing parameter names and
* their values
* @return mixed
*/
abstract
public
function
execute
(
array
$params
=
array
());
protected
function
_isSubquery
()
{
$lookahead
=
$this
->
_parser
->
lookahead
;
$next
=
$this
->
_parser
->
getScanner
()
->
peek
();
return
$lookahead
[
'value'
]
===
'('
&&
$next
[
'type'
]
===
Doctrine_Query_Token
::
T_SELECT
;
}
}
draft/Doctrine/Query/Production/Atom.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* Atom = string | numeric | input_parameter
*/
class
Doctrine_Query_Production_Atom
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
switch
(
$this
->
_parser
->
lookahead
[
'type'
])
{
case
Doctrine_Query_Token
::
T_STRING
:
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_STRING
);
break
;
case
Doctrine_Query_Token
::
T_NUMERIC
:
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_NUMERIC
);
break
;
case
Doctrine_Query_Token
::
T_INPUT_PARAMETER
:
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_INPUT_PARAMETER
);
break
;
default
:
$this
->
_parser
->
syntaxError
();
}
}
}
draft/Doctrine/Query/Production/BetweenExpression.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* BetweenExpression = ["NOT"] "BETWEEN" Expression "AND" Expression
*/
class
Doctrine_Query_Production_BetweenExpression
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
if
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_NOT
))
{
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_NOT
);
}
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_BETWEEN
);
$this
->
Expression
();
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_AND
);
$this
->
Expression
();
}
}
draft/Doctrine/Query/Production/ComparisonExpression.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* ComparisonExpression = ComparisonOperator ( QuantifiedExpression | Expression | "(" Subselect ")" )
*/
class
Doctrine_Query_Production_ComparisonExpression
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
$this
->
ComparisonOperator
();
if
(
$this
->
_isSubquery
())
{
$this
->
_parser
->
match
(
'('
);
$this
->
Subselect
();
$this
->
_parser
->
match
(
')'
);
}
else
{
switch
(
$this
->
_parser
->
lookahead
[
'type'
])
{
case
Doctrine_Query_Token
::
T_ALL
:
case
Doctrine_Query_Token
::
T_SOME
:
case
Doctrine_Query_Token
::
T_NONE
:
$this
->
QuantifiedExpression
();
break
;
default
:
$this
->
Expression
();
}
}
}
}
draft/Doctrine/Query/Production/ComparisonOperator.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* ComparisonOperator = "=" | "<" | "<=" | "<>" | ">" | ">="
*/
class
Doctrine_Query_Production_ComparisonOperator
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
switch
(
$this
->
_parser
->
lookahead
[
'value'
])
{
case
'='
:
$this
->
_parser
->
match
(
'='
);
break
;
case
'<'
:
$this
->
_parser
->
match
(
'<'
);
if
(
$this
->
_isNextToken
(
'='
))
{
$this
->
_parser
->
match
(
'='
);
}
elseif
(
$this
->
_isNextToken
(
'>'
))
{
$this
->
_parser
->
match
(
'>'
);
}
break
;
case
'>'
:
$this
->
_parser
->
match
(
'>'
);
if
(
$this
->
_isNextToken
(
'='
))
{
$this
->
_parser
->
match
(
'='
);
}
break
;
default
:
$this
->
_parser
->
syntaxError
();
}
}
}
draft/Doctrine/Query/Production/ConditionalExpression.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* ConditionalExpression = ConditionalTerm {"OR" ConditionalTerm}
*/
class
Doctrine_Query_Production_ConditionalExpression
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
$this
->
ConditionalTerm
();
while
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_OR
))
{
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_OR
);
$this
->
ConditionalTerm
();
}
}
}
draft/Doctrine/Query/Production/ConditionalFactor.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* ConditionalFactor = ["NOT"] ConditionalPrimary
*/
class
Doctrine_Query_Production_ConditionalFactor
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
if
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_NOT
))
{
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_NOT
);
}
$this
->
ConditionalPrimary
();
}
}
draft/Doctrine/Query/Production/ConditionalPrimary.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* ConditionalPrimary = SimpleConditionalExpression | "(" ConditionalExpression ")"
*/
class
Doctrine_Query_Production_ConditionalPrimary
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
if
(
$this
->
_isNextToken
(
'('
))
{
$this
->
_parser
->
match
(
'('
);
$this
->
ConditionalExpression
();
$this
->
_parser
->
match
(
')'
);
}
else
{
$this
->
SimpleConditionalExpression
();
}
}
}
draft/Doctrine/Query/Production/ConditionalTerm.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* ConditionalTerm = ConditionalFactor {"AND" ConditionalFactor}
*/
class
Doctrine_Query_Production_ConditionalTerm
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
$this
->
ConditionalFactor
();
while
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_AND
))
{
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_AND
);
$this
->
ConditionalFactor
();
}
}
}
draft/Doctrine/Query/Production/DeleteClause.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* DeleteClause = "DELETE" "FROM" RangeVariableDeclaration
*/
class
Doctrine_Query_Production_DeleteClause
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_DELETE
);
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_FROM
);
$this
->
RangeVariableDeclaration
();
}
}
draft/Doctrine/Query/Production/DeleteStatement.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* DeleteStatement = DeleteClause [WhereClause] [OrderByClause] [LimitClause]
*/
class
Doctrine_Query_Production_DeleteStatement
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
$this
->
DeleteClause
();
if
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_WHERE
))
{
$this
->
WhereClause
();
}
if
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_ORDER
))
{
$this
->
OrderByClause
();
}
if
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_LIMIT
))
{
$this
->
LimitClause
();
}
}
}
draft/Doctrine/Query/Production/Expression.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* Expression = Term {("+" | "-") Term}
*/
class
Doctrine_Query_Production_Expression
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
$this
->
Term
();
while
(
$this
->
_isNextToken
(
'+'
)
||
$this
->
_isNextToken
(
'-'
))
{
if
(
$this
->
_isNextToken
(
'+'
))
{
$this
->
_parser
->
match
(
'+'
);
}
else
{
$this
->
_parser
->
match
(
'-'
);
}
$this
->
Term
();
}
}
}
draft/Doctrine/Query/Production/Factor.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* Factor = [("+" | "-")] Primary
*/
class
Doctrine_Query_Production_Factor
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
if
(
$this
->
_isNextToken
(
'+'
))
{
$this
->
_parser
->
match
(
'+'
);
}
elseif
(
$this
->
_isNextToken
(
'-'
))
{
$this
->
_parser
->
match
(
'-'
);
}
$this
->
Primary
();
}
}
draft/Doctrine/Query/Production/FromClause.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* FromClause = "FROM" IdentificationVariableDeclaration {"," IdentificationVariableDeclaration}
*/
class
Doctrine_Query_Production_FromClause
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_FROM
);
$this
->
IdentificationVariableDeclaration
();
while
(
$this
->
_isNextToken
(
','
))
{
$this
->
_parser
->
match
(
','
);
$this
->
IdentificationVariableDeclaration
();
}
}
}
draft/Doctrine/Query/Production/GroupByClause.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* GroupByClause = "GROUP" "BY" GroupByItem {"," GroupByItem}
*/
class
Doctrine_Query_Production_GroupByClause
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_GROUP
);
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_BY
);
$this
->
GroupByItem
();
while
(
$this
->
_isNextToken
(
','
))
{
$this
->
_parser
->
match
(
','
);
$this
->
GroupByItem
();
}
}
}
draft/Doctrine/Query/Production/GroupByItem.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* OrderByItem = PathExpression
*/
class
Doctrine_Query_Production_GroupByItem
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
$this
->
PathExpression
();
}
}
draft/Doctrine/Query/Production/HavingClause.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* HavingClause = "HAVING" ConditionalExpression
*/
class
Doctrine_Query_Production_HavingClause
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_HAVING
);
$this
->
ConditionalExpression
();
}
}
draft/Doctrine/Query/Production/IdentificationVariableDeclaration.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* IdentificationVariableDeclaration = RangeVariableDeclaration {Join}
*/
class
Doctrine_Query_Production_IdentificationVariableDeclaration
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
$this
->
RangeVariableDeclaration
();
while
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_LEFT
)
||
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_INNER
)
||
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_JOIN
))
{
$this
->
Join
();
}
}
}
draft/Doctrine/Query/Production/Join.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* Join = ["LEFT" ["OUTER"] | "INNER"] "JOIN" PathExpression "AS" identifier
*/
class
Doctrine_Query_Production_Join
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
if
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_LEFT
))
{
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_LEFT
);
if
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_OUTER
))
{
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_OUTER
);
}
}
elseif
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_INNER
))
{
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_INNER
);
}
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_JOIN
);
$this
->
PathExpression
();
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_AS
);
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_IDENTIFIER
);
}
}
draft/Doctrine/Query/Production/OrderByClause.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* OrderByClause = "ORDER" "BY" OrderByItem {"," OrderByItem}
*/
class
Doctrine_Query_Production_OrderByClause
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_ORDER
);
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_BY
);
$this
->
OrderByItem
();
while
(
$this
->
_isNextToken
(
','
))
{
$this
->
_parser
->
match
(
','
);
$this
->
OrderByItem
();
}
}
}
draft/Doctrine/Query/Production/OrderByItem.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* OrderByItem = PathExpression ["ASC" | "DESC"]
*/
class
Doctrine_Query_Production_OrderByItem
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
$this
->
PathExpression
();
if
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_ASC
))
{
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_ASC
);
}
elseif
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_DESC
))
{
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_DESC
);
}
}
}
draft/Doctrine/Query/Production/PathExpression.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* PathExpression = identifier { "." identifier }
*/
class
Doctrine_Query_Production_PathExpression
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_IDENTIFIER
);
while
(
$this
->
_isNextToken
(
'.'
))
{
$this
->
_parser
->
match
(
'.'
);
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_IDENTIFIER
);
}
}
}
draft/Doctrine/Query/Production/Primary.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* Primary = PathExpression | Atom | "(" Expression ")" | Function |
* AggregateExpression
*/
class
Doctrine_Query_Production_Primary
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
switch
(
$this
->
_parser
->
lookahead
[
'type'
])
{
case
Doctrine_Query_Token
::
T_IDENTIFIER
:
// @todo: custom functions
$this
->
PathExpression
();
break
;
case
Doctrine_Query_Token
::
T_STRING
:
case
Doctrine_Query_Token
::
T_NUMERIC
:
case
Doctrine_Query_Token
::
T_INPUT_PARAMETER
:
$this
->
Atom
();
break
;
case
Doctrine_Query_Token
::
T_LENGTH
:
case
Doctrine_Query_Token
::
T_LOCATE
:
case
Doctrine_Query_Token
::
T_ABS
:
case
Doctrine_Query_Token
::
T_SQRT
:
case
Doctrine_Query_Token
::
T_MOD
:
case
Doctrine_Query_Token
::
T_SIZE
:
case
Doctrine_Query_Token
::
T_CURRENT_DATE
:
case
Doctrine_Query_Token
::
T_CURRENT_TIMESTAMP
:
case
Doctrine_Query_Token
::
T_CURRENT_TIME
:
case
Doctrine_Query_Token
::
T_SUBSTRING
:
case
Doctrine_Query_Token
::
T_CONCAT
:
case
Doctrine_Query_Token
::
T_TRIM
:
case
Doctrine_Query_Token
::
T_LOWER
:
case
Doctrine_Query_Token
::
T_UPPER
:
$this
->
Function
();
break
;
case
Doctrine_Query_Token
::
T_AVG
:
case
Doctrine_Query_Token
::
T_MAX
:
case
Doctrine_Query_Token
::
T_MIN
:
case
Doctrine_Query_Token
::
T_SUM
:
case
Doctrine_Query_Token
::
T_MOD
:
case
Doctrine_Query_Token
::
T_SIZE
:
$this
->
AggregateExpression
();
break
;
case
Doctrine_Query_Token
::
T_NONE
:
if
(
$this
->
_isNextToken
(
'('
))
{
$this
->
_parser
->
match
(
'('
);
$this
->
Expression
();
$this
->
_parser
->
match
(
')'
);
break
;
}
default
:
$this
->
_parser
->
syntaxError
();
}
}
}
draft/Doctrine/Query/Production/QuantifiedExpression.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* QuantifiedExpression = ("ALL" | "ANY" | "SOME") "(" Subselect ")"
*/
class
Doctrine_Query_Production_QuantifiedExpression
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
switch
(
$this
->
_parser
->
lookahead
[
'type'
])
{
case
Doctrine_Query_Token
::
T_ALL
:
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_ALL
);
break
;
case
Doctrine_Query_Token
::
T_ANY
:
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_ANY
);
break
;
case
Doctrine_Query_Token
::
T_SOME
:
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_SOME
);
break
;
default
:
$this
->
syntaxError
();
}
$this
->
_parser
->
match
(
'('
);
$this
->
Subselect
();
$this
->
_parser
->
match
(
')'
);
}
}
draft/Doctrine/Query/Production/QueryLanguage.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* QueryLanguage = SelectStatement | UpdateStatement | DeleteStatement
*/
class
Doctrine_Query_Production_QueryLanguage
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
switch
(
$this
->
_parser
->
lookahead
[
'type'
])
{
case
Doctrine_Query_Token
::
T_SELECT
:
case
Doctrine_Query_Token
::
T_FROM
:
$this
->
SelectStatement
();
break
;
case
Doctrine_Query_Token
::
T_UPDATE
:
$this
->
UpdateStatement
();
break
;
case
Doctrine_Query_Token
::
T_DELETE
:
$this
->
DeleteStatement
();
break
;
default
:
$this
->
_parser
->
syntaxError
();
}
}
}
draft/Doctrine/Query/Production/RangeVariableDeclaration.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* RangeVariableDeclaration = PathExpression [["AS" ] identifier]
*/
class
Doctrine_Query_Production_RangeVariableDeclaration
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
$this
->
PathExpression
();
if
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_AS
))
{
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_AS
);
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_IDENTIFIER
);
}
elseif
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_IDENTIFIER
))
{
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_IDENTIFIER
);
}
}
}
draft/Doctrine/Query/Production/SelectClause.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* SelectClause = "SELECT" ["DISTINCT"] SelectExpression {"," SelectExpression}
*/
class
Doctrine_Query_Production_SelectClause
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_SELECT
);
if
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_DISTINCT
))
{
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_DISTINCT
);
}
$this
->
SelectExpression
();
while
(
$this
->
_isNextToken
(
','
))
{
$this
->
_parser
->
match
(
','
);
$this
->
SelectExpression
();
}
}
}
draft/Doctrine/Query/Production/SelectExpression.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* SelectExpression = (Expression | "(" Subselect ")" ) [["AS"] identifier]
*/
class
Doctrine_Query_Production_SelectExpression
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
if
(
$this
->
_isSubquery
())
{
$this
->
_parser
->
match
(
'('
);
$this
->
Subselect
();
$this
->
_parser
->
match
(
')'
);
}
else
{
$this
->
Expression
();
}
if
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_AS
))
{
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_AS
);
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_IDENTIFIER
);
}
elseif
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_IDENTIFIER
))
{
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_IDENTIFIER
);
}
}
}
draft/Doctrine/Query/Production/SelectStatement.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* SelectStatement = [SelectClause] FromClause [WhereClause] [GroupByClause]
* [HavingClause] [OrderByClause] [LimitClause]
*/
class
Doctrine_Query_Production_SelectStatement
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
if
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_SELECT
))
{
$this
->
SelectClause
();
}
$this
->
FromClause
();
if
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_WHERE
))
{
$this
->
WhereClause
();
}
if
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_GROUP
))
{
$this
->
GroupByClause
();
}
if
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_HAVING
))
{
$this
->
HavingClause
();
}
if
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_ORDER
))
{
$this
->
OrderByClause
();
}
if
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_LIMIT
))
{
$this
->
LimitClause
();
}
}
}
draft/Doctrine/Query/Production/SimpleConditionalExpression.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* SimpleConditionalExpression =
* Expression (ComparisonExpression | BetweenExpression | LikeExpression |
* InExpression | NullComparisonExpression | QuantifiedExpression) |
* ExistsExpression
*/
class
Doctrine_Query_Production_SimpleConditionalExpression
extends
Doctrine_Query_Production
{
protected
function
_getExpressionType
()
{
if
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_NOT
))
{
$token
=
$this
->
_parser
->
getScanner
()
->
peek
();
$this
->
_parser
->
getScanner
()
->
resetPeek
();
}
else
{
$token
=
$this
->
_parser
->
lookahead
;
}
return
$token
[
'type'
];
}
public
function
execute
(
array
$params
=
array
())
{
if
(
$this
->
_getExpressionType
()
===
Doctrine_Query_Token
::
T_EXISTS
)
{
$this
->
ExistsExpression
();
}
else
{
$this
->
Expression
();
switch
(
$this
->
_getExpressionType
())
{
case
Doctrine_Query_Token
::
T_BETWEEN
:
$this
->
BetweenExpression
();
break
;
case
Doctrine_Query_Token
::
T_LIKE
:
$this
->
LikeExpression
();
break
;
case
Doctrine_Query_Token
::
T_IN
:
$this
->
InExpression
();
break
;
case
Doctrine_Query_Token
::
T_IS
:
$this
->
NullComparisonExpression
();
break
;
case
Doctrine_Query_Token
::
T_NONE
:
$this
->
ComparisonExpression
();
break
;
default
:
$this
->
_parser
->
syntaxError
();
}
}
}
}
draft/Doctrine/Query/Production/Term.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* Term = Factor {("*" | "/") Factor}
*/
class
Doctrine_Query_Production_Term
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
$this
->
Factor
();
while
(
$this
->
_isNextToken
(
'*'
)
||
$this
->
_isNextToken
(
'/'
))
{
if
(
$this
->
_isNextToken
(
'*'
))
{
$this
->
_parser
->
match
(
'*'
);
}
else
{
$this
->
_parser
->
match
(
'/'
);
}
$this
->
Factor
();
}
}
}
draft/Doctrine/Query/Production/UpdateClause.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* UpdateClause = "UPDATE" RangeVariableDeclaration "SET" UpdateItem {"," UpdateItem}
*/
class
Doctrine_Query_Production_UpdateClause
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_UPDATE
);
$this
->
RangeVariableDeclaration
();
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_SET
);
$this
->
RangeVariableDeclaration
();
while
(
$this
->
_isNextToken
(
','
))
{
$this
->
_parser
->
match
(
','
);
$this
->
RangeVariableDeclaration
();
}
}
}
draft/Doctrine/Query/Production/UpdateStatement.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* UpdateStatement = UpdateClause [WhereClause] [OrderByClause] [LimitClause]
*/
class
Doctrine_Query_Production_UpdateStatement
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
$this
->
UpdateClause
();
if
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_WHERE
))
{
$this
->
WhereClause
();
}
if
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_ORDER
))
{
$this
->
OrderByClause
();
}
if
(
$this
->
_isNextToken
(
Doctrine_Query_Token
::
T_LIMIT
))
{
$this
->
LimitClause
();
}
}
}
draft/Doctrine/Query/Production/WhereClause.php
0 → 100644
View file @
97b4eb3f
<?php
/**
* WhereClause = "WHERE" ConditionalExpression
*/
class
Doctrine_Query_Production_WhereClause
extends
Doctrine_Query_Production
{
public
function
execute
(
array
$params
=
array
())
{
$this
->
_parser
->
match
(
Doctrine_Query_Token
::
T_WHERE
);
$this
->
ConditionalExpression
();
}
}
draft/Doctrine/Query/Scanner.php
0 → 100644
View file @
97b4eb3f
<?php
class
Doctrine_Query_Scanner
{
/**
* The query string
*
* @var string
*/
protected
$_input
;
/**
* The length of the query string
*
* @var string
*/
protected
$_length
;
/**
* Array of tokens already peeked
*
* @var array
*/
protected
$_tokens
=
array
();
/**
*
* @var int
*/
protected
$_peekPosition
=
0
;
protected
$_position
=
0
;
protected
$_line
=
1
;
protected
$_column
=
1
;
protected
static
$_regex
=
array
(
'identifier'
=>
'/^[a-z][a-z0-9_]*/i'
,
'numeric'
=>
'/^[+-]?([0-9]+([\.][0-9]+)?)(e[+-]?[0-9]+)?/i'
,
'string'
=>
"/^'([^']|'')*'/"
,
'input_parameter'
=>
'/^\?|:[a-z]+/'
);
/**
* Creates a new query scanner object.
*
* @param string $input a query string
*/
public
function
__construct
(
$input
)
{
$this
->
_input
=
$input
;
$this
->
_length
=
strlen
(
$input
);
}
/**
* Checks if an identifier is a keyword and returns its correct type.
*
* @param string $identifier identifier name
* @return int token type
*/
public
function
_checkLiteral
(
$identifier
)
{
$name
=
'Doctrine_Query_Token::T_'
.
strtoupper
(
$identifier
);
if
(
defined
(
$name
))
{
$type
=
constant
(
$name
);
if
(
$type
>
100
)
{
return
$type
;
}
}
return
Doctrine_Query_Token
::
T_IDENTIFIER
;
}
/**
* Returns the next token in the input string.
*
* The returned token is an associative array containing the following keys:
* 'type' : type of the token; @see Doctrine_Query_Token::T_* constants
* 'value' : string value of the token in the input string
* 'position' : start position of the token in the input string
* 'line' :
* 'column' :
*
* @return array the next token
*/
protected
function
_nextToken
()
{
// ignore whitespace
while
(
$this
->
_position
<
$this
->
_length
&&
ctype_space
(
$this
->
_input
[
$this
->
_position
]))
{
if
(
$this
->
_input
[
$this
->
_position
]
===
"
\n
"
)
{
$this
->
_line
++
;
$this
->
_column
=
1
;
}
else
{
$this
->
_column
++
;
}
$this
->
_position
++
;
}
if
(
$this
->
_position
<
$this
->
_length
)
{
$subject
=
substr
(
$this
->
_input
,
$this
->
_position
);
if
(
preg_match
(
self
::
$_regex
[
'identifier'
],
$subject
,
$matches
))
{
$value
=
$matches
[
0
];
$type
=
$this
->
_checkLiteral
(
$value
);
}
elseif
(
preg_match
(
self
::
$_regex
[
'numeric'
],
$subject
,
$matches
))
{
$value
=
$matches
[
0
];
$type
=
Doctrine_Query_Token
::
T_NUMERIC
;
}
elseif
(
preg_match
(
self
::
$_regex
[
'string'
],
$subject
,
$matches
))
{
$value
=
$matches
[
0
];
$type
=
Doctrine_Query_Token
::
T_STRING
;
}
elseif
(
preg_match
(
self
::
$_regex
[
'input_parameter'
],
$subject
,
$matches
))
{
$value
=
$matches
[
0
];
$type
=
Doctrine_Query_Token
::
T_INPUT_PARAMETER
;
}
else
{
$value
=
$subject
[
0
];
$type
=
Doctrine_Query_Token
::
T_NONE
;
}
}
else
{
$value
=
''
;
$type
=
Doctrine_Query_Token
::
T_EOS
;
}
$token
=
array
(
'type'
=>
$type
,
'value'
=>
$value
,
'position'
=>
$this
->
_position
,
'line'
=>
$this
->
_line
,
'column'
=>
$this
->
_column
);
$increment
=
strlen
(
$value
);
$this
->
_position
+=
$increment
;
$this
->
_column
+=
$increment
;
return
$token
;
}
/**
* Returns the next token without removing it from the input string.
*
* @return array the next token
*/
public
function
peek
()
{
if
(
$this
->
_peekPosition
>=
count
(
$this
->
_tokens
))
{
$this
->
_tokens
[]
=
$this
->
_nextToken
();
}
return
$this
->
_tokens
[
$this
->
_peekPosition
++
];
}
public
function
resetPeek
()
{
$this
->
_peekPosition
=
0
;
}
/**
* Returns the next token in the input string.
*
* @return array the next token
*/
public
function
scan
()
{
if
(
count
(
$this
->
_tokens
)
>
0
)
{
$this
->
resetPeek
();
return
array_shift
(
$this
->
_tokens
);
}
else
{
return
$this
->
_nextToken
();
}
}
}
draft/Doctrine/Query/Token.php
0 → 100644
View file @
97b4eb3f
<?php
class
Doctrine_Query_Token
{
const
T_EOS
=
0
;
const
T_NONE
=
1
;
const
T_IDENTIFIER
=
2
;
const
T_NUMERIC
=
3
;
const
T_STRING
=
4
;
const
T_INPUT_PARAMETER
=
5
;
const
T_ALL
=
101
;
const
T_AND
=
102
;
const
T_ANY
=
103
;
const
T_AS
=
104
;
const
T_ASC
=
105
;
const
T_AVG
=
106
;
const
T_BETWEEN
=
107
;
const
T_BY
=
108
;
const
T_COUNT
=
109
;
const
T_DELETE
=
100
;
const
T_DESC
=
111
;
const
T_DISTINCT
=
112
;
const
T_ESCAPE
=
113
;
const
T_EXISTS
=
114
;
const
T_FROM
=
115
;
const
T_GROUP
=
116
;
const
T_HAVING
=
117
;
const
T_IN
=
118
;
const
T_INNER
=
119
;
const
T_IS
=
120
;
const
T_JOIN
=
121
;
const
T_LEFT
=
122
;
const
T_LIKE
=
123
;
const
T_LIMIT
=
124
;
const
T_MAX
=
125
;
const
T_MIN
=
126
;
const
T_NOT
=
127
;
const
T_NULL
=
128
;
const
T_OFFSET
=
129
;
const
T_OR
=
130
;
const
T_ORDER
=
131
;
const
T_SELECT
=
132
;
const
T_SET
=
133
;
const
T_SOME
=
134
;
const
T_SUM
=
135
;
const
T_UPDATE
=
136
;
const
T_WHERE
=
137
;
const
T_LENGTH
=
138
;
const
T_LOCATE
=
139
;
const
T_ABS
=
140
;
const
T_SQRT
=
141
;
const
T_MOD
=
142
;
const
T_SIZE
=
143
;
const
T_CURRENT_DATE
=
144
;
const
T_CURRENT_TIMESTAMP
=
145
;
const
T_CURRENT_TIME
=
146
;
const
T_SUBSTRING
=
147
;
const
T_CONCAT
=
148
;
const
T_TRIM
=
149
;
const
T_LOWER
=
150
;
const
T_UPPER
=
151
;
}
draft/query-language.txt
0 → 100644
View file @
97b4eb3f
QueryLanguage = SelectStatement | UpdateStatement | DeleteStatement
SelectStatement = [SelectClause] FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause] [LimitClause]
UpdateStatement = UpdateClause [WhereClause] [OrderByClause] [LimitClause]
DeleteStatement = DeleteClause [WhereClause] [OrderByClause] [LimitClause]
Subselect = SimpleSelectClause FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause] [LimitClause] [OffsetClause]
SelectClause = "SELECT" ["ALL" | "DISTINCT"] SelectExpression {"," SelectExpression}
SimpleSelectClause = "SELECT" ["ALL" | "DISTINCT"] SelectExpression
DeleteClause = "DELETE" "FROM" RangeVariableDeclaration
WhereClause = "WHERE" ConditionalExpression
FromClause = "FROM" IdentificationVariableDeclaration {"," IdentificationVariableDeclaration}
HavingClause = "HAVING" ConditionalExpression
GroupByClause = "GROUP" "BY" GroupByItem {"," GroupByItem}
OrderByClause = "ORDER" "BY" OrderByItem {"," OrderByItem}
LimitClause = "LIMIT" Expression ["OFFSET" Expression]
UpdateClause = "UPDATE" RangeVariableDeclaration "SET" UpdateItem {"," UpdateItem}
OrderByItem = PathExpression ["ASC" | "DESC"]
GroupByItem = PathExpression
UpdateItem = PathExpression "=" (Expression | "NULL")
IdentificationVariableDeclaration = RangeVariableDeclaration {Join}
RangeVariableDeclaration = PathExpression [["AS" ] identifier<identification-variable>]
Join = ["LEFT" | "INNER"] "JOIN" PathExpression "AS" identifier
ConditionalExpression = ConditionalTerm {"OR" ConditionalTerm}
ConditionalTerm = ConditionalFactor {"AND" ConditionalFactor}
ConditionalFactor = ["NOT"] ConditionalPrimary
ConditionalPrimary = SimpleConditionalExpression | "(" ConditionalExpression ")"
SimpleConditionalExpression
= Expression (ComparisonExpression | BetweenExpression | LikeExpression
| InExpression | NullComparisonExpression) | ExistsExpression
Atom = string-literal | numeric-constant | input-parameter
Expression = Expression {("+" | "-" | "*" | "/") Expression}
Expression = ("+" | "-") Expression
Expression = "(" Expression ")"
Expression = PathExpression | Atom | | Function | AggregateExpression
SelectExpression = (Expression | "(" Subselect ")" ) [["AS"] identifier]
PathExpression = identifier {"." identifier}
AggregateExpression = ("AVG" | "MAX" | "MIN" | "SUM") "(" ["DISTINCT"] Expression ")"
| "COUNT" "(" ["DISTINCT"] (Expression | "*") ")"
QuantifiedExpression = ("ALL" | "ANY" | "SOME") "(" Subselect ")"
BetweenExpression = ["NOT"] "BETWEEN" Expression "AND" Expression
ComparisonExpression = ComparisonOperator ( QuantifiedExpression | Expression | "(" Subselect ")" )
InExpression = ["NOT"] "IN" "(" (Atom {"," Atom} | Subselect) ")"
LikeExpression = ["NOT"] "LIKE" Expression ["ESCAPE" escape_character]
NullComparisonExpression = "IS" ["NOT"] "NULL"
ExistsExpression = ["NOT"] "EXISTS" "(" Subselect ")"
Function =
"CURRENT_DATE" |
"CURRENT_TIME" |
"CURRENT_TIMESTAMP" |
"LENGTH" "(" Expression ")" |
"LOCATE" "(" Expression "," Expression ["," Expression] ")" |
"ABS" "(" Expression ")" |
"SQRT" "(" Expression ")" |
"MOD" "(" Expression "," Expression ")" |
"SIZE" "(" Expression ")" |
"CONCAT" "(" Expression "," Expression ")" |
"SUBSTRING" "(" Expression "," Expression "," "Expression" ")" |
"TRIM" "(" [[TrimSpecification] [trim_character] "FROM"] string_primary ")" |
"LOWER" "(" string_primary ")" |
"UPPER" "(" string_primary ")" |
identifier "(" [Expression {"," Expression}]")" // Custom function
TrimSpecification = "LEADING" | "TRAILING" | "BOTH"
draft/test.php
0 → 100644
View file @
97b4eb3f
<?php
require_once
'Doctrine.php'
;
spl_autoload_register
(
array
(
'Doctrine'
,
'autoload'
));
$n
=
1000
;
$start
=
microtime
(
true
);
for
(
$i
=
0
;
$i
<
$n
;
$i
++
)
{
/* $parser = new Doctrine_Query_Parser('SELECT u.name, u.age FROM User u WHERE u.id = ?');
$parser->parse();*/
$scanner
=
new
Doctrine_Query_Scanner
(
'SELECT u.name, u.age FROM User u WHERE u.id = ?'
);
do
{
$token
=
$scanner
->
scan
();
}
while
(
$token
[
'type'
]
!==
Doctrine_Query_Token
::
T_EOS
);
}
$end
=
microtime
(
true
);
printf
(
"Parsed %d queries: %.3f ms per query
\n
"
,
$n
,
(
$end
-
$start
)
/
$n
*
1000
);
draft/tests/ScannerTest.php
0 → 100644
View file @
97b4eb3f
<?php
require_once
'PHPUnit/Framework.php'
;
require_once
'../Doctrine.php'
;
spl_autoload_register
(
array
(
'Doctrine'
,
'autoload'
));
class
ScannerTest
extends
PHPUnit_Framework_TestCase
{
public
function
testScannerRecognizesIdentifierWithLengthOfOneCharacter
()
{
$scanner
=
new
Doctrine_Query_Scanner
(
'u'
);
$token
=
$scanner
->
scan
();
$this
->
assertEquals
(
Doctrine_Query_Token
::
T_IDENTIFIER
,
$token
->
getType
());
$this
->
assertEquals
(
'u'
,
$token
->
getValue
());
}
public
function
testScannerRecognizesIdentifierConsistingOfLetters
()
{
$scanner
=
new
Doctrine_Query_Scanner
(
'someIdentifier'
);
$token
=
$scanner
->
scan
();
$this
->
assertEquals
(
Doctrine_Query_Token
::
T_IDENTIFIER
,
$token
->
getType
());
$this
->
assertEquals
(
'someIdentifier'
,
$token
->
getValue
());
}
public
function
testScannerRecognizesIdentifierIncludingDigits
()
{
$scanner
=
new
Doctrine_Query_Scanner
(
's0m31d3nt1f13r'
);
$token
=
$scanner
->
scan
();
$this
->
assertEquals
(
Doctrine_Query_Token
::
T_IDENTIFIER
,
$token
->
getType
());
$this
->
assertEquals
(
's0m31d3nt1f13r'
,
$token
->
getValue
());
}
public
function
testScannerRecognizesIdentifierIncludingUnderscore
()
{
$scanner
=
new
Doctrine_Query_Scanner
(
'some_identifier'
);
$token
=
$scanner
->
scan
();
$this
->
assertEquals
(
Doctrine_Query_Token
::
T_IDENTIFIER
,
$token
->
getType
());
$this
->
assertEquals
(
'some_identifier'
,
$token
->
getValue
());
}
public
function
testScannerRecognizesDecimalInteger
()
{
$scanner
=
new
Doctrine_Query_Scanner
(
'1234'
);
$token
=
$scanner
->
scan
();
$this
->
assertEquals
(
Doctrine_Query_Token
::
T_NUMERIC
,
$token
->
getType
());
$this
->
assertEquals
(
1234
,
$token
->
getValue
());
}
public
function
testScannerRecognizesNegativeDecimalInteger
()
{
$scanner
=
new
Doctrine_Query_Scanner
(
'-123'
);
$token
=
$scanner
->
scan
();
$this
->
assertEquals
(
Doctrine_Query_Token
::
T_NUMERIC
,
$token
->
getType
());
$this
->
assertEquals
(
-
123
,
$token
->
getValue
());
}
public
function
testScannerRecognizesFloat
()
{
$scanner
=
new
Doctrine_Query_Scanner
(
'1.234'
);
$token
=
$scanner
->
scan
();
$this
->
assertEquals
(
Doctrine_Query_Token
::
T_NUMERIC
,
$token
->
getType
());
$this
->
assertEquals
(
1.234
,
$token
->
getValue
());
}
public
function
testScannerRecognizesFloatWithExponent
()
{
$scanner
=
new
Doctrine_Query_Scanner
(
'1.2e3'
);
$token
=
$scanner
->
scan
();
$this
->
assertEquals
(
Doctrine_Query_Token
::
T_NUMERIC
,
$token
->
getType
());
$this
->
assertEquals
(
1.2e3
,
$token
->
getValue
());
}
public
function
testScannerRecognizesFloatWithNegativeExponent
()
{
$scanner
=
new
Doctrine_Query_Scanner
(
'7E-10'
);
$token
=
$scanner
->
scan
();
$this
->
assertEquals
(
Doctrine_Query_Token
::
T_NUMERIC
,
$token
->
getType
());
$this
->
assertEquals
(
7E-10
,
$token
->
getValue
());
}
public
function
testScannerRecognizesStringContainingWhitespace
()
{
$scanner
=
new
Doctrine_Query_Scanner
(
"'This is a string.'"
);
$token
=
$scanner
->
scan
();
$this
->
assertEquals
(
Doctrine_Query_Token
::
T_STRING
,
$token
->
getType
());
$this
->
assertEquals
(
"'This is a string.'"
,
$token
->
getValue
());
}
public
function
testScannerRecognizesStringContainingSingleQuotes
()
{
$scanner
=
new
Doctrine_Query_Scanner
(
"'abc''defg'''"
);
$token
=
$scanner
->
scan
();
$this
->
assertEquals
(
Doctrine_Query_Token
::
T_STRING
,
$token
->
getType
());
$this
->
assertEquals
(
"'abc''defg'''"
,
$token
->
getValue
());
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment