Skip to content

Commit 6829c27

Browse files
authored
Merge pull request #32 from Software-Developers-IRL/f/lastlink
F/lastlink better mermaid erd diagram generator, reformat sql parser
2 parents f8b1ab8 + df57d6c commit 6829c27

File tree

4 files changed

+113
-57
lines changed

4 files changed

+113
-57
lines changed

samples/mermaid.py

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,49 @@
11
from schemacrawler.schema import TableRelationshipType # pylint: disable=import-error
22
import re
3+
from datetime import date
34

5+
today = date.today()
6+
7+
print('# Mermaid erDiagram')
8+
print ('* generated using schemacrawler on:' + str(today))
9+
print ('* using Little-Mermaid-2-TheSQL formatting')
10+
# TODO include package version
11+
print('')
12+
print('```mermaid')
413
print('erDiagram')
514
print('')
615
for table in catalog.tables:
716
print(' ' + table.fullName + ' {')
817
for column in table.columns:
9-
print(' ' + re.sub(r'\([\d ,]+\)', '', column.columnDataType.name) + ' ' + column.name)
18+
# // need to remove quotes and spaces
19+
# get all column attributes for debugging
20+
# print (dir(column))
21+
columnShortName = re.sub("[\"\']", "", column.name).replace(" ","")
22+
columnFullName = ""
23+
if(columnShortName != column.name):
24+
columnFullName = "'" + column.name + "'"
25+
# values cared about:
26+
# isNullable
27+
# autoIncremented
28+
# isPartOfIndex
29+
# isPartOfUniqueIndex
30+
keyType = " PK" if column.partOfPrimaryKey else ""
31+
if(keyType != "" and column.partOfForeignKey ):
32+
keyType = " FK"
33+
# dont need to define FK can get through relationships
34+
# keyType += ("" if keyType == "" else ",") + "FK" if column.partOfForeignKey else ""
35+
extraAttributes = ""
36+
if(columnFullName != ""):
37+
extraAttributes += columnFullName
38+
39+
if(extraAttributes != ""):
40+
extraAttributes = " \"" + extraAttributes + "\""
41+
print(' ' + re.sub("[,]", "_",re.sub(r'[()]', '', column.columnDataType.name)) + ' ' + columnShortName + keyType + extraAttributes)
1042
print(' }')
1143
print('')
1244

1345
for table in catalog.tables:
1446
for childTable in table.getRelatedTables(TableRelationshipType.child):
1547
print(' ' + table.name + ' ||--o{ ' + childTable.name + ' : "foreign key"')
16-
print('')
48+
print('')
49+
print('```')

src/Library.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { MermaidConfig } from "../deps/mermaid/src/config.type";
2424
import { log } from "../deps/mermaid/src/logger";
2525
import erDb from "./mermaid/src/diagrams/er/erDb";
2626
import { DiagramDefinition } from "./types";
27+
import { DbParser } from "./generate-sql-ddl";
2728
// import { getDiagram } from '../deps/mermaid/src/diagram-api/diagramAPI';
2829
const diagrams: Record<string, DiagramDefinition> = {};
2930

