k_domain 0.0.16 → 0.0.26

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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.builders/boot.rb +40 -0
  3. data/.builders/generators/configuration_generator.rb +22 -0
  4. data/.builders/run.rb +16 -0
  5. data/.gitignore +1 -0
  6. data/.rubocop.yml +1 -2
  7. data/Guardfile +1 -0
  8. data/README.md +15 -0
  9. data/STORIES.md +35 -6
  10. data/lib/k_domain/config/_.rb +4 -0
  11. data/lib/k_domain/config/config.rb +19 -0
  12. data/lib/k_domain/config/configuration.rb +76 -0
  13. data/lib/k_domain/domain_model/load.rb +41 -0
  14. data/lib/k_domain/domain_model/transform.rb +27 -55
  15. data/lib/k_domain/domain_model/transform_steps/_.rb +8 -7
  16. data/lib/k_domain/domain_model/transform_steps/step.rb +27 -1
  17. data/lib/k_domain/domain_model/transform_steps/{step1_attach_db_schema.rb → step1_db_schema.rb} +2 -1
  18. data/lib/k_domain/domain_model/transform_steps/{step5_attach_dictionary.rb → step20_dictionary.rb} +7 -4
  19. data/lib/k_domain/domain_model/transform_steps/step2_domain_models.rb +123 -0
  20. data/lib/k_domain/domain_model/transform_steps/{step8_rails_resource_models.rb → step4_rails_resource_models.rb} +4 -4
  21. data/lib/k_domain/domain_model/transform_steps/step5_rails_resource_routes.rb +36 -0
  22. data/lib/k_domain/domain_model/transform_steps/step6_rails_structure_models.rb +90 -0
  23. data/lib/k_domain/domain_model/transform_steps/step7_rails_structure_controllers.rb +111 -0
  24. data/lib/k_domain/domain_model/transform_steps/step8_domain_columns.rb +99 -0
  25. data/lib/k_domain/rails_code_extractor/_.rb +5 -0
  26. data/lib/k_domain/rails_code_extractor/extract_controller.rb +61 -0
  27. data/lib/k_domain/rails_code_extractor/extract_model.rb +56 -6
  28. data/lib/k_domain/rails_code_extractor/{load_shim.rb → shim_loader.rb} +3 -5
  29. data/lib/k_domain/raw_db_schema/load.rb +1 -1
  30. data/lib/k_domain/raw_db_schema/transform.rb +28 -3
  31. data/lib/k_domain/schemas/_.rb +6 -3
  32. data/lib/k_domain/schemas/database.rb +86 -0
  33. data/lib/k_domain/schemas/domain/erd_file.rb +78 -77
  34. data/lib/k_domain/schemas/domain.rb +149 -0
  35. data/lib/k_domain/schemas/domain_model.rb +6 -5
  36. data/lib/k_domain/schemas/{domain/_.rb → domain_types.rb} +1 -8
  37. data/lib/k_domain/schemas/rails_resource.rb +43 -6
  38. data/lib/k_domain/schemas/rails_structure.rb +182 -0
  39. data/lib/k_domain/version.rb +1 -1
  40. data/lib/k_domain.rb +4 -2
  41. data/templates/custom/action_controller.rb +36 -0
  42. data/templates/custom/controller_interceptors.rb +78 -0
  43. data/templates/custom/model_interceptors.rb +71 -0
  44. data/templates/load_schema.rb +7 -0
  45. data/templates/rails/action_controller.rb +301 -0
  46. data/templates/{active_record_shims.rb → rails/active_record.rb} +42 -49
  47. data/templates/ruby_code_extractor/attach_class_info.rb +13 -0
  48. data/templates/ruby_code_extractor/behaviour_accessors.rb +39 -0
  49. data/templates/sample_config.rb +47 -0
  50. data/templates/simple/controller_interceptors.rb +2 -0
  51. metadata +33 -22
  52. data/lib/k_domain/domain_model/transform_steps/step2_attach_models.rb +0 -62
  53. data/lib/k_domain/domain_model/transform_steps/step3_attach_columns.rb +0 -137
  54. data/lib/k_domain/domain_model/transform_steps/step4_attach_erd_files.rb +0 -457
  55. data/lib/k_domain/domain_model/transform_steps/step9_rails_structure_models.rb +0 -33
  56. data/lib/k_domain/schemas/database/_.rb +0 -7
  57. data/lib/k_domain/schemas/database/foreign_key.rb +0 -14
  58. data/lib/k_domain/schemas/database/index.rb +0 -14
  59. data/lib/k_domain/schemas/database/schema.rb +0 -31
  60. data/lib/k_domain/schemas/database/table.rb +0 -32
  61. data/lib/k_domain/schemas/domain/domain.rb +0 -11
  62. data/lib/k_domain/schemas/domain/models/column.rb +0 -49
  63. data/lib/k_domain/schemas/domain/models/model.rb +0 -111
  64. data/templates/fake_module_shims.rb +0 -42
