elasticsearch_record 1.8.1 → 2.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.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +0 -0
  3. data/.yardopts +0 -0
  4. data/Gemfile +7 -0
  5. data/README.md +76 -7
  6. data/Rakefile +0 -0
  7. data/docs/CHANGELOG.md +52 -0
  8. data/docs/CODE_OF_CONDUCT.md +0 -0
  9. data/docs/LICENSE +0 -0
  10. data/elasticsearch_record.gemspec +1 -1
  11. data/lib/active_record/connection_adapters/elasticsearch/column.rb +0 -0
  12. data/lib/active_record/connection_adapters/elasticsearch/database_statements.rb +18 -17
  13. data/lib/active_record/connection_adapters/elasticsearch/quoting.rb +0 -0
  14. data/lib/active_record/connection_adapters/elasticsearch/schema_creation.rb +0 -0
  15. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/attribute_methods.rb +0 -0
  16. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/clone_table_definition.rb +0 -0
  17. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/column_methods.rb +1 -1
  18. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/create_table_definition.rb +6 -0
  19. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_alias_definition.rb +0 -0
  20. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_definition.rb +0 -0
  21. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_meta_definition.rb +0 -0
  22. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_setting_definition.rb +7 -5
  23. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/update_table_definition.rb +3 -1
  24. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions.rb +0 -0
  25. data/lib/active_record/connection_adapters/elasticsearch/schema_dumper.rb +24 -3
  26. data/lib/active_record/connection_adapters/elasticsearch/schema_statements.rb +39 -34
  27. data/lib/active_record/connection_adapters/elasticsearch/table_statements.rb +251 -72
  28. data/lib/active_record/connection_adapters/elasticsearch/transactions.rb +0 -0
  29. data/lib/active_record/connection_adapters/elasticsearch/type/format_string.rb +0 -0
  30. data/lib/active_record/connection_adapters/elasticsearch/type/multicast_value.rb +0 -0
  31. data/lib/active_record/connection_adapters/elasticsearch/type/nested.rb +0 -0
  32. data/lib/active_record/connection_adapters/elasticsearch/type/object.rb +0 -0
  33. data/lib/active_record/connection_adapters/elasticsearch/type/range.rb +0 -0
  34. data/lib/active_record/connection_adapters/elasticsearch/type.rb +0 -0
  35. data/lib/active_record/connection_adapters/elasticsearch/unsupported_implementation.rb +0 -0
  36. data/lib/active_record/connection_adapters/elasticsearch_adapter.rb +144 -87
  37. data/lib/arel/collectors/elasticsearch_query.rb +0 -0
  38. data/lib/arel/nodes/select_agg.rb +1 -1
  39. data/lib/arel/nodes/select_configure.rb +0 -0
  40. data/lib/arel/nodes/select_kind.rb +0 -0
  41. data/lib/arel/nodes/select_query.rb +0 -0
  42. data/lib/arel/visitors/elasticsearch.rb +0 -0
  43. data/lib/arel/visitors/elasticsearch_base.rb +7 -5
  44. data/lib/arel/visitors/elasticsearch_query.rb +51 -9
  45. data/lib/elasticsearch_record/base.rb +0 -0
  46. data/lib/elasticsearch_record/core.rb +0 -0
  47. data/lib/elasticsearch_record/errors.rb +0 -0
  48. data/lib/elasticsearch_record/extensions/relation.rb +0 -0
  49. data/lib/elasticsearch_record/gem_version.rb +3 -3
  50. data/lib/elasticsearch_record/instrumentation/controller_runtime.rb +0 -0
  51. data/lib/elasticsearch_record/instrumentation/log_subscriber.rb +11 -9
  52. data/lib/elasticsearch_record/instrumentation/railtie.rb +0 -0
  53. data/lib/elasticsearch_record/instrumentation.rb +0 -0
  54. data/lib/elasticsearch_record/model_api.rb +8 -5
  55. data/lib/elasticsearch_record/model_schema.rb +1 -1
  56. data/lib/elasticsearch_record/patches/active_record/relation_merger_patch.rb +0 -0
  57. data/lib/elasticsearch_record/patches/arel/select_core_patch.rb +0 -0
  58. data/lib/elasticsearch_record/patches/arel/select_manager_patch.rb +0 -0
  59. data/lib/elasticsearch_record/patches/arel/select_statement_patch.rb +0 -0
  60. data/lib/elasticsearch_record/patches/arel/update_manager_patch.rb +0 -0
  61. data/lib/elasticsearch_record/patches/arel/update_statement_patch.rb +0 -0
  62. data/lib/elasticsearch_record/persistence.rb +35 -18
  63. data/lib/elasticsearch_record/query.rb +53 -33
  64. data/lib/elasticsearch_record/querying.rb +5 -7
  65. data/lib/elasticsearch_record/relation/calculation_methods.rb +38 -2
  66. data/lib/elasticsearch_record/relation/core_methods.rb +0 -0
  67. data/lib/elasticsearch_record/relation/query_clause.rb +0 -0
  68. data/lib/elasticsearch_record/relation/query_clause_tree.rb +0 -0
  69. data/lib/elasticsearch_record/relation/query_methods.rb +36 -0
  70. data/lib/elasticsearch_record/relation/result_methods.rb +47 -43
  71. data/lib/elasticsearch_record/relation/value_methods.rb +0 -0
  72. data/lib/elasticsearch_record/result.rb +144 -60
  73. data/lib/elasticsearch_record/schema_migration.rb +0 -0
  74. data/lib/elasticsearch_record/statement_cache.rb +0 -0
  75. data/lib/elasticsearch_record/tasks/elasticsearch_database_tasks.rb +0 -0
  76. data/lib/elasticsearch_record/version.rb +0 -0
  77. data/lib/elasticsearch_record.rb +15 -0
  78. metadata +17 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ef01a33de054cbae1fe582ba5f7d8a5910c73dd81e3395f8b6c07ec9d3a5fbe2
