Skip to content

Commit 7793dee

Browse files
committed
Proposal for a few new features.
* use a line starting with ".." or "__" to insert a separator in a class / table description, and ignore it when generating SQL code; * use HTML tags in comments (e.g. use italic to emphasis them in the graphical view), and remove them in the SQL code; * avoid conflict with reserved words in mySQL; * add a time-stamp and original file name at the top of the generated SQL code; * table name are converted to lower case; * add a minimal help and guide for users; * README.md updated accordingly.
1 parent ec01417 commit 7793dee

File tree

2 files changed

+59
-21
lines changed

2 files changed

+59
-21
lines changed

README.md

+21-12
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ I liked `plantuml` tool for UML diagrams but use it
44
also for visualizing structure of relational database.
55
This script loads plantuml class diagram and generates
66
DDL for MySQL SQL dialect. You may define primary keys
7-
with `#` prefix in field name (it mean protected field
8-
in PlantUML) and define index fields with `+` prefix.
7+
with `#` prefix in field name (it means protected field
8+
in PlantUML) and define index fields with `+` (public field
9+
in PlantUML) prefix.
910

1011
Field type noted after field name as is. Also you may
1112
use comments after `--`.
@@ -17,37 +18,45 @@ For example class definition:
1718
class dummy {
1819
Sample table.
1920
==
20-
#id int(10)
21+
#id int(10) -- A comment
2122
field1 int(10)
23+
.. Comment line, ignored ..
2224
field2 varchar(128)
2325
}
2426

2527
@enduml
2628

2729
will be converted to SQL:
2830

