Class: Smith::PersistenceAdapters::ActiveRecordStore
- Inherits:
-
Object
- Object
- Smith::PersistenceAdapters::ActiveRecordStore
- Includes:
- ActiveRecordExactStore
- Defined in:
- lib/smith/persistence_adapters/active_record_store.rb
Instance Attribute Summary
Attributes included from ActiveRecordExactStore
Instance Method Summary collapse
- #delete(key) ⇒ Object
- #fetch(key) ⇒ Object
-
#initialize(model:, key_column: :key, payload_column: :payload, version_column: :lock_version, identity: nil) ⇒ ActiveRecordStore
constructor
AR transient errors resolved via class-name guard so Smith doesn't require activerecord at load time.
-
#store(key, payload, ttl: nil) ⇒ Object
rubocop:disable Lint/UnusedMethodArgument.
-
#store_versioned(key, payload, expected_version:, ttl: nil) ⇒ Object
Optimistic locking via Rails' built-in optimistic locking on the
lock_versioncolumn. - #transaction_identity ⇒ Object
- #transaction_open? ⇒ Boolean
Methods included from ActiveRecordExactStore
Constructor Details
#initialize(model:, key_column: :key, payload_column: :payload, version_column: :lock_version, identity: nil) ⇒ ActiveRecordStore
AR transient errors resolved via class-name guard so Smith doesn't require activerecord at load time. Hosts that use this adapter already have activerecord in their dep tree.
11 12 13 14 15 16 17 |
# File 'lib/smith/persistence_adapters/active_record_store.rb', line 11 def initialize(model:, key_column: :key, payload_column: :payload, version_column: :lock_version, identity: nil) @model_source = model.is_a?(String) ? model.dup.freeze : model @key_column = normalize_column(key_column) @payload_column = normalize_column(payload_column) @version_column = normalize_column(version_column) @persistence_identity = identity.to_s.dup.freeze if identity end |
Instance Method Details
#delete(key) ⇒ Object
36 37 38 39 40 |
# File 'lib/smith/persistence_adapters/active_record_store.rb', line 36 def delete(key) Retry.with_retries(operation: :delete, transient: ActiveRecordConnectionErrors.classes) do model_class.where(@key_column => key).delete_all end end |
#fetch(key) ⇒ Object
30 31 32 33 34 |
# File 'lib/smith/persistence_adapters/active_record_store.rb', line 30 def fetch(key) Retry.with_retries(operation: :fetch, transient: ActiveRecordConnectionErrors.classes) do model_class.find_by(@key_column => key)&.public_send(@payload_column) end end |
#store(key, payload, ttl: nil) ⇒ Object
rubocop:disable Lint/UnusedMethodArgument
19 20 21 22 23 24 25 26 27 28 |
# File 'lib/smith/persistence_adapters/active_record_store.rb', line 19 def store(key, payload, ttl: nil) # rubocop:disable Lint/UnusedMethodArgument # TTL is deferred for ActiveRecordStore — would require an # `expires_at` column + a periodic sweeper job. Ignored here; # documented as a known limitation. Retry.with_retries(operation: :store, transient: ActiveRecordConnectionErrors.classes) do record = model_class.find_or_initialize_by(@key_column => key) record.public_send(:"#{@payload_column}=", payload) record.save! end end |
#store_versioned(key, payload, expected_version:, ttl: nil) ⇒ Object
Optimistic locking via Rails' built-in optimistic locking on the
lock_version column. Requires the AR model to have a
lock_version (or configured) integer column with default 0.
If absent, raises ArgumentError directing the host to migrate.
50 51 52 53 54 55 56 57 |
# File 'lib/smith/persistence_adapters/active_record_store.rb', line 50 def store_versioned(key, payload, expected_version:, ttl: nil) # rubocop:disable Lint/UnusedMethodArgument ensure_version_column! ensure_locking_configuration! write_versioned(key, payload, expected_version) rescue *ActiveRecordConnectionErrors.classes => e raise Smith::PersistenceIOError.new(operation: :store_versioned, cause: e) end |
#transaction_identity ⇒ Object
44 |
# File 'lib/smith/persistence_adapters/active_record_store.rb', line 44 def transaction_identity = model_class.respond_to?(:current_transaction) && model_class.current_transaction.uuid |
#transaction_open? ⇒ Boolean
42 |
# File 'lib/smith/persistence_adapters/active_record_store.rb', line 42 def transaction_open? = model_class.connection.transaction_open? |