k_domain 0.0.20 → 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.
- checksums.yaml +4 -4
- data/.builders/config/_.rb +3 -0
- data/.builders/setup.rb +30 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +1 -2
- data/Guardfile +1 -0
- data/README.md +15 -0
- data/lib/k_domain/domain_model/transform.rb +23 -13
- data/lib/k_domain/domain_model/transform_steps/_.rb +7 -5
- data/lib/k_domain/domain_model/transform_steps/step.rb +20 -0
- 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/{step6_attach_dictionary.rb → step20_dictionary.rb} +6 -6
- data/lib/k_domain/domain_model/transform_steps/step2_domain_models.rb +123 -0
- data/lib/k_domain/domain_model/transform_steps/step4_rails_resource_models.rb +3 -3
- 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 +19 -8
- data/lib/k_domain/rails_code_extractor/shim_loader.rb +1 -0
- data/lib/k_domain/raw_db_schema/load.rb +1 -1
- data/lib/k_domain/raw_db_schema/transform.rb +2 -1
- data/lib/k_domain/schemas/_.rb +2 -2
- data/lib/k_domain/schemas/database.rb +86 -0
- data/lib/k_domain/schemas/domain.rb +154 -0
- data/lib/k_domain/schemas/domain_model.rb +2 -2
- data/lib/k_domain/schemas/rails_resource.rb +43 -6
- data/lib/k_domain/schemas/rails_structure.rb +94 -14
- data/lib/k_domain/version.rb +1 -1
- data/lib/k_domain.rb +1 -2
- 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/{active_record_shims.rb → rails/active_record.rb} +21 -41
- 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 +26 -18
- data/lib/k_domain/domain_model/transform_steps/step2_attach_models.rb +0 -62
- data/lib/k_domain/domain_model/transform_steps/step5_rails_models.rb +0 -71
- 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
- data/templates/fake_module_shims.rb +0 -42
    
        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
         | 
| @@ -19,9 +19,9 @@ module KDomain | |
| 19 19 | 
             
                  def extract(file)
         | 
| 20 20 | 
             
                    load_shims unless shims_loaded
         | 
| 21 21 |  | 
| 22 | 
            -
                    ActiveRecord. | 
| 22 | 
            +
                    ActiveRecord.class_info = nil
         | 
| 23 23 |  | 
| 24 | 
            -
                    load_retry(file, 10)
         | 
| 24 | 
            +
                    load_retry(file, 10, nil)
         | 
| 25 25 | 
             
                  rescue StandardError => e
         | 
| 26 26 | 
             
                    log.exception(e)
         | 
| 27 27 | 
             
                  end
         | 
| @@ -34,23 +34,34 @@ module KDomain | |
| 34 34 | 
             
                  end
         | 
| 35 35 |  | 
| 36 36 | 
             
                  # rubocop:disable Security/Eval,Style/EvalWithLocation,Style/DocumentDynamicEvalDefinition,Metrics/AbcSize
         | 
| 37 | 
            -
                  def load_retry(file, times)
         | 
| 37 | 
            +
                  def load_retry(file, times, last_error)
         | 
| 38 38 | 
             
                    return if times.negative?
         | 
| 39 39 |  | 
| 40 40 | 
             
                    load(file)
         | 
| 41 41 |  | 
| 42 | 
            -
                    @model = ActiveRecord. | 
| 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 | 
            +
             | 
| 43 53 | 
             
                    @models << @model
         | 
| 44 54 |  | 
| 45 55 | 
             
                    # get_method_info(File.base_name(file))
         | 
| 46 56 | 
             
                  rescue StandardError => e
         | 
| 47 | 
            -
                     | 
| 48 | 
            -
                     | 
| 57 | 
            +
                    log.kv 'times', times
         | 
| 58 | 
            +
                    # puts e.message
         | 
| 59 | 
            +
                    if e.is_a?(NameError) && e.message != last_error&.message
         | 
| 49 60 | 
             
                      log.kv('add module', e.name)
         | 
| 50 61 | 
             
                      eval("module #{e.name}; end")
         | 
