Class: Familia::DataType

Inherits:
Object
  • Object
show all
Extended by:
ClassMethods, Features
Includes:
Base, Commands, Serialization
Defined in:
lib/familia/data_type.rb,
lib/familia/data_type/commands.rb,
lib/familia/data_type/serialization.rb

Overview

lib/familia/data_type/serialization.rb

Direct Known Subclasses

HashKey, List, Set, SortedSet, String

Defined Under Namespace

Modules: ClassMethods, Commands, Serialization

Class Attribute Summary collapse

Instance Attribute Summary collapse

Attributes included from Features

#features_enabled

Instance Method Summary collapse

Methods included from Features

feature

Methods included from ClassMethods

has_relations?, inherited, register, valid_keys_only

Methods included from Serialization

#deserialize_value, #deserialize_values, #deserialize_values_with_nil, #serialize_value

Methods included from Commands

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

Methods included from Base

add_feature, #generate_id, #to_s, #update_expiration, #uuid

Constructor Details

#initialize(keystring, opts = {}) ⇒ DataType

+keystring+: If parent is set, this will be used as the suffix for dbkey. Otherwise this becomes the value of the key. If this is an Array, the elements will be joined.

Options:

:class => A class that responds to Familia.load_method and Familia.dump_method. These will be used when loading and saving data from/to the database to unmarshal/marshal the class.

:parent => The Familia object that this datatype object belongs to. This can be a class that includes Familia or an instance.

:default_expiration => the time to live in seconds. When not nil, this will set the default expiration for this dbkey whenever #save is called. You can also call it explicitly via #update_expiration.

:default => the default value (String-only)

:logical_database => the logical database index to use (ignored if :dbclient is used).

:dbclient => an instance of database client.

:dbkey => a hardcoded key to use instead of the deriving the from the name and parent (e.g. a derived key: customer:custid:secret_counter).

:suffix => the suffix to use for the key (e.g. ‘scores’ in customer:custid:scores). :prefix => the prefix to use for the key (e.g. ‘customer’ in customer:custid:scores).

Connection precendence: uses the database connection of the parent or the value of opts[:dbclient] or Familia.dbclient (in that order).



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/familia/data_type.rb', line 103

def initialize(keystring, opts = {})
  @keystring = keystring
  @keystring = @keystring.join(Familia.delim) if @keystring.is_a?(Array)

  # Remove all keys from the opts that are not in the allowed list
  @opts = opts || {}
  @opts = DataType.valid_keys_only(@opts)

  # Apply the options to instance method setters of the same name
  @opts.each do |k, v|
    # Bewarde logging :parent instance here implicitly calls #to_s which for
    # some classes could include the identifier which could still be nil at
    # this point. This would result in a Familia::Problem being raised. So
    # to be on the safe-side here until we have a better understanding of
    # the issue, we'll just log the class name for each key-value pair.
    Familia.trace :SETTING, nil, " [setting] #{k} #{v.class}", caller(1..1) if Familia.debug?
    send(:"#{k}=", v) if respond_to? :"#{k}="
  end

  init if respond_to? :init
end

Class Attribute Details

.has_relationsObject (readonly)

Returns the value of attribute has_relations.



25
26
27
# File 'lib/familia/data_type.rb', line 25

def has_relations
  @has_relations
end

.logical_database=(value) ⇒ Object (writeonly)

Sets the attribute logical_database

Parameters:

  • value

    the value to set the attribute logical_database to.



27
28
29
# File 'lib/familia/data_type.rb', line 27

def logical_database=(value)
  @logical_database = value
end

.parentObject

Returns the value of attribute parent.



26
27
28
# File 'lib/familia/data_type.rb', line 26

def parent
  @parent
end

.registered_typesObject (readonly)

Returns the value of attribute registered_types.



25
26
27
# File 'lib/familia/data_type.rb', line 25

def registered_types
  @registered_types
end

.uri=(value) ⇒ Object (writeonly)

Sets the attribute uri

Parameters:

  • value

    the value to set the attribute uri to.



27
28
29
# File 'lib/familia/data_type.rb', line 27

def uri=(value)
  @uri = value
end

.valid_optionsObject (readonly)

Returns the value of attribute valid_options.



25
26
27
# File 'lib/familia/data_type.rb', line 25

def valid_options
  @valid_options
end

Instance Attribute Details

#dump_methodObject



