Class: Familia::HashKey

Inherits:
DataType show all
Defined in:
lib/familia/data_type/types/hashkey.rb

Instance Attribute Summary collapse

Attributes included from Settings

#current_key_version, #default_expiration, #delim, #encryption_keys, #encryption_personalization, #logical_database, #prefix, #schema_path, #schema_validator, #schemas, #suffix, #transaction_mode

Instance Method Summary collapse

Methods included from Features::Autoloader

autoload_files, included, normalize_to_config_name

Methods included from DataType::Serialization

#deserialize_value, #deserialize_values, #deserialize_values_with_nil, #serialize_value

Methods included from DataType::DatabaseCommands

#current_expiration, #delete!, #echo, #exists?, #expire, #expireat, #move, #persist, #rename, #renamenx, #type

Methods included from DataType::Connection

#dbclient, #dbkey, #direct_access, #uri

Methods included from Connection::Behavior

#connect, #create_dbclient, #multi, #normalize_uri, #pipeline, #pipelined, #transaction, #uri=, #url, #url=

Methods included from Settings

#configure, #default_suffix, #pipelined_mode, #pipelined_mode=

Methods included from Base

add_feature, #as_json, #expired?, #expires?, find_feature, #generate_id, #to_json, #to_s, #ttl, #update_expiration, #uuid

Constructor Details

This class inherits a constructor from Familia::DataType

Instance Attribute Details

#features_enabledObject (readonly) Originally defined in module Features

Returns the value of attribute features_enabled.

#logical_database(val = nil) ⇒ Object Originally defined in module DataType::ClassMethods

#parentObject Originally defined in module DataType::ClassMethods

Returns the value of attribute parent.

#prefixObject Originally defined in module DataType::ClassMethods

Returns the value of attribute prefix.

#suffixObject Originally defined in module DataType::ClassMethods

Returns the value of attribute suffix.

#uri(val = nil) ⇒ Object Originally defined in module DataType::ClassMethods

Returns the value of attribute uri.

Instance Method Details

#[](field) ⇒ Object Also known as: get



38
39
40
# File 'lib/familia/data_type/types/hashkey.rb', line 38

def [](field)
  deserialize_value dbclient.hget(dbkey, field.to_s)
end

#[]=(field, val) ⇒ Object Also known as: put, store, add

+return+ [Integer] Returns 1 if the field is new and added, 0 if the field already existed and the value was updated.



22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/familia/data_type/types/hashkey.rb', line 22

def []=(field, val)
  ret = dbclient.hset dbkey, field.to_s, serialize_value(val)
  update_expiration
  ret
rescue TypeError => e
  Familia.error "[hset]= #{e.message}"
  Familia.debug "[hset]= #{dbkey} #{field}=#{val}"
  echo :hset, Familia.pretty_stack(limit: 1) if Familia.debug # logs via echo to the db and back
  klass = val.class
  msg = "Cannot store #{field} => #{val.inspect} (#{klass}) in #{dbkey}"
  raise e.class, msg
end

#decrement(field, by = 1) ⇒ Object Also known as: decr, decrby



109
110
111
# File 'lib/familia/data_type/types/hashkey.rb', line 109

def decrement(field, by = 1)
  increment field, -by
end

#empty?Boolean

Returns:

  • (Boolean)


16
17
18
# File 'lib/familia/data_type/types/hashkey.rb', line 16

def empty?
  field_count.zero?
end

#fetch(field, default = nil) ⇒ Object



43
44
45
46
47
48
49
50
51
52
# File 'lib/familia/data_type/types/hashkey.rb', line 43

def fetch(field, default = nil)
  ret = self[field.to_s]
  if ret.nil?
    raise IndexError, "No such index for: #{field}" if default.nil?

    default
  else
    ret
  end
end

#field_countInteger Also known as: size, length, count

Returns the number of fields in the hash

Returns:

  • (Integer)

    number of fields



9
10
11
# File 'lib/familia/data_type/types/hashkey.rb', line 9

def field_count
  dbclient.hlen dbkey
end

#hgetallObject Also known as: all



62
63
64
65
66
# File 'lib/familia/data_type/types/hashkey.rb', line 62

def hgetall
  dbclient.hgetall(dbkey).transform_values do |v|
    deserialize_value v
  end
end

#hsetnx(field, val) ⇒ Integer

Sets field in the hash stored at key to value, only if field does not yet exist. If field already exists, this operation has no effect.

Parameters:

  • field (String)

    The field name

  • val (Object)

    The value to set

Returns:

  • (Integer)

    1 if field is a new field and value was set, 0 if field already exists