@@ -205,8 +206,9 @@ export const GenerateSqlFromMermaid = async function (
205206
var r:boolean = diag.parser.parse(md);
206207
var entities = diag.db.getEntities();
207208
var relationships = diag.db.getRelationships();
208-
// TODO: model interfaces
209+
// model interfaces
209210
// TODO: models to sql
211+
const ddlSyntax = new DbParser(databaseType, diag.db).getSQLDataDefinition();
210212
// var r2 = diag.parser.parser.parse(md);
211213
// console.log(JSON.stringify(r));
212214
var test5 = 1 + 1;

src/generate-sql-ddl.ts

Lines changed: 69 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
import {
2+
DbDefinition,
3+
DbEntityDefinition,
4+
DbRelationshipDefinition,
5+
} from "./types";
16

27
interface Table {
3-
name: string;
4-
columns: string[];
8+
name: string;
9+
columns: string[];
510
}
611

712
class Node<T> {
@@ -10,57 +15,72 @@ class Node<T> {
1015
constructor(public data: T) {}
1116
}
1217

13-
export class Parser {
18+
export class DbParser {
19+
private symbols = ["INTEGER", "NVARCHAR", "DATETIME", "NUMERIC"];
20+
private db: DbDefinition;
21+
private dbType: string;
22+
private dataDefinitions!: Array<string>;
23+
private entities!: Record<string, DbEntityDefinition>;
24+
private relationships!: DbRelationshipDefinition[];
1425

15-
private symbols = ['INTEGER', 'NVARCHAR', 'DATETIME', 'NUMERIC'];
16-
private ast: string;
17-
private dataDefinitions! : Array<string>;
26+
constructor(dbType: string, db: DbDefinition) {
27+
this.db = db;
28+
this.dbType = dbType;
29+
}
1830

19-
constructor(abstractSyntaxTree: string){
20-
this.ast = abstractSyntaxTree;
21-
}
22-
23-
public getSQLDataDefinition(){
24-
const tokens = this.ast.trim().split(" ");
25-
console.log(tokens);
26-
if(tokens[0] !== 'erDiagram'){
27-
throw 'Expecting erDiagram keyword';
28-
}
29-
return this.lexer(tokens);
30-
}
31+
public getSQLDataDefinition() {
32+
this.entities = this.db.getEntities();
33+
this.relationships = this.db.getRelationships();
34+
// const tokens = this.ast.trim().split(" ");
35+
// console.log(tokens);
36+
// if(tokens[0] !== 'erDiagram'){
37+
// throw 'Expecting erDiagram keyword';
38+
// }
39+
return this.lexer();
40+
}
3141

32-
private lexer(tokens : Array<string>): string{
33-
let statementGeneration : Array<string> = [];
34-
for(let i = 1; i < tokens.length; i++){
35-
if(this.symbols.includes(tokens[i])){
36-
throw `Keyword reserved '${tokens[i]}'`;
37-
}
38-
const tableName = tokens[i];
39-
i++;
40-
if(tokens[i] !== "{"){
41-
throw `Expecting '{' got : '${tokens[i]}'`;
42-
}
43-
i++;
44-
while(tokens[i] !== '}' && i < tokens.length){
45-
if(!this.symbols.includes(tokens[i])){
46-
throw `Expecting keyword got : '${tokens[i]}'`;
47-
}
48-
const dataType = tokens[i];
49-
i++;
50-
statementGeneration.push(this.createColumn(tableName, tokens[i], dataType));
51-
i++;
52-
}
53-
statementGeneration.unshift(this.createTable(tableName));
42+
private lexer(): string {
43+
let statementGeneration: Array<string> = [];
44+
if (this.entities) {
45+
for (const key in this.entities) {
46+
if (Object.prototype.hasOwnProperty.call(this.entities, key)) {
47+
const element = this.entities[key];
5448
}
55-
return statementGeneration.join("");
49+
}
5650
}
51+
// for(let i = 1; i < tokens.length; i++){
52+
// if(this.symbols.includes(tokens[i])){
53+
// throw `Keyword reserved '${tokens[i]}'`;
54+
// }
55+
// const tableName = tokens[i];
56+
// i++;
57+
// if(tokens[i] !== "{"){
58+
// throw `Expecting '{' got : '${tokens[i]}'`;
59+
// }
60+
// i++;
61+
// while(tokens[i] !== '}' && i < tokens.length){
62+
// if(!this.symbols.includes(tokens[i])){
63+
// throw `Expecting keyword got : '${tokens[i]}'`;
64+
// }
65+
// const dataType = tokens[i];
66+
// i++;
67+
// statementGeneration.push(this.createColumn(tableName, tokens[i], dataType));
68+
// i++;
69+
// }
70+
// statementGeneration.unshift(this.createTable(tableName));
71+
// }
72+
return statementGeneration.join("");
73+
}
5774

58-
private createTable(tableName: string,){
59-
return `CREATE TABLE ${tableName}`;
60-
}
61-
62-
private createColumn(tableName: string, columnName: string, dataType: string){
63-
return `ALTER TABLE ${tableName } ADD ${columnName} ${dataType}`;
64-
}
75+
private createTable(tableName: string) {
76+
return `CREATE TABLE ${tableName}`;
77+
}
6578

66-
}
79+
private createColumn(
80+
tableName: string,
81+
columnName: string,
82+
dataType: string
83+
) {
84+
return `ALTER TABLE ${tableName} ADD ${columnName} ${dataType}`;
85+
}
86+
}

tests/generate-sql-ddl.spec.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import { Parser } from "../src/generate-sql-ddl";
2-
1+
import { DbParser } from "../src/generate-sql-ddl";
2+
import erDb from "../src/mermaid/src/diagrams/er/erDb";
33
describe("Generate DDL examples", () => {
44
it("Should generate create table SQL syntax", () => {
5-
const abt = `erDiagram artists { }`;
6-
const ddlSyntax = new Parser(abt).getSQLDataDefinition();
7-
expect(ddlSyntax).toBe('CREATE TABLE artists');
5+
const db = erDb;
6+
// `erDiagram artists { }`;
7+
const ddlSyntax = new DbParser('sqlite', db).getSQLDataDefinition();
8+
// expect(ddlSyntax).toBe('CREATE TABLE artists');
89
});
910
});

0 commit comments

Comments
 (0)