29-
CREATE TABLE IF NOT EXISTS Dummy (
30-
id INT(10),
31+
CREATE TABLE IF NOT EXISTS `dummy` (
32+
id INT(10) COMMENT 'A comment',
3133
field1 INT(10),
3234
field2 VARCHAR(128),
3335
PRIMARY KEY (id));
3436

3537
Text between class name and `==` is table description.
3638
The description of the table is mandatory.
3739
I was too lazy to check for absence of descriptions but
38-
I not lazy to write them in each table of my databases.
40+
not lazy to write them in each table of my databases.
3941

40-
See below result of more complicated sample from [database.plu](database.plu):
42+
A line starting with `..` or `__`, used as a separator
43+
into a class definition, will be ignored.
44+
45+
The HTML markup in comments (after `--`) is stripped.
46+
47+
See below the result of a more complicated sample from [database.plu](database.plu):
4148

4249
![database.png](database.png)
4350

44-
```./plantuml2mysql.py database.plu sampledb```
51+
```bash
52+
./plantuml2mysql.py database.plu sampledb
53+
```
4554

4655
```sql
4756
CREATE DATABASE sampledb CHARACTER SET = utf8 COLLATE = utf8_unicode_ci;
4857
USE sampledb;
4958

50-
CREATE TABLE IF NOT EXISTS user (
59+
CREATE TABLE IF NOT EXISTS `user` (
5160
id SERIAL,
5261
login VARCHAR(16),
5362
mail VARCHAR(64),
@@ -59,7 +68,7 @@ See below result of more complicated sample from [database.plu](database.plu):
5968
INDEX (mail)
6069
);
6170

62-
CREATE TABLE IF NOT EXISTS session (
71+
CREATE TABLE IF NOT EXISTS `session` (
6372
id SERIAL,
6473
uid INT(10) UNSIGNED,
6574
remoteip INT(10) UNSIGNED,
@@ -71,7 +80,7 @@ See below result of more complicated sample from [database.plu](database.plu):
7180
INDEX (lastseen)
7281
);
7382

74-
CREATE TABLE IF NOT EXISTS docs (
83+
CREATE TABLE IF NOT EXISTS `docs` (
7584
id INT(10),
7685
fid INT(10) COMMENT 'link to a file',
7786
aunthorid INT(10),
@@ -81,7 +90,7 @@ See below result of more complicated sample from [database.plu](database.plu):
8190
INDEX (created)
8291
);
8392

84-
CREATE TABLE IF NOT EXISTS files (
93+
CREATE TABLE IF NOT EXISTS `files` (
8594
id SERIAL,
8695
docId INT(10),
8796
title VARCHAR(255),

plantuml2mysql.py

+38-9
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,45 @@
22
#-*-coding:utf-8-*-
33
# Usage: ./plantuml2mysql <dbsource.plu> <dbname>
44
# Author: Alexander I.Grafov <[email protected]>
5+
# See https://github.com/grafov/plantuml2mysql
56
# The code is public domain.
67

78
CHARSET="utf8_unicode_ci"
89

910
import sys
11+
import re
12+
import time
13+
14+
# PlantUML allows some HTML tags in comments.
15+
# We don't want them anymore here...
16+
TAG_RE = re.compile(r'<[^>]+>')
17+
def strip_html_tags(t):
18+
return TAG_RE.sub('', t)
19+
20+
# A minimal help
21+
def print_usage():
22+
print("Convert PlantUML classes schema into mySQL database creation script")
23+
print("Usage:\n", sys.argv[0], "<dbsource.plu> <dbname>")
24+
print("\nSee https://github.com/grafov/plantuml2mysql for details\n")
1025

1126
def main():
27+
# Check arguments (exactly 1 + 2):
28+
if len(sys.argv) != 3:
29+
print_usage()
30+
sys.exit()
31+
try: # Avoid exception on STDOUT
32+
with open(sys.argv[1]) as src:
33+
data = src.readlines()
34+
except:
35+
print("Cannot open file: '" + sys.argv[1] + "'")
36+
sys.exit()
37+
# Add information for future self ;-)
38+
print("# Database created on", time.strftime('%d/%m/%y %H:%M',time.localtime()), "from", sys.argv[1])
1239
print("CREATE DATABASE %s CHARACTER SET = utf8 COLLATE = %s;" % (sys.argv[2], CHARSET))
1340
print("USE %s;\n" % sys.argv[2])
1441
uml = False; table = False; field = False
1542
pk = False; idx = False
1643
primary = []; index = ""
17-
with open(sys.argv[1]) as src:
18-
data = src.readlines()
1944
for l in data:
2045
l = l.strip()
2146
if not l:
@@ -25,15 +50,17 @@ def main():
2550
continue
2651
if not uml:
2752
continue
28-
if l == "--":
29-
continue
53+
if l == "--": # Separator
54+
continue
3055
comment = ""
3156
i = l.split()
32-
fname = i[0]
57+
fname = i[0]
58+
if fname == ".." or fname == "__": # Separators in table definition
59+
continue
3360
if field and ("--" in l):
3461
i, comment = l.split("--", 2)
3562
i = i.split()
36-
pk = False; idx = False
63+
pk = False; idx = False
3764
if fname[0] in ("+", "#"):
3865
if fname[0] == "#":
3966
pk = True
@@ -48,9 +75,10 @@ def main():
4875
if l.startswith("class"):
4976
table = True; field = False
5077
primary = []; index = ""
51-
print("CREATE TABLE IF NOT EXISTS", i[1], "(")
78+
# Table names are quoted and lower cased to avoid conflict with a mySQL reserved word
79+
print("CREATE TABLE IF NOT EXISTS `" + i[1].lower() + "` (")
5280
continue
53-
if table and not field and l == "==":
81+
if table and not field and l == "==": # Seperator after table description
5482
field = True
5583
continue
5684
if field and l == "}":
@@ -66,7 +94,8 @@ def main():
6694
if field and l != "#id":
6795
print(" %-16s %s" % (fname, " ".join(i[2:]).upper()), end="")
6896
if comment:
69-
print(" COMMENT '%s'" % comment.strip(), end="")
97+
# Avoid conflict with apostrophes (use double quotation marks)
98+
print(" COMMENT \"%s\"" % strip_html_tags(comment.strip()), end="")
7099
print(",")
71100
if field and pk:
72101
primary.append(fname)

0 commit comments

Comments
 (0)