4
- data.tar.gz: d574bafc90b201869727539fd0a0c148118d6f666f9f29400690613bd7cbbaa8
3
+ metadata.gz: 27f0d74b39e373493b56511cb08e07ed2fc447da5f33cf5a23a8a080072f3d4e
4
+ data.tar.gz: 52f5843b03ea19f3f236910f2268aadb1eba5b7eae48c59734d162fdd2bc6000
5
5
  SHA512:
6
- metadata.gz: 89ac7c99f35a36650c2ac8f00600f0c702ed8ec4c4aaa5d28ad86c329a66be3625d063ada9dd8c6630b8b30eea1a5283a0231a60c0d8021242adeae4efe86316
7
- data.tar.gz: b44f713a1650100a925c94349fcb9fdce4b72bf5acb901c5ff04b871e0586115bf5e08e42f38cd9ecb0e550663977da48e430a739b67230ced4eb29aa4f5bb8b
6
+ metadata.gz: '07733791c4f29ed331631d6ede8ba83b23ebad2af68afffda6e998eca7d09f4aad4a57a83c87e10dbd866a98bb8f77a6d4fffc905b1dd214d13f48313d603955'
7
+ data.tar.gz: 4f3e9ffb52a06c4db77fb698b7e715eac3ad77aa259df5f66905890f69646b35e4f6ee809c52feae3180544de8e47943f6cff95faeff12c43bfaecc9d0e01cb4
data/.rspec CHANGED
File without changes
data/.yardopts CHANGED
File without changes
data/Gemfile CHANGED
@@ -4,3 +4,10 @@ source "https://rubygems.org"
4
4
 
5
5
  # Specify your gem's dependencies in elasticsearch_record.gemspec
6
6
  gemspec
7
+
8
+ # Pin the Elasticsearch client to the 8.x line for local development & specs.
9
+ # The gemspec intentionally allows '>= 7.17', but the 9.x client sends an
10
+ # 'Accept: application/vnd.elasticsearch+json; compatible-with=9' header that
11
+ # 8.x servers reject with a media_type_header_exception (HTTP 400).
12
+ # Keep this in sync with the server you develop against.
13
+ gem 'elasticsearch', '~> 8.0'
data/README.md CHANGED
@@ -14,8 +14,11 @@ _ElasticsearchRecord is a ActiveRecord adapter and provides similar functionalit
14
14
 
15
15
  **PLEASE NOTE:**
16
16
 