| 51 | 
            -
                      return load_retry( | 
| 62 | 
            +
                      return load_retry(file, times - 1, e)
         | 
| 52 63 | 
             
                    end
         | 
| 53 | 
            -
                    log.exception(e)
         | 
| 64 | 
            +
                    log.exception(e, style: :short, method_info: method(__callee__))
         | 
| 54 65 | 
             
                  end
         | 
| 55 66 | 
             
                  # rubocop:enable Security/Eval,Style/EvalWithLocation,Style/DocumentDynamicEvalDefinition,Metrics/AbcSize
         | 
| 56 67 | 
             
                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)
         | 
    
        data/lib/k_domain/schemas/_.rb
    CHANGED
    
    | @@ -9,8 +9,8 @@ end | |
| 9 9 | 
             
            require_relative 'rails_resource'
         | 
| 10 10 | 
             
            require_relative 'rails_structure'
         | 
| 11 11 | 
             
            require_relative 'investigate'
         | 
| 12 | 
            -
            require_relative 'database | 
| 12 | 
            +
            require_relative 'database'
         | 
| 13 13 | 
             
            require_relative 'dictionary'
         | 
| 14 | 
            -
            require_relative 'domain | 
| 14 | 
            +
            require_relative 'domain'
         | 
| 15 15 |  | 
| 16 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
         | 
| @@ -0,0 +1,154 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # Domain class holds a list of the entities
         | 
| 4 | 
            +
            module KDomain
         | 
| 5 | 
            +
              module Schemas
         | 
| 6 | 
            +
                class Domain < Dry::Struct
         | 
| 7 | 
            +
                  class Model < Dry::Struct
         | 
| 8 | 
            +
                    class Column < Dry::Struct
         | 
| 9 | 
            +
                      attribute :name                 , Types::Strict::String                         #  "source_account_id"
         | 
| 10 | 
            +
                      attribute :name_plural          , Types::Strict::String                         #  "source_account_ids"
         | 
| 11 | 
            +
                      attribute :type                 , Types::Coercible::Symbol                      #  "integer"
         | 
| 12 | 
            +
                      attribute :precision            , Types::Strict::Integer.optional.default(nil)  #  null
         | 
| 13 | 
            +
                      attribute :scale                , Types::Strict::Integer.optional.default(nil)  #  null
         | 
| 14 | 
            +
                      attribute :default              , Types::Nominal::Any.optional.default(nil)     #  null
         | 
| 15 | 
            +
                      attribute :null                 , Types::Nominal::Any.optional.default(nil)     #  null
         | 
| 16 | 
            +
                      attribute :limit                , Types::Strict::Integer.optional.default(nil)  #  null
         | 
| 17 | 
            +
                      attribute :array                , Types::Strict::Bool.optional.default(nil)     #  null
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                      # Calculated value
         | 
| 20 | 
            +
                      attribute :structure_type       , Types::Coercible::Symbol #
         | 
| 21 | 
            +
                      # attribute :foreign_key          , Types::Strict::Bool.optional.default(nil)     #
         | 
| 22 | 
            +
                      # attribute :foreign_table        , Types::Strict::String                         #
         | 
| 23 | 
            +
                      # attribute :foreign_table_plural , Types::Strict::String                         #
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                      # def data_column
         | 
| 26 | 
            +
                      #   @columns_data ||= structure_type?(:data)
         | 
| 27 | 
            +
                      # end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                      # def structure_type?(*structure_types)
         | 
| 30 | 
            +
                      #   structure_types.include?(column.structure_type)
         | 
| 31 | 
            +
                      # end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                      def db_type
         | 
| 34 | 
            +
                        return @db_type if defined? @db_type
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                        @db_type = DB_TYPE[type] || '******'
         | 
| 37 | 
            +
                      end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                      def ruby_type
         | 
| 40 | 
            +
                        return @ruby_type if defined? @ruby_type
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                        @ruby_type = RUBY_TYPE[type] || '******'
         | 
| 43 | 
            +
                      end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                      def csharp_type
         | 
| 46 | 
            +
                        return @csharp_type if defined? @csharp_type
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                        @csharp_type = CSHARP_TYPE[type] || '******'
         | 
| 49 | 
            +
                      end
         | 
| 50 | 
            +
                    end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                    class Pk < Dry::Struct
         | 
| 53 | 
            +
                      attribute :name               , Types::Strict::String.optional.default(nil)
         | 
| 54 | 
            +
                      attribute :type               , Types::Strict::String.optional.default(nil)
         | 
| 55 | 
            +
                      attribute :exist              , Types::Strict::Bool
         | 
| 56 | 
            +
                    end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                    attribute :name                 , Types::Strict::String
         | 
| 59 | 
            +
                    attribute :name_plural          , Types::Strict::String
         | 