224
225
226
# File 'lib/familia/data_type.rb', line 224

def dump_method
  @dump_method || self.class.dump_method
end

#keystringObject (readonly)

Returns the value of attribute keystring.



69
70
71
# File 'lib/familia/data_type.rb', line 69

def keystring
  @keystring
end

#load_methodObject



228
229
230
# File 'lib/familia/data_type.rb', line 228

def load_method
  @load_method || self.class.load_method
end

#optsObject (readonly)

Returns the value of attribute opts.



69
70
71
# File 'lib/familia/data_type.rb', line 69

def opts
  @opts
end

#parentObject (readonly)

Returns the value of attribute parent.



69
70
71
# File 'lib/familia/data_type.rb', line 69

def parent
  @parent
end

Instance Method Details

#class?Boolean

Returns:

  • (Boolean)


182
183
184
# File 'lib/familia/data_type.rb', line 182

def class?
  !@opts[:class].to_s.empty? && @opts[:class].is_a?(Familia)
end

#dbclientObject



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

def dbclient
  return Fiber[:familia_transaction] if Fiber[:familia_transaction]
  return @dbclient if @dbclient

  parent? ? parent.dbclient : Familia.dbclient(opts[:logical_database])
end

#dbkeyString

Produces the full dbkey for this object.

This method determines the appropriate dbkey based on the context of the DataType object:

  1. If a hardcoded key is set in the options, it returns that key.
  2. For instance-level DataType objects, it uses the parent instance’s dbkey method.
  3. For class-level DataType objects, it uses the parent class’s dbkey method.
  4. For standalone DataType objects, it uses the keystring as the full dbkey.

For class-level DataType objects (parent_class? == true): - The suffix is optional and used to differentiate between different types of objects. - If no suffix is provided, the class’s default suffix is used (via the self.suffix method). - If a nil suffix is explicitly passed, it won’t appear in the resulting dbkey. - Passing nil as the suffix is how class-level DataType objects are created without the global default ‘object’ suffix.

Examples:

Instance-level DataType

user_instance.some_datatype.dbkey  # => "user:123:some_datatype"

Class-level DataType

User.some_datatype.dbkey  # => "user:some_datatype"

Standalone DataType

DataType.new("mykey").dbkey  # => "mykey"

Class-level DataType with explicit nil suffix

User.dbkey("123", nil)  # => "user:123"

Returns:

  • (String)

    The full dbkey.



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/familia/data_type.rb', line 162

def dbkey
  # Return the hardcoded key if it's set. This is useful for
  # support legacy keys that aren't derived in the same way.
  return opts[:dbkey] if opts[:dbkey]

  if parent_instance?
    # This is an instance-level datatype object so the parent instance's
    # dbkey method is defined in Familia::Horreum::InstanceMethods.
    parent.dbkey(keystring)
  elsif parent_class?
    # This is a class-level datatype object so the parent class' dbkey
    # method is defined in Familia::Horreum::DefinitionMethods.
    parent.dbkey(keystring, nil)
  else
    # This is a standalone DataType object where it's keystring
    # is the full database key (dbkey).
    keystring
  end
end

#logical_databaseObject



202
203
204
# File 'lib/familia/data_type.rb', line 202

def logical_database
  @opts[:logical_database] || self.class.logical_database
end

#parent?Boolean

Returns:

  • (Boolean)


194
195
196
# File 'lib/familia/data_type.rb', line 194

def parent?
  parent_class? || parent_instance?
end

#parent_class?Boolean

Returns:

  • (Boolean)


190
191
192
# File 'lib/familia/data_type.rb', line 190

def parent_class?
  parent.is_a?(Class) && parent <= Familia::Horreum
end

#parent_instance?Boolean

Returns:

  • (Boolean)


186
187
188
# File 'lib/familia/data_type.rb', line 186

def parent_instance?
  parent.is_a?(Familia::Horreum)
end

#uriObject



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/familia/data_type.rb', line 206

def uri
  # If a specific URI is set in opts, use it
  return @opts[:uri] if @opts[:uri]

  # If parent has a DB set, create a URI with that DB
  if parent? && parent.respond_to?(:logical_database) && parent.logical_database
    base_uri = self.class.uri || Familia.uri
    if base_uri
      uri_with_db = base_uri.dup
      uri_with_db.db = parent.logical_database
      return uri_with_db
    end
  end

  # Otherwise fall back to class URI
  self.class.uri
end