17
- - This is the `rails-7-1-stable`-branch, which only supports rails **7.1** _(see section 'Rails_Versions' for supported versions)_
17
+ - This is the `main`-branch, which currently supports rails **7.1** _(see section 'Rails_Versions' for supported versions)_
18
18
  - supports ActiveRecord ~> 7.1 + Elasticsearch >= 7.17
19
+ - added features up to Elasticsearch `8.17.1`
20
+ - _ES|QL_ queries _(`TYPE_ESQL` / the `esql.query` gate)_ require **Elasticsearch >= 8.11**, where the feature became
21
+ generally available. All other features remain available from Elasticsearch `7.17`.
19
22
 
20
23
  -----
21
24
 
@@ -48,6 +51,7 @@ gem 'elasticsearch_record', '~> 1.8'
48
51
 
49
52
  # alternative
50
53
  gem 'elasticsearch_record', git: 'https://github.com/ruby-smart/elasticsearch_record', branch: 'rails-7-1-stable'
54
+ gem 'elasticsearch_record', git: 'https://github.com/ruby-smart/elasticsearch_record', branch: 'rails-7-0-stable'
51
55
 
52
56
  ```
53
57
 
@@ -613,17 +617,29 @@ end
613
617
  ```
614
618
 
615
619
  ## environment-related-table-name:
616
- Using the `_env_table_name`-method will resolve the table (index) name within the current environment,
617
- even if the environments shares the same cluster ...
620
+ Table (index) names are resolved within the current environment, even if the environments share the
621
+ same cluster ...
618
622
 
619
623
  This can be provided through the `database.yml` by using the `table_name_prefix/suffix` configuration keys.
620
- Within the migration the `_env_table_name`-method must be used in combination with the table (index) base name.
624
+ **Every table statement applies them by default**, so a migration only ever names the table (index)
625
+ _base_ name.
621
626
 
622
627
  **Example:**
623
628
  Production uses a index suffix with '-pro', development uses '-dev' - they share the same cluster, but different indexes.
624
629
 
625
- For the **settings** table:
630
+ ```yml
631
+ production:
632
+ elasticsearch:
633
+ # ...
634
+ table_name_suffix: '-pro'
635
+
636
+ development:
637
+ elasticsearch:
638
+ # ...
639
+ table_name_suffix: '-dev'
640
+ ```
626
641
 
642
+ For the **settings** table / index this results in the following names:
627
643
  * settings-pro
628
644
  * settings-dev
629
645
 
@@ -633,7 +649,8 @@ A single migration can be created to be used within each environment:
633
649
  # Example migration
634
650
  class AddSettings < ActiveRecord::Migration[7.0]
635
651
  def up
636
- create_table _env_table_name("settings"), force: true do |t|
652
+ # creates 'settings-pro' on production & 'settings-dev' on development
653
+ create_table "settings", force: true do |t|
637
654
  t.mapping :created_at, :date
638
655
  t.mapping :key, :integer do |m|
639
656
  m.primary_key = true
@@ -650,11 +667,63 @@ class AddSettings < ActiveRecord::Migration[7.0]
650
667
  end
651
668
 
652
669
  def down
653
- drop_table _env_table_name("settings")
670
+ drop_table "settings"
654
671
  end
655
672
  end
