k_domain 0.0.20 → 0.0.23

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) 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 +1 -2
  6. data/Guardfile +1 -0
  7. data/README.md +15 -0
  8. data/lib/k_domain/domain_model/transform.rb +23 -13
  9. data/lib/k_domain/domain_model/transform_steps/_.rb +7 -5
  10. data/lib/k_domain/domain_model/transform_steps/step.rb +20 -0
  11. data/lib/k_domain/domain_model/transform_steps/{step1_attach_db_schema.rb → step1_db_schema.rb} +2 -1
  12. data/lib/k_domain/domain_model/transform_steps/{step6_attach_dictionary.rb → step20_dictionary.rb} +6 -6
  13. data/lib/k_domain/domain_model/transform_steps/step2_domain_models.rb +123 -0
  14. data/lib/k_domain/domain_model/transform_steps/step4_rails_resource_models.rb +3 -3
  15. data/lib/k_domain/domain_model/transform_steps/step5_rails_resource_routes.rb +36 -0
  16. data/lib/k_domain/domain_model/transform_steps/step6_rails_structure_models.rb +90 -0
  17. data/lib/k_domain/domain_model/transform_steps/step7_rails_structure_controllers.rb +109 -0
  18. data/lib/k_domain/domain_model/transform_steps/{step3_attach_columns.rb → step8_domain_columns.rb} +40 -73
  19. data/lib/k_domain/rails_code_extractor/_.rb +5 -0
  20. data/lib/k_domain/rails_code_extractor/extract_controller.rb +59 -0
  21. data/lib/k_domain/rails_code_extractor/extract_model.rb +19 -8
  22. data/lib/k_domain/rails_code_extractor/shim_loader.rb +1 -0
  23. data/lib/k_domain/raw_db_schema/load.rb +1 -1
  24. data/lib/k_domain/raw_db_schema/transform.rb +2 -1
  25. data/lib/k_domain/schemas/_.rb +2 -2
  26. data/lib/k_domain/schemas/database.rb +86 -0
  27. data/lib/k_domain/schemas/domain.rb +154 -0
  28. data/lib/k_domain/schemas/domain_model.rb +2 -2
  29. data/lib/k_domain/schemas/rails_resource.rb +43 -6
  30. data/lib/k_domain/schemas/rails_structure.rb +94 -14
  31. data/lib/k_domain/version.rb +1 -1
  32. data/lib/k_domain.rb +1 -2
  33. data/templates/custom/action_controller.rb +36 -0
  34. data/templates/custom/controller_interceptors.rb +78 -0
  35. data/templates/custom/model_interceptors.rb +71 -0
  36. data/templates/load_schema.rb +7 -0
  37. data/templates/old_printspeek_schema copy.rb +231 -0
  38. data/templates/old_printspeek_schema.rb +233 -0
  39. data/templates/rails/action_controller.rb +301 -0
  40. data/templates/{active_record_shims.rb → rails/active_record.rb} +21 -41
  41. data/templates/ruby_code_extractor/attach_class_info.rb +13 -0
  42. data/templates/ruby_code_extractor/behaviour_accessors.rb +39 -0
  43. data/templates/simple/controller_interceptors.rb +2 -0
  44. metadata +26 -18
  45. data/lib/k_domain/domain_model/transform_steps/step2_attach_models.rb +0 -62
  46. data/lib/k_domain/domain_model/transform_steps/step5_rails_models.rb +0 -71
  47. data/lib/k_domain/schemas/database/_.rb +0 -7
  48. data/lib/k_domain/schemas/database/foreign_key.rb +0 -14
  49. data/lib/k_domain/schemas/database/index.rb +0 -14
  50. data/lib/k_domain/schemas/database/schema.rb +0 -31
  51. data/lib/k_domain/schemas/database/table.rb +0 -32
  52. data/lib/k_domain/schemas/domain/domain.rb +0 -11
  53. data/lib/k_domain/schemas/domain/models/column.rb +0 -49
  54. data/lib/k_domain/schemas/domain/models/model.rb +0 -111
  55. data/templates/fake_module_shims.rb +0 -42
@@ -8,26 +8,26 @@ module KDomain
8
8
  attribute :block? , Types::Strict::String
9
9
  end
10
10
 
11
- class BaseType < Dry::Struct
12
- attribute :name? , Types::Strict::String
11
+ class NameOptsType < Dry::Struct
12
+ attribute :name? , Types::Strict::String | Types::Strict::Bool
13
13
  attribute :opts? , Types::Strict::Hash
14
14
  attribute :block? , Types::Strict::String.optional.default(nil)
15
15
  end
16
16
 
