k_domain 0.0.23 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cbbddfe9857696b7a3a02fc370c51205d584fd08aaad5f8b8605dccebab02bc1
4
- data.tar.gz: c37fee293561e73b3ed4b4e31f9def8c13848217ee9c4d14efdcfc67a46d42ea
3
+ metadata.gz: 86f877b2fd5644c7ebd211c662cb4cd1ff63213dcc3cc588d3485f698a2bc7b9
4
+ data.tar.gz: 9999ee5fa153fa7c1833cd21a0a5a145cbee4a97cd11284c1bb4440157ae6d0a
5
5
  SHA512:
6
- metadata.gz: 12d58c761198fe6fa8336871ab5a3475c0a1caf358c09af2005e8bab3192c82b864663b867b3f2a39d8ba7c20e58258a8981ddd6339dbdb4edec73e37bca4652
7
- data.tar.gz: 0bfd25819a3425f2932ba751d9e4413b41ae2c617416751855ced16a7fc74f68eff64d87a92138c73b85b0df175f38b8b299f5912f67f8a78970926ff83a4df8
6
+ metadata.gz: 013e1f7524e395b9766831786cd1f4052eb6000fd35105c58bfb51869f9d1b93151f3fbc3e8fe349f59dd6819daf7d27e22a05ae5f95fba6826bf61af06eb235
7
+ data.tar.gz: c56d291ba618e70863e334bca9c1e817da700d6d0769e92ac5fb7d267b1f02068f6d4275e423264147066389d45dca831d3b3878eef45662d0f4ef8457d99e20
data/.builders/boot.rb ADDED
@@ -0,0 +1,40 @@
1
+ # Boot Sequence
2
+
3
+ include KLog::Logging
4
+
5
+ CONFIG_KEY = :k_domain
6
+
7
+ log.kv 'working folder', Dir.pwd
8
+
9
+ Handlebars::Helpers.configure do |config|
10
+ config_file = File.join(Gem.loaded_specs['handlebars-helpers'].full_gem_path, '.handlebars_helpers.json')
11
+ config.helper_config_file = config_file
12
+
13
+ string_config_file = File.join(Gem.loaded_specs['handlebars-helpers'].full_gem_path, '.handlebars_string_formatters.json')
14
+ config.string_formatter_config_file = string_config_file
15
+ end
16
+
17
+ def builder
18
+ @builder ||= KBuilder::BaseBuilder.init(KConfig.configuration(CONFIG_KEY))
19
+ end
20
+
21
+ KConfig.configure(CONFIG_KEY) do |config|
22
+ global_template = File.expand_path('~/dev/kgems/k_templates/templates')
23
+ config.target_folders.add(:app, File.expand_path('../', Dir.pwd))
24
+ config.target_folders.add(:lib_config, :app, 'lib/k_domain/config')
25
+ config.template_folders.add(:global_template, global_template)
26
+ config.template_folders.add(:app_template, File.expand_path('.templates', Dir.pwd))
27
+ end
28
+
29
+ KConfig.configuration(CONFIG_KEY).debug
30
+
31
+ area = KManager.add_area(CONFIG_KEY)
32
+ resource_manager = area.resource_manager
33
+ resource_manager.add_resource('https://raw.githubusercontent.com/klueless-io/k_playground/main/ruby/components/configuration/.builders/configuration_director.rb', content_type: :ruby)
34
+ resource_manager
35
+ .fileset
36
+ .glob('*.rb', exclude: ['boot.rb'])
37
+ .glob('generators/**/*.rb')
38
+ resource_manager.add_resources
39
+
40
+ KManager.boot
@@ -0,0 +1,22 @@
1
+ KManager.action do
2
+ def on_action
3
+ puts '-' * 70
4
+ builder.cd(:lib_config)
5
+ director = ConfigurationDirector
6
+ .init(builder, on_exist: :compare)
7
+ .style(:single)
8
+ .name('Domain Configuration')
9
+ .main_namespace('KDomain', 'Config')
10
+ .add_config_key(:default_main_key, "nil")
11
+ .add_config_key(:default_traits, "%i[trait1 trait2 trait3]")
12
+ .add_config_key(:fallback_keys, "%i[]")
13
+ .add_config_key(:entities, "[]")
14
+ # .logit
15
+
16
+ # dom = director.dom
17
+ # data = director.data
18
+
19
+ director.add_config
20
+ # director.add_configuration
21
+ end
22
+ end
data/.builders/run.rb ADDED
@@ -0,0 +1,16 @@
1
+ # Run
2
+
3
+ KManager.action do
4
+ def on_action
5
+ end
6
+ end
7
+
8
+ KManager.opts.app_name = 'KDomain Generator'
9
+ KManager.opts.sleep = 5
10
+ KManager.opts.reboot_on_kill = 0
11
+ KManager.opts.reboot_sleep = 4
12
+ KManager.opts.exception_style = :short
13
+ KManager.opts.show.time_taken = true
14
+ KManager.opts.show.finished = true
15
+ KManager.opts.show.finished_message = 'FINISHED :)'
16
+
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './config'
4
+ require_relative './configuration'
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Usage: include KDomain::Config::
4
+
5
+ module KDomain
6
+ module Config
7
+ def configuration
8
+ @configuration ||= KDomain::Config::Configuration.new
9
+ end
10
+
11
+ def reset
12
+ @configuration = KDomain::Config::Configuration.new
13
+ end
14
+
15
+ def configure
16
+ yield(configuration)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KDomain
4
+ module Config
5
+ # Configuration object for Domain Configuration
6
+ class Configuration
7
+ include KLog::Logging
8
+
9
+ ConfigModel = Struct.new(:name, :main_key, :traits)
10
+
11
+ attr_accessor :default_main_key
12
+ attr_accessor :default_traits
13
+ attr_accessor :fallback_keys
14
+ attr_accessor :models
15
+
16
+ def initialize
17
+ @default_main_key = nil
18
+ @default_traits = %i[trait1 trait2 trait3]
19
+ @fallback_keys = %i[]
20
+ @models = []
21
+ end
22
+
23
+ def model(name, main_key: nil, traits: nil)
24
+ @models << new_config_model(
25
+ name,
26
+ main_key: main_key || default_main_key,
27
+ traits: traits || default_traits
28
+ )
29
+ end
30
+
31
+ def find_model(table_name)
32
+ @find_model ||= Hash.new do |h, key|
33
+ h[key] = begin
34
+ entity = models.find { |e| e.name == key }
35
+ entity ||= new_config_model(key)
36
+ entity
37
+ end
38
+ end
39
+
40
+ @find_model[table_name]
41
+ end
42
+
43
+ def fallback_key(columns)
44
+ column_names = columns.each_with_object({}) do |column, hash|
45
+ hash[column.name.to_sym] = column.name.to_sym
46
+ end
47
+
48
+ fallback_keys.find { |key| column_names.key?(key) }
49
+ end
50
+
51
+ def debug(heading: 'Domain configuration')
52
+ log.structure(to_h, title: heading) # , line_width: 150, formatter: formatter)
53
+ ''
54
+ end
55
+
56
+ def to_h
57
+ {
58
+ default_main_key: default_main_key,
59
+ default_traits: default_traits,
60
+ fallback_keys: fallback_keys,
61
+ models: models.map(&:to_h)
62
+ }
63
+ end
64
+
65
+ private
66
+
67
+ def new_config_model(name, main_key: nil, traits: nil)
68
+ ConfigModel.new(
69
+ name,
70
+ main_key || default_main_key,
71
+ traits || default_traits
72
+ )
73
+ end
74
+ end
75
+ end
76
+ end
@@ -23,6 +23,8 @@ module KDomain
23
23
  @raw_data = KUtil.data.json_parse(json, as: :hash_symbolized)