656
673
  ```
657
674
 
675
+ ### opting out with `decorate: false`
676
+
677
+ Provide `decorate: false` to address an index by its **literal** name:
678
+
679
+ ```ruby
680
+ # addresses 'settings-pro' - even from a '-dev' suffixed connection
681
+ drop_table "settings-pro", decorate: false
682
+ ```
683
+
684
+ This is required in two cases:
685
+
686
+ * the name is **already resolved** _(e.g. `Model.table_name`, or a name read back from `#tables`)_
687
+ * the base name itself **starts with the prefix** or **ends with the suffix** - `_env_table_name`
688
+ keeps itself idempotent through a `start_with?` / `end_with?` check and cannot tell such a name
689
+ apart from an already resolved one
690
+
691
+ The flag only ever applies to table (index) names - `alias`, `mapping`, `setting` & `meta` names are
692
+ never touched. Statements taking **two** names _(`clone_table`, `rename_table`, `reindex_table`,
693
+ `restore_table`, `backup_table`, `create_table copy_from:`)_ resolve both.
694
+
695
+ The **schema statements** _(`table_exists?`, `table_schema`, `table_mappings`, `table_settings`,
696
+ `columns`, ...)_ are deliberately **not** decorated - ActiveRecord and the schema dumper call them
697
+ with an already resolved index name.
698
+
699
+ The `_env_table_name`-method itself is still public, so existing migrations keep working - it is now
700
+ redundant, since it resolves the very same name the statement would resolve on its own.
701
+
702
+ ### global kill-switch
703
+
704
+ The default of a **not explicitly provided** `decorate:` argument is resolved from a global flag:
705
+
706
+ ```ruby
707
+ # e.g. in an initializer
708
+ ElasticsearchRecord.decorate_table_names = false
709
+ ```
710
+
711
+ Setting it to `false` restores the former, opt-in behaviour, where the decoration had to be applied
712
+ by hand through `_env_table_name`. A single statement can still opt in or out on its own, so
713
+ `decorate: true` keeps working while the flag is off:
714
+
715
+ ```ruby
716
+ ElasticsearchRecord.decorate_table_names = false
717
+
718
+ drop_table "settings" # => drops 'settings'
719
+ drop_table "settings", decorate: true # => drops 'settings-dev'
720
+ drop_table _env_table_name("settings") # => drops 'settings-dev' (the former syntax)
721
+ ```
722
+
723
+ The schema dumper follows the flag: while the decoration is globally disabled it dumps the **full**
724
+ index name with an explicit `decorate: false`, so a dumped schema stays correct even if the flag is
725
+ flipped back on before it is loaded.
726
+
658
727
  ## Docs
659
728
 
660
729
  [CHANGELOG](docs/CHANGELOG.md)
data/Rakefile CHANGED
File without changes
data/docs/CHANGELOG.md CHANGED
@@ -1,5 +1,49 @@
1
1
  # ElasticsearchRecord - CHANGELOG
2
2
 