17
- class Scope < KDomain::Schemas::RailsStructure::BaseType
17
+ class OptsType < Dry::Struct
18
+ attribute :opts? , Types::Strict::Hash
18
19
  end
19
20
 
20
- class BelongsTo < KDomain::Schemas::RailsStructure::BaseType
21
- end
21
+ # Model Behaviours
22
+ class Scope < KDomain::Schemas::RailsStructure::NameOptsType; end
22
23
 
23
- class HasOne < KDomain::Schemas::RailsStructure::BaseType
24
- end
24
+ class BelongsTo < KDomain::Schemas::RailsStructure::NameOptsType; end
25
25
 
26
- class HasMany < KDomain::Schemas::RailsStructure::BaseType
27
- end
26
+ class HasOne < KDomain::Schemas::RailsStructure::NameOptsType; end
28
27
 
29
- class HasAndBelongsToMany < KDomain::Schemas::RailsStructure::BaseType
30
- end
28
+ class HasMany < KDomain::Schemas::RailsStructure::NameOptsType; end
29
+
30
+ class HasAndBelongsToMany < KDomain::Schemas::RailsStructure::NameOptsType; end
31
31
 
32
32
  class Validate < Dry::Struct
33
33
  attribute :names? , Types::Array.of(Types::Strict::String)
@@ -35,10 +35,10 @@ module KDomain
35
35
  attribute :block? , Types::Strict::String.optional.default(nil)
36
36
  end
37
37
 
38
- class Validates < KDomain::Schemas::RailsStructure::BaseType
38
+ class Validates < KDomain::Schemas::RailsStructure::NameOptsType
39
39
  end
40
40
 
41
- class Behaviours < Dry::Struct
41
+ class ModelBehaviours < Dry::Struct
42
42
  attribute :class_name? , Types::Strict::String
43
43
  attribute :default_scope? , KDomain::Schemas::RailsStructure::DefaultScope
44
44
  attribute :scopes? , Types::Strict::Array.of(KDomain::Schemas::RailsStructure::Scope)
@@ -76,15 +76,95 @@ module KDomain
76
76
  attribute :exist , Types::Strict::Bool
77
77
  attribute :state , Types::Strict::String
78
78
  attribute :code , Types::Strict::String
79
- attribute :behaviours? , KDomain::Schemas::RailsStructure::Behaviours
79
+ attribute :behaviours? , KDomain::Schemas::RailsStructure::ModelBehaviours
80
80
  attribute :functions? , KDomain::Schemas::RailsStructure::Functions
81
81
  end
82
82
 
83
+ # Controller Behaviours
84
+ class AfterAction < KDomain::Schemas::RailsStructure::NameOptsType; end
85
+
86
+ class AroundAction < KDomain::Schemas::RailsStructure::NameOptsType; end
87
+
88
+ class BeforeAction < KDomain::Schemas::RailsStructure::NameOptsType; end
89
+
90
+ # rubocop:disable Naming/ClassAndModuleCamelCase
91
+ class Prepend_beforeAction < KDomain::Schemas::RailsStructure::NameOptsType; end
92
+
93
+ class Skip_beforeAction < KDomain::Schemas::RailsStructure::NameOptsType; end
94
+ # rubocop:enable Naming/ClassAndModuleCamelCase
95
+
96
+ class BeforeFilter < KDomain::Schemas::RailsStructure::NameOptsType; end
97
+
98
+ class SkipBeforeFilter < KDomain::Schemas::RailsStructure::NameOptsType; end
99
+
100
+ class Layout < KDomain::Schemas::RailsStructure::NameOptsType; end
101
+
102
+ class HttpBasicAuthenticateWith < KDomain::Schemas::RailsStructure::OptsType; end
103
+
104
+ class ProtectFromForgery < KDomain::Schemas::RailsStructure::OptsType; end
105
+
106
+ class RescueFrom < Dry::Struct
107
+ attribute :type , Types::Strict::String
108
+ end
109
+
110
+ class HelperMethod < Dry::Struct
111
+ attribute :names , Types::Strict::Array.of(Types::Strict::String)
112
+ end
113
+
114
+ class Helper < Dry::Struct
115
+ attribute :name , Types::Strict::String
116
+ end
117
+
118
+ class ControllerBehaviours < Dry::Struct
119
+ attribute :class_name? , Types::Strict::String
120
+ attribute :after_action? , Types::Strict::Array.of(KDomain::Schemas::RailsStructure::AfterAction)
121
+ attribute :around_action? , Types::Strict::Array.of(KDomain::Schemas::RailsStructure::AroundAction)
122
+ attribute :before_action? , Types::Strict::Array.of(KDomain::Schemas::RailsStructure::BeforeAction)
123
+ attribute :prepend_before_action? , Types::Strict::Array.of(KDomain::Schemas::RailsStructure::Prepend_beforeAction)
124
+ attribute :skip_before_action? , Types::Strict::Array.of(KDomain::Schemas::RailsStructure::Skip_beforeAction)
125
+ attribute :before_filter? , Types::Strict::Array.of(KDomain::Schemas::RailsStructure::BeforeFilter)
126
+ attribute :skip_before_filter? , Types::Strict::Array.of(KDomain::Schemas::RailsStructure::SkipBeforeFilter)
127
+ attribute :layout? , KDomain::Schemas::RailsStructure::Layout
128
+ attribute :http_basic_authenticate_with? , KDomain::Schemas::RailsStructure::OptsType
129
+ attribute :protect_from_forgery? , KDomain::Schemas::RailsStructure::OptsType
130
+
131
+ attribute :rescue_from? , Types::Strict::Array.of(KDomain::Schemas::RailsStructure::RescueFrom)
132
+ attribute :helper_method? , Types::Strict::Array.of(KDomain::Schemas::RailsStructure::HelperMethod)
133
+ attribute :helper? , Types::Strict::Array.of(KDomain::Schemas::RailsStructure::Helper)
134
+ end
135
+
136
+ class ControllerActions < Dry::Struct
137
+ attribute :route_name? , Types::Strict::String
138
+ attribute :action? , Types::String.optional
139
+ attribute :uri_path? , Types::String
140
+ attribute :mime_match? , Types::String
141
+ attribute :verbs? , Types.Array(Types::Verb)
142
+ end
143
+
83
144
  class Controller < Dry::Struct
