sequel-schema-dot-generator 0.0.3 → 0.0.4
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 +7 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +1 -1
- data/README.md +13 -3
- data/lib/sequel_schema_dot_generator.rb +113 -0
- data/lib/{sequel/schema/dot/generator → sequel_schema_dot_generator}/diagram.dot.erb +0 -0
- data/lib/sequel_schema_dot_generator/schema_source_types/base.rb +23 -0
- data/lib/sequel_schema_dot_generator/schema_source_types/column.rb +34 -0
- data/lib/sequel_schema_dot_generator/schema_source_types/model.rb +30 -0
- data/lib/sequel_schema_dot_generator/version.rb +3 -0
- data/sequel-schema-dot-generator.gemspec +3 -3
- metadata +22 -37
- data/.rvmrc +0 -34
- data/lib/sequel/schema/dot/generator.rb +0 -118
- data/lib/sequel/schema/dot/generator/schema_source_types/base.rb +0 -29
- data/lib/sequel/schema/dot/generator/schema_source_types/column.rb +0 -40
- data/lib/sequel/schema/dot/generator/schema_source_types/model.rb +0 -36
- data/lib/sequel/schema/dot/generator/version.rb +0 -9
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2dc716c3f182abf30384a4b32318559291b40415
|
4
|
+
data.tar.gz: f6ddc030b24cc70467aec4957ae63b0362b5f729
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ec1c08f6477d03ae2852a0ee338064c5070c889a987ef563b79d94c24302965ec658ec564d4a6a502cd97ad0440ca7b112e11e0fd333922655b51270c20744e6
|
7
|
+
data.tar.gz: c42c2b2c1b32000e02ff740a1471e24d34735501cddd546a1945588026ced2522b80af54f0e468b9def1216d47461fa3ab0c77ade28e90601a35c8ef414ad12b
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
sequel-schema-dot-generator
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.0.0-p247
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
Sequel database structure Dot language generator
|
4
4
|
|
5
|
+
[](http://badge.fury.io/rb/sequel-schema-dot-generator)
|
6
|
+
|
5
7
|
## Installation
|
6
8
|
|
7
9
|
Add this line to your application's Gemfile:
|
@@ -27,8 +29,6 @@ Or install it yourself as:
|
|
27
29
|
|
28
30
|
puts dot_db.generate
|
29
31
|
|
30
|
-
=>
|
31
|
-
|
32
32
|
## Contributing
|
33
33
|
|
34
34
|
1. Fork it
|
@@ -39,7 +39,17 @@ Or install it yourself as:
|
|
39
39
|
|
40
40
|
## Changelog
|
41
41
|
|
42
|
+
### 0.0.4
|
43
|
+
- Module structure flattened
|
44
|
+
- Dir structure flattened
|
45
|
+
- active_support -> activesupport, smaller adjustments
|
46
|
+
- Transition to Ruby 2.0 and .ruby-version files for gem development
|
47
|
+
|
48
|
+
### 0.0.3
|
49
|
+
- Associations detection from model (`params[:schema_source_type] = :model`)
|
50
|
+
- New homepage
|
51
|
+
|
42
52
|
### 0.0.2
|
43
53
|
- optional colored association edges to distinguish them in big intersections (`params[:colored_associations]`)
|
44
54
|
- multiple foreign table support
|
45
|
-
- columns has written types in diagram
|
55
|
+
- columns has written types in diagram
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'sequel_schema_dot_generator/version'
|
2
|
+
require 'sequel_schema_dot_generator/schema_source_types/base'
|
3
|
+
require 'sequel_schema_dot_generator/schema_source_types/column'
|
4
|
+
require 'sequel_schema_dot_generator/schema_source_types/model'
|
5
|
+
require 'erb'
|
6
|
+
require 'logger'
|
7
|
+
require 'sequel'
|
8
|
+
require 'active_support/inflector'
|
9
|
+
|
10
|
+
# Module for generating Sequel schema structure into Dot language format
|
11
|
+
module SequelSchemaDotGenerator
|
12
|
+
class Generator
|
13
|
+
@db = nil
|
14
|
+
@dot_template_path = nil
|
15
|
+
@logger = nil
|
16
|
+
@colored_associations = nil
|
17
|
+
|
18
|
+
# @todo Consider write the params as block
|
19
|
+
#
|
20
|
+
# @param [Hash] params Setup of Generator instance
|
21
|
+
# :db [Sequel::Database] required From this one will be generated the diagram
|
22
|
+
# :logger [Logger] optional Will be used for logging
|
23
|
+
# :dot_template_path [String] optional Template is supposed to be ERB template. Will be used as template for resulting Dot file
|
24
|
+
# :colored_associations [Boolean] optional Whether lines representing associations will be draw in color (=False)
|
25
|
+
# :schema_source_type [Symbol] optional How will be data acquired (:column|:model)
|
26
|
+
#
|
27
|
+
def initialize params
|
28
|
+
check_params params
|
29
|
+
|
30
|
+
@db = params[:db]
|
31
|
+
@logger = params[:logger] || Logger.new(STDERR)
|
32
|
+
@dot_template_path = params[:dot_template_path] || File.join( File.dirname(__FILE__),
|
33
|
+
'sequel_schema_dot_generator/diagram.dot.erb')
|
34
|
+
@colored_associations = params[:colored_associations]
|
35
|
+
initialize_ss params[:schema_source_type]
|
36
|
+
end
|
37
|
+
|
38
|
+
def initialize_ss type
|
39
|
+
sst_params = @db, @db.tables
|
40
|
+
|
41
|
+
if type == :model
|
42
|
+
@schema_source = SchemaSourceType::Model.new *sst_params
|
43
|
+
end
|
44
|
+
|
45
|
+
# Column Source as fallback
|
46
|
+
@schema_source ||= SchemaSourceType::Column.new *sst_params
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [String] Content which can be passed to dot parsing tool
|
50
|
+
def generate
|
51
|
+
tables = []
|
52
|
+
|
53
|
+
@db.tables.each do |table_name|
|
54
|
+
next if table_name == :schema_info
|
55
|
+
tables << [table_name, @db.schema(table_name)]
|
56
|
+
end
|
57
|
+
|
58
|
+
relations = @schema_source.relations
|
59
|
+
|
60
|
+
if @colored_associations
|
61
|
+
edge_colors = random_color_set relations.count
|
62
|
+
else
|
63
|
+
edge_colors = Array.new relations.count, '000000'
|
64
|
+
end
|
65
|
+
|
66
|
+
ERB.new( File.read(@dot_template_path),nil,'>' ).result(binding)
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
# @param [Integer] number of colors we want to generate
|
72
|
+
#
|
73
|
+
# @return [Array] of random and unique colors
|
74
|
+
def random_color_set number
|
75
|
+
raise 'Number of colors must be greater than 0' if number < 1
|
76
|
+
colors = []
|
77
|
+
(1..number).each do
|
78
|
+
colors << random_unique_hex_color(colors)
|
79
|
+
end
|
80
|
+
|
81
|
+
colors
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
# @param [Array] existing colors which should be avoided
|
86
|
+
#
|
87
|
+
# @return [String] Random color which is not presented in existing param
|
88
|
+
def random_unique_hex_color existing
|
89
|
+
color = '%06x' % (rand * 0xffffff)
|
90
|
+
if existing.include?(color)
|
91
|
+
random_unique_hex_color existing
|
92
|
+
else
|
93
|
+
color
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Checks if all parameters for new Object are alright
|
98
|
+
def check_params params
|
99
|
+
unless params[:db].is_a?Sequel::Database
|
100
|
+
raise 'Database connection is supposed to be Sequel::Database. %s given'%params[:database_connection].class.name
|
101
|
+
end
|
102
|
+
unless params[:dot_template_path].nil? || params[:dot_template_path].is_a?(String) || File.exist?(params[:dot_template_path])
|
103
|
+
raise 'Template path is supposed to be string with an existing file. %s given'%params[:dot_template_path].inspect
|
104
|
+
end
|
105
|
+
unless params[:logger].nil? || params[:logger].is_a?(Logger)
|
106
|
+
raise 'Logger is supposed to be... Logger, know. %s given'%params[:logger].inspect
|
107
|
+
end
|
108
|
+
unless params[:colored_associations].nil? || !!params[:colored_associations] == params[:colored_associations]
|
109
|
+
raise 'Colored association is supposed to be boolean. %s given'%params[:colored_associations].inspect
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
File without changes
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module SequelSchemaDotGenerator
|
2
|
+
module SchemaSourceType
|
3
|
+
class Base
|
4
|
+
# Initialize Schema Source Type
|
5
|
+
#
|
6
|
+
# Tables could be retrieved from db connection, but there is plan to provide
|
7
|
+
# control over what tables will be in output structure
|
8
|
+
#
|
9
|
+
# @param [Sequel::Database] db for which should be acquired data
|
10
|
+
# @param [Array] tables for which should be acquired data
|
11
|
+
def initialize db, tables
|
12
|
+
@tables = tables
|
13
|
+
@db = db
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [Array] associations for tables given to constructor
|
17
|
+
# Each item is array of [<foreign_table>, <id>, <table_name>, <foreign_column>]
|
18
|
+
def relations
|
19
|
+
raise NotImplementedError
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module SequelSchemaDotGenerator
|
2
|
+
module SchemaSourceType
|
3
|
+
class Column < SchemaSourceType::Base
|
4
|
+
def relations
|
5
|
+
relations = []
|
6
|
+
|
7
|
+
@tables.each do |table_name|
|
8
|
+
@db[table_name].columns.select{|cn|cn=~/_id$/}.each do |column_name|
|
9
|
+
foreign_column = column_name.to_s
|
10
|
+
foreign_table = existing_table_name foreign_column.gsub(/_id$/, '')
|
11
|
+
relations << [foreign_table, 'id', table_name, foreign_column]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
relations
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
# @param [String] name
|
21
|
+
#
|
22
|
+
# @return [String] form of name param in which it is name of existing table
|
23
|
+
def existing_table_name name
|
24
|
+
tables = @db.tables.map(&:to_s)
|
25
|
+
table_name = name if tables.include? name
|
26
|
+
table_name ||= name.pluralize if tables.include? name.pluralize
|
27
|
+
table_name ||= name.singularize if tables.include? name.singularize
|
28
|
+
table_name ||= 'association_table_not_found'
|
29
|
+
|
30
|
+
table_name
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module SequelSchemaDotGenerator
|
2
|
+
module SchemaSourceType
|
3
|
+
class Model < SchemaSourceType::Base
|
4
|
+
def relations
|
5
|
+
relations = {}
|
6
|
+
|
7
|
+
@tables.collect do |table_name|
|
8
|
+
model = table_name.to_s.singularize.classify.constantize
|
9
|
+
model.associations.each do |assoc|
|
10
|
+
assoc_info = model.association_reflection(assoc)
|
11
|
+
|
12
|
+
right_key = assoc_info[:join_table].to_s+assoc_info[:right_key].to_s
|
13
|
+
left_key = assoc_info[:join_table].to_s+assoc_info[:left_key].to_s
|
14
|
+
|
15
|
+
if assoc_info[:type] == :many_to_many
|
16
|
+
relations[right_key] = [assoc_info[:join_table].to_s, assoc_info[:right_key], assoc_info[:class_name].constantize.implicit_table_name, assoc_info[:class_name].constantize.primary_key]
|
17
|
+
relations[left_key] = [assoc_info[:join_table].to_s, assoc_info[:left_key], assoc_info[:model].implicit_table_name, assoc_info[:model].primary_key]
|
18
|
+
else
|
19
|
+
# one_to_many
|
20
|
+
table_name = assoc_info[:model].implicit_table_name.to_s
|
21
|
+
table_key = assoc_info[:key].to_s
|
22
|
+
relations[right_key] = [table_name, table_key, assoc_info[:class_name].constantize.implicit_table_name, assoc_info[:class_name].constantize.primary_key]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
relations.values
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require File.expand_path 'lib/
|
4
|
+
require File.expand_path 'lib/sequel_schema_dot_generator/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = 'sequel-schema-dot-generator'
|
8
|
-
spec.version =
|
8
|
+
spec.version = SequelSchemaDotGenerator::VERSION
|
9
9
|
spec.authors = ['Mailo Svetel']
|
10
10
|
spec.email = %w(development@rooland.cz)
|
11
11
|
spec.description = %q{This gem makes it easier to generate database schema overview image}
|
@@ -22,5 +22,5 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_development_dependency 'rake'
|
23
23
|
|
24
24
|
spec.add_dependency 'sequel'
|
25
|
-
spec.add_dependency '
|
25
|
+
spec.add_dependency 'activesupport'
|
26
26
|
end
|
metadata
CHANGED
@@ -1,20 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequel-schema-dot-generator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.4
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Mailo Svetel
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-11-02 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: bundler
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
17
|
- - ~>
|
20
18
|
- !ruby/object:Gem::Version
|
@@ -22,7 +20,6 @@ dependencies:
|
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
24
|
- - ~>
|
28
25
|
- !ruby/object:Gem::Version
|
@@ -30,49 +27,43 @@ dependencies:
|
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rake
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - '>='
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '0'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: sequel
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - '>='
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '0'
|
54
48
|
type: :runtime
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - '>='
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: '0'
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
|
-
name:
|
56
|
+
name: activesupport
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- -
|
59
|
+
- - '>='
|
68
60
|
- !ruby/object:Gem::Version
|
69
61
|
version: '0'
|
70
62
|
type: :runtime
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- -
|
66
|
+
- - '>='
|
76
67
|
- !ruby/object:Gem::Version
|
77
68
|
version: '0'
|
78
69
|
description: This gem makes it easier to generate database schema overview image
|
@@ -83,47 +74,41 @@ extensions: []
|
|
83
74
|
extra_rdoc_files: []
|
84
75
|
files:
|
85
76
|
- .gitignore
|
86
|
-
- .
|
77
|
+
- .ruby-gemset
|
78
|
+
- .ruby-version
|
87
79
|
- Gemfile
|
88
80
|
- LICENSE.txt
|
89
81
|
- README.md
|
90
82
|
- Rakefile
|
91
|
-
- lib/
|
92
|
-
- lib/
|
93
|
-
- lib/
|
94
|
-
- lib/
|
95
|
-
- lib/
|
96
|
-
- lib/
|
83
|
+
- lib/sequel_schema_dot_generator.rb
|
84
|
+
- lib/sequel_schema_dot_generator/diagram.dot.erb
|
85
|
+
- lib/sequel_schema_dot_generator/schema_source_types/base.rb
|
86
|
+
- lib/sequel_schema_dot_generator/schema_source_types/column.rb
|
87
|
+
- lib/sequel_schema_dot_generator/schema_source_types/model.rb
|
88
|
+
- lib/sequel_schema_dot_generator/version.rb
|
97
89
|
- sequel-schema-dot-generator.gemspec
|
98
90
|
homepage: http://www.rooland.cz/sequel-schema-dot-generator-gem
|
99
91
|
licenses:
|
100
92
|
- MIT
|
93
|
+
metadata: {}
|
101
94
|
post_install_message:
|
102
95
|
rdoc_options: []
|
103
96
|
require_paths:
|
104
97
|
- lib
|
105
98
|
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
-
none: false
|
107
99
|
requirements:
|
108
|
-
- -
|
100
|
+
- - '>='
|
109
101
|
- !ruby/object:Gem::Version
|
110
102
|
version: '0'
|
111
|
-
segments:
|
112
|
-
- 0
|
113
|
-
hash: -3800259323698899955
|
114
103
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
-
none: false
|
116
104
|
requirements:
|
117
|
-
- -
|
105
|
+
- - '>='
|
118
106
|
- !ruby/object:Gem::Version
|
119
107
|
version: '0'
|
120
|
-
segments:
|
121
|
-
- 0
|
122
|
-
hash: -3800259323698899955
|
123
108
|
requirements: []
|
124
109
|
rubyforge_project:
|
125
|
-
rubygems_version: 1.
|
110
|
+
rubygems_version: 2.1.2
|
126
111
|
signing_key:
|
127
|
-
specification_version:
|
112
|
+
specification_version: 4
|
128
113
|
summary: Dot language format generator for Sequel schema structure
|
129
114
|
test_files: []
|
data/.rvmrc
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
#!/usr/bin/env bash
|
2
|
-
|
3
|
-
# This is an RVM Project .rvmrc file, used to automatically load the ruby
|
4
|
-
# development environment upon cd'ing into the directory
|
5
|
-
|
6
|
-
# First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
|
7
|
-
# Only full ruby name is supported here, for short names use:
|
8
|
-
# echo "rvm use 1.9.3" > .rvmrc
|
9
|
-
environment_id="ruby-1.9.3-p385@sequel-dot-generator"
|
10
|
-
|
11
|
-
# Uncomment the following lines if you want to verify rvm version per project
|
12
|
-
# rvmrc_rvm_version="1.18.8 (stable)" # 1.10.1 seams as a safe start
|
13
|
-
# eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
|
14
|
-
# echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
|
15
|
-
# return 1
|
16
|
-
# }
|
17
|
-
|
18
|
-
# First we attempt to load the desired environment directly from the environment
|
19
|
-
# file. This is very fast and efficient compared to running through the entire
|
20
|
-
# CLI and selector. If you want feedback on which environment was used then
|
21
|
-
# insert the word 'use' after --create as this triggers verbose mode.
|
22
|
-
if [[ -d "${rvm_path:-$HOME/.rvm}/environments"
|
23
|
-
&& -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
|
24
|
-
then
|
25
|
-
\. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
|
26
|
-
[[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] &&
|
27
|
-
\. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true
|
28
|
-
else
|
29
|
-
# If the environment file has not yet been created, use the RVM CLI to select.
|
30
|
-
rvm --create "$environment_id" || {
|
31
|
-
echo "Failed to create RVM environment '${environment_id}'."
|
32
|
-
return 1
|
33
|
-
}
|
34
|
-
fi
|
@@ -1,118 +0,0 @@
|
|
1
|
-
require 'sequel/schema/dot/generator/version'
|
2
|
-
require 'sequel/schema/dot/generator/schema_source_types/base'
|
3
|
-
require 'sequel/schema/dot/generator/schema_source_types/column'
|
4
|
-
require 'sequel/schema/dot/generator/schema_source_types/model'
|
5
|
-
require 'erb'
|
6
|
-
require 'logger'
|
7
|
-
require 'sequel'
|
8
|
-
require 'active_support/inflector'
|
9
|
-
|
10
|
-
module Sequel
|
11
|
-
module Schema
|
12
|
-
module Dot
|
13
|
-
# Module for generating Sequel schema structure into Dot language format
|
14
|
-
module Generator
|
15
|
-
class Generator
|
16
|
-
@db = nil
|
17
|
-
@dot_template_path = nil
|
18
|
-
@logger = nil
|
19
|
-
@colored_associations = nil
|
20
|
-
|
21
|
-
# @todo Consider write the params as block
|
22
|
-
#
|
23
|
-
# @param [Hash] params Setup of Generator instance
|
24
|
-
# :db [Sequel::Database] required From this one will be generated the diagram
|
25
|
-
# :logger [Logger] optional Will be used for logging
|
26
|
-
# :dot_template_path [String] optional Template is supposed to be ERB template. Will be used as template for resulting Dot file
|
27
|
-
# :colored_associations [Boolean] optional Whether lines representing associations will be draw in color (=False)
|
28
|
-
# :schema_source_type [Symbol] optional How will be data acquired (:column|:model)
|
29
|
-
#
|
30
|
-
def initialize params
|
31
|
-
check_params params
|
32
|
-
|
33
|
-
@db = params[:db]
|
34
|
-
@logger = params[:logger] || Logger.new(STDERR)
|
35
|
-
@dot_template_path = params[:dot_template_path] || File.join(File.dirname(__FILE__), 'generator/diagram.dot.erb')
|
36
|
-
@colored_associations = params[:colored_associations]
|
37
|
-
initialize_ss params[:schema_source_type]
|
38
|
-
end
|
39
|
-
|
40
|
-
def initialize_ss type
|
41
|
-
sst_params = @db, @db.tables
|
42
|
-
|
43
|
-
if type == :model
|
44
|
-
@schema_source = SchemaSourceType::Model.new *sst_params
|
45
|
-
end
|
46
|
-
|
47
|
-
# Column Source as fallback
|
48
|
-
@schema_source ||= SchemaSourceType::Column.new *sst_params
|
49
|
-
end
|
50
|
-
|
51
|
-
# @return [String] Content which can be passed to dot parsing tool
|
52
|
-
def generate
|
53
|
-
tables = []
|
54
|
-
|
55
|
-
@db.tables.each do |table_name|
|
56
|
-
next if table_name == :schema_info
|
57
|
-
tables << [table_name, @db.schema(table_name)]
|
58
|
-
end
|
59
|
-
|
60
|
-
relations = @schema_source.relations
|
61
|
-
|
62
|
-
if @colored_associations
|
63
|
-
edge_colors = random_color_set relations.count
|
64
|
-
else
|
65
|
-
edge_colors = Array.new relations.count, '000000'
|
66
|
-
end
|
67
|
-
|
68
|
-
ERB.new( File.read(@dot_template_path),nil,'>' ).result(binding)
|
69
|
-
end
|
70
|
-
|
71
|
-
private
|
72
|
-
|
73
|
-
# @param [Integer] number of colors we want to generate
|
74
|
-
#
|
75
|
-
# @return [Array] of random and unique colors
|
76
|
-
def random_color_set number
|
77
|
-
raise 'Number of colors must be greater than 0' if number < 1
|
78
|
-
colors = []
|
79
|
-
(1..number).each do
|
80
|
-
colors << random_unique_hex_color(colors)
|
81
|
-
end
|
82
|
-
|
83
|
-
colors
|
84
|
-
end
|
85
|
-
|
86
|
-
|
87
|
-
# @param [Array] existing colors which should be avoided
|
88
|
-
#
|
89
|
-
# @return [String] Random color which is not presented in existing param
|
90
|
-
def random_unique_hex_color existing
|
91
|
-
color = '%06x' % (rand * 0xffffff)
|
92
|
-
if existing.include?(color)
|
93
|
-
random_unique_hex_color existing
|
94
|
-
else
|
95
|
-
color
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
# Checks if all parameters for new Object are alright
|
100
|
-
def check_params params
|
101
|
-
unless params[:db].is_a?Sequel::Database
|
102
|
-
raise 'Database connection is supposed to be Sequel::Database. %s given'%params[:database_connection].class.name
|
103
|
-
end
|
104
|
-
unless params[:dot_template_path].nil? || params[:dot_template_path].is_a?(String) || File.exist?(params[:dot_template_path])
|
105
|
-
raise 'Template path is supposed to be string with an existing file. %s given'%params[:dot_template_path].inspect
|
106
|
-
end
|
107
|
-
unless params[:logger].nil? || params[:logger].is_a?(Logger)
|
108
|
-
raise 'Logger is supposed to be... Logger, know. %s given'%params[:logger].inspect
|
109
|
-
end
|
110
|
-
unless params[:colored_associations].nil? || !!params[:colored_associations] == params[:colored_associations]
|
111
|
-
raise 'Colored association is supposed to be boolean. %s given'%params[:colored_associations].inspect
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
module Sequel
|
2
|
-
module Schema
|
3
|
-
module Dot
|
4
|
-
module Generator
|
5
|
-
module SchemaSourceType
|
6
|
-
class Base
|
7
|
-
# Initialize Schema Source Type
|
8
|
-
#
|
9
|
-
# Tables could be retrieved from db connection, but there is plan to provide
|
10
|
-
# control over what tables will be in output structure
|
11
|
-
#
|
12
|
-
# @param [Sequel::Database] db for which should be acquired data
|
13
|
-
# @param [Array] tables for which should be acquired data
|
14
|
-
def initialize db, tables
|
15
|
-
@tables = tables
|
16
|
-
@db = db
|
17
|
-
end
|
18
|
-
|
19
|
-
# @return [Array] associations for tables given to constructor
|
20
|
-
# Each item is array of [<foreign_table>, <id>, <table_name>, <foreign_column>]
|
21
|
-
def relations
|
22
|
-
raise NotImplementedError
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
module Sequel
|
2
|
-
module Schema
|
3
|
-
module Dot
|
4
|
-
module Generator
|
5
|
-
module SchemaSourceType
|
6
|
-
class Column < SchemaSourceType::Base
|
7
|
-
def relations
|
8
|
-
relations = []
|
9
|
-
|
10
|
-
@tables.each do |table_name|
|
11
|
-
@db[table_name].columns.select{|cn|cn=~/_id$/}.each do |column_name|
|
12
|
-
foreign_column = column_name.to_s
|
13
|
-
foreign_table = existing_table_name foreign_column.gsub(/_id$/, '')
|
14
|
-
relations << [foreign_table, 'id', table_name, foreign_column]
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
relations
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
# @param [String] name
|
24
|
-
#
|
25
|
-
# @return [String] form of name param in which it is name of existing table
|
26
|
-
def existing_table_name name
|
27
|
-
tables = @db.tables.map(&:to_s)
|
28
|
-
table_name = name if tables.include? name
|
29
|
-
table_name ||= name.pluralize if tables.include? name.pluralize
|
30
|
-
table_name ||= name.singularize if tables.include? name.singularize
|
31
|
-
table_name ||= 'association_table_not_found'
|
32
|
-
|
33
|
-
table_name
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
module Sequel
|
2
|
-
module Schema
|
3
|
-
module Dot
|
4
|
-
module Generator
|
5
|
-
module SchemaSourceType
|
6
|
-
class Model < SchemaSourceType::Base
|
7
|
-
def relations
|
8
|
-
relations = {}
|
9
|
-
|
10
|
-
@tables.collect do |table_name|
|
11
|
-
model = table_name.to_s.singularize.classify.constantize
|
12
|
-
model.associations.each do |assoc|
|
13
|
-
assoc_info = model.association_reflection(assoc)
|
14
|
-
|
15
|
-
right_key = assoc_info[:join_table].to_s+assoc_info[:right_key].to_s
|
16
|
-
left_key = assoc_info[:join_table].to_s+assoc_info[:left_key].to_s
|
17
|
-
|
18
|
-
if assoc_info[:type] == :many_to_many
|
19
|
-
relations[right_key] = [assoc_info[:join_table].to_s, assoc_info[:right_key], assoc_info[:class_name].constantize.implicit_table_name, assoc_info[:class_name].constantize.primary_key]
|
20
|
-
relations[left_key] = [assoc_info[:join_table].to_s, assoc_info[:left_key], assoc_info[:model].implicit_table_name, assoc_info[:model].primary_key]
|
21
|
-
else
|
22
|
-
# one_to_many
|
23
|
-
table_name = assoc_info[:model].implicit_table_name.to_s
|
24
|
-
table_key = assoc_info[:key].to_s
|
25
|
-
relations[right_key] = [table_name, table_key, assoc_info[:class_name].constantize.implicit_table_name, assoc_info[:class_name].constantize.primary_key]
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
relations.values
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|