elasticsearch_record 1.5.3 → 1.7.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: 238cf0f5e82cb385fc6d0f4e7f0416192f1cf65134b9726de16149be5fe6dc6b
4
- data.tar.gz: 002b7d91869f2c0a9f03729c9c2c0db3719abfa9d523925cfeaf5bacf101e563
3
+ metadata.gz: 92676fe7f2327036588c1d2e3cb6756cabbc2365ee8984196f1ef1c4a23d8448
4
+ data.tar.gz: 8c1f329957f4a1909181dde9e9c781a86a41188ee7337a73614eb8d893cae482
5
5
  SHA512:
6
- metadata.gz: b58fc1dbdd310c1e5c8c47bb54398a4300042c063afd6a49543a5c6b2a270f2ffe7fb168b357ff1da5cb738ab602550bbf8a1297d4464089c5c0d8809a4e3a8c
7
- data.tar.gz: 10be3f8fa2ea798bf58f2187ee7ea23099545ddad32036642e3b16d5e48cde7ccbabaff2bc68bc0baa2c71c41409de14abebedd11d6b0bcbe026c0e8200f0db2
6
+ metadata.gz: 9cb4514641f1f26d922f5cb941a677c5cff568641ddcf7243a914481707a982440b6a8967e74734d7900c00c6441128ef69c29a5c3774455df018206932e1b85
7
+ data.tar.gz: 004b62c74a4b4878c2e0a982a91217beee695a8e58d4509bba4cbd8f7664fdd0a4658cfd8533e1ff5a409f5fee6bce613d46f398ac067ed474324d65ad43406c
data/.yardopts CHANGED
@@ -1,6 +1,6 @@
1
1
  --embed-mixins
2
2
  --markup=markdown
