k_domain 0.0.14 → 0.0.23

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 (59) hide show
  1. checksums.yaml +4 -4
  2. data/.builders/config/_.rb +3 -0
  3. data/.builders/setup.rb +30 -0
  4. data/.gitignore +1 -0
  5. data/.rubocop.yml +4 -3
  6. data/Gemfile +1 -1
  7. data/Guardfile +1 -0
  8. data/README.md +15 -0
  9. data/STORIES.md +35 -6
  10. data/k_domain.gemspec +1 -1
  11. data/lib/k_domain/domain_model/load.rb +8 -2
  12. data/lib/k_domain/domain_model/transform.rb +34 -51
  13. data/lib/k_domain/domain_model/transform_steps/_.rb +8 -6
  14. data/lib/k_domain/domain_model/transform_steps/step.rb +47 -2
  15. data/lib/k_domain/domain_model/transform_steps/{step1_attach_db_schema.rb → step1_db_schema.rb} +2 -1
  16. data/lib/k_domain/domain_model/transform_steps/{step5_attach_dictionary.rb → step20_dictionary.rb} +7 -3
  17. data/lib/k_domain/domain_model/transform_steps/step2_domain_models.rb +123 -0
  18. data/lib/k_domain/domain_model/transform_steps/{step8_locate_rails_models.rb → step4_rails_resource_models.rb} +4 -4
  19. data/lib/k_domain/domain_model/transform_steps/step5_rails_resource_routes.rb +36 -0
  20. data/lib/k_domain/domain_model/transform_steps/step6_rails_structure_models.rb +90 -0
  21. data/lib/k_domain/domain_model/transform_steps/step7_rails_structure_controllers.rb +109 -0
  22. data/lib/k_domain/domain_model/transform_steps/{step3_attach_columns.rb → step8_domain_columns.rb} +40 -73
  23. data/lib/k_domain/rails_code_extractor/_.rb +5 -0
  24. data/lib/k_domain/rails_code_extractor/extract_controller.rb +59 -0
  25. data/lib/k_domain/rails_code_extractor/extract_model.rb +69 -0
  26. data/lib/k_domain/rails_code_extractor/shim_loader.rb +30 -0
  27. data/lib/k_domain/raw_db_schema/load.rb +8 -2
  28. data/lib/k_domain/raw_db_schema/transform.rb +9 -8
  29. data/lib/k_domain/schemas/_.rb +3 -2
  30. data/lib/k_domain/schemas/database.rb +86 -0
  31. data/lib/k_domain/schemas/domain/erd_file.rb +2 -0
  32. data/lib/k_domain/schemas/domain.rb +154 -0
  33. data/lib/k_domain/schemas/domain_model.rb +6 -5
  34. data/lib/k_domain/schemas/rails_resource.rb +43 -6
  35. data/lib/k_domain/schemas/rails_structure.rb +172 -0
  36. data/lib/k_domain/version.rb +1 -1
  37. data/lib/k_domain.rb +2 -0
  38. data/templates/custom/action_controller.rb +36 -0
  39. data/templates/custom/controller_interceptors.rb +78 -0
  40. data/templates/custom/model_interceptors.rb +71 -0
  41. data/templates/load_schema.rb +7 -0
  42. data/templates/old_printspeek_schema copy.rb +231 -0
  43. data/templates/old_printspeek_schema.rb +233 -0
  44. data/templates/rails/action_controller.rb +301 -0
  45. data/templates/rails/active_record.rb +348 -0
  46. data/templates/ruby_code_extractor/attach_class_info.rb +13 -0
  47. data/templates/ruby_code_extractor/behaviour_accessors.rb +39 -0
  48. data/templates/simple/controller_interceptors.rb +2 -0
  49. metadata +30 -17
  50. data/lib/k_domain/domain_model/transform_steps/step2_attach_models.rb +0 -62
  51. data/lib/k_domain/domain_model/transform_steps/step4_attach_erd_files.rb +0 -454
  52. data/lib/k_domain/schemas/database/_.rb +0 -7
  53. data/lib/k_domain/schemas/database/foreign_key.rb +0 -14
  54. data/lib/k_domain/schemas/database/index.rb +0 -14
  55. data/lib/k_domain/schemas/database/schema.rb +0 -31
  56. data/lib/k_domain/schemas/database/table.rb +0 -32
  57. data/lib/k_domain/schemas/domain/domain.rb +0 -11
  58. data/lib/k_domain/schemas/domain/models/column.rb +0 -49
  59. data/lib/k_domain/schemas/domain/models/model.rb +0 -111
