Module: ActiveRecord::ConnectionAdapters::Elasticsearch::TableStatements

Extended by:
ActiveSupport::Concern
Included in:
ActiveRecord::ConnectionAdapters::ElasticsearchAdapter
Defined in:
lib/active_record/connection_adapters/elasticsearch/table_statements.rb

Overview

extend adapter with table-related statements

== Table name decoration

Every statement below resolves its provided table name(s) through +#_env_table_name+, which recaps them with the +table_name_prefix+ & +table_name_suffix+ of the connection config. This happens by default - so a migration only ever has to name the base table (index):

create_table 'settings' # => creates 'settings-dev' on a '-dev' suffixed connection

Provide +decorate: false+ to address an index by its literal name instead. This is required for names that are already resolved and for base names that happen to start with the prefix (or end with the suffix), which +#_env_table_name+ cannot tell apart:

drop_table 'settings-pro', decorate: false

The default of a NOT explicitly provided +decorate:+ argument is resolved from +ElasticsearchRecord.decorate_table_names+ - setting it to false restores the former, opt-in behaviour, where the decoration had to be applied by hand through +#_env_table_name+. A single statement can still opt in or out on its own.

PLEASE NOTE: the decoration only applies to table (index) names - +alias+, +mapping+, +setting+ & +meta+ names are never touched.

== Internal tables

+schema_migrations+ & +ar_internal_metadata+ carry the migration state of the connection. Only +#truncate_table+ guards them - it raises instead of wiping the state of a whole environment, which in Elasticsearch means a +drop+ & +create+ of the index.

Every other statement passes them through on purpose. +#drop_table+ especially MUST stay open: ActiveRecord resets both tables through it (+ActiveRecord::SchemaMigration#drop_table+ & +ActiveRecord::InternalMetadata#drop_table+ both call +connection.drop_table(table_name, if_exists: true)+), so a guard there would break that API without an escape hatch.

Instance Method Summary collapse

Instance Method Details

#_env_table_name(table_name) ⇒ String

recaps a provided +table_name+ with optionally configured +table_name_prefix+ & +table_name_suffix+. This depends on the connection config of the current environment.

PLEASE NOTE: the method is idempotent through a +start_with?+ / +end_with?+ check, so it can safely be called on an already resolved name. That check cannot tell a resolved name apart from a base name that legitimately starts with the prefix (or ends with the suffix) - use +decorate: false+ on the statement to address such an index literally.

Parameters:

  • table_name (String)

Returns:

  • (String)


521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 521

def _env_table_name(table_name)
  # ensure *table_name* is a string
  table_name = table_name.to_s

  # ensure *prefix* and *suffix* are strings
  prefix = table_name_prefix.to_s
  suffix = table_name_suffix.to_s

  # HINT: +"" creates a new +unfrozen+ string!
  name = +""
  name << prefix unless table_name.start_with?(prefix)
  name << table_name
  name << suffix unless table_name.end_with?(suffix)

  name
end

#add_alias(table_name, name, **options, &block) ⇒ Object

-- alias ---------------------------------------------------------------------------------------------------



499
500
501
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 499

def add_alias(table_name, name, **options, &block)
  _exec_change_table_with(:add_alias, table_name, name, **options, &block)
end

#add_mapping(table_name, name, type, **options, &block) ⇒ Object Also known as: add_column

-- mapping -------------------------------------------------------------------------------------------------

PLEASE NOTE: every statement below reaches +#change_table+ through +#_exec_change_table_with+, which forwards a provided +decorate:+ flag - only the TABLE name is ever decorated, never the mapping / meta / setting / alias name.



448
449
450
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 448

def add_mapping(table_name, name, type, **options, &block)
  _exec_change_table_with(:add_mapping, table_name, name, type, **options, &block)
end

#add_setting(table_name, name, value, **options, &block) ⇒ Object

-- setting -------------------------------------------------------------------------------------------------



485
486
487
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 485

def add_setting(table_name, name, value, **options, &block)
  _exec_change_table_with(:add_setting, table_name, name, value, **options, &block)
end

#backup_table(table_name, to: nil, close: true, decorate: nil) ⇒ String

creates a backup (snapshot) of the entire table (index) from provided +table_name+. The backup will be closed, to prevent read/write access. The +target_name+ will be auto-generated, if not provided.