@@ -1,62 +0,0 @@
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
@@ -1,137 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Attach columns to models
4
- class Step3AttachColumns < KDomain::DomainModel::Step
5
- attr_accessor :table
6
- attr_reader :column_name
7
- attr_reader :column_symbol
8
-
9
- def call
10
- build_columns
11
- end
12
-
13
- def build_columns
14
- domain_models.each do |model|
15
- @table = find_table_for_model(model)
16
- columns = columns(table[:columns])
17
- columns = insert_primary_key(model, columns)
18
- model[:columns] = columns
19
- end
20
- end
21
-
22
- def column_data(name)
23
- @column_name = name
24
- @column_symbol = name.to_sym
25
- {
26
- name: name,
27
- name_plural: name.pluralize,
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)
51
- end
52
- end
53
-
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
- def expand_column(column)
66
- foreign_table = lookup_foreign_table(column_name)
67
- is_foreign = !foreign_table.nil?
68
- # is_foreign = foreign_key?(column_name)
69
- structure_type = structure_type(is_foreign)
70
-
71
- column.merge({
72
- structure_type: structure_type,
73
- foreign_key: is_foreign,
74
- foreign_table: (foreign_table || '').singularize,
75
- foreign_table_plural: (foreign_table || '').pluralize
76
- })
77
- end
78
-
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
- def lookup_foreign_table(column_name)
96
- foreign_table = find_foreign_table(table[:name], column_name)
97
-
98
- return foreign_table if foreign_table
99
-
100
- cn = column_name.to_s
101
-
102
- if cn.ends_with?('_id')
103
- table_name = column_name[0..-4]
104
- table_name_plural = table_name.pluralize
105
-
106
- if table_name_exist?(table_name_plural.to_s)
107
- investigate(step: :step3_attach_columns,
108
- location: :lookup_foreign_table,
109
- key: column_name,
110
- 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")
111
-
112
- return table_name
113
- end
114
-
115
- investigate(step: :step3_attach_columns,
116
- location: :lookup_foreign_table,
117
- key: column_name,
118
- message: "#{@table[:name]}.#{column_name} => #{table_name_plural} - Table not found for a column that looks like foreign_key")
119
- end
120
-
121
- nil
122
- end
123
-
124
- # Need some configurable data dictionary where by
125
- # _token can be setup on a project by project basis
126
- def structure_type(is_foreign)
127
- return :foreign_key if is_foreign
128
- return :primary_key if column_symbol == :id
129
- return :timestamp if column_symbol == :created_at || column_symbol == :updated_at
130
- return :timestamp if column_symbol == :created_at || column_symbol == :updated_at
131
- return :deleted_at if column_symbol == :deleted_at
132
- return :encrypted_password if column_symbol == :encrypted_password
133
- return :token if column_name.ends_with?('_token') || column_name.ends_with?('_token_iv')
134
-
135
- :data
136
- end
137
- end
@@ -1,457 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Attach source code found in rails model definitions to models
4
- class Step4AttachErdFiles < KDomain::DomainModel::Step
5
- attr_accessor :ruby_code
6
-
7
- # NOTE: This code could be rewritten using monkey patched modules and peak
8
- def call
9
- domain[:erd_files] = domain_models.map { |model| load_dsl(model) }
10
- end
11
-
12
- private
13
-
14
- def reset_dsl
15
- @ruby_code = nil
16
- @dsl = nil
17
- end
18
-
19
- def dsl
20
- @dsl ||= {
21
- name: '',
22
- name_plural: ''
23
- }
24
- end
25
-
26
- def load_dsl(model)
27
- # this should be a configuration
28
- # print '.'
29
-
30
- reset_dsl
31
-
32
- dsl[:name] = model[:name]
33
- dsl[:name_plural] = model[:name_plural]
34
- dsl[:dsl_file] = model[:erd_location][:exist] ? model[:erd_location][:file] : ''
35
-
36
- return dsl unless File.exist?(dsl[:dsl_file])
37
-
38
- @ruby_code = File.read(dsl[:dsl_file])
39
-
40
- dsl[:source] = read_dsl_source
41
- dsl[:dsl] = build_dsl
42
- dsl[:todo] = todo
43
-
44
- dsl
45
- end
46
-
47
- def read_dsl_source
48
- regex_split_private_public = /(?<public>.+?)(?=\bprivate\b)(?<private>.*)/m
49
-
50
- split_code = regex_split_private_public.match(ruby_code)
51
-
52
- public_code = nil
53
- private_code = nil
54
-
55
- if split_code
56
- public_code = split_code[:public]
57
- private_code = split_code[:private]
58
- end
59
-
60
- {
61
- ruby: ruby_code,
62
- public: public_code,
63
- private: private_code,
64
- all_methods: grab_methods(public_code, private_code)
65
- }
66
- end
67
-
68
- def build_dsl
69
- return if ruby_code.nil?
70
-
71
- # need to support options as hash instead of options as string in the future
72
- {
73
- default_scope: grab_default_scope,
74
- scopes: grab_scopes,
75
- belongs_to: grab_belongs_to,
76
- has_one: grab_has_one,
77
- has_many: grab_has_many,
78
- has_and_belongs_to_many: grab_has_and_belongs_to_many,
79
- validate_on: grab_validate,
80
- validates_on: grab_validates
81
- }
82
-
83
- # ^(?<spaces>\s*)(?<event_type>before_create|before_save|before_destroy|after_create|after_save|after_destroy) (:(?<name>\w*)[, ]?(?<scope>.*)|(?<scope>\{.*?\}.*$))
84
- end
85
-
86
- def grab_default_scope
87
- regex = /default_scope \{(?<scope>.*?)\}/m
88
-
89
- m = regex.match(ruby_code)
90
-
91
- return "{ #{m[:scope].strip.gsub('\n', '')} }" if m
92
-
93
- nil
94
- end
95
-
96
- def grab_scopes
97
- entries = []
98
- # Start from beginning of line and capture
99
- # - number of spaces scope
100
- # - name of scope
101
- # - value of scope to end of line
102
- regex = /^(?<spaces>\s*)scope :(?<name>\w*)[, ]?(?<scope>.*)/
103
-
104
- # rubocop:disable Metrics/BlockLength
105
- ruby_code.scan(regex) do
106
- m = $LAST_MATCH_INFO
107
- spaces = m[:spaces] # .delete("\n")
108
- last_lf = spaces.rindex("\n")
109
- spaces = last_lf ? spaces[spaces.rindex("\n") + 1..-1] : spaces
110
- name = m[:name]
111
- scope = m[:scope].strip
112
-
113
- # Found a valid one liner
114
- if scope.ends_with?('}') && (scope.scan(/{/).count == scope.scan(/}/).count)
115
- scope = escape_single_quote(scope)
116
- entries << { name: name, scope: scope }
117
- else
118
- # Have a multiline scope, lets see if it is cleanly formatted
119
-
120
- start_anchor = "#{spaces}scope :#{name}"
121
- end_anchor = "#{spaces}}"
122
-
123
- # log.kv 'spaces', spaces.length
124
- # log.kv 'name', name
125
- # log.kv 'start_anchor', start_anchor
126
- # log.kv 'end_anchor', end_anchor
127
-
128
- start_index = ruby_code.index(/#{start_anchor}/)
129
-
130
- if start_index.nil?
131
- log.error("[#{@current_entity[:name]}] could not find [start] anchor index for [#{name}]")
132
- else
133
- ruby_section = ruby_code[start_index..-1]
134
- end_index = ruby_section.index(/^#{end_anchor}/) # Add ^ start of line
135
- if end_index.nil?
136
- log.error("[#{@current_entity[:name]}] could not find [end] anchor index for [#{name}]")
137
- else
138
- scope = ruby_section[start_anchor.length + 1..end_index].strip
139
- scope = escape_single_quote("#{scope}#{end_anchor}")
140
- entries << { name: name, scope: scope }
141
- end
142
- end
143
- end
144
- end
145
- entries
146
- rescue StandardError => e
147
- # bin ding.pry
148
- puts e.message
149
- end
150
- # rubocop:enable Metrics/BlockLength
151
-
152
- def grab_belongs_to
153
- entries = []
154
-
155
- # Start from beginning of line and capture
156
- # - number of spaces before belongs_to
157
- # - name of the belongs_to
158
- # - value of belongs_to to end of line
159
- regex = /^(?<spaces>\s*)belongs_to :(?<name>\w*)[, ]?(?<options>.*)/
160
-
161
- ruby_code.scan(regex) do
162
- m = $LAST_MATCH_INFO
163
-
164
- # spaces = m[:spaces] # .delete("\n")
165
- # last_lf = spaces.rindex("\n")
166
- # spaces = last_lf ? spaces[spaces.rindex("\n") + 1..-1] : spaces
167
- name = m[:name]
168
-
169
- options = m[:options]
170
- .gsub(':polymorphic => ', 'polymorphic: ')
171
- .gsub(':class_name => ', 'class_name: ')
172
- .gsub(':foreign_key => ', 'foreign_key: ')
173
- .strip
174
-
175
- options = clean_lambda(options)
176
-
177
- entries << { name: name, options: extract_options(options), raw_options: options }
178
- end
179
- entries
180
- rescue StandardError => e
181
- # bin ding.pry
182
- puts e.message
183
- end
184
-
185
- def grab_has_one
186
- entries = []
187
-
188
- # Start from beginning of line and capture
189
- # - number of spaces before has_one
190
- # - name of the has_one
191
- # - value of has_one to end of line
192
- regex = /^(?<spaces>\s*)has_one :(?<name>\w*)[, ]?(?<options>.*)/
193
-
194
- ruby_code.scan(regex) do
195
- m = $LAST_MATCH_INFO
196
-
197
- # spaces = m[:spaces] # .delete("\n")
198
- # last_lf = spaces.rindex("\n")
199
- # spaces = last_lf ? spaces[spaces.rindex("\n") + 1..-1] : spaces
200
- name = m[:name]
201
- options = m[:options]
202
- .strip
203
- # .gsub(':polymorphic => ', 'polymorphic: ')
204
- # .gsub(':class_name => ', 'class_name: ')
205
- # .gsub(':foreign_key => ', 'foreign_key: ')
206
-
207
- options = clean_lambda(options)
208
-
209
- entries << { name: name, options: extract_options(options), raw_options: options }
210
- end
211
- entries
212
- rescue StandardError => e
213
- # bin ding.pry
214
- puts e.message
215
- end
216
-
217
- def grab_has_many
218
- entries = []
219
- # Start from beginning of line and capture
220
- # - number of spaces before has_many
221
- # - name of the has_many
222
- # - value of has_many to end of line
223
- regex = /^(?<spaces>\s*)has_many :(?<name>\w*)[, ]?(?<options>.*)/
224
-
225
- ruby_code.scan(regex) do
226
- m = $LAST_MATCH_INFO
227
-
228
- # spaces = m[:spaces] # .delete("\n")
229
- # last_lf = spaces.rindex("\n")
230
- # spaces = last_lf ? spaces[spaces.rindex("\n") + 1..-1] : spaces
231
- name = m[:name]
232
- options = m[:options]
233
- .gsub(':dependent => ', 'dependent: ')
234
- .gsub(':class_name => ', 'class_name: ')
235
- .gsub(':foreign_key => ', 'foreign_key: ')
236
- .gsub(':primary_key => ', 'primary_key: ')
237
- .strip
238
-
239
- options = clean_lambda(options)
240
-
241
- entries << { name: name, options: extract_options(options), raw_options: options }
242
- end
243
- entries
244
- rescue StandardError => e
245
- # bin ding.pry
246
- puts e.message
247
- end
248
-
249
- def grab_has_and_belongs_to_many
250
- entries = []
251
- # Start from beginning of line and capture
252
- # - number of spaces before has_and_belongs_to_many
253
- # - name of the has_and_belongs_to_many
254
- # - value of has_and_belongs_to_many to end of line
255
- regex = /^(?<spaces>\s*)has_and_belongs_to_many :(?<name>\w*)[, ]?(?<options>.*)/
256
-
257
- ruby_code.scan(regex) do
258
- m = $LAST_MATCH_INFO
259
-
260
- # spaces = m[:spaces] # .delete("\n")
261
- # last_lf = spaces.rindex("\n")
262
- # spaces = last_lf ? spaces[spaces.rindex("\n") + 1..-1] : spaces
263
- name = m[:name]
264
- options = m[:options]
265
- .gsub(':dependent => ', 'dependent: ')
266
- .gsub(':class_name => ', 'class_name: ')
267
- .gsub(':foreign_key => ', 'foreign_key: ')
268
- .gsub(':primary_key => ', 'primary_key: ')
269
- .strip
270
-
271
- options = clean_lambda(options)
272
-
273
- entries << { name: name, options: {}, raw_options: options }
274
- end
275
- entries
276
- rescue StandardError => e
277
- # bin ding.pry
278
- puts e.message
279
- end
280
-
281
- def grab_validates
282
- entries = []
283
- # Start from beginning of line and capture
284
- # - number of spaces before validates
285
- # - name of the validates
286
- # - value of validates to end of line
287
- regex = /^(?<spaces>\s*)validates :(?<name>\w*)[, ]?(?<options>.*)/
288
-
289
- ruby_code.scan(regex) do
290
- m = $LAST_MATCH_INFO
291
-
292
- # spaces = m[:spaces] # .delete("\n")
293
- # last_lf = spaces.rindex("\n")
294
- # spaces = last_lf ? spaces[spaces.rindex("\n") + 1..-1] : spaces
295
- name = m[:name]
296
-
297
- options = m[:options].strip
298
-
299
- options = clean_lambda(options)
300
-
301
- entries << { name: name, raw_options: options }
302
- end
303
- entries
304
- rescue StandardError => e
305
- # bin ding.pry
306
- puts e.message
307
- end
308
-
309
- def grab_validate
310
- entries = []
311
- # Start from beginning of line and capture
312
- # - number of spaces before validate
313
- # - list of methods to call until to end of line
314
- # regex = /^(?<spaces>\s*)validate :(?<name>\w*)[, ]?(?<options>.*)/
315
- regex = /^(?<spaces>\s*)validate (?<line>:.*)/
316
- # puts @current_entity[:name]
317
-
318
- ruby_code.scan(regex) do
319
- m = $LAST_MATCH_INFO
320
-
321
- # spaces = m[:spaces] # .delete("\n")
322
- # last_lf = spaces.rindex("\n")
323
- # spaces = last_lf ? spaces[spaces.rindex("\n") + 1..-1] : spaces
324
- line = m[:line]
325
-
326
- entries << { line: line }
327
- # puts @current_entity[:validate]
328
- end
329
- entries
330
- rescue StandardError => e
331
- # bin ding.pry
332
- puts e.message
333
- end
334
-
335
- def grab_methods(public_code = ruby_code, private_code = nil)
336
- # public_code = ruby_code_public.nil? ? ruby_code : ruby_code_public
337
- # private_code = ruby_code_private
338
-
339
- regex = /def (?<method>.*)/
340
-
341
- # log.info(@current_entity[:name])
342
-
343
- public_methods = parse_methods(:public, public_code&.scan(regex)&.flatten || [])
344
- private_methods = parse_methods(:private, private_code&.scan(regex)&.flatten || [])
345
- methods = (public_methods + private_methods)
346
-
347
- class_methods = methods.select { |method| method[:class_method] == true }
348
-
349
- all_instance = methods.select { |method| method[:class_method] == false }
350
- instance_public = all_instance.select { |method| method[:scope] == :public }
351
- instance_private = all_instance.select { |method| method[:scope] == :private }
352
-
353
- {
354
- klass: class_methods,
355
- instance: all_instance,
356
- instance_public: instance_public,
357
- instance_private: instance_private
358
- }
359
- end
360
-
361
- def parse_methods(scope, methods)
362
- methods.map do |value|
363
- class_method = value.starts_with?('self.')
364
- name = class_method ? value[5..-1] : value
365
- arguments = nil
366
- arguments_index = name.index('(')
367
-
368
- if arguments_index
369
- arguments = name[arguments_index..-1]
370
- name = name[0..arguments_index - 1]
371
- end
372
-
373
- arguments = escape_single_quote(arguments)
374
-
375
- {
376
- name: name,
377
- scope: scope,
378
- class_method: class_method,
379
- arguments: arguments&.strip.to_s
380
- }
381
- end
382
- end
383
-
384
- def todo
385
- {
386
- after_destroy: [], # to do
387
- before_save: [], # to do
388
- after_save: [], # to do
389
- before_create: [], # to do
390
- after_create: [], # to do
391
- enum: [], # to do
392
- attr_encrypted: [], # to do
393
- validates_uniqueness_of: [], # to do
394
- validates_confirmation_of: [], # to do
395
- attr_accessor: [], # to do
396
- attr_reader: [], # to do
397
- attr_writer: [] # to do
398
- }
399
- end
400
-
401
- def escape_single_quote(value)
402
- return nil if value.nil?
403
-
404
- value.gsub("'", "\\\\'")
405
- end
406
-
407
- # rubocop:disable Style/EvalWithLocation, Security/Eval, Style/DocumentDynamicEvalDefinition
408
- def extract_options(options)
409
- eval("{ #{options} }")
410
- rescue StandardError => e
411
- investigate(
412
- step: :step4_attach_erd_files_models,
413
- location: :extract_options,
414
- key: nil,
415
- message: e.message
416
- )
417
- {}
418
- rescue SyntaxError => e
419
- # may be the issue is from a comment at the off the line
420
- comment_index = options.rindex('#') - 1
421
-
422
- if comment_index.positive?
423
- options_minus_comment = options[0..comment_index].squish
424
- return extract_options(options_minus_comment)
425
- end
426
-
427
- investigate(
428
- step: :step4_attach_erd_files_models,
429
- location: :extract_options,
430
- key: nil,
431
- message: e.message
432
- )
433
- {}
434
- end
435
- # rubocop:enable Style/EvalWithLocation, Security/Eval, Style/DocumentDynamicEvalDefinition
436
-
437
- def clean_lambda(options)
438
- if /^->/.match?(options)
439
- index = options.index(/}\s*,/)
440
- if index.nil?
441
- if options.count('{') == options.count('}')
442
- index = options.rindex(/}/)
443
- options = "a_lambda: '#{escape_single_quote(options[0..index])}'"
444
- else
445
- log.error(options)
446
- options = "a_lambda: '#{escape_single_quote(options)}'"
447
- end
448
- else
449
- options = "a_lambda: '#{escape_single_quote(options[0..index])}', #{options[index + 2..-1]}"
450
- end
451
- end
452
- options
453
- rescue StandardError => e
454
- # bin ding.pry
455
- puts e.message
456
- end
457
- end
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Locate rails model files
4
- class Step9RailsStructureModels < KDomain::DomainModel::Step
5
- attr_accessor :ruby_code
6
-
7
- def call
8
- raise 'ERD path not supplied' if opts[:erd_path].nil?
9
-
10
- self.rails_structure_models = rails_resource_models.map do |resource|
11
- process_resource(OpenStruct.new(resource))
12
- end
13
- end
14
-
15
- private
16
-
17
- def process_resource(resource)
18
- erd_path = opts[:erd_path]
19
- puts erd_path
20
- @model = {
21
- model_name: resource.model_name,
22
- table_name: resource.table_name,
23
- file: resource.file,
24
- exist: resource.exist,
25
- state: resource.state,
26
- code: resource.exist ? File.read(resource.file) : '',
27
- behaviours: {},
28
- functions: {}
29
- }
30
-
31
- @model
32
- end
33
- end
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # The require order is important due to dependencies
4
- require_relative './index'
5
- require_relative './table'
6
- require_relative './foreign_key'
7
- require_relative './schema'
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module KDomain
4
- module Database
5
- class ForeignKey < Dry::Struct
6
- attribute :left , Types::Strict::String
7
- attribute :right , Types::Strict::String
8
- attribute :name? , Types::Strict::String.optional.default(nil)
9
- attribute :on_update? , Types::Strict::String.optional.default(nil)
10
- attribute :on_delete? , Types::Strict::String.optional.default(nil)
11
- attribute :column? , Types::Strict::String.optional.default(nil)
12
- end
13
- end
14
- end