Skip to content

Draft: Add ConfigurationSetting

John Mason requested to merge jm-ilm-db-settings into master

What does this MR do and why?

Adds ConfigurationSetting, which is an alternative to ApplicationSetting. It uses Single Table Inheritance for different sections (or namespaces) of settings and can be accessed similarly to key value storage.

Includes some handy bits for interacting with settings as well, for example:

Ability to interact with settings like a hash

[1] pry(main)> Search::CurationSetting[:curation_enabled] = true
  TRANSACTION (0.1ms)  BEGIN
  ConfigurationSetting Exists? (0.7ms)  SELECT 1 AS one FROM "configuration_settings" WHERE "configuration_settings"."setting" = 'curation_enabled' AND "configuration_settings"."id" != 9 AND "configuration_settings"."namespace" = 'Search::CurationSetting' LIMIT 1 
  Search::CurationSetting Update (0.3ms)  UPDATE "configuration_settings" SET "raw_value" = 't', "updated_at" = '2022-12-18 13:24:27.423919' WHERE "configuration_settings"."id" = 9
  TRANSACTION (0.1ms)  COMMIT
=> true
[2] pry(main)> Search::CurationSetting[:curation_enabled]
=> true

Read settings like a ruby object

[3] pry(main)> Search::CurationSetting.curation_enabled
=> true

Underlying DB table uses single table inheritance for namespacing

[5] pry(main)> Search::CurationSetting.last
  Search::CurationSetting Load (0.9ms)  SELECT "configuration_settings".* FROM "configuration_settings" WHERE "configuration_settings"."namespace" = 'Search::CurationSetting' ORDER BY "configuration_settings"."id" DESC LIMIT 1
=> #<Search::CurationSetting:0x000000010c9daf00
 id: 9,
 namespace: "Search::CurationSetting",
 setting: "curation_enabled",
 raw_value: "t",
 datatype: "bool",
 created_at: Sun, 18 Dec 2022 00:43:25.734946000 UTC +00:00,
 updated_at: Sun, 18 Dec 2022 13:29:26.163974000 UTC +00:00>

Validates only configured fields can be saved

Click to expand
[1] pry(main)> Search::CurationSetting[:not_configured] = "foo"
  Search::CurationSetting Load (0.5ms)  SELECT "configuration_settings".* FROM "configuration_settings" WHERE "configuration_settings"."namespace" = 'Search::CurationSetting' AND "configuration_settings"."setting" = 'not_configured' LIMIT 1
  Search::CurationSetting Load (0.1ms)  SELECT "configuration_settings".* FROM "configuration_settings" WHERE "configuration_settings"."namespace" = 'Search::CurationSetting' AND "configuration_settings"."setting" = 'not_configured' LIMIT 1
  TRANSACTION (0.1ms)  BEGIN /*application:console,db_config_name:main,console_hostname:Johns-MBP.lan,console_username:m,line:/app/models/concerns/key_value_store.rb:20:in `[]='*/
  ConfigurationSetting Exists? (0.1ms)  SELECT 1 AS one FROM "configuration_settings" WHERE "configuration_settings"."setting" = 'not_configured' AND "configuration_settings"."namespace" = 'Search::CurationSetting' LIMIT 1
  TRANSACTION (0.1ms)  ROLLBACK
ActiveRecord::RecordInvalid: Validation failed: Setting `not_configured` is not a configured field. Valid options are `["max_shard_size_gb", "max_docs_denominator", "min_docs_before_rollover", "curation_enabled"]`
from /Users/m/.asdf/installs/ruby/2.7.7/lib/ruby/gems/2.7.0/gems/activerecord-6.1.6.1/lib/active_record/validations.rb:80:in `raise_validation_error'

Data type validations for configured fields

Click to expand
[2] pry(main)> Search::CurationSetting[:curation_enabled] = "foo"
  TRANSACTION (0.2ms)  BEGIN /*application:console,db_config_name:main,console_hostname:Johns-MBP.lan,console_username:m,line:/app/models/concerns/key_value_store.rb:20:in `[]='*/
  ConfigurationSetting Exists? (0.3ms)  SELECT 1 AS one FROM "configuration_settings" WHERE "configuration_settings"."setting" = 'curation_enabled' AND "configuration_settings"."id" != 9 AND "configuration_settings"."namespace" = 'Search::CurationSetting' LIMIT 1 
  TRANSACTION (0.1ms)  ROLLBACK
ActiveRecord::RecordInvalid: Validation failed: Datatype should be a `bool`
from /Users/m/.asdf/installs/ruby/2.7.7/lib/ruby/gems/2.7.0/gems/activerecord-6.1.6.1/lib/active_record/validations.rb:80:in `raise_validation_error'

Ability to get all settings in a hash

Click to expand
[1] pry(main)> Search::CurationSetting.to_h
  Search::CurationSetting Load (0.6ms)  SELECT "configuration_settings".* FROM "configuration_settings" WHERE "configuration_settings"."namespace" = 'Search::CurationSetting'
=> {"curation_enabled"=>false,
 "max_docs_denominator"=>100,
 "max_shard_size_gb"=>1,
 "min_docs_before_rollover"=>100,
 "dry_run"=>true,
 "ignore_patterns"=>[/.*/],
 "include_patterns"=>[]}

Screenshots or screen recordings

Screenshots are required for UI changes, and strongly recommended for all other merge requests.

How to set up and validate locally

Numbered steps to set up and validate the change are strongly suggested.

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by John Mason

Merge request reports