145
+ attribute :name , Types::String
146
+ attribute :path , Types::String
147
+ attribute :namespace , Types::String
148
+ attribute :file , Types::String
149
+ attribute :exist , Types::Bool
150
+ attribute :full_file , Types::String
151
+ attribute :behaviours? , KDomain::Schemas::RailsStructure::ControllerBehaviours
152
+ attribute :functions? , KDomain::Schemas::RailsStructure::Functions
153
+ attribute :actions? , Types::Strict::Array.of(KDomain::Schemas::RailsStructure::ControllerActions)
84
154
  end
85
155
 
86
156
  attribute :models , Types::Strict::Array.of(KDomain::Schemas::RailsStructure::Model)
87
157
  attribute :controllers , Types::Strict::Array.of(KDomain::Schemas::RailsStructure::Controller)
158
+
159
+ def find_controller(path)
160
+ path = path.to_s
161
+ controllers.find { |controller| controller.path.to_s == path }
162
+ end
163
+
164
+ def find_model(name)
165
+ name = name.to_s
166
+ models.find { |model| model.model_name.to_s == name }
167
+ end
88
168
  end
89
169
  end
90
170
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KDomain
4
- VERSION = '0.0.20'
4
+ VERSION = '0.0.23'
5
5
  end
data/lib/k_domain.rb CHANGED
@@ -11,8 +11,7 @@ require 'k_domain/raw_db_schema/load'
11
11
  require 'k_domain/domain_model/transform'
12
12
  require 'k_domain/domain_model/transform_steps/_'
13
13
  require 'k_domain/domain_model/load'
14
- require 'k_domain/rails_code_extractor/shim_loader'
15
- require 'k_domain/rails_code_extractor/extract_model'
14
+ require 'k_domain/rails_code_extractor/_'
16
15
 
17
16
  # # This is useful if you want to initialize structures via Hash
18
17
  # class SymbolizeStruct < Dry::Struct