Examples:

backup_table('screenshots', to: 'screenshots-backup-v1')

Parameters:

  • table_name (String)
  • to (String) (defaults to: nil)
    • target_name
  • close (Boolean) (defaults to: true)
    • closes backup after creation (default: true)
  • decorate (Boolean) (defaults to: nil)
    • resolve both table names with the configured prefix & suffix (default: +ElasticsearchRecord.decorate_table_names+)

Returns:

  • (String)

    backup_name

Raises:

  • (ArgumentError)


262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 262

def backup_table(table_name, to: nil, close: true, decorate: nil)
  table_name = _decorate_table_name(table_name, decorate: decorate)

  # IMPORTANT: the auto-generated name is built from the ALREADY resolved +table_name+, so
  # it stays within the current environment without being decorated a second time (which
  # would append the suffix BEHIND the '-snapshot-' part).
  to = to.nil? ? "#{table_name}-snapshot-#{Time.now.strftime('%s%3N')}" : _decorate_table_name(to, decorate: decorate)

  raise ArgumentError, "unable to backup '#{table_name}' to already existing target '#{to}'!" if table_exists?(to)

  clone_table(table_name, to, decorate: false)
  close_table(to, decorate: false) if close

  to
end

#block_table(table_name, block_name = :write, decorate: nil) ⇒ Boolean

blocks access to the provided table (index) and +block+ name.

Parameters:

  • table_name (String)
  • block_name (Symbol) (defaults to: :write)

    The block to add (one of :read, :write, :read_only or :metadata)

  • decorate (Boolean) (defaults to: nil)
    • resolve the table name with the configured prefix & suffix (default: +ElasticsearchRecord.decorate_table_names+)

Returns:

  • (Boolean)

    acknowledged status



200
201
202
203
204
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 200

def block_table(table_name, block_name = :write, decorate: nil)
  table_name = _decorate_table_name(table_name, decorate: decorate)

  api('indices.add_block', { index: table_name, block: block_name }, "BLOCK #{block_name.to_s.upcase} TABLE").dig('acknowledged')
end

#change_alias(table_name, name, **options, &block) ⇒ Object



503
504
505
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 503

def change_alias(table_name, name, **options, &block)
  _exec_change_table_with(:change_alias, table_name, name, **options, &block)
end

#change_mapping(table_name, name, type, **options, &block) ⇒ Object Also known as: change_column

will fail unless +recreate:true+ option was provided



455
456
457
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 455

def change_mapping(table_name, name, type, **options, &block)
  _exec_change_table_with(:change_mapping, table_name, name, type, **options, &block)
end

#change_mapping_attributes(table_name, name, **options, &block) ⇒ Object



471
472
473
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 471

def change_mapping_attributes(table_name, name, **options, &block)
  _exec_change_table_with(:change_mapping_attributes, table_name, name, **options, &block)
end

#change_mapping_meta(table_name, name, **options) ⇒ Object



467
468
469
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 467

def change_mapping_meta(table_name, name, **options)
  _exec_change_table_with(:change_mapping_meta, table_name, name, **options)
end

#change_meta(table_name, name, value, **options) ⇒ Object



475
476
477
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 475

def change_meta(table_name, name, value, **options)
  _exec_change_table_with(:change_meta, table_name, name, value, **options)
end

#change_setting(table_name, name, value, **options, &block) ⇒ Object



489
490
491
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 489

def change_setting(table_name, name, value, **options, &block)
  _exec_change_table_with(:change_setting, table_name, name, value, **options, &block)
end

#change_table(table_name, if_exists: false, recreate: false, decorate: nil, **options, &block) ⇒ Object

A block for changing mappings, settings & aliases in +table+.

# change_table() yields a ChangeTableDefinition instance change_table(:suppliers) do |t| t.mapping :name, :string # Other column alterations here end

Parameters:

  • table_name (String)
  • if_exists (Boolean) (defaults to: false)
    • skip if the index does not exist (default: false)
  • recreate (Boolean) (defaults to: false)
    • recreate the index from a copy of the current one (default: false)
  • decorate (Boolean) (defaults to: nil)
    • resolve the table name with the configured prefix & suffix (default: +ElasticsearchRecord.decorate_table_names+)
  • options (Hash)


