@dbml/core 2.3.1 → 2.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/export/DbmlExporter.js +11 -6
- package/lib/export/MysqlExporter.js +127 -48
- package/lib/export/PostgresExporter.js +142 -55
- package/lib/export/SqlServerExporter.js +130 -52
- package/lib/export/utils.js +40 -0
- package/lib/model_structure/database.js +53 -12
- package/lib/model_structure/endpoint.js +2 -2
- package/lib/model_structure/field.js +31 -1
- package/lib/model_structure/ref.js +1 -2
- package/lib/model_structure/schema.js +3 -19
- package/lib/model_structure/tableGroup.js +1 -1
- package/lib/model_structure/utils.js +5 -0
- package/lib/parse/dbml/parser.pegjs +74 -24
- package/lib/parse/dbmlParser.js +1275 -886
- package/lib/parse/mssql/fk_definition/actions.js +10 -3
- package/lib/parse/mssql/keyword_parsers.js +12 -1
- package/lib/parse/mssql/statements/actions.js +37 -6
- package/lib/parse/mssql/statements/index.js +1 -1
- package/lib/parse/mssql/statements/statement_types/alter_table/actions.js +11 -5
- package/lib/parse/mssql/statements/statement_types/comments/actions.js +57 -0
- package/lib/parse/mssql/statements/statement_types/comments/index.js +97 -0
- package/lib/parse/mssql/statements/statement_types/create_index/actions.js +6 -1
- package/lib/parse/mssql/statements/statement_types/create_table/actions.js +11 -9
- package/lib/parse/mssql/statements/statement_types/index.js +4 -1
- package/lib/parse/mssql/utils.js +15 -0
- package/lib/parse/mysql/parser.pegjs +55 -20
- package/lib/parse/mysqlParser.js +479 -308
- package/lib/parse/postgresParser.js +15 -14
- package/lib/parse/postgresql/Base_rules.pegjs +24 -3
- package/lib/parse/postgresql/Commands/Alter_table/Alter_table.pegjs +49 -4
- package/lib/parse/postgresql/Commands/Comment.pegjs +18 -6
- package/lib/parse/postgresql/Commands/Create_table/Create_table_normal.pegjs +5 -3
- package/lib/parse/postgresql/Commands/Create_table/Create_table_of.pegjs +1 -1
- package/lib/parse/postgresql/Commands/Create_table/Create_table_partition_of.pegjs +1 -1
- package/lib/parse/postgresql/Commands/Create_type/Create_type_enum.pegjs +2 -2
- package/lib/parse/postgresql/Commands/Ignore_syntax.pegjs +10 -1
- package/lib/parse/postgresql/InitializerUtils.pegjs +14 -2
- package/lib/parse/postgresql/Keywords.pegjs +5 -1
- package/lib/parse/postgresql/parser.pegjs +22 -8
- package/package.json +2 -2
|
@@ -1,8 +1,27 @@
|
|
|
1
1
|
// Base rules:
|
|
2
2
|
// collumn_name, table_name
|
|
3
3
|
column_name "valid column name" = identifier
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
|
|
5
|
+
path_name = names:(identifier _ "." _)* {
|
|
6
|
+
let dbName = null;
|
|
7
|
+
let schemaName = null;
|
|
8
|
+
if (names && names.length > 0) {
|
|
9
|
+
if (names.length === 1) schemaName = names[0][0];
|
|
10
|
+
else {
|
|
11
|
+
dbName = names[0][0];
|
|
12
|
+
schemaName = names[1][0];
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return { dbName, schemaName }
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
table_name "valid table name" = pathName:path_name name:identifier {
|
|
19
|
+
return { ...pathName, name }
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
enum_name "valid enum name" = pathName:path_name? name:identifier {
|
|
23
|
+
return { ...pathName, name }
|
|
24
|
+
}
|
|
6
25
|
|
|
7
26
|
// string constant
|
|
8
27
|
string_constant "string" = "'" c:char_inside_single_quote+ "'" {
|
|
@@ -58,6 +77,7 @@ data_type "VALID TYPE" = c1:"CHARACTER"i _ c2:"VARYING"i _ args:("("expression")
|
|
|
58
77
|
const args = c.args;
|
|
59
78
|
return {
|
|
60
79
|
type_name: c.type_name + (dimensions ? dimensions.map((dimension) => '[' + dimension + ']').join('') : ''),
|
|
80
|
+
schemaName: c.schemaName,
|
|
61
81
|
args
|
|
62
82
|
};
|
|
63
83
|
}
|
|
@@ -67,7 +87,7 @@ data_type "VALID TYPE" = c1:"CHARACTER"i _ c2:"VARYING"i _ args:("("expression")
|
|
|
67
87
|
args: null
|
|
68
88
|
}
|
|
69
89
|
}
|
|
70
|
-
type_name = c:(character)+ _ args:("(" expression ")")? {
|
|
90
|
+
type_name = pathName:path_name? c:(character)+ _ args:("(" expression ")")? {
|
|
71
91
|
let type_name = c.join("");
|
|
72
92
|
args = args ? args[1] : null;
|
|
73
93
|
if (type_name.toLowerCase() !== 'enum') {
|
|
@@ -75,6 +95,7 @@ type_name = c:(character)+ _ args:("(" expression ")")? {
|
|
|
75
95
|
}
|
|
76
96
|
|
|
77
97
|
return {
|
|
98
|
+
...pathName,
|
|
78
99
|
type_name,
|
|
79
100
|
args
|
|
80
101
|
}
|
|
@@ -1,17 +1,57 @@
|
|
|
1
|
-
alter_table =
|
|
1
|
+
alter_table = alter_sub_syntax:(
|
|
2
|
+
alter_table_action /
|
|
3
|
+
alter_table_rename /
|
|
4
|
+
alter_table_set_schema /
|
|
5
|
+
alter_table_set_tablespace /
|
|
6
|
+
alter_table_attach /
|
|
7
|
+
alter_table_detach
|
|
8
|
+
) {
|
|
2
9
|
return {
|
|
3
10
|
command_name: "alter_table",
|
|
4
|
-
value:
|
|
11
|
+
value: alter_sub_syntax
|
|
5
12
|
}
|
|
6
13
|
}
|
|
7
14
|
|
|
8
|
-
|
|
15
|
+
alter_table_rename = _ ALTER __ TABLE (__ IF_EXISTS)? (__ ONLY)? __ table_name (_ "*")? __ RENAME (cmt / !semicolon .)* _ semicolon _ {
|
|
16
|
+
return {
|
|
17
|
+
syntax_name: "alter_table_rename",
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
alter_table_set_schema = _ ALTER __ TABLE (__ IF_EXISTS)? __ table_name __ SET __ SCHEMA (cmt / !semicolon .)* _ semicolon _ {
|
|
22
|
+
return {
|
|
23
|
+
syntax_name: "alter_table_set_schema",
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
alter_table_set_tablespace = _ ALTER __ TABLE __ ALL __ IN __ TABLESPACE __ table_name
|
|
28
|
+
(__ OWNED __ BY __ identifier (_ comma _ identifier)*)? __ SET __ TABLESPACE
|
|
29
|
+
(cmt / !semicolon .)* _ semicolon _ {
|
|
30
|
+
return {
|
|
31
|
+
syntax_name: "alter_set_tablespace",
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
alter_table_attach = _ ALTER __ TABLE (__ IF_EXISTS)? __ table_name __ ATTACH __ PARTITION (cmt / !semicolon .)* _ semicolon _ {
|
|
36
|
+
return {
|
|
37
|
+
syntax_name: "alter_table_attach",
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
alter_table_detach = _ ALTER __ TABLE (__ IF_EXISTS)? __ table_name __ DETACH __ PARTITION (cmt / !semicolon .)* _ semicolon _ {
|
|
42
|
+
return {
|
|
43
|
+
syntax_name: "alter_table_detach",
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
alter_table_action = _ ALTER __ TABLE (__ IF_EXISTS)? (__ ONLY)? __ name:table_name (_ "*")? __
|
|
9
48
|
actions:actions _ semicolon _ {
|
|
10
49
|
actions.forEach(({ type, t_value}) => {
|
|
11
50
|
switch(type.toLowerCase()) {
|
|
12
51
|
case "fk":
|
|
13
52
|
t_value.forEach(({ endpoints }) => {
|
|
14
|
-
endpoints[0].tableName = name
|
|
53
|
+
endpoints[0].tableName = name.name;
|
|
54
|
+
endpoints[0].schemaName = name.schemaName;
|
|
15
55
|
})
|
|
16
56
|
}
|
|
17
57
|
})
|
|
@@ -78,6 +118,11 @@ action = ADD __ table_constraint:table_constraint (__ NOT __ VALID)? { // reuse
|
|
|
78
118
|
value: value.toLowerCase()
|
|
79
119
|
}
|
|
80
120
|
}
|
|
121
|
+
/ (cmt / !semicolon .)* {
|
|
122
|
+
return {
|
|
123
|
+
type: "unknown",
|
|
124
|
+
}
|
|
125
|
+
}
|
|
81
126
|
|
|
82
127
|
|
|
83
128
|
set_attribute_options = first:set_attribute_option rest:(_ comma _ set_attribute_option)* {
|
|
@@ -2,9 +2,7 @@ comment = _ COMMENT __ ON __ comment_option:comment_option __ IS __ text:(string
|
|
|
2
2
|
_ semicolon _ {
|
|
3
3
|
if (text.toLowerCase() !== "null") {
|
|
4
4
|
comment_option.value.text = text;
|
|
5
|
-
} else
|
|
6
|
-
comment_option.value.syntax_name = "remove_comment";
|
|
7
|
-
}
|
|
5
|
+
} else comment_option.value.text = null;
|
|
8
6
|
|
|
9
7
|
return {
|
|
10
8
|
command_name: "comment",
|
|
@@ -13,12 +11,26 @@ comment = _ COMMENT __ ON __ comment_option:comment_option __ IS __ text:(string
|
|
|
13
11
|
}
|
|
14
12
|
|
|
15
13
|
comment_option = (
|
|
16
|
-
COLUMN __
|
|
14
|
+
COLUMN __ path:(identifier '.')+ column_name:column_name {
|
|
15
|
+
let dbName = null, schemaName = null, tableName;
|
|
16
|
+
if (path.length === 1) {
|
|
17
|
+
tableName = path[0][0];
|
|
18
|
+
} else if (path.length === 2) {
|
|
19
|
+
schemaName = path[0][0];
|
|
20
|
+
tableName = path[1][0];
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
dbName = path[0][0];
|
|
24
|
+
schemaName = path[1][0];
|
|
25
|
+
tableName = path[2][0];
|
|
26
|
+
}
|
|
17
27
|
return {
|
|
18
28
|
syntax_name: "column",
|
|
19
29
|
value: {
|
|
20
|
-
|
|
21
|
-
|
|
30
|
+
dbName,
|
|
31
|
+
schemaName,
|
|
32
|
+
tableName,
|
|
33
|
+
columnName: column_name
|
|
22
34
|
}
|
|
23
35
|
}
|
|
24
36
|
}
|
|
@@ -7,7 +7,7 @@ create_table_normal =
|
|
|
7
7
|
(__ ON __ COMMIT __ (PRESERVE __ ROWS/ DELETE __ ROWS/ DROP))?
|
|
8
8
|
(__ TABLESPACE __ tablespace_name:identifier)?
|
|
9
9
|
_ semicolon _ {
|
|
10
|
-
const table = { name: table_name, fields: [], indexes: [] }
|
|
10
|
+
const table = { name: table_name.name, schemaName: table_name.schemaName, fields: [], indexes: [] }
|
|
11
11
|
// process table_properties
|
|
12
12
|
table_properties.forEach(({ table_property_name, value }) => {
|
|
13
13
|
switch(table_property_name.toLowerCase()) {
|
|
@@ -156,7 +156,8 @@ column_constraint = (CONSTRAINT __ constraint_name:identifier __)?
|
|
|
156
156
|
type: "fk",
|
|
157
157
|
value: {
|
|
158
158
|
endpoint: {
|
|
159
|
-
tableName: reftable,
|
|
159
|
+
tableName: reftable.name,
|
|
160
|
+
schemaName: reftable.schemaName,
|
|
160
161
|
fieldNames: refcolumn ? [refcolumn] : null,
|
|
161
162
|
relation: "1"
|
|
162
163
|
},
|
|
@@ -192,7 +193,8 @@ table_constraint = (CONSTRAINT __ constraint_name:identifier __)?
|
|
|
192
193
|
relation: "*",
|
|
193
194
|
},
|
|
194
195
|
{
|
|
195
|
-
tableName: reftable,
|
|
196
|
+
tableName: reftable.name,
|
|
197
|
+
schemaName: reftable.schemaName,
|
|
196
198
|
fieldNames: refcolumn,// ? refcolumn[key] : null,
|
|
197
199
|
relation: "1",
|
|
198
200
|
},
|
|
@@ -6,7 +6,7 @@ create_table_of =
|
|
|
6
6
|
(__ ON __ COMMIT __ (PRESERVE __ ROWS/ DELETE __ ROWS/ DROP))?
|
|
7
7
|
(__ TABLESPACE __ tablespace_name:identifier)?
|
|
8
8
|
_ semicolon _ {
|
|
9
|
-
const table = { name: table_name, type: type_name}
|
|
9
|
+
const table = { name: table_name.name, schemaName: table_name.schemaName, type: type_name}
|
|
10
10
|
return {
|
|
11
11
|
syntax_name: "create_table_of",
|
|
12
12
|
value: table
|
|
@@ -7,7 +7,7 @@ create_table_partition_of =
|
|
|
7
7
|
(__ ON __ COMMIT __ (PRESERVE __ ROWS/ DELETE __ ROWS/ DROP))?
|
|
8
8
|
(__ TABLESPACE __ tablespace_name:identifier)?
|
|
9
9
|
_ semicolon _ {
|
|
10
|
-
const table = { name: table_name, parent_table: parent_table}
|
|
10
|
+
const table = { name: table_name.name, schemaName: table_name.schemaName, parent_table: parent_table}
|
|
11
11
|
return {
|
|
12
12
|
syntax_name: "create_table_partition_of",
|
|
13
13
|
value: table
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
create_type_enum =
|
|
2
|
-
_ CREATE __ TYPE __
|
|
2
|
+
_ CREATE __ TYPE __ enumName:enum_name __ AS __ ENUM _
|
|
3
3
|
"(" _ labels:labels _ ")"
|
|
4
4
|
_ semicolon _ {
|
|
5
5
|
const values = labels.map(name => ({ name }))
|
|
6
6
|
return {
|
|
7
7
|
syntax_name: "create_type_enum",
|
|
8
8
|
value: {
|
|
9
|
-
|
|
9
|
+
...enumName,
|
|
10
10
|
values,
|
|
11
11
|
}
|
|
12
12
|
}
|
|
@@ -8,10 +8,19 @@ ignore_syntax = _ value:(
|
|
|
8
8
|
/ CREATE __ SEQUENCE [^;]* { return { syntax_name: "create_sequence" } }
|
|
9
9
|
/ CREATE __ SCHEMA [^;]* { return { syntax_name: "create_schema" } }
|
|
10
10
|
/ CREATE __ VIEW [^;]* { return { syntax_name: "create_view" } }
|
|
11
|
+
/ ALTER __ (cmt / !(semicolon) .)* { return { syntax_name: "alter_not_table" } }
|
|
11
12
|
/ __ { return { syntax_name: "comment_and_space" } }
|
|
12
13
|
) semicolon _ {
|
|
14
|
+
const loc = location();
|
|
15
|
+
const t = text();
|
|
13
16
|
return {
|
|
14
17
|
command_name: "ignore_syntax",
|
|
15
|
-
value
|
|
18
|
+
value,
|
|
19
|
+
warning: {
|
|
20
|
+
type: 'ignore',
|
|
21
|
+
location: loc,
|
|
22
|
+
text: t,
|
|
23
|
+
message: `ignoring "${t}" at line: ${loc.start.line}`,
|
|
24
|
+
},
|
|
16
25
|
}
|
|
17
26
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
// intput:
|
|
3
|
-
// `
|
|
3
|
+
// `
|
|
4
4
|
// 'created'
|
|
5
|
-
// ,
|
|
5
|
+
// ,
|
|
6
6
|
// 'pending', 'done'
|
|
7
7
|
// `
|
|
8
8
|
// => `'created', 'pending', 'done'`
|
|
@@ -14,4 +14,16 @@
|
|
|
14
14
|
});
|
|
15
15
|
return arrAfterTrim.join(', ');
|
|
16
16
|
}
|
|
17
|
+
|
|
18
|
+
// TODO: support configurable default schema name other than 'public'
|
|
19
|
+
const findTable = (schemaName, tableName) => {
|
|
20
|
+
const realSchemaName = schemaName || 'public';
|
|
21
|
+
const table = tables.find(table => {
|
|
22
|
+
const targetSchemaName = table.schemaName || 'public';
|
|
23
|
+
return targetSchemaName === realSchemaName && table.name === tableName;
|
|
24
|
+
});
|
|
25
|
+
return table;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const findField = (table, fieldName) => table.fields.find(field => field.name === fieldName);
|
|
17
29
|
}
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
const tables = [];
|
|
3
3
|
const refs = [];
|
|
4
4
|
const enums = [];
|
|
5
|
+
const warnings = [];
|
|
5
6
|
}
|
|
6
7
|
|
|
7
8
|
parser = commands:command* {
|
|
8
|
-
commands.forEach((
|
|
9
|
+
commands.forEach((cmd) => {
|
|
10
|
+
const { command_name, value: { syntax_name, value }, warning } = cmd;
|
|
9
11
|
switch(command_name.toLowerCase()){
|
|
10
12
|
case "create_table":
|
|
11
13
|
const table = value;
|
|
@@ -23,6 +25,7 @@ parser = commands:command* {
|
|
|
23
25
|
endpoints: [
|
|
24
26
|
{
|
|
25
27
|
tableName: table.name,
|
|
28
|
+
schemaName: table.schemaName,
|
|
26
29
|
fieldNames: [field.name],
|
|
27
30
|
relation: "*",
|
|
28
31
|
},
|
|
@@ -70,7 +73,7 @@ parser = commands:command* {
|
|
|
70
73
|
case "create_index":
|
|
71
74
|
const { table_name } = value;
|
|
72
75
|
delete value.table_name; // remove table_name from column
|
|
73
|
-
|
|
76
|
+
const table_index = findTable(table_name.schemaName, table_name.name);
|
|
74
77
|
if (table_index.indexes) {
|
|
75
78
|
table_index.indexes.push(value);
|
|
76
79
|
} else {
|
|
@@ -103,18 +106,29 @@ parser = commands:command* {
|
|
|
103
106
|
break;
|
|
104
107
|
case "comment":
|
|
105
108
|
switch(syntax_name.toLowerCase()) {
|
|
106
|
-
case "column":
|
|
107
|
-
const
|
|
108
|
-
const
|
|
109
|
-
|
|
109
|
+
case "column": {
|
|
110
|
+
const { schemaName, tableName, columnName } = value;
|
|
111
|
+
const foundTable = findTable(schemaName, tableName);
|
|
112
|
+
if (foundTable) {
|
|
113
|
+
const foundField = findField(foundTable, columnName);
|
|
114
|
+
if (foundField) foundField.note = value.text;
|
|
115
|
+
}
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
case "table": {
|
|
119
|
+
const { schemaName, name: tableName } = value.table_name;
|
|
120
|
+
const foundTable = findTable(schemaName, tableName);
|
|
121
|
+
if (foundTable) foundTable.note = value.text;
|
|
110
122
|
break;
|
|
123
|
+
}
|
|
111
124
|
}
|
|
112
125
|
break;
|
|
113
|
-
case "
|
|
126
|
+
case "ignore_syntax":
|
|
127
|
+
// warnings.push(warning);
|
|
114
128
|
break;
|
|
115
129
|
}
|
|
116
130
|
})
|
|
117
|
-
|
|
131
|
+
|
|
118
132
|
return {tables, refs, enums};
|
|
119
133
|
}
|
|
120
134
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dbml/core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.2",
|
|
4
4
|
"description": "> TODO: description",
|
|
5
5
|
"author": "Holistics <dev@holistics.io>",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -56,5 +56,5 @@
|
|
|
56
56
|
"\\.(?!json$)[^.]*$": "jest-raw-loader"
|
|
57
57
|
}
|
|
58
58
|
},
|
|
59
|
-
"gitHead": "
|
|
59
|
+
"gitHead": "2d33941ba6f0833254bfc434abed1dc59f8f2b87"
|
|
60
60
|
}
|