@@ -0,0 +1,36 @@
1
+ module ActionController
2
+ class Base
3
+ def self.require(require)
4
+ add(:require, require)
5
+ end
6
+ # def self.rescue_from(type)#, &block)
7
+ # # block_source = nil
8
+ # # block_source = lambda_source(block, 'default_scope') if block_given?
9
+
10
+ # add(:rescue_from, {
11
+ # type: type#,
12
+ # # block: block_source
13
+ # })
14
+ # end
15
+ # def self.helper_method(*names)
16
+ # add(:helper_method, {
17
+ # names: names
18
+ # })
19
+ # end
20
+ # def self.helper(name)
21
+ # add(:helper, {
22
+ # name: name
23
+ # })
24
+ # end
25
+ # def self.http_basic_authenticate_with(**opts)
26
+ # add(:http_basic_authenticate_with, {
27
+ # opts: opts
28
+ # })
29
+ # end
30
+ # def self.protect_from_forgery(**opts)
31
+ # add(:protect_from_forgery, {
32
+ # opts: opts
33
+ # })
34
+ # end
35
+ end
36
+ end
@@ -0,0 +1,78 @@
1
+ class Rails
2
+ def self.env; end
3
+
4
+ def self.application
5
+ OpenStruct.new(
6
+ secrets: OpenStruct.new(
7
+ credentials_secret_key: Base64.encode64('ABC'),
8
+ aws_secret_access_key: Base64.encode64('ABC')
9
+ )
10
+ )
11
+ end
12
+ end
13
+ class RegionConfig
14
+ def self.require_value(*_p, **_o, &block); end
15
+ end
16
+
17
+ class ApplicationController < ActionController::Base
18
+ end
19
+
20
+ module Admin
21
+ class BaseController < ActionController::Base
22
+ end
23
+ end
24
+
25
+ module Api
26
+ module V1
27
+ class BaseController < ActionController::Base
28
+ end
29
+ end
30
+ end
31
+
32
+ module Enterprises
33
+ class BaseController < ActionController::Base
34
+ end
35
+ end
36
+
37
+ module Portal
38
+ class BaseController < ApplicationController
39
+ end
40
+ end
41
+
42
+ module ActiveRecord
43
+ class RecordNotFound
44
+ end
45
+ end
46
+
47
+ module Aws
48
+ class Credentials
49
+ def initialize(*_p, **_o, &block); end
50
+ end
51
+ module S3
52
+ class Client
53
+ def initialize(*_p, **_o, &block); end
54
+ end
55
+ end
56
+ end
57
+
58
+ module Devise
59
+ class SessionsController < ActionController::Base
60
+ end
61
+ class Mapping
62
+ def self.find_scope!(*_p, **_o); end
63
+ end
64
+ end
65
+
66
+ module Respondable; end
67
+ module ContactUpdateable; end
68
+ module SalesRepUpdateable; end
69
+ module MIME; end
70
+ module MaterialIconsHelper; end
71
+ module LocationUpdateable; end
72
+ module WantedByUpdateable; end
73
+ module FollowUpUpdateable; end
74
+ module EstimateArchiveUpdateable; end
75
+ module ContextContactUpdateable; end
76
+ module ProofDateUpdateable; end
77
+ module PoUpdateable; end
78
+ module SalesRepUpdateable; end
@@ -0,0 +1,71 @@
1
+ class Rails
2
+ def self.env; end
3
+
4
+ def self.application
5
+ OpenStruct.new(secrets: OpenStruct.new(credentials_secret_key: Base64.encode64('ABC')))
6
+ end
7
+ end
8
+
9
+ module ActsAsCommentable
10
+ module Comment
11
+ end
12
+ end
13
+
14
+ module Scopes
15
+ module CompanyScopes
16
+ end
17
+ end
18
+
19
+ class Thread
20
+ def initialize(*_p, **_o, &block); end
21
+ end
22
+
23
+ class ApplicationRecord < ActiveRecord::Base
24
+ end
25
+
26
+ class Email < ActiveRecord::Base
27
+ def self.ses_send(*_p, **_o); end
28
+ end
29
+
30
+ module Emails
31
+ class Task
32
+ def new_task(*_p, **_o); end
33
+ end
34
+ class Salesrep
35
+ def change_sales_rep(*_p, **_o); end
36
+ end
37
+ end
38
+
39
+ module EstimateConvertable; end
40
+ module ApiLoggable; end
41
+ module Excludable; end
42
+ module Bookmarkable; end
43
+ module Categorizable; end
44
+ module PgSearch; end
45
+ module Excludable; end
46
+ module JsonbStore; end
47
+
48
+ module ActionView
49
+ module Helpers
50
+ module NumberHelper
51
+ end
52
+ end
53
+ end
54
+
55
+ module RailsUpgrade
56
+ def rails4?
57
+ true
58
+ end
59
+
60
+ def rails5?
61
+ true
62
+ end
63
+
64
+ def rails6?
65
+ true
66
+ end
67
+
68
+ def belongs_to_required
69
+ {}
70
+ end
71
+ end
@@ -1,6 +1,7 @@
1
1
  class LoadSchema
2
2
  attr_reader :schema
3
3
 
4
+ # XMEN
4
5
  def initialize
5
6
  @unique_keys = {}
6
7
  @current_table = nil
@@ -9,6 +10,7 @@ class LoadSchema
9
10
  tables: [],
10
11
  foreign_keys: [],
11
12
  indexes: [],
13
+ views: [],
12
14
  meta: {
13
15
  rails: @rails_version,
14
16
  db_info: {
@@ -131,6 +133,11 @@ class LoadSchema
131
133
  add_index(name, fields, **opts)
132
134
  end
133
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
134
141
 
135
142
  def add_foreign_key(left_table, right_table, **opts)
136
143
  # puts "add_foreign_key(#{left_table}, #{right_table})"
@@ -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