406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 406

def change_table(table_name, if_exists: false, recreate: false, decorate: nil, **options, &block)
  table_name = _decorate_table_name(table_name, decorate: decorate)

  return if if_exists && !table_exists?(table_name)

  # check 'recreate' flag.
  # If true, a 'create_table' with copy of the current will be executed
  return create_table(table_name, force: true, copy_from: table_name, decorate: false, **options, &block) if recreate

  # build new update definition
  definition = update_table_definition(table_name, self, **options)

  # yield optional block
  if block_given?
    definition.assign do |d|
      yield d
    end
  end

  # execute definition query(ies)
  definition.exec!
end

#clone_table(table_name, target_name, decorate: nil, **options) ⇒ Boolean

clones an entire table (index) with its docs to the provided +target_name+. During cloning, the table will be automatically 'write'-blocked.

Parameters:

  • table_name (String)
  • target_name (String)
  • decorate (Boolean) (defaults to: nil)
    • resolve both table names with the configured prefix & suffix (default: +ElasticsearchRecord.decorate_table_names+)
  • options (Hash)

Returns:

  • (Boolean)

    acknowledged status



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 232

def clone_table(table_name, target_name, decorate: nil, **options)
  table_name  = _decorate_table_name(table_name, decorate: decorate)
  target_name = _decorate_table_name(target_name, decorate: decorate)

  # create new definition
  definition = clone_table_definition(table_name, target_name, **extract_table_options!(options))

  # yield optional block
  if block_given?
    definition.assign do |d|
      yield d
    end
  end

  # execute definition query(ies)
  definition.exec!
end

#close_table(table_name, decorate: nil) ⇒ Boolean

Closes an index.

Parameters:

  • table_name (String)
  • decorate (Boolean) (defaults to: nil)
    • resolve the table name with the configured prefix & suffix (default: +ElasticsearchRecord.decorate_table_names+)

Returns:

  • (Boolean)

    acknowledged status



93
94
95
96
97
98
99
100
101
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 93

def close_table(table_name, decorate: nil)
  table_name = _decorate_table_name(table_name, decorate: decorate)

  # IMPORTANT: Clears out internal caches for the *table_name*
  schema_cache.clear_data_source_cache!(table_name)

  # call the API
  api('indices.close', { index: table_name }, 'CLOSE TABLE').dig('acknowledged')
end

#close_tables(*table_names, decorate: nil) ⇒ Array

Closes indices by provided names.

Parameters:

  • table_names (Array)
  • decorate (Boolean) (defaults to: nil)
    • resolve the table names with the configured prefix & suffix (default: +ElasticsearchRecord.decorate_table_names+)

Returns:

  • (Array)

    acknowledged status for each provided table



107
108
109
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 107

def close_tables(*table_names, decorate: nil)
  table_names.map { |table_name| close_table(table_name, decorate: decorate) }
end

#create_table(table_name, force: false, copy_from: nil, if_not_exists: false, decorate: nil, **options) ⇒ Boolean

creates a new table (index). [:force] Set to +true+ to drop an existing index Defaults to false. [:copy_from] Set to an existing index, to copy it's schema. [:if_not_exists] Set to +true+ to skip creation if index already exists. Defaults to false.

Parameters:

  • table_name (String)
  • force (Boolean) (defaults to: false)
    • force a drop on the existing index (default: false)
  • copy_from (nil, String) (defaults to: nil)
    • copy schema from existing index
  • if_not_exists (Boolean) (defaults to: false)
    • skip the creation if the index already exists (default: false)
  • decorate (Boolean) (defaults to: nil)
    • resolve the table name (and +copy_from+) with the configured prefix & suffix (default: +ElasticsearchRecord.decorate_table_names+)
  • options (Hash)

Returns:

  • (Boolean)

    acknowledged status



363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 363

def create_table(table_name, force: false, copy_from: nil, if_not_exists: false, decorate: nil, **options)
  table_name = _decorate_table_name(table_name, decorate: decorate)

  return if if_not_exists && table_exists?(table_name)

  # copy schema from existing table
  options.merge!(table_schema(_decorate_table_name(copy_from, decorate: decorate))) if copy_from

  # create new definition
  definition = create_table_definition(table_name, **extract_table_options!(options))

  # yield optional block
  if block_given?
    definition.assign do |d|
      yield d
    end
  end

  # force drop existing table
  if force
    drop_table(table_name, if_exists: true, decorate: false)
  else
    # IMPORTANT: Clears out internal caches
    schema_cache.clear_data_source_cache!(table_name)
  end

  # execute definition query(ies)
  definition.exec!
