dba 2.1.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6d8a51736a883e5fa3608fd0429dbf3a819f2903a2da62d1df26d234952c899d
4
- data.tar.gz: bcdb786558aab8e9235324eeb06e073bff126c73abd680213f030d8560cc5306
3
+ metadata.gz: da758f6bcc3df6dac6998bebc89cbe8d9de6e50a318bb1a0b471336df4a219e3
4
+ data.tar.gz: 0a20d9f33e0930b9dde939ac3edea265e74a95a92a5c9dbdaa68165c963158f8
5
5
  SHA512:
6
- metadata.gz: 5fefa4be5caa1d897e9a3e330b6535351f5f503cc4b351e37cf8a7ef8b30f93555491bf5c09836c8b43f13c503d3783bb7e9173a2a4c2ca696bc8b5b1c903379
7
- data.tar.gz: c6aea9949fe0b38718bee070cc3772b57b1ecb060b89c6fd497baa27dc30a0b2ed0edbc9b51157d8373ca057fbd85cb0a858f7f7665b3ba94bb99bcee095cc83
6
+ metadata.gz: c8b210d99644562b7d1df35058e04c3e79542058ce4d46d5eddf5575b5164c8d533c8507fd33ff2e58b1ecfad15d935f471144b047924d26cf26464ea41e01cf
7
+ data.tar.gz: d95737e82ce807531b6263bdb0219937ac942ed1d886bea6f1c13e12d9679dd14de12dbb675add906280f96ae5bb455e0f8e92eaf76b902dfd2f495a30ea48a0
data/CHANGES.md CHANGED
@@ -1,3 +1,17 @@
1
+ # 2.3.0
2
+
3
+ * Added diagram command for generating diagrams with Graphviz, DBML, or PlantUML
4
+
5
+ * Usage is now printed to STDOUT instead of STDERR
6
+
7
+
8
+ # 2.2.0
9
+
10
+ * Fixed compatibility with psych 4+
11
+
12
+ * The sample command now excludes nil/null values
13
+
14
+
1
15
  # 2.1.0
2
16
 
3
17
  * Fixed arity check for commands with optional arguments
data/dba.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'dba'
3
- s.version = '2.1.0'
3
+ s.version = '2.3.0'
4
4
  s.license = 'GPL-3.0'
5
5
  s.platform = Gem::Platform::RUBY
6
6
  s.authors = ['Tim Craft']
data/lib/dba/database.rb CHANGED
@@ -73,7 +73,13 @@ module DBA::Database
73
73
  end
74
74
 
75
75
  def database_config
76
- YAML.load(ERB.new(File.read(database_config_path)).result)
76
+ source = ERB.new(File.read(database_config_path)).result
77
+
78
+ if YAML.respond_to?(:unsafe_load)
79
+ YAML.unsafe_load(source)
80
+ else
81
+ YAML.load(source)
82
+ end
77
83
  end
78
84
 
