diff options
author | Dan Ungureanu <udan1107@gmail.com> | 2015-07-23 00:14:58 +0300 |
---|---|---|
committer | Dan Ungureanu <udan1107@gmail.com> | 2015-07-23 00:14:58 +0300 |
commit | 367981588c47f5dc2f3c8cffa9b0038f5d807e65 (patch) | |
tree | b8d4feb3748021a2cb74d3a05d6e58835762b728 | |
parent | e1b91ed012ca2701ec0c129c44906bf4d282e99c (diff) | |
download | sql-parser-367981588c47f5dc2f3c8cffa9b0038f5d807e65.zip sql-parser-367981588c47f5dc2f3c8cffa9b0038f5d807e65.tar.gz sql-parser-367981588c47f5dc2f3c8cffa9b0038f5d807e65.tar.bz2 |
Implemented support for transactions.
-rw-r--r-- | src/Component.php | 4 | ||||
-rw-r--r-- | src/Components/SetOperation.php | 18 | ||||
-rw-r--r-- | src/Contexts/ContextMySql50000.php | 11 | ||||
-rw-r--r-- | src/Contexts/ContextMySql50100.php | 11 | ||||
-rw-r--r-- | src/Contexts/ContextMySql50500.php | 11 | ||||
-rw-r--r-- | src/Contexts/ContextMySql50600.php | 11 | ||||
-rw-r--r-- | src/Contexts/ContextMySql50700.php | 11 | ||||
-rw-r--r-- | src/Parser.php | 92 | ||||
-rw-r--r-- | tests/Components/FragmentTest.php | 19 |
9 files changed, 133 insertions, 55 deletions
diff --git a/src/Component.php b/src/Component.php index 296ce77..3aa5506 100644 --- a/src/Component.php +++ b/src/Component.php @@ -39,7 +39,7 @@ abstract class Component ) { // This method should be abstract, but it can't be both static and // abstract. - return null; + throw new \Exception('Not implemented yet.'); } /** @@ -56,7 +56,7 @@ abstract class Component { // This method should be abstract, but it can't be both static and // abstract. - return null; + throw new \Exception('Not implemented yet.'); } /** diff --git a/src/Components/SetOperation.php b/src/Components/SetOperation.php index a9e8ba1..fc05cf7 100644 --- a/src/Components/SetOperation.php +++ b/src/Components/SetOperation.php @@ -117,4 +117,22 @@ class SetOperation extends Component --$list->idx; return $ret; } + + /** + * @param SetOperation|SetOperation[] $component The component to be built. + * + * @return string + */ + public static function build($component) + { + if (is_array($component)) { + $ret = array(); + foreach ($component as $c) { + $ret[] = static::build($c); + } + return implode(", ", $ret); + } else { + return $component->column . ' = ' . $component->value; + } + } } diff --git a/src/Contexts/ContextMySql50000.php b/src/Contexts/ContextMySql50000.php index 5069b91..ed86320 100644 --- a/src/Contexts/ContextMySql50000.php +++ b/src/Contexts/ContextMySql50000.php @@ -144,15 +144,18 @@ class ContextMySql50000 extends Context 'SQL_CALC_FOUND_ROWS' => 3, 'GROUP BY' => 7, 'NOT NULL' => 7, 'ORDER BY' => 7, 'SET NULL' => 7, - 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7, 'NO ACTION' => 7, - 'ON DELETE' => 7, 'ON UPDATE' => 7, - 'INNER JOIN' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7, - 'FOR EACH ROW' => 7, 'SQL SECURITY' => 7, + 'AND CHAIN' => 7, 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7, + 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7, + 'INNER JOIN' => 7, 'NO RELEASE' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7, + 'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'SQL SECURITY' => 7, 'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7, 'DATA DIRECTORY' => 7, 'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'INDEX DIRECTORY' => 7, 'GENERATED ALWAYS' => 7, + 'START TRANSACTION' => 7, + 'SELECT TRANSACTION' => 7, 'DEFAULT CHARACTER SET' => 7, + 'WITH CONSISTENT SNAPSHOT' => 7, 'XML' => 9, 'ENUM' => 9, 'TEXT' => 9, diff --git a/src/Contexts/ContextMySql50100.php b/src/Contexts/ContextMySql50100.php index ad39eb7..c71ff6c 100644 --- a/src/Contexts/ContextMySql50100.php +++ b/src/Contexts/ContextMySql50100.php @@ -156,15 +156,18 @@ class ContextMySql50100 extends Context 'MASTER_SSL_VERIFY_SERVER_CERT' => 3, 'GROUP BY' => 7, 'NOT NULL' => 7, 'ORDER BY' => 7, 'SET NULL' => 7, - 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7, 'NO ACTION' => 7, - 'ON DELETE' => 7, 'ON UPDATE' => 7, - 'INNER JOIN' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7, - 'FOR EACH ROW' => 7, 'SQL SECURITY' => 7, + 'AND CHAIN' => 7, 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7, + 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7, + 'INNER JOIN' => 7, 'NO RELEASE' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7, + 'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'SQL SECURITY' => 7, 'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7, 'DATA DIRECTORY' => 7, 'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'INDEX DIRECTORY' => 7, 'GENERATED ALWAYS' => 7, + 'START TRANSACTION' => 7, + 'SELECT TRANSACTION' => 7, 'DEFAULT CHARACTER SET' => 7, + 'WITH CONSISTENT SNAPSHOT' => 7, 'XML' => 9, 'ENUM' => 9, 'TEXT' => 9, diff --git a/src/Contexts/ContextMySql50500.php b/src/Contexts/ContextMySql50500.php index c0074c7..6f6bb66 100644 --- a/src/Contexts/ContextMySql50500.php +++ b/src/Contexts/ContextMySql50500.php @@ -161,15 +161,18 @@ class ContextMySql50500 extends Context 'MASTER_SSL_VERIFY_SERVER_CERT' => 3, 'GROUP BY' => 7, 'NOT NULL' => 7, 'ORDER BY' => 7, 'SET NULL' => 7, - 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7, 'NO ACTION' => 7, - 'ON DELETE' => 7, 'ON UPDATE' => 7, - 'INNER JOIN' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7, - 'FOR EACH ROW' => 7, 'SQL SECURITY' => 7, + 'AND CHAIN' => 7, 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7, + 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7, + 'INNER JOIN' => 7, 'NO RELEASE' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7, + 'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'SQL SECURITY' => 7, 'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7, 'DATA DIRECTORY' => 7, 'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'INDEX DIRECTORY' => 7, 'GENERATED ALWAYS' => 7, + 'START TRANSACTION' => 7, + 'SELECT TRANSACTION' => 7, 'DEFAULT CHARACTER SET' => 7, + 'WITH CONSISTENT SNAPSHOT' => 7, 'XML' => 9, 'ENUM' => 9, 'TEXT' => 9, diff --git a/src/Contexts/ContextMySql50600.php b/src/Contexts/ContextMySql50600.php index 453d9e2..62b75ab 100644 --- a/src/Contexts/ContextMySql50600.php +++ b/src/Contexts/ContextMySql50600.php @@ -166,15 +166,18 @@ class ContextMySql50600 extends Context 'MASTER_SSL_VERIFY_SERVER_CERT' => 3, 'GROUP BY' => 7, 'NOT NULL' => 7, 'ORDER BY' => 7, 'SET NULL' => 7, - 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7, 'NO ACTION' => 7, - 'ON DELETE' => 7, 'ON UPDATE' => 7, - 'INNER JOIN' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7, - 'FOR EACH ROW' => 7, 'SQL SECURITY' => 7, + 'AND CHAIN' => 7, 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7, + 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7, + 'INNER JOIN' => 7, 'NO RELEASE' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7, + 'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'SQL SECURITY' => 7, 'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7, 'DATA DIRECTORY' => 7, 'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'INDEX DIRECTORY' => 7, 'GENERATED ALWAYS' => 7, + 'START TRANSACTION' => 7, + 'SELECT TRANSACTION' => 7, 'DEFAULT CHARACTER SET' => 7, + 'WITH CONSISTENT SNAPSHOT' => 7, 'XML' => 9, 'ENUM' => 9, 'TEXT' => 9, diff --git a/src/Contexts/ContextMySql50700.php b/src/Contexts/ContextMySql50700.php index 9946a26..8b0568b 100644 --- a/src/Contexts/ContextMySql50700.php +++ b/src/Contexts/ContextMySql50700.php @@ -174,15 +174,18 @@ class ContextMySql50700 extends Context 'MASTER_SSL_VERIFY_SERVER_CERT' => 3, 'GROUP BY' => 7, 'NOT NULL' => 7, 'ORDER BY' => 7, 'SET NULL' => 7, - 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7, 'NO ACTION' => 7, - 'ON DELETE' => 7, 'ON UPDATE' => 7, - 'INNER JOIN' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7, - 'FOR EACH ROW' => 7, 'SQL SECURITY' => 7, + 'AND CHAIN' => 7, 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7, + 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7, + 'INNER JOIN' => 7, 'NO RELEASE' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7, + 'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'SQL SECURITY' => 7, 'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7, 'DATA DIRECTORY' => 7, 'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'INDEX DIRECTORY' => 7, 'GENERATED ALWAYS' => 7, + 'START TRANSACTION' => 7, + 'SELECT TRANSACTION' => 7, 'DEFAULT CHARACTER SET' => 7, + 'WITH CONSISTENT SNAPSHOT' => 7, 'XML' => 9, 'ENUM' => 9, 'TEXT' => 9, diff --git a/src/Parser.php b/src/Parser.php index f00e442..2d23f6a 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -28,8 +28,9 @@ namespace { namespace SqlParser { - use SqlParser\Statements\SelectStatement; use SqlParser\Exceptions\ParserException; + use SqlParser\Statements\SelectStatement; + use SqlParser\Statements\TransactionStatement; /** * Takes multiple tokens (contained in a Lexer instance) as input and builds a @@ -50,47 +51,54 @@ namespace SqlParser { */ public static $STATEMENT_PARSERS = array( - 'EXPLAIN' => 'SqlParser\\Statements\\ExplainStatement', + 'EXPLAIN' => 'SqlParser\\Statements\\ExplainStatement', // Table Maintenance Statements // https://dev.mysql.com/doc/refman/5.7/en/table-maintenance-sql.html - 'ANALYZE' => 'SqlParser\\Statements\\AnalyzeStatement', - 'BACKUP' => 'SqlParser\\Statements\\BackupStatement', - 'CHECK' => 'SqlParser\\Statements\\CheckStatement', - 'CHECKSUM' => 'SqlParser\\Statements\\ChecksumStatement', - 'OPTIMIZE' => 'SqlParser\\Statements\\OptimizeStatement', - 'REPAIR' => 'SqlParser\\Statements\\RepairStatement', - 'RESTORE' => 'SqlParser\\Statements\\RestoreStatement', + 'ANALYZE' => 'SqlParser\\Statements\\AnalyzeStatement', + 'BACKUP' => 'SqlParser\\Statements\\BackupStatement', + 'CHECK' => 'SqlParser\\Statements\\CheckStatement', + 'CHECKSUM' => 'SqlParser\\Statements\\ChecksumStatement', + 'OPTIMIZE' => 'SqlParser\\Statements\\OptimizeStatement', + 'REPAIR' => 'SqlParser\\Statements\\RepairStatement', + 'RESTORE' => 'SqlParser\\Statements\\RestoreStatement', // Database Administration Statements // https://dev.mysql.com/doc/refman/5.7/en/sql-syntax-server-administration.html - 'SET' => '', - 'SHOW' => 'SqlParser\\Statements\\ShowStatement', + 'SET' => '', + 'SHOW' => 'SqlParser\\Statements\\ShowStatement', // Data Definition Statements. // https://dev.mysql.com/doc/refman/5.7/en/sql-syntax-data-definition.html - 'ALTER' => 'SqlParser\\Statements\\AlterStatement', - 'CREATE' => 'SqlParser\\Statements\\CreateStatement', - 'DROP' => 'SqlParser\\Statements\\DropStatement', - 'RENAME' => 'SqlParser\\Statements\\RenameStatement', - 'TRUNCATE' => 'SqlParser\\Statements\\TruncateStatement', + 'ALTER' => 'SqlParser\\Statements\\AlterStatement', + 'CREATE' => 'SqlParser\\Statements\\CreateStatement', + 'DROP' => 'SqlParser\\Statements\\DropStatement', + 'RENAME' => 'SqlParser\\Statements\\RenameStatement', + 'TRUNCATE' => 'SqlParser\\Statements\\TruncateStatement', // Data Manipulation Statements. // https://dev.mysql.com/doc/refman/5.7/en/sql-syntax-data-manipulation.html - 'CALL' => 'SqlParser\\Statements\\CallStatement', - 'DELETE' => 'SqlParser\\Statements\\DeleteStatement', - 'DO' => '', - 'HANDLER' => '', - 'INSERT' => 'SqlParser\\Statements\\InsertStatement', - 'LOAD' => '', - 'REPLACE' => 'SqlParser\\Statements\\ReplaceStatement', - 'SELECT' => 'SqlParser\\Statements\\SelectStatement', - 'UPDATE' => 'SqlParser\\Statements\\UpdateStatement', + 'CALL' => 'SqlParser\\Statements\\CallStatement', + 'DELETE' => 'SqlParser\\Statements\\DeleteStatement', + 'DO' => '', + 'HANDLER' => '', + 'INSERT' => 'SqlParser\\Statements\\InsertStatement', + 'LOAD' => '', + 'REPLACE' => 'SqlParser\\Statements\\ReplaceStatement', + 'SELECT' => 'SqlParser\\Statements\\SelectStatement', + 'UPDATE' => 'SqlParser\\Statements\\UpdateStatement', // Prepared Statements. // https://dev.mysql.com/doc/refman/5.7/en/sql-syntax-prepared-statements.html - 'PREPARE' => '', - 'EXECUTE' => '', + 'PREPARE' => '', + 'EXECUTE' => '', + + // Transactional and Locking Statements + // https://dev.mysql.com/doc/refman/5.7/en/commit.html + 'START TRANSACTION' => 'SqlParser\\Statements\\TransactionStatement', + 'BEGIN' => 'SqlParser\\Statements\\TransactionStatement', + 'COMMIT' => 'SqlParser\\Statements\\TransactionStatement', + 'ROLLBACK' => 'SqlParser\\Statements\\TransactionStatement', ); /** @@ -312,6 +320,13 @@ namespace SqlParser { { /** + * Last transaction. + * + * @var TransactionStatement + */ + $lastTransaction = null; + + /** * Last parsed statement. * @var Statement $lastStatement */ @@ -400,21 +415,40 @@ namespace SqlParser { $statement->last = $list->idx; $prevLastIdx = $list->idx; - // Finally, storing the statement. + // Handles unions. if (($inUnion) && ($lastStatement instanceof SelectStatement) && ($statement instanceof SelectStatement) ) { + /** * Last SELECT statement. * @var SelectStatement $lastStatement */ $lastStatement->union[] = $statement; $inUnion = false; + continue; + } + + // Handles transactions. + if ($statement instanceof TransactionStatement) { + if ($statement->type === TransactionStatement::TYPE_BEGIN) { + $lastTransaction = $statement; + $this->statements[] = $statement; + } elseif ($statement->type === TransactionStatement::TYPE_END) { + $lastTransaction->end = $statement; + $lastTransaction = null; + } + continue; + } + + // Finally, storing the statement. + if ($lastTransaction !== null) { + $lastTransaction->statements[] = $statement; } else { $this->statements[] = $statement; - $lastStatement = $statement; } + $lastStatement = $statement; } } diff --git a/tests/Components/FragmentTest.php b/tests/Components/FragmentTest.php index 64cc8b1..f8b27fa 100644 --- a/tests/Components/FragmentTest.php +++ b/tests/Components/FragmentTest.php @@ -5,16 +5,27 @@ namespace SqlParser\Tests\Parser; use SqlParser\Component; use SqlParser\Parser; use SqlParser\TokensList; -use SqlParser\Components\ArrayObj; use SqlParser\Tests\TestCase; class ComponentTest extends TestCase { - public function testDummy() + /** + * @expectedException \Exception + * @expectedExceptionMessage Not implemented yet. + */ + public function testParse() { - $this->assertEquals(null, Component::parse(new Parser(), new TokensList())); - $this->assertEquals(null, Component::build(new ArrayObj())); + Component::parse(new Parser(), new TokensList()); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage Not implemented yet. + */ + public function testBuild() + { + Component::build(null); } } |