3
- --files docs/*.*
3
+ --files docs/*
4
4
  --plugin relative_markdown_links
5
5
  --plugin activesupport-concern
6
6
  --exclude lib/elasticsearch_record/patches
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![Documentation](https://img.shields.io/badge/docs-rdoc.info-blue.svg)](http://rubydoc.info/gems/elasticsearch_record)
5
5
 
6
6
  [![Gem Version](https://badge.fury.io/rb/elasticsearch_record.svg)](https://badge.fury.io/rb/elasticsearch_record)
7
- [![License](https://img.shields.io/github/license/ruby-smart/elasticsearch_record)](docs/LICENSE.txt)
7
+ [![License](https://img.shields.io/github/license/ruby-smart/elasticsearch_record)](docs/LICENSE)
8
8
 
9
9
  ActiveRecord adapter for Elasticsearch
10
10
 
@@ -14,8 +14,28 @@ _ElasticsearchRecord is a ActiveRecord adapter and provides similar functionalit
14
14
 
15
15
  **PLEASE NOTE:**
16
16
 
17
- - Specs & documentation are still missing, but will follow.
18
- - Currently supports ActiveRecord ~> 7.0 + Elasticsearch >= 7.17
17
+ - This is the `rails-7-0-stable`-branch, which only supports rails **7.0** _(see section 'Rails_Versions' for supported versions)_
18
+ - supports ActiveRecord ~> 7.0 + Elasticsearch >= 7.17
19
+
20
+ -----
21
+
22
+ ## Rails versions
23
+
24
+ Supported rails versions:
25
+
26
+ ### Rails 7.1:
27
+ _(since gem version 1.8)_
28
+
29
+ https://github.com/ruby-smart/elasticsearch_record/tree/rails-7-1-stable
30
+
31
+ [![rails-7-1-stable](https://img.shields.io/badge/rails-7.1.stable-orange.svg)](https://github.com/ruby-smart/elasticsearch_record/tree/rails-7-1-stable)
32
+
33
+ ### Rails 7.0:
34
+ _(until gem version 1.7)_
35
+
36
+ https://github.com/ruby-smart/elasticsearch_record/tree/rails-7-0-stable
37
+
38
+ [![rails-7-0-stable](https://img.shields.io/badge/rails-7.0.stable-orange.svg)](https://github.com/ruby-smart/elasticsearch_record/tree/rails-7-0-stable)
19
39
 
20
40
  -----
21
41
 
@@ -24,7 +44,11 @@ _ElasticsearchRecord is a ActiveRecord adapter and provides similar functionalit
24
44
  Add this line to your application's Gemfile:
25
45
 
26
46
  ```ruby
27
- gem 'elasticsearch_record'
47
+ gem 'elasticsearch_record', '~> 1.7'
48
+
49
+ # alternative
50
+ gem 'elasticsearch_record', git: 'https://github.com/ruby-smart/elasticsearch_record', branch: 'rails-7-0-stable'
51
+
28
52
  ```
29
53
 
30
54
  And then execute:
@@ -53,6 +77,22 @@ Or install it yourself as:
53
77
  * logs Elasticsearch API-calls
54
78
  * shows Runtime in logs
55
79
 
80
+ ## Notice
81
+ Since ActiveRecord does not have any configuration option to support transactions and
82
+ Elasticsearch does **NOT** support transactions, it may be risky to ignore them.
83
+
84
+ As a default, transactions are 'silently swallowed' to not break any existing applications...
85
+
86
+ To raise an exception while using transactions on a ElasticsearchRecord model, the following flag can be enabled.
87
+ However enabling this flag will surely fail transactional tests _(prevent this with 'use_transactional_tests=false')_
88
+
89
+ ```ruby
90
+ # config/initializers/elasticsearch_record.yml
91
+
92
+ # enable transactional exceptions
93
+ ElasticsearchRecord.error_on_transaction = true
94
+ ```
95
+
56
96
  ## Setup
57
97
 
58
98
  ### a) Update your **database.yml** and add a elasticsearch connection:
@@ -219,11 +259,25 @@ total = scope.total
219
259
  # > 3335
220
260
  ```
221
261
 
262
+ ### Available core query methods
263
+
264
+ - find_by_sql
265
+ - find_by_query
266
+ - find_by_esql
267
+ - esql
268
+ - msearch
269
+ - search
270
+
271
+ _see simple documentation about these methods @ {ElasticsearchRecord::Querying rubydoc}_
272
+
273
+ _(also see @ [github](https://github.com/ruby-smart/elasticsearch_record/blob/main/lib/elasticsearch_record/querying.rb) )_
274
+
222
275
  ### Available query/relation chain methods
223
276
  - kind
224
277
  - configure
225
278
  - aggregate
226
279
  - refresh
280
+ - timeout
227
281
  - query
228
282
  - filter
229
283
  - must_not
@@ -235,7 +289,9 @@ total = scope.total
235
289
  - aggs_only!
236
290
  - total_only!
237
291
 
238
- _see simple documentation about these methods @ [rubydoc](https://rubydoc.info/gems/elasticsearch_record/ElasticsearchRecord/Relation/QueryMethods)_
292
+ _see simple documentation about these methods @ {ElasticsearchRecord::Relation::QueryMethods rubydoc}_
293
+
294
+ _(also see @ [github](https://github.com/ruby-smart/elasticsearch_record/blob/main/lib/elasticsearch_record/relation/query_methods.rb) )_
239
295
 
240
296
  ### Available calculation methods
241
297
  - percentiles
@@ -245,9 +301,16 @@ _see simple documentation about these methods @ [rubydoc](https://rubydoc.info/g
245
301
  - minimum
246
302
  - maximum
247
303
  - sum
304
+ - boxplot
305
+ - stats
306
+ - string_stats
307
+ - matrix_stats
308
+ - median_absolute_deviation
248
309
  - calculate
249
310
 
250
- _see simple documentation about these methods @ [rubydoc](https://rubydoc.info/gems/elasticsearch_record/ElasticsearchRecord/Relation/CalculationMethods)_
311
+ _see simple documentation about these methods @ {ElasticsearchRecord::Relation::CalculationMethods rubydoc}_
312
+
313
+ _(also see @ [github](https://github.com/ruby-smart/elasticsearch_record/blob/main/lib/elasticsearch_record/relation/calculation_methods.rb) )_
251
314
 
252
315
  ### Available result methods
253
316
  - aggregations
@@ -260,8 +323,11 @@ _see simple documentation about these methods @ [rubydoc](https://rubydoc.info/g
260
323
  - composite
261
324
  - point_in_time
262
325
  - pit_results
326
+ - pit_delete
263
327
 
264
- _see simple documentation about these methods @ [rubydoc](https://rubydoc.info/gems/elasticsearch_record/ElasticsearchRecord/Relation/ResultMethods)_
328
+ _see simple documentation about these methods @ {ElasticsearchRecord::Relation::ResultMethods rubydoc}_
329
+
330
+ _(also see @ [github](https://github.com/ruby-smart/elasticsearch_record/blob/main/lib/elasticsearch_record/relation/result_methods.rb) )_
265
331
 
266
332
  ### Additional methods
267
333
  - to_query
@@ -366,13 +432,26 @@ SearchUser.api.mappings
366
432
  SearchUser.api.insert([{name: 'Hans', age: 34}, {name: 'Peter', age: 22}])
367
433
  ```
368
434
 
435
+ ### dangerous methods
369
436
  * open!
370
437
  * close!
371
438
  * refresh!
372
439
  * block!
373
440
  * unblock!
441
+
442
+ ### dangerous methods with args
443
+ * create!(...)
444
+ * clone!(...)
445
+ * rename!(...)
446
+ * backup!(...)
447
+ * restore!(...)
448
+ * reindex!(...)
449
+
450
+ ### dangerous methods with confirm parameter
374
451
  * drop!(confirm: true)
375
452
  * truncate!(confirm: true)
453
+
454
+ ### table methods
376
455
  * mappings
377
456
  * metas
378
457
  * settings
@@ -380,17 +459,19 @@ SearchUser.api.insert([{name: 'Hans', age: 34}, {name: 'Peter', age: 22}])
380
459
  * state
381
460
  * schema
382
461
  * exists?
383
- * alias_exists?
384
- * setting_exists?
385
- * mapping_exists?
386
- * meta_exists?
387
-
388
- Fast insert, update, delete raw data
389
- * index
390
- * insert
391
- * update
392
- * delete
393
- * bulk
462
+
463
+ ### plain methods
464
+ * alias_exists?(...)
465
+ * setting_exists?(...)
466
+ * mapping_exists?(...)
467
+ * meta_exists?(...)
468
+
469
+ ### Fast insert, update, delete raw data
470
+ * index(...)
471
+ * insert(...)
472
+ * update(...)
473
+ * delete(...)
474
+ * bulk(...)
394
475
 
395
476
  -----
396
477
 
@@ -436,6 +517,9 @@ Access these methods through the model's connection or within any `Migration`.
436
517
  - create_table
437
518
  - change_table
438
519
  - rename_table
520
+ - reindex_table
521
+ - backup_table
522
+ - restore_table
439
523
 
440
524
  ### table actions:
441
525
  - change_meta
@@ -584,7 +668,7 @@ This project is intended to be a safe, welcoming space for collaboration, and co
584
668
 
585
669
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
586
670
 
587
- A copy of the [LICENSE](docs/LICENSE.txt) can be found @ the docs.
671
+ A copy of the [LICENSE](docs/LICENSE) can be found @ the docs.
588
672
 
589
673
  ## Code of Conduct
590
674
 
data/docs/CHANGELOG.md CHANGED
@@ -1,5 +1,37 @@
1
1
  # ElasticsearchRecord - CHANGELOG
2
2
 
3
+ ## [1.7.0] - 2024-01-09
4
+ * [add] `ElasticsearchRecord::Relation#boxplot` calculation method
5
+ * [add] `ElasticsearchRecord::Relation#stats` calculation method
6
+ * [add] `ElasticsearchRecord::Relation#string_stats` calculation method
7
+ * [add] `ElasticsearchRecord::Relation#matrix_stats` calculation method
8
+ * [add] `ElasticsearchRecord::Relation#median_absolute_deviation` calculation method
9
+ * [add] `ElasticsearchRecord::Base#esql` + `ElasticsearchRecord::Base#find_by_esql` to support `ES|QL` queries
10
+ * [add] new repository branch `rails-7-0-stable` to support different rails versions
11
+ * [ref] minor code optimizations & documentation changes
12
+
13
+ ## [1.6.0] - 2023-08-11
14
+ * [add] `ElasticsearchRecord::Base#undelegate_id_attribute_with` method to support a temporary 'undelegation' (used to create a new record)
15
+ * [add] `ElasticsearchRecord::Relation#timeout` to directly provide the timeout-parameter to the query
16
+ * [add] `ElasticsearchRecord.error_on_transaction`-flag to throw transactional errors (default: `false`) - this will now **IGNORE** all transactions
17
+ * [add] `ElasticsearchRecord::ModelApi` create!, clone!, rename!, backup!, restore! & reindex!-methods
18
+ * [add] `ElasticsearchRecord::Relation#pit_delete` which executes a delete query in a 'point_in_time' scope.
19
+ * [add] `ActiveRecord::ConnectionAdapters::Elasticsearch::TableStatements#backup_table` to create a backup (snapshot) of the entire table (index)
20
+ * [add] `ActiveRecord::ConnectionAdapters::Elasticsearch::TableStatements#restore_table` to restore a entire table (index)
21
+ * [add] `ActiveRecord::ConnectionAdapters::Elasticsearch::TableStatements#reindex_table` to copy documents from source to destination
22
+ * [ref] `ElasticsearchRecord::Base.delegate_id_attribute` now supports instance writer
23
+ * [ref] `ElasticsearchRecord::Relation#pit_results` adds `ids_only`-parameter to now support a simple return of the records-ids...
24
+ * [fix] Relation `#last`-method will raise an transport exception if cluster setting '**indices.id_field_data.enabled**' is disabled (now checks for `access_id_fielddata?`)
25
+ * [fix] ElasticsearchRecord-connection settings does not support `username` key
26
+ * [fix] ElasticsearchRecord-connection settings does not support `port` key
27
+ * [fix] `_id`-Attribute is erroneously defined as 'virtual' attribute - but is required for insert statements.
28
+ * [fix] unsupported **SAVEPOINT** transactions throws exceptions _(especially in tests)_
29
+ * [fix] `ElasticsearchRecord::ModelApi#bulk` does not recognize `'_id' / :_id` attribute
30
+ * [fix] `ElasticsearchRecord::ModelApi#bulk` does not correctly build the data-hash for `update`-operation _(missing 'doc'-node)_
31
+ * [ref] simplify `ElasticsearchRecord::Base#searchable_column_names`
32
+ * [fix] creating a new record does not recognize a manually provided `_id`-attribute
33
+ * [fix] creating a new record with active `delegate_id_attribute`-flag does not update the records `_id`.
34
+
3
35
  ## [1.5.3] - 2023-07-14
4
36
  * [fix] `ElasticsearchRecord::Relation#where!` on nested, provided `:none` key
5
37
  * [ref] minor code tweaks and comment updates
@@ -13,10 +45,10 @@
13
45
 
14
46
  ## [1.5.0] - 2023-07-10
15
47
  * [add] additional `ElasticsearchRecord::ModelApi` methods **drop!** & **truncate!**, which have to be called with a `confirm:true` parameter
16
- * [add] `.ElasticsearchRecord::Base.delegate_query_nil_limit` to automatically delegate a relations `limit(nil)`-call to the **max_result_window** _(set to 10.000 as default)_
48
+ * [add] `ElasticsearchRecord::Base.delegate_query_nil_limit` to automatically delegate a relations `limit(nil)`-call to the **max_result_window** _(set to 10.000 as default)_
17
49
  * [add] `ActiveRecord::ConnectionAdapters::Elasticsearch::SchemaStatements#access_shard_doc?` which checks, if the **PIT**-shard_doc order is available
18
50
  * [add] support for **_shard_doc** as a default order for `ElasticsearchRecord::Relation#pit_results`
19
- * [ref] `.ElasticsearchRecord::Base.relay_id_attribute` to a more coherent name: `delegate_id_attribute`
51
+ * [ref] `ElasticsearchRecord::Base.relay_id_attribute` to a more coherent name: `delegate_id_attribute`
20
52
  * [ref] `ElasticsearchRecord::Relation#ordered_relation` to optimize already ordered relations
21
53
  * [ref] gemspecs to support different versions of Elasticsearch
22
54
  * [ref] improved README
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2022 Ruby Smart
3
+ Copyright (c) 2024 Ruby Smart
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -116,7 +116,7 @@ module ActiveRecord
116
116
  # Defaults to false.
117
117
  # @param [String] table_name
118
118
  # @param [Boolean] if_exists
119
- # @return [Array] acknowledged status
119
+ # @return [Boolean] acknowledged status
120
120
  def drop_table(table_name, if_exists: false, **)
121
121
  schema_cache.clear_data_source_cache!(table_name)
122
122
  api(:indices, :delete, { index: table_name, ignore: (if_exists ? 404 : nil) }, 'DROP TABLE').dig('acknowledged')
@@ -148,11 +148,12 @@ module ActiveRecord
148
148
  end
149
149
  end
150
150
 
151
- # clones an entire table (index) to the provided +target_name+.
151
+ # clones an entire table (index) with its docs to the provided +target_name+.
152
152
  # During cloning, the table will be automatically 'write'-blocked.
153
153
  # @param [String] table_name
154
154
  # @param [String] target_name
155
155
  # @param [Hash] options
156
+ # @return [Boolean] acknowledged status
156
157
  def clone_table(table_name, target_name, **options)
157
158
  # create new definition
158
159
  definition = clone_table_definition(table_name, target_name, **extract_table_options!(options))
@@ -168,6 +169,54 @@ module ActiveRecord
168
169
  definition.exec!
169
170
  end
170
171
 
172
+ # creates a backup (snapshot) of the entire table (index) from provided +table_name+.
173
+ # The backup will be closed, to prevent read/write access.
174
+ # The +target_name+ will be auto-generated, if not provided.
175
+ #
176
+ # @example
177
+ # backup_table('screenshots', to: 'screenshots-backup-v1')
178
+ #
179
+ # @param [String] table_name
180
+ # @param [String] to - target_name
181
+ # @param [Boolean] close - closes backup after creation (default: true)
182
+ # @return [String] backup_name
183
+ def backup_table(table_name, to: nil, close: true)
184
+ to ||= "#{table_name}-snapshot-#{Time.now.strftime('%s%3N')}"
185
+ raise ArgumentError, "unable to backup '#{table_name}' to already existing target '#{to}'!" if table_exists?(to)
186
+
187
+ clone_table(table_name, to)
188
+ close_table(to) if close
189
+
190
+ to
191
+ end
192
+
193
+ # restores a entire table (index) from provided +target_name+.
194
+ # The +table_name+ will be dropped, if exists.
195
+ # The +from+ will persist, if not provided +drop_backup:true+.
196
+ #
197
+ # @example
198
+ # restore_table('screenshots', from: 'screenshots-backup-v1')
199
+ #
200
+ # @param [String] table_name
201
+ # @param [String] from
202
+ # @param [String (frozen)] timeout - renaming timout (default: '30s')
203
+ # @param [Boolean] open - opens restored backup after creation (default: true)
204
+ # @return [Boolean] acknowledged status
205
+ def restore_table(table_name, from:, timeout: nil, open: true, drop_backup: false)
206
+ raise ArgumentError, "unable to restore from missing target '#{from}'!" unless table_exists?(from)
207
+ drop_table(table_name, if_exists: true)
208
+
209
+ # choose best strategy
210
+ if drop_backup
211
+ rename_table(from, table_name, timeout: timeout)
212
+ else
213
+ clone_table(from, table_name)
214
+ end
215
+
216
+ # open, if provided
217
+ open_table(from) if open
218
+ end
219
+
171
220
  # renames a table (index) by executing multiple steps:
172
221
  # - clone table
173
222
  # - wait for 'green' state
@@ -178,11 +227,11 @@ module ActiveRecord
178
227
  # @param [String] target_name
179
228
  # @param [String (frozen)] timeout (default: '30s')
180
229
  # @param [Hash] options - additional 'clone' options (like settings, alias, ...)
181
- def rename_table(table_name, target_name, timeout: '30s', **options)
230
+ def rename_table(table_name, target_name, timeout: nil, **options)
182
231
  schema_cache.clear_data_source_cache!(table_name)
183
232
 
184
233
  clone_table(table_name, target_name, **options)
185
- cluster_health(index: target_name, wait_for_status: 'green', timeout: timeout)
234
+ cluster_health(index: target_name, wait_for_status: 'green', timeout: timeout.presence || '30s')
186
235
  drop_table(table_name)
187
236
  end
188
237
 
@@ -255,6 +304,15 @@ module ActiveRecord
255
304
  definition.exec!
256
305
  end
257
306
 
307
+ # Copies documents from a source to a destination.
308
+ # @param [String] table_name
309
+ # @param [String] target_name
310
+ # @param [Hash] options
311
+ # @return [Hash] reindex stats
312
+ def reindex_table(table_name, target_name, **options)
313
+ api(:core, :reindex, { body: { source: { index: table_name }, dest: { index: target_name } } }.merge(options), 'REINDEX TABLE')
314
+ end
315
+
258
316
  # -- mapping -------------------------------------------------------------------------------------------------
259
317
 
260
318
  def add_mapping(table_name, name, type, **options, &block)
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module Elasticsearch
6
+ module Transactions
7
+ extend ActiveSupport::Concern
8
+
9
+ def transaction(*)
10
+ # since ActiveRecord does not have any configuration option to support transactions,
11
+ # this will be always false
12
+ # return super if supports_transactions?
13
+ #
14
+ # So, transactions are silently swallowed...
15
+ yield
16
+ end
17
+
18
+ # Begins the transaction (and turns off auto-committing).
19
+ def begin_db_transaction(*)
20
+ _throw_transaction_exception!(:begin_db_transaction)
21
+ end
22
+
23
+ # Commits the transaction (and turns on auto-committing).
24
+ def commit_db_transaction(*)
25
+ _throw_transaction_exception!(:commit_db_transaction)
26
+ end
27
+
28
+ # rollback transaction
29
+ def exec_rollback_db_transaction(*)
30
+ _throw_transaction_exception!(:exec_rollback_db_transaction)
31
+ end
32
+
33
+ def create_savepoint(*)
34
+ _throw_transaction_exception!(:create_savepoint)
35
+ end
36
+
37
+ def exec_rollback_to_savepoint(*)
38
+ _throw_transaction_exception!(:exec_rollback_to_savepoint)
39
+ end
40
+
41
+ def release_savepoint(*)
42
+ _throw_transaction_exception!(:release_savepoint)
43
+ end
44
+
45
+ private
46
+
47
+ def _throw_transaction_exception!(method_name)
48
+ return unless ElasticsearchRecord.error_on_transaction
49
+ raise NotImplementedError, "'##{method_name}' is not supported by Elasticsearch.\nTry to prevent transactions or set the 'ElasticsearchRecord.error_on_transaction' to false!"
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -3,13 +3,6 @@
3
3
  module ActiveRecord
4
4
  module ConnectionAdapters
5
5
  module Elasticsearch
6
-
7
- class UnsupportedImplementationError < StandardError
8
- def initialize(method_name)
9
- super "Unsupported implementation of method: #{method_name}."
10
- end
11
- end
12
-
13
6
  module UnsupportedImplementation
14
7
  extend ActiveSupport::Concern
15
8
 
@@ -13,6 +13,7 @@ require 'active_record/connection_adapters/elasticsearch/schema_dumper'
13
13
  require 'active_record/connection_adapters/elasticsearch/schema_statements'
14
14
  require 'active_record/connection_adapters/elasticsearch/type'
15
15
  require 'active_record/connection_adapters/elasticsearch/table_statements'
16
+ require 'active_record/connection_adapters/elasticsearch/transactions'
16
17
 
17
18
  require 'arel/visitors/elasticsearch'
18
19
  require 'arel/collectors/elasticsearch_query'
@@ -25,6 +26,12 @@ module ActiveRecord # :nodoc:
25
26
  def elasticsearch_connection(config)
26
27
  config = config.symbolize_keys
27
28
 
29
+ # move 'username' to 'user'
30
+ config[:user] = config.delete(:username) if config[:username]
31
+
32
+ # append 'port' to 'host'
33
+ config[:host] += ":#{config.delete(:port)}" if config[:port] && config[:host]
34
+
28
35
  # move 'host' to 'hosts'
29
36
  config[:hosts] = config.delete(:host) if config[:host]
30
37
 
@@ -45,7 +52,7 @@ module ActiveRecord # :nodoc:
45
52
 
46
53
  # defines the Elasticsearch 'base' structure, which is always included but cannot be resolved through mappings ...
47
54
  BASE_STRUCTURE = [
48
- { 'name' => '_id', 'type' => 'keyword', 'virtual' => true, 'enabled' => true, 'meta' => { 'primary_key' => 'true' } },
55
+ { 'name' => '_id', 'type' => 'keyword', 'meta' => { 'primary_key' => 'true' } },
49
56
  { 'name' => '_index', 'type' => 'keyword', 'virtual' => true },
50
57
  { 'name' => '_score', 'type' => 'float', 'virtual' => true },
51
58
  { 'name' => '_type', 'type' => 'keyword', 'virtual' => true },
@@ -57,6 +64,7 @@ module ActiveRecord # :nodoc:
57
64
  include Elasticsearch::DatabaseStatements
58
65
  include Elasticsearch::SchemaStatements
59
66
  include Elasticsearch::TableStatements
67
+ include Elasticsearch::Transactions
60
68
 
61
69
  class << self
62
70
  def base_structure_keys
@@ -69,7 +77,7 @@ module ActiveRecord # :nodoc:
69
77
  client.ping unless config[:ping] == false
70
78
  client
71
79
  rescue ::Elastic::Transport::Transport::Errors::Unauthorized
72
- raise ActiveRecord::DatabaseConnectionError.username_error(config[:username])
80
+ raise ActiveRecord::DatabaseConnectionError.username_error(config[:user])
73
81
  rescue ::Elastic::Transport::Transport::ServerError => error
74
82
  raise ::ActiveRecord::ConnectionNotEstablished, error.message
75
83
  end
@@ -135,7 +143,7 @@ module ActiveRecord # :nodoc:
135
143
 
136
144
  # define native types - which will be used for schema-dumping
137
145
  NATIVE_DATABASE_TYPES = {
138
- primary_key: { name: 'long' },
146
+ primary_key: { name: 'long' }, # maybe this hae to changed to 'keyword'
139
147
  string: { name: 'keyword' },
140
148
  blob: { name: 'binary' },
141
149
  datetime: { name: 'date' },
@@ -172,6 +180,12 @@ module ActiveRecord # :nodoc:
172
180
  @config[:migrations_paths] || ['db/migrate_elasticsearch']
173
181
  end
174
182
 
183
+ # Does this adapter support transactions in general?
184
+ # HINT: This is +NOT* an official setting and only introduced to ElasticsearchRecord
185
+ def supports_transactions?
186
+ false
187
+ end
188
+
175
189
  # Does this adapter support explain?
176
190
  def supports_explain?
177
191
  false
@@ -28,6 +28,9 @@ module Arel # :nodoc: all
28
28
  when :refresh
29
29
  # change the refresh state
30
30
  @refresh = args[0]
31
+ when :timeout
32
+ # change the timeout
33
+ @timeout = args[0]
31
34
  when :index
32
35
  # change the index name
33
36
  @index = args[0]
@@ -8,7 +8,7 @@ module ElasticsearchRecord
8
8
  # this through +_read_attribute(:id)+.
9
9
  # To also have the ability of accessing this attribute through the default, this flag can be enabled.
10
10
  # @attribute! Boolean
11
- class_attribute :delegate_id_attribute, instance_writer: false, default: false
11
+ class_attribute :delegate_id_attribute, default: false
12
12
 
13
13
  # Elasticsearch's default value for queries without a +size+ is forced to +10+.
14
14
  # To provide a similar behaviour as SQL, this can be automatically set to the +max_result_window+ value.
@@ -45,7 +45,7 @@ module ElasticsearchRecord
45
45
 
46
46
  # overwrite to provide a Elasticsearch version of returning a 'primary_key' was attribute.
47
47
  # Elasticsearch uses the static +_id+ column as primary_key, but also supports an additional +id+ column.
48
- # To provide functionality of returning the +id_Was+ attribute, this method must also support it
48
+ # To provide functionality of returning the +id_was+ attribute, this method must also support it
49
49
  # with enabled +delegate_id_attribute+.
50
50
  def id_was
51
51
  delegate_id_attribute? && has_attribute?('id') ? attribute_was('id') : super
@@ -69,6 +69,19 @@ module ElasticsearchRecord
69
69
  super
70
70
  end
71
71
 
72
+ # resets a possible active +delegate_id_attribute?+ to false during block execution.
73
+ # Unfortunately this is required, since a lot of rails-code forces 'accessors' on the primary_key-field through the
74
+ # +id+-getter & setter methods. This will then fail to set the doc-_id and instead set the +id+-attribute ...
75
+ def undelegate_id_attribute_with(&block)
76
+ return block.call unless self.delegate_id_attribute?
77
+
78
+ self.delegate_id_attribute = false
79
+ result = block.call
80
+ self.delegate_id_attribute = true
81
+
82
+ result
83
+ end
84
+
72
85
  module PrependClassMethods
73
86
  # returns the table_name.
74
87
  # Has to be prepended to provide automated compatibility to other gems.
@@ -8,8 +8,8 @@ module ElasticsearchRecord
8
8
 
9
9
  module VERSION
10
10
  MAJOR = 1
11
- MINOR = 5
12
- TINY = 3
11
+ MINOR = 7
12
+ TINY = 0
13
13
  PRE = nil
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
@@ -46,7 +46,7 @@ module ElasticsearchRecord
46
46
 
47
47
  # final coloring
48
48
  name = color(name, name_color(payload[:name]), true)
49
- query = color(query, gate_color(payload[:gate]), true) if colorize_logging
49
+ query = color(query, gate_color(payload[:gate], payload[:name]), true) if colorize_logging
50
50
 
51
51
  debug " #{name} #{query.presence || '-/-'}"
52
52
  end
@@ -61,7 +61,7 @@ module ElasticsearchRecord
61
61
  end
62
62
  end
63
63
 
64
- def gate_color(gate)
64
+ def gate_color(gate, name)
65
65
  case gate
66
66
  # SELECTS
67
67
  when 'core.get', 'core.mget', 'core.search', 'core.msearch', 'core.count', 'core.exists', 'sql.query'
@@ -77,7 +77,11 @@ module ElasticsearchRecord
77
77
  YELLOW
78
78
  # MIXINS
79
79
  when /indices\.\w+/, 'core.bulk', 'core.index'
80
- WHITE
80
+ if name.end_with?('Pit Delete')
81
+ RED
82
+ else
83
+ WHITE
84
+ end
81
85
  else
82
86
  MAGENTA
83
87
  end