Skip to content

Commit a3a4046

Browse files
Alexey Solodkiyiamcal
authored andcommitted
support database
1 parent f3fa038 commit a3a4046

3 files changed

Lines changed: 220 additions & 40 deletions

File tree

src/SQLParser.php

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,14 +198,14 @@ function walk($tokens, $sql, $source_map){
198198

199199
$table = $this->parse_create_table($s, 1, count($s));
200200
$table['sql'] = $stmt['sql'];
201-
$tables[$table['name']] = $table;
201+
$tables[$this->generateTableKey($table)] = $table;
202202
}
203203

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

206206
$table = $this->parse_create_table($s, 1, count($s));
207207
$table['props']['temporary'] = true;
208-
$tables[$table['name']] = $table;
208+
$tables[$this->generateTableKey($table)] = $table;
209209
$table['sql'] = $stmt['sql'];
210210
}
211211

@@ -219,6 +219,15 @@ function walk($tokens, $sql, $source_map){
219219
);
220220
}
221221

222+
private function generateTableKey(array $table)
223+
{
224+
if (!is_null($table['database'])) {
225+
return $table['database'] . '.' . $table['name'];
226+
} else {
227+
return $table['name'];
228+
}
229+
}
230+
222231

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

@@ -230,9 +239,15 @@ function parse_create_table($tokens, $i, $num){
230239
#
231240
# name
232241
#
233-
242+
$database = null;
234243
$name = $this->decode_identifier($tokens[$i++]);
235244

245+
if (isset($tokens[$i]) && $tokens[$i] === '.') {
246+
$i++;
247+
$database = $name;
248+
$name = $this->decode_identifier($tokens[$i++]);
249+
}
250+
236251

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

260+
$like_database = null;
261+
if (isset($tokens[$i]) && $tokens[$i] === '.') {
262+
$i++;
263+
$like_database = $old_name;
264+
$old_name = $this->decode_identifier($tokens[$i++]);
265+
}
266+
245267
return array(
246268
'name' => $name,
269+
'database' => $database,
247270
'like' => $old_name,
271+
'like_database' => $like_database,
248272
);
249273
}
250274

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