3
+ ## [2.0.0] - 2026-08-10
4
+ * [add] `ElasticsearchRecord.decorate_table_names` _(default: `true`)_ as global kill-switch for the table name decoration - only provides the default for an omitted `decorate:`-argument, `#_env_table_name` stays unaffected
5
+ * [add] `TableStatements#truncate_table` raises an `ArgumentError` for AR-internal indices - the statement runs a `drop` & `create` and would wipe the migration state. `#drop_table` stays unguarded by design _(AR resets both tables through it)_
6
+ * [add] `QueryMethods#select` raises on metadata fields _(`_id`, `_score`, ...)_ - they are always returned anyway
7
+ * [add] `ElasticsearchRecord::Result` now resolves **tabular** responses _(`sql`: columns + rows, `esql`: columns + values)_, so `find_by_sql` _(String)_ & `find_by_esql` instantiate records - rows are zipped against the **response** columns
8
+ * [add] `CalculationMethods#matrix_stats` raises an `ArgumentError` for less than two columns - the metric quantifies the relationship **between** fields
9
+ * [add] `ResultMethods#meta_only!` to resolve the metadata nodes _(`_id`, `_score`, ...)_ of each hit without transferring the `_source`
10
+ * [add] `Query::COLUMNS_NONE` constant for the `'!'` projection marker - replaces the bare literal in `visit_Selects` & `meta_only!`
11
+ * [add] specs for `ElasticsearchRecord::Persistence`, `ModelApi`, `SchemaMigration`, `Querying::ClassMethods`, the `Relation` methods _(Core, Query, Calculation & Result)_, the `Elasticsearch::SchemaStatements`, `TableStatements` & `SchemaDumper`, every class of the `Elasticsearch::Type` namespace _(incl. its `TYPE_MAP` registration)_, `Arel::Collectors::ElasticsearchQuery` and all three `Arel::Visitors::Elasticsearch*` visitors - incl. the 1.8.1 "only ten migrations" and 1.8.2 nested-reset regressions and a `TestIndexWithAutoIncrement` support that builds a model against a real `auto_increment` schema _(destructive calls still run through `TestIndex` and its name guard)_. Behaviours pinned as-is:
12
+ * `#or` compiles into a **failed** query _(the visitor fails every `Arel::Nodes::Grouping`)_, and AR's blank-arg stripping silently drops `configure(key, nil)` _(only the Hash form removes a key)_
13
+ * an index **alias** is dumped as a mapping of the elasticsearch 'alias' field type, which makes the `t.alias` branch of the dumper unreachable
14
+ * opposed nil-handling of metas _(deleted)_ and settings _(kept through `:__force__`)_
15
+ * a failed `create` has no `FAILED_BODIES` entry and falls back to an empty body; a multi-column `order` keeps only the last sort
16
+ * `SchemaMigration#count` and `#delete_version` / `#delete_all_versions` cannot be served by elasticsearch
17
+ * `_update_record` / `_delete_record` always return `0` _(a document-API response carries no `total`)_, and an auto-incremented id is only written as document `_id`, never into the mapped primary-key field
18
+ * `meta_only!` **spawns** instead of mutating the receiver _(unlike the other bang methods)_ and pins the `COLUMNS_NONE` projection; `pit_results` pins its infinite-loop guard
19
+ * [ref] **BREAKING**: every table statement resolves its table (index) name through `#_env_table_name` **by default** - the `table_name_prefix` / `table_name_suffix` no longer have to be applied by hand, which silently wrote into another environment's index. A new `decorate:`-argument _(default: `true`)_ switches it off per call for already resolved names. Only TABLE names are decorated; schema statements stay undecorated
20
+ * [ref] `SchemaDumper#table` dumps the **base** name instead of a `_env_table_name(...)` call - if that name would not resolve back, the full name is dumped with an explicit `decorate: false`
21
+ * [ref] **BREAKING**: `#open_tables`, `#close_tables`, `#refresh_tables` & `#truncate_tables` no longer subtract the AR-internal indices _(an explicitly named index was silently dropped)_ - plain loops now, forwarding `decorate:` to their singular statement and returning an `Array` for every provided name
22
+ * [ref] `TableStatements` drops the stale `:rename_table` entry from `define_unsupported_method` - the real implementation overwrote it anyway
23
+ * [ref] `#restore_table` replaces its `open`-argument with `unblock:` _(default: true)_ - a restore clones and inherits the 'write'-block, so the table was open but **read-only**. `ModelApi#restore!` follows along
24
+ * [ref] `ResultMethods#pit_results` resolves through `ElasticsearchRecord::Result` and respects the current projection _(`ids_only` removed in favour of `meta_only!`)_
25
+ * [ref] `TestIndex` spec support to optionally create/drop a second index _(still guarded by the `ALLOWED` name check)_
26
+ * [fix] `#rename_table` to resolve both names **itself** - the `clear_data_source_cache!` and `cluster_health` calls in between were left with the undecorated name
27
+ * [fix] `#backup_table` to build the auto-generated target from the **already resolved** name _(the suffix landed behind the `-snapshot-` part)_
28
+ * [fix] `#_env_table_name` to cast prefix & suffix - an empty `table_name_prefix:` yml entry resolves to `nil` and raised a `TypeError`
29
+ * [fix] `Result#cast_values` to resolve values from the `_source` node, metadata fields from the document level
30
+ * [fix] `visit_Selects` to no longer provide metadata fields to the `_source`-filter _(never matched)_ - projects `_source: false` if only metadata is selected
31
+ * [fix] `Querying::ClassMethods#esql` & `#msearch` to dispatch through the public `exec_query` _(rails 7.1 made `internal_exec_query` private)_ - the `async:`-argument was dropped along with it
32
+ * [fix] `Querying::ClassMethods#find_by_sql` to reference the provided `sql` for `String` queries _(undefined `query_or_sql` raised a `NameError`)_
33
+ * [fix] `SchemaStatements#max_result_window` to resolve the **flat** setting key and cast it to an `Integer` _(always fell back to 10000 and broke the batch_size guards)_
34
+ * [fix] `SchemaStatements#primary_keys` to always return an `Array` _(the `_meta` branch returned a raw String)_
35
+ * [fix] `CalculationMethods#count` to apply the SQL `LIMIT n OFFSET m` semantic on the resolved total - `terminate_after` alone acts **per shard** and never fires on a count query. `#size` on an unloaded relation was affected as well
36
+ * [fix] `UpdateTableDefinition#change_mapping_attributes` to resolve the current mapping type with a **String** key _(fell back to `:object` / `:nested`, so elasticsearch rejected every mapping parameter)_
37
+ * [fix] `#restore_table` to no longer touch the backup after a `drop_backup: true` _(it no longer exists at that point)_
38
+ * [fix] `_insert_with_auto_increment` to write the **plain, integer** id into `_meta.auto_increment` - the block returns an Array of the `returning` values, which was stored as-is and raised on the NEXT insert. Now unwraps Array / Hash / plain and casts to `Integer`
39
+ * [fix] `ResultMethods#pit_delete` to no longer `select('_id')` _(rejected by the new metadata guard)_ - resolves the ids through `meta_only!`
40
+
41
+ ## [1.8.2] - 2024-11-26
42
+ * [fix] `ElasticsearchRecord::Relation::QueryMethods#build_query_clause` to raise an exception on `nil` assignments
43
+ * [fix] `Arel::Visitors::ElasticsearchBase#compile` to always reset temporary assignments _(causes missing assignments after a query-build-exception)_
44
+ * [fix] `Arel::Nodes::SelectAgg` to not merge nil-values
45
+ * [add] elasticsearch mapping type _(semantic_text)_
46
+
3
47
  ## [1.8.1] - 2024-05-07