24
24
 
25
25
  @data = KDomain::Schemas::DomainModel.new(@raw_data)
26
+
27
+ enrichment
26
28
  end
27
29
 
28
30
  def to_h
@@ -30,6 +32,45 @@ module KDomain
30
32
 
31
33
  @raw_data
32
34
  end
35
+
36
+ private
37
+
38
+ def enrichment
39
+ attach_rails_model_to_domain_model
40
+ end
41
+
42
+ def attach_rails_model_to_domain_model
43
+ @data.domain.models.each do |domain_model|
44
+ domain_model.rails_model = @data.rails_structure.find_model(domain_model.name)
45
+
46
+ if domain_model.rails_model
47
+ attach_column_relations(domain_model)
48
+ else
49
+ log.error("Rails Model not found for #{domain_model.name}") unless domain_model.rails_model
50
+ end
51
+ end
52
+ end
53
+
54
+ def attach_column_relations(domain_model)
55
+ domain_model.columns.each do |column|
56
+ column.relationships = []
57
+ add_column_relations(domain_model.rails_model, column, :belongs_to)
58
+ add_column_relations(domain_model.rails_model, column, :has_one)
59
+ add_column_relations(domain_model.rails_model, column, :has_many)
60
+ add_column_relations(domain_model.rails_model, column, :has_and_belongs_to_many)
61
+ end
62
+ end
63
+
64
+ def add_column_relations(rails_model, column, relation_type)
65
+ relations = rails_model.behaviours.send(relation_type)
66
+
67
+ return if relations.nil?
68
+
69
+ relations = relations.map { |relation| { relation_type: relation_type }.merge(relation.to_h) }
70
+ relations.select { |relation| column[:name] == relation.dig(:opts, :foreign_key) }.each do |relation|
71
+ column.relationships << KDomain::Schemas::Domain::Model::Relationship.new(relation)
72
+ end
73
+ end
33
74
  end