| 60 | 
            +
                    attribute :table_name           , Types::Strict::String
         | 
| 61 | 
            +
                    # Model type - :entity, :basic_user, :admin_user, possibly: m2m, agg_root
         | 
| 62 | 
            +
                    attribute :type                 , Types::Strict::Symbol.optional.default(:entity)
         | 
| 63 | 
            +
                    attribute :pk                   , KDomain::Schemas::Domain::Model::Pk
         | 
| 64 | 
            +
                    attribute :columns              , Types::Strict::Array.of(KDomain::Schemas::Domain::Model::Column)
         | 
| 65 | 
            +
                    attribute :file                 , Types::Strict::String.optional.default(nil)
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                    def ruby?
         | 
| 68 | 
            +
                      file && File.exist?(file)
         | 
| 69 | 
            +
                    end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                    def pk?
         | 
| 72 | 
            +
                      pk.exist
         | 
| 73 | 
            +
                    end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                    # If filled in, the model has a main field that is useful for rendering and may be used for unique constraint, may also be called display_name
         | 
| 76 | 
            +
                    def main_key
         | 
| 77 | 
            +
                      @main_key ||= MainKey.lookup(name, columns_data)
         | 
| 78 | 
            +
                    end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                    def traits
         | 
| 81 | 
            +
                      @traits ||= Traits.lookup(name)
         | 
| 82 | 
            +
                    end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                    # def where()
         | 
| 85 | 
            +
                    # end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                    # def columns_where()
         | 
| 88 | 
            +
                    # end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                    # Column filters
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                    def columns_data
         | 
| 93 | 
            +
                      @columns_data ||= columns_for_structure_types(:data)
         | 
| 94 | 
            +
                    end
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                    # def columns_data_optional
         | 
| 97 | 
            +
                    #   @columns_data_optional ||= columns_for_structure_types(:data).select { |c| true }
         | 
| 98 | 
            +
                    # end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                    # def columns_data_required
         | 
| 101 | 
            +
                    #   @columns_data_required ||= columns_for_structure_types(:data).select { |c| false }
         | 
| 102 | 
            +
                    # end
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                    def columns_primary
         | 
| 105 | 
            +
                      @columns_primary ||= columns_for_structure_types(:primary_key)
         | 
| 106 | 
            +
                    end
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                    def columns_foreign
         | 
| 109 | 
            +
                      @columns_foreign ||= columns_for_structure_types(:foreign_key)
         | 
| 110 | 
            +
                    end
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                    def columns_timestamp
         | 
| 113 | 
            +
                      @columns_data_timestamp ||= columns_for_structure_types(:timestamp)
         | 
| 114 | 
            +
                    end
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                    def columns_deleted_at
         | 
| 117 | 
            +
                      @columns_data_deleted_at ||= columns_for_structure_types(:deleted_at)
         | 
| 118 | 
            +
                    end
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                    def columns_virtual
         | 
| 121 | 
            +
                      @columns_virtual ||= columns_for_structure_types(:timestamp, :deleted_at)
         | 
| 122 | 
            +
                    end
         | 
| 123 | 
            +
             | 
| 124 | 
            +
                    def columns_data_foreign
         | 
| 125 | 
            +
                      @columns_data_foreign ||= columns_for_structure_types(:data, :foreign_key)
         | 
| 126 | 
            +
                    end
         | 
| 127 | 
            +
                    alias rows_fields_and_fk columns_data_foreign
         | 
| 128 | 
            +
             | 
| 129 | 
            +
                    def columns_data_primary
         | 
| 130 | 
            +
                      @columns_data_primary ||= columns_for_structure_types(:data, :primary_key)
         | 
| 131 | 
            +
                    end
         | 
| 132 | 
            +
                    alias rows_fields_and_pk columns_data_primary
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                    def columns_data_virtual
         | 
| 135 | 
            +
                      @columns_data_virtual ||= columns_for_structure_types(:data, :timestamp, :deleted_at)
         | 
| 136 | 
            +
                    end
         | 
| 137 | 
            +
                    alias rows_fields_and_virtual columns_data_virtual
         | 
| 138 | 
            +
             | 
| 139 | 
            +
                    def columns_data_foreign_virtual
         | 
| 140 | 
            +
                      @columns_data_foreign_virtual ||= columns_for_structure_types(:data, :foreign_key, :timestamp, :deleted_at)
         | 
| 141 | 
            +
                    end
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                    private
         | 
| 144 | 
            +
             | 