end

#drop_table(table_name, if_exists: false, decorate: nil) ⇒ Boolean

drops an index [:if_exists] Set to +true+ to only drop the table if it exists. Defaults to false.

PLEASE NOTE: unlike +#truncate_table+ this does NOT guard the AR-internal indices - ActiveRecord resets them through exactly this statement (+ActiveRecord::SchemaMigration#drop_table+ & +ActiveRecord::InternalMetadata#drop_table+ both call +connection.drop_table(table_name, if_exists: true)+).

Parameters:

  • table_name (String)
  • if_exists (Boolean) (defaults to: false)
  • decorate (Boolean) (defaults to: nil)
    • resolve the table name with the configured prefix & suffix (default: +ElasticsearchRecord.decorate_table_names+)

Returns:

  • (Boolean)

    acknowledged status



185
186
187
188
189
190
191
192
193
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 185

def drop_table(table_name, if_exists: false, decorate: nil, **)
  table_name = _decorate_table_name(table_name, decorate: decorate)

  # IMPORTANT: Clears out internal caches for the *table_name*
  schema_cache.clear_data_source_cache!(table_name)

  # call the API
  api('indices.delete', { index: table_name, ignore: (if_exists ? 404 : nil) }, 'DROP TABLE').dig('acknowledged')
end

#open_table(table_name, decorate: nil) ⇒ Boolean

Opens a closed index.

Parameters:

  • table_name (String)
  • decorate (Boolean) (defaults to: nil)
    • resolve the table name with the configured prefix & suffix (default: +ElasticsearchRecord.decorate_table_names+)

Returns:

  • (Boolean)

    acknowledged status



71
72
73
74
75
76
77
78
79
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 71

def open_table(table_name, decorate: nil)
  table_name = _decorate_table_name(table_name, decorate: decorate)

  # IMPORTANT: Clears out internal caches for the *table_name*
  schema_cache.clear_data_source_cache!(table_name)

  # call the API
  api('indices.open', { index: table_name }, 'OPEN TABLE').dig('acknowledged')
end

#open_tables(*table_names, decorate: nil) ⇒ Array

Opens closed indices.

Parameters:

  • table_names (Array)
  • decorate (Boolean) (defaults to: nil)
    • resolve the table names with the configured prefix & suffix (default: +ElasticsearchRecord.decorate_table_names+)

Returns:

  • (Array)

    acknowledged status for each provided table



85
86
87
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 85

def open_tables(*table_names, decorate: nil)
  table_names.map { |table_name| open_table(table_name, decorate: decorate) }
end

#refresh_table(table_name, decorate: nil) ⇒ Boolean

refresh an index. A refresh makes recent operations performed on one or more indices available for search. raises an exception if the index could not be found.

Parameters:

  • table_name (String)
  • decorate (Boolean) (defaults to: nil)
    • resolve the table name with the configured prefix & suffix (default: +ElasticsearchRecord.decorate_table_names+)

Returns:

  • (Boolean)

    result state (returns false if refreshing failed)



118
119
120
121
122
123
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 118

def refresh_table(table_name, decorate: nil)
  table_name = _decorate_table_name(table_name, decorate: decorate)

  # call the API
  api('indices.refresh', { index: table_name }, 'REFRESH TABLE').dig('_shards', 'failed') == 0
end

#refresh_tables(*table_names, decorate: nil) ⇒ Array

refresh indices by provided names.

Parameters:

  • table_names (Array)
  • decorate (Boolean) (defaults to: nil)
    • resolve the table names with the configured prefix & suffix (default: +ElasticsearchRecord.decorate_table_names+)

Returns:

  • (Array)

    result state (returns false if refreshing failed)



129
130
131
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 129

def refresh_tables(*table_names, decorate: nil)
  table_names.map { |table_name| refresh_table(table_name, decorate: decorate) }
end

#reindex_table(table_name, target_name, decorate: nil, **options) ⇒ Hash