34
75
  end
35
76
  end
@@ -8,7 +8,7 @@ module KDomain
8
8
  raise 'Schema not supplied' if opts[:db_schema].nil?
9
9
 
10
10
  self.database = opts[:db_schema].clone
11
- database[:tables] = database[:tables] # .slice(156, 1)
11
+ database[:tables] = database[:tables] # .take(10) # .slice(156, 1)
12
12
 
13
13
  guard('tables are missing') if database[:tables].nil?
14
14
  guard('indexes are missing') if database[:indexes].nil?
@@ -18,7 +18,7 @@ class Step2DomainModels < KDomain::DomainModel::Step
18
18
  name_plural: table_name, # need to check if this is correct as I know it is wrong for account_history_datum
19
19
  table_name: table_name,
20
20
  pk: primary_key(table),
21
- file: nil
21
+ file: nil # will be set in step8_domain_columns
22
22
  }
23
23
 
24
24
  attach_columns(model)
@@ -66,7 +66,7 @@ class Step7RailsStructureControllers < KDomain::DomainModel::Step
66
66
  end
67
67
  controller[:behaviours] = extract_behavior(controller[:full_file])
68
68
  klass_name = controller[:behaviours][:class_name]
69
- controller[:functions] = extract_functions(klass_name)
69
+ controller[:functions] = extract_functions(klass_name, controller[:full_file])
70
70
  end
71
71
  end
72
72
 
@@ -97,13 +97,15 @@ class Step7RailsStructureControllers < KDomain::DomainModel::Step
97
97
  shim_loader
98
98
  end
99
99
 
100
- def extract_functions(klass_name)
100
+ def extract_functions(klass_name, controller_file)
101
101
  klass = Module.const_get(klass_name.classify)
102
102
 
103
103
  class_info = Peeky.api.build_class_info(klass.new)
104
104
 
105
105
  class_info.to_h
106
106
  rescue StandardError => e
107
- log.exception(e)
107
+ log.kv 'controller_file', controller_file
108
+ log.exception(e, style: :short)
109
+ {}
108
110
  end
109
111
  end
@@ -9,15 +9,15 @@ class Step8DomainColumns < KDomain::DomainModel::Step
9
9
  attr_reader :column_symbol
10
10
 
11
11
  def call
12
+ @debug = true
12
13
  enrich_columns
13
14
  end
14
15
 
15
16
  def enrich_columns
16
17
  # .select {|m| m[:name] == 'app_user'}
17
18
  domain_models.each do |model|
18
- @domain_model = model
19
+ @domain_model = enrich_model(model)
19
20
  # this will be nil if there is no rails model code
20
- @rails_model = find_rails_structure_models(domain_model[:name])
21
21
 
22
22
  # log.warn domain_model[:name]
23
23
  domain_model[:columns].each do |column|
@@ -25,75 +25,29 @@ class Step8DomainColumns < KDomain::DomainModel::Step
25
25
  @column_name = column[:name]
26
26
  @column_symbol = column[:name].to_sym
27
27
 
28
- attach_foreign_key
29
28
  column[:structure_type] = structure_type
30
29
  end
31
30
  end
32
31
  end
33
32
 
