forked from rm-hull/sql_graphviz
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsql_graphviz.py
More file actions
95 lines (64 loc) · 3.45 KB
/
sql_graphviz.py
File metadata and controls
95 lines (64 loc) · 3.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#!/usr/bin/env python
import html
import sys
from datetime import datetime
from pyparsing import alphas, alphanums, Literal, Word, Forward, OneOrMore, ZeroOrMore, CharsNotIn, Suppress, QuotedString, Optional
def field_act(s, loc, tok):
fieldName = tok[0].replace('"', '')
fieldSpec = html.escape(' '.join(tok[1::]).replace('"', '\\"'))
return '<tr><td bgcolor="grey96" align="left" port="{0}"><font face="Times-bold">{0}</font> <font color="#535353">{1}</font></td></tr>'.format(fieldName, fieldSpec)
def field_list_act(s, loc, tok):
return "\n ".join(tok)
def create_table_act(s, loc, tok):
return '''
"{tableName}" [
shape=none
label=<
<table border="0" cellspacing="0" cellborder="1">
<tr><td bgcolor="lightblue2"><font face="Times-bold" point-size="20">{tableName}</font></td></tr>
{fields}
</table>
>];'''.format(**tok)
def add_fkey_act(s, loc, tok):
return ' "{tableName}":{keyName} -> "{fkTable}":{fkCol}'.format(**tok)
def other_statement_act(s, loc, tok):
return ""
def join_string_act(s, loc, tok):
return "".join(tok).replace('\n', '\\n')
def quoted_default_value_act(s, loc, tok):
return tok[0] + " " + "".join(tok[1::])
def grammar():
parenthesis = Forward()
parenthesis <<= "(" + ZeroOrMore(CharsNotIn("()") | parenthesis) + ")"
parenthesis.setParseAction(join_string_act)
quoted_string = "'" + OneOrMore(CharsNotIn("'")) + "'"
quoted_string.setParseAction(join_string_act)
quoted_default_value = "DEFAULT" + quoted_string + OneOrMore(CharsNotIn(", \n\t"))
quoted_default_value.setParseAction(quoted_default_value_act)
field_def = OneOrMore(quoted_default_value | Word(alphanums + "_\"'`:-/[].") | parenthesis)
field_def.setParseAction(field_act)
tablename_def = ( Word(alphas + "`_.") | QuotedString("\"") )
field_list_def = field_def + ZeroOrMore(Suppress(",") + field_def)
field_list_def.setParseAction(field_list_act)
create_table_def = Literal("CREATE") + "TABLE" + tablename_def.setResultsName("tableName") + "(" + field_list_def.setResultsName("fields") + ")" + ";"
create_table_def.setParseAction(create_table_act)
add_fkey_def = Literal("ALTER") + "TABLE" + "ONLY" + tablename_def.setResultsName("tableName") + "ADD" + "CONSTRAINT" + Word(alphanums + "_") + "FOREIGN" + "KEY" + "(" + Word(alphanums + "_").setResultsName("keyName") + ")" + "REFERENCES" + Word(alphanums + "._").setResultsName("fkTable") + "(" + Word(alphanums + "_").setResultsName("fkCol") + ")" + Optional(Literal("DEFERRABLE")) + Optional(Literal("ON") + "DELETE" + ( Literal("CASCADE") | Literal("RESTRICT") )) + ";"
add_fkey_def.setParseAction(add_fkey_act)
other_statement_def = OneOrMore(CharsNotIn(";")) + ";"
other_statement_def.setParseAction(other_statement_act)
comment_def = "--" + ZeroOrMore(CharsNotIn("\n"))
comment_def.setParseAction(other_statement_act)
return OneOrMore(comment_def | create_table_def | add_fkey_def | other_statement_def)
def graphviz(filename):
print("/*")
print(" * Graphviz of '%s', created %s" % (filename, datetime.now()))
print(" * Generated from https://github.com/rm-hull/sql_graphviz")
print(" */")
print("digraph g { graph [ rankdir = \"LR\" ];")
for i in grammar().setDebug(False).parseFile(filename):
if i != "":
print(i)
print("}")
if __name__ == '__main__':
filename = sys.stdin if len(sys.argv) == 1 else sys.argv[1]
graphviz(filename)