4
48
  * [add] new elasticsearch mapping types _(percolator, geo, vector, texts, ...)_
5
49
  * [ref] `ElasticsearchRecord::Relation#limit` to detect `Float::INFINITY` to also set the **max_result_window**
@@ -12,6 +56,14 @@
12
56
  * [add] new repository branch `rails-7-1-stable` to support different rails version
13
57
  * [ref] gemspec to lock on rails 7.1
14
58
 
59
+ ## [1.7.5] - 2024-11-26 _(no gem release)_
60
+ * [ref] `ElasticsearchRecord::Relation::QueryMethods#build_query_clause` to raise an exception instead of building an empty `QueryClause`
61
+
62
+ ## [1.7.4] - 2024-11-25 _(no gem release)_
63
+ * [fix] `Arel::Visitors::ElasticsearchBase#compile` to always reset temporary assignments _(causes missing assignments after a query-build-exception)_
64
+ * [fix] `Arel::Nodes::SelectAgg` to not merge nil-values
65
+ * [fix] `ElasticsearchRecord::Relation::QueryMethods#build_query_clause` to prevent nil-Array assignment _(e.g. `[nil]` causes q query exception)_
66
+
15
67
  ## [1.7.3] - 2024-05-07 _(no gem release)_
16
68
  * [add] new elasticsearch mapping types _(percolator, geo, vector, texts, ...)_
17
69
  * [ref] `ElasticsearchRecord::Relation#limit` to detect `Float::INFINITY` to also set the **max_result_window**
File without changes
data/docs/LICENSE CHANGED
File without changes
@@ -35,7 +35,7 @@ DESC
35
35
  spec.add_dependency 'activerecord', '~> 7.1.0'
36
36
  spec.add_dependency 'elasticsearch', '>= 7.17'
37
37
 
38
- #spec.add_development_dependency 'coveralls_reborn', '~> 0.25'
38
+ spec.add_development_dependency 'coveralls_reborn', '~> 0.25'
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'
@@ -131,14 +131,29 @@ module ActiveRecord
131
131
 
132
132
  private
133
133
 
134
+ # gets called for all queries - a +ElasticsearchRecord::Query+ must be provided.
135
+ # @param [ElasticsearchRecord::Query] query
136
+ # @param [String (frozen),nil] name
137
+ # @param [Array] binds - not supported on the top-level and therefore ignored!
138
+ # @param [Boolean] prepare - used by the default AbstractAdapter - but not supported and therefore never ignored!
139
+ # @param [Boolean] async
140
+ # @return [ElasticsearchRecord::Result]
141
+ def internal_exec_query(query, name = "QUERY", binds = [], prepare: false, async: false)
142
+ build_result(
143
+ internal_execute(query, name, async: async),
144
+ columns: query.columns
145
+ )
146
+ end
147
+
134
148
  # Executes the query object in the context of this connection and returns the raw result
135
149
  # from the connection adapter.
136
150
  # @param [ElasticsearchRecord::Query] query
137
151
  # @param [String (frozen),nil] name
138
- # @param [Boolean] async (default: false)
152
+ # @param [Boolean] async (default: false) - NOT supported!
139
153
  # @param [Boolean] allow_retry (default: false)