268292
$table = array(
269293
'name' => $name,
294+
'database' => $database,
270295
'fields' => $fields,
271296
'indexes' => $indexes,
272297
'props' => $props,

tests/FullTest.php

Lines changed: 182 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,183 @@
11
<?php
2-
use PHPUnit\Framework\TestCase;
3-
4-
final class FullTest extends TestCase{
5-
6-
function full_test($sql, $expected){
7-
8-
$obj = new iamcal\SQLParser();
9-
$obj->parse($sql);
10-
11-
$lines = array();
12-
foreach ($obj->tables as $table){
13-
$lines[] = "TABLE:{$table['name']}";
14-
$lines[] = "SQL:{$table['sql']}";
15-
foreach ($table['fields'] as $field){
16-
$lines[] = "-FIELD:{$field['name']}:{$field['type']}";
17-
}
18-
}
19-
20-
$this->assertEquals($lines, $expected);
21-
}
22-
23-
24-
function testBasicCases(){
25-
26-
$this->full_test("CREATE TABLE table_name (a INT);\n" .
27-
"-- ignored comment\n\n" .
28-
"CREATE TABLE t2 (b VARCHAR)\n\n;\n",
29-
array(
30-
"TABLE:table_name",
31-
"SQL:CREATE TABLE table_name (a INT);",
32-
"-FIELD:a:INT",
33-
"TABLE:t2",
34-
"SQL:CREATE TABLE t2 (b VARCHAR)\n\n;",
35-
"-FIELD:b:VARCHAR",
36-
));
37-
}
38-
}
2+
3+
use PHPUnit\Framework\TestCase;
4+
5+
final class FullTest extends TestCase
6+
{
7+
/**
8+
* @param $sql
9+
* @param $expected
10+
* @dataProvider parseProvider
11+
*/
12+
public function testBasicCases($sql, $expected)
13+
{
14+
$obj = new iamcal\SQLParser();
15+
$tables = $obj->parse($sql);
16+
17+
$this->assertEquals($expected, $tables);
18+
}
19+
20+
public function parseProvider()
21+
{
22+
return [
23+
[
24+
"CREATE TABLE table_name (a INT);\n"
25+
. "-- ignored comment\n\n"
26+
. "CREATE TABLE t2 (b VARCHAR)\n\n;\n",
27+
[
28+
'table_name' => [
29+
'name' => 'table_name',
30+
'database' => null,
31+
'fields' => [
32+
[
33+
'name' => 'a',
34+
'type' => 'INT',
35+
],
36+
],
37+
'indexes' => [],
38+
'props' => [],
39+
'more' => [],
40+
'sql' => 'CREATE TABLE table_name (a INT);',
41+
],
42+
't2' => [
43+
'name' => 't2',
44+
'database' => null,
45+
'fields' => [
46+
[
47+
'name' => 'b',
48+
'type' => 'VARCHAR',
49+
],
50+
],
51+
'indexes' => [],
52+
'props' => [],
53+
'more' => [],
54+
'sql' => "CREATE TABLE t2 (b VARCHAR)\n\n;",
55+
],
56+
57+
]
58+
],
59+
[
60+
'CREATE TABLE DbName.TableName (
61+
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
62+
errcnt INT(10) UNSIGNED NOT NULL DEFAULT \'0\',
63+
user_id INT UNSIGNED NOT NULL,
64+
photo_id INT UNSIGNED NOT NULL,
65+
place_id INT UNSIGNED NOT NULL,
66+
next_processing_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
67+
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
68+
PRIMARY KEY (id),
69+
KEY (place_id, next_processing_time),
70+
UNIQUE KEY (user_id, place_id, photo_id)
71+
);',
72+
[
73+
'DbName.TableName' => [
74+
'name' => 'TableName',
75+
'database' => 'DbName',
76+
'fields' => [
77+
[
78+
'name' => 'id',
79+
'type' => 'BIGINT',
80+
'unsigned' => true,
81+
'null' => false,
82+
'auto_increment' => true,
83+
],
84+
[
85+
'name' => 'errcnt',
86+
'type' => 'INT',
87+
'length' => '10',
88+
'unsigned' => true,
89+
'null' => false,
90+
'default' => '0',
91+
],
92+
[
93+
'name' => 'user_id',
94+
'type' => 'INT',
95+
'unsigned' => true,
96+
'null' => false,
97+
],
98+
[
99+
'name' => 'photo_id',
100+
'type' => 'INT',
101+
'unsigned' => true,
102+
'null' => false,
103+
],
104+
[
105+
'name' => 'place_id',
106+
'type' => 'INT',
107+
'unsigned' => true,
108+
'null' => false,
109+
],
110+
[
111+
'name' => 'next_processing_time',
112+
'type' => 'TIMESTAMP',
113+
'null' => false,
114+
'default' => 'CURRENT_TIMESTAMP',
115+
],
116+
[
117+
'name' => 'created',
118+
'type' => 'TIMESTAMP',
119+
'null' => false,
120+
'default' => 'CURRENT_TIMESTAMP',
121+
],
122+
],
123+
'indexes' => [
124+
[
125+
'type' => 'PRIMARY',
126+
'cols' =>
127+
[
128+
[
129+
'name' => 'id',
130+
],
131+
],
132+
],
133+
[
134+
'type' => 'INDEX',
135+
'cols' =>
136+
[
137+
[
138+
'name' => 'place_id',
139+
],
140+
[
141+
'name' => 'next_processing_time',
142+
],
143+
],
144+
],
145+
[
146+
'type' => 'UNIQUE',
147+
'cols' =>
148+
[
149+
[
150+
'name' => 'user_id',
151+
],
152+
[
153+
'name' => 'place_id',
154+
],
155+
[
156+
'name' => 'photo_id',
157+
],
158+
],
159+
],
160+
],
161+
'props' => [],
162+
'more' => [],
163+
'sql' => 'CREATE TABLE DbName.TableName (
164+
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
165+
errcnt INT(10) UNSIGNED NOT NULL DEFAULT \'0\',
166+
user_id INT UNSIGNED NOT NULL,
167+
photo_id INT UNSIGNED NOT NULL,
168+
place_id INT UNSIGNED NOT NULL,
169+
next_processing_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
170+
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
171+
PRIMARY KEY (id),
172+
KEY (place_id, next_processing_time),
173+
UNIQUE KEY (user_id, place_id, photo_id)
174+
);',
175+
],
176+
177+
]
178+
]
179+
180+
];
181+
}
182+
183+
}

tests/TablesTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ function testCreateTableLike(){
3434
$this->assertEquals($tbl['like'], "bar");
3535
}
3636

37+
function testCreateTableLikeWithDb(){
38+
39+
$tbl = $this->get_first_table("CREATE TABLE db.foo LIKE `db2`.`bar`");
40+
41+
$this->assertEquals($tbl['name'], "foo");
42+
$this->assertEquals($tbl['database'], "db");
43+
$this->assertEquals($tbl['like'], "bar");
44+
$this->assertEquals($tbl['like_database'], "db2");
45+
}
46+
3747

3848
function get_first_table($str){
3949
$obj = new iamcal\SQLParser();

0 commit comments

Comments
 (0)