@@ -0,0 +1,231 @@
1
+ # Store the raw schema for the tables that are used in the original PrintSpeak database
2
+ class SchemaPrintspeak
3
+ def self.instance
4
+ @instance ||= SchemaPrintspeak.new
5
+ end
6
+
7
+ attr_accessor :tables
8
+
9
+ def initialize
10
+ @tables = []
11
+ @current_table = nil
12
+ load_tables
13
+ end
14
+ private
15
+
16
+ def add_table(table)
17
+ @tables.push(table)
18
+ @current_table = table
19
+ end
20
+
21
+ def add_index(_table_name, columns, **opts)
22
+ @current_table[:indexes] = [] if @current_table[:indexes].nil?
23
+
24
+ @current_table[:indexes].push({columns: columns}.merge(opts))
25
+ end
26
+
27
+ # ----------------------------------------------------------------------
28
+ # Inject start
29
+ # original file: {{source_file}}
30
+ # ----------------------------------------------------------------------
31
+ def load_tables
32
+ {{rails_schema}}
33
+ end
34
+
35
+
36
+ def write_json(file)
37
+ schema[:meta][:rails] = @rails_version
38
+ File.write(file, JSON.pretty_generate(schema))
39
+ end
40
+
41
+ # This is the rails timestamp and will be replaced by the action rails version
42
+ def load(version:)
43
+ start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
44
+ # puts 'about to load'
45
+ yield if block_given?
46
+
47
+ schema[:meta][:rails] = @rails_version
48
+
49
+ sort
50
+ # code to time
51
+
52
+ # log.kv 'extensions', schema[:db_info][:extensions].length
53
+ # log.kv 'tables', schema[:tables].length
54
+ # log.kv 'indexes', schema[:indexes].length
55
+ # # a low foreign_keys count is indicative of not using SQL referential integrity
56
+ # log.kv 'foreign_keys', schema[:foreign_keys].length
57
+ # log.kv 'Time Taken', (finish - start)
58
+
59
+ # puts schema[:db_info][:extensions]
60
+ # print_unique_keys(type: :foreign_keys, title: 'unique options for foreign_keys')
61
+ # print_unique_keys(type: :columns, title: 'unique options for columns')
62
+ # print_unique_keys(type: :fields, category: :integer , title: 'unique options for column - integer')
63
+ # print_unique_keys(type: :fields, category: :decimal , title: 'unique options for column - decimal')
64
+ # print_unique_keys(type: :fields, category: :string , title: 'unique options for column - string')
65
+ # print_unique_keys(type: :fields, category: :datetime, title: 'unique options for column - datetime')
66
+ # print_unique_keys(type: :fields, category: :date , title: 'unique options for column - date')
67
+ # print_unique_keys(type: :fields, category: :text , title: 'unique options for column - text')
68
+ # print_unique_keys(type: :fields, category: :boolean , title: 'unique options for column - boolean')
69
+ # print_unique_keys(type: :fields, category: :jsonb , title: 'unique options for column - jsonb')
70
+ # print_unique_keys(type: :fields, category: :hstore , title: 'unique options for column - hstore')
71
+ # print_unique_keys(type: :fields, category: :float , title: 'unique options for column - float')
72
+ end
73
+
74
+ def enable_extension(name)
75
+ # puts "enable_extension(#{name})"
76
+ schema[:meta][:db_info][:extensions] << name
77
+ end
78
+
79
+ def create_table(name, **opts)
80
+ id = opts[:id]
81
+ primary_key = opts[:primary_key] || (id == false ? nil : "id")
82
+ primary_key_type = if id == false
83
+ nil
84
+ elsif id.nil?
85
+ "bigint"
86
+ else
87
+ id
88
+ end
89
+
90
+ @current_table = {
91
+ name: name,
92
+ primary_key: primary_key, # infer the actual value that should be in the database
93
+ primary_key_type: primary_key_type, # infer the actual value that should be in the database
94
+ columns: [],
95
+ indexes: [],
96
+ rails_schema: { # as reported by the rails schema
97
+ primary_key: opts[:primary_key],
98
+ id: id,
99
+ force: opts[:force]
100
+ }
101
+ }
102
+ # schema[:tables][name] = @current_table
103
+ schema[:tables] << @current_table
104
+
105
+ yield(self) if block_given?
106
+ end
107
+
108
+ def add_field(name, type, **opts)
109
+ # puts "add_field(#{name}, #{type})"
110
+ row = { name: name, type: type, **opts }
111
+ @current_table[:columns] << row
112
+
113
+ add_unique_keys(row.keys, type: :columns)
114
+ add_unique_keys(row.keys, type: :fields, category: type)
115
+ end
116
+
117
+ def add_index(name, fields, **opts)
118
+ # puts "add_index(#{name})"
119
+ row = { name: name, fields: fields, **opts }
120
+ @current_table[:indexes] << row
121
+ schema[:indexes] << row
122
+ add_unique_keys(row.keys, type: :indexes)
123
+ end
124
+
125
+ # This method was introduced onto the schema in rails 5
126
+ def index(fields, **opts)
127
+ @rails_version = 5
128
+ name = opts[:name]
129
+ opts.delete(:name)
130
+ add_index(name, fields, **opts)
131
+ end
132
+
133
+ def create_view(name, **opts)
134
+ row = { name: name, **opts }
135
+ schema[:views] << row
136
+ add_unique_keys(row.keys, type: :views)
137
+ end
138
+
139
+ def add_foreign_key(left_table, right_table, **opts)
140
+ # puts "add_foreign_key(#{left_table}, #{right_table})"
141
+ row = { left: left_table, right: right_table, **opts }
142
+ schema[:foreign_keys] << row
143
+ add_unique_keys(row.keys, type: :foreign_keys)
144
+ end
145
+
146
+ def add_unique_keys(keys, type:, category: nil)
147
+ key = [type, category, keys.join('-')].compact.join('|')
148
+ return if @unique_keys.key?(key)
149
+
150
+ @unique_keys[key] = key
151
+ schema[:meta][:unique_keys] << { type: type, category: category, key: keys.join(','), keys: keys }
152
+ end
153
+
154
+ def print_unique_keys(type:, category: nil, title: )
155
+ log.section_heading(title)
156
+
157
+ filter_key_infos = schema[:meta][:unique_keys].select { |key_info| key_info[:type] == type && (category.nil? || key_info[:category] == category) }
158
+
159
+ # log.kv 'all', filter_key_infos.flat_map { |key_info| key_info[:keys] }.uniq, 50
160
+
161
+ filter_key_infos.each do |key_info|
162
+ log.kv key_info[:key], key_info[:keys], 50
163
+ end
164
+ end
165
+
166
+ def integer(name, **opts)
167
+ add_field(name, :integer, **opts)
168
+ end
169
+
170
+ def bigint(name, **opts)
171
+ add_field(name, :bigint, **opts)
172
+ end
173
+
174
+ def decimal(name, **opts)
175
+ add_field(name, :decimal, **opts)
176
+ end
177
+
178
+ def string(name, **opts)
179
+ add_field(name, :string, **opts)
180
+ end
181
+
182
+ def datetime(name, **opts)
183
+ add_field(name, :datetime, **opts)
184
+ end
185
+
186
+ def date(name, **opts)
187
+ add_field(name, :date, **opts)
188
+ end
189
+
190
+ def text(name, **opts)
191
+ add_field(name, :text, **opts)
192
+ end
193
+
194
+ def boolean(name, **opts)
195
+ add_field(name, :boolean, **opts)
196
+ end
197
+
198
+ def jsonb(name, **opts)
199
+ add_field(name, :jsonb, **opts)
200
+ end
201
+
202
+ def hstore(name, **opts)
203
+ add_field(name, :hstore, **opts)
204
+ end
205
+
206
+ def float(name, **opts)
207
+ add_field(name, :float, **opts)
208
+ end
209
+
210
+ def sort
211
+ schema[:indexes].sort_by! { |i| i[:name] }
212
+ schema[:tables].each { |table| table[:indexes].sort_by! { |i| i[:name] } }
213
+
214
+ # Insert a key that represents all unique keys, and then sort
215
+ unique_keys_per_group = schema[:meta][:unique_keys]
216
+ .group_by { |key_info| [key_info[:type], key_info[:category]] }
217
+ .map do |group, values|
218
+ all_keys = values.flat_map { |key_info| key_info[:keys] }.uniq
219
+ {
220
+ type: group[0],
221
+ category: group[01],
222
+ key: 'all',
223
+ keys: all_keys
224
+ }
225
+ end
226
+
227
+ schema[:meta][:unique_keys].concat(unique_keys_per_group)
228
+ schema[:meta][:unique_keys].sort! { |a,b| ([a[:type], a[:category],a[:key]] <=> [b[:type], b[:category],b[:key]]) }
229
+ end
230
+
231
+ end
@@ -0,0 +1,233 @@
1
+ class LoadSchema
2
+ attr_reader :schema
3
+
4
+ # XMEN
5
+ def initialize
6
+ @unique_keys = {}
7
+ @current_table = nil
8
+ @rails_version = 4
9
+ @schema = {
10
+ tables: [],
11
+ foreign_keys: [],
12
+ indexes: [],
13
+ views: [],
14
+ meta: {
15
+ rails: @rails_version,
16
+ db_info: {
17
+ type: 'postgres',
18
+ version: nil, # TODO
19
+ extensions: []
20
+ },
21
+ unique_keys: []
22
+ }
23
+ }
24
+ end
25
+
26
+ # ----------------------------------------------------------------------
27
+ # Inject start
28
+ # original file: {{source_file}}
29
+ # ----------------------------------------------------------------------
30
+ def load_schema
31
+ {{rails_schema}}
32
+ end
33
+
34
+ # ----------------------------------------------------------------------
35
+ # original file: {{source_file}}
36
+ # Inject end
37
+ # ----------------------------------------------------------------------
38
+
39
+ def write_json(file)
40
+ schema[:meta][:rails] = @rails_version
41
+ File.write(file, JSON.pretty_generate(schema))
42
+ end
43
+
44
+ # This is the rails timestamp and will be replaced by the action rails version
45
+ def load(version:)
46
+ start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
47
+ # puts 'about to load'
48
+ yield if block_given?
49
+
50
+ schema[:meta][:rails] = @rails_version
51
+
52
+ sort
53
+ # code to time
54
+
55
+ # log.kv 'extensions', schema[:db_info][:extensions].length
56
+ # log.kv 'tables', schema[:tables].length
57
+ # log.kv 'indexes', schema[:indexes].length
58
+ # # a low foreign_keys count is indicative of not using SQL referential integrity
59
+ # log.kv 'foreign_keys', schema[:foreign_keys].length
60
+ # log.kv 'Time Taken', (finish - start)
61
+
62
+ # puts schema[:db_info][:extensions]
63
+ # print_unique_keys(type: :foreign_keys, title: 'unique options for foreign_keys')
64
+ # print_unique_keys(type: :columns, title: 'unique options for columns')
65
+ # print_unique_keys(type: :fields, category: :integer , title: 'unique options for column - integer')
66
+ # print_unique_keys(type: :fields, category: :decimal , title: 'unique options for column - decimal')
67
+ # print_unique_keys(type: :fields, category: :string , title: 'unique options for column - string')
68
+ # print_unique_keys(type: :fields, category: :datetime, title: 'unique options for column - datetime')
69
+ # print_unique_keys(type: :fields, category: :date , title: 'unique options for column - date')
70
+ # print_unique_keys(type: :fields, category: :text , title: 'unique options for column - text')
71
+ # print_unique_keys(type: :fields, category: :boolean , title: 'unique options for column - boolean')
72
+ # print_unique_keys(type: :fields, category: :jsonb , title: 'unique options for column - jsonb')
73
+ # print_unique_keys(type: :fields, category: :hstore , title: 'unique options for column - hstore')
74
+ # print_unique_keys(type: :fields, category: :float , title: 'unique options for column - float')
75
+ end
76
+
77
+ def enable_extension(name)
78
+ # puts "enable_extension(#{name})"
79
+ schema[:meta][:db_info][:extensions] << name
80
+ end
81
+
82
+ def create_table(name, **opts)
83
+ id = opts[:id]
84
+ primary_key = opts[:primary_key] || (id == false ? nil : "id")
85
+ primary_key_type = if id == false
86
+ nil
87
+ elsif id.nil?
88
+ "bigint"
89
+ else
90
+ id
91
+ end
92
+
93
+ @current_table = {
94
+ name: name,
95
+ primary_key: primary_key, # infer the actual value that should be in the database
96
+ primary_key_type: primary_key_type, # infer the actual value that should be in the database
97
+ columns: [],
98
+ indexes: [],
99
+ rails_schema: { # as reported by the rails schema
100
+ primary_key: opts[:primary_key],
101
+ id: id,
102
+ force: opts[:force]
103
+ }
104
+ }
105
+ # schema[:tables][name] = @current_table
106
+ schema[:tables] << @current_table
107
+
108
+ yield(self) if block_given?
109
+ end
110
+
111
+ def add_field(name, type, **opts)
112
+ # puts "add_field(#{name}, #{type})"
113
+ row = { name: name, type: type, **opts }
114
+ @current_table[:columns] << row
115
+
116
+ add_unique_keys(row.keys, type: :columns)
117
+ add_unique_keys(row.keys, type: :fields, category: type)
118
+ end
119
+
120
+ def add_index(name, fields, **opts)
121
+ # puts "add_index(#{name})"
122
+ row = { name: name, fields: fields, **opts }
123
+ @current_table[:indexes] << row
124
+ schema[:indexes] << row
125
+ add_unique_keys(row.keys, type: :indexes)
126
+ end
127
+
128
+ # This method was introduced onto the schema in rails 5
129
+ def index(fields, **opts)
130
+ @rails_version = 5
131
+ name = opts[:name]
132
+ opts.delete(:name)
133
+ add_index(name, fields, **opts)
134
+ end
135
+
136
+ def create_view(name, **opts)
137
+ row = { name: name, **opts }
138
+ schema[:views] << row
139
+ add_unique_keys(row.keys, type: :views)
140
+ end
141
+
142
+ def add_foreign_key(left_table, right_table, **opts)
143
+ # puts "add_foreign_key(#{left_table}, #{right_table})"
144
+ row = { left: left_table, right: right_table, **opts }
145
+ schema[:foreign_keys] << row
146
+ add_unique_keys(row.keys, type: :foreign_keys)
147
+ end
148
+
149
+ def add_unique_keys(keys, type:, category: nil)
150
+ key = [type, category, keys.join('-')].compact.join('|')
151
+ return if @unique_keys.key?(key)
152
+
153
+ @unique_keys[key] = key
154
+ schema[:meta][:unique_keys] << { type: type, category: category, key: keys.join(','), keys: keys }
155
+ end
156
+
157
+ def print_unique_keys(type:, category: nil, title: )
158
+ log.section_heading(title)
159
+
160
+ filter_key_infos = schema[:meta][:unique_keys].select { |key_info| key_info[:type] == type && (category.nil? || key_info[:category] == category) }
161
+
162
+ # log.kv 'all', filter_key_infos.flat_map { |key_info| key_info[:keys] }.uniq, 50
163
+
164
+ filter_key_infos.each do |key_info|
165
+ log.kv key_info[:key], key_info[:keys], 50
166
+ end
167
+ end
168
+
169
+ def integer(name, **opts)
170
+ add_field(name, :integer, **opts)
171
+ end
172
+
173
+ def bigint(name, **opts)
174
+ add_field(name, :bigint, **opts)
175
+ end
176
+
177
+ def decimal(name, **opts)
178
+ add_field(name, :decimal, **opts)
179
+ end
180
+
181
+ def string(name, **opts)
182
+ add_field(name, :string, **opts)
183
+ end
184
+
185
+ def datetime(name, **opts)
186
+ add_field(name, :datetime, **opts)
187
+ end
188
+
189
+ def date(name, **opts)
190
+ add_field(name, :date, **opts)
191
+ end
192
+
193
+ def text(name, **opts)
194
+ add_field(name, :text, **opts)
195
+ end
196
+
197
+ def boolean(name, **opts)
198
+ add_field(name, :boolean, **opts)
199
+ end
200
+
201
+ def jsonb(name, **opts)
202
+ add_field(name, :jsonb, **opts)
203
+ end
204
+
205
+ def hstore(name, **opts)
206
+ add_field(name, :hstore, **opts)
207
+ end
208
+
209
+ def float(name, **opts)
210
+ add_field(name, :float, **opts)
211
+ end
212
+
213
+ def sort
214
+ schema[:indexes].sort_by! { |i| i[:name] }
215
+ schema[:tables].each { |table| table[:indexes].sort_by! { |i| i[:name] } }
216
+
217
+ # Insert a key that represents all unique keys, and then sort
218
+ unique_keys_per_group = schema[:meta][:unique_keys]
219
+ .group_by { |key_info| [key_info[:type], key_info[:category]] }
220
+ .map do |group, values|
221
+ all_keys = values.flat_map { |key_info| key_info[:keys] }.uniq
222
+ {
223
+ type: group[0],
224
+ category: group[01],
225
+ key: 'all',
226
+ keys: all_keys
227
+ }
228
+ end
229
+
230
+ schema[:meta][:unique_keys].concat(unique_keys_per_group)
231
+ schema[:meta][:unique_keys].sort! { |a,b| ([a[:type], a[:category],a[:key]] <=> [b[:type], b[:category],b[:key]]) }
232
+ end
233
+ end