79
85
  def development_database_args
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ class DBA::DBMLPrinter < DBA::DiagramPrinter
4
+ def print_table_start(name)
5
+ @io.puts "Table #{name} {"
6
+ end
7
+
8
+ def print_table_end(name)
9
+ @io.puts '}'
10
+ end
11
+
12
+ def print_column(name, type)
13
+ @io.puts " #{name} #{type}"
14
+ end
15
+
16
+ def print_foreign_key(table, column, other_table, other_column)
17
+ @io.puts %{Ref: #{table}.#{column} > #{other_table}.#{other_column}}
18
+ end
19
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ class DBA::Diagram < DBA::Command
4
+ PRINTERS = {
5
+ '.dbml' => :DBMLPrinter,
6
+ '.dot' => :DOTPrinter,
7
+ '.gv' => :DOTPrinter,
8
+ '.pu' => :PlantUMLPrinter,
9
+ '.puml' => :PlantUMLPrinter,
10
+ }
11
+
12
+ def call(path = nil)
13
+ if path.nil?
14
+ printer = DBA::DOTPrinter.new
15
+ printer.print_diagram(database)
16
+ else
17
+ extension = File.extname(path)
18
+
19
+ printer = PRINTERS.fetch(extension) { raise DBA::Error, 'unsupported file extension' }
20
+ printer = DBA.const_get(printer)
21
+
22
+ File.open(path, 'w+') do |file|
23
+ printer = printer.new(file)
24
+ printer.print_diagram(database)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,67 @@
1
+ class DBA::DiagramPrinter
2
+ def initialize(io = STDOUT)
3
+ @io = io
4
+ end
5
+
6
+ def print_diagram(database)
7
+ print_start
8
+
9
+ @primary_keys = {}
10
+
11
+ table_names = database.tables
12
+
13
+ table_names.each do |name|
14
+ schema_hash = database.schema(name)
15
+
16
+ print_table(name, schema_hash)
17
+ end
18
+
19
+ table_names.each do |table|
20
+ database.foreign_key_list(table).each do |hash|
21
+ column = hash.fetch(:columns).first
22
+
23
+ other_table = hash.fetch(:table)
24
+
25
+ other_column = @primary_keys.fetch(other_table)
26
+
27
+ print_foreign_key(table, column, other_table, other_column)
28
+ end
29
+ end
30
+
31
+ print_end
32
+ end
33
+
34
+ def print_start
35
+ end
36
+
37
+ def print_end
38
+ end
39
+
40
+ def print_table(name, schema_hash)
41
+ print_table_start(name)
42
+
43
+ schema_hash.each do |column_name, info_hash|
44
+ column_type = info_hash[:type] || info_hash[:db_type]
45
+
46
+ if info_hash[:primary_key]
47
+ @primary_keys[name] = column_name
48
+ end
49
+
50
+ print_column(column_name, column_type)
51
+ end
52
+
53
+ print_table_end(name)
54
+ end
55
+
56
+ def print_table_start(name)
57
+ end
58
+
59
+ def print_table_end(name)
60
+ end
61
+
62
+ def print_column(name, type)
63
+ end
64
+
65
+ def print_foreign_key(table, column, other_table, other_column)
66
+ end
67
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ class DBA::DOTPrinter < DBA::DiagramPrinter
4
+ def print_start
5
+ @io.puts 'digraph database {'
6
+ @io.puts ' graph[rankdir="LR",ranksep=1.5,nodesep=0.5];'
7
+ @io.puts ' node[shape="Mrecord",fontname="Helvetica,Arial,sans-serif"];'
8
+ end
9
+
10
+ def print_end
11
+ @io.puts '}'
12
+ end
13
+
14
+ def print_table(name, schema_hash)
15
+ label = [name]
16
+
17
+ schema_hash.each do |column_name, info_hash|
18
+ column_type = info_hash[:type] || info_hash[:db_type]
19
+
20
+ if info_hash[:primary_key]
21
+ @primary_keys[name] = column_name
22
+
23
+ label << "{<#{column_name}>#{column_name}|#{column_type}}"
24
+ else
25
+ label << "{#{column_name}|<#{column_name}>#{column_type}}"
26
+ end
27
+ end
28
+
29
+ label = label.join('|')
30
+
31
+ @io.puts %{ #{name}[label="#{label}"];}
32
+ end
33
+
34
+ def print_foreign_key(table, column, other_table, other_column)
35
+ @io.puts %{ #{table}:#{column} -> #{other_table}:#{other_column};}
36
+ end
37
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ class DBA::PlantUMLPrinter < DBA::DiagramPrinter
4
+ def print_start
5
+ @io.puts '@startuml'
6
+ @io.puts 'left to right direction'
7
+ end
8
+
9
+ def print_end
10
+ @io.puts '@enduml'
11
+ end
12
+
13
+ def print_table_start(name)
14
+ @io.puts "map #{name} {"
15
+ end
16
+
17
+ def print_table_end(name)
18
+ @io.puts '}'
19
+ end
20
+
21
+ def print_column(name, type)
22
+ @io.puts " #{name} => #{type}"
23
+ end
24
+
25
+ def print_foreign_key(table, column, other_table, other_column)
26
+ @io.puts %{#{table}::#{column} *-> #{other_table}::#{other_column}}
27
+ end
28
+ end
data/lib/dba/sample.rb CHANGED
@@ -5,7 +5,7 @@ class DBA::Sample < DBA::Command
5
5
  column_name = column.to_sym if column
6
6
 
7
7
  if column_name
8
- dataset = database[table_name].distinct.select(column_name)
8
+ dataset = database[table_name].exclude(column_name => nil).distinct.select(column_name)
9
9
  dataset.from_self.order(random_function).limit(20).each do |row|
10
10
  puts row[column_name]
11
11
  end
data/lib/dba/shell.rb CHANGED
@@ -30,6 +30,7 @@ module DBA::Shell
30
30
 
31
31
  def commands
32
32
  {
33
+ 'diagram' => :Diagram,
33
34
  'diff' => :Diff,
34
35
  'dump' => :Dump,
35
36
  'edit' => :Edit,
@@ -55,7 +56,7 @@ module DBA::Shell
55
56
  end
56
57
 
57
58
  def print_usage
58
- printer = DBA::Printer.new(STDERR)
59
+ printer = DBA::Printer.new
59
60
  printer.print_usage(program_name, command_parameters)
60
61
 
61
62
  Kernel::exit(1)
data/lib/dba.rb CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2019-2022 TIMCRAFT
1
+ # Copyright (c) 2019-2024 TIMCRAFT
2
2
  #
3
3
  # This program is free software: you can redistribute it and/or modify
4
4
  # it under the terms of the GNU General Public License as published by
@@ -18,9 +18,12 @@ module DBA
18
18
  loader = Zeitwerk::Loader.new
19
19
  loader.tag = File.basename(__FILE__, '.rb')
20
20
  loader.inflector.inflect({
21
- 'dba' => 'DBA',
22
21
  'csv' => 'CSV',
22
+ 'dba' => 'DBA',
23
+ 'dbml_printer' => 'DBMLPrinter',
24
+ 'dot_printer' => 'DOTPrinter',
23
25
  'ldjson' => 'LDJSON',
26
+ 'plant_uml_printer' => 'PlantUMLPrinter',
24
27
  'yaml' => 'YAML'
25
28
  })
26
29
  loader.push_dir(__dir__)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dba
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Craft
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-06 00:00:00.000000000 Z
11
+ date: 2024-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: zeitwerk
@@ -75,13 +75,18 @@ files:
75
75
  - lib/dba/command.rb
76
76
  - lib/dba/csv.rb
77
77
  - lib/dba/database.rb
78
+ - lib/dba/dbml_printer.rb
79
+ - lib/dba/diagram.rb
80
+ - lib/dba/diagram_printer.rb
78
81
  - lib/dba/diff.rb
82
+ - lib/dba/dot_printer.rb
79
83
  - lib/dba/dump.rb
80
84
  - lib/dba/edit.rb
81
85
  - lib/dba/find.rb
82
86
  - lib/dba/indexes.rb
83
87
  - lib/dba/ldjson.rb
84
88
  - lib/dba/load.rb
89
+ - lib/dba/plant_uml_printer.rb
85
90
  - lib/dba/printer.rb
86
91
  - lib/dba/pull.rb
87
92
  - lib/dba/row_command.rb
@@ -114,7 +119,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
119
  - !ruby/object:Gem::Version
115
120
  version: '0'
116
121
  requirements: []
117
- rubygems_version: 3.3.7
122
+ rubygems_version: 3.5.11
118
123
  signing_key:
119
124
  specification_version: 4
120
125
  summary: See description