34
- def expand_column(column)
35
- foreign_table = lookup_foreign_table(column_name)
36
- is_foreign = !foreign_table.nil?
37
- # is_foreign = foreign_key?(column_name)
38
- structure_type = structure_type(is_foreign)
39
-
40
- column.merge({
41
- structure_type: structure_type,
42
- foreign_key: is_foreign,
43
- foreign_table: (foreign_table || '').singularize,
44
- foreign_table_plural: (foreign_table || '').pluralize
45
- })
46
- end
47
-
48
- def lookup_foreign_table(column_name)
49
- foreign_table = find_foreign_table(table[:name], column_name)
50
-
51
- return foreign_table if foreign_table
52
-
53
- cn = column_name.to_s
54
-
55
- if cn.ends_with?('_id')
56
- table_name = column_name[0..-4]
57
- table_name_plural = table_name.pluralize
58
-
59
- if table_name_exist?(table_name_plural.to_s)
60
- investigate(step: :step8_columns,
61
- location: :lookup_foreign_table,
62
- key: column_name,
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")
64
-
65
- return table_name
66
- end
67
-
68
- investigate(step: :step8_columns,
69
- location: :lookup_foreign_table,
70
- key: column_name,
71
- message: "#{@table[:name]}.#{column_name} => #{table_name_plural} - Table not found for a column that looks like foreign_key")
72
- end
73
-
74
- nil
75
- end
33
+ def enrich_model(model)
34
+ # NOTE: THIS MAY GET MOVED TO DomainModel::Load#enrichment
35
+ @rails_model = find_rails_structure_models(model[:name])
76
36
 
77
- def attach_foreign_key
78
- return if rails_model.nil? || rails_model[:behaviours].nil? || rails_model[:behaviours][:belongs_to].nil?
37
+ model[:file] = @rails_model[:file]
79
38
 
80
- foreign = rails_model[:behaviours][:belongs_to].find { |belong| belong[:opts][:foreign_key].to_sym == domain_column[:name].to_sym }
39
+ log.error "Rails model not found for: #{model[:name]}" unless @rails_model
81
40
 
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'
41
+ model
88
42
  end
89
43
 
90
44
  # Need some configurable data dictionary where by
91
45
  # _token can be setup on a project by project basis
92
46
  def structure_type
93
47
  return :primary_key if domain_model[:pk][:name] == column_name
94
- return :foreign_key if domain_column[:foreign_table]
48
+ return :foreign_key if foreign_relationship?
49
+ return :foreign_type if column_symbol == :context_type || column_symbol == :element_type
95
50
 
96
- return :timestamp if column_symbol == :created_at || column_symbol == :updated_at
97
51
  return :timestamp if column_symbol == :created_at || column_symbol == :updated_at
98
52
  return :deleted_at if column_symbol == :deleted_at
99
53
  return :encrypted_password if column_symbol == :encrypted_password
@@ -101,4 +55,45 @@ class Step8DomainColumns < KDomain::DomainModel::Step
101
55
 
102
56
  :data
103
57
  end
58
+
59
+ def foreign_relationship?
60
+ return false if rails_model.nil? || rails_model[:behaviours].nil? || rails_model[:behaviours][:belongs_to].nil?
61
+
62
+ column_name = domain_column[:name].to_sym
63
+ rails_model[:behaviours][:belongs_to].any? { |belong| belong[:opts][:foreign_key].to_sym == column_name }
64
+ end
65
+
66
+ # def attach_relationships
67
+ # domain_column[:relationships] = []
68
+ # return if rails_model.nil? || rails_model[:behaviours].nil? || rails_model[:behaviours][:belongs_to].nil?
69
+
70
+ # column_name = domain_column[:name].to_sym
71
+
72
+ # attach_column_relationships(column_name)
73
+ # end
74
+
75
+ # def select_belongs_to(column_name)
76
+ # rails_model[:behaviours][:belongs_to].select { |belong| belong[:opts][:foreign_key].to_sym == column_name.to_sym }
77
+ # end
78
+
79
+ # # this just maps basic relationship information,
80
+ # # to go deeper you really need to use the Rails Model Behaviours
81
+ # def attach_column_relationships(column_name)
82
+ # select_belongs_to(column_name).each do |belongs_to|
83
+ # domain_column[:relationships] << map_belongs_to(belongs_to)
84
+ # end
85
+ # end
86
+
87
+ # def map_belongs_to(belongs_to)
88
+ # @domain_column[:structure_type] = :foreign_key
89
+ # # result = {
90
+ # # type: :belongs_to,
91
+ # # name: belongs_to[:name],
92
+ # # foreign_key: belongs_to.dig(:opts, :foreign_key) || @domain_column[:name],
93
+ # # }
94
+
95
+ # # result[:primary_key] = belongs_to.dig(:opts, :primary_key) if belongs_to.dig(:opts, :primary_key)
96
+ # # result[:class_name] = belongs_to.dig(:opts, :class_name) if belongs_to.dig(:opts, :class_name)
97
+ # result
98
+ # end
104
99
  end
@@ -48,9 +48,11 @@ module KDomain
48
48
  # puts e.message
49
49
  if e.is_a?(NameError) && e.message != last_error&.message
50
50
  log.kv('add module', e.name)
51
+ log.kv 'file', file
51
52
  eval("module #{e.name}; end")
52
53
  return load_retry(file, times - 1, e)
53
54
  end
55
+ log.kv 'file', file
54
56
  log.exception(e, style: :short, method_info: method(__callee__))
55
57
  end
56
58
  # rubocop:enable Security/Eval,Style/EvalWithLocation,Style/DocumentDynamicEvalDefinition,Metrics/AbcSize
@@ -58,9 +58,11 @@ module KDomain
58
58
  # puts e.message
59
59
  if e.is_a?(NameError) && e.message != last_error&.message
60
60
  log.kv('add module', e.name)
61
+ log.kv 'file', file
61
62
  eval("module #{e.name}; end")
62
63
  return load_retry(file, times - 1, e)
63
64
  end
65
+ log.kv 'file', file
64
66
  log.exception(e, style: :short, method_info: method(__callee__))
65
67
  end
66
68
  # rubocop:enable Security/Eval,Style/EvalWithLocation,Style/DocumentDynamicEvalDefinition,Metrics/AbcSize
@@ -7,16 +7,29 @@
7
7
  # builds the hash
8
8
  module KDomain
9
9
  module RawDbSchema
10
+ # class TransformFilter
11
+ # attr_accessor :take
12
+ # def initialize(take: :all)
13
+ # @take = take
14
+ # end
15
+ # end
16
+
10
17
  class Transform
11
18
  include KLog::Logging
12
19
 
13
20
  attr_reader :source_file
14
21
  attr_accessor :template_file
15
22
  attr_reader :schema_loader
23
+ attr_reader :filter
16
24
 
17
- def initialize(source_file)
25
+ # @param [String] source_file Rails Schema file
26
+ # @param [OpenStruct] filter Settings for filtering data before transformation, this is useful during debugging
27
+ # examples
28
+ # filter = os(run: 1, tables: os(offset: 10, limit: 10))
29
+ def initialize(source_file, filter)
18
30
  @source_file = source_file
19
31
  @template_file = KDomain::Gem.resource('templates/load_schema.rb')
32
+ @filter = filter
20
33
  end
21
34
 
22
35
  def call
@@ -73,11 +86,22 @@ module KDomain
73
86
 
74
87
  loader = LoadSchema.new
75
88
  loader.load_schema
76
- loader.schema
89
+
90
+ apply_filter(loader.schema)
77
91
  rescue StandardError => e
78
92
  log.exception(e)
79
93
  end
80
94
  # rubocop:enable Security/Eval
95
+
96
+ # rubocop:disable Metrics/AbcSize
97
+ def apply_filter(schema)
98
+ return schema unless filter.active == 1
99
+
100
+ schema[:tables] = schema[:tables].slice(filter.table.offset, filter.table.limit) || [] if filter.table.offset.is_a?(Integer) && filter.table.limit.is_a?(Integer)
101
+
102
+ schema
103
+ end
104
+ # rubocop:enable Metrics/AbcSize
81
105
  end
82
106
  end
83
107
  end
@@ -11,6 +11,8 @@ require_relative 'rails_structure'
11
11
  require_relative 'investigate'
12
12
  require_relative 'database'
13
13
  require_relative 'dictionary'
14
+ require_relative 'domain_types'
14
15
  require_relative 'domain'
16
+ require_relative 'domain_model'
15
17
 
16
- require_relative './domain_model'
18
+ # require_relative './domain_model'