elasticsearch_record 3.0.0 → 5.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: df21aa38516f4e56830e16ffcff4164b65541a869e3964771771eacdf4e8ad16
4
- data.tar.gz: 7ba579e28c1a85e7f890654c99c675eb60dd2fddf1b1eb877b0967e17f1d7097
3
+ metadata.gz: a4f850e5600056256b188825cc8ca7067b4928014a09b05bb18ed37fb648478f
4
+ data.tar.gz: 19cec69e3a5a67752f8c94a2b22968e29dd5edf7166e4e205903164387e8606f
5
5
  SHA512:
6
- metadata.gz: cb521dc265ec3a517ebda7b8b6e60b5471b1411bd8f04d6be72098e95177e32af06267bc9a2e2881699d0f7f317c3bf1ef77b6613d9657df6ac7347affa80cf9
7
- data.tar.gz: 981b0955f21d2260d794cc1946ed560fa70d0e429b5c0bc97d2c9c5b29b396af471cd8d6460929fa451913ad44f7d9992c9b8c0d8a6cd6a7035c338147161138
6
+ metadata.gz: 076f2df28822bba0a2148d2e3043cb403cb04d388c5034056eb7e298004694707b2e2b8c003257f8da4dc5d1bea80ae5bce8b851244cd146232b381ecc35543e
7
+ data.tar.gz: 91a406efac0912da2f2427120b0cf1fdbf1ae78166b9853c3af6099b6e19fd4aa09aebf962840f01345d4b32a523a1fd74706f827f86b0804a0f8ffef2199392
data/README.md CHANGED
@@ -16,8 +16,8 @@ _ElasticsearchRecord is a ActiveRecord adapter and provides similar functionalit
16
16
 
17
17
  **PLEASE NOTE:**
18
18
 
19
- - This is the `main`-branch, which supports rails **7.2** _(see section 'Rails_Versions' for supported versions)_
20
- - supports ActiveRecord ~> 7.2 + Elasticsearch >= 7.17
19
+ - This is the `main`-branch, which supports rails **8.1** _(see section 'Rails_Versions' for supported versions)_
20
+ - supports ActiveRecord ~> 8.1 + Elasticsearch >= 7.17
21
21
  - added features up to Elasticsearch `8.17.1` _(tested against `8.19.14`)_
22
22
  - _ES|QL_ queries _(`TYPE_ESQL` / the `esql.query` gate)_ require **Elasticsearch >= 8.11**, where the feature became
23
23
  generally available. All other features remain available from Elasticsearch `7.17`.
@@ -28,15 +28,30 @@ _ElasticsearchRecord is a ActiveRecord adapter and provides similar functionalit
28
28
 
29
29
  Supported rails versions:
30
30
 
