elasticsearch_record 1.1.0 → 1.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +3 -1
  3. data/Gemfile.lock +5 -2
  4. data/README.md +29 -9
  5. data/docs/CHANGELOG.md +40 -1
  6. data/elasticsearch_record.gemspec +1 -0
  7. data/lib/active_record/connection_adapters/elasticsearch/column.rb +9 -2
  8. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/clone_table_definition.rb +88 -0
  9. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/column_methods.rb +1 -1
  10. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/create_table_definition.rb +29 -27
  11. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_definition.rb +67 -12
  12. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_mapping_definition.rb +48 -13
  13. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_meta_definition.rb +24 -0
  14. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_setting_definition.rb +9 -4
  15. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/update_table_definition.rb +38 -13
  16. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions.rb +3 -0
  17. data/lib/active_record/connection_adapters/elasticsearch/schema_dumper.rb +41 -0
  18. data/lib/active_record/connection_adapters/elasticsearch/schema_statements.rb +59 -11
  19. data/lib/active_record/connection_adapters/elasticsearch/table_statements.rb +88 -9
  20. data/lib/active_record/connection_adapters/elasticsearch_adapter.rb +17 -2
  21. data/lib/arel/collectors/elasticsearch_query.rb +3 -0
  22. data/lib/arel/visitors/elasticsearch_query.rb +19 -0
  23. data/lib/arel/visitors/elasticsearch_schema.rb +48 -7
  24. data/lib/elasticsearch_record/core.rb +24 -8
  25. data/lib/elasticsearch_record/gem_version.rb +2 -2
  26. data/lib/elasticsearch_record/model_schema.rb +26 -2
  27. data/lib/elasticsearch_record/persistence.rb +45 -34
  28. data/lib/elasticsearch_record/query.rb +4 -1
  29. data/lib/elasticsearch_record/relation/core_methods.rb +22 -0
  30. data/lib/elasticsearch_record/relation/query_methods.rb +31 -16
  31. data/lib/elasticsearch_record/relation/result_methods.rb +2 -0
  32. data/lib/elasticsearch_record/result.rb +28 -15
  33. data/lib/elasticsearch_record/schema_migration.rb +49 -0
  34. data/lib/elasticsearch_record/tasks/elasticsearch_database_tasks.rb +15 -5
  35. data/lib/elasticsearch_record.rb +1 -0
  36. metadata +20 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6cf2af35e8ed5eb94892c5e1c6c5a7b11fab36539a48a3106b3444862c3654fc
4
- data.tar.gz: 63f47637943c1e65e8d2a53c9f887b57ca5bdb139c4b6575997abbd640f2586d
3
+ metadata.gz: 41575ee0aefe81ed3069dc81c1c0d9062ea841998a7bb4affaab885dad0a4291
4
+ data.tar.gz: 73e98d4b6aad0fda63df0fff562537245f2d4c95fb5f53d67ad891550d8e6b1b
5
5
  SHA512:
6
- metadata.gz: 96f3ce41b50dc97f5e4d9cdf79bf5b58af5bedcf219edee5d5d22a88b6517efcad0f3d7a0e26ca0042493d83a59d274a3f33d80ec4e16032c7ec50dfcb6790b2
7
- data.tar.gz: c041e7d0bc2e00dd006d1c5b87e403b03f2e9c98a55672f636b29821a318425dc72aabff46e439a4c1281c914f1a07ac86487961f06930fac4169d538a2b9888
6
+ metadata.gz: ed60e5fe591f92169d51f333c600338cd4fcee46ca6ca988625399ee522068e3b5c67738fe5b9f3fcc1cede6491cfb1b969c525d5b1af2f2ed03e93b7303237f
7
+ data.tar.gz: eb51b9dc16d0457905fb15589ff2542dfe0a8f59678459be910726305a3b0527e3ddcee6d7e5271e2db0d658dabd5f476eea71b4dca27c1f99375d987de50f0b
data/.yardopts CHANGED
@@ -1,4 +1,6 @@
1
1
  --embed-mixins
2
2
  --markup=markdown
