Skip to content

Commit

Permalink
support database
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexey Solodkiy authored and iamcal committed Mar 1, 2019
1 parent f3fa038 commit a3a4046
Show file tree
Hide file tree
Showing 3 changed files with 220 additions and 40 deletions.
31 changes: 28 additions & 3 deletions src/SQLParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -198,14 +198,14 @@ function walk($tokens, $sql, $source_map){

$table = $this->parse_create_table($s, 1, count($s));
$table['sql'] = $stmt['sql'];
$tables[$table['name']] = $table;
$tables[$this->generateTableKey($table)] = $table;
}

if (StrToUpper($s[0]) == 'CREATE TEMPORARY TABLE'){

$table = $this->parse_create_table($s, 1, count($s));
$table['props']['temporary'] = true;
$tables[$table['name']] = $table;
$tables[$this->generateTableKey($table)] = $table;
$table['sql'] = $stmt['sql'];
}

Expand All @@ -219,6 +219,15 @@ function walk($tokens, $sql, $source_map){
);
}

private function generateTableKey(array $table)
{
if (!is_null($table['database'])) {
return $table['database'] . '.' . $table['name'];
} else {
return $table['name'];
}
}


function parse_create_table($tokens, $i, $num){

Expand All @@ -230,9 +239,15 @@ function parse_create_table($tokens, $i, $num){
#
# name
#

$database = null;
$name = $this->decode_identifier($tokens[$i++]);

if (isset($tokens[$i]) && $tokens[$i] === '.') {
$i++;
$database = $name;
$name = $this->decode_identifier($tokens[$i++]);
}


#
# CREATE TABLE x LIKE y
Expand All @@ -242,9 +257,18 @@ function parse_create_table($tokens, $i, $num){
$i++;
$old_name = $this->decode_identifier($tokens[$i++]);

$like_database = null;
if (isset($tokens[$i]) && $tokens[$i] === '.') {
$i++;
$like_database = $old_name;
$old_name = $this->decode_identifier($tokens[$i++]);
}

return array(
'name' => $name,
'database' => $database,
'like' => $old_name,
'like_database' => $like_database,
);
}

Expand All @@ -267,6 +291,7 @@ function parse_create_table($tokens, $i, $num){

$table = array(
'name' => $name,
'database' => $database,
'fields' => $fields,
'indexes' => $indexes,
'props' => $props,
Expand Down
219 changes: 182 additions & 37 deletions tests/FullTest.php
Original file line number Diff line number Diff line change
@@ -1,38 +1,183 @@
<?php
use PHPUnit\Framework\TestCase;

final class FullTest extends TestCase{

function full_test($sql, $expected){

$obj = new iamcal\SQLParser();
$obj->parse($sql);

$lines = array();
foreach ($obj->tables as $table){
$lines[] = "TABLE:{$table['name']}";
$lines[] = "SQL:{$table['sql']}";
foreach ($table['fields'] as $field){
$lines[] = "-FIELD:{$field['name']}:{$field['type']}";
}
}

$this->assertEquals($lines, $expected);
}


function testBasicCases(){

$this->full_test("CREATE TABLE table_name (a INT);\n" .
"-- ignored comment\n\n" .
"CREATE TABLE t2 (b VARCHAR)\n\n;\n",
array(
"TABLE:table_name",
"SQL:CREATE TABLE table_name (a INT);",
"-FIELD:a:INT",
"TABLE:t2",
"SQL:CREATE TABLE t2 (b VARCHAR)\n\n;",
"-FIELD:b:VARCHAR",
));
}
}

use PHPUnit\Framework\TestCase;

final class FullTest extends TestCase
{
/**
* @param $sql
* @param $expected
* @dataProvider parseProvider
*/
public function testBasicCases($sql, $expected)
{
$obj = new iamcal\SQLParser();
$tables = $obj->parse($sql);

$this->assertEquals($expected, $tables);
}

public function parseProvider()
{
return [
[
"CREATE TABLE table_name (a INT);\n"
. "-- ignored comment\n\n"
. "CREATE TABLE t2 (b VARCHAR)\n\n;\n",
[
'table_name' => [
'name' => 'table_name',
'database' => null,
'fields' => [
[
'name' => 'a',
'type' => 'INT',
],
],
'indexes' => [],
'props' => [],
'more' => [],
'sql' => 'CREATE TABLE table_name (a INT);',
],
't2' => [
'name' => 't2',
'database' => null,
'fields' => [
[
'name' => 'b',
'type' => 'VARCHAR',
],
],
'indexes' => [],
'props' => [],
'more' => [],
'sql' => "CREATE TABLE t2 (b VARCHAR)\n\n;",
],

]
],
[
'CREATE TABLE DbName.TableName (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
errcnt INT(10) UNSIGNED NOT NULL DEFAULT \'0\',
user_id INT UNSIGNED NOT NULL,
photo_id INT UNSIGNED NOT NULL,
place_id INT UNSIGNED NOT NULL,
next_processing_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY (place_id, next_processing_time),
UNIQUE KEY (user_id, place_id, photo_id)
);',
[
'DbName.TableName' => [
'name' => 'TableName',
'database' => 'DbName',
'fields' => [
[
'name' => 'id',
'type' => 'BIGINT',
'unsigned' => true,
'null' => false,
'auto_increment' => true,
],
[
'name' => 'errcnt',
'type' => 'INT',
'length' => '10',
'unsigned' => true,
'null' => false,
'default' => '0',
],
[
'name' => 'user_id',
'type' => 'INT',
'unsigned' => true,
'null' => false,
],
[
'name' => 'photo_id',
'type' => 'INT',
'unsigned' => true,
'null' => false,
],
[
'name' => 'place_id',
'type' => 'INT',
'unsigned' => true,
'null' => false,
],
[
'name' => 'next_processing_time',
'type' => 'TIMESTAMP',
'null' => false,
'default' => 'CURRENT_TIMESTAMP',
],
[
'name' => 'created',
'type' => 'TIMESTAMP',
'null' => false,
'default' => 'CURRENT_TIMESTAMP',
],
],
'indexes' => [
[
'type' => 'PRIMARY',
'cols' =>
[
[
'name' => 'id',
],
],
],
[
'type' => 'INDEX',
'cols' =>
[
[
'name' => 'place_id',
],
[
'name' => 'next_processing_time',
],
],
],
[
'type' => 'UNIQUE',
'cols' =>
[
[
'name' => 'user_id',
],
[
'name' => 'place_id',
],
[
'name' => 'photo_id',
],
],
],
],
'props' => [],
'more' => [],
'sql' => 'CREATE TABLE DbName.TableName (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
errcnt INT(10) UNSIGNED NOT NULL DEFAULT \'0\',
user_id INT UNSIGNED NOT NULL,
photo_id INT UNSIGNED NOT NULL,
place_id INT UNSIGNED NOT NULL,
next_processing_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY (place_id, next_processing_time),
UNIQUE KEY (user_id, place_id, photo_id)
);',
],

]
]

];
}

}
10 changes: 10 additions & 0 deletions tests/TablesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ function testCreateTableLike(){
$this->assertEquals($tbl['like'], "bar");
}

function testCreateTableLikeWithDb(){

$tbl = $this->get_first_table("CREATE TABLE db.foo LIKE `db2`.`bar`");

$this->assertEquals($tbl['name'], "foo");
$this->assertEquals($tbl['database'], "db");
$this->assertEquals($tbl['like'], "bar");
$this->assertEquals($tbl['like_database'], "db2");
}


function get_first_table($str){
$obj = new iamcal\SQLParser();
Expand Down

0 comments on commit a3a4046

Please sign in to comment.