elasticsearch_record 1.0.2 → 1.1.0

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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +4 -0
  3. data/Gemfile.lock +10 -14
  4. data/README.md +180 -27
  5. data/docs/CHANGELOG.md +36 -18
  6. data/docs/LICENSE.txt +1 -1
  7. data/elasticsearch_record.gemspec +42 -0
  8. data/lib/active_record/connection_adapters/elasticsearch/column.rb +20 -6
  9. data/lib/active_record/connection_adapters/elasticsearch/database_statements.rb +142 -125
  10. data/lib/active_record/connection_adapters/elasticsearch/quoting.rb +2 -23
  11. data/lib/active_record/connection_adapters/elasticsearch/schema_creation.rb +30 -0
  12. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/attribute_methods.rb +103 -0
  13. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/column_methods.rb +42 -0
  14. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/create_table_definition.rb +158 -0
  15. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_alias_definition.rb +32 -0
  16. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_definition.rb +132 -0
  17. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_mapping_definition.rb +110 -0
  18. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_setting_definition.rb +136 -0
  19. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/update_table_definition.rb +174 -0
  20. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions.rb +37 -0
  21. data/lib/active_record/connection_adapters/elasticsearch/schema_dumper.rb +110 -0
  22. data/lib/active_record/connection_adapters/elasticsearch/schema_statements.rb +398 -174
  23. data/lib/active_record/connection_adapters/elasticsearch/table_statements.rb +232 -0
  24. data/lib/active_record/connection_adapters/elasticsearch/type/multicast_value.rb +2 -0
  25. data/lib/active_record/connection_adapters/elasticsearch/unsupported_implementation.rb +32 -0
  26. data/lib/active_record/connection_adapters/elasticsearch_adapter.rb +112 -19
  27. data/lib/arel/collectors/elasticsearch_query.rb +0 -1
  28. data/lib/arel/visitors/elasticsearch.rb +7 -579
  29. data/lib/arel/visitors/elasticsearch_base.rb +234 -0
  30. data/lib/arel/visitors/elasticsearch_query.rb +463 -0
  31. data/lib/arel/visitors/elasticsearch_schema.rb +124 -0
  32. data/lib/elasticsearch_record/core.rb +44 -10
  33. data/lib/elasticsearch_record/errors.rb +13 -0
  34. data/lib/elasticsearch_record/gem_version.rb +6 -2
  35. data/lib/elasticsearch_record/instrumentation/log_subscriber.rb +27 -9
  36. data/lib/elasticsearch_record/model_schema.rb +5 -0
  37. data/lib/elasticsearch_record/persistence.rb +31 -26
  38. data/lib/elasticsearch_record/query.rb +56 -17
  39. data/lib/elasticsearch_record/querying.rb +17 -0
  40. data/lib/elasticsearch_record/relation/calculation_methods.rb +3 -0
  41. data/lib/elasticsearch_record/relation/core_methods.rb +57 -17
  42. data/lib/elasticsearch_record/relation/query_clause_tree.rb +38 -1
  43. data/lib/elasticsearch_record/relation/query_methods.rb +6 -0
  44. data/lib/elasticsearch_record/relation/result_methods.rb +15 -9
  45. data/lib/elasticsearch_record/result.rb +32 -5
  46. data/lib/elasticsearch_record/statement_cache.rb +2 -1
  47. data/lib/elasticsearch_record.rb +2 -2
  48. metadata +29 -11
  49. data/.ruby-version +0 -1
  50. data/lib/elasticsearch_record/schema_migration.rb +0 -30
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_model/validations'
4
+
5
+ module ActiveRecord
6
+ module ConnectionAdapters
7
+ module Elasticsearch
8
+ class TableAliasDefinition
9
+ include AttributeMethods
10
+ include ActiveModel::Validations
11
+
12
+ # available alias properties
13
+ # - see @ https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-create-index.html#indices-create-api-request-body
14
+ ATTRIBUTES = [:filter, :index_routing, :is_hidden, :is_write_index, :routing, :search_routing].freeze
15
+ build_attribute_methods! *ATTRIBUTES
16
+
17
+ # attributes
18
+ attr_accessor :name
19
+ attr_accessor :attributes
20
+
21
+ # validations
22
+ validates_presence_of :name
23
+ validates_inclusion_of :__attributes_keys, in: ATTRIBUTES, allow_blank: true
24
+
25
+ def initialize(name, attributes)
26
+ self.name = name.to_sym
27
+ self.attributes = attributes.symbolize_keys
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ # required to load related definitions
4
+ # - ActiveRecord::ConnectionAdapters::ReferenceDefinition
5
+ require 'active_record/connection_adapters/abstract/schema_definitions'
6
+
7
+ module ActiveRecord
8
+ module ConnectionAdapters
9
+ module Elasticsearch
10
+ class TableDefinition
11
+ include ColumnMethods
12
+
13
+ delegate :execute, :schema_creation, :column_exists?, :mapping_exists?, :setting_exists?, :alias_exists?, :close_table, :open_table, :table_mappings, to: :conn
14
+
15
+ attr_reader :conn
16
+ attr_reader :name
17
+ attr_reader :opts
18
+
19
+ def initialize(conn, name, **opts)
20
+ @conn = conn
21
+ @name = name
22
+ @opts = opts
23
+ @failed = false
24
+ end
25
+
26
+ # yields provided block with self to change the table and collect table information
27
+ # returns self, to chain this method
28
+ def assign
29
+ # if before assign fails, we don't want to continue yielding!
30
+ _before_assign
31
+
32
+ begin
33
+ yield self
34
+ rescue => e
35
+ @failed = false
36
+ raise e
37
+ ensure
38
+ _after_assign
39
+ end
40
+ end
41
+
42
+ def exec!
43
+ # if before exec fails, we don't want to continue with execution!
44
+ _before_exec
45
+
46
+ begin
47
+ _exec
48
+ rescue => e
49
+ @failed = false
50
+ raise e
51
+ ensure
52
+ _after_exec
53
+ end
54
+ end
55
+
56
+ def failed?
57
+ @failed
58
+ end
59
+
60
+ private
61
+
62
+ def _before_assign
63
+ true
64
+ end
65
+
66
+ def _after_assign
67
+ true
68
+ end
69
+
70
+ def _before_exec
71
+ true
72
+ end
73
+
74
+ def _after_exec
75
+ true
76
+ end
77
+
78
+ def _exec
79
+ raise ArgumentError, "you cannot execute a TableDefinition directly - use 'CreateTableDefinition' or 'UpdateTableDefinition' instead!"
80
+ end
81
+
82
+ def new_mapping_definition(name, type, strict: true, **attributes, &block)
83
+ mapping = TableMappingDefinition.new(name, type, attributes)
84
+ block.call(mapping) if block_given?
85
+
86
+ raise ArgumentError, "you cannot define an invalid mapping '#{name}' (#{mapping.error_messages})!" if strict?(strict) && !mapping.valid?
87
+
88
+ mapping
89
+ end
90
+
91
+ alias :new_column_definition :new_mapping_definition
92
+
93
+ def new_alias_definition(name, strict: true, **attributes, &block)
94
+ # create new alias
95
+ tbl_alias = TableAliasDefinition.new(name, attributes)
96
+ block.call(tbl_alias) if block_given?
97
+
98
+ raise ArgumentError, "you cannot define an invalid alias '#{tbl_alias}' (#{tbl_alias.error_messages})!" if strict?(strict) && !tbl_alias.valid?
99
+
100
+ tbl_alias
101
+ end
102
+
103
+ def new_setting_definition(name, value, strict: true, **, &block)
104
+ # create new setting
105
+ setting = TableSettingDefinition.new(name, value).with_state(state)
106
+ block.call(setting) if block_given?
107
+
108
+ raise ArgumentError, "you cannot define an invalid setting '#{name}' (#{setting.error_messages})!" if strict?(strict) && !setting.valid?
109
+
110
+ setting
111
+ end
112
+
113
+ # returns the state of the current table.
114
+ def state
115
+ @state ||= conn.table_state(name) rescue { status: 'missing', name: name }
116
+ end
117
+
118
+ def clear_state!
119
+ @state = nil
120
+ end
121
+
122
+ def force?(fallback = false)
123
+ opts.fetch(:force, fallback)
124
+ end
125
+
126
+ def strict?(strict = nil)
127
+ opts.fetch(:strict, true) && strict != false
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_model/validations'
4
+
5
+ module ActiveRecord
6
+ module ConnectionAdapters
7
+ module Elasticsearch
8
+ class TableMappingDefinition
9
+ include AttributeMethods
10
+ include ActiveModel::Validations
11
+
12
+ # available mapping properties
13
+ # - see @ https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-params.html
14
+ ATTRIBUTES = [:analyzer, :coerce, :copy_to, :doc_values, :dynamic, :eager_global_ordinals, :enabled,
15
+ :fielddata, :fields, :format, :ignore_above, :ignore_malformed, :index_options, :index_phrases,
16
+ :index_prefixes, :index, :meta, :normalizer, :norms, :null_value, :position_increment_gap,
17
+ :properties, :search_analyzer, :similarity, :subobjects, :store, :term_vector].freeze
18
+
19
+ build_attribute_methods! *ATTRIBUTES
20
+
21
+ # attributes
22
+ attr_accessor :name
23
+ attr_accessor :type
24
+ attr_accessor :attributes
25
+
26
+ # validations
27
+ validates_presence_of :name
28
+ validates_presence_of :type
29
+ validates_inclusion_of :__attributes_keys, in: ATTRIBUTES, allow_blank: true
30
+
31
+ # disable validation for meta attribute - maybe future updates of Elasticsearch have other restrictions.
32
+ # To not be hooked on those possible changes we
33
+ #validate :_validate_meta
34
+
35
+ # sets the default value (alias for null_value)
36
+ alias_method :default=, :null_value=
37
+ alias_method :default, :null_value
38
+
39
+ ####################
40
+ # INSTANCE METHODS #
41
+ ####################
42
+
43
+ def initialize(name, type, attributes)
44
+ @name = name.to_sym
45
+ @attributes = attributes.symbolize_keys
46
+
47
+ @type = _resolve_type(type)
48
+ end
49
+
50
+ # comment is handled as nested key from 'meta' attribute
51
+ def comment
52
+ __get_nested(:meta, :comment)
53
+ end
54
+
55
+ def comment=(value)
56
+ # important: meta-values can only be strings!
57
+ __set_nested(:meta, :comment, value.to_s)
58
+ end
59
+
60
+ def primary_key
61
+ __get_nested(:meta, :primary_key) == 'true'
62
+ end
63
+
64
+ alias_method :primary_key?, :primary_key
65
+
66
+ # defines this mapping as a primary key
67
+ def primary_key=(value)
68
+ # important: meta-values can only be strings!
69
+ __set_nested(:meta, :primary_key, value ? 'true' : nil)
70
+ end
71
+
72
+ def meta=(value)
73
+ if value.nil?
74
+ __remove_attribute(:meta)
75
+ else
76
+ __set_attribute(:meta, value.compact)
77
+ end
78
+ end
79
+
80
+ private
81
+
82
+ # resolves the provided type.
83
+ # prevents to set a nil type (sets +:object+ or +:nested+ - depends on existing properties)
84
+ # @return [Symbol, nil]
85
+ def _resolve_type(type)
86
+ return type.to_sym if type.present?
87
+
88
+ # fallback for possible empty type
89
+ (properties.present? ? :object : :nested)
90
+ end
91
+
92
+ # validates metadata restrictions
93
+ def _validate_meta
94
+ return true if meta.nil?
95
+
96
+ return invalid!("'meta' must be a hash", :attributes) unless meta.is_a?(Hash)
97
+ return invalid!("'meta' enforces at most 5 entries", :attributes) if meta.length > 5
98
+ return invalid!("'meta' has a key with more then 20 chars", :attributes) if meta.keys.any? { |key| key.length > 20 }
99
+ return invalid!("'meta' is not supported on object or nested types", :attributes) if [:object, :nested].include?(type)
100
+
101
+ # allow only strings
102
+ vkey = meta.keys.detect { |key| !meta[key].is_a?(String) }
103
+ return invalid!("'meta' has a key '#{vkey}' with a none string value", :attributes) if vkey.present?
104
+
105
+ true
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,136 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_model/validations'
4
+
5
+ module ActiveRecord
6
+ module ConnectionAdapters
7
+ module Elasticsearch
8
+ class TableSettingDefinition
9
+ include AttributeMethods
10
+ include ActiveModel::Validations
11
+
12
+ # exclude settings, that are provided through the API but are not part of the index-settings API
13
+ IGNORE_NAMES = ['provided_name', 'creation_date', 'uuid', 'version'].freeze
14
+
15
+ # available setting names
16
+ # - see @ https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html#index-modules-settings
17
+
18
+ # final names can only be set during index creation
19
+ FINAL_NAMES = ['number_of_shards', 'routing_partition_size', 'soft_deletes.enabled'].freeze
20
+
21
+ # static names can only be set during index creation or closed
22
+ STATIC_NAMES = ['number_of_routing_shards', 'codec',
23
+ 'soft_deletes.retention_lease.period',
24
+ 'load_fixed_bitset_filters_eagerly', 'shard.check_on_startup',
25
+
26
+ # modules
27
+ 'analysis', 'routing', 'unassigned', 'merge', 'similarity', 'search', 'store', 'translog',
28
+ 'indexing_pressure'].freeze
29
+
30
+ # dynamic names can always be changed
31
+ DYNAMIC_NAMES = ['number_of_replicas', 'auto_expand_replicas', "search.idle.after", 'refresh_interval',
32
+ 'max_result_window', 'max_inner_result_window', 'max_rescore_window',
33
+ 'max_docvalue_fields_search', 'max_script_fields', 'max_ngram_diff', 'max_shingle_diff',
34
+ 'max_refresh_listeners', 'analyze.max_token_count', 'highlight.max_analyzed_offset',
35
+ 'max_terms_count', 'max_regex_length', 'query.default_field', 'routing.allocation.enable',
36
+ 'routing.rebalance.enable', 'gc_deletes', 'default_pipeline', 'final_pipeline', 'hidden'].freeze
37
+
38
+ VALID_NAMES = (FINAL_NAMES + STATIC_NAMES + DYNAMIC_NAMES).freeze
39
+
40
+ # attributes
41
+ attr_accessor :name
42
+ attr_accessor :value
43
+
44
+ # validations
45
+ validates_presence_of :name
46
+ validate :_validate_name
47
+ validate :_validate_final_name
48
+ validate :_validate_static_name
49
+
50
+ def self.match_ignore_names?(name)
51
+ IGNORE_NAMES.any? { |invalid| name.match?(invalid) }
52
+ end
53
+
54
+ def self.match_valid_names?(name)
55
+ VALID_NAMES.any? { |invalid| name.match?(invalid) }
56
+ end
57
+
58
+ def self.match_final_names?(name)
59
+ FINAL_NAMES.any? { |invalid| name.match?(invalid) }
60
+ end
61
+
62
+ def self.match_dynamic_names?(name)
63
+ DYNAMIC_NAMES.any? { |invalid| name.match?(invalid) }
64
+ end
65
+
66
+ def self.match_static_names?(name)
67
+ STATIC_NAMES.any? { |invalid| name.match?(invalid) }
68
+ end
69
+
70
+ def initialize(name, value)
71
+ @name = name.to_s
72
+ @value = value
73
+ end
74
+
75
+ def final?
76
+ @final = flat_names.all? { |flat_name| self.class.match_final_names?(flat_name) } if @final.nil?
77
+ @final
78
+ end
79
+
80
+ def static?
81
+ !dynamic?
82
+ end
83
+
84
+ def dynamic?
85
+ @dynamic = flat_names.all? { |flat_name| self.class.match_dynamic_names?(flat_name) } if @dynamic.nil?
86
+ @dynamic
87
+ end
88
+
89
+ # returns a array of flat names
90
+ def flat_names
91
+ @flat_names ||= _generate_flat_names.uniq
92
+ end
93
+
94
+ private
95
+
96
+ def _validate_name
97
+ invalid_name = flat_names.detect { |flat_name| !self.class.match_valid_names?(flat_name) }
98
+
99
+ invalid!("is invalid!", :name) if invalid_name.present?
100
+ end
101
+
102
+ def _validate_static_name
103
+ return true if dynamic?
104
+ return true if ['missing', 'close'].include?(_table_status)
105
+
106
+ invalid!("is static - this setting can only be changed on a closed index!", :name)
107
+ end
108
+
109
+ def _validate_final_name
110
+ return true unless final?
111
+ return true if _table_status == 'missing'
112
+
113
+ invalid!("is final - this setting can only be set at index creation time!", :name)
114
+ end
115
+
116
+ def _generate_flat_names(parent = name, current = value)
117
+ ret = []
118
+ if current.is_a?(Hash)
119
+ current.each do |k, v|
120
+ ret += _generate_flat_names("#{parent}.#{k}", v)
121
+ end
122
+ else
123
+ ret << parent.to_s
124
+ end
125
+
126
+ ret
127
+ end
128
+
129
+ def _table_status
130
+ return 'missing' unless state?
131
+ state[:status]
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,174 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_record/connection_adapters/abstract/schema_definitions'
4
+ require 'active_record/connection_adapters/elasticsearch/schema_definitions/table_definition'
5
+
6
+ module ActiveRecord
7
+ module ConnectionAdapters
8
+ module Elasticsearch
9
+ class UpdateTableDefinition < TableDefinition
10
+
11
+ attr_reader :definitions
12
+
13
+ # defines which definitions can be executed composite
14
+ COMPOSITE_DEFINITIONS = [
15
+ AddMappingDefinition,
16
+ ChangeMappingDefinition,
17
+
18
+ AddSettingDefinition,
19
+ DeleteAliasDefinition
20
+ ].freeze
21
+
22
+ def add_mapping(name, type, if_not_exists: false, **options, &block)
23
+ return if if_not_exists && mapping_exists?(self.name, name, type)
24
+
25
+ define! AddMappingDefinition, new_mapping_definition(name, type, **options, &block)
26
+ end
27
+
28
+ alias :add_column :add_mapping
29
+ alias :mapping :add_mapping
30
+ alias :column :add_mapping
31
+
32
+ def change_mapping(name, type, if_exists: false, **options, &block)
33
+ return if if_exists && !mapping_exists?(self.name, name, type)
34
+
35
+ define! ChangeMappingDefinition, new_mapping_definition(name, type, **options, &block)
36
+ end
37
+
38
+ alias :change_column :change_mapping
39
+ alias :change :change_mapping
40
+
41
+ def change_mapping_meta(name, **options)
42
+ mapping = table_mappings(self.name).dig('properties', name.to_s)
43
+ raise ArgumentError, "you cannot change the 'meta' parameter for an unknown mapping '#{name}'" if mapping.blank?
44
+
45
+ # resolve existing meta & merge with new
46
+ meta = (mapping['meta'] || {}).merge(options)
47
+
48
+ define! ChangeMappingDefinition, new_mapping_definition(name, mapping['type'], meta: meta)
49
+ end
50
+
51
+ def change_mapping_attributes(name, **options, &block)
52
+ mapping = table_mappings(self.name).dig('properties', name.to_s)
53
+ raise ArgumentError, "you cannot change parameters for an unknown mapping '#{name}'" if mapping.blank?
54
+
55
+ options = mapping.with_indifferent_access.except(:type).merge(options) if options.present?
56
+
57
+ define! ChangeMappingDefinition, new_mapping_definition(name, mapping['type'], **options, &block)
58
+ end
59
+ alias :change_mapping_attribute :change_mapping_attributes
60
+
61
+ def add_setting(name, value, if_not_exists: false, **options, &block)
62
+ return if if_not_exists && setting_exists?(self.name, name)
63
+
64
+ define! AddSettingDefinition, new_setting_definition(name, value, **options, &block)
65
+ end
66
+
67
+ def change_setting(name, value, if_exists: false, **options, &block)
68
+ return if if_exists && !setting_exists?(self.name, name)
69
+
70
+ define! ChangeSettingDefinition, new_setting_definition(name, value, **options, &block)
71
+ end
72
+
73
+ def delete_setting(name, if_exists: false, **options, &block)
74
+ return if if_exists && !setting_exists?(self.name, name)
75
+
76
+ define! DeleteSettingDefinition, new_setting_definition(name, nil, **options, &block)
77
+ end
78
+
79
+ def add_alias(name, if_not_exists: false, **options, &block)
80
+ return if if_not_exists && alias_exists?(self.name, name)
81
+
82
+ define! AddAliasDefinition, new_alias_definition(name, **options, &block)
83
+ end
84
+
85
+ def change_alias(name, if_exists: false, **options, &block)
86
+ return if if_exists && !alias_exists?(self.name, name)
87
+
88
+ define! ChangeAliasDefinition, new_alias_definition(name, **options, &block)
89
+ end
90
+
91
+ def delete_alias(name, if_exists: false, **, &block)
92
+ return if if_exists && !alias_exists?(self.name, name)
93
+
94
+ define! DeleteAliasDefinition, new_alias_definition(name, &block)
95
+ end
96
+
97
+ # Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and
98
+ # <tt>:updated_at</tt> to the table. See {connection.add_timestamps}[rdoc-ref:SchemaStatements#add_timestamps]
99
+ #
100
+ # t.timestamps
101
+ def timestamps(**options)
102
+ add_mapping(:created_at, :datetime, if_not_exists: true, **options)
103
+ add_mapping(:updated_at, :datetime, if_not_exists: true, **options)
104
+ end
105
+
106
+ private
107
+
108
+ def define!(klass, item)
109
+ @definitions ||= {}
110
+ @definitions[klass] ||= []
111
+ @definitions[klass] << item
112
+ end
113
+
114
+ def _before_assign
115
+ # check, if the table should be closed before executing the queries
116
+ close_table(self.name) if _toggle_table_status?
117
+
118
+ # reset table state
119
+ clear_state!
120
+ end
121
+
122
+ def _after_assign
123
+ # run the same content as +_after_exec+, but only if the assignment failed
124
+ _after_exec if failed?
125
+ end
126
+
127
+ def _after_exec
128
+ # reopen the table again
129
+ open_table(self.name) if _toggle_table_status?
130
+
131
+ # reset table state
132
+ clear_state!
133
+ end
134
+
135
+ def _toggle_table_status?
136
+ @toggle_table_status = (force? && state[:status] == 'open') if @toggle_table_status.nil?
137
+
138
+ @toggle_table_status
139
+ end
140
+
141
+ def _exec
142
+ return unless definitions.any?
143
+
144
+ # check, if the table should be closed before executing the queries
145
+ close_table(self.name) if opts[:close] == true
146
+
147
+ definitions.each do |klass, items|
148
+ # check if the provided definition klass is a composite definition
149
+ executable_definitions = if COMPOSITE_DEFINITIONS.include?(klass)
150
+ [InterlacedUpdateTableDefinition.new(name, klass.new(items))]
151
+ else
152
+ items.map { |d|
153
+ InterlacedUpdateTableDefinition.new(name, klass.new(d))
154
+ }
155
+ end
156
+
157
+ executable_definitions.each do |ed|
158
+ execute(schema_creation.accept(ed), _to_composite_log(klass))
159
+ end
160
+ end
161
+
162
+ open_table(self.name) if opts[:close] == true
163
+
164
+ # cleanup definitions
165
+ @definitions = {}
166
+ end
167
+
168
+ def _to_composite_log(klass)
169
+ klass.name.demodulize.underscore.gsub(/_definition/, '').gsub(/_/, ' ').upcase
170
+ end
171
+ end
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module Elasticsearch
6
+ # interlaced / nested definition to handle multiple grouped definitions
7
+ InterlacedUpdateTableDefinition = Struct.new(:name, :definition)
8
+
9
+ # mapping definitions
10
+ AddMappingDefinition = Struct.new(:items) # composite
11
+ ChangeMappingDefinition = Struct.new(:items) # composite
12
+
13
+ # setting definitions
14
+ AddSettingDefinition = Struct.new(:items) # composite
15
+ ChangeSettingDefinition = Struct.new(:items) # composite
16
+ DeleteSettingDefinition = Struct.new(:items) # composite
17
+
18
+ # alias definitions
19
+ AddAliasDefinition = Struct.new(:item) # single
20
+ ChangeAliasDefinition = Struct.new(:item) # single
21
+ DeleteAliasDefinition = Struct.new(:items) # composite
22
+ end
23
+ end
24
+ end
25
+
26
+ # WARNING: the loading order is mandatory and must not be changed
27
+ # ALSO: the requirements have to be below the upper definitions
28
+ require 'active_record/connection_adapters/elasticsearch/schema_definitions/attribute_methods'
29
+ require 'active_record/connection_adapters/elasticsearch/schema_definitions/column_methods'
30
+
31
+ require 'active_record/connection_adapters/elasticsearch/schema_definitions/table_alias_definition'
32
+ require 'active_record/connection_adapters/elasticsearch/schema_definitions/table_mapping_definition'
33
+ require 'active_record/connection_adapters/elasticsearch/schema_definitions/table_setting_definition'
34
+
35
+ require 'active_record/connection_adapters/elasticsearch/schema_definitions/table_definition'
36
+ require 'active_record/connection_adapters/elasticsearch/schema_definitions/create_table_definition'
37
+ require 'active_record/connection_adapters/elasticsearch/schema_definitions/update_table_definition'