erdb 1.0.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
+ SHA256:
3
+ metadata.gz: 25ee47da83fb1accfed1d03d3c4fa6b0639640961180bfe86985a9f272bac629
4
+ data.tar.gz: 345bc5e3caf6f76a70dbc7af2c237770c9e7938e5bd39eddfeb34d5f14cba870
5
+ SHA512:
6
+ metadata.gz: 6da4c1fc2b88e3507e6e364edc27f6bb9abe7d6a3d01002224294cb2c7c302edd594cbeea0efa5d06fdb7ab7516f1c0ac0b34db9084acf488b718b26429a8970
7
+ data.tar.gz: 72beed6a8e53f9e1bd19360f1796980797bdfb35e5df889294602df85105cb3d5fe9773abeed0fabdcac20e69ce1f74f1709f7f3c1ff5efe5fbd6519a5c12aec
data/CHANGES.md ADDED
@@ -0,0 +1,6 @@
1
+ ### 1.0.0
2
+
3
+ - Initial release
4
+ - Added ERD generation for SQLite, PostgreSQL and MySQL
5
+ - Use [Azimutt](https://azimutt.app) to generate the diagrams
6
+ - Use [DBDiagram](https://dbdiagram.io) to generate the diagrams
data/README.md ADDED
@@ -0,0 +1,75 @@
1
+ # ERDB [![Gem Version](https://badge.fury.io/rb/erdb.svg)](https://badge.fury.io/rb/erdb) [![Ruby Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)](https://github.com/rubocop/rubocop)
2
+
3
+ ERDB is a Ruby Gem for generation Entity-Relationship Diagrams (ERD).
4
+ Currently it support `sqlite3`, `mysql2` and `postgresql` database.
5
+ ERDB is just a wrapper to automate the process of generating ERD using -
6
+
7
+ - [Azimutt(Open Source)](https://azimutt.app)
8
+ - [DBDiagram](https://dbdiagram.io)
9
+
10
+ > Currently there is no support for `one-to-one` relationship. If you want to use it you have to manually edit the generated ERD.
11
+
12
+ <!-- graphviz coming soon -->
13
+
14
+ ## Demo
15
+
16
+ ![erdb](./images/erdb.gif)
17
+
18
+ ## Requirements
19
+
20
+ - Ruby 2.7.0 or higher
21
+ - Chrome Browser.
22
+
23
+ ## Installation
24
+
25
+ Use the package manager [gem](https://rubygems.org/) to install ERDB.
26
+
27
+ ```bash
28
+ gem install erdb
29
+ ```
30
+
31
+ > Important note for Linux users: The clipboard requires the _xsel_ or the _xclip_ command-line program. On debian and ubuntu, _xsel_ can be installed with: `sudo apt-get install xsel`
32
+ > Visit [clipboard](https://github.com/janlelis/clipboard) for more details.
33
+
34
+ #### Adapters
35
+
36
+ For `mysql2` and `postgresql` database, you have to install the required gem.
37
+ I didn't include them in the gemspec because I don't want to install them if you don't need them.
38
+ Because it depends on native extensions, you'll need a compiler and the development headers for your Ruby and database.
39
+
40
+ ```bash
41
+ gem install mysql2
42
+ gem install pg
43
+ ```
44
+
45
+ ## Usage
46
+
47
+ After install ERDB, you can use `erdb` command to generate ER Diagram.
48
+
49
+ ```bash
50
+ erdb
51
+ ```
52
+
53
+ ## Why I created this gem?
54
+
55
+ I know there are many tools available for generating ERD,
56
+ but I wanted to create a tool that is easy to use and can be used with any database.
57
+ `Azimutt` also support converting schema to ERD, but it's only working well with remote databases.
58
+ If I want to generate local database using `Azimutt`, I have to setup `Azimutt` locally that is alot of step -\_-
59
+
60
+ ## Roadmap
61
+
62
+ - [x] Support `sqlite3`, `mysql2` and `postgresql` database.
63
+ - [x] Generate ERD using Azimutt
64
+ - [x] Generate ERD using DBDiagram
65
+ - [ ] Support `MongoDB` database.
66
+ - [ ] Generate ERD using Graphviz
67
+
68
+ ## Contributing
69
+
70
+ Pull requests are welcome. Feel free to open an issue first to discuss what you would like to change.
71
+
72
+ ## License
73
+
74
+ This project is licensed under [MIT](https://choosealicense.com/licenses/mit/) license.
75
+ View [LICENSE](./LICENSE) for more details.
data/bin/erdb ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/erdb"
4
+
5
+ ERDB::Cli.start(ARGV)
@@ -0,0 +1,60 @@
1
+ module ERDB
2
+ class Db
3
+ #
4
+ # @param adapter [String] The adapter to use.
5
+ # @param database [String] The database to connect to.
6
+ # @return [void]
7
+ #
8
+ def initialize(adapter, database)
9
+ @adapter = adapter
10
+ @database = database
11
+ end
12
+
13
+ #
14
+ # Connect to a database.
15
+ #
16
+ def connect
17
+ raise "[connect] Not implemented."
18
+ end
19
+
20
+ #
21
+ # Disconnect from a database.
22
+ #
23
+ def disconnect
24
+ raise "[disconnect] Not implemented."
25
+ end
26
+
27
+ #
28
+ # Convert database tables to ERD convertable Array.
29
+ # @return [Array] The converted hash format. see example result below.
30
+ #
31
+ # @example Example result:
32
+ # ```ruby
33
+ # [
34
+ # {
35
+ # name: "table_name",
36
+ # is_join_table: false,
37
+ # columns: [{ name: "column_name", type: "column_type" }, ...],
38
+ # relations: [
39
+ # {
40
+ # from: {
41
+ # table: "table_name",
42
+ # column: "column_name"
43
+ # },
44
+ # to: {
45
+ # table: "table_name",
46
+ # column: "column_name"
47
+ # }
48
+ # }
49
+ # ...
50
+ # ]
51
+ # }
52
+ # ...
53
+ # ]
54
+ # ```
55
+ #
56
+ def to_erdb
57
+ raise "[to_erdb] Not implemented."
58
+ end
59
+ end
60
+ end
@@ -0,0 +1 @@
1
+ # Planning to use this file to create a NoSQL database for the project
@@ -0,0 +1,114 @@
1
+ require "active_record"
2
+ require_relative "db"
3
+
4
+ module ERDB
5
+ class SQL < Db
6
+ #
7
+ # Initialize a new SQL instance.
8
+ #
9
+ def initialize(adapter, database)
10
+ super
11
+
12
+ @db = ActiveRecord::Base
13
+ @connection = nil
14
+ end
15
+
16
+ #
17
+ # Connect to a database.
18
+ #
19
+ def connect
20
+ puts "\n"
21
+ puts "Connecting to #{@adapter} database..."
22
+
23
+ case @adapter.to_sym
24
+ when :sqlite3
25
+ connect_sqlite3
26
+ when :postgresql, :mysql2
27
+ connect_with_connection_string
28
+ else
29
+ raise "Adapter not supported."
30
+ end
31
+
32
+ @connection = @db.connection
33
+ end
34
+
35
+ #
36
+ # Convert database tables to ERD convertable Array.
37
+ #
38
+ def to_erdb
39
+ puts "\nAnalyzing database..."
40
+ @connection.tables.map do |table|
41
+ columns = @connection.columns(table).map { |column| { name: column.name, type: column.type || "unknown" } }
42
+ relations = @connection.foreign_keys(table).map do |fk|
43
+ {
44
+ from: {
45
+ table: table,
46
+ column: fk.options[:column]
47
+ },
48
+ to: {
49
+ table: fk[:to_table],
50
+ column: fk.options[:primary_key]
51
+ }
52
+ }
53
+ end
54
+
55
+ hash = { name: table, columns: columns, relations: relations }
56
+ hash[:is_join_table] = join_table?(hash)
57
+ hash
58
+ end
59
+ end
60
+
61
+ #
62
+ # Disconnect from a database.
63
+ #
64
+ def disconnect
65
+ @db.remove_connection
66
+ @connection = nil
67
+ end
68
+
69
+ private
70
+
71
+ #
72
+ # Check current table is a join table or not.
73
+ #
74
+ # @param table [Hash] The table to check.
75
+ # @return [Boolean] True if the table is a join table, false otherwise.
76
+ #
77
+ def join_table?(table)
78
+ relations = table[:relations]
79
+
80
+ # remove data like id, created_at, updated_at
81
+ columns = table[:columns].map { |c| c[:name] }.reject do |column|
82
+ %w[id created_at updated_at].include?(column)
83
+ end
84
+
85
+ if relations.size == columns.size && relations.size >= 2
86
+ columns.include?(relations[0][:from][:column]) && columns.include?(relations[1][:from][:column])
87
+ else
88
+ false
89
+ end
90
+ end
91
+
92
+ #
93
+ # Connect to a SQLite3 database.
94
+ # @param database [String] The database to connect to.
95
+ # @raise [RuntimeError] If the database does not exist.
96
+ #
97
+ def connect_sqlite3
98
+ raise "Database does not exist." unless File.exist?(@database)
99
+
100
+ @db.establish_connection(
101
+ adapter: :sqlite3,
102
+ database: @database
103
+ )
104
+ end
105
+
106
+ #
107
+ # Connect to a PostgreSQL or MySQL database.
108
+ # @param database [String] The database to connect to.
109
+ #
110
+ def connect_with_connection_string
111
+ @db.establish_connection(@database)
112
+ end
113
+ end
114
+ end
data/lib/erdb/cli.rb ADDED
@@ -0,0 +1,179 @@
1
+ require "json"
2
+
3
+ module ERDB
4
+ class Cli
5
+ class << self
6
+ #
7
+ # Start the CLI.
8
+ # @param [Array] args
9
+ # @return [void]
10
+ #
11
+ def start(_args)
12
+ ARGV.clear
13
+
14
+ welcome
15
+
16
+ db = select_database
17
+
18
+ erd_builder = select_diagram_builder
19
+
20
+ ERDB.show_join_table = ask_yes_no("\nDo you want to display join tables? (Y/n)", true)
21
+
22
+ db.connect
23
+
24
+ erd_builder.create(db.to_erdb)
25
+ rescue RuntimeError => e
26
+ puts "Error: #{e.message}"
27
+ exit 1
28
+ rescue Interrupt
29
+ puts "\n\nThank you for using ERDB!"
30
+ exit 0
31
+ end
32
+
33
+ private
34
+
35
+ #
36
+ # Ask user which database to use.
37
+ # @return [Db]
38
+ #
39
+ def select_database
40
+ data = {
41
+ sqlite3: { name: "SQLite", gem: "sqlite3" },
42
+ postgresql: { name: "PostgreSQL(Gem 'pg' must be installed)", gem: "pg" },
43
+ mysql2: { name: "MySQL(Gem 'mysql2' must be installed)", gem: "mysql2" }
44
+ }
45
+
46
+ puts "Select a database adapter:"
47
+
48
+ data.each_with_index do |v, i|
49
+ puts "#{i + 1}. #{v[1][:name]}"
50
+ end
51
+
52
+ response = ask_number(1, data.size)
53
+
54
+ adapter = data.keys[response.to_i - 1].to_sym
55
+
56
+ # check if the gem is installed
57
+ # I don't want to include the gem in the gemspec file
58
+ # cuz it's dependencies are too big and depend on the native library
59
+ # I only include sqlite3 gem cuz it's small and doesn't have any dependencies
60
+ gem = data[adapter][:gem]
61
+
62
+ begin
63
+ require gem
64
+ rescue LoadError
65
+ puts "\nError: '#{gem}' gem is not installed."
66
+ puts "Please install the gem '#{gem}' first."
67
+ puts "Run 'gem install #{gem}' to install the gem."
68
+ exit 1
69
+ end
70
+
71
+ database = if adapter == :sqlite3
72
+ ask_file "\nEnter the path to the database file:"
73
+ else
74
+ ask "\nEnter the database connection string:"
75
+ end
76
+
77
+ return SQL.new(adapter, database) if %i[sqlite3 mysql2 postgresql].include?(adapter)
78
+
79
+ raise "Invalid database adapter"
80
+ end
81
+
82
+ #
83
+ # Select a diagram builder.
84
+ # @return [ERDProvider]
85
+ #
86
+ def select_diagram_builder
87
+ data = [Azimutt, DBDiagram]
88
+
89
+ puts "\nSelect a diagram builder:"
90
+
91
+ data.each_with_index do |v, i|
92
+ puts "#{i + 1}. #{v.name.split('::').last}"
93
+ end
94
+
95
+ response = ask_number(1, data.size)
96
+
97
+ data[response.to_i - 1]
98
+ end
99
+
100
+ #
101
+ # Display welcome message.
102
+ #
103
+ def welcome
104
+ puts <<~WELCOME
105
+ .----------------. .----------------. .----------------. .----------------.
106
+ | .--------------. || .--------------. || .--------------. || .--------------. |
107
+ | | _________ | || | _______ | || | ________ | || | ______ | |
108
+ | | |_ ___ | | || | |_ __ \\ | || | |_ ___ `. | || | |_ _ \\ | |
109
+ | | | |_ \\_| | || | | |__) | | || | | | `. \\ | || | | |_) | | |
110
+ | | | _| _ | || | | __ / | || | | | | | | || | | __'. | |
111
+ | | _| |___/ | | || | _| | \\ \\_ | || | _| |___.' / | || | _| |__) | | |
112
+ | | |_________| | || | |____| |___| | || | |________.' | || | |_______/ | |
113
+ | | | || | | || | | || | | |
114
+ | '--------------' || '--------------' || '--------------' || '--------------' |
115
+ '----------------' '----------------' '----------------' '----------------'
116
+
117
+ ERDB is an automate tool to generate Entity-Relationship Diagrams from a database.
118
+ It use Azimutt and DBDiagram to generate the diagrams.
119
+
120
+ WELCOME
121
+ end
122
+
123
+ #
124
+ # Ask a question to the user.
125
+ # @param [String] question
126
+ # @return [String]
127
+ #
128
+ def ask(question = nil)
129
+ puts question if question
130
+ print "> "
131
+ gets.chomp
132
+ end
133
+
134
+ #
135
+ # Ask a number input to the user.
136
+ # @param [Integer] min
137
+ # @param [Integer] max
138
+ # @return [Integer]
139
+ #
140
+ def ask_number(min, max)
141
+ response = nil
142
+ until response.to_i.between?(min, max)
143
+ response = ask
144
+ unless response.match(/^\d+$/)
145
+ puts "Please enter a number"
146
+ response = nil
147
+ end
148
+
149
+ unless response.to_i.between?(min, max)
150
+ puts "Please enter a number between #{min} and #{max}"
151
+ response = nil
152
+ end
153
+ end
154
+ response
155
+ end
156
+
157
+ def ask_file(question)
158
+ loop do
159
+ file = ask question
160
+ return file if File.exist?(file)
161
+
162
+ puts "Invalid file path"
163
+ end
164
+ end
165
+
166
+ #
167
+ # Ask a yes/no question to the user.
168
+ # @param [String] question
169
+ # @param [Boolean] default
170
+ # @return [Boolean]
171
+ #
172
+ def ask_yes_no(question, default = true)
173
+ result = ask question
174
+
175
+ result.empty? ? default : result.downcase == "y"
176
+ end
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,134 @@
1
+ require "clipboard"
2
+ require "watir"
3
+
4
+ module ERDB
5
+ class Azimutt < ERDProvider
6
+ class << self
7
+ #
8
+ # Create a new ER Diagram using https://azimutt.app/.
9
+ # @param [Hash] tables
10
+ #
11
+ def create(tables)
12
+ converted_data = to_aml(tables)
13
+
14
+ Utils.display_output(converted_data, "Azimutt")
15
+
16
+ start_automation(converted_data)
17
+ end
18
+
19
+ private
20
+
21
+ #
22
+ # Start the automation process to generate the ER Diagram.
23
+ # @param [String] data
24
+ # @return [void]
25
+ #
26
+ def start_automation(data)
27
+ browser = Watir::Browser.new(ERDB.default_browser)
28
+
29
+ browser.goto "https://azimutt.app/new"
30
+
31
+ browser.span(text: "From scratch (db design)").click
32
+
33
+ browser.button(id: "create-project-btn").click
34
+
35
+ textarea = browser.textarea(id: "source-editor")
36
+ textarea.click
37
+
38
+ old_clipboard = Clipboard.paste
39
+ Clipboard.copy(data)
40
+
41
+ # set! sometimes doesn't work cuz azimutt automatically reset incorrectly formatted data
42
+ # and set is also slow as hell better to use send_keys
43
+ # sometime naive is better than smart lol
44
+ #
45
+ # textarea.set(data)
46
+
47
+ control = Utils.is_mac? ? :command : :control
48
+ browser.send_keys control, "v"
49
+
50
+ Clipboard.copy(old_clipboard)
51
+
52
+ # rubocop:disable Lint/MissingCopEnableDirective
53
+ # rubocop:disable Layout/LineLength
54
+ btn = browser.button(class: "-ml-px rounded-r-md relative inline-flex items-center p-2 border border-gray-300 text-sm font-medium focus:z-10 focus:outline-none focus:ring-1 focus:ring-primary-500 focus:border-primary-500 bg-white text-gray-700 hover:bg-gray-50")
55
+
56
+ btn.click if btn.exists?
57
+
58
+ puts "Enter 'q' to exit."
59
+
60
+ loop do
61
+ v = gets.chomp
62
+ break if v == "q"
63
+ end
64
+
65
+ browser.close
66
+ end
67
+
68
+ #
69
+ # Convert the data to AML(Azimutt Markup Language) format.
70
+ #
71
+ # @param [Hash] tables
72
+ # @return [String]
73
+ #
74
+ def to_aml(tables)
75
+ str = ""
76
+ tables.each_with_index do |table, i|
77
+ if table[:is_join_table] && !ERDB.show_join_table?
78
+ str += to_many_to_many_str(table)
79
+ next
80
+ end
81
+
82
+ str += "\n\n" if i.positive?
83
+ str += "#{table[:name]}\n"
84
+ str += table[:columns].map { |c| to_column(c[:name], c[:type]) }.join("\n")
85
+
86
+ # relations
87
+ r = table[:relations]
88
+ next if r.nil? || r.empty?
89
+
90
+ r.each do |relation|
91
+ str += "\n"
92
+ f = relation[:from]
93
+ t = relation[:to]
94
+
95
+ str += "fk #{f[:table]}.#{f[:column]} -> #{t[:table]}.#{t[:column]}"
96
+ end
97
+ end
98
+ str
99
+ end
100
+
101
+ #
102
+ # Convert a column to a string.
103
+ # @param [String] name
104
+ # @param [String] type
105
+ #
106
+ def to_column(name, type)
107
+ " #{name} #{type}"
108
+ end
109
+
110
+ #
111
+ # Convert a many-to-many table to a AML formatted string.
112
+ # @param [Hash] table
113
+ # @return [String]
114
+ #
115
+ def to_many_to_many_str(table)
116
+ str = "\n"
117
+ relations = Utils.to_many_to_many(table[:relations])
118
+
119
+ # Azimutt doesn't support many-to-many relations
120
+ # so we have to convert it to two one-to-many relations
121
+ # Really weird but does the job :/
122
+ relations.each do |relation|
123
+ relations.each do |other|
124
+ next if relation == other
125
+
126
+ str += "\nfk: #{relation} -> #{other}\n"
127
+ end
128
+ end
129
+
130
+ str
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,121 @@
1
+ require "clipboard"
2
+ require "watir"
3
+
4
+ module ERDB
5
+ class DBDiagram < ERDProvider
6
+ class << self
7
+ #
8
+ # Create a new ER Diagram using https://dbdiagram.io
9
+ # @param [Hash] tables
10
+ #
11
+ def create(tables)
12
+ converted_data = to_dbdiagram_format(tables)
13
+
14
+ Utils.display_output(converted_data, "DBDiagram")
15
+
16
+ start_automation(converted_data)
17
+ end
18
+
19
+ private
20
+
21
+ #
22
+ # Start the automation process to generate the ER Diagram.
23
+ # @param [String] data
24
+ # @return [void]
25
+ #
26
+ def start_automation(data)
27
+ browser = Watir::Browser.new(ERDB.default_browser)
28
+
29
+ browser.goto "https://dbdiagram.io/d"
30
+
31
+ editor = browser.div(class: "view-lines monaco-mouse-cursor-text")
32
+ editor.click
33
+
34
+ control = Utils.is_mac? ? :command : :control
35
+
36
+ browser.send_keys control, "a"
37
+ browser.send_keys :delete
38
+
39
+ old_clipboard = Clipboard.paste
40
+ # Yep, I know this is ugly.
41
+ # But DBDiagram don't use input element for editor. -_-
42
+ Clipboard.copy(data)
43
+
44
+ browser.send_keys control, "v"
45
+
46
+ Clipboard.copy(old_clipboard)
47
+
48
+ puts "Enter 'q' to exit."
49
+
50
+ loop do
51
+ v = gets.chomp
52
+ break if v == "q"
53
+ end
54
+
55
+ browser.close
56
+ end
57
+
58
+ #
59
+ # Convert the data DBDiagram string format.
60
+ #
61
+ # @param [Hash] tables
62
+ # @return [String]
63
+ #
64
+ def to_dbdiagram_format(tables)
65
+ str = ""
66
+ tables.each_with_index do |table, i|
67
+ if table[:is_join_table] && !ERDB.show_join_table?
68
+ str += to_many_to_many_str(table)
69
+ next
70
+ end
71
+
72
+ str += "\n" if i.positive?
73
+ str += "Table #{table[:name]} {\n"
74
+ str += table[:columns].map { |c| to_column(c[:name], c[:type]) }.join("\n")
75
+ str += "\n}\n"
76
+
77
+ r = table[:relations]
78
+ next if r.nil? || r.empty?
79
+
80
+ r.each do |relation|
81
+ str += "\n"
82
+ f = relation[:from]
83
+ t = relation[:to]
84
+
85
+ str += "Ref: #{f[:table]}.#{f[:column]} > #{t[:table]}.#{t[:column]}"
86
+ end
87
+
88
+ str += "\n"
89
+ end
90
+ str
91
+ end
92
+
93
+ #
94
+ # Convert a column to a string.
95
+ # @param [String] name
96
+ # @param [String] type
97
+ #
98
+ def to_column(name, type)
99
+ " #{name} #{type}"
100
+ end
101
+
102
+ #
103
+ # Convert a many-to-many table to a dbdiagram formatted string.
104
+ # @param [Hash] table
105
+ # @return [String]
106
+ #
107
+ def to_many_to_many_str(table)
108
+ str = ""
109
+ relations = Utils.to_many_to_many(table[:relations])
110
+
111
+ relations.each_with_index do |relation, i|
112
+ next if i.zero?
113
+
114
+ str += "\nRef: #{relations.first} <> #{relation}\n"
115
+ end
116
+
117
+ str
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,11 @@
1
+ module ERDB
2
+ class ERDProvider
3
+ #
4
+ # Create a new ER Diagram.
5
+ # @param [Hash] tables
6
+ #
7
+ def create(tables)
8
+ raise NotImplementedError
9
+ end
10
+ end
11
+ end
data/lib/erdb/utils.rb ADDED
@@ -0,0 +1,49 @@
1
+ module ERDB
2
+ class Utils
3
+ class << self
4
+ #
5
+ # Display the ER Diagram required data.
6
+ # @param [String] data
7
+ # @param [String] provider
8
+ # @return [void]
9
+ #
10
+ def display_output(data, provider)
11
+ puts "### Copy following output to #{provider} if unexpected error happen ###"
12
+ puts "### Start of output ###\n\n"
13
+ puts data
14
+ puts "\n### End of output ###"
15
+ end
16
+
17
+ #
18
+ # Check if the current OS is macOS.
19
+ # @return [Boolean]
20
+ def is_mac?
21
+ RbConfig::CONFIG["host_os"] =~ /darwin|mac os/
22
+ end
23
+
24
+ #
25
+ # Convert the relations to ER Diagram format.
26
+ # @param [Array] relations
27
+ # @return [Array]
28
+ # @example
29
+ # [
30
+ # {
31
+ # from: {
32
+ # table: "users",
33
+ # column: "id"
34
+ # },
35
+ # to: {
36
+ # table: "posts",
37
+ # column: "user_id"
38
+ # }
39
+ # }
40
+ # ]
41
+ # # => ["users.id", "posts.user_id"]
42
+ def to_many_to_many(relations)
43
+ relations.map do |relation|
44
+ "#{relation[:to][:table]}.#{relation[:to][:column]}"
45
+ end.uniq
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,3 @@
1
+ module ERDB
2
+ VERSION = "1.0.0".freeze
3
+ end
data/lib/erdb.rb ADDED
@@ -0,0 +1,38 @@
1
+ require_relative "erdb/cli"
2
+ require_relative "erdb/version"
3
+ require_relative "erdb/utils"
4
+ require_relative "erdb/providers/erd_provider"
5
+
6
+ module ERDB
7
+ autoload :SQL, File.expand_path("erdb/adapters/sql", __dir__)
8
+ autoload :Azimutt, File.expand_path("erdb/providers/azimutt", __dir__)
9
+ autoload :DBDiagram, File.expand_path("erdb/providers/dbdiagram", __dir__)
10
+
11
+ class << self
12
+ attr_writer :default_timeout, :default_browser, :show_join_table
13
+
14
+ #
15
+ # Default wait time for wait methods.
16
+ # @return [Integer] Default wait time in seconds.
17
+ #
18
+ def default_timeout
19
+ @default_timeout ||= 30
20
+ end
21
+
22
+ #
23
+ # Default browser to use for automation.
24
+ # @return [Symbol]
25
+ #
26
+ def default_browser
27
+ @default_browser ||= :chrome
28
+ end
29
+
30
+ #
31
+ # Show join table in the diagram.
32
+ # @return [Boolean]
33
+ #
34
+ def show_join_table?
35
+ @show_join_table.nil? ? true : @show_join_table
36
+ end
37
+ end
38
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: erdb
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Wai Yan Phyo
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-05-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '7.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '7.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: clipboard
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: sqlite3
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.6'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.6'
55
+ - !ruby/object:Gem::Dependency
56
+ name: watir
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '7.2'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '7.2'
69
+ description: ERDB is a Ruby Gem for generation Entity-Relationship Diagrams (ERD).
70
+ email: oyhpnayiaw@gmail.com
71
+ executables:
72
+ - erdb
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - CHANGES.md
77
+ - README.md
78
+ - bin/erdb
79
+ - lib/erdb.rb
80
+ - lib/erdb/adapters/db.rb
81
+ - lib/erdb/adapters/nosql.rb
82
+ - lib/erdb/adapters/sql.rb
83
+ - lib/erdb/cli.rb
84
+ - lib/erdb/providers/azimutt.rb
85
+ - lib/erdb/providers/dbdiagram.rb
86
+ - lib/erdb/providers/erd_provider.rb
87
+ - lib/erdb/utils.rb
88
+ - lib/erdb/version.rb
89
+ homepage: https://github.com/oyhpnayiaw/erdb
90
+ licenses:
91
+ - MIT
92
+ metadata:
93
+ source_code_uri: https://github.com/oyhpnayiaw/erdb
94
+ rubygems_mfa_required: 'true'
95
+ post_install_message:
96
+ rdoc_options: []
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: 2.7.0
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ requirements: []
110
+ rubygems_version: 3.4.10
111
+ signing_key:
112
+ specification_version: 4
113
+ summary: ERDB is a Ruby Gem for generation Entity-Relationship Diagrams (ERD).
114
+ test_files: []