Copies documents from a source to a destination.

Parameters:

  • table_name (String)
  • target_name (String)
  • decorate (Boolean) (defaults to: nil)
    • resolve both table names with the configured prefix & suffix (default: +ElasticsearchRecord.decorate_table_names+)
  • options (Hash)

Returns:

  • (Hash)

    reindex stats



435
436
437
438
439
440
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 435

def reindex_table(table_name, target_name, decorate: nil, **options)
  table_name  = _decorate_table_name(table_name, decorate: decorate)
  target_name = _decorate_table_name(target_name, decorate: decorate)

  api(:reindex, { body: { source: { index: table_name }, dest: { index: target_name } } }.merge(options), 'REINDEX TABLE')
end

#remove_alias(table_name, name, **options, &block) ⇒ Object



507
508
509
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 507

def remove_alias(table_name, name, **options, &block)
  _exec_change_table_with(:remove_alias, table_name, name, **options, &block)
end

#remove_mapping(table_name, name, **options) ⇒ Object Also known as: remove_column



461
462
463
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 461

def remove_mapping(table_name, name, **options)
  _exec_change_table_with(:remove_mapping, table_name, name, **options)
end

#remove_meta(table_name, name, **options) ⇒ Object



479
480
481
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 479

def remove_meta(table_name, name, **options)
  _exec_change_table_with(:remove_meta, table_name, name, **options)
end

#remove_setting(table_name, name, **options, &block) ⇒ Object



493
494
495
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 493

def remove_setting(table_name, name, **options, &block)
  _exec_change_table_with(:remove_setting, table_name, name, **options, &block)
end

#rename_table(table_name, target_name, timeout: '1m', decorate: nil, **options) ⇒ Object

renames a table (index) by executing multiple steps:

  • clone table
  • wait for 'green' state
  • drop old table The +timeout+ option will define how long to wait for the 'green' state.

Parameters:

  • table_name (String)
  • target_name (String)
  • timeout (String (frozen)) (defaults to: '1m')

    (default: '1m')

  • decorate (Boolean) (defaults to: nil)
    • resolve both table names with the configured prefix & suffix (default: +ElasticsearchRecord.decorate_table_names+)
  • options (Hash)
    • additional 'clone' options (like settings, alias, ...)


332
333
334
335
336
337
338
339
340
341
342
343
344
345
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 332

def rename_table(table_name, target_name, timeout: '1m', decorate: nil, **options)
  # IMPORTANT: both names must be resolved HERE and not only forwarded to the statements
  # below - the +schema_cache+ and the +cluster_health+ call in between address the index
  # directly and would otherwise miss the decorated one
  table_name  = _decorate_table_name(table_name, decorate: decorate)
  target_name = _decorate_table_name(target_name, decorate: decorate)

  # IMPORTANT: Clears out internal caches
  schema_cache.clear_data_source_cache!(table_name)

  clone_table(table_name, target_name, decorate: false, **options)
  cluster_health(index: target_name, wait_for_status: 'green', timeout: timeout)
  drop_table(table_name, decorate: false)
end

#restore_table(table_name, from:, timeout: '1m', unblock: true, drop_backup: false, decorate: nil) ⇒ nil

restores a entire table (index) from provided +target_name+. The +table_name+ will be dropped, if exists. The +from+ will persist, if not provided +drop_backup:true+.

IMPORTANT: both strategies restore through a +clone+, which inherits the settings of its source - including the 'write'-block that is required to clone at all. The restored table is therefore open but read-only until that block is released, which is what the +unblock+ flag is for. (there is no +open+ flag: a clone is always created open - even from a closed source) see @ ActiveRecord::ConnectionAdapters::Elasticsearch::CloneTableDefinition#_before_exec

Examples:

restore_table('screenshots', from: 'screenshots-backup-v1')
# keep the restored table read-only
restore_table('screenshots', from: 'screenshots-backup-v1', unblock: false)

Parameters:

  • table_name (String)
  • from (String)
  • timeout (String (frozen)) (defaults to: '1m')
    • renaming timout (default: '1m')
  • unblock (Boolean) (defaults to: true)
    • releases the inherited 'write'-block on the restored table (default: true)
  • drop_backup (Boolean) (defaults to: false)
    • renames instead of clones, which removes the +from+ (default: false)
  • decorate (Boolean) (defaults to: nil)
    • resolve both table names with the configured prefix & suffix (default: +ElasticsearchRecord.decorate_table_names+)

