elasticsearch_record 1.1.0 → 1.2.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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +22 -8
- data/docs/CHANGELOG.md +20 -1
- data/lib/active_record/connection_adapters/elasticsearch/column.rb +9 -2
- data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/clone_table_definition.rb +88 -0
- data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/column_methods.rb +1 -1
- data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/create_table_definition.rb +29 -27
- data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_definition.rb +67 -12
- data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_mapping_definition.rb +48 -13
- data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_meta_definition.rb +24 -0
- data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_setting_definition.rb +9 -4
- data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/update_table_definition.rb +38 -13
- data/lib/active_record/connection_adapters/elasticsearch/schema_definitions.rb +3 -0
- data/lib/active_record/connection_adapters/elasticsearch/schema_dumper.rb +41 -0
- data/lib/active_record/connection_adapters/elasticsearch/schema_statements.rb +36 -10
- data/lib/active_record/connection_adapters/elasticsearch/table_statements.rb +102 -8
- data/lib/active_record/connection_adapters/elasticsearch_adapter.rb +17 -2
- data/lib/arel/collectors/elasticsearch_query.rb +3 -0
- data/lib/arel/visitors/elasticsearch_query.rb +1 -0
- data/lib/arel/visitors/elasticsearch_schema.rb +48 -7
- data/lib/elasticsearch_record/core.rb +24 -8
- data/lib/elasticsearch_record/gem_version.rb +1 -1
- data/lib/elasticsearch_record/model_schema.rb +26 -2
- data/lib/elasticsearch_record/persistence.rb +45 -34
- data/lib/elasticsearch_record/query.rb +4 -1
- data/lib/elasticsearch_record/schema_migration.rb +49 -0
- data/lib/elasticsearch_record/tasks/elasticsearch_database_tasks.rb +15 -5
- data/lib/elasticsearch_record.rb +1 -0
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8c479344b27eac6994fc17c6607f42221b093ddfc5f6db36b88994f25f2a0e56
|
4
|
+
data.tar.gz: 884ba24246d3ab9ef3500546bca84dcb3eaea184ac20bcfde6a2713e0a6def79
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 554ca0302d07210beef1f8bcb4b49f65b9e734122ccbbfb4a44d619d7697d1e5ec4b4164890beacaab4106654e5cdb7c817adf81d5953d46ed9f600b395e8018
|
7
|
+
data.tar.gz: 2a6a3579a00f2734c623f364a1eea5ba9802896a122c74ea4503764c63ad0294f16279b02cf3ce0f6a8d924ef3cb15004c2e2a933e90f22d311f4cbae067597c
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -240,20 +240,24 @@ total = scope.total
|
|
240
240
|
- index_base_name
|
241
241
|
- relay_id_attribute
|
242
242
|
|
243
|
-
### Useful model
|
243
|
+
### Useful model class methods
|
244
|
+
- auto_increment?
|
245
|
+
- max_result_window
|
244
246
|
- source_column_names
|
245
247
|
- searchable_column_names
|
246
248
|
- find_by_query
|
247
249
|
- msearch
|
248
250
|
|
249
|
-
## ActiveRecord ConnectionAdapters
|
251
|
+
## ActiveRecord ConnectionAdapters table-methods
|
250
252
|
Access these methods through the model's connection.
|
253
|
+
|
251
254
|
```ruby
|
252
255
|
# returns mapping of provided table (index)
|
253
256
|
model.connection.table_mappings('table-name')
|
254
257
|
```
|
255
258
|
|
256
259
|
- table_mappings
|
260
|
+
- table_metas
|
257
261
|
- table_settings
|
258
262
|
- table_aliases
|
259
263
|
- table_state
|
@@ -261,12 +265,14 @@ Access these methods through the model's connection.
|
|
261
265
|
- alias_exists?
|
262
266
|
- setting_exists?
|
263
267
|
- mapping_exists?
|
268
|
+
- meta_exists?
|
264
269
|
- max_result_window
|
265
270
|
- cluster_info
|
266
271
|
|
267
272
|
## Active Record Schema migration methods
|
268
273
|
Access these methods through the model's connection or within any `Migration`.
|
269
274
|
|
275
|
+
**cluster actions:**
|
270
276
|
- open_table
|
271
277
|
- open_tables
|
272
278
|
- close_table
|
@@ -274,8 +280,15 @@ Access these methods through the model's connection or within any `Migration`.
|
|
274
280
|
- truncate_table
|
275
281
|
- truncate_tables
|
276
282
|
- drop_table
|
283
|
+
- block_table
|
284
|
+
- unblock_table
|
285
|
+
- clone_table
|
277
286
|
- create_table
|
278
287
|
- change_table
|
288
|
+
|
289
|
+
**table actions:**
|
290
|
+
- change_meta
|
291
|
+
- delete_meta
|
279
292
|
- add_mapping
|
280
293
|
- change_mapping
|
281
294
|
- change_mapping_meta
|
@@ -299,11 +312,15 @@ class AddTests < ActiveRecord::Migration[7.0]
|
|
299
312
|
t.setting :number_of_shards, "1"
|
300
313
|
t.setting :number_of_replicas, 0
|
301
314
|
end
|
315
|
+
|
316
|
+
# changes the auto-increment value
|
317
|
+
change_meta "assignments", :auto_increment, 3625
|
302
318
|
|
303
319
|
create_table "settings", force: true do |t|
|
304
320
|
t.mapping :created_at, :date
|
305
|
-
t.mapping :key, :
|
321
|
+
t.mapping :key, :integer do |m|
|
306
322
|
m.primary_key = true
|
323
|
+
m.auto_increment = 10
|
307
324
|
end
|
308
325
|
t.mapping :status, :keyword
|
309
326
|
t.mapping :updated_at, :date
|
@@ -315,11 +332,11 @@ class AddTests < ActiveRecord::Migration[7.0]
|
|
315
332
|
end
|
316
333
|
|
317
334
|
add_mapping "settings", :active, :boolean do |m|
|
318
|
-
m.comment = "
|
335
|
+
m.comment = "Contains the active state"
|
319
336
|
end
|
320
337
|
|
321
338
|
change_table 'settings', force: true do |t|
|
322
|
-
t.add_setting(
|
339
|
+
t.add_setting("index.search.idle.after", "20s")
|
323
340
|
t.add_setting("index.shard.check_on_startup", true)
|
324
341
|
t.add_alias('supersettings')
|
325
342
|
end
|
@@ -337,9 +354,6 @@ class AddTests < ActiveRecord::Migration[7.0]
|
|
337
354
|
t.timestamps
|
338
355
|
end
|
339
356
|
|
340
|
-
change_mapping_meta "vintage", :number, auto_increment: 'true'
|
341
|
-
change_mapping_meta "vintage", :number, peter: 'hans'
|
342
|
-
|
343
357
|
change_mapping_attributes "vintage", :number, fields: {raw: {type: :keyword}}
|
344
358
|
end
|
345
359
|
|
data/docs/CHANGELOG.md
CHANGED
@@ -1,6 +1,25 @@
|
|
1
1
|
# ElasticsearchRecord - CHANGELOG
|
2
2
|
|
3
|
-
## [1.
|
3
|
+
## [1.2.0] - 2022-12-02
|
4
|
+
* [add] `ElasticsearchRecord::SchemaMigration` to fix connection-related differences (like table_name_prefix, table_name_suffix)
|
5
|
+
* [add] connection (config-related) 'table_name_prefix' & 'table_name_suffix' - now will be forwarded to all related models & schema-tables
|
6
|
+
* [add] `#block_table`, `#unblock_table`, `#clone_table`, `#table_metas`, `#meta_exists?`, `#change_meta`, `#delete_meta` methods for Elasticsearch ConnectionAdapter
|
7
|
+
* [add] `ElasticsearchRecord::Base.auto_increment?`
|
8
|
+
* [add] index 'meta' method to access the `_meta` mapping
|
9
|
+
* [add] `.ElasticsearchRecord::Base.relay_id_attribute` to relay a possible existing 'id'-attribute
|
10
|
+
* [add] new enabled attribute `enabled` - which defines 'searchable attributes & fields' and gets also read from the index-mappings
|
11
|
+
* [ref] insert a new record with primary_key & auto_increment through a wrapper `_insert_with_auto_increment`
|
12
|
+
* [ref] resolve `primary_keys` now from the index `_meta` mapping first (old mapping-related 'meta.primary_key:"true"' is still supported)
|
13
|
+
* [ref] disable 'strict' mode (= validation) of settings, alias, mappings as default (this can be still used with `strict: true`)
|
14
|
+
* [ref] silent unsupported methods 'create/drop' for `ElasticsearchRecord::Tasks::ElasticsearchDatabaseTasks`
|
15
|
+
* [ref] primary_key & auto_increment handling of custom defined mappings - now uses the index `_meta` mapping
|
16
|
+
* [fix] creating a record with different 'primary_key' fails with removed value (value no longer gets dropped)
|
17
|
+
* [fix] some index-settings not being ignored through `#transform_settings!`
|
18
|
+
* [fix] `ActiveRecord::ConnectionAdapters::Elasticsearch::SchemaDumper` dumping environment-related tables in the same database
|
19
|
+
* [fix] `ActiveRecord::ConnectionAdapters::Elasticsearch::TableMappingDefinition` fails with explicit assignable attributes (now uses ASSIGNABLE_ATTRIBUTES)
|
20
|
+
* [fix] tables with provided 'table_name_prefix' or 'table_name_suffix' not being ignored by the SchemaDumper
|
21
|
+
|
22
|
+
## [1.1.0] - 2022-12-01
|
4
23
|
* [add] support for schema dumps & migrations for Elasticsearch
|
5
24
|
* [add] `buckets` query/relation result method to resolve the buckets as key->value hash from aggregations
|
6
25
|
* [add] support for third-party gems (e.g. elasticsearch-dsl)
|
@@ -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
|
data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/column_methods.rb
CHANGED
@@ -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
|
-
|
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
|
data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_definition.rb
CHANGED
@@ -10,16 +10,19 @@ module ActiveRecord
|
|
10
10
|
class TableDefinition
|
11
11
|
include ColumnMethods
|
12
12
|
|
13
|
-
delegate :execute, :schema_creation,
|
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
|
21
|
-
@name
|
22
|
-
@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
|
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:
|
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:
|
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,
|
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
|
@@ -16,6 +16,9 @@ module ActiveRecord
|
|
16
16
|
:index_prefixes, :index, :meta, :normalizer, :norms, :null_value, :position_increment_gap,
|
17
17
|
:properties, :search_analyzer, :similarity, :subobjects, :store, :term_vector].freeze
|
18
18
|
|
19
|
+
# define virtual attributes, that must be assigned due a special logic
|
20
|
+
ASSIGNABLE_ATTRIBUTES = [:comment, :primary_key, :auto_increment, :meta].freeze
|
21
|
+
|
19
22
|
build_attribute_methods! *ATTRIBUTES
|
20
23
|
|
21
24
|
# attributes
|
@@ -27,10 +30,7 @@ module ActiveRecord
|
|
27
30
|
validates_presence_of :name
|
28
31
|
validates_presence_of :type
|
29
32
|
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
|
33
|
+
validate :_validate_meta
|
34
34
|
|
35
35
|
# sets the default value (alias for null_value)
|
36
36
|
alias_method :default=, :null_value=
|
@@ -41,32 +41,62 @@ module ActiveRecord
|
|
41
41
|
####################
|
42
42
|
|
43
43
|
def initialize(name, type, attributes)
|
44
|
-
@name
|
45
|
-
|
44
|
+
@name = name.to_sym
|
45
|
+
|
46
|
+
attributes = attributes.symbolize_keys
|
47
|
+
# directly set attributes, that cannot be assigned
|
48
|
+
@attributes = attributes.except(*ASSIGNABLE_ATTRIBUTES)
|
49
|
+
# assign special attributes
|
50
|
+
__assign(attributes.slice(*ASSIGNABLE_ATTRIBUTES))
|
46
51
|
|
47
52
|
@type = _resolve_type(type)
|
48
53
|
end
|
49
54
|
|
50
|
-
#
|
55
|
+
# returns the +comment+ from 'meta' attribute
|
56
|
+
# @return [String, nil]
|
51
57
|
def comment
|
52
58
|
__get_nested(:meta, :comment)
|
53
59
|
end
|
54
60
|
|
61
|
+
# sets the +comment+ as 'meta' attribute
|
62
|
+
# @param [String] value
|
55
63
|
def comment=(value)
|
56
64
|
# important: meta-values can only be strings!
|
57
65
|
__set_nested(:meta, :comment, value.to_s)
|
58
66
|
end
|
59
67
|
|
68
|
+
# returns true if the +primary_key+ 'attribute' was provided
|
69
|
+
# @return [Boolean]
|
60
70
|
def primary_key
|
61
|
-
|
71
|
+
!!_lazy_attributes[:primary_key]
|
62
72
|
end
|
63
73
|
|
64
74
|
alias_method :primary_key?, :primary_key
|
65
75
|
|
66
|
-
#
|
76
|
+
# sets the +primary_key+ as 'lazy_attribute'
|
77
|
+
# @param [Boolean] value
|
67
78
|
def primary_key=(value)
|
68
|
-
|
69
|
-
|
79
|
+
_lazy_attributes[:primary_key] = value
|
80
|
+
end
|
81
|
+
|
82
|
+
# returns the +auto_increment+ value, if provided
|
83
|
+
# @return [Integer]
|
84
|
+
def auto_increment
|
85
|
+
return nil unless _lazy_attributes[:auto_increment]
|
86
|
+
return 0 if _lazy_attributes[:auto_increment] == true
|
87
|
+
_lazy_attributes[:auto_increment].to_i
|
88
|
+
end
|
89
|
+
|
90
|
+
# returns true if the +auto_increment+ 'attribute' was provided
|
91
|
+
# @return [Boolean]
|
92
|
+
def auto_increment?
|
93
|
+
!!auto_increment
|
94
|
+
end
|
95
|
+
|
96
|
+
# sets the +auto_increment+ as 'lazy_attribute'
|
97
|
+
# @param [Boolean, Integer] value
|
98
|
+
def auto_increment=(value)
|
99
|
+
_lazy_attributes[:auto_increment] = value
|
70
100
|
end
|
71
101
|
|
72
102
|
def meta=(value)
|
@@ -79,6 +109,11 @@ module ActiveRecord
|
|
79
109
|
|
80
110
|
private
|
81
111
|
|
112
|
+
# non persistent attributes
|
113
|
+
def _lazy_attributes
|
114
|
+
@_lazy_attributes ||= {}
|
115
|
+
end
|
116
|
+
|
82
117
|
# resolves the provided type.
|
83
118
|
# prevents to set a nil type (sets +:object+ or +:nested+ - depends on existing properties)
|
84
119
|
# @return [Symbol, nil]
|
@@ -99,8 +134,8 @@ module ActiveRecord
|
|
99
134
|
return invalid!("'meta' is not supported on object or nested types", :attributes) if [:object, :nested].include?(type)
|
100
135
|
|
101
136
|
# allow only strings
|
102
|
-
|
103
|
-
return invalid!("'meta' has a key '#{
|
137
|
+
failed_key = meta.keys.detect { |key| !meta[key].is_a?(String) }
|
138
|
+
return invalid!("'meta' has a key '#{failed_key}' with a none string value", :attributes) if failed_key.present?
|
104
139
|
|
105
140
|
true
|
106
141
|
end
|
data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_meta_definition.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_model/validations'
|
4
|
+
|
5
|
+
module ActiveRecord
|
6
|
+
module ConnectionAdapters
|
7
|
+
module Elasticsearch
|
8
|
+
class TableMetaDefinition
|
9
|
+
include ActiveModel::Validations
|
10
|
+
|
11
|
+
# attributes
|
12
|
+
attr_accessor :name
|
13
|
+
attr_accessor :value
|
14
|
+
|
15
|
+
validates_presence_of :name
|
16
|
+
|
17
|
+
def initialize(name, value)
|
18
|
+
@name = name.to_sym
|
19
|
+
@value = value
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|