Module: Familia::Features

Included in:
DataType
Defined in:
lib/familia/features.rb,
lib/familia/features/safe_dump.rb,
lib/familia/features/expiration.rb,
lib/familia/features/quantization.rb,
lib/familia/features/encrypted_fields.rb,
lib/familia/features/transient_fields.rb

Overview

lib/familia/features/quantization.rb

Defined Under Namespace

Modules: EncryptedFields, Expiration, Quantization, SafeDump, TransientFields

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#features_enabledObject (readonly)

Returns the value of attribute features_enabled.



12
13
14
# File 'lib/familia/features.rb', line 12

def features_enabled
  @features_enabled
end

Instance Method Details

#feature(feature_name = nil) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/familia/features.rb', line 14

def feature(feature_name = nil)
  @features_enabled ||= []

  return features_enabled if feature_name.nil?

  # If there's a value provied check that it's a valid feature
  feature_name = feature_name.to_sym
  unless Familia::Base.features_available.key?(feature_name)
    raise Familia::Problem, "Unsupported feature: #{feature_name}"
  end

  # If the feature is already available, do nothing but log about it
  if features_enabled.member?(feature_name)
    Familia.warn "[#{self.class}] feature already available: #{feature_name}"
    return
  end

  if Familia.debug?
    Familia.trace :FEATURE, nil, "#{self} includes #{feature_name.inspect}", caller(1..1)
  end

  # Add it to the list available features_enabled for Familia::Base classes.
  features_enabled << feature_name

  klass = Familia::Base.features_available[feature_name]

  # Validate dependencies
  feature_def = Familia::Base.feature_definitions[feature_name]
  if feature_def&.depends_on&.any?
    missing = feature_def.depends_on - features_enabled
    raise Familia::Problem, "#{feature_name} requires: #{missing.join(', ')}" if missing.any?
  end

  # Extend the Familia::Base subclass (e.g. Customer) with the feature module
  include klass

  # NOTE: Do we want to extend Familia::DataType here? That would make it
  # possible to call safe_dump on relations fields (e.g. list, zset, hashkey).
  #
  # The challenge is that DataType classes (List, Set, etc.) are shared across
  # all Horreum models. If Customer extends DataType with safe_dump, then
  # Session's lists would also have it. Not ideal. If that's all we wanted
  # then we can do that by looping through every DataType class here.
  #
  # We'd need to extend the DataType instances for each Horreum subclass. That
  # avoids it getting included multiple times per DataType
end