diff options
Diffstat (limited to 'src/Fragments')
-rw-r--r-- | src/Fragments/ArrayFragment.php | 37 | ||||
-rw-r--r-- | src/Fragments/CallKeyword.php | 33 | ||||
-rw-r--r-- | src/Fragments/CreateDefFragment.php | 1 | ||||
-rw-r--r-- | src/Fragments/DataTypeFragment.php | 1 | ||||
-rw-r--r-- | src/Fragments/FieldDefFragment.php | 3 | ||||
-rw-r--r-- | src/Fragments/FieldFragment.php | 73 | ||||
-rw-r--r-- | src/Fragments/FieldListFragment.php (renamed from src/Fragments/SelectKeyword.php) | 18 | ||||
-rw-r--r-- | src/Fragments/FromKeyword.php | 83 | ||||
-rw-r--r-- | src/Fragments/IntoKeyword.php | 5 | ||||
-rw-r--r-- | src/Fragments/JoinKeyword.php | 1 | ||||
-rw-r--r-- | src/Fragments/KeyFragment.php | 1 | ||||
-rw-r--r-- | src/Fragments/LimitKeyword.php | 27 | ||||
-rw-r--r-- | src/Fragments/OptionsFragment.php | 32 | ||||
-rw-r--r-- | src/Fragments/OrderKeyword.php | 3 | ||||
-rw-r--r-- | src/Fragments/ParamDefFragment.php | 1 | ||||
-rw-r--r-- | src/Fragments/ReferencesKeyword.php | 5 | ||||
-rw-r--r-- | src/Fragments/RenameKeyword.php | 1 | ||||
-rw-r--r-- | src/Fragments/SetKeyword.php | 1 | ||||
-rw-r--r-- | src/Fragments/ValuesKeyword.php | 1 | ||||
-rw-r--r-- | src/Fragments/WhereKeyword.php | 51 |
20 files changed, 245 insertions, 133 deletions
diff --git a/src/Fragments/ArrayFragment.php b/src/Fragments/ArrayFragment.php index 7ed22ad..db12622 100644 --- a/src/Fragments/ArrayFragment.php +++ b/src/Fragments/ArrayFragment.php @@ -26,6 +26,13 @@ class ArrayFragment extends Fragment { /** + * The array that contains the unprocessed value of each token. + * + * @var array + */ + public $raw = array(); + + /** * The array that contains the processed value of each token. * * @var array @@ -33,11 +40,16 @@ class ArrayFragment extends Fragment public $values = array(); /** - * The array that contains the unprocessed value of each token. + * Constructor. * - * @var array + * @param array $raw The unprocessed values. + * @param array $values The processed values. */ - public $raw = array(); + public function __construct(array $raw = array(), array $values = array()) + { + $this->raw = $raw; + $this->values = $values; + } /** * @param Parser $parser The parser that serves as context. @@ -67,7 +79,6 @@ class ArrayFragment extends Fragment $state = 0; for (; $list->idx < $list->count; ++$list->idx) { - /** * Token parsed at this moment. * @var Token @@ -114,4 +125,22 @@ class ArrayFragment extends Fragment return $ret; } + + /** + * @param ArrayFragment $fragment The fragment to be built. + * + * @return string + */ + public static function build(ArrayFragment $fragment) + { + $values = array(); + if (!empty($fragment->raw)) { + $values = $fragment->raw; + } else { + foreach ($fragment->values as $value) { + $values[] = $value; + } + } + return '(' . implode(', ', $values) . ')'; + } } diff --git a/src/Fragments/CallKeyword.php b/src/Fragments/CallKeyword.php index ae3c467..3b8cc80 100644 --- a/src/Fragments/CallKeyword.php +++ b/src/Fragments/CallKeyword.php @@ -35,9 +35,25 @@ class CallKeyword extends Fragment /** * The list of parameters * - * @var array + * @var ArrayFragment */ - public $parameters = array(); + public $parameters; + + /** + * Constructor. + * + * @param string $name The name of the function to be called. + * @param array|ArrayFragment $parameters The parameters of this function. + */ + public function __construct($name = null, $parameters = null) + { + $this->name = $name; + if (is_array($parameters)) { + $this->parameters = new ArrayFragment($parameters); + } elseif ($parameters instanceof ArrayFragment) { + $this->parameters = $parameters; + } + } /** * @param Parser $parser The parser that serves as context. @@ -64,7 +80,6 @@ class CallKeyword extends Fragment $state = 0; for (; $list->idx < $list->count; ++$list->idx) { - /** * Token parsed at this moment. * @var Token @@ -86,7 +101,7 @@ class CallKeyword extends Fragment $state = 1; } elseif ($state === 1) { if (($token->type === Token::TYPE_OPERATOR) && ($token->value === '(')) { - $ret->parameters = ArrayFragment::parse($parser, $list)->values; + $ret->parameters = ArrayFragment::parse($parser, $list); } break; } @@ -95,4 +110,14 @@ class CallKeyword extends Fragment return $ret; } + + /** + * @param CallKeyword $fragment The fragment to be built. + * + * @return string + */ + public static function build(CallKeyword $fragment) + { + return $fragment->name . ArrayFragment::build($fragment->parameters); + } } diff --git a/src/Fragments/CreateDefFragment.php b/src/Fragments/CreateDefFragment.php index 403426c..933ea5e 100644 --- a/src/Fragments/CreateDefFragment.php +++ b/src/Fragments/CreateDefFragment.php @@ -92,7 +92,6 @@ class CreateDefFragment extends Fragment $ret = new CreateDefFragment(); for (; $list->idx < $list->count; ++$list->idx) { - /** * Token parsed at this moment. * @var Token diff --git a/src/Fragments/DataTypeFragment.php b/src/Fragments/DataTypeFragment.php index 2ad700a..0b9e1a8 100644 --- a/src/Fragments/DataTypeFragment.php +++ b/src/Fragments/DataTypeFragment.php @@ -94,7 +94,6 @@ class DataTypeFragment extends Fragment $state = 0; for (; $list->idx < $list->count; ++$list->idx) { - /** * Token parsed at this moment. * @var Token diff --git a/src/Fragments/FieldDefFragment.php b/src/Fragments/FieldDefFragment.php index d38eeda..6c5771e 100644 --- a/src/Fragments/FieldDefFragment.php +++ b/src/Fragments/FieldDefFragment.php @@ -129,7 +129,6 @@ class FieldDefFragment extends Fragment $state = 0; for (; $list->idx < $list->count; ++$list->idx) { - /** * Token parsed at this moment. * @var Token @@ -176,7 +175,7 @@ class FieldDefFragment extends Fragment --$list->idx; } $state = 5; - } else if ($state === 5) { + } elseif ($state === 5) { if ((!empty($expr->type)) || (!empty($expr->key))) { $ret[] = $expr; } diff --git a/src/Fragments/FieldFragment.php b/src/Fragments/FieldFragment.php index 5140324..8b0f0ef 100644 --- a/src/Fragments/FieldFragment.php +++ b/src/Fragments/FieldFragment.php @@ -75,6 +75,38 @@ class FieldFragment extends Fragment public $subquery; /** + * Constructor. + * + * Syntax: + * new FieldFragment('expr') + * new FieldFragment('expr', 'alias') + * new FieldFragment('database', 'table', 'column') + * new FieldFragment('database', 'table', 'column', 'alias') + * + * If the database, table or column name is not required, pass an empty + * string. + * + * @param string $database The name of the database or the the expression. + * the the expression. + * @param string $table The name of the table or the alias of the expression. + * the alias of the expression. + * @param string $column The name of the column. + * @param string $alias The name of the alias. + */ + public function __construct($database = null, $table = null, $column = null, $alias = null) + { + if (($column === null) && ($alias === null)) { + $this->expr = $database; // case 1 + $this->alias = $table; // case 2 + } else { + $this->database = $database; // case 3 + $this->table = $table; // case 3 + $this->column = $column; // case 3 + $this->alias = $alias; // case 4 + } + } + + /** * @param Parser $parser The parser that serves as context. * @param TokensList $list The list of tokens that are being parsed. * @param array $options Parameters for parsing. @@ -120,7 +152,6 @@ class FieldFragment extends Fragment $prev = null; for (; $list->idx < $list->count; ++$list->idx) { - /** * Token parsed at this moment. * @var Token @@ -150,8 +181,10 @@ class FieldFragment extends Fragment $alias = 2; continue; } - break; - } else if ($prev === true) { + if (!($token->flags & Token::FLAG_KEYWORD_FUNCTION)) { + break; + } + } elseif ($prev === true) { if ((empty($ret->subquery) && (!empty(Parser::$STATEMENT_PARSERS[$token->value])))) { // A `(` was previously found and this keyword is the // beginning of a statement, so this is a subquery. @@ -236,7 +269,7 @@ class FieldFragment extends Fragment if (($token->type === Token::TYPE_KEYWORD) && ($token->flags & Token::FLAG_KEYWORD_FUNCTION)) { $prev = strtoupper($token->value); - } else if (($token->type === Token::TYPE_OPERATOR) || ($token->value === '(')) { + } elseif (($token->type === Token::TYPE_OPERATOR) || ($token->value === '(')) { $prev = true; } else { $prev = null; @@ -258,4 +291,36 @@ class FieldFragment extends Fragment --$list->idx; return $ret; } + + /** + * @param FieldFragment $fragment The fragment to be built. + * + * @return string + */ + public static function build($fragment) + { + $ret = ''; + + if (!empty($fragment->expr)) { + $ret = $fragment->expr; + } else { + $fields = array(); + if (!empty($fragment->database)) { + $fields[] = $fragment->database; + } + if (!empty($fragment->table)) { + $fields[] = $fragment->table; + } + if (!empty($fragment->column)) { + $fields[] = $fragment->column; + } + $ret = implode('.', $fields); + } + + if (!empty($fragment->alias)) { + $ret .= ' AS ' . $fragment->alias; + } + + return $ret; + } } diff --git a/src/Fragments/SelectKeyword.php b/src/Fragments/FieldListFragment.php index 5cf4719..cc769e0 100644 --- a/src/Fragments/SelectKeyword.php +++ b/src/Fragments/FieldListFragment.php @@ -1,7 +1,7 @@ <?php /** - * `SELECT` keyword parser. + * Parses a a list of fields delimited by a single comma. * * @package SqlParser * @subpackage Fragments @@ -14,7 +14,7 @@ use SqlParser\Token; use SqlParser\TokensList; /** - * `SELECT` keyword parser. + * Parses a a list of fields delimited by a single comma. * * @category Keywords * @package SqlParser @@ -22,7 +22,7 @@ use SqlParser\TokensList; * @author Dan Ungureanu <udan1107@gmail.com> * @license http://opensource.org/licenses/GPL-2.0 GNU Public License */ -class SelectKeyword extends Fragment +class FieldListFragment extends Fragment { /** @@ -39,7 +39,6 @@ class SelectKeyword extends Fragment $expr = null; for (; $list->idx < $list->count; ++$list->idx) { - /** * Token parsed at this moment. * @var Token @@ -64,7 +63,7 @@ class SelectKeyword extends Fragment if (($token->type === Token::TYPE_OPERATOR) && ($token->value === ',')) { $ret[] = $expr; } else { - $expr = FieldFragment::parse($parser, $list); + $expr = FieldFragment::parse($parser, $list, $options); if ($expr === null) { break; } @@ -80,4 +79,13 @@ class SelectKeyword extends Fragment --$list->idx; return $ret; } + + public static function build($fragment) + { + $ret = array(); + foreach ($fragment as $frag) { + $ret[] = $frag::build($frag); + } + return implode($ret, ', '); + } } diff --git a/src/Fragments/FromKeyword.php b/src/Fragments/FromKeyword.php deleted file mode 100644 index 6fbf0ba..0000000 --- a/src/Fragments/FromKeyword.php +++ /dev/null @@ -1,83 +0,0 @@ -<?php - -/** - * `FROM` keyword parser. - * - * @package SqlParser - * @subpackage Fragments - */ -namespace SqlParser\Fragments; - -use SqlParser\Fragment; -use SqlParser\Parser; -use SqlParser\Token; -use SqlParser\TokensList; - -/** - * `FROM` keyword parser. - * - * @category Keywords - * @package SqlParser - * @subpackage Fragments - * @author Dan Ungureanu <udan1107@gmail.com> - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License - */ -class FromKeyword extends Fragment -{ - - /** - * @param Parser $parser The parser that serves as context. - * @param TokensList $list The list of tokens that are being parsed. - * @param array $options Parameters for parsing. - * - * @return FieldFragment[] - */ - public static function parse(Parser $parser, TokensList $list, array $options = array()) - { - $ret = array(); - - $expr = new FieldFragment(); - - for (; $list->idx < $list->count; ++$list->idx) { - - /** - * Token parsed at this moment. - * @var Token - */ - $token = $list->tokens[$list->idx]; - - // End of statement. - if ($token->type === Token::TYPE_DELIMITER) { - break; - } - - // Skipping whitespaces and comments. - if (($token->type === Token::TYPE_WHITESPACE) || ($token->type === Token::TYPE_COMMENT)) { - continue; - } - - // No keyword is expected. - if (($token->type === Token::TYPE_KEYWORD) && ($token->flags & Token::FLAG_KEYWORD_RESERVED)) { - break; - } - - if (($token->type === Token::TYPE_OPERATOR) && ($token->value === ',')) { - $ret[] = $expr; - } else { - $expr = FieldFragment::parse($parser, $list, array('skipColumn' => true)); - if ($expr === null) { - break; - } - } - - } - - // Last iteration was not saved. - if ($expr !== null) { - $ret[] = $expr; - } - - --$list->idx; - return $ret; - } -} diff --git a/src/Fragments/IntoKeyword.php b/src/Fragments/IntoKeyword.php index 558b3e6..0b51531 100644 --- a/src/Fragments/IntoKeyword.php +++ b/src/Fragments/IntoKeyword.php @@ -74,7 +74,6 @@ class IntoKeyword extends Fragment $state = 0; for (; $list->idx < $list->count; ++$list->idx) { - /** * Token parsed at this moment. * @var Token @@ -105,13 +104,13 @@ class IntoKeyword extends Fragment if ($state === 0) { $ret->name = $token->value; $state = 1; - } else if ($state === 1) { + } elseif ($state === 1) { if (($token->type === Token::TYPE_OPERATOR) && ($token->value === '(')) { $ret->fields = ArrayFragment::parse($parser, $list)->values; ++$list->idx; } break; - } else if ($state === 2) { + } elseif ($state === 2) { $ret->name = $token->value; ++$list->idx; break; diff --git a/src/Fragments/JoinKeyword.php b/src/Fragments/JoinKeyword.php index 011bd4d..f8e1a57 100644 --- a/src/Fragments/JoinKeyword.php +++ b/src/Fragments/JoinKeyword.php @@ -66,7 +66,6 @@ class JoinKeyword extends Fragment $state = 0; for (; $list->idx < $list->count; ++$list->idx) { - /** * Token parsed at this moment. * @var Token diff --git a/src/Fragments/KeyFragment.php b/src/Fragments/KeyFragment.php index 4a71857..d84c9f6 100644 --- a/src/Fragments/KeyFragment.php +++ b/src/Fragments/KeyFragment.php @@ -95,7 +95,6 @@ class KeyFragment extends Fragment $state = 0; for (; $list->idx < $list->count; ++$list->idx) { - /** * Token parsed at this moment. * @var Token diff --git a/src/Fragments/LimitKeyword.php b/src/Fragments/LimitKeyword.php index a23eb4c..af8d92d 100644 --- a/src/Fragments/LimitKeyword.php +++ b/src/Fragments/LimitKeyword.php @@ -40,6 +40,18 @@ class LimitKeyword extends Fragment public $rowCount; /** + * Constructor. + * + * @param int $rowCount The row count. + * @param int $offset The offset. + */ + public function __construct($rowCount = null, $offset = null) + { + $this->rowCount = $rowCount; + $this->offset = $offset; + } + + /** * @param Parser $parser The parser that serves as context. * @param TokensList $list The list of tokens that are being parsed. * @param array $options Parameters for parsing. @@ -53,7 +65,6 @@ class LimitKeyword extends Fragment $offset = false; for (; $list->idx < $list->count; ++$list->idx) { - /** * Token parsed at this moment. * @var Token @@ -103,4 +114,18 @@ class LimitKeyword extends Fragment --$list->idx; return $ret; } + + /** + * @param LimitKeyword $fragment The fragment to be built. + * + * @return string + */ + public static function build($fragment) + { + if (empty($fragment->offset)) { + return $fragment->rowCount; + } else { + return $fragment->offset . ', ' . $fragment->rowCount; + } + } } diff --git a/src/Fragments/OptionsFragment.php b/src/Fragments/OptionsFragment.php index 54d4857..16459cc 100644 --- a/src/Fragments/OptionsFragment.php +++ b/src/Fragments/OptionsFragment.php @@ -33,6 +33,17 @@ class OptionsFragment extends Fragment public $options = array(); /** + * Constructor. + * + * @param array $options The array of options. Options that have a value + * must be an array with two keys 'name' and 'value'. + */ + public function __construct(array $options = array()) + { + $this->options = $options; + } + + /** * @param Parser $parser The parser that serves as context. * @param TokensList $list The list of tokens that are being parsed. * @param array $options Parameters for parsing. @@ -59,7 +70,6 @@ class OptionsFragment extends Fragment $brackets = 0; for (; $list->idx < $list->count; ++$list->idx) { - /** * Token parsed at this moment. * @var Token @@ -128,6 +138,24 @@ class OptionsFragment extends Fragment } /** + * @param OptionsFragment $fragment The fragment to be built. + * + * @return string + */ + public static function build(OptionsFragment $fragment) + { + $options = array(); + foreach ($fragment->options as $option) { + if (is_array($option)) { + $options[] = $option['name'] . '=' . $option['value']; + } else { + $options[] = $option; + } + } + return implode(' ', $options); + } + + /** * Checks if it has the specified option and returns it value or true. * * @param string $key The key to be checked. @@ -158,7 +186,7 @@ class OptionsFragment extends Fragment { if (is_array($options)) { $this->options = array_merge_recursive($this->options, $options); - } else if ($options instanceof OptionsFragment) { + } elseif ($options instanceof OptionsFragment) { $this->options = array_merge_recursive($this->options, $options->options); } } diff --git a/src/Fragments/OrderKeyword.php b/src/Fragments/OrderKeyword.php index 5194208..7a76084 100644 --- a/src/Fragments/OrderKeyword.php +++ b/src/Fragments/OrderKeyword.php @@ -67,7 +67,6 @@ class OrderKeyword extends Fragment $state = 0; for (; $list->idx < $list->count; ++$list->idx) { - /** * Token parsed at this moment. * @var Token @@ -90,7 +89,7 @@ class OrderKeyword extends Fragment } elseif ($state === 1) { if (($token->type === Token::TYPE_KEYWORD) && (($token->value === 'ASC') || ($token->value === 'DESC'))) { $expr->type = $token->value; - } else if (($token->type === Token::TYPE_OPERATOR) && ($token->value === ',')) { + } elseif (($token->type === Token::TYPE_OPERATOR) && ($token->value === ',')) { if (!empty($expr->field)) { $ret[] = $expr; } diff --git a/src/Fragments/ParamDefFragment.php b/src/Fragments/ParamDefFragment.php index a512596..583c3ab 100644 --- a/src/Fragments/ParamDefFragment.php +++ b/src/Fragments/ParamDefFragment.php @@ -80,7 +80,6 @@ class ParamDefFragment extends Fragment $state = 0; for (; $list->idx < $list->count; ++$list->idx) { - /** * Token parsed at this moment. * @var Token diff --git a/src/Fragments/ReferencesKeyword.php b/src/Fragments/ReferencesKeyword.php index d4afd01..8de0233 100644 --- a/src/Fragments/ReferencesKeyword.php +++ b/src/Fragments/ReferencesKeyword.php @@ -84,7 +84,6 @@ class ReferencesKeyword extends Fragment $state = 0; for (; $list->idx < $list->count; ++$list->idx) { - /** * Token parsed at this moment. * @var Token @@ -104,10 +103,10 @@ class ReferencesKeyword extends Fragment if ($state === 0) { $ret->table = $token->value; $state = 1; - } else if ($state === 1) { + } elseif ($state === 1) { $ret->columns = ArrayFragment::parse($parser, $list)->values; $state = 2; - } else if ($state === 2) { + } elseif ($state === 2) { $ret->options = OptionsFragment::parse($parser, $list, static::$REFERENCES_OPTIONS); ++$list->idx; break; diff --git a/src/Fragments/RenameKeyword.php b/src/Fragments/RenameKeyword.php index 980ad7b..077982a 100644 --- a/src/Fragments/RenameKeyword.php +++ b/src/Fragments/RenameKeyword.php @@ -71,7 +71,6 @@ class RenameKeyword extends Fragment $state = 0; for (; $list->idx < $list->count; ++$list->idx) { - /** * Token parsed at this moment. * @var Token diff --git a/src/Fragments/SetKeyword.php b/src/Fragments/SetKeyword.php index 547768c..bced45f 100644 --- a/src/Fragments/SetKeyword.php +++ b/src/Fragments/SetKeyword.php @@ -67,7 +67,6 @@ class SetKeyword extends Fragment $state = 0; for (; $list->idx < $list->count; ++$list->idx) { - /** * Token parsed at this moment. * @var Token diff --git a/src/Fragments/ValuesKeyword.php b/src/Fragments/ValuesKeyword.php index 6977f68..c867551 100644 --- a/src/Fragments/ValuesKeyword.php +++ b/src/Fragments/ValuesKeyword.php @@ -65,7 +65,6 @@ class ValuesKeyword extends Fragment $state = 0; for (; $list->idx < $list->count; ++$list->idx) { - /** * Token parsed at this moment. * @var Token diff --git a/src/Fragments/WhereKeyword.php b/src/Fragments/WhereKeyword.php index 1b36cc8..d2143f3 100644 --- a/src/Fragments/WhereKeyword.php +++ b/src/Fragments/WhereKeyword.php @@ -47,6 +47,16 @@ class WhereKeyword extends Fragment public $condition; /** + * Constructor. + * + * @param string $condition The condition or the operator. + */ + public function __construct($condition = null) + { + $this->condition = trim($condition); + } + + /** * @param Parser $parser The parser that serves as context. * @param TokensList $list The list of tokens that are being parsed. * @param array $options Parameters for parsing. @@ -57,10 +67,13 @@ class WhereKeyword extends Fragment { $ret = array(); - $expr = new WhereKeyword(); + /** + * The condition that was parsed so far. + * @var string + */ + $condition = ''; for (; $list->idx < $list->count; ++$list->idx) { - /** * Token parsed at this moment. * @var Token @@ -73,23 +86,23 @@ class WhereKeyword extends Fragment } // Skipping whitespaces and comments. - if (($token->type === Token::TYPE_WHITESPACE) || ($token->type === Token::TYPE_COMMENT)) { + if ($token->type === Token::TYPE_COMMENT) { continue; } // Conditions are delimited by logical operators. if (in_array($token->value, static::$OPERATORS, true)) { - if (!empty($expr->condition)) { - $ret[] = $expr; + if (!empty(trim($condition))) { + // Adding the condition that is delimited by this operator. + $ret[] = new WhereKeyword($condition); + $condition = ''; } - $expr = new WhereKeyword(); + // Adding the operator. + $expr = new WhereKeyword($token->value); $expr->isOperator = true; - $expr->condition = $token->value; $ret[] = $expr; - $expr = new WhereKeyword(); - continue; } @@ -98,16 +111,30 @@ class WhereKeyword extends Fragment break; } - $expr->condition .= $token->token; + $condition .= $token->token; } // Last iteration was not processed. - if (!empty($expr->condition)) { - $ret[] = $expr; + if (!empty(trim($condition))) { + $ret[] = new WhereKeyword($condition); } --$list->idx; return $ret; } + + /** + * @param WhereKeyword $fragment The fragment to be built. + * + * @return string + */ + public static function build($fragment) + { + $conditions = array(); + foreach ($fragment as $f) { + $conditions[] = $f->condition; + } + return implode(' ', $conditions); + } } |