3
3
  --files docs/*.*
4
- --plugin relative_markdown_links
4
+ --plugin relative_markdown_links
5
+ --plugin activesupport-concern
6
+ --exclude lib/elasticsearch_record/patches
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- elasticsearch_record (1.1.0)
4
+ elasticsearch_record (1.2.4)
5
5
  activerecord (~> 7.0.0)
6
6
  elasticsearch (~> 8.4)
7
7
 
@@ -28,7 +28,7 @@ GEM
28
28
  elasticsearch-api (= 8.5.2)
29
29
  elasticsearch-api (8.5.2)
30
30
  multi_json
31
- faraday (2.7.1)
31
+ faraday (2.7.2)
32
32
  faraday-net_http (>= 2.0, < 3.1)
33
33
  ruby2_keywords (>= 0.0.4)
34
34
  faraday-net_http (3.0.2)
@@ -56,6 +56,8 @@ GEM
56
56
  webrick (1.7.0)
57
57
  yard (0.9.28)
58
58
  webrick (~> 1.7.0)
59
+ yard-activesupport-concern (0.0.1)
60
+ yard (>= 0.8)
59
61
 
60
62
  PLATFORMS
61
63
  x86_64-linux
@@ -65,6 +67,7 @@ DEPENDENCIES
65
67
  rake (~> 13.0)
66
68
  rspec (~> 3.0)
67
69
  yard (~> 0.9)
70
+ yard-activesupport-concern (~> 0.0.1)
68
71
 
69
72
  BUNDLED WITH
70
73
  2.3.18
data/README.md CHANGED
@@ -136,7 +136,7 @@ scope.where(kind: :undefined).offset(10).update_all(name: "New Name")
136
136
  ### Refactored ```where``` method:
137
137
  Different to the default where-method you can now use it in different ways.
138
138
 
139
- Using it by default with a Hash, the method decides itself to either add a filter, or must_not query.
139
+ Using it by default with a Hash, the method decides itself to either add a filter, or must_not clause.
140
140
 
141
141
  _Hint: If not provided through ```#kind```-method a default kind **:bool** will be used._
142
142
  ```ruby
@@ -209,6 +209,8 @@ total = scope.total
209
209
  - aggs_only!
210
210
  - total_only!
211
211
 
212
+ _see simple documentation about these methods @ [rubydoc](https://rubydoc.info/gems/elasticsearch_record/ElasticsearchRecord/Relation/QueryMethods)_
213
+
212
214
  ### Available calculation methods
213
215
  - percentiles
214
216
  - percentile_ranks
@@ -219,6 +221,8 @@ total = scope.total
219
221
  - sum
220
222
  - calculate
221
223
 
224
+ _see simple documentation about these methods @ [rubydoc](https://rubydoc.info/gems/elasticsearch_record/ElasticsearchRecord/Relation/CalculationMethods)_
225
+
222
226
  ### Available result methods
223
227
  - aggregations
224
228
  - buckets
@@ -231,6 +235,8 @@ total = scope.total
231
235
  - point_in_time
232
236
  - pit_results
233
237
 
238
+ _see simple documentation about these methods @ [rubydoc](https://rubydoc.info/gems/elasticsearch_record/ElasticsearchRecord/Relation/ResultMethods)_
239
+
234
240
  ### Additional methods
235
241
  - to_query
236
242
 
@@ -240,20 +246,24 @@ total = scope.total
240
246
  - index_base_name
241
247
  - relay_id_attribute
242
248
 
243
- ### Useful model instance methods
249
+ ### Useful model class methods
250
+ - auto_increment?
251
+ - max_result_window
244
252
  - source_column_names
245
253
  - searchable_column_names
246
254
  - find_by_query
247
255
  - msearch
248
256
 
249
- ## ActiveRecord ConnectionAdapters schema-methods
257
+ ## ActiveRecord ConnectionAdapters table-methods
250
258
  Access these methods through the model's connection.
259
+
251
260
  ```ruby
252
261
  # returns mapping of provided table (index)
253
262
  model.connection.table_mappings('table-name')
254
263
  ```
255
264
 
256
265
  - table_mappings
266
+ - table_metas
257
267
  - table_settings
258
268
  - table_aliases
259
269
  - table_state
@@ -261,12 +271,14 @@ Access these methods through the model's connection.
261
271
  - alias_exists?
262
272
  - setting_exists?
263
273
  - mapping_exists?
274
+ - meta_exists?
264
275
  - max_result_window
265
276
  - cluster_info
266
277
 
267
278
  ## Active Record Schema migration methods
268
279
  Access these methods through the model's connection or within any `Migration`.
269
280
 
281
+ **cluster actions:**
270
282
  - open_table
271
283
  - open_tables
272
284
  - close_table
@@ -274,8 +286,15 @@ Access these methods through the model's connection or within any `Migration`.
274
286
  - truncate_table
275
287
  - truncate_tables
276
288
  - drop_table
289
+ - block_table
290
+ - unblock_table
291
+ - clone_table
277
292
  - create_table
278
293
  - change_table
294
+
295
+ **table actions:**
296
+ - change_meta
297
+ - delete_meta
279
298
  - add_mapping
280
299
  - change_mapping
281
300
  - change_mapping_meta
@@ -299,11 +318,15 @@ class AddTests < ActiveRecord::Migration[7.0]
299
318
  t.setting :number_of_shards, "1"
300
319
  t.setting :number_of_replicas, 0
301
320
  end
321
+
322
+ # changes the auto-increment value
323
+ change_meta "assignments", :auto_increment, 3625
302
324
 
303
325
  create_table "settings", force: true do |t|
304
326
  t.mapping :created_at, :date
305
- t.mapping :key, :keyword do |m|
327
+ t.mapping :key, :integer do |m|
306
328
  m.primary_key = true
329
+ m.auto_increment = 10
307
330
  end
308
331
  t.mapping :status, :keyword
309
332
  t.mapping :updated_at, :date
@@ -315,11 +338,11 @@ class AddTests < ActiveRecord::Migration[7.0]
315
338
  end
316
339
 
317
340
  add_mapping "settings", :active, :boolean do |m|
318
- m.comment = "Hans"
341
+ m.comment = "Contains the active state"
319
342
  end
320
343
 
321
344
  change_table 'settings', force: true do |t|
322
- t.add_setting( "index.search.idle.after", "20s")
345
+ t.add_setting("index.search.idle.after", "20s")
323
346
  t.add_setting("index.shard.check_on_startup", true)
324
347
  t.add_alias('supersettings')
325
348
  end
@@ -337,9 +360,6 @@ class AddTests < ActiveRecord::Migration[7.0]
337
360
  t.timestamps
338
361
  end
339
362
 
340
- change_mapping_meta "vintage", :number, auto_increment: 'true'
341
- change_mapping_meta "vintage", :number, peter: 'hans'
342
-
343
363
  change_mapping_attributes "vintage", :number, fields: {raw: {type: :keyword}}
344
364
  end
345
365
 
data/docs/CHANGELOG.md CHANGED
@@ -1,6 +1,45 @@
1
1
  # ElasticsearchRecord - CHANGELOG
2
2
 
3
- ## [1.1.0] - 2022-12-02
3
+ ## [1.2.4] - 2022-12-15
4
+ * [fix] missing `#visit_Arel_Nodes_In` method in `Arel::Visitors::ElasticsearchQuery` to build array conditions
5
+ * [fix] resolving buckets from relation `ElasticsearchRecord::Result#buckets` not recognizing sub-buckets
6
+
7
+ ## [1.2.3] - 2022-12-12
8
+ * [fix] `change_table` 'if_exists: true' returns at the wrong state
9
+
10
+ ## [1.2.2] - 2022-12-12
11
+ * [add] `:if_exists` option for `change_table`
12
+ * [fix] executing `_compute_table_name` irregular on some schema methods and some not - not only executes on `create_table` and `change_table`
13
+ * [ref] private `_compute_table_name` method to public `compute_table_name`
14
+ * [ref] drop `_compute_table_name` on methods: open_table, close_table, truncate_table, drop_table, block_table, unblock_table & clone_table
15
+
16
+ ## [1.2.1] - 2022-12-12
17
+ * [add] `ActiveRecord::ConnectionAdapters::Elasticsearch::SchemaStatements#access_id_fielddata?` which checks the clusters setting 'indices.id_field_data.enabled' to determinate if a general sorting on the +_id+-field is possible or not.
18
+ * [add] `ElasticsearchRecord::Relation#ordered_relation` which overwrites the original method to check against the `#access_id_fielddata?` method
19
+ * [fix] default order by '_id' causes an exception if clusters 'indices.id_field_data.enabled' is disabled
20
+ * [fix] subfield where-condition `where('field.subfield', 'value')` was transformed into a nested 'join-table' hash
21
+ * [fix] yardoc docs & generation
22
+
23
+ ## [1.2.0] - 2022-12-02
24
+ * [add] `ElasticsearchRecord::SchemaMigration` to fix connection-related differences (like table_name_prefix, table_name_suffix)
25
+ * [add] connection (config-related) 'table_name_prefix' & 'table_name_suffix' - now will be forwarded to all related models & schema-tables
26
+ * [add] `#block_table`, `#unblock_table`, `#clone_table`, `#table_metas`, `#meta_exists?`, `#change_meta`, `#delete_meta` methods for Elasticsearch ConnectionAdapter
27
+ * [add] `ElasticsearchRecord::Base.auto_increment?`
28
+ * [add] index 'meta' method to access the `_meta` mapping
29
+ * [add] `.ElasticsearchRecord::Base.relay_id_attribute` to relay a possible existing 'id'-attribute
30
+ * [add] new enabled attribute `enabled` - which defines 'searchable attributes & fields' and gets also read from the index-mappings
31
+ * [ref] insert a new record with primary_key & auto_increment through a wrapper `_insert_with_auto_increment`
32
+ * [ref] resolve `primary_keys` now from the index `_meta` mapping first (old mapping-related 'meta.primary_key:"true"' is still supported)
33
+ * [ref] disable 'strict' mode (= validation) of settings, alias, mappings as default (this can be still used with `strict: true`)
34
+ * [ref] silent unsupported methods 'create/drop' for `ElasticsearchRecord::Tasks::ElasticsearchDatabaseTasks`
35
+ * [ref] primary_key & auto_increment handling of custom defined mappings - now uses the index `_meta` mapping
36
+ * [fix] creating a record with different 'primary_key' fails with removed value (value no longer gets dropped)
37
+ * [fix] some index-settings not being ignored through `#transform_settings!`
38
+ * [fix] `ActiveRecord::ConnectionAdapters::Elasticsearch::SchemaDumper` dumping environment-related tables in the same database
39
+ * [fix] `ActiveRecord::ConnectionAdapters::Elasticsearch::TableMappingDefinition` fails with explicit assignable attributes (now uses ASSIGNABLE_ATTRIBUTES)
40
+ * [fix] tables with provided 'table_name_prefix' or 'table_name_suffix' not being ignored by the SchemaDumper
41
+
42
+ ## [1.1.0] - 2022-12-01
4
43
  * [add] support for schema dumps & migrations for Elasticsearch
5
44
  * [add] `buckets` query/relation result method to resolve the buckets as key->value hash from aggregations
6
45
  * [add] support for third-party gems (e.g. elasticsearch-dsl)
@@ -39,4 +39,5 @@ DESC
39
39
  spec.add_development_dependency 'rspec', '~> 3.0'
40
40
  spec.add_development_dependency 'rake', "~> 13.0"
41
41
  spec.add_development_dependency 'yard', '~> 0.9'
42
+ spec.add_development_dependency 'yard-activesupport-concern', '~> 0.0.1'
42
43
  end
@@ -5,13 +5,14 @@ module ActiveRecord
5
5
  module Elasticsearch
6
6
  class Column < ConnectionAdapters::Column # :nodoc:
7
7
 
8
- attr_reader :virtual, :fields, :properties, :meta
8
+ attr_reader :virtual, :fields, :properties, :meta, :enabled
9
9
 
10
- def initialize(name, default, sql_type_metadata = nil, virtual: false, fields: nil, properties: nil, meta: nil, **kwargs)
10
+ def initialize(name, default, sql_type_metadata = nil, virtual: false, fields: nil, properties: nil, meta: nil, enabled: nil, **kwargs)
11
11
  @virtual = virtual
12
12
  @fields = fields.presence || []
13
13
  @properties = properties.presence || []
14
14
  @meta = meta.presence || {}
15
+ @enabled = enabled.nil? ? true : enabled
15
16
 
16
17
  super(name, default, sql_type_metadata, true, nil, **kwargs)
17
18
  end
@@ -21,6 +22,12 @@ module ActiveRecord
21
22
  meta? && meta['comment']
22
23
  end
23
24
 
25
+ # returns true if this column is enabled (= searchable by queries)
26
+ # @return [Boolean]
27
+ def enabled?
28
+ !!enabled
29
+ end
30
+
24
31
  # returns true if this column is virtual.
25
32
  # Virtual columns cannot be saved.
26
33
  # @return [Boolean]
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_record/connection_adapters/elasticsearch/schema_definitions/table_definition'
4
+
5
+ module ActiveRecord
6
+ module ConnectionAdapters
7
+ module Elasticsearch
8
+ class CloneTableDefinition < TableDefinition
9
+
10
+ attr_reader :target
11
+
12
+ def initialize(conn, name, target, settings: nil, aliases: nil, **opts)
13
+ super(conn, name, **opts)
14
+
15
+ @target = target
16
+ @settings = HashWithIndifferentAccess.new
17
+ @aliases = HashWithIndifferentAccess.new
18
+
19
+ transform_settings!(settings) if settings.present?
20
+ transform_aliases!(aliases) if aliases.present?
21
+ end
22
+
23
+ # returns an array with all +TableSettingDefinition+.
24
+ # @return [Array]
25
+ def settings
26
+ @settings.values
27
+ end
28
+
29
+ # returns an array with all +TableAliasDefinition+.
30
+ # @return [Array]
31
+ def aliases
32
+ @aliases.values
33
+ end
34
+
35
+ ######################
36
+ # DEFINITION METHODS #
37
+ ######################
38
+
39
+ def setting(name, value, force: false, **options, &block)
40
+ raise ArgumentError, "you cannot define an already defined setting '#{name}'!" if @settings.key?(name) && !force?(force)
41
+
42
+ @settings[name] = new_setting_definition(name, value, **options, &block)
43
+
44
+ self
45
+ end
46
+
47
+ def remove_setting(name)
48
+ @settings.delete name
49
+ end
50
+
51
+ # we can use +alias+ here, since the instance method is not a reserved keyword!
52
+
53
+ def alias(name, force: false, **options, &block)
54
+ raise ArgumentError, "you cannot define an already defined alias '#{name}'." if @aliases.key?(name) && !force?(force)
55
+
56
+ @aliases[name] = new_alias_definition(name, **options, &block)
57
+
58
+ self
59
+ end
60
+
61
+ def remove_alias(name)
62
+ @aliases.delete name
63
+ end
64
+
65
+ private
66
+
67
+ def _before_exec
68
+ block_table(self.name, :write)
69
+ end
70
+
71
+ def _after_exec
72
+ unblock_table(self.name, :write)
73
+ end
74
+
75
+ alias :_rescue_exec :_after_exec
76
+
77
+ def _exec
78
+ execute(schema_creation.accept(self), 'CLONE TABLE').dig('acknowledged')
79
+ end
80
+
81
+ # force empty states to prevent "Name is static for an open table" error.
82
+ def state
83
+ nil
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -17,7 +17,7 @@ module ActiveRecord
17
17
  # Appends a primary key definition to the table definition.
18
18
  # Can be called multiple times, but this is probably not a good idea.
19
19
  def primary_key(name, type = :primary_key, **options)
20
- mapping(name, type, **options.merge(primary_key: true))
20
+ mapping(name, type, **options.merge(primary_key: true, auto_increment: true))
21
21
  end
22
22
  end
23
23
 
@@ -12,6 +12,7 @@ module ActiveRecord
12
12
  @settings = HashWithIndifferentAccess.new
13
13
  @mappings = HashWithIndifferentAccess.new
14
14
  @aliases = HashWithIndifferentAccess.new
15
+ @metas = HashWithIndifferentAccess.new
15
16
 
16
17
  transform_settings!(settings) if settings.present?
17
18
  transform_mappings!(mappings) if mappings.present?
@@ -30,6 +31,12 @@ module ActiveRecord
30
31
  @mappings.values
31
32
  end
32
33
 
34
+ # returns an array with all +TableMetaDefinition+.
35
+ # @return [Array]
36
+ def metas
37
+ @metas.values
38
+ end
39
+
33
40
  # provide backwards compatibility to columns
34
41
  alias columns mappings
35
42
 
@@ -48,11 +55,32 @@ module ActiveRecord
48
55
  # DEFINITION METHODS #
49
56
  ######################
50
57
 
58
+ # adds a new meta
59
+ def meta(name, value, force: false, **options)
60
+ raise ArgumentError, "you cannot define an already defined meta '#{name}'!" if @metas.key?(name) && !force?(force)
61
+
62
+ @metas[name] = new_meta_definition(name, value, **options)
63
+
64
+ self
65
+ end
66
+
67
+ def remove_meta(name)
68
+ @metas.delete(name)
69
+ end
70
+
51
71
  # adds a new mapping
52
72
  def mapping(name, type, force: false, **options, &block)
53
73
  raise ArgumentError, "you cannot define an already defined mapping '#{name}'!" if @mappings.key?(name) && !force?(force)
54
74
 
55
- @mappings[name] = new_mapping_definition(name, type, **options, &block)
75
+ mapping = new_mapping_definition(name, type, **options, &block)
76
+ @mappings[name] = mapping
77
+
78
+
79
+ # check if the mapping is assigned as primary_key
80
+ if mapping.primary_key?
81
+ meta :primary_key, mapping.name
82
+ meta(:auto_increment, mapping.auto_increment) if mapping.auto_increment?
83
+ end
56
84
 
57
85
  self
58
86
  end
@@ -126,32 +154,6 @@ module ActiveRecord
126
154
  def state
127
155
  nil
128
156
  end
129
-
130
- def transform_mappings!(mappings)
131
- return unless mappings['properties'].present?
132
-
133
- mappings['properties'].each do |name, attributes|
134
- self.mapping(name, attributes.delete('type'), **attributes)
135
- end
136
- end
137
-
138
- def transform_settings!(settings)
139
- # exclude settings, that are provided through the API but are not part of the index-settings
140
- settings
141
- .with_indifferent_access
142
- .each { |name, value|
143
- # don't transform ignored names
144
- next if ActiveRecord::ConnectionAdapters::Elasticsearch::TableSettingDefinition.match_ignore_names?(name)
145
-
146
- self.setting(name, value)
147
- }
148
- end
149
-
150
- def transform_aliases!(aliases)
151
- aliases.each do |name, attributes|
152
- self.alias(name, **attributes)
153
- end
154
- end
155
157
  end
156
158
  end
157
159
  end
@@ -10,16 +10,19 @@ module ActiveRecord
10
10
  class TableDefinition
11
11
  include ColumnMethods
12
12
 
13
- delegate :execute, :schema_creation, :column_exists?, :mapping_exists?, :setting_exists?, :alias_exists?, :close_table, :open_table, :table_mappings, to: :conn
13
+ delegate :execute, :schema_creation,
14
+ :column_exists?, :mapping_exists?, :meta_exists?, :setting_exists?, :alias_exists?,
15
+ :close_table, :open_table, :block_table, :unblock_table,
16
+ :table_mappings, :table_metas, :table_settings, to: :conn
14
17
 
15
18
  attr_reader :conn
16
19
  attr_reader :name
17
20
  attr_reader :opts
18
21
 
19
22
  def initialize(conn, name, **opts)
20
- @conn = conn
21
- @name = name
22
- @opts = opts
23
+ @conn = conn
24
+ @name = name
25
+ @opts = opts
23
26
  @failed = false
24
27
  end
25
28
 
@@ -33,10 +36,11 @@ module ActiveRecord
33
36
  yield self
34
37
  rescue => e
35
38
  @failed = false
39
+ _rescue_assign
36
40
  raise e
37
- ensure
38
- _after_assign
39
41
  end
42
+
43
+ _after_assign
40
44
  end
41
45
 
42
46
  def exec!
@@ -47,10 +51,11 @@ module ActiveRecord
47
51
  _exec
48
52
  rescue => e
49
53
  @failed = false
54
+ _rescue_exec
50
55
  raise e
51
- ensure
52
- _after_exec
53
56
  end
57
+
58
+ _after_exec
54
59
  end
55
60
 
56
61
  def failed?
@@ -67,6 +72,10 @@ module ActiveRecord
67
72
  true
68
73
  end
69
74
 
75
+ def _rescue_assign
76
+ true
77
+ end
78
+
70
79
  def _before_exec
71
80
  true
72
81
  end
@@ -75,11 +84,23 @@ module ActiveRecord
75
84
  true
76
85
  end
77
86
 
87
+ def _rescue_exec
88
+ true
89
+ end
90
+
78
91
  def _exec
79
92
  raise ArgumentError, "you cannot execute a TableDefinition directly - use 'CreateTableDefinition' or 'UpdateTableDefinition' instead!"
80
93
  end
81
94
 
82
- def new_mapping_definition(name, type, strict: true, **attributes, &block)
95
+ def new_meta_definition(name, value, strict: false, **)
96
+ meta = TableMetaDefinition.new(name, value)
97
+
98
+ raise ArgumentError, "you cannot define an invalid meta '#{name}' (#{meta.error_messages})!" if strict?(strict) && !meta.valid?
99
+
100
+ meta
101
+ end
102
+
103
+ def new_mapping_definition(name, type, strict: false, **attributes, &block)
83
104
  mapping = TableMappingDefinition.new(name, type, attributes)
84
105
  block.call(mapping) if block_given?
85
106
 
@@ -90,7 +111,7 @@ module ActiveRecord
90
111
 
91
112
  alias :new_column_definition :new_mapping_definition
92
113
 
93
- def new_alias_definition(name, strict: true, **attributes, &block)
114
+ def new_alias_definition(name, strict: false, **attributes, &block)
94
115
  # create new alias
95
116
  tbl_alias = TableAliasDefinition.new(name, attributes)
96
117
  block.call(tbl_alias) if block_given?
@@ -100,7 +121,7 @@ module ActiveRecord
100
121
  tbl_alias
101
122
  end
102
123
 
103
- def new_setting_definition(name, value, strict: true, **, &block)
124
+ def new_setting_definition(name, value, strict: false, **, &block)
104
125
  # create new setting
105
126
  setting = TableSettingDefinition.new(name, value).with_state(state)
106
127
  block.call(setting) if block_given?
@@ -124,7 +145,41 @@ module ActiveRecord
124
145
  end
125
146
 
126
147
  def strict?(strict = nil)
127
- opts.fetch(:strict, true) && strict != false
148
+ opts.fetch(:strict, false) || strict
149
+ end
150
+
151
+ def transform_mappings!(mappings)
152
+ # transform +_meta+ mappings
153
+ if mappings['_meta'].present?
154
+ mappings['_meta'].each do |name, value|
155
+ self.meta(name, value)
156
+ end
157
+ end
158
+
159
+ # transform properties (=columns)
160
+ if mappings['properties'].present?
161
+ mappings['properties'].each do |name, attributes|
162
+ self.mapping(name, attributes.delete('type'), **attributes)
163
+ end
164
+ end
165
+ end
166
+
167
+ def transform_settings!(settings)
168
+ # exclude settings, that are provided through the API but are not part of the index-settings
169
+ settings
170
+ .with_indifferent_access
171
+ .each { |name, value|
172
+ # don't transform ignored names
173
+ next if ActiveRecord::ConnectionAdapters::Elasticsearch::TableSettingDefinition.match_ignore_names?(name)
174
+
175
+ self.setting(name, value)
176
+ }
177
+ end
178
+
179
+ def transform_aliases!(aliases)
180
+ aliases.each do |name, attributes|
181
+ self.alias(name, **attributes)
182
+ end
128
183
  end
129
184
  end
130
185
  end