Module: Familia::Horreum::DatabaseCommands
- Included in:
- Familia::Horreum
- Defined in:
- lib/familia/horreum/database_commands.rb
Overview
DatabaseCommands - Instance-level methods for horreum models that call Database commands
NOTE: There is no hgetall for Horreum. This is because Horreum is a single hash in Database that we aren't meant to have be working on in memory for more than, making changes -> committing. To emphasize this, instead of "refreshing" the object with hgetall, just load the object again.
Instance Method Summary collapse
-
#current_expiration ⇒ Integer
Retrieves the remaining time to live (TTL) for the object's dbkey.
-
#data_type ⇒ String
Returns the Redis data type of the key.
-
#decr(field) ⇒ Integer
(also: #decrement)
Decrements the integer value of a hash field by 1.
-
#decrby(field, decrement) ⇒ Integer
(also: #decrementby)
Decrements the integer value of a hash field by the given amount.
-
#delete! ⇒ Boolean
(also: #clear)
Deletes the dbkey for this horreum :object.
-
#discard ⇒ String
Flushes all previously queued commands in a transaction and all watched keys.
-
#echo(*args) ⇒ String
Echoes a message through the Redis connection.
-
#exists?(check_size: true) ⇒ Boolean
Checks if the calling object's key exists in the database.
-
#expire(default_expiration = nil) ⇒ Integer
Sets a timeout on key.
-
#field_count ⇒ Integer
(also: #size, #length)
Returns the number of fields in the main object hash.
-
#hget(field) ⇒ String?
Gets the value of a hash field.
-
#hgetall ⇒ Hash
(also: #all)
Returns all fields and values in the hash.
-
#hkeys ⇒ Array<String>
Returns all field names in the hash.
-
#hmset(hsh = {}) ⇒ String
Sets multiple hash fields to multiple values.
-
#hset(field, value) ⇒ Integer
Sets the value of a hash field.
-
#hsetnx(field, value) ⇒ Integer
Sets field in the hash stored at key to value, only if field does not yet exist.
-
#hstrlen(field) ⇒ Integer
(also: #hstrlength)
Returns the string length of the value associated with field in the hash.
-
#hvals ⇒ Array<String>
Returns all values in the hash.
-
#incr(field) ⇒ Integer
(also: #increment)
Increments the integer value of a hash field by 1.
-
#incrby(field, increment) ⇒ Integer
(also: #incrementby)
Increments the integer value of a hash field by the given amount.
-
#incrbyfloat(field, increment) ⇒ Float
(also: #incrementbyfloat)
Increments the float value of a hash field by the given amount.
-
#key?(field) ⇒ Boolean
(also: #has_key?)
Determines if a hash field exists.
-
#move(logical_database) ⇒ Boolean
Moves the object's key to a different logical database.
-
#remove_field(field) ⇒ Integer
(also: #remove)
Removes a field from the hash stored at the dbkey.
-
#unwatch ⇒ String
Flushes all the previously watched keys for a transaction.
-
#watch ⇒ String
Watches the key for changes during a MULTI/EXEC transaction.
Instance Method Details
#current_expiration ⇒ Integer
Retrieves the remaining time to live (TTL) for the object's dbkey.
This method accesses the objects Database client to obtain the TTL of dbkey.
If debugging is enabled, it logs the TTL retrieval operation using Familia.trace.
90 91 92 93 |
# File 'lib/familia/horreum/database_commands.rb', line 90 def current_expiration Familia.trace :CURRENT_EXPIRATION, nil, self.class.uri if Familia.debug? dbclient.ttl dbkey end |
#data_type ⇒ String
Returns the Redis data type of the key.
108 109 110 111 |
# File 'lib/familia/horreum/database_commands.rb', line 108 def data_type Familia.trace :DATATYPE, nil, self.class.uri if Familia.debug? dbclient.type dbkey(suffix) end |
#decr(field) ⇒ Integer Also known as: decrement
Decrements the integer value of a hash field by 1.
224 225 226 |
# File 'lib/familia/horreum/database_commands.rb', line 224 def decr(field) dbclient.hdecr field end |
#decrby(field, decrement) ⇒ Integer Also known as: decrementby
Decrements the integer value of a hash field by the given amount.
215 216 217 |
# File 'lib/familia/horreum/database_commands.rb', line 215 def decrby(field, decrement) dbclient.decrby dbkey(suffix), field, decrement end |
#delete! ⇒ Boolean Also known as: clear
Deletes the dbkey for this horreum :object.
It does not delete the related fields keys. See destroy!
252 253 254 255 256 257 |
# File 'lib/familia/horreum/database_commands.rb', line 252 def delete! Familia.trace :DELETE!, nil, self.class.uri if Familia.debug? # Delete the main object key dbclient.del dbkey end |
#discard ⇒ String
Flushes all previously queued commands in a transaction and all watched keys
NOTE: This command operates on the connection itself; not a specific key
307 |
# File 'lib/familia/horreum/database_commands.rb', line 307 def discard(...) = dbclient.discard(...) |
#echo(*args) ⇒ String
Echoes a message through the Redis connection.
313 314 315 |
# File 'lib/familia/horreum/database_commands.rb', line 313 def echo(*args) dbclient.echo "[#{self.class}] #{args.join(' ')}" end |
#exists?(check_size: true) ⇒ Boolean
The default behavior maintains backward compatibility by treating empty hashes
as non-existent. Use check_size: false for pure key existence checking.
Checks if the calling object's key exists in the database.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/familia/horreum/database_commands.rb', line 45 def exists?(check_size: true) key_exists = self.class.exists?(identifier) return key_exists unless check_size # Handle Redis::Future in transactions - skip size check if key_exists.is_a?(Redis::Future) return key_exists end current_size = size # Handle Redis::Future from size call too if current_size.is_a?(Redis::Future) return current_size end key_exists && !current_size.zero? end |
#expire(default_expiration = nil) ⇒ Integer
Sets a timeout on key. After the timeout has expired, the key will automatically be deleted. Returns 1 if the timeout was set, 0 if key does not exist or the timeout could not be set.
77 78 79 80 81 |
# File 'lib/familia/horreum/database_commands.rb', line 77 def expire(default_expiration = nil) default_expiration ||= self.class.default_expiration Familia.trace :EXPIRE, nil, default_expiration if Familia.debug? dbclient.expire dbkey, default_expiration.to_i end |
#field_count ⇒ Integer Also known as: size, length
Returns the number of fields in the main object hash
65 66 67 |
# File 'lib/familia/horreum/database_commands.rb', line 65 def field_count dbclient.hlen dbkey end |
#hget(field) ⇒ String?
Gets the value of a hash field.
127 128 129 130 |
# File 'lib/familia/horreum/database_commands.rb', line 127 def hget(field) Familia.trace :HGET, nil, field if Familia.debug? dbclient.hget dbkey(suffix), field end |
#hgetall ⇒ Hash Also known as: all
For parity with DataType#hgetall
Returns all fields and values in the hash.
117 118 119 120 |
# File 'lib/familia/horreum/database_commands.rb', line 117 def hgetall Familia.trace :HGETALL, nil, self.class.uri if Familia.debug? dbclient.hgetall dbkey(suffix) end |
#hkeys ⇒ Array<String>
Returns all field names in the hash.
169 170 171 172 |
# File 'lib/familia/horreum/database_commands.rb', line 169 def hkeys Familia.trace :HKEYS, nil, self.class.uri if Familia.debug? dbclient.hkeys dbkey(suffix) end |
#hmset(hsh = {}) ⇒ String
Sets multiple hash fields to multiple values.
160 161 162 163 164 |
# File 'lib/familia/horreum/database_commands.rb', line 160 def hmset(hsh = {}) hsh ||= to_h_for_storage Familia.trace :HMSET, nil, hsh if Familia.debug? dbclient.hmset dbkey(suffix), hsh end |
#hset(field, value) ⇒ Integer
Sets the value of a hash field.
138 139 140 141 |
# File 'lib/familia/horreum/database_commands.rb', line 138 def hset(field, value) Familia.trace :HSET, nil, field if Familia.debug? dbclient.hset dbkey, field, value end |
#hsetnx(field, value) ⇒ Integer
Sets field in the hash stored at key to value, only if field does not yet exist. If key does not exist, a new key holding a hash is created. If field already exists, this operation has no effect.
151 152 153 154 |
# File 'lib/familia/horreum/database_commands.rb', line 151 def hsetnx(field, value) Familia.trace :HSETNX, nil, field if Familia.debug? dbclient.hsetnx dbkey, field, value end |
#hstrlen(field) ⇒ Integer Also known as: hstrlength
Returns the string length of the value associated with field in the hash.
233 234 235 |
# File 'lib/familia/horreum/database_commands.rb', line 233 def hstrlen(field) dbclient.hstrlen dbkey(suffix), field end |
#hvals ⇒ Array<String>
Returns all values in the hash.
177 178 179 |
# File 'lib/familia/horreum/database_commands.rb', line 177 def hvals dbclient.hvals dbkey(suffix) end |
#incr(field) ⇒ Integer Also known as: increment
Increments the integer value of a hash field by 1.
185 186 187 |
# File 'lib/familia/horreum/database_commands.rb', line 185 def incr(field) dbclient.hincrby dbkey(suffix), field, 1 end |
#incrby(field, increment) ⇒ Integer Also known as: incrementby
Increments the integer value of a hash field by the given amount.
195 196 197 |
# File 'lib/familia/horreum/database_commands.rb', line 195 def incrby(field, increment) dbclient.hincrby dbkey(suffix), field, increment end |
#incrbyfloat(field, increment) ⇒ Float Also known as: incrementbyfloat
Increments the float value of a hash field by the given amount.
205 206 207 |
# File 'lib/familia/horreum/database_commands.rb', line 205 def incrbyfloat(field, increment) dbclient.hincrbyfloat dbkey(suffix), field, increment end |
#key?(field) ⇒ Boolean Also known as: has_key?
Determines if a hash field exists.
242 243 244 |
# File 'lib/familia/horreum/database_commands.rb', line 242 def key?(field) dbclient.hexists dbkey(suffix), field end |
#move(logical_database) ⇒ Boolean
Moves the object's key to a different logical database.
25 26 27 |
# File 'lib/familia/horreum/database_commands.rb', line 25 def move(logical_database) dbclient.move dbkey, logical_database end |
#remove_field(field) ⇒ Integer Also known as: remove
Removes a field from the hash stored at the dbkey.
99 100 101 102 |
# File 'lib/familia/horreum/database_commands.rb', line 99 def remove_field(field) Familia.trace :HDEL, nil, field if Familia.debug? dbclient.hdel dbkey, field end |
#unwatch ⇒ String
Flushes all the previously watched keys for a transaction.
If a transaction completes successfully or discard is called, there's no need to manually call unwatch.
NOTE: This command operates on the connection itself; not a specific key
300 |
# File 'lib/familia/horreum/database_commands.rb', line 300 def unwatch(...) = dbclient.unwatch(...) |
#watch ⇒ String
Watches the key for changes during a MULTI/EXEC transaction.
Decision Matrix:
| Scenario | Use | Why | |----------|-----|-----| | First-one-wins / idempotency | SET NX | Atomic claim, no read needed | | Distributed lock acquisition | SET NX EX | Claim with automatic expiry | | Read value, update conditionally | WATCH | Decision depends on current state | | Compare-and-swap operations | WATCH | Need optimistic locking | | Version-based updates | WATCH | Must detect concurrent changes | | Status transitions (pending→processing) | WATCH | Must verify current state | | Batch field updates | MULTI only | No conditional logic | | Increment + timestamp together | MULTI only | Concurrent increments OK | | Save object atomically | MULTI only | Just need atomicity | | Update indexes with save | MULTI only | No state checking needed |
If you don't need to read before deciding, WATCH adds complexity without benefit. SET NX handles the "claim" pattern in one atomic shot.
282 283 284 285 286 287 288 289 290 |
# File 'lib/familia/horreum/database_commands.rb', line 282 def watch(...) raise ArgumentError, 'Block required' unless block_given? # Forward all arguments including the block to the watch command dbclient.watch(dbkey, ...) rescue Redis::BaseError => e raise OptimisticLockError, "Redis error: #{e.}" end |