| 145 | 
            +
                    def columns_for_structure_types(*structure_types)
         | 
| 146 | 
            +
                      columns.select { |column| structure_types.include?(column.structure_type) }
         | 
| 147 | 
            +
                    end
         | 
| 148 | 
            +
                  end
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                  attribute :models , Types::Strict::Array.of(KDomain::Schemas::Domain::Model)
         | 
| 151 | 
            +
                  # attribute :erd_files            , Types::Strict::Array.of(KDomain::DomainModel::ErdFile)
         | 
| 152 | 
            +
                end
         | 
| 153 | 
            +
              end
         | 
| 154 | 
            +
            end
         | 
| @@ -4,8 +4,8 @@ | |
| 4 4 | 
             
            module KDomain
         | 
| 5 5 | 
             
              module Schemas
         | 
| 6 6 | 
             
                class DomainModel < Dry::Struct
         | 
| 7 | 
            -
                  attribute :domain           , KDomain:: | 
| 8 | 
            -
                  attribute :database         , KDomain::Database | 
| 7 | 
            +
                  attribute :domain           , KDomain::Schemas::Domain
         | 
| 8 | 
            +
                  attribute :database         , KDomain::Schemas::Database
         | 
| 9 9 | 
             
                  attribute :dictionary       , KDomain::Schemas::Dictionary
         | 
| 10 10 | 
             
                  attribute :rails_resource   , KDomain::Schemas::RailsResource
         | 
| 11 11 | 
             
                  attribute :rails_structure  , KDomain::Schemas::RailsStructure
         | 
| @@ -3,13 +3,50 @@ | |
| 3 3 | 
             
            # Domain class holds a dictionary entry
         | 
| 4 4 | 
             
            module KDomain
         | 
| 5 5 | 
             
              module Schemas
         | 
| 6 | 
            +
                # Route related files
         | 
| 7 | 
            +
                module Types
         | 
| 8 | 
            +
                  include Dry.Types()
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  Verb      = Strict::String.enum('', 'GET', 'PATCH', 'POST', 'PUT', 'DELETE')
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                class Route < Dry::Struct
         | 
| 14 | 
            +
                  attribute :name                 , Types::String
         | 
| 15 | 
            +
                  attribute :controller_name      , Types::String
         | 
| 16 | 
            +
                  attribute :controller_path      , Types::String
         | 
| 17 | 
            +
                  attribute :controller_namespace , Types::String
         | 
| 18 | 
            +
                  attribute :controller_file      , Types::String
         | 
| 19 | 
            +
                  attribute :controller_exist     , Types::Bool
         | 
| 20 | 
            +
                  attribute :action               , Types::String.optional
         | 
| 21 | 
            +
                  attribute :uri_path             , Types::String
         | 
| 22 | 
            +
                  attribute :mime_match           , Types::String
         | 
| 23 | 
            +
                  attribute :verbs                , Types.Array(Types::Verb)
         | 
| 24 | 
            +
                  attribute :file                 , Types::String
         | 
| 25 | 
            +
                  attribute :exist                , Types::Bool
         | 
| 26 | 
            +
                  attribute :duplicate_verb       , Types::Bool
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                # Model related files
         | 
| 30 | 
            +
                class Model < Dry::Struct
         | 
| 31 | 
            +
                  attribute :model_name         , Types::String
         | 
| 32 | 
            +
                  attribute :table_name         , Types::String
         | 
| 33 | 
            +
                  attribute :file               , Types::String
         | 
| 34 | 
            +
                  attribute :exist              , Types::Bool
         | 
| 35 | 
            +
                  attribute :state              , Types::String
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 6 38 | 
             
                class RailsResource < Dry::Struct
         | 
| 7 | 
            -
                  attribute :models | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 39 | 
            +
                  attribute :models, Types.Array(Model)
         | 
| 40 | 
            +
                  attribute :routes, Types.Array(Route)
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  # def find_route(name)
         | 
| 43 | 
            +
                  #   name = name.to_s
         | 
| 44 | 
            +
                  #   routes.find { |route| route.name.to_s == name }
         | 
| 45 | 
            +
                  # end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  def find_model(name)
         | 
| 48 | 
            +
                    name = name.to_s
         | 
| 49 | 
            +
                    models.find { |model| model.model_name.to_s == name }
         | 
| 13 50 | 
             
                  end
         | 
| 14 51 | 
             
                end
         | 
| 15 52 | 
             
              end
         |