154
+ # @param [Boolean] materialize_transactions (default: false) - NOT supported!
140
155
  # @return [ElasticsearchRecord::Result]
141
- def internal_execute(query, name = nil, async: false, allow_retry: false, materialize_transactions: nil)
156
+ def internal_execute(query, name = nil, async: false, allow_retry: false, materialize_transactions: false)
142
157
  # validate the query
143
158
  raise ActiveRecord::StatementInvalid, 'Unable to execute! Provided query is not a "ElasticsearchRecord::Query".' unless query.is_a?(ElasticsearchRecord::Query)
144
159
  raise ActiveRecord::StatementInvalid, 'Unable to execute! Provided query is invalid.' unless query.valid?
@@ -146,21 +161,7 @@ module ActiveRecord
146
161
  # checks for write query - raises an exception if connection is locked to readonly ...
147
162
  check_if_write_query(query)
148
163
 
149
- api(*query.gate, query.query_arguments, name, async: async)
150
- end
151
-
152
- # gets called for all queries - a +ElasticsearchRecord::Query+ must be provided.
153
- # @param [ElasticsearchRecord::Query] query
154
- # @param [String (frozen),nil] name
155
- # @param [Array] binds - not supported on the top-level and therefore ignored!
156
- # @param [Boolean] prepare - used by the default AbstractAdapter - but not supported and therefore never ignored!
157
- # @param [Boolean] async
158
- # @return [ElasticsearchRecord::Result]
159
- def internal_exec_query(query, name = "QUERY", binds = [], prepare: false, async: false)
160
- build_result(
161
- internal_execute(query, name, async: async),
162
- columns: query.columns
163
- )
164
+ api(query.gate, query.query_arguments, name, async: async, allow_retry: allow_retry, materialize_transactions: materialize_transactions)
164
165
  end
165
166
  end
166
167
  end
@@ -18,7 +18,7 @@ module ActiveRecord
18
18
  :integer_range, :float_range, :long_range, :double_range, :date_range, :ip_range,
19
19
  :ip, :version, :murmur3,
20
20
  :aggregate_metric_double, :histogram,
21
- :text, :match_only_text, :completion, :search_as_you_type, :token_count,
21
+ :text, :match_only_text, :completion, :search_as_you_type, :token_count, :semantic_text,
22
22
  :dense_vector, :sparse_vector, :rank_feature, :rank_features,
23
23
  :geo_point, :geo_shape, :point, :shape,
24
24
  :percolator
@@ -14,6 +14,12 @@ module ActiveRecord
14
14
  @aliases = HashWithIndifferentAccess.new
15
15
  @metas = HashWithIndifferentAccess.new
16
16
 
17
+ # HINT: Currently there is only one attribute, that cannot be assigned to any of the top hash kind, and also not opts:
18
+ # * dynamic
19
+ # This attribute must be assigned below the *mappings* node but as sibling to *properties*.
20
+ # This can only be done to create a special kind of options (@flags ???) and assign & fetch them within the required arel.
21
+ # Since this only setting can also be assigned to each individual mapping, there is currently no need to build this ...
22
+
17
23
  transform_settings!(settings) if settings.present?
18
24
  transform_mappings!(mappings) if mappings.present?
19
25
  transform_aliases!(aliases) if aliases.present?
@@ -10,7 +10,7 @@ module ActiveRecord
10
10
  include ActiveModel::Validations
11
11
 
12
12
  # exclude settings, that are provided through the API but are not part of the index-settings API
13
- IGNORE_NAMES = ['provided_name', 'creation_date', 'uuid', 'version','routing.allocation.initial_recovery','resize'].freeze
13
+ IGNORE_NAMES = ['provided_name', 'creation_date', 'uuid', 'version', 'routing.allocation.initial_recovery', 'resize'].freeze
14
14
 
15
15
  # available setting names
16
16
  # - see @ https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html#index-modules-settings
@@ -19,13 +19,12 @@ module ActiveRecord
19
19
  FINAL_NAMES = ['number_of_shards', 'routing_partition_size', 'soft_deletes.enabled'].freeze
20
20
 
21
21
  # static names can only be set during index creation or closed
