diff options
Diffstat (limited to 'tests/Utils')
-rw-r--r-- | tests/Utils/MiscTest.php | 101 | ||||
-rw-r--r-- | tests/Utils/QueryTest.php | 328 | ||||
-rw-r--r-- | tests/Utils/RoutineTest.php | 196 | ||||
-rw-r--r-- | tests/Utils/TableTest.php | 181 |
4 files changed, 806 insertions, 0 deletions
diff --git a/tests/Utils/MiscTest.php b/tests/Utils/MiscTest.php new file mode 100644 index 0000000..4e04a60 --- /dev/null +++ b/tests/Utils/MiscTest.php @@ -0,0 +1,101 @@ +<?php + +namespace SqlParser\Tests\Utils; + +use SqlParser\Parser; +use SqlParser\Utils\Misc; + +use SqlParser\Tests\TestCase; + +class MiscTest extends TestCase +{ + + /** + * @dataProvider getAliasesProvider + */ + public function testGetAliases($query, $db, array $expected) + { + $parser = new Parser($query); + $statement = empty($parser->statements[0]) ? + null : $parser->statements[0]; + $this->assertEquals($expected, Misc::getAliases($statement, $db)); + } + + public function getAliasesProvider() + { + return array( + array( + 'select i.name as `n`,abcdef gh from qwerty i', + 'mydb', + array( + 'mydb' => array( + 'alias' => null, + 'tables' => array( + 'qwerty' => array( + 'alias' => 'i', + 'columns' => array( + 'name' => 'n', + 'abcdef' => 'gh' + ) + ) + ) + ) + ) + ), + array( + 'select film_id id,title from film', + 'sakila', + array( + 'sakila' => array( + 'alias' => null, + 'tables' => array( + 'film' => array( + 'alias' => null, + 'columns' => array( + 'film_id' => 'id' + ) + ) + ) + ) + ) + ), + array( + 'select `sakila`.`A`.`actor_id` as aid,`F`.`film_id` `fid`,' + . 'last_update updated from `sakila`.actor A join `film_actor` as ' + . '`F` on F.actor_id = A.`actor_id`', + 'sakila', + array( + 'sakila' => array( + 'alias' => null, + 'tables' => array( + 'film_actor' => array( + 'alias' => 'F', + 'columns' => array( + 'film_id' => 'fid', + 'last_update' => 'updated' + ) + ), + 'actor' => array( + 'alias'=> 'A', + 'columns' => array( + 'actor_id' => 'aid', + 'last_update' => 'updated' + ) + ) + ) + ) + ) + ), + array( + 'SELECT film_id FROM (SELECT * FROM film) as f;', + 'sakila', + array() + ), + array( + '', + null, + array() + ) + ); + } +} diff --git a/tests/Utils/QueryTest.php b/tests/Utils/QueryTest.php new file mode 100644 index 0000000..5bdd57f --- /dev/null +++ b/tests/Utils/QueryTest.php @@ -0,0 +1,328 @@ +<?php + +namespace SqlParser\Tests\Utils; + +use SqlParser\Parser; +use SqlParser\Utils\Query; + +use SqlParser\Tests\TestCase; + +class QueryTest extends TestCase +{ + + /** + * @dataProvider testGetFlagsProvider + */ + public function testGetFlags($query, $expected) + { + $parser = new Parser($query); + $this->assertEquals( + $expected, + Query::getFlags($parser->statements[0]) + ); + } + + public function testGetFlagsProvider() + { + return array( + array( + 'ALTER TABLE DROP col', + array( + 'reload' => true, + 'querytype' => 'ALTER' + ) + ), + array( + 'CALL test()', + array( + 'is_procedure' => true, + 'querytype' => 'CALL' + ) + ), + array( + 'CREATE TABLE tbl (id INT)', + array( + 'reload' => true, + 'querytype' => 'CREATE' + ) + ), + array( + 'CHECK TABLE tbl', + array( + 'is_maint' => true, + 'querytype' => 'CHECK' + ) + ), + array( + 'DELETE FROM tbl', + array( + 'is_affected' => true, + 'is_delete' => true, + 'querytype' => 'DELETE', + ), + ), + array( + 'DROP VIEW v', + array( + 'reload' => true, + 'querytype' => 'DROP' + ) + ), + array( + 'DROP DATABASE db', + array( + 'drop_database' => true, + 'reload' => true, + 'querytype' => 'DROP' + ) + ), + array( + 'EXPLAIN tbl', + array( + 'is_explain' => true, + 'querytype' => 'EXPLAIN' + ), + ), + array( + 'INSERT INTO tbl VALUES (1)', + array( + 'is_affected' => true, + 'is_insert' => true, + 'querytype' => 'INSERT' + ) + ), + array( + 'REPLACE INTO tbl VALUES (2)', + array( + 'is_affected' => true, + 'is_replace' => true, + 'is_insert' => true, + 'querytype' => 'REPLACE' + ) + ), + array( + 'SELECT 1', + array( + 'is_select' => true, + 'querytype' => 'SELECT' + ) + ), + array( + 'SELECT * FROM tbl', + array( + 'is_select' => true, + 'select_from' => true, + 'querytype' => 'SELECT' + ) + ), + array( + 'SELECT DISTINCT * FROM tbl LIMIT 0, 10 ORDER BY id', + array( + 'distinct' => true, + 'is_select' => true, + 'select_from' => true, + 'limit' => true, + 'order' => true, + 'querytype' => 'SELECT' + ) + ), + array( + 'SELECT * FROM actor GROUP BY actor_id', + array( + 'is_group' => true, + 'is_select' => true, + 'select_from' => true, + 'group' => true, + 'querytype' => 'SELECT' + ) + ), + array( + 'SELECT col1, col2 FROM table1 PROCEDURE ANALYSE(10, 2000);', + array( + 'is_analyse' => true, + 'is_select' => true, + 'select_from' => true, + 'querytype' => 'SELECT' + ) + ), + array( + 'SELECT * FROM tbl INTO OUTFILE "/tmp/export.txt"', + array( + 'is_export' => true, + 'is_select' => true, + 'select_from' => true, + 'querytype' => 'SELECT' + ) + ), + array( + 'SELECT COUNT(id), SUM(id) FROM tbl', + array( + 'is_count' => true, + 'is_func' => true, + 'is_select' => true, + 'select_from' => true, + 'querytype' => 'SELECT' + ) + ), + array( + 'SELECT (SELECT "foo")', + array( + 'is_select' => true, + 'is_subquery' => true, + 'querytype' => 'SELECT' + ) + ), + array( + 'SELECT * FROM customer HAVING store_id = 2;', + array( + 'is_select' => true, + 'select_from' => true, + 'is_group' => true, + 'having' => true, + 'querytype' => 'SELECT' + ) + ), + array( + 'SELECT * FROM table1 INNER JOIN table2 ON table1.id=table2.id;', + array( + 'is_select' => true, + 'select_from' => true, + 'join' => true, + 'querytype' => 'SELECT' + ) + ), + array( + 'SHOW CREATE TABLE tbl', + array( + 'is_show' => true, + 'querytype' => 'SHOW' + ) + ), + array( + 'UPDATE tbl SET id = 1', + array( + 'is_affected' => true, + 'querytype' => 'UPDATE' + ) + ), + array( + 'ANALYZE TABLE tbl', + array( + 'is_maint' => true, + 'querytype' => 'ANALYZE' + ) + ), + array( + 'CHECKSUM TABLE tbl', + array( + 'is_maint' => true, + 'querytype' => 'CHECKSUM' + ) + ), + array( + 'OPTIMIZE TABLE tbl', + array( + 'is_maint' => true, + 'querytype' => 'OPTIMIZE' + ) + ), + array( + 'REPAIR TABLE tbl', + array( + 'is_maint' => true, + 'querytype' => 'REPAIR' + ) + ), + array( + '(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10) ' . + 'UNION ' . + '(SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10);', + array( + 'is_select' => true, + 'select_from' => true, + 'limit' => true, + 'order' => true, + 'union' => true, + 'querytype' => 'SELECT' + ) + ), + ); + } + + public function testGetAll() + { + $query = 'SELECT *, actor.actor_id, sakila2.film.* + FROM sakila2.city, sakila2.film, actor'; + $parser = new Parser($query); + $this->assertEquals( + array_merge( + Query::getFlags($parser->statements[0], true), + array( + 'parser' => $parser, + 'statement' => $parser->statements[0], + 'select_expr' => array('*'), + 'select_tables' => array( + array('actor', null), + array('film', 'sakila2') + ) + ) + ), + Query::getAll($query) + ); + + $query = 'SELECT * FROM sakila.actor, film'; + $parser = new Parser($query); + $this->assertEquals( + array_merge( + Query::getFlags($parser->statements[0], true), + array( + 'parser' => $parser, + 'statement' => $parser->statements[0], + 'select_expr' => array('*'), + 'select_tables' => array( + array('actor', 'sakila'), + array('film', null) + ) + ) + ), + Query::getAll($query) + ); + } + + public function testGetAllEmpty() + { + $this->assertEquals(array(), Query::getAll('')); + } + + public function testGetClauseType() + { + $this->assertEquals('LIMIT', Query::getClauseType(' LIMIT 0, 10 ')); + } + + public function testReplaceClause() + { + $parser = new Parser('SELECT *, (SELECT 1) FROM film LIMIT 0, 10;'); + $this->assertEquals( + 'SELECT *, (SELECT 1) FROM film WHERE film_id > 0 LIMIT 0, 10', + Query::replaceClause( + $parser->statements[0], + $parser->list, + 'WHERE film_id > 0' + ) + ); + } + + public function testReplaceClauseOnlyKeyword() + { + $parser = new Parser('SELECT *, (SELECT 1) FROM film LIMIT 0, 10'); + $this->assertEquals( + ' SELECT SQL_CALC_FOUND_ROWS *, (SELECT 1) FROM film LIMIT 0, 10', + Query::replaceClause( + $parser->statements[0], + $parser->list, + 'SELECT SQL_CALC_FOUND_ROWS', + true + ) + ); + } +} diff --git a/tests/Utils/RoutineTest.php b/tests/Utils/RoutineTest.php new file mode 100644 index 0000000..51f558f --- /dev/null +++ b/tests/Utils/RoutineTest.php @@ -0,0 +1,196 @@ +<?php + +namespace SqlParser\Tests\Utils; + +use SqlParser\Parser; +use SqlParser\Utils\Routine; + +use SqlParser\Tests\TestCase; + +class RoutineTest extends TestCase +{ + + /** + * @dataProvider getReturnTypeProvider + */ + public function testGetReturnType($def, array $expected) + { + $this->assertEquals($expected, Routine::getReturnType($def)); + } + + public function getReturnTypeProvider() + { + return array( + array('', array('', '', '', '', '')), + array('TEXT', array('', '', 'TEXT', '', '')), + array('INT(20)', array('', '', 'INT', '20', '')), + array( + 'INT UNSIGNED', + array('', '', 'INT', '', 'UNSIGNED') + ), + array( + 'VARCHAR(1) CHARSET utf8', + array('', '', 'VARCHAR', '1', 'utf8') + ), + array( + 'ENUM(\'a\', \'b\') CHARSET latin1', + array('', '', 'ENUM', '\'a\',\'b\'', 'latin1') + ), + array( + 'DECIMAL(5,2) UNSIGNED ZEROFILL', + array('', '', 'DECIMAL', '5,2', 'UNSIGNED ZEROFILL') + ), + array( + 'SET(\'test\'\'esc"\', \'more\\\'esc\')', + array( + '', '', 'SET', '\'test\'\'esc"\',\'more\\\'esc\'', '' + ) + ) + ); + } + + /** + * @dataProvider getParameterProvider + */ + public function testGetParameter($def, array $expected) + { + $this->assertEquals($expected, Routine::getParameter($def)); + } + + public function getParameterProvider() + { + return array( + array('', array('', '', '', '', '')), + array('`foo` TEXT', array('', 'foo', 'TEXT', '', '')), + array('`foo` INT(20)', array('', 'foo', 'INT', '20', '')), + array( + 'IN `fo``fo` INT UNSIGNED', + array('IN', 'fo`fo', 'INT', '', 'UNSIGNED') + ), + array( + 'OUT bar VARCHAR(1) CHARSET utf8', + array('OUT', 'bar', 'VARCHAR', '1', 'utf8') + ), + array( + '`"baz\'\'` ENUM(\'a\', \'b\') CHARSET latin1', + array('', '"baz\'\'', 'ENUM', '\'a\',\'b\'', 'latin1') + ), + array( + 'INOUT `foo` DECIMAL(5,2) UNSIGNED ZEROFILL', + array('INOUT', 'foo', 'DECIMAL', '5,2', 'UNSIGNED ZEROFILL') + ), + array( + '`foo``s func` SET(\'test\'\'esc"\', \'more\\\'esc\')', + array( + '', 'foo`s func', 'SET', '\'test\'\'esc"\',\'more\\\'esc\'', '' + ) + ) + ); + } + + /** + * @dataProvider getParametersProvider + */ + public function testGetParameters($query, array $expected) + { + $parser = new Parser($query); + $this->assertEquals($expected, Routine::getParameters($parser->statements[0])); + } + + public function getParametersProvider() + { + return array( + array( + 'CREATE PROCEDURE `foo`() SET @A=0', + array( + 'num' => 0, + 'dir' => array(), + 'name' => array(), + 'type' => array(), + 'length' => array(), + 'length_arr' => array(), + 'opts' => array() + ) + ), + array( + 'CREATE DEFINER=`user\\`@`somehost``(` FUNCTION `foo```(`baz` INT) BEGIN SELECT NULL; END', + array( + 'num' => 1, + 'dir' => array( + 0 => '' + ), + 'name' => array( + 0 => 'baz' + ), + 'type' => array( + 0 => 'INT' + ), + 'length' => array( + 0 => '' + ), + 'length_arr' => array( + 0 => array(), + ), + 'opts' => array( + 0 => '' + ) + ) + ), + array( + 'CREATE PROCEDURE `foo`(IN `baz\\)` INT(25) zerofill unsigned) BEGIN SELECT NULL; END', + array( + 'num' => 1, + 'dir' => array( + 0 => 'IN' + ), + 'name' => array( + 0 => 'baz\\)' + ), + 'type' => array( + 0 => 'INT' + ), + 'length' => array( + 0 => '25' + ), + 'length_arr' => array( + 0 => array('25'), + ), + 'opts' => array( + 0 => 'UNSIGNED ZEROFILL' + ) + ) + ), + array( + 'CREATE PROCEDURE `foo`(IN `baz\\` INT(001) zerofill, out bazz varchar(15) charset utf8) '. + 'BEGIN SELECT NULL; END', + array( + 'num' => 2, + 'dir' => array( + 0 => 'IN', + 1 => 'OUT' + ), + 'name' => array( + 0 => 'baz\\', + 1 => 'bazz' + ), + 'type' => array( + 0 => 'INT', + 1 => 'VARCHAR' + ), + 'length' => array( + 0 => '1', + 1 => '15' + ), + 'length_arr' => array( + 0 => array('1'), + 1 => array('15') + ), + 'opts' => array( + 0 => 'ZEROFILL', + 1 => 'utf8' + ) + ) + ), + ); + } +} diff --git a/tests/Utils/TableTest.php b/tests/Utils/TableTest.php new file mode 100644 index 0000000..bda6e78 --- /dev/null +++ b/tests/Utils/TableTest.php @@ -0,0 +1,181 @@ +<?php + +namespace SqlParser\Tests\Utils; + +use SqlParser\Parser; +use SqlParser\Utils\Table; + +use SqlParser\Tests\TestCase; + +class TableTest extends TestCase +{ + + /** + * @dataProvider getForeignKeysProvider + */ + public function testGetForeignKeys($query, array $expected) + { + $parser = new Parser($query); + $this->assertEquals($expected, Table::getForeignKeys($parser->statements[0])); + } + + public function getForeignKeysProvider() + { + return array( + array( + 'CREATE USER test', + array(), + ), + array( + 'CREATE TABLE `payment` ( + `payment_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, + `customer_id` smallint(5) unsigned NOT NULL, + `staff_id` tinyint(3) unsigned NOT NULL, + `rental_id` int(11) DEFAULT NULL, + `amount` decimal(5,2) NOT NULL, + `payment_date` datetime NOT NULL, + `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`payment_id`), + KEY `idx_fk_staff_id` (`staff_id`), + KEY `idx_fk_customer_id` (`customer_id`), + KEY `fk_payment_rental` (`rental_id`), + CONSTRAINT `fk_payment_customer` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`customer_id`) ON UPDATE CASCADE, + CONSTRAINT `fk_payment_rental` FOREIGN KEY (`rental_id`) REFERENCES `rental` (`rental_id`) ON DELETE SET NULL ON UPDATE CASCADE, + CONSTRAINT `fk_payment_staff` FOREIGN KEY (`staff_id`) REFERENCES `staff` (`staff_id`) ON UPDATE CASCADE + ) ENGINE=InnoDB AUTO_INCREMENT=16050 DEFAULT CHARSET=utf8', + array( + array( + 'constraint' => 'fk_payment_customer', + 'index_list' => array('customer_id'), + 'ref_table_name' => 'customer', + 'ref_index_list' => array('customer_id'), + 'on_update' => 'CASCADE', + ), + array( + 'constraint' => 'fk_payment_rental', + 'index_list' => array('rental_id'), + 'ref_table_name' => 'rental', + 'ref_index_list' => array('rental_id'), + 'on_delete' => 'SET_NULL', + 'on_update' => 'CASCADE', + ), + array( + 'constraint' => 'fk_payment_staff', + 'index_list' => array('staff_id'), + 'ref_table_name' => 'staff', + 'ref_index_list' => array('staff_id'), + 'on_update' => 'CASCADE', + ), + ), + ), + array( + 'CREATE TABLE `actor` ( + `actor_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, + `first_name` varchar(45) NOT NULL, + `last_name` varchar(45) NOT NULL, + `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`actor_id`), + KEY `idx_actor_last_name` (`last_name`) + ) ENGINE=InnoDB AUTO_INCREMENT=201 DEFAULT CHARSET=utf8', + array(), + ), + array( + 'CREATE TABLE `address` ( + `address_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, + `address` varchar(50) NOT NULL, + `address2` varchar(50) DEFAULT NULL, + `district` varchar(20) NOT NULL, + `city_id` smallint(5) unsigned NOT NULL, + `postal_code` varchar(10) DEFAULT NULL, + `phone` varchar(20) NOT NULL, + `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`address_id`), + KEY `idx_fk_city_id` (`city_id`), + CONSTRAINT `fk_address_city` FOREIGN KEY (`city_id`) REFERENCES `city` (`city_id`) ON UPDATE CASCADE + ) ENGINE=InnoDB AUTO_INCREMENT=606 DEFAULT CHARSET=utf8', + array( + array( + 'constraint' => 'fk_address_city', + 'index_list' => array('city_id'), + 'ref_table_name' => 'city', + 'ref_index_list' => array('city_id'), + 'on_update' => 'CASCADE', + ), + ), + ), + ); + } + + /** + * @dataProvider getFieldsProvider + */ + public function testGetFields($query, array $expected) + { + $parser = new Parser($query); + $this->assertEquals($expected, Table::getFields($parser->statements[0])); + } + + public function getFieldsProvider() + { + return array( + array( + 'CREATE USER test', + array(), + ), + array( + 'CREATE TABLE `address` ( + `address_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, + `address` varchar(50) NOT NULL, + `address2` varchar(50) DEFAULT NULL, + `district` varchar(20) NOT NULL, + `city_id` smallint(5) unsigned NOT NULL, + `postal_code` varchar(10) DEFAULT NULL, + `phone` varchar(20) NOT NULL, + `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`address_id`), + KEY `idx_fk_city_id` (`city_id`), + CONSTRAINT `fk_address_city` FOREIGN KEY (`city_id`) REFERENCES `city` (`city_id`) ON UPDATE CASCADE + ) ENGINE=InnoDB AUTO_INCREMENT=606 DEFAULT CHARSET=utf8', + array( + 'address_id' => array( + 'type' => 'SMALLINT', + 'timestamp_not_null' => null, + ), + 'address' => array( + 'type' => 'VARCHAR', + 'timestamp_not_null' => null, + ), + 'address2' => array( + 'type' => 'VARCHAR', + 'timestamp_not_null' => null, + 'default_value' => 'NULL', + ), + 'district' => array( + 'type' => 'VARCHAR', + 'timestamp_not_null' => null, + ), + 'city_id' => array( + 'type' => 'SMALLINT', + 'timestamp_not_null' => null, + ), + 'postal_code' => array( + 'type' => 'VARCHAR', + 'timestamp_not_null' => null, + 'default_value' => 'NULL', + ), + 'phone' => array( + 'type' => 'VARCHAR', + 'timestamp_not_null' => null, + ), + 'last_update' => array( + 'type' => 'TIMESTAMP', + 'timestamp_not_null' => true, + 'default_value' => 'CURRENT_TIMESTAMP', + 'default_current_timestamp' => true, + 'on_update_current_timestamp' => true + ) + ) + ), + ); + } +} |