74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/familia/data_type/types/hashkey.rb', line 74

def hsetnx(field, val)
  ret = dbclient.hsetnx dbkey, field.to_s, serialize_value(val)
  update_expiration if ret == 1
  ret
rescue TypeError => e
  Familia.error "[hsetnx] #{e.message}"
  Familia.debug "[hsetnx] #{dbkey} #{field}=#{val}"
  echo :hsetnx, Familia.pretty_stack(limit: 1) if Familia.debug # logs via echo to the db and back
  klass = val.class
  msg = "Cannot store #{field} => #{val.inspect} (#{klass}) in #{dbkey}"
  raise e.class, msg
end

#increment(field, by = 1) ⇒ Object Also known as: incr, incrby



103
104
105
# File 'lib/familia/data_type/types/hashkey.rb', line 103

def increment(field, by = 1)
  dbclient.hincrby(dbkey, field.to_s, by).to_i
end

#key?(field) ⇒ Boolean Also known as: has_key?, include?, member?

Returns:

  • (Boolean)


87
88
89
# File 'lib/familia/data_type/types/hashkey.rb', line 87

def key?(field)
  dbclient.hexists dbkey, field.to_s
end

#keysObject



54
55
56
# File 'lib/familia/data_type/types/hashkey.rb', line 54

def keys
  dbclient.hkeys dbkey
end

#refreshself

The friendly neighborhood refresh method!

This method is like refresh! but with better manners - it returns self so you can chain it with other methods. It's perfect for when you want to refresh your hash and immediately do something with it.

Examples:

Refresh and chain

my_hash.refresh.keys  # Refresh and get all keys
my_hash.refresh['field']  # Refresh and get a specific field

Returns:

  • (self)

    Returns the refreshed hash, ready for more adventures!

Raises:

See Also:



183
184
185
186
# File 'lib/familia/data_type/types/hashkey.rb', line 183

def refresh
  refresh!
  self
end

#refresh!void

Note:

This operation is atomic - it either succeeds completely or fails safely. Any unsaved changes to the hash will be overwritten.

This method returns an undefined value.

The Great Database Refresh-o-matic 3000 for HashKey!

This method performs a complete refresh of the hash's state from the database. It's like giving your hash a memory transfusion - out with the old state, in with the fresh data straight from Valkey/Redis!

Examples:

Basic usage

my_hash.refresh!  # ZAP! Fresh data loaded

With error handling

begin
  my_hash.refresh!
rescue Familia::KeyNotFoundError
  puts "Oops! Our hash seems to have vanished into the Database void!"
end

Raises:



156
157
158
159
160
161
162
163
164
165
# File 'lib/familia/data_type/types/hashkey.rb', line 156

def refresh!
  Familia.trace :REFRESH, nil, self.class.uri if Familia.debug?
  raise Familia::KeyNotFoundError, dbkey unless dbclient.exists(dbkey)

  fields = hgetall
  Familia.debug "[refresh!] #{self.class} #{dbkey} #{fields.keys}"

  # For HashKey, we update by merging the fresh data
  update(fields)
end

#remove_field(field) ⇒ Integer Also known as: remove, remove_element

Removes a field from the hash

Parameters:

  • field (String)

    The field to remove

Returns:

  • (Integer)

    The number of fields that were removed (0 or 1)



97
98
99
# File 'lib/familia/data_type/types/hashkey.rb', line 97

def remove_field(field)
  dbclient.hdel dbkey, field.to_s
end

#update(hsh = {}) ⇒ Object Also known as: merge!

Raises:

  • (ArgumentError)


115
116
117
118
119
120
121
122
123
# File 'lib/familia/data_type/types/hashkey.rb', line 115

def update(hsh = {})
  raise ArgumentError, 'Argument to bulk_set must be a hash' unless hsh.is_a?(Hash)

  data = hsh.inject([]) { |ret, pair| ret << [pair[0], serialize_value(pair[1])] }.flatten

  ret = dbclient.hmset(dbkey, *data)
  update_expiration
  ret
end

#valuesObject



58
59
60
# File 'lib/familia/data_type/types/hashkey.rb', line 58

def values
  dbclient.hvals(dbkey).map { |v| deserialize_value v }
end

#values_at(*fields) ⇒ Object



126
127
128
129
130
# File 'lib/familia/data_type/types/hashkey.rb', line 126

def values_at *fields
  string_fields = fields.flatten.compact.map(&:to_s)
  elements = dbclient.hmget(dbkey, *string_fields)
  deserialize_values(*elements)
end