k_domain 0.0.2 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +31 -1
- data/STORIES.md +6 -2
- data/k_domain.gemspec +2 -0
- data/lib/k_domain/domain_model/dtos/_.rb +88 -0
- data/lib/k_domain/domain_model/dtos/belongs_to.rb +25 -0
- data/lib/k_domain/domain_model/dtos/column_old.rb +225 -0
- data/lib/k_domain/domain_model/dtos/dictionary/dictionary.rb +17 -0
- data/lib/k_domain/domain_model/dtos/domain.rb +11 -0
- data/lib/k_domain/domain_model/dtos/domain_statistics.rb +29 -0
- data/lib/k_domain/domain_model/dtos/entity.rb +338 -0
- data/lib/k_domain/domain_model/dtos/entity_statistics.rb +22 -0
- data/lib/k_domain/domain_model/dtos/foreign_key.rb +17 -0
- data/lib/k_domain/domain_model/dtos/has_and_belongs_to_many.rb +20 -0
- data/lib/k_domain/domain_model/dtos/has_many.rb +27 -0
- data/lib/k_domain/domain_model/dtos/has_one.rb +41 -0
- data/lib/k_domain/domain_model/dtos/investigate/investigate.rb +10 -0
- data/lib/k_domain/domain_model/dtos/investigate/issue.rb +13 -0
- data/lib/k_domain/domain_model/dtos/models/column.rb +49 -0
- data/lib/k_domain/domain_model/dtos/models/model.rb +111 -0
- data/lib/k_domain/domain_model/dtos/name_options.rb +10 -0
- data/lib/k_domain/domain_model/dtos/rails_controller.rb +10 -0
- data/lib/k_domain/domain_model/dtos/rails_model.rb +92 -0
- data/lib/k_domain/domain_model/dtos/related_entity.rb +36 -0
- data/lib/k_domain/domain_model/dtos/schema.rb +12 -0
- data/lib/k_domain/domain_model/dtos/statistics.rb +21 -0
- data/lib/k_domain/domain_model/dtos/validate.rb +25 -0
- data/lib/k_domain/domain_model/dtos/validates.rb +50 -0
- data/lib/k_domain/domain_model/load.rb +29 -0
- data/lib/k_domain/domain_model/transform.rb +94 -0
- data/lib/k_domain/domain_model/transform_steps/_.rb +9 -0
- data/lib/k_domain/domain_model/transform_steps/step.rb +123 -0
- data/lib/k_domain/domain_model/transform_steps/step1_attach_db_schema.rb +21 -0
- data/lib/k_domain/domain_model/transform_steps/step2_attach_models.rb +62 -0
- data/lib/k_domain/domain_model/transform_steps/step3_attach_columns.rb +137 -0
- data/lib/k_domain/domain_model/transform_steps/step4_attach_erd_files.rb +454 -0
- data/lib/k_domain/domain_model/transform_steps/step5_attach_dictionary.rb +56 -0
- data/lib/k_domain/raw_db_schema/dtos/_.rb +14 -0
- data/lib/k_domain/raw_db_schema/dtos/column.rb +16 -0
- data/lib/k_domain/raw_db_schema/dtos/database.rb +11 -0
- data/lib/k_domain/raw_db_schema/dtos/foreign_key.rb +14 -0
- data/lib/k_domain/raw_db_schema/dtos/index.rb +14 -0
- data/lib/k_domain/raw_db_schema/dtos/schema.rb +18 -0
- data/lib/k_domain/raw_db_schema/dtos/table.rb +21 -0
- data/lib/k_domain/raw_db_schema/dtos/unique_key.rb +14 -0
- data/lib/k_domain/raw_db_schema/load.rb +29 -0
- data/lib/k_domain/{raw_schema → raw_db_schema}/template.rb +0 -0
- data/lib/k_domain/{raw_schema → raw_db_schema}/transform.rb +37 -21
- data/lib/k_domain/version.rb +1 -1
- data/lib/k_domain.rb +14 -1
- metadata +74 -4
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KDomain
|
4
|
+
module DomainModel
|
5
|
+
# Rails model represents information that is found the model.rb class in the rails project
|
6
|
+
class RailsModel
|
7
|
+
attr_accessor :name
|
8
|
+
attr_accessor :name_plural
|
9
|
+
attr_accessor :name_original
|
10
|
+
attr_accessor :documentation_rel_path
|
11
|
+
attr_accessor :model_path
|
12
|
+
|
13
|
+
# @param [Symbol] value The value of ID has different meanings
|
14
|
+
# @option value :true Id column exists and it uses an Integer type
|
15
|
+
# @option value :false Id column does not exist
|
16
|
+
# @option value :bigserial Id column exists and it uses a BigSerial type
|
17
|
+
attr_accessor :id
|
18
|
+
|
19
|
+
attr_accessor :force
|
20
|
+
attr_accessor :primary_key
|
21
|
+
attr_accessor :quirks
|
22
|
+
|
23
|
+
attr_accessor :ruby_raw
|
24
|
+
attr_accessor :ruby_code
|
25
|
+
attr_accessor :ruby_frozen
|
26
|
+
attr_accessor :ruby_header
|
27
|
+
attr_accessor :ruby_code_public
|
28
|
+
attr_accessor :ruby_code_private
|
29
|
+
|
30
|
+
attr_accessor :default_scope
|
31
|
+
attr_accessor :scopes
|
32
|
+
attr_accessor :public_class_methods
|
33
|
+
attr_accessor :public_instance_methods
|
34
|
+
attr_accessor :private_instance_methods
|
35
|
+
|
36
|
+
# stats
|
37
|
+
attr_accessor :time_stamp1
|
38
|
+
attr_accessor :time_stamp2
|
39
|
+
attr_accessor :time_stamp3
|
40
|
+
|
41
|
+
def code_length
|
42
|
+
ruby_raw&.length
|
43
|
+
end
|
44
|
+
|
45
|
+
def display_quirks
|
46
|
+
quirks.join(' ')
|
47
|
+
end
|
48
|
+
|
49
|
+
def exists?
|
50
|
+
File.exist?(model_path)
|
51
|
+
end
|
52
|
+
|
53
|
+
def initialize
|
54
|
+
@quirks = []
|
55
|
+
end
|
56
|
+
|
57
|
+
def add_quirk(quirk)
|
58
|
+
@quirks << quirk
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_h
|
62
|
+
{
|
63
|
+
name: name,
|
64
|
+
name_plural: name_plural,
|
65
|
+
name_original: name_original,
|
66
|
+
documentation_rel_path: documentation_rel_path,
|
67
|
+
model_path: model_path,
|
68
|
+
id: id,
|
69
|
+
force: force,
|
70
|
+
primary_key: primary_key,
|
71
|
+
quirks: quirks,
|
72
|
+
ruby_raw: ruby_raw,
|
73
|
+
ruby_code: ruby_code,
|
74
|
+
ruby_frozen: ruby_frozen,
|
75
|
+
ruby_header: ruby_header,
|
76
|
+
ruby_code_public: ruby_code_public,
|
77
|
+
ruby_code_private: ruby_code_private,
|
78
|
+
default_scope: default_scope,
|
79
|
+
scopes: scopes,
|
80
|
+
public_class_methods: public_class_methods,
|
81
|
+
public_instance_methods: public_instance_methods,
|
82
|
+
private_instance_methods: private_instance_methods,
|
83
|
+
time_stamp1: time_stamp1,
|
84
|
+
time_stamp2: time_stamp2,
|
85
|
+
time_stamp3: time_stamp3,
|
86
|
+
code_length: code_length,
|
87
|
+
exists: exists?
|
88
|
+
}
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KDomain
|
4
|
+
module DomainModel
|
5
|
+
class RelatedEntity
|
6
|
+
# Name of the entity model
|
7
|
+
attr_accessor :name
|
8
|
+
attr_accessor :name_plural
|
9
|
+
attr_accessor :main_key
|
10
|
+
|
11
|
+
attr_accessor :trait1
|
12
|
+
attr_accessor :trait2
|
13
|
+
attr_accessor :trait3
|
14
|
+
|
15
|
+
def initialize(entity)
|
16
|
+
@name = entity.name
|
17
|
+
@name_plural = entity.name_plural
|
18
|
+
@main_key = entity.main_key
|
19
|
+
@trait1 = entity.trait1
|
20
|
+
@trait2 = entity.trait2
|
21
|
+
@trait3 = entity.trait3
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_h
|
25
|
+
{
|
26
|
+
name: name,
|
27
|
+
name_plural: name_plural,
|
28
|
+
main_key: main_key,
|
29
|
+
trait1: trait1,
|
30
|
+
trait2: trait2,
|
31
|
+
trait3: trait3
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# DomainModel holds the entire domain model including database and ancillary information
|
4
|
+
module KDomain
|
5
|
+
module DomainModel
|
6
|
+
class Schema < Dry::Struct
|
7
|
+
attribute :domain , KDomain::DomainModel::Domain
|
8
|
+
attribute :database , KDomain::RawDbSchema::Schema
|
9
|
+
attribute :investigate , KDomain::DomainModel::Investigate
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# module KDomain
|
3
|
+
# module DomainModel
|
4
|
+
# # Rails model represents information that is found the model.rb class in the rails project
|
5
|
+
# class Statistics
|
6
|
+
# attr_accessor :column_counts
|
7
|
+
# attr_accessor :code_counts
|
8
|
+
# attr_accessor :code_dsl_counts
|
9
|
+
# attr_accessor :data_counts
|
10
|
+
# attr_accessor :issues
|
11
|
+
|
12
|
+
# def initialize(meta)
|
13
|
+
# @column_counts = OpenStruct.new(meta[:column_counts])
|
14
|
+
# @code_counts = OpenStruct.new(meta[:code_counts])
|
15
|
+
# @code_dsl_counts = OpenStruct.new(meta[:code_dsl_counts])
|
16
|
+
# @data_counts = OpenStruct.new(meta[:data_counts])
|
17
|
+
# @issues = meta[:issues]
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
# end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KDomain
|
4
|
+
module DomainModel
|
5
|
+
class Validate
|
6
|
+
KEYS = [:on].freeze
|
7
|
+
|
8
|
+
attr_accessor :methods
|
9
|
+
|
10
|
+
attr_accessor :on
|
11
|
+
|
12
|
+
def format_on
|
13
|
+
for_template(on)
|
14
|
+
end
|
15
|
+
|
16
|
+
def for_template(value)
|
17
|
+
return nil if value.nil?
|
18
|
+
return value.to_s if value.is_a?(Hash)
|
19
|
+
return ":#{value}" if value.is_a?(Symbol)
|
20
|
+
|
21
|
+
value
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KDomain
|
4
|
+
module DomainModel
|
5
|
+
class Validates
|
6
|
+
KEYS = %i[length unless format presence].freeze
|
7
|
+
|
8
|
+
attr_accessor :name
|
9
|
+
|
10
|
+
attr_accessor :length
|
11
|
+
attr_accessor :unless
|
12
|
+
attr_accessor :format
|
13
|
+
attr_accessor :presence
|
14
|
+
|
15
|
+
def format_length
|
16
|
+
for_template(length)
|
17
|
+
end
|
18
|
+
|
19
|
+
def format_unless
|
20
|
+
for_template(self.unless)
|
21
|
+
end
|
22
|
+
|
23
|
+
def format_format
|
24
|
+
for_template(self.format)
|
25
|
+
end
|
26
|
+
|
27
|
+
def format_presence
|
28
|
+
for_template(presence)
|
29
|
+
end
|
30
|
+
|
31
|
+
def for_template(value)
|
32
|
+
return nil if value.nil?
|
33
|
+
return value.to_s if value.is_a?(Hash)
|
34
|
+
return ":#{value}" if value.is_a?(Symbol)
|
35
|
+
|
36
|
+
value
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_h
|
40
|
+
{
|
41
|
+
name: name,
|
42
|
+
length: length,
|
43
|
+
unless: self.unless,
|
44
|
+
format: self.format,
|
45
|
+
presence: presence
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Annotates the original schema with methods that implement existing method calls
|
4
|
+
# that are already in the schema so that we can build a hash.
|
5
|
+
#
|
6
|
+
# Writes a new annotated schema.rb file with a public method called load that
|
7
|
+
# builds the hash
|
8
|
+
|
9
|
+
module KDomain
|
10
|
+
module DomainModel
|
11
|
+
class Load
|
12
|
+
include KLog::Logging
|
13
|
+
|
14
|
+
attr_reader :source_file
|
15
|
+
attr_reader :data
|
16
|
+
|
17
|
+
def initialize(source_file)
|
18
|
+
@source_file = source_file
|
19
|
+
end
|
20
|
+
|
21
|
+
def call
|
22
|
+
json = File.read(source_file)
|
23
|
+
data = KUtil.data.json_parse(json, as: :hash_symbolized)
|
24
|
+
|
25
|
+
@data = KDomain::DomainModel::Schema.new(data)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Loads the db schema object and works through a series of enrichment steps to
|
4
|
+
# that builds the domain modal
|
5
|
+
|
6
|
+
module KDomain
|
7
|
+
module DomainModel
|
8
|
+
class Transform
|
9
|
+
include KLog::Logging
|
10
|
+
|
11
|
+
attr_reader :db_schema
|
12
|
+
attr_reader :target_step_file
|
13
|
+
attr_reader :target_file
|
14
|
+
attr_reader :erd_path
|
15
|
+
|
16
|
+
def initialize(db_schema, target_file, target_step_file, erd_path)
|
17
|
+
@db_schema = db_schema
|
18
|
+
@target_step_file = target_step_file
|
19
|
+
@target_file = target_file
|
20
|
+
@erd_path = erd_path
|
21
|
+
end
|
22
|
+
|
23
|
+
def call
|
24
|
+
valid = true
|
25
|
+
valid &&= step1
|
26
|
+
valid &&= step2
|
27
|
+
valid &&= step3
|
28
|
+
valid &&= step4
|
29
|
+
valid &&= step5
|
30
|
+
|
31
|
+
raise 'DomainModal transform failed' unless valid
|
32
|
+
|
33
|
+
write
|
34
|
+
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
|
38
|
+
def step1
|
39
|
+
Step1AttachDbSchema.run(domain_data, db_schema: db_schema)
|
40
|
+
write(step: '1-attach-db-schema')
|
41
|
+
end
|
42
|
+
|
43
|
+
def step2
|
44
|
+
Step2AttachModels.run(domain_data, erd_path: erd_path)
|
45
|
+
write(step: '2-attach-model')
|
46
|
+
end
|
47
|
+
|
48
|
+
def step3
|
49
|
+
Step3AttachColumns.run(domain_data)
|
50
|
+
write(step: '3-attach-columns')
|
51
|
+
end
|
52
|
+
|
53
|
+
def step4
|
54
|
+
Step4AttachErdFiles.run(domain_data, erd_path: erd_path)
|
55
|
+
write(step: '4-attach-erd-files')
|
56
|
+
end
|
57
|
+
|
58
|
+
def step5
|
59
|
+
Step5AttachDictionary.run(domain_data, erd_path: erd_path)
|
60
|
+
write(step: '5-attach-dictionary')
|
61
|
+
end
|
62
|
+
|
63
|
+
def write(step: nil)
|
64
|
+
file = if step.nil?
|
65
|
+
target_file
|
66
|
+
else
|
67
|
+
format(target_step_file, step: step)
|
68
|
+
end
|
69
|
+
FileUtils.mkdir_p(File.dirname(file))
|
70
|
+
File.write(file, JSON.pretty_generate(domain_data))
|
71
|
+
end
|
72
|
+
|
73
|
+
def domain_data
|
74
|
+
# The initial domain model structure is created here, but populated during the workflows.
|
75
|
+
@domain_data ||= {
|
76
|
+
domain: {
|
77
|
+
models: [],
|
78
|
+
erd_files: [],
|
79
|
+
dictionary: []
|
80
|
+
},
|
81
|
+
database: {
|
82
|
+
tables: [],
|
83
|
+
indexes: [],
|
84
|
+
foreign_keys: [],
|
85
|
+
meta: {}
|
86
|
+
},
|
87
|
+
investigate: {
|
88
|
+
issues: []
|
89
|
+
}
|
90
|
+
}
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# The require order is important due to dependencies
|
4
|
+
require_relative './step'
|
5
|
+
require_relative './step1_attach_db_schema'
|
6
|
+
require_relative './step2_attach_models'
|
7
|
+
require_relative './step3_attach_columns'
|
8
|
+
require_relative './step4_attach_erd_files'
|
9
|
+
require_relative './step5_attach_dictionary'
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KDomain
|
4
|
+
module DomainModel
|
5
|
+
class Step
|
6
|
+
include KLog::Logging
|
7
|
+
|
8
|
+
attr_reader :domain_data
|
9
|
+
attr_reader :opts
|
10
|
+
attr_reader :valid
|
11
|
+
alias valid? valid
|
12
|
+
|
13
|
+
def initialize(domain_data, **opts)
|
14
|
+
# Useful for debugging
|
15
|
+
# log.info "Initialize #{self.class.name}"
|
16
|
+
|
17
|
+
@domain_data = domain_data
|
18
|
+
@opts = opts
|
19
|
+
@valid = true
|
20
|
+
end
|
21
|
+
|
22
|
+
def call; end
|
23
|
+
|
24
|
+
def self.run(domain_data, **opts)
|
25
|
+
step = new(domain_data, **opts)
|
26
|
+
step.call
|
27
|
+
step
|
28
|
+
end
|
29
|
+
|
30
|
+
def guard(message)
|
31
|
+
log.error message
|
32
|
+
@valid = false
|
33
|
+
end
|
34
|
+
|
35
|
+
# Domain Model Accessor/Helpers
|
36
|
+
def domain
|
37
|
+
guard('domain is missing') if domain_data[:domain].nil?
|
38
|
+
|
39
|
+
domain_data[:domain]
|
40
|
+
end
|
41
|
+
|
42
|
+
def domain_models
|
43
|
+
domain[:models]
|
44
|
+
end
|
45
|
+
|
46
|
+
# Database Accessor/Helpers
|
47
|
+
def database=(value)
|
48
|
+
domain_data[:database] = value
|
49
|
+
end
|
50
|
+
|
51
|
+
def database
|
52
|
+
guard('database is missing') if domain_data[:database].nil?
|
53
|
+
|
54
|
+
domain_data[:database]
|
55
|
+
end
|
56
|
+
|
57
|
+
def database_tables
|
58
|
+
guard('database_tables is missing') if database[:tables].nil?
|
59
|
+
|
60
|
+
database[:tables]
|
61
|
+
end
|
62
|
+
|
63
|
+
def database_foreign_keys
|
64
|
+
guard('database_foreign_keys is missing') if database[:foreign_keys].nil?
|
65
|
+
|
66
|
+
database[:foreign_keys]
|
67
|
+
end
|
68
|
+
|
69
|
+
def find_table_for_model(model)
|
70
|
+
database_tables.find { |table| table[:name] == model[:table_name] }
|
71
|
+
end
|
72
|
+
|
73
|
+
def table_name_exist?(table_name)
|
74
|
+
if table_name.nil?
|
75
|
+
guard('table_name_exist? was provided with a table_name: nil')
|
76
|
+
return false
|
77
|
+
end
|
78
|
+
database_table_name_hash.key?(table_name)
|
79
|
+
end
|
80
|
+
|
81
|
+
def find_foreign_table(lhs_table_name, column_name)
|
82
|
+
fk = database_foreign_keys.find { |foreign_key| foreign_key[:left] == lhs_table_name && foreign_key[:column] == column_name }
|
83
|
+
return fk[:right] if fk
|
84
|
+
|
85
|
+
nil
|
86
|
+
end
|
87
|
+
|
88
|
+
def investigate(step:, location:, key:, message:)
|
89
|
+
unique_key = build_key(step, location, key)
|
90
|
+
|
91
|
+
return if issue_hash.key?(unique_key)
|
92
|
+
|
93
|
+
value = { step: step, location: location, key: key, message: message }
|
94
|
+
|
95
|
+
issues << value # list
|
96
|
+
issue_hash[unique_key] = value # lookup
|
97
|
+
end
|
98
|
+
|
99
|
+
def issues
|
100
|
+
domain_data[:investigate][:issues]
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def database_table_name_hash
|
106
|
+
@database_table_name_hash ||= database_tables.to_h { |table| [table[:name], table[:name]] }
|
107
|
+
end
|
108
|
+
|
109
|
+
def build_key(*values)
|
110
|
+
values.join('-')
|
111
|
+
end
|
112
|
+
|
113
|
+
def issue_hash
|
114
|
+
return @issue_hash if defined? @issue_hash
|
115
|
+
|
116
|
+
@issue_hash = issues.to_h do |issue|
|
117
|
+
unique_key = build_key(issue[:step], issue[:location], issue[:key])
|
118
|
+
[unique_key, issue]
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KDomain
|
4
|
+
module DomainModel
|
5
|
+
class Step1AttachDbSchema < KDomain::DomainModel::Step
|
6
|
+
# Map database schema to domain model
|
7
|
+
def call
|
8
|
+
raise 'Schema not supplied' if opts[:db_schema].nil?
|
9
|
+
|
10
|
+
self.database = opts[:db_schema].clone
|
11
|
+
|
12
|
+
guard('tables are missing') if database[:tables].nil?
|
13
|
+
guard('indexes are missing') if database[:indexes].nil?
|
14
|
+
guard('foreign keys are missing') if database[:foreign_keys].nil?
|
15
|
+
guard('rails version is missing') if database[:meta][:rails].nil?
|
16
|
+
guard('postgres extensions are missing') if database[:meta][:database][:extensions].nil?
|
17
|
+
guard('unique keys are missing') if database[:meta][:unique_keys].nil?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Loop through the db_schema tables and build up a
|
4
|
+
# basic model for each table
|
5
|
+
class Step2AttachModels < KDomain::DomainModel::Step
|
6
|
+
# Map database schema to domain model
|
7
|
+
def call
|
8
|
+
raise 'ERD path not supplied' if opts[:erd_path].nil?
|
9
|
+
|
10
|
+
# Schema is re-shaped into a format designed for domain modeling
|
11
|
+
domain[:models] = database_tables.map { |table| model(table) }
|
12
|
+
end
|
13
|
+
|
14
|
+
def model(table)
|
15
|
+
table_name = table[:name].to_s
|
16
|
+
model_name = table_name.singularize
|
17
|
+
|
18
|
+
{
|
19
|
+
name: model_name,
|
20
|
+
name_plural: table_name, # need to check if this is correct as I know it is wrong for account_history_datum
|
21
|
+
table_name: table_name,
|
22
|
+
pk: primary_key(table),
|
23
|
+
erd_location: location(table_name, model_name),
|
24
|
+
statistics: {}, # Load in future step
|
25
|
+
columns: [] # Load in future step
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def primary_key(table)
|
30
|
+
{
|
31
|
+
name: table[:primary_key],
|
32
|
+
type: table[:primary_key_type],
|
33
|
+
exist: !table[:primary_key].nil?
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
# Location of source code
|
38
|
+
def location(table_name, model_name)
|
39
|
+
file_normal = File.join(opts[:erd_path], "#{model_name}.rb")
|
40
|
+
file_custom = File.join(opts[:erd_path], "#{table_name}.rb")
|
41
|
+
file_exist = true
|
42
|
+
state = []
|
43
|
+
|
44
|
+
if File.exist?(file_normal)
|
45
|
+
file = file_normal
|
46
|
+
state.push(:has_ruby_model)
|
47
|
+
elsif File.exist?(file_custom)
|
48
|
+
file = file_custom
|
49
|
+
state.push(:has_ruby_model)
|
50
|
+
state.push(:nonconventional_name)
|
51
|
+
else
|
52
|
+
file = ''
|
53
|
+
file_exist = false
|
54
|
+
end
|
55
|
+
|
56
|
+
{
|
57
|
+
file: file,
|
58
|
+
exist: file_exist,
|
59
|
+
state: state # display_state: state.join(' ')
|
60
|
+
}
|
61
|
+
end
|
62
|
+
end
|