diff --git a/libraries/Tracker.php b/libraries/Tracker.php index 0338384bd9..c2003a160e 100644 --- a/libraries/Tracker.php +++ b/libraries/Tracker.php @@ -616,212 +616,130 @@ class Tracker // $parsed_sql = PMA_SQP_parse($query); // $sql_info = PMA_SQP_analyze($parsed_sql); - $query = str_replace("\n", " ", $query); - $query = str_replace("\r", " ", $query); + $parser = new \SqlParser\Parser($query); - $query = trim($query); - $query = trim($query, ' -'); - - $tokens = explode(" ", $query); - foreach ($tokens as $key => $value) { - $tokens[$key] = mb_strtoupper($value); - } + $tokens = $parser->list->tokens; // Parse USE statement, need it for SQL dump imports - if (mb_substr($query, 0, 4) == 'USE ') { - $prefix = explode('USE ', $query); - $GLOBALS['db'] = self::getTableName($prefix[1]); + if ($tokens[0]->value == 'USE') { + $GLOBALS['db'] = $tokens[2]->value; } - /* - * DDL statements - */ + $result = array(); - $result = array(); - $result['type'] = 'DDL'; + if (!empty($parser->statements)) { + $statement = $parser->statements[0]; + $options = isset($statement->options) ? $statement->options->options : null; - // Parse CREATE VIEW statement - if (in_array('CREATE', $tokens) == true - && in_array('VIEW', $tokens) == true - && in_array('AS', $tokens) == true - ) { - $result['identifier'] = 'CREATE VIEW'; + /* + * DDL statements + */ + $result['type'] = 'DDL'; - $index = array_search('VIEW', $tokens); + // Parse CREATE statement + if ($statement instanceof \SqlParser\Statements\CreateStatement) { + if (empty($options) || !isset($options[6])) { + return $result; + } - $result['tablename'] = mb_strtolower( - self::getTableName($tokens[$index + 1]) - ); - } + if ($options[6] == 'VIEW' || $options[6] == 'TABLE') { + $result['identifier'] = 'CREATE ' . $options[6]; + $result['tablename'] = $statement->name->table ; + } elseif ($options[6] == 'DATABASE') { + $result['identifier'] = 'CREATE DATABASE' ; + $result['tablename'] = '' ; - // Parse ALTER VIEW statement - if (in_array('ALTER', $tokens) == true - && in_array('VIEW', $tokens) == true - && in_array('AS', $tokens) == true - && ! isset($result['identifier']) - ) { - $result['identifier'] = 'ALTER VIEW'; + // In case of CREATE DATABASE, table field of the CreateStatement is actually name of the database + $GLOBALS['db'] = $statement->name->table; + } elseif ($options[6] == 'INDEX' + || $options[6] == 'UNIQUE INDEX' + || $options[6] == 'FULLTEXT INDEX' + || $options[6] == 'SPATIAL INDEX' + ){ + $result['identifier'] = 'CREATE INDEX'; - $index = array_search('VIEW', $tokens); + // In case of CREATE INDEX, we have to get the table name from body of the statement + $result['tablename'] = $statement->body[3]->value == '.' ? $statement->body[4]->value + : $statement->body[2]->value ; + } + } - $result['tablename'] = mb_strtolower( - self::getTableName($tokens[$index + 1]) - ); - } + // Parse ALTER statement + elseif ($statement instanceof \SqlParser\Statements\AlterStatement) { + if (empty($options) || !isset($options[3])) { + return $result; + } - // Parse DROP VIEW statement - if (! isset($result['identifier']) - && substr($query, 0, 10) == 'DROP VIEW ' - ) { - $result['identifier'] = 'DROP VIEW'; + if ($options[3] == 'VIEW' || $options[3] == 'TABLE') { + $result['identifier'] = 'ALTER ' . $options[3] ; + $result['tablename'] = $statement->table->table ; + } elseif ($options[3] == 'DATABASE') { + $result['identifier'] = 'ALTER DATABASE' ; + $result['tablename'] = '' ; - $prefix = explode('DROP VIEW ', $query); - $str = str_replace('IF EXISTS', '', $prefix[1]); - $result['tablename'] = self::getTableName($str); - } + $GLOBALS['db'] = $statement->table->table ; + } + } - // Parse CREATE DATABASE statement - if (! isset($result['identifier']) - && substr($query, 0, 15) == 'CREATE DATABASE' - ) { - $result['identifier'] = 'CREATE DATABASE'; - $str = str_replace('CREATE DATABASE', '', $query); - $str = str_replace('IF NOT EXISTS', '', $str); + // Parse DROP statement + elseif ($statement instanceof \SqlParser\Statements\DropStatement) { + if (empty($options) || !isset($options[1])) { + return $result; + } - $prefix = explode('DEFAULT ', $str); + if ($options[1] == 'VIEW' || $options[1] == 'TABLE') { + $result['identifier'] = 'DROP ' . $options[1] ; + $result['tablename'] = $statement->fields[0]->table; + } elseif ($options[1] == 'DATABASE') { + $result['identifier'] = 'DROP DATABASE' ; + $result['tablename'] = ''; - $result['tablename'] = ''; - $GLOBALS['db'] = self::getTableName($prefix[0]); - } + $GLOBALS['db'] = $statement->fields[0]->table; + } elseif ($options[1] == 'INDEX') { + $result['identifier'] = 'DROP INDEX' ; + $result['tablename'] = $statement->table->table; + } + } - // Parse ALTER DATABASE statement - if (! isset($result['identifier']) - && substr($query, 0, 14) == 'ALTER DATABASE' - ) { - $result['identifier'] = 'ALTER DATABASE'; - $result['tablename'] = ''; - } + // Prase RENAME statement + elseif ($statement instanceof \SqlParser\Statements\RenameStatement) { + $result['identifier'] = 'RENAME TABLE'; + $result['tablename'] = $statement->renames[0]->old->table; + $result['tablename_after_rename'] = $statement->renames[0]->new->table; + } - // Parse DROP DATABASE statement - if (! isset($result['identifier']) - && substr($query, 0, 13) == 'DROP DATABASE' - ) { - $result['identifier'] = 'DROP DATABASE'; - $str = str_replace('DROP DATABASE', '', $query); - $str = str_replace('IF EXISTS', '', $str); - $GLOBALS['db'] = self::getTableName($str); - $result['tablename'] = ''; - } + if (isset($result['identifier'])) { + return $result ; + } - // Parse CREATE TABLE statement - if (! isset($result['identifier']) - && substr($query, 0, 12) == 'CREATE TABLE' - ) { - $result['identifier'] = 'CREATE TABLE'; - $query = str_replace('IF NOT EXISTS', '', $query); - $prefix = explode('CREATE TABLE ', $query); - $suffix = explode('(', $prefix[1]); - $result['tablename'] = self::getTableName($suffix[0]); - } + /* + * DML statements + */ + $result['type'] = 'DML'; - // Parse ALTER TABLE statement - if (! isset($result['identifier']) - && substr($query, 0, 12) == 'ALTER TABLE ' - ) { - $result['identifier'] = 'ALTER TABLE'; + // Parse UPDATE statement + if ($statement instanceof \SqlParser\Statements\UpdateStatement) { + $result['identifier'] = 'UPDATE'; + $result['tablename'] = $statement->tables[0]->table; + } - $prefix = explode('ALTER TABLE ', $query); - $suffix = explode(' ', $prefix[1]); - $result['tablename'] = self::getTableName($suffix[0]); - } + // Parse INSERT INTO statement + if ($statement instanceof \SqlParser\Statements\InsertStatement) { + $result['identifier'] = 'INSERT'; + $result['tablename'] = $statement->into->dest->table; + } - // Parse DROP TABLE statement - if (! isset($result['identifier']) - && substr($query, 0, 11) == 'DROP TABLE ' - ) { - $result['identifier'] = 'DROP TABLE'; + // Parse DELETE statement + if ($statement instanceof \SqlParser\Statements\DeleteStatement) { + $result['identifier'] = 'DELETE'; + $result['tablename'] = $statement->from[0]->table; + } - $prefix = explode('DROP TABLE ', $query); - $str = str_replace('IF EXISTS', '', $prefix[1]); - $result['tablename'] = self::getTableName($str); - } - - // Parse CREATE INDEX statement - if (! isset($result['identifier']) - && (substr($query, 0, 12) == 'CREATE INDEX' - || substr($query, 0, 19) == 'CREATE UNIQUE INDEX' - || substr($query, 0, 20) == 'CREATE SPATIAL INDEX') - ) { - $result['identifier'] = 'CREATE INDEX'; - $prefix = explode('ON ', $query); - $suffix = explode('(', $prefix[1]); - $result['tablename'] = self::getTableName($suffix[0]); - } - - // Parse DROP INDEX statement - if (! isset($result['identifier']) - && substr($query, 0, 10) == 'DROP INDEX' - ) { - $result['identifier'] = 'DROP INDEX'; - $prefix = explode('ON ', $query); - $result['tablename'] = self::getTableName($prefix[1]); - } - - // Parse RENAME TABLE statement - if (! isset($result['identifier']) - && substr($query, 0, 13) == 'RENAME TABLE ' - ) { - $result['identifier'] = 'RENAME TABLE'; - $prefix = explode('RENAME TABLE ', $query); - $names = explode(' TO ', $prefix[1]); - $result['tablename'] = self::getTableName($names[0]); - $result["tablename_after_rename"] = self::getTableName($names[1]); - } - - /* - * DML statements - */ - - if (! isset($result['identifier'])) { - $result["type"] = 'DML'; - } - // Parse UPDATE statement - if (! isset($result['identifier']) - && substr($query, 0, 6) == 'UPDATE' - ) { - $result['identifier'] = 'UPDATE'; - $prefix = explode('UPDATE ', $query); - $suffix = explode(' ', $prefix[1]); - $result['tablename'] = self::getTableName($suffix[0]); - } - - // Parse INSERT INTO statement - if (! isset($result['identifier']) - && substr($query, 0, 11) == 'INSERT INTO' - ) { - $result['identifier'] = 'INSERT'; - $prefix = explode('INSERT INTO', $query); - $suffix = explode('(', $prefix[1]); - $result['tablename'] = self::getTableName($suffix[0]); - } - - // Parse DELETE statement - if (! isset($result['identifier']) - && substr($query, 0, 6) == 'DELETE' - ) { - $result['identifier'] = 'DELETE'; - $prefix = explode('FROM ', $query); - $suffix = explode(' ', $prefix[1]); - $result['tablename'] = self::getTableName($suffix[0]); - } - - // Parse TRUNCATE statement - if (! isset($result['identifier']) - && substr($query, 0, 8) == 'TRUNCATE' - ) { - $result['identifier'] = 'TRUNCATE'; - $prefix = explode('TRUNCATE', $query); - $result['tablename'] = self::getTableName($prefix[1]); + // Parse TRUNCATE statement + if ($statement instanceof \SqlParser\Statements\TruncateStatement) { + $result['identifier'] = 'TRUNCATE' ; + $result['tablename'] = $statement->table->table; + } } return $result; diff --git a/test/classes/TrackerTest.php b/test/classes/TrackerTest.php index e4c25c6c74..05846ef898 100644 --- a/test/classes/TrackerTest.php +++ b/test/classes/TrackerTest.php @@ -770,99 +770,99 @@ class TrackerTest extends PMATestCase ); */ $query[] = array( - "- CREATE VIEW v AS SELECT * FROM t;", + "CREATE VIEW v AS SELECT * FROM t;", "DDL", "CREATE VIEW", "v", ); $query[] = array( - "- ALTER VIEW db1.v AS SELECT col1, col2, col3, col4 FROM t", + "ALTER VIEW db1.v AS SELECT col1, col2, col3, col4 FROM t", "DDL", "ALTER VIEW", "v" ); $query[] = array( - "- DROP VIEW db1.v;", + "DROP VIEW db1.v;", "DDL", "DROP VIEW", "v" ); $query[] = array( - "- DROP VIEW IF EXISTS db1.v;", + "DROP VIEW IF EXISTS db1.v;", "DDL", "DROP VIEW", "v" ); $query[] = array( - "- CREATE DATABASE db1; -", + "CREATE DATABASE db1;", "DDL", "CREATE DATABASE", "", "db1" ); $query[] = array( - "- ALTER DATABASE db1; -", + "ALTER DATABASE db1;", "DDL", "ALTER DATABASE", "" ); $query[] = array( - "- DROP DATABASE db1; -", + "DROP DATABASE db1;", "DDL", "DROP DATABASE", "", "db1" ); $query[] = array( - "- CREATE TABLE db1.t1 (c1 INT);", + "CREATE TABLE db1.t1 (c1 INT);", "DDL", "CREATE TABLE", "t1" ); $query[] = array( - "- ALTER TABLE db1.t1 ADD c2 TEXT;", + "ALTER TABLE db1.t1 ADD c2 TEXT;", "DDL", "ALTER TABLE", "t1" ); $query[] = array( - "- DROP TABLE db1.t1", + "DROP TABLE db1.t1", "DDL", "DROP TABLE", "t1" ); $query[] = array( - "- DROP TABLE IF EXISTS db1.t1", + "DROP TABLE IF EXISTS db1.t1", "DDL", "DROP TABLE", "t1" ); $query[] = array( - "- CREATE INDEX ind ON db1.t1 (c2(10));", + "CREATE INDEX ind ON db1.t1 (c2(10));", "DDL", "CREATE INDEX", "t1" ); $query[] = array( - "- CREATE UNIQUE INDEX ind ON db1.t1 (c2(10));", + "CREATE UNIQUE INDEX ind ON db1.t1 (c2(10));", "DDL", "CREATE INDEX", "t1" ); $query[] = array( - "- CREATE SPATIAL INDEX ind ON db1.t1 (c2(10));", + "CREATE SPATIAL INDEX ind ON db1.t1 (c2(10));", "DDL", "CREATE INDEX", "t1" ); $query[] = array( - "- DROP INDEX ind ON db1.t1;", + "DROP INDEX ind ON db1.t1;", "DDL", "DROP INDEX", "t1" ); $query[] = array( - "- RENAME TABLE db1.t1 TO db1.t2", + "RENAME TABLE db1.t1 TO db1.t2", "DDL", "RENAME TABLE", "t1", @@ -870,25 +870,25 @@ class TrackerTest extends PMATestCase "t2" ); $query[] = array( - "- UPDATE db1.t1 SET a = 2", + "UPDATE db1.t1 SET a = 2", "DML", "UPDATE", "t1" ); $query[] = array( - "- INSERT INTO db1.t1 (a, b, c) VALUES(1, 2, 3)", + "INSERT INTO db1.t1 (a, b, c) VALUES(1, 2, 3)", "DML", "INSERT", "t1" ); $query[] = array( - "- DELETE FROM db1.t1", + "DELETE FROM db1.t1", "DML", "DELETE", "t1" ); $query[] = array( - "- TRUNCATE db1.t1", + "TRUNCATE db1.t1", "DML", "TRUNCATE", "t1"