summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Ungureanu <udan1107@gmail.com>2015-07-23 00:14:58 +0300
committerDan Ungureanu <udan1107@gmail.com>2015-07-23 00:14:58 +0300
commit367981588c47f5dc2f3c8cffa9b0038f5d807e65 (patch)
treeb8d4feb3748021a2cb74d3a05d6e58835762b728
parente1b91ed012ca2701ec0c129c44906bf4d282e99c (diff)
downloadsql-parser-367981588c47f5dc2f3c8cffa9b0038f5d807e65.zip
sql-parser-367981588c47f5dc2f3c8cffa9b0038f5d807e65.tar.gz
sql-parser-367981588c47f5dc2f3c8cffa9b0038f5d807e65.tar.bz2
Implemented support for transactions.
-rw-r--r--src/Component.php4
-rw-r--r--src/Components/SetOperation.php18
-rw-r--r--src/Contexts/ContextMySql50000.php11
-rw-r--r--src/Contexts/ContextMySql50100.php11
-rw-r--r--src/Contexts/ContextMySql50500.php11
-rw-r--r--src/Contexts/ContextMySql50600.php11
-rw-r--r--src/Contexts/ContextMySql50700.php11
-rw-r--r--src/Parser.php92
-rw-r--r--tests/Components/FragmentTest.php19
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);
}
}