22
- STATIC_NAMES = ['number_of_routing_shards', 'codec',
22
+ STATIC_NAMES = ['number_of_routing_shards', 'codec', 'mode',
23
23
  'soft_deletes.retention_lease.period',
24
24
  'load_fixed_bitset_filters_eagerly', 'shard.check_on_startup',
25
25
 
26
26
  # modules
27
- 'analysis', 'routing', 'unassigned', 'merge', 'similarity', 'search', 'store', 'translog',
28
- 'indexing_pressure'].freeze
27
+ 'analysis', 'routing', 'unassigned', 'merge', 'similarity', 'search', 'store', 'indexing_pressure'].freeze
29
28
 
30
29
  # dynamic names can always be changed
31
30
  DYNAMIC_NAMES = ['number_of_replicas', 'auto_expand_replicas', "search.idle.after", 'refresh_interval',
@@ -34,7 +33,10 @@ module ActiveRecord
34
33
  'max_refresh_listeners', 'analyze.max_token_count', 'highlight.max_analyzed_offset',
35
34
  'max_terms_count', 'max_regex_length', 'query.default_field', 'routing.allocation.enable',
36
35
  'routing.rebalance.enable', 'gc_deletes', 'default_pipeline', 'final_pipeline',
37
- 'hidden', 'blocks'].freeze
36
+ 'hidden', 'blocks',
37
+
38
+ # modules
39
+ 'translog'].freeze
38
40
 
39
41
  VALID_NAMES = (FINAL_NAMES + STATIC_NAMES + DYNAMIC_NAMES).freeze
40
42
 
@@ -66,7 +66,9 @@ module ActiveRecord
66
66
  raise ArgumentError, "you cannot change an unknown mapping '#{name}'" if current_mapping.blank?
67
67
 
68
68
  # build new mapping
69
- mapping = new_mapping_definition(name, current_mapping[:type], **options, &block)
69
+ # IMPORTANT: the received mapping is a String-keyed Hash - a symbol access would resolve
70
+ # nil here, which +TableMappingDefinition+ then falls back to :object / :nested
71
+ mapping = new_mapping_definition(name, current_mapping['type'], **options, &block)
70
72
  define! ChangeMappingDefinition, mapping
71
73
 
72
74
  # check if the mapping is assigned as new primary_key
@@ -45,6 +45,25 @@ module ActiveRecord
45
45
  false
46
46
  end
47
47
 
48
+ # returns true if the BASE name may be dumped, which keeps the dump loadable in another
49
+ # environment (with its own prefix / suffix): every table statement decorates its name on
50
+ # its own, so the base name may only be dumped if that decoration lands on exactly this
51
+ # index again. Otherwise the FULL name is dumped with a +decorate: false+.
52
+ #
53
+ # see @ ActiveRecord::ConnectionAdapters::Elasticsearch::TableStatements#_env_table_name
54
+ def _dumps_base_name?(table, base_name)
55
+ # without a prefix & suffix nothing is ever decorated - the plain name IS the index
56
+ return true unless _has_env_table_names?
57
+
58
+ # a globally disabled decoration would leave the base name untouched while loading
59
+ return false unless ElasticsearchRecord.decorate_table_names
60
+
61
+ # the base name must resolve BACK to the real index. It does not if the base name itself
62
+ # starts with the prefix (or ends with the suffix), and not if the dumper was built with a
63
+ # prefix / suffix that differs from the one of the connection.
64
+ @connection._env_table_name(base_name) == table
65
+ end
66
+
48
67
  def table(table, stream, nested_blocks: false, **)
49
68
  begin
50
69
  self.table_name = table
@@ -57,10 +76,12 @@ module ActiveRecord
57
76
 
58
77
  tbl.print " create_table"
59
78
 
60
- if _has_env_table_names?
61
- tbl.print " _env_table_name(#{remove_prefix_and_suffix(table).inspect})"
79
+ base_name = remove_prefix_and_suffix(table)
80
+
81
+ if _dumps_base_name?(table, base_name)
82
+ tbl.print " #{base_name.inspect}"
62
83
  else
63
- tbl.print " #{remove_prefix_and_suffix(table).inspect}"
84
+ tbl.print " #{table.inspect}, decorate: false"
64
85
  end
65
86
 
66
87
  tbl.print ", force: true do |t|"