Returns:

  • (nil)
    • every failing step raises instead

Raises:

  • (ArgumentError)


303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 303

def restore_table(table_name, from:, timeout: '1m', unblock: true, drop_backup: false, decorate: nil)
  table_name = _decorate_table_name(table_name, decorate: decorate)
  from       = _decorate_table_name(from, decorate: decorate)

  raise ArgumentError, "unable to restore from missing target '#{from}'!" unless table_exists?(from)
  drop_table(table_name, if_exists: true, decorate: false)

  # choose best strategy
  if drop_backup
    rename_table(from, table_name, timeout: timeout, decorate: false)
  else
    clone_table(from, table_name, decorate: false)
  end

  # release the inherited 'write'-block, if provided
  unblock_table(table_name, :write, decorate: false) if unblock
end

#truncate_table(table_name, decorate: nil) ⇒ Boolean Also known as: truncate

truncates index by provided name. HINT: Elasticsearch does not have a +truncate+ concept:

  • so we have to store the current index' schema
  • drop the index
  • and create it again

PLEASE NOTE: an AR-internal index (+schema_migrations+ / +ar_internal_metadata+) raises instead - a truncate would drop the migration state of the whole environment. The check runs on the ALREADY resolved name and +#_internal_table_names+ holds both forms, so neither a base nor a resolved name slips through.

Parameters:

  • table_name (String)
  • decorate (Boolean) (defaults to: nil)
    • resolve the table name with the configured prefix & suffix (default: +ElasticsearchRecord.decorate_table_names+)

Returns:

  • (Boolean)

    acknowledged status

Raises:

  • (ArgumentError)

    if the resolved name is an AR-internal index



148
149
150
151
152
153
154
155
156
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 148

def truncate_table(table_name, decorate: nil)
  table_name = _decorate_table_name(table_name, decorate: decorate)

  # ensure the provided *table_name* is NOT an internal table_name
  raise ArgumentError, "Cannot truncate internal table '#{table_name}'!" if _internal_table_names.include?(table_name)

  # force: automatically drops an existing index
  create_table(table_name, force: true, decorate: false, **table_schema(table_name))
end

#truncate_tables(*table_names, decorate: nil) ⇒ Array

truncate indices by provided names. PLEASE NOTE: a single AR-internal index raises through +#truncate_table+ and aborts the whole call - the tables before it are already truncated at that point.

Parameters:

  • table_names (Array)
  • decorate (Boolean) (defaults to: nil)
    • resolve the table names with the configured prefix & suffix (default: +ElasticsearchRecord.decorate_table_names+)

Returns:

  • (Array)

    acknowledged status for each provided table

Raises:

  • (ArgumentError)

    if one of the resolved names is an AR-internal index



167
168
169
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 167

def truncate_tables(*table_names, decorate: nil)
  table_names.map { |table_name| truncate_table(table_name, decorate: decorate) }
end

#unblock_table(table_name, block_name = nil, decorate: nil) ⇒ Boolean

unblocks access to the provided table (index) and +block+ name. provide a nil-value to unblock all blocks, otherwise provide the blocked name.

Parameters:

  • table_name (String)
  • block_name (Symbol) (defaults to: nil)

    The block to add (one of :read, :write, :read_only or :metadata)

  • decorate (Boolean) (defaults to: nil)
    • resolve the table name with the configured prefix & suffix (default: +ElasticsearchRecord.decorate_table_names+)

Returns:

  • (Boolean)

    acknowledged status



212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/active_record/connection_adapters/elasticsearch/table_statements.rb', line 212

def unblock_table(table_name, block_name = nil, decorate: nil)
  if block_name.nil?
    change_table(table_name, decorate: decorate) do |t|
      t.change_setting('index.blocks.read', nil)
      t.change_setting('index.blocks.write', nil)
      t.change_setting('index.blocks.read_only', nil)
      t.change_setting('index.blocks.metadata', nil)
    end
  else
    change_setting(table_name, "index.blocks.#{block_name}", nil, decorate: decorate)
  end
end