31
+ ### Rails 8.1:
32
+ _(since gem version 5.0)_
33
+
34
+ https://github.com/ruby-smart/elasticsearch_record/tree/rails-8-1-stable
35
+
36
+ [![rails-7-1-stable](https://img.shields.io/badge/rails-8.1.stable-orange.svg)](https://github.com/ruby-smart/elasticsearch_record/tree/rails-8-1-stable)
37
+
38
+ ### Rails 8.0:
39
+ _(since gem version 4.0)_
40
+
41
+ https://github.com/ruby-smart/elasticsearch_record/tree/rails-8-0-stable
42
+
43
+ [![rails-7-1-stable](https://img.shields.io/badge/rails-8.0.stable-orange.svg)](https://github.com/ruby-smart/elasticsearch_record/tree/rails-8-0-stable)
44
+
45
+
31
46
  ### Rails 7.2:
32
- _(since gem version 2.1)_
47
+ _(since gem version 3.0)_
33
48
 
34
49
  https://github.com/ruby-smart/elasticsearch_record/tree/rails-7-2-stable
35
50
 
36
51
  [![rails-7-1-stable](https://img.shields.io/badge/rails-7.2.stable-orange.svg)](https://github.com/ruby-smart/elasticsearch_record/tree/rails-7-2-stable)
37
52
 
38
53
  ### Rails 7.1:
39
- _(since gem version 1.8)_
54
+ _(since gem version 2.0)_
40
55
 
41
56
  https://github.com/ruby-smart/elasticsearch_record/tree/rails-7-1-stable
42
57
 
data/docs/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # ElasticsearchRecord - CHANGELOG
2
2
 
3
+ ## [5.0.0] - 2026-09-10
4
+ * [add] **BREAKING**: requires `activerecord ~> 8.1.0`
5
+ * [add] `Relation::ValueMethods#limit!` - keeps the `'__max__'` & `Float::INFINITY` limits, which rails now casts through `Integer()`
6
+ * [add] specs for `SchemaStatements#new_column_from_field` resolving the cast type upfront
7
+ * [ref] `Elasticsearch::Column#initialize` takes `cast_type` as 2nd positional argument
8
+ * [ref] `SchemaStatements#lookup_cast_type_from_column` -> `#lookup_multicast_cast_type` - resolves from a `sql_type` and is called upfront
9
+ * [ref] `DatabaseStatements#internal_execute` guards writes through `#write_query?` & `#ensure_writes_are_allowed`
10
+ * [ref] `StatementCache::PartialQuery#initialize` takes the `retryable:` flag
11
+
12
+ ## [4.0.0] - 2026-09-08
13
+ * [add] **BREAKING**: requires `activerecord ~> 8.0.0`
14
+ * [add] `ElasticsearchRecord::Result#indexed_rows` - rails 8.0 instantiates records through this method instead of iterating the result set itself.
15
+ * [ref] `ElasticsearchAdapter#log` resolves the instrumenter through `#instrumenter` instead of the former `@instrumenter` ivar
16
+ * [ref] `ActiveRecord::ConnectionAdapters::Elasticsearch::SchemaDumper` remove redundant blank lines
17
+
3
18
  ## [3.0.0] - 2026-09-08
4
19
  * [add] **BREAKING**: requires `activerecord ~> 7.2.0`
5
20
  * [add] `Quoting::ClassMethods#quote_column_name` & `#quote_table_name` - identifier quoting is class-level & mandatory now
@@ -14,7 +14,7 @@ DESC
14
14
 
15
15
  spec.homepage = "https://github.com/ruby-smart/elasticsearch_record"
16
16
  spec.license = "MIT"
17
- spec.required_ruby_version = ">= 3.1.0"
17
+ spec.required_ruby_version = ">= 3.2.0"
18
18
 
19
19
  spec.metadata["allowed_push_host"] = "https://rubygems.org"
20
20
  spec.metadata["homepage_uri"] = spec.homepage
@@ -32,7 +32,7 @@ DESC
32
32
 
33
33
  spec.require_paths = ["lib"]
34
34
 
35
- spec.add_dependency 'activerecord', '~> 7.2.0'
35
+ spec.add_dependency 'activerecord', '~> 8.1.0'
36
36
  spec.add_dependency 'elasticsearch', '>= 7.17'
37
37
 
38
38
  spec.add_development_dependency 'coveralls_reborn', '~> 0.25'
@@ -7,14 +7,14 @@ module ActiveRecord
7
7
 
8
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, enabled: nil, **kwargs)
10
+ def initialize(name, cast_type, 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
15
  @enabled = enabled.nil? ? true : enabled
16
16
 
17
- super(name, default, sql_type_metadata, true, nil, **kwargs)
17
+ super(name, cast_type, default, sql_type_metadata, true, nil, **kwargs)
18
18
  end
19
19
 
20
20
  # returns comment from meta
@@ -160,7 +160,7 @@ module ActiveRecord
160
160
  raise ActiveRecord::StatementInvalid, 'Unable to execute! Provided query is invalid.' unless query.valid?
161
161
 
162
162
  # checks for write query - raises an exception if connection is locked to readonly ...
163
- check_if_write_query(query)
163
+ ensure_writes_are_allowed(query) if write_query?(query)
164
164
 
165
165
  api(query.gate, query.query_arguments, name, async: async, allow_retry: allow_retry, materialize_transactions: materialize_transactions)
166
166
  end
@@ -151,14 +151,12 @@ module ActiveRecord
151
151
  end
152
152
 
153
153
  tbl.puts " end"
154
- tbl.puts
155
154
 
156
155
  tbl.rewind
157
156
  stream.print tbl.read
158
157
  rescue => e
159
158
  stream.puts "# Could not dump table #{table.inspect} because of following #{e.class}"
160
159
  stream.puts "# #{e.message}"
161
- stream.puts
162
160
  ensure
163
161
  self.table_name = nil
164
162
  end
@@ -226,6 +226,8 @@ module ActiveRecord
226
226
  def new_column_from_field(_table_name, field, _definitions)
227
227
  ActiveRecord::ConnectionAdapters::Elasticsearch::Column.new(
228
228
  field["name"],
229
+ # the cast type is resolved upfront and stored on the column
230
+ lookup_multicast_cast_type(field["type"]),
229
231
  field["null_value"],
230
232
  fetch_type_metadata(field["type"]),
231
233
  meta: field['meta'],
@@ -236,13 +238,13 @@ module ActiveRecord
236
238
  )
237
239
  end
238
240
 
239
- # lookups from building the @columns_hash.
241
+ # resolves the cast type of the provided +sql_type+ and wraps it into a +MulticastValue+.
240
242
  # since Elasticsearch has the "feature" to provide multicast values on any type, we need to fetch them ...
241
243
  # you know, ES can return an integer or an array of integers for any column ...
242
- # @param [ActiveRecord::ConnectionAdapters::Elasticsearch::Column] column
244
+ # @param [String] sql_type
243
245
  # @return [ActiveRecord::ConnectionAdapters::Elasticsearch::Type::MulticastValue]
244
- def lookup_cast_type_from_column(column)
245
- type_map.lookup(:multicast_value, super)
246
+ def lookup_multicast_cast_type(sql_type)
247
+ type_map.lookup(:multicast_value, lookup_cast_type(sql_type))
246
248
  end
247
249
 
248
250
  # Returns a array of tables primary keys.
@@ -114,8 +114,8 @@ module ActiveRecord # :nodoc:
114
114
  # this special Type is required to parse a ES-value into the +nested_type+, array or hash.
115
115
  # For arrays & hashes it tries to cast the values with the provided +nested_type+
116
116
  # but falls back to provided value if cast fails.
117
- # This type cannot be accessed through the mapping and is only called @ #lookup_cast_type_from_column
118
- # @see ActiveRecord::ConnectionAdapters::Elasticsearch::SchemaStatements#lookup_cast_type_from_column
117
+ # This type cannot be accessed through the mapping and is only called @ #lookup_multicast_cast_type
118
+ # @see ActiveRecord::ConnectionAdapters::Elasticsearch::SchemaStatements#lookup_multicast_cast_type
119
119
  m.register_type :multicast_value do |_type, nested_type|
120
120
  ActiveRecord::ConnectionAdapters::Elasticsearch::Type::MulticastValue.new(nested_type: nested_type)
121
121
  end
@@ -384,7 +384,9 @@ module ActiveRecord # :nodoc:
384
384
  # @raise [Exception] any exception encountered during execution, after translation.
385
385
  # @return [void]
386
386
  def log(gate, arguments, name = 'QUERY', async: false, statistics: nil, &block)
387
- @instrumenter.instrument(
387
+ # +instrumenter+ instead of the former +@instrumenter+ ivar - the abstract adapter
388
+ # resolves it per execution context now
389
+ instrumenter.instrument(
388
390
  "query.elasticsearch_record",
389
391
  gate: gate,
390
392
  name: name,
File without changes
@@ -7,7 +7,7 @@ module ElasticsearchRecord
7
7
  end
8
8
 
9
9
  module VERSION
10
- MAJOR = 3
10
+ MAJOR = 5
11
11
  MINOR = 0
12
12
  TINY = 0
13
13
  PRE = nil
@@ -43,6 +43,14 @@ module ElasticsearchRecord
43
43
  @values[:aggs] = value
44
44
  end
45
45
 
46
+ # overwrite the +limit!+ method, since the default implementation casts the provided value
47
+ # through +Integer()+ before it reaches the +limit_value=+ setter - which would raise
48
+ # for our special values ('__max__' & +Float::INFINITY+).
49
+ def limit!(value)
50
+ self.limit_value = value
51
+ self
52
+ end
53
+
46
54
  # overwrite the limit_value setter, to provide a special behaviour of auto-setting the +max_result_window+.
47
55
  def limit_value=(limit)
48
56
  if limit == '__max__' || limit == Float::INFINITY || (limit.nil? && delegate_query_nil_limit?)
@@ -172,6 +172,16 @@ module ElasticsearchRecord
172
172
  n ? computed_results.last(n) : computed_results.last
173
173
  end
174
174
 
175
+ # Returns the rows to instantiate records from - ActiveRecord resolves them through this
176
+ # method instead of iterating the result set itself.
177
+ # Each element is a Hash keyed by column / metadata name and therefore already provides the
178
+ # read surface of +ActiveRecord::Result::IndexedRow+ (+key?+, +[]+, +fetch+, +keys+, ...).
179
+ # used by +ActiveRecord+
180
+ # @return [Array<Hash>]
181
+ def indexed_rows # :nodoc:
182
+ computed_results
183
+ end
184
+
175
185
  # used by ActiveRecord
176
186
  def cancel # :nodoc:
177
187
  self
@@ -4,8 +4,9 @@ module ElasticsearchRecord
4
4
  class StatementCache < ActiveRecord::StatementCache
5
5
 
6
6
  class PartialQuery < ActiveRecord::StatementCache::PartialQuery # :nodoc:
7
- def initialize(values)
8
- @values = values
7
+ def initialize(values, retryable:)
8
+ @values = values
9
+ @retryable = retryable
9
10
  # no need to create indexes
10
11
  end
11
12
 
@@ -77,8 +78,8 @@ module ElasticsearchRecord
77
78
  end
78
79
  end
79
80
 
80
- def self.partial_query(values)
81
- PartialQuery.new(values)
81
+ def self.partial_query(...)
82
+ PartialQuery.new(...)
82
83
  end
83
84
 
84
85
  def self.partial_query_collector
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elasticsearch_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 5.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Gonsior
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: 7.2.0
18
+ version: 8.1.0
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: 7.2.0
25
+ version: 8.1.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: elasticsearch
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -228,7 +228,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
228
228
  requirements:
229
229
  - - ">="
230
230
  - !ruby/object:Gem::Version
231
- version: 3.1.0
231
+ version: 3.2.0
232
232
  required_rubygems_version: !ruby/object:Gem::Requirement
233
233
  requirements:
234
234
  - - ">="