simple-erd 0.1.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8614975c029b989cdb575295e93ff68f8cbf2b69
4
+ data.tar.gz: c7d877e22ab7a082d0f3c2383cb30b891fdf2f3e
5
+ SHA512:
6
+ metadata.gz: 50600242c993bc3124cc2009702a9269e1078c69723b1f37cc6c2ca5804f99950efd2f954dbf398dbf36c2e0e03cfd0ad7ef3844ff3b2e931571efe2639d3488
7
+ data.tar.gz: b561d60e38097db0f514dceec0a51555285f5205eb498e353cf3e37d07ab4112a7e255e19d7911082a43a166270e35a2876f6f6a15f6e29afd0ef32944307292
data/LICENCE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017 IEVGEN PYROGOV
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,90 @@
1
+ # SimpleERD
2
+
3
+ SimpleERD is a tool to generate beautiful ERD digrams from plain text.
4
+
5
+ SimpleERD started out as an experiment and is currently at its early stage of development. Consider it a working prototype. SimpleERD is written in Ruby, but this is likely subject for a change.
6
+
7
+ ## Installation
8
+
9
+ There are two installation options on macOS:
10
+
11
+ * via [`homebrew`](https://brew.sh):
12
+
13
+ ```bash
14
+ $ brew tap gmile/apps
15
+ $ brew install simple-erd --HEAD
16
+ ```
17
+
18
+ * via [`rubygems`](https://rubygems.org):
19
+
20
+ 1. make sure to have `graphviz` installed:
21
+
22
+ ```bash
23
+ $ brew install graphviz
24
+ ```
25
+
26
+ 2. intall the gem:
27
+
28
+ ```bash
29
+ $ gem install simple-erd
30
+ ```
31
+
32
+ ## Usage
33
+
34
+ SimpleERD requires a text file as an input. Input file contains text formatted the following way:
35
+
36
+ ```
37
+ [entity_1]
38
+ attribute | type
39
+
40
+ [entity_2]
41
+ attribute | type | modifier
42
+
43
+ [entity_3]
44
+ attribute
45
+
46
+ (entity_group_1)
47
+ entity_1
48
+ entity_2
49
+
50
+ (entity_group_2)
51
+ entity_3
52
+
53
+ entity_1 ?--1 entity_2
54
+ entity_3 *--n entity_2
55
+ ```
56
+
57
+ Here, `[entity_1]` starts a block, indicating an entity. Right below `[entity_1]` come entity attributes. An entity attribute is defined by a `attribute_name`, `type` (optional and `modifier` (optional).
58
+
59
+ At the bottom of input file – relations between entities. Syntax for relations:
60
+
61
+ * `?` – 0 or 1
62
+ * `1` – exactly 1
63
+ * `*` – 0 or more
64
+ * `+` – 1 or more
65
+ * `x` – relation is undefined, will render as `???` in the output.
66
+
67
+ ## Examples
68
+
69
+ ```bash
70
+ $ simple-erd -i samples/complex_input.txt -o /tmp/output.pdf
71
+ ```
72
+
73
+ See [/samples](/samples) for more samples.
74
+
75
+ ## Motivation
76
+
77
+ I was inspired by [`erd`](https://github.com/BurntSushi/erd) from [Andrew Gallant](https://github.com/BurntSushi), but had a couple of issues with it:
78
+
79
+ * mainly I found it hard, although possible, to install:
80
+
81
+ * `erd` requires haskell runtime to be available, which takes around 1Gb when installed.
82
+ * it is required to install `cabal` and all of `erd`'s dependencies manually.
83
+
84
+ * the libarary doesn't seem to be actively maintained.
85
+
86
+ Also, I wanted to work on the custom styling of the diagram.
87
+
88
+ ## Licence
89
+
90
+ MIT
@@ -0,0 +1,202 @@
1
+ [legal_entity]
2
+ id | VARCHAR(36) | NOT NULL
3
+ name | TEXT | NOT NULL
4
+ short_name | TEXT | NULL
5
+ type | ENUM('msp', 'mis', 'drug_store') | NOT NULL
6
+ edrpou | TEXT | NOT NULL
7
+ addresses[] | JSON | NULL
8
+ phones[] | JSON | NULL
9
+ emails[] | JSON | NULL
10
+ created_at | DATETIME | NOT NULL
11
+ created_by | TEXT | NOT NULL
12
+ updated_at | DATETIME | NULL
13
+ updated_by | TEXT | NULL
14
+ active | TINYINT | NOT NULL
15
+ public_name | VARCHAR(45) | NULL
16
+ kved | JSON | NOT NULL
17
+ founders[] | JSON | NOT NULL
18
+ status | ENUM('new', 'verified') | NOT NULL
19
+ owner_property_type | ENUM('state', 'private') | NOT NULL
20
+ legal_form | ENUM('ТОВ', 'ФОП') | NOT NULL
21
+
22
+ [doctor]
23
+ id | VARCHAR(36) | NOT NULL
24
+ education[] | JSON | NOT NULL
25
+ qualification[] | JSON | NULL
26
+ speciality[] | ENUM('терапевт', 'педіатр', 'сімейний лікар') | NOT NULL
27
+ professional_level | JSON | NOT NULL
28
+ science_degree | JSON | NULL
29
+ academic_degree | JSON | NULL
30
+ specialization | TEXT | NULL
31
+
32
+ [party]
33
+ id | VARCHAR(36) | NOT NULL
34
+ last_name | TEXT | NOT NULL
35
+ first_name | TEXT | NOT NULL
36
+ second_name | TEXT | NULL
37
+ birth_date | DATE | NOT NULL
38
+ gender | ENUM('GENDER') | NOT NULL
39
+ tax_id | TEXT | NULL
40
+ national_id | TEXT | NULL
41
+ documents | JSON | NULL
42
+ phones | JSON | NULL
43
+ created_at | DATETIME | NOT NULL
44
+ created_by | TEXT | NOT NULL
45
+ updated_at | DATETIME | NOT NULL
46
+ updated_by | TEXT | NOT NULL
47
+
48
+ [employee_doctor]
49
+ id | VARCHAR(36) NOT | NULL
50
+ education[] | JSON | NOT NULL
51
+ qualification[] | JSON | NULL
52
+ speciality[] | ENUM('терапевт', 'педіатр', 'сімейний лікар') | NOT NULL
53
+ professional_level | JSON | NOT NULL
54
+ science_degree | JSON | NULL
55
+ academic_degree | JSON | NULL
56
+ specialization | TEXT | NULL
57
+ working_hours | TEXT | NULL
58
+
59
+ [division]
60
+ id | VARCHAR(36) | NOT NULL
61
+ msp_id | TEXT | NOT NULL
62
+ name | VARCHAR(45) | NOT NULL
63
+ address | JSON | NOT NULL
64
+ external_id | TEXT | NULL
65
+ phones[] | JSON | NULL
66
+ email | JSON | NULL
67
+
68
+ [employee]
69
+ id | VARCHAR(36) | NOT NULL
70
+ legal_entity_id | TEXT | NOT NULL
71
+ position | TEXT | NOT NULL
72
+ start_date | DATETIME | NOT NULL
73
+ end_date | DATETIME | NULL
74
+ active | TINYINT | NOT NULL
75
+ created_at | TIMESTAMP | NOT NULL
76
+ updated_at | TIMESTAMP | NOT NULL
77
+ created_by | TEXT | NOT NULL
78
+ updated_by | TEXT | NOT NULL
79
+ status | ENUM('') | NOT NULL
80
+ employee_type | ENUM('doctor', 'hr', 'owner', 'accountant') | NOT NULL
81
+ party_id | TEXT | NOT NULL
82
+ division_id | VARCHAR(45) | NOT NULL
83
+
84
+ [declaration_signed]
85
+ id | VARCHAR(36) | NOT NULL
86
+ document_type | ENUM('declaration', 'msp_registration') | NOT NULL
87
+ document | TEXT | NOT NULL
88
+ content | TEXT | NOT NULL
89
+ public_key | TEXT | NOT NULL
90
+
91
+ [msp]
92
+ id | VARCHAR(36) | NOT NULL
93
+ mountain_group | ENUM('') | NOT NULL
94
+ accreditation[] | JSON | NOT NULL
95
+ license[] | JSON | NOT NULL
96
+
97
+ [capitation_contract]
98
+ id | VARCHAR(36) | NOT NULL
99
+ msp_id | TEXT | NOT NULL
100
+ product_id | TEXT | NOT NULL
101
+ start_date | DATETIME | NOT NULL
102
+ end_date | DATETIME | NULL
103
+ status | ENUM('') | NOT NULL
104
+ signed_at | DATETIME | NULL
105
+ services[] | JSON | NULL
106
+
107
+ [product]
108
+ id | VARCHAR(36) | NOT NULL
109
+ name | TEXT | NOT NULL
110
+ parameters[] | JSON | NOT NULL
111
+
112
+ [declaration_request]
113
+ id | VARCHAR(36) | NOT NULL
114
+ f1 | VARCHAR(45) | NULL
115
+ f2 | VARCHAR(45) | NULL
116
+
117
+ [declaration]
118
+ id | VARCHAR(36) | NOT NULL
119
+ patient_id | TEXT | NOT NULL
120
+ start_date | DATETIME | NOT NULL
121
+ end_date | DATETIME | NOT NULL
122
+ legal_entity_id | TEXT | NOT NULL
123
+ status | ENUM('') | NOT NULL
124
+ signed_at | DATETIME | NULL
125
+ created_at | DATETIME | NOT NULL
126
+ created_by | TEXT | NOT NULL
127
+ updated_at | DATETIME | NOT NULL
128
+ updated_by | TEXT | NOT NULL
129
+ active | TINYINT | NULL
130
+ scope | ENUM('') | NULL
131
+ employee_id | TEXT | NOT NULL
132
+ declaration_signed_id | INT | NOT NULL
133
+
134
+ [log_changes]
135
+ id | VARCHAR(36) | NOT NULL
136
+ user_id | VARCHAR(45) | NOT NULL
137
+ resource | TEXT | NOT NULL
138
+ what_changed | JSON | NOT NULL
139
+ TS | TIMESTAMP | NOT NULL
140
+
141
+ [legal_entity_requests]
142
+ id | INT | NOT NULL
143
+ legal_entity_data | VARCHAR(45) | NULL
144
+
145
+ [registration_requests]
146
+ id | VARCHAR(36) | NOT NULL
147
+ msp_id | VARCHAR(45) | NULL
148
+ creator_id | VARCHAR(45) | NOT NULL
149
+ data | JSON | NOT NULL
150
+ email | TEXT | NOT NULL
151
+ creator_signature | TEXT | NOT NULL
152
+ status | ENUM('') | NOT NULL
153
+ verification_id | VARCHAR(45) | NOT NULL
154
+
155
+ [users]
156
+ id | VARCHAR(36) | NOT NULL
157
+ email | TEXT | NOT NULL
158
+ user_name | VARCHAR(45) | NOT NULL
159
+ inserted_at | DATETIME | NOT NULL
160
+ inserted_by | TEXT | NOT NULL
161
+ updated_at | DATETIME | NOT NULL
162
+ updated_by | TEXT | NOT NULL
163
+ status | ENUM('') | NOT NULL
164
+ credentials | JSON | NOT NULL
165
+ party_id | VARCHAR(26) | NULL
166
+ scopes[] | TEXT | NOT NULL
167
+
168
+ (PRM)
169
+ party
170
+ doctor
171
+ division
172
+ msp
173
+ employee
174
+ legal_entity
175
+ capitation_contract
176
+ product
177
+ employee_doctor
178
+
179
+ (Auth)
180
+ users
181
+ registration_requests
182
+
183
+ (OPS_DB)
184
+ declaration
185
+ declaration_request
186
+
187
+ (Media Storage)
188
+ declaration_signed
189
+
190
+ party 1--? doctor
191
+ party 1--+ employee
192
+ employee *--1 division
193
+ employee *--1 legal_entity
194
+ division +--1 legal_entity
195
+ msp +--1 legal_entity
196
+ product x--1 legal_entity
197
+ capitation_contract *--1 product
198
+ capitation_contract 1--x product
199
+ employee 1--? employee_doctor
200
+ employee 1--* declaration
201
+ declaration ?--1 declaration_signed
202
+ party ?--+ users
@@ -0,0 +1,13 @@
1
+ [Person]
2
+ *name
3
+ height
4
+ weight
5
+ +birth_location_id
6
+
7
+ [Location]
8
+ *id
9
+ city
10
+ state
11
+ country
12
+
13
+ Person 1--1 Location
data/simple-erd ADDED
@@ -0,0 +1,182 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+
5
+ required_options = {
6
+ input: nil,
7
+ output: nil,
8
+ output_format: "pdf"
9
+ }
10
+
11
+ OptionParser.new do |parser|
12
+ parser.on("-i", "--input PATH", "A path to the input file.") do |v|
13
+ required_options[:input] = v
14
+ end
15
+
16
+ parser.on("-o", "--output PATH", "A path to the output file.") do |v|
17
+ required_options[:output] = v
18
+ end
19
+
20
+ parser.on("-f", "--format FORMAT", "Output file format. See a list of available formats here: http://www.graphviz.org/doc/info/output.html") do |v|
21
+ required_options[:output_format] = v
22
+ end
23
+ end.parse!
24
+
25
+ required_options.each do |key, value|
26
+ if required_options[key].nil?
27
+ puts "Please, specify '#{key}' parameter."
28
+ puts ""
29
+ puts "For further help, run:"
30
+ puts ""
31
+ puts " simple-erd --help"
32
+
33
+ exit(1)
34
+ end
35
+ end
36
+
37
+ input_filename = required_options[:input]
38
+ output_filename = required_options[:output]
39
+ output_format = required_options[:output_format]
40
+
41
+ input = IO.read(input_filename)
42
+
43
+ node_template = %{
44
+ "%{entity_name}" [label=<%{entity_contents}>]
45
+ }
46
+
47
+ table_template = %(
48
+ <table border="0" cellborder="0" cellspacing="0" bgcolor="#FFFFFF">
49
+ <tr>
50
+ <td colspan="3" border="1" bgcolor="#EEEEEE" cellpadding="0"><font face="PT Mono"><b>%{entity_name}</b></font></td>
51
+ </tr>
52
+ %{attributes}
53
+ </table>
54
+ )
55
+
56
+ row_template = %Q(
57
+ <tr>
58
+ <td border="1" sides="l%{b}" align="left" port="id"><font face="PT Mono">%{column_name}&nbsp;</font></td>
59
+ <td %{draw_bottom} align="left"><font color="#999999" face="PT Mono">%{column_type}&nbsp;</font></td>
60
+ <td border="1" sides="r%{b}" align="left"><font color="#CCCCCC" face="PT Mono">%{null_or_not}</font></td>
61
+ </tr>
62
+ )
63
+
64
+ edge_template = %{%{from} -> %{to} [headlabel="%{to_n}", taillabel="%{from_n}", arrowtail=odot, arrowhead=none, style="%{line_type}", fontname="PT Mono"]}
65
+
66
+ @cluster_n = 0
67
+
68
+ contents =
69
+ input.split("\n\n").map do |group|
70
+ lines = group.strip.split("\n")
71
+
72
+ case
73
+ when lines[0].start_with?("[")
74
+ entity_name = lines[0].scan(/\w+/)[0]
75
+
76
+ n_of_attributes = lines[1..-1].size
77
+
78
+ if entity_name[-1] != "s"
79
+ puts "Warning: '#{entity_name}' table name must be in plural form"
80
+ end
81
+
82
+ attributes =
83
+ lines[1..-1].map.with_index do |line, idx|
84
+ match = line.match /(?<a>.[^\|]*)\s?\|?\s?(?<b>.[^\|]*)?\s?\|?\s?(?<c>.[^\|]*)?/
85
+
86
+ draw_bottom = idx == n_of_attributes - 1
87
+
88
+ if !(match[:a].strip.match? /^\w+$/)
89
+ if match[:a].strip.end_with?("[]")
90
+ puts "Warning: '#{entity_name}'.'#{match[:a]}' ends with '[]'. If it meant to indicate an array, consider making the attribute name plural and appending '[]' to the type, e.g.: #{match[:b].strip}[]"
91
+ else
92
+ puts "Warning: '#{entity_name}'.'#{match[:a]}' contains characters, other than A-Za-z_. Please, rename the attribute to only contain only A-Za-z_."
93
+ end
94
+ end
95
+
96
+ if match[:a].strip.end_with?("_id") && match[:b].strip == "TEXT"
97
+ puts "Warning: '#{entity_name}'.'#{match[:a].strip}' looks like a secondary key. Should its type be 'integer' or 'UUID'?"
98
+ end
99
+
100
+ if match[:b].strip == "VARCHAR(36)"
101
+ puts "Warning: '#{entity_name}'.'#{match[:a].strip}' is a UUID? Consider using built-in type, UUID"
102
+ end
103
+
104
+ if match[:c] == "NULL"
105
+ puts "Warning: '#{entity_name}'.'#{match[:a].strip}' - no need to specify explitit NULL"
106
+ end
107
+
108
+ (row_template % {
109
+ column_name: match[:a],
110
+ column_type: match[:b],
111
+ null_or_not: match[:c] || "&nbsp;",
112
+ b: draw_bottom ? "b" : "",
113
+ draw_bottom: draw_bottom ? 'border="1" sides="b"' : ""
114
+ }).strip
115
+ end.join("\n")
116
+
117
+ table =
118
+ table_template % {
119
+ entity_name: entity_name,
120
+ attributes: attributes
121
+ }
122
+
123
+ node_template % {
124
+ entity_name: entity_name,
125
+ entity_contents: table
126
+ }
127
+ when lines[0].start_with?("(")
128
+ cluster_name = lines[0].match(/\((.*)\)/)[1]
129
+
130
+ @cluster_n += 1
131
+
132
+ %Q{
133
+ subgraph cluster_#{@cluster_n} {
134
+ label = "#{cluster_name}";
135
+ labeljust = "l";
136
+ style=filled;
137
+ fontname = "PT Mono";
138
+ color="#f0f1fe";
139
+
140
+ #{lines[1..-1].join(",")};
141
+ }
142
+ }
143
+ else
144
+ lines.map do |line|
145
+ from, relation, to = line.split(" ")
146
+ from_n, to_n = relation.split("--")
147
+
148
+ t = ->(string) {
149
+ case string
150
+ when "?" then "0..1"
151
+ when "1" then "1"
152
+ when "*" then "0..n"
153
+ when "+" then "1..n"
154
+ when "x" then "???"
155
+ end
156
+ }
157
+
158
+ line_type = "dashed"
159
+
160
+ edge_template % {
161
+ line_type: line_type,
162
+ from: from,
163
+ from_n: t.(from_n),
164
+ to: to,
165
+ to_n: t.(to_n),
166
+ }
167
+ end
168
+ end
169
+ end.join("\n")
170
+
171
+ File.open("test.dot", "w+") do |f|
172
+ f.puts "
173
+ digraph G {
174
+ node [shape=plaintext]
175
+
176
+ #{contents}
177
+ }
178
+ "
179
+ end
180
+
181
+ `dot test.dot -T#{output_format} > #{output_filename}`
182
+ `open #{output_filename}`
metadata ADDED
@@ -0,0 +1,48 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple-erd
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Eugene Pirogov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-04-23 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A tool to generate ERD diagrams
14
+ email: iamexile@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - LICENCE
20
+ - README.md
21
+ - samples/complex_input.txt
22
+ - samples/simple_input.txt
23
+ - simple-erd
24
+ homepage: http://rubygems.org/gems/simple-erd
25
+ licenses:
26
+ - MIT
27
+ metadata: {}
28
+ post_install_message:
29
+ rdoc_options: []
30
+ require_paths:
31
+ - lib
32
+ required_ruby_version: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ required_rubygems_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ requirements: []
43
+ rubyforge_project:
44
+ rubygems_version: 2.6.11
45
+ signing_key:
46
+ specification_version: 4
47
+ summary: A tool to generate ERD diagrams
48
+ test_files: []