1 2 3 4 5 6 7 8 9 10 11 12 13 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 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
|
require 'set'
module Flipper
module Adapters
# Public: Adapter for storing everything in memory.
# Useful for tests/specs.
class Memory
include ::Flipper::Adapter
FeaturesKey = :features
# Public: The name of the adapter.
attr_reader :name
# Public
def initialize(source = nil)
@source = source || {}
@name = :memory
end
# Public: The set of known features.
def features
read_feature_keys
end
# Public: Adds a feature to the set of known features.
def add(feature)
features.add(feature.key)
true
end
# Public: Removes a feature from the set of known features and clears
# all the values for the feature.
def remove(feature)
features.delete(feature.name.to_s)
clear(feature)
true
end
# Public: Clears all the gate values for a feature.
def clear(feature)
feature.gates.each do |gate|
delete key(feature, gate)
end
true
end
# Public
def get(feature)
read_feature(feature)
end
def get_multi(features)
read_many_features(features)
end
def get_all
features = read_feature_keys.map do |key|
Flipper::Feature.new(key, self)
end
read_many_features(features)
end
# Public
def enable(feature, gate, thing)
case gate.data_type
when :boolean, :integer
write key(feature, gate), thing.value.to_s
when :set
set_add key(feature, gate), thing.value.to_s
else
raise "#{gate} is not supported by this adapter yet"
end
true
end
# Public
def disable(feature, gate, thing)
case gate.data_type
when :boolean
clear(feature)
when :integer
write key(feature, gate), thing.value.to_s
when :set
set_delete key(feature, gate), thing.value.to_s
else
raise "#{gate} is not supported by this adapter yet"
end
true
end
# Public
def inspect
attributes = [
'name=:memory',
"source=#{@source.inspect}",
]
"#<#{self.class.name}:#{object_id} #{attributes.join(', ')}>"
end
private
def read_feature_keys
set_members(FeaturesKey)
end
# Private
def key(feature, gate)
"feature/#{feature.key}/#{gate.key}"
end
def read_many_features(features)
result = {}
features.each do |feature|
result[feature.key] = read_feature(feature)
end
result
end
def read_feature(feature)
result = {}
feature.gates.each do |gate|
result[gate.key] =
case gate.data_type
when :boolean, :integer
read key(feature, gate)
when :set
set_members key(feature, gate)
else
raise "#{gate} is not supported by this adapter yet"
end
end
result
end
# Private
def read(key)
@source[key.to_s]
end
# Private
def write(key, value)
@source[key.to_s] = value.to_s
end
# Private
def delete(key)
@source.delete(key.to_s)
end
# Private
def set_add(key, value)
ensure_set_initialized(key)
@source[key.to_s].add(value.to_s)
end
# Private
def set_delete(key, value)
ensure_set_initialized(key)
@source[key.to_s].delete(value.to_s)
end
# Private
def set_members(key)
ensure_set_initialized(key)
@source[key.to_s]
end
# Private
def ensure_set_initialized(key)
@source[key.to_s] ||= Set.new
end
end
end
end
|