k_domain 0.0.14 → 0.0.23
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.builders/config/_.rb +3 -0
- data/.builders/setup.rb +30 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +4 -3
- data/Gemfile +1 -1
- data/Guardfile +1 -0
- data/README.md +15 -0
- data/STORIES.md +35 -6
- data/k_domain.gemspec +1 -1
- data/lib/k_domain/domain_model/load.rb +8 -2
- data/lib/k_domain/domain_model/transform.rb +34 -51
- data/lib/k_domain/domain_model/transform_steps/_.rb +8 -6
- data/lib/k_domain/domain_model/transform_steps/step.rb +47 -2
- data/lib/k_domain/domain_model/transform_steps/{step1_attach_db_schema.rb → step1_db_schema.rb} +2 -1
- data/lib/k_domain/domain_model/transform_steps/{step5_attach_dictionary.rb → step20_dictionary.rb} +7 -3
- data/lib/k_domain/domain_model/transform_steps/step2_domain_models.rb +123 -0
- data/lib/k_domain/domain_model/transform_steps/{step8_locate_rails_models.rb → step4_rails_resource_models.rb} +4 -4
- data/lib/k_domain/domain_model/transform_steps/step5_rails_resource_routes.rb +36 -0
- data/lib/k_domain/domain_model/transform_steps/step6_rails_structure_models.rb +90 -0
- data/lib/k_domain/domain_model/transform_steps/step7_rails_structure_controllers.rb +109 -0
- data/lib/k_domain/domain_model/transform_steps/{step3_attach_columns.rb → step8_domain_columns.rb} +40 -73
- data/lib/k_domain/rails_code_extractor/_.rb +5 -0
- data/lib/k_domain/rails_code_extractor/extract_controller.rb +59 -0
- data/lib/k_domain/rails_code_extractor/extract_model.rb +69 -0
- data/lib/k_domain/rails_code_extractor/shim_loader.rb +30 -0
- data/lib/k_domain/raw_db_schema/load.rb +8 -2
- data/lib/k_domain/raw_db_schema/transform.rb +9 -8
- data/lib/k_domain/schemas/_.rb +3 -2
- data/lib/k_domain/schemas/database.rb +86 -0
- data/lib/k_domain/schemas/domain/erd_file.rb +2 -0
- data/lib/k_domain/schemas/domain.rb +154 -0
- data/lib/k_domain/schemas/domain_model.rb +6 -5
- data/lib/k_domain/schemas/rails_resource.rb +43 -6
- data/lib/k_domain/schemas/rails_structure.rb +172 -0
- data/lib/k_domain/version.rb +1 -1
- data/lib/k_domain.rb +2 -0
- data/templates/custom/action_controller.rb +36 -0
- data/templates/custom/controller_interceptors.rb +78 -0
- data/templates/custom/model_interceptors.rb +71 -0
- data/templates/load_schema.rb +7 -0
- data/templates/old_printspeek_schema copy.rb +231 -0
- data/templates/old_printspeek_schema.rb +233 -0
- data/templates/rails/action_controller.rb +301 -0
- data/templates/rails/active_record.rb +348 -0
- data/templates/ruby_code_extractor/attach_class_info.rb +13 -0
- data/templates/ruby_code_extractor/behaviour_accessors.rb +39 -0
- data/templates/simple/controller_interceptors.rb +2 -0
- metadata +30 -17
- data/lib/k_domain/domain_model/transform_steps/step2_attach_models.rb +0 -62
- data/lib/k_domain/domain_model/transform_steps/step4_attach_erd_files.rb +0 -454
- data/lib/k_domain/schemas/database/_.rb +0 -7
- data/lib/k_domain/schemas/database/foreign_key.rb +0 -14
- data/lib/k_domain/schemas/database/index.rb +0 -14
- data/lib/k_domain/schemas/database/schema.rb +0 -31
- data/lib/k_domain/schemas/database/table.rb +0 -32
- data/lib/k_domain/schemas/domain/domain.rb +0 -11
- data/lib/k_domain/schemas/domain/models/column.rb +0 -49
- data/lib/k_domain/schemas/domain/models/model.rb +0 -111
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Locate rails model files
|
4
|
+
class Step6RailsStructureModels < KDomain::DomainModel::Step
|
5
|
+
def call
|
6
|
+
raise 'Rails model path not supplied' unless opts[:model_path]
|
7
|
+
|
8
|
+
# THIS IS NOT WORKING YET
|
9
|
+
self.rails_structure_models = rails_resource_models.map do |resource|
|
10
|
+
process_resource(OpenStruct.new(resource))
|
11
|
+
end
|
12
|
+
|
13
|
+
attach_behavior_and_functions
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def process_resource(resource)
|
19
|
+
{
|
20
|
+
model_name: resource.model_name,
|
21
|
+
table_name: resource.table_name,
|
22
|
+
file: resource.file,
|
23
|
+
exist: resource.exist,
|
24
|
+
state: resource.state,
|
25
|
+
code: resource.exist ? File.read(resource.file) : '',
|
26
|
+
behaviours: {},
|
27
|
+
functions: {}
|
28
|
+
}
|
29
|
+
|
30
|
+
# return @model unless resource.exist
|
31
|
+
|
32
|
+
# @model[:behaviours] = extract_behavior(resource.file)
|
33
|
+
# @model[:functions] = extract_functions(resource.file)
|
34
|
+
|
35
|
+
# @model
|
36
|
+
end
|
37
|
+
|
38
|
+
def attach_behavior_and_functions
|
39
|
+
rails_structure_models.select { |model| model[:exist] }.each do |model|
|
40
|
+
model[:behaviours] = extract_behavior(model[:file])
|
41
|
+
klass_name = model[:behaviours][:class_name]
|
42
|
+
model[:functions] = extract_functions(klass_name)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def extract_behavior(file)
|
47
|
+
extractor.extract(file)
|
48
|
+
extractor.model
|
49
|
+
end
|
50
|
+
|
51
|
+
def extract_functions(klass_name)
|
52
|
+
klass = klass_type(klass_name)
|
53
|
+
|
54
|
+
return {} if klass.nil?
|
55
|
+
|
56
|
+
Peeky.api.build_class_info(klass.new).to_h
|
57
|
+
rescue StandardError => e
|
58
|
+
log.exception(e)
|
59
|
+
end
|
60
|
+
|
61
|
+
def klass_type(klass_name)
|
62
|
+
Module.const_get(klass_name.classify)
|
63
|
+
rescue NameError
|
64
|
+
puts ''
|
65
|
+
puts klass_name
|
66
|
+
puts klass_name.classify
|
67
|
+
puts klass_name.pluralize
|
68
|
+
puts 'Trying the pluralized version: '
|
69
|
+
Module.const_get(klass_name.pluralize)
|
70
|
+
end
|
71
|
+
|
72
|
+
def extractor
|
73
|
+
@extractor ||= KDomain::RailsCodeExtractor::ExtractModel.new(shim_loader)
|
74
|
+
end
|
75
|
+
|
76
|
+
def shim_loader
|
77
|
+
return opts[:shim_loader] if !opts[:shim_loader].nil? && opts[:shim_loader].is_a?(KDomain::RailsCodeExtractor::ShimLoader)
|
78
|
+
|
79
|
+
shim_loader = KDomain::RailsCodeExtractor::ShimLoader.new
|
80
|
+
# Shims to attach generic class_info writers
|
81
|
+
shim_loader.register(:attach_class_info , KDomain::Gem.resource('templates/ruby_code_extractor/attach_class_info.rb'))
|
82
|
+
shim_loader.register(:behaviour_accessors , KDomain::Gem.resource('templates/ruby_code_extractor/behaviour_accessors.rb'))
|
83
|
+
|
84
|
+
# Shims to support standard active_record DSL methods
|
85
|
+
shim_loader.register(:active_record , KDomain::Gem.resource('templates/rails/active_record.rb'))
|
86
|
+
|
87
|
+
# Shims to support application specific [module, class, method] implementations for suppression and exception avoidance
|
88
|
+
shim_loader
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Locate rails controller files
|
4
|
+
class Step7RailsStructureControllers < KDomain::DomainModel::Step
|
5
|
+
attr_accessor :controllers
|
6
|
+
|
7
|
+
def call
|
8
|
+
raise 'Rails controller path not supplied' unless opts[:controller_path]
|
9
|
+
|
10
|
+
@controllers = {}
|
11
|
+
|
12
|
+
rails_resource_routes.map do |route|
|
13
|
+
process_route(OpenStruct.new(route))
|
14
|
+
end
|
15
|
+
|
16
|
+
self.rails_structure_controllers = controllers.keys.map { |key| controllers[key] }
|
17
|
+
|
18
|
+
attach_behavior_and_functions
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def process_route(route)
|
24
|
+
if new_controller?(route)
|
25
|
+
new_controller(route)
|
26
|
+
else
|
27
|
+
controller = @controllers[route[:controller_file]]
|
28
|
+
controller[:actions] << new_action(route)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def new_controller?(route)
|
33
|
+
!controllers.key?(route[:controller_file])
|
34
|
+
end
|
35
|
+
|
36
|
+
def new_controller(route)
|
37
|
+
controllers[route[:controller_file]] = {
|
38
|
+
name: route[:controller_name],
|
39
|
+
path: route[:controller_path],
|
40
|
+
namespace: route[:controller_namespace],
|
41
|
+
file: route[:controller_file],
|
42
|
+
exist: route[:controller_exist],
|
43
|
+
full_file: route[:file],
|
44
|
+
behaviours: {},
|
45
|
+
functions: {},
|
46
|
+
actions: [new_action(route)]
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
def new_action(route)
|
51
|
+
{
|
52
|
+
route_name: route[:name],
|
53
|
+
action: route[:action],
|
54
|
+
uri_path: route[:uri_path],
|
55
|
+
mime_match: route[:mime_match],
|
56
|
+
verbs: route[:verbs]
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
def attach_behavior_and_functions
|
61
|
+
rails_structure_controllers.select { |controller| controller[:exist] }.each do |controller|
|
62
|
+
unless File.exist?(controller[:full_file])
|
63
|
+
log.error 'Controller apparently exists but no file found, this means that you need re-run rake routes'
|
64
|
+
puts controller[:full_file]
|
65
|
+
next
|
66
|
+
end
|
67
|
+
controller[:behaviours] = extract_behavior(controller[:full_file])
|
68
|
+
klass_name = controller[:behaviours][:class_name]
|
69
|
+
controller[:functions] = extract_functions(klass_name)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def extract_behavior(file)
|
74
|
+
# puts file
|
75
|
+
extractor.extract(file)
|
76
|
+
extractor.controller
|
77
|
+
end
|
78
|
+
|
79
|
+
def extractor
|
80
|
+
@extractor ||= KDomain::RailsCodeExtractor::ExtractController.new(shim_loader)
|
81
|
+
end
|
82
|
+
|
83
|
+
def shim_loader
|
84
|
+
return opts[:shim_loader] if !opts[:shim_loader].nil? && opts[:shim_loader].is_a?(KDomain::RailsCodeExtractor::ShimLoader)
|
85
|
+
|
86
|
+
shim_loader = KDomain::RailsCodeExtractor::ShimLoader.new
|
87
|
+
# Shims to attach generic class_info writers
|
88
|
+
shim_loader.register(:attach_class_info , KDomain::Gem.resource('templates/ruby_code_extractor/attach_class_info.rb'))
|
89
|
+
shim_loader.register(:behaviour_accessors , KDomain::Gem.resource('templates/ruby_code_extractor/behaviour_accessors.rb'))
|
90
|
+
|
91
|
+
# Shims to support stand rails controller DSL methods
|
92
|
+
shim_loader.register(:action_controller , KDomain::Gem.resource('templates/rails/action_controller.rb'))
|
93
|
+
|
94
|
+
# Shims to support application specific [module, class, method] implementations for suppression and exception avoidance
|
95
|
+
# shim_loader.register(:app_action_controller , KDomain::Gem.resource('templates/advanced/action_controller.rb'))
|
96
|
+
# shim_loader.register(:app_controller_interceptors , KDomain::Gem.resource('templates/advanced/controller_interceptors.rb'))
|
97
|
+
shim_loader
|
98
|
+
end
|
99
|
+
|
100
|
+
def extract_functions(klass_name)
|
101
|
+
klass = Module.const_get(klass_name.classify)
|
102
|
+
|
103
|
+
class_info = Peeky.api.build_class_info(klass.new)
|
104
|
+
|
105
|
+
class_info.to_h
|
106
|
+
rescue StandardError => e
|
107
|
+
log.exception(e)
|
108
|
+
end
|
109
|
+
end
|
data/lib/k_domain/domain_model/transform_steps/{step3_attach_columns.rb → step8_domain_columns.rb}
RENAMED
@@ -1,67 +1,36 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
4
|
-
class
|
5
|
-
|
3
|
+
# columns to models
|
4
|
+
class Step8DomainColumns < KDomain::DomainModel::Step
|
5
|
+
attr_reader :domain_model
|
6
|
+
attr_reader :domain_column
|
7
|
+
attr_reader :rails_model
|
6
8
|
attr_reader :column_name
|
7
9
|
attr_reader :column_symbol
|
8
10
|
|
9
11
|
def call
|
10
|
-
|
12
|
+
enrich_columns
|
11
13
|
end
|
12
14
|
|
13
|
-
def
|
15
|
+
def enrich_columns
|
16
|
+
# .select {|m| m[:name] == 'app_user'}
|
14
17
|
domain_models.each do |model|
|
15
|
-
@
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
type: nil,
|
29
|
-
precision: nil,
|
30
|
-
scale: nil,
|
31
|
-
default: nil,
|
32
|
-
null: nil,
|
33
|
-
limit: nil,
|
34
|
-
array: nil
|
35
|
-
}
|
36
|
-
end
|
37
|
-
|
38
|
-
def columns(db_columns)
|
39
|
-
db_columns.map do |db_column|
|
40
|
-
column = column_data(db_column[:name]).merge(
|
41
|
-
type: check_type(db_column[:type]),
|
42
|
-
precision: db_column[:precision],
|
43
|
-
scale: db_column[:scale],
|
44
|
-
default: db_column[:default],
|
45
|
-
null: db_column[:null],
|
46
|
-
limit: db_column[:limit],
|
47
|
-
array: db_column[:array]
|
48
|
-
)
|
49
|
-
|
50
|
-
expand_column(column)
|
18
|
+
@domain_model = model
|
19
|
+
# this will be nil if there is no rails model code
|
20
|
+
@rails_model = find_rails_structure_models(domain_model[:name])
|
21
|
+
|
22
|
+
# log.warn domain_model[:name]
|
23
|
+
domain_model[:columns].each do |column|
|
24
|
+
@domain_column = column
|
25
|
+
@column_name = column[:name]
|
26
|
+
@column_symbol = column[:name].to_sym
|
27
|
+
|
28
|
+
attach_foreign_key
|
29
|
+
column[:structure_type] = structure_type
|
30
|
+
end
|
51
31
|
end
|
52
32
|
end
|
53
33
|
|
54
|
-
def insert_primary_key(model, columns)
|
55
|
-
return columns unless model[:pk][:exist]
|
56
|
-
|
57
|
-
column = column_data('id').merge(
|
58
|
-
type: check_type(model[:pk][:type])
|
59
|
-
)
|
60
|
-
|
61
|
-
columns.unshift(expand_column(column))
|
62
|
-
columns
|
63
|
-
end
|
64
|
-
|
65
34
|
def expand_column(column)
|
66
35
|
foreign_table = lookup_foreign_table(column_name)
|
67
36
|
is_foreign = !foreign_table.nil?
|
@@ -76,22 +45,6 @@ class Step3AttachColumns < KDomain::DomainModel::Step
|
|
76
45
|
})
|
77
46
|
end
|
78
47
|
|
79
|
-
def check_type(type)
|
80
|
-
type = type.to_sym if type.is_a?(String)
|
81
|
-
|
82
|
-
return type if %i[string integer bigint bigserial boolean float decimal datetime date hstore text jsonb].include?(type)
|
83
|
-
|
84
|
-
if type.nil?
|
85
|
-
guard('nil type detected for db_column[:type]')
|
86
|
-
|
87
|
-
return :string
|
88
|
-
end
|
89
|
-
|
90
|
-
guard("new type detected for db_column[:type] - #{type}")
|
91
|
-
|
92
|
-
camel.parse(type.to_s).downcase
|
93
|
-
end
|
94
|
-
|
95
48
|
def lookup_foreign_table(column_name)
|
96
49
|
foreign_table = find_foreign_table(table[:name], column_name)
|
97
50
|
|
@@ -104,7 +57,7 @@ class Step3AttachColumns < KDomain::DomainModel::Step
|
|
104
57
|
table_name_plural = table_name.pluralize
|
105
58
|
|
106
59
|
if table_name_exist?(table_name_plural.to_s)
|
107
|
-
investigate(step: :
|
60
|
+
investigate(step: :step8_columns,
|
108
61
|
location: :lookup_foreign_table,
|
109
62
|
key: column_name,
|
110
63
|
message: "#{@table[:name]}.#{column_name} => #{table_name_plural} - Relationship not found in DB, so have inferred this relationship. You may want to check that this relation is correct")
|
@@ -112,7 +65,7 @@ class Step3AttachColumns < KDomain::DomainModel::Step
|
|
112
65
|
return table_name
|
113
66
|
end
|
114
67
|
|
115
|
-
investigate(step: :
|
68
|
+
investigate(step: :step8_columns,
|
116
69
|
location: :lookup_foreign_table,
|
117
70
|
key: column_name,
|
118
71
|
message: "#{@table[:name]}.#{column_name} => #{table_name_plural} - Table not found for a column that looks like foreign_key")
|
@@ -121,11 +74,25 @@ class Step3AttachColumns < KDomain::DomainModel::Step
|
|
121
74
|
nil
|
122
75
|
end
|
123
76
|
|
77
|
+
def attach_foreign_key
|
78
|
+
return if rails_model.nil? || rails_model[:behaviours].nil? || rails_model[:behaviours][:belongs_to].nil?
|
79
|
+
|
80
|
+
foreign = rails_model[:behaviours][:belongs_to].find { |belong| belong[:opts][:foreign_key].to_sym == domain_column[:name].to_sym }
|
81
|
+
|
82
|
+
return unless foreign
|
83
|
+
|
84
|
+
# NEED TO PRE-LOAD the table, table_plural and model
|
85
|
+
domain_column[:foreign_table] = 'xxx1'
|
86
|
+
domain_column[:foreign_table_plural] = 'xxx3'
|
87
|
+
domain_column[:foreign_model] = 'xxx2'
|
88
|
+
end
|
89
|
+
|
124
90
|
# Need some configurable data dictionary where by
|
125
91
|
# _token can be setup on a project by project basis
|
126
|
-
def structure_type
|
127
|
-
return :
|
128
|
-
return :
|
92
|
+
def structure_type
|
93
|
+
return :primary_key if domain_model[:pk][:name] == column_name
|
94
|
+
return :foreign_key if domain_column[:foreign_table]
|
95
|
+
|
129
96
|
return :timestamp if column_symbol == :created_at || column_symbol == :updated_at
|
130
97
|
return :timestamp if column_symbol == :created_at || column_symbol == :updated_at
|
131
98
|
return :deleted_at if column_symbol == :deleted_at
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Takes a Rails controller and extracts DSL behaviours and custom functions (instance, class and private methods)
|
4
|
+
module KDomain
|
5
|
+
module RailsCodeExtractor
|
6
|
+
class ExtractController
|
7
|
+
include KLog::Logging
|
8
|
+
|
9
|
+
attr_reader :shims_loaded
|
10
|
+
attr_reader :controller
|
11
|
+
|
12
|
+
def initialize(load_shim)
|
13
|
+
@load_shim = load_shim
|
14
|
+
@shims_loaded = false
|
15
|
+
end
|
16
|
+
|
17
|
+
def extract(file)
|
18
|
+
load_shims unless shims_loaded
|
19
|
+
|
20
|
+
ActionController.class_info = nil
|
21
|
+
# KDomain::RailsCodeExtractor.reset
|
22
|
+
|
23
|
+
load_retry(file, 10, nil)
|
24
|
+
rescue StandardError => e
|
25
|
+
log.exception(e)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def load_shims
|
31
|
+
@load_shim.call
|
32
|
+
@shims_loaded = true
|
33
|
+
end
|
34
|
+
|
35
|
+
# rubocop:disable Security/Eval,Style/EvalWithLocation,Style/DocumentDynamicEvalDefinition,Metrics/AbcSize
|
36
|
+
def load_retry(file, times, last_error)
|
37
|
+
return if times.negative?
|
38
|
+
|
39
|
+
# puts file
|
40
|
+
load(file)
|
41
|
+
|
42
|
+
@controller = ActionController::Base.class_info
|
43
|
+
# @controller = KDomain::RailsCodeExtractor.class_info
|
44
|
+
|
45
|
+
# get_method_info(File.base_name(file))
|
46
|
+
rescue StandardError => e
|
47
|
+
log.kv 'times', times
|
48
|
+
# puts e.message
|
49
|
+
if e.is_a?(NameError) && e.message != last_error&.message
|
50
|
+
log.kv('add module', e.name)
|
51
|
+
eval("module #{e.name}; end")
|
52
|
+
return load_retry(file, times - 1, e)
|
53
|
+
end
|
54
|
+
log.exception(e, style: :short, method_info: method(__callee__))
|
55
|
+
end
|
56
|
+
# rubocop:enable Security/Eval,Style/EvalWithLocation,Style/DocumentDynamicEvalDefinition,Metrics/AbcSize
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Takes a Rails Model and extracts DSL behaviours and custom functions (instance, class and private methods)
|
4
|
+
module KDomain
|
5
|
+
module RailsCodeExtractor
|
6
|
+
class ExtractModel
|
7
|
+
include KLog::Logging
|
8
|
+
|
9
|
+
attr_reader :shims_loaded
|
10
|
+
attr_reader :models
|
11
|
+
attr_reader :model
|
12
|
+
|
13
|
+
def initialize(load_shim)
|
14
|
+
@load_shim = load_shim
|
15
|
+
@shims_loaded = false
|
16
|
+
@models = []
|
17
|
+
end
|
18
|
+
|
19
|
+
def extract(file)
|
20
|
+
load_shims unless shims_loaded
|
21
|
+
|
22
|
+
ActiveRecord.class_info = nil
|
23
|
+
|
24
|
+
load_retry(file, 10, nil)
|
25
|
+
rescue StandardError => e
|
26
|
+
log.exception(e)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def load_shims
|
32
|
+
@load_shim.call
|
33
|
+
@shims_loaded = true
|
34
|
+
end
|
35
|
+
|
36
|
+
# rubocop:disable Security/Eval,Style/EvalWithLocation,Style/DocumentDynamicEvalDefinition,Metrics/AbcSize
|
37
|
+
def load_retry(file, times, last_error)
|
38
|
+
return if times.negative?
|
39
|
+
|
40
|
+
load(file)
|
41
|
+
|
42
|
+
@model = ActiveRecord.class_info
|
43
|
+
|
44
|
+
if @model.nil?
|
45
|
+
# puts ''
|
46
|
+
# puts file
|
47
|
+
# puts 'class probably has no DSL methods'
|
48
|
+
@model = {
|
49
|
+
class_name: File.basename(file, File.extname(file)).classify
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
@models << @model
|
54
|
+
|
55
|
+
# get_method_info(File.base_name(file))
|
56
|
+
rescue StandardError => e
|
57
|
+
log.kv 'times', times
|
58
|
+
# puts e.message
|
59
|
+
if e.is_a?(NameError) && e.message != last_error&.message
|
60
|
+
log.kv('add module', e.name)
|
61
|
+
eval("module #{e.name}; end")
|
62
|
+
return load_retry(file, times - 1, e)
|
63
|
+
end
|
64
|
+
log.exception(e, style: :short, method_info: method(__callee__))
|
65
|
+
end
|
66
|
+
# rubocop:enable Security/Eval,Style/EvalWithLocation,Style/DocumentDynamicEvalDefinition,Metrics/AbcSize
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Code extraction requires shims to be loaded before extraction
|
4
|
+
#
|
5
|
+
# This shims server two purposes
|
6
|
+
#
|
7
|
+
# 1. Inject data capture methods calls that intercept DSL macros so that data can be extracted
|
8
|
+
# 2. Inject fake module/classes that would otherwise break code loading with various exceptions
|
9
|
+
module KDomain
|
10
|
+
module RailsCodeExtractor
|
11
|
+
class ShimLoader
|
12
|
+
include KLog::Logging
|
13
|
+
|
14
|
+
attr_reader :shim_files
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
@shim_files = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def call
|
21
|
+
# puts shim_files.map { |sf| sf[:file] }
|
22
|
+
shim_files.select { |sf| sf[:exist] }.each { |sf| require sf[:file] }
|
23
|
+
end
|
24
|
+
|
25
|
+
def register(name, file)
|
26
|
+
@shim_files << { name: name, file: file, exist: File.exist?(file) }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -20,9 +20,15 @@ module KDomain
|
|
20
20
|
|
21
21
|
def call
|
22
22
|
json = File.read(source_file)
|
23
|
-
|
23
|
+
@raw_data = KUtil.data.json_parse(json, as: :hash_symbolized)
|
24
24
|
|
25
|
-
@data = KDomain::Database
|
25
|
+
@data = KDomain::Schemas::Database.new(@raw_data)
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_h
|
29
|
+
return nil unless defined? @raw_data
|
30
|
+
|
31
|
+
@raw_data
|
26
32
|
end
|
27
33
|
end
|
28
34
|
end
|
@@ -11,7 +11,7 @@ module KDomain
|
|
11
11
|
include KLog::Logging
|
12
12
|
|
13
13
|
attr_reader :source_file
|
14
|
-
|
14
|
+
attr_accessor :template_file
|
15
15
|
attr_reader :schema_loader
|
16
16
|
|
17
17
|
def initialize(source_file)
|
@@ -24,6 +24,7 @@ module KDomain
|
|
24
24
|
# log.kv 'template_file', template_file
|
25
25
|
# log.kv 'source_file?', File.exist?(source_file)
|
26
26
|
# log.kv 'template_file?', File.exist?(template_file)
|
27
|
+
|
27
28
|
log.error "Template not found: #{template_file}" unless File.exist?(template_file)
|
28
29
|
|
29
30
|
content = File.read(source_file)
|
@@ -33,9 +34,9 @@ module KDomain
|
|
33
34
|
lines = content.lines.map { |line| " #{line}" }.join
|
34
35
|
|
35
36
|
@schema_loader = File
|
36
|
-
|
37
|
-
|
38
|
-
|
37
|
+
.read(template_file)
|
38
|
+
.gsub('{{source_file}}', source_file)
|
39
|
+
.gsub('{{rails_schema}}', lines)
|
39
40
|
end
|
40
41
|
|
41
42
|
# rename to target_ruby
|
@@ -68,13 +69,13 @@ module KDomain
|
|
68
69
|
return
|
69
70
|
end
|
70
71
|
|
71
|
-
eval(schema_loader)
|
72
|
+
eval(schema_loader) # , __FILE__, __LINE__)
|
72
73
|
|
73
74
|
loader = LoadSchema.new
|
74
75
|
loader.load_schema
|
75
|
-
|
76
|
-
rescue =>
|
77
|
-
log.exception(
|
76
|
+
loader.schema
|
77
|
+
rescue StandardError => e
|
78
|
+
log.exception(e)
|
78
79
|
end
|
79
80
|
# rubocop:enable Security/Eval
|
80
81
|
end
|
data/lib/k_domain/schemas/_.rb
CHANGED
@@ -7,9 +7,10 @@ module Types
|
|
7
7
|
end
|
8
8
|
|
9
9
|
require_relative 'rails_resource'
|
10
|
+
require_relative 'rails_structure'
|
10
11
|
require_relative 'investigate'
|
11
|
-
require_relative 'database
|
12
|
+
require_relative 'database'
|
12
13
|
require_relative 'dictionary'
|
13
|
-
require_relative 'domain
|
14
|
+
require_relative 'domain'
|
14
15
|
|
15
16
|
require_relative './domain_model'
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# KDomain::Schemas::Domain::Column
|
4
|
+
# KDomain::Schemas::Domain::Model
|
5
|
+
|
6
|
+
module KDomain
|
7
|
+
module Schemas
|
8
|
+
class Database < Dry::Struct
|
9
|
+
class ForeignKey < Dry::Struct
|
10
|
+
attribute :left , Types::Strict::String
|
11
|
+
attribute :right , Types::Strict::String
|
12
|
+
attribute :name? , Types::Strict::String.optional.default(nil)
|
13
|
+
attribute :on_update? , Types::Strict::String.optional.default(nil)
|
14
|
+
attribute :on_delete? , Types::Strict::String.optional.default(nil)
|
15
|
+
attribute :column? , Types::Strict::String.optional.default(nil)
|
16
|
+
end
|
17
|
+
|
18
|
+
class Index < Dry::Struct
|
19
|
+
attribute :name , Types::Strict::String
|
20
|
+
attribute :fields , Types::Nominal::Any.optional.default('xxxxx1')
|
21
|
+
attribute :using , Types::Nominal::String
|
22
|
+
attribute :order? , Types::Nominal::Hash
|
23
|
+
attribute :where? , Types::Nominal::Any.optional.default(nil)
|
24
|
+
attribute :unique? , Types::Nominal::Any.optional.default(nil)
|
25
|
+
end
|
26
|
+
|
27
|
+
class View < Dry::Struct
|
28
|
+
attribute :name , Types::Strict::String
|
29
|
+
attribute :materialized , Types::Strict::Bool
|
30
|
+
attribute :sql_definition , Types::Nominal::String
|
31
|
+
end
|
32
|
+
|
33
|
+
class Table < Dry::Struct
|
34
|
+
class RailsSchema < Dry::Struct
|
35
|
+
attribute :primary_key , Types::Nominal::Any.optional.default(nil)
|
36
|
+
attribute :id , Types::Nominal::Any.optional.default(nil)
|
37
|
+
attribute :force , Types::Nominal::Any.optional.default(nil)
|
38
|
+
end
|
39
|
+
|
40
|
+
class Column < Dry::Struct
|
41
|
+
attribute :name , Types::Strict::String
|
42
|
+
attribute :type , Types::Strict::String
|
43
|
+
attribute :precision? , Types::Strict::Integer.optional.default(nil)
|
44
|
+
attribute :scale? , Types::Strict::Integer.optional.default(nil)
|
45
|
+
attribute :default? , Types::Nominal::Any.optional.default(nil)
|
46
|
+
attribute :array? , Types::Strict::Bool.optional.default(nil)
|
47
|
+
attribute :null? , Types::Strict::Bool.optional.default(nil)
|
48
|
+
attribute :limit? , Types::Strict::Integer.optional.default(nil)
|
49
|
+
end
|
50
|
+
|
51
|
+
attribute :name , Types::Strict::String
|
52
|
+
attribute :primary_key , Types::Strict::String.optional.default(nil)
|
53
|
+
attribute :primary_key_type , Types::Strict::String.optional.default(nil)
|
54
|
+
attribute :id? , Types::Nominal::Any.optional.default(nil)
|
55
|
+
attribute :columns , Types::Strict::Array.of(KDomain::Schemas::Database::Table::Column)
|
56
|
+
attribute :indexes , Types::Strict::Array.of(KDomain::Schemas::Database::Index)
|
57
|
+
attribute :rails_schema , KDomain::Schemas::Database::Table::RailsSchema
|
58
|
+
end
|
59
|
+
|
60
|
+
class DbInfo < Dry::Struct
|
61
|
+
attribute :type , Types::Strict::String
|
62
|
+
attribute :version , Types::Nominal::Any.optional.default(nil)
|
63
|
+
attribute :extensions , Types::Strict::Array
|
64
|
+
end
|
65
|
+
|
66
|
+
class UniqueKey < Dry::Struct
|
67
|
+
attribute :type , Types::Strict::String
|
68
|
+
attribute :category , Types::Strict::String.optional
|
69
|
+
attribute :key , Types::Strict::String
|
70
|
+
attribute :keys , Types::Strict::Array
|
71
|
+
end
|
72
|
+
|
73
|
+
class Meta < Dry::Struct
|
74
|
+
attribute :rails , Types::Strict::Integer
|
75
|
+
attribute :db_info , KDomain::Schemas::Database::DbInfo
|
76
|
+
attribute :unique_keys , Types::Strict::Array.of(KDomain::Schemas::Database::UniqueKey)
|
77
|
+
end
|
78
|
+
|
79
|
+
attribute :tables , Types::Strict::Array.of(KDomain::Schemas::Database::Table)
|
80
|
+
attribute :foreign_keys? , Types::Strict::Array.of(KDomain::Schemas::Database::ForeignKey)
|
81
|
+
attribute :indexes? , Types::Strict::Array.of(KDomain::Schemas::Database::Index)
|
82
|
+
attribute :views? , Types::Strict::Array.of(KDomain::Schemas::Database::View)
|
83
|
+
attribute :meta , KDomain::Schemas::Database::Meta
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|