class Flipper::Adapters::Sequel
Attributes
Public: The name of the adapter.
Public Class Methods
Public: Initialize a new Sequel
adapter instance.
name - The Symbol name for this adapter. Optional (default :active_record) feature_class - The AR class responsible for the features table. gate_class - The AR class responsible for the gates table.
Allowing the overriding of name is so you can differentiate multiple instances of this adapter from each other, if, for some reason, that is a thing you do.
Allowing the overriding of the default feature/gate classes means you can roll your own tables and what not, if you so desire.
# File lib/flipper/adapters/sequel.rb, line 46 def initialize(options = {}) @name = options.fetch(:name, :sequel) @feature_class = options.fetch(:feature_class) { Feature } @gate_class = options.fetch(:gate_class) { Gate } end
Public Instance Methods
Public: Adds a feature to the set of known features.
# File lib/flipper/adapters/sequel.rb, line 58 def add(feature) # race condition, but add is only used by enable/disable which happen # super rarely, so it shouldn't matter in practice @feature_class.find_or_create(key: feature.key.to_s) true end
Public: Clears the gate values for a feature.
# File lib/flipper/adapters/sequel.rb, line 75 def clear(feature) @gate_class.where(feature_key: feature.key.to_s).delete true end
Public: Disables a gate for a given thing.
feature - The Flipper::Feature for the gate. gate - The Flipper::Gate to disable. thing - The Flipper::Type being disabled for the gate.
Returns true.
# File lib/flipper/adapters/sequel.rb, line 150 def disable(feature, gate, thing) case gate.data_type when :boolean clear(feature) when :integer set(feature, gate, thing) when :set @gate_class.where(gate_attrs(feature, gate, thing)) .delete else unsupported_data_type gate.data_type end true end
Public: Enables a gate for a given thing.
feature - The Flipper::Feature for the gate. gate - The Flipper::Gate to disable. thing - The Flipper::Type being disabled for the gate.
Returns true.
# File lib/flipper/adapters/sequel.rb, line 125 def enable(feature, gate, thing) case gate.data_type when :boolean set(feature, gate, thing, clear: true) when :integer set(feature, gate, thing) when :set begin @gate_class.create(gate_attrs(feature, gate, thing)) rescue ::Sequel::UniqueConstraintViolation end else unsupported_data_type gate.data_type end true end
Public: The set of known features.
# File lib/flipper/adapters/sequel.rb, line 53 def features @feature_class.all.map(&:key).to_set end
Public: Gets the values for all gates for a given feature.
Returns a Hash of Flipper::Gate#key => value.
# File lib/flipper/adapters/sequel.rb, line 83 def get(feature) db_gates = @gate_class.where(feature_key: feature.key.to_s).all result_for_feature(feature, db_gates) end
# File lib/flipper/adapters/sequel.rb, line 99 def get_all feature_table = @feature_class.table_name.to_sym gate_table = @gate_class.table_name.to_sym features_sql = @feature_class.select(:key.qualify(feature_table).as(:feature_key)) .select_append(:key.qualify(gate_table)) .select_append(:value.qualify(gate_table)) .left_join(@gate_class.table_name.to_sym, feature_key: :key) .sql db_gates = @gate_class.fetch(features_sql).to_a grouped_db_gates = db_gates.group_by(&:feature_key) result = Hash.new { |hash, key| hash[key] = default_config } features = grouped_db_gates.keys.map { |key| Flipper::Feature.new(key, self) } features.each do |feature| result[feature.key] = result_for_feature(feature, grouped_db_gates[feature.key]) end result end
# File lib/flipper/adapters/sequel.rb, line 89 def get_multi(features) db_gates = @gate_class.where(feature_key: features.map(&:key)).to_a grouped_db_gates = db_gates.group_by(&:feature_key) result = {} features.each do |feature| result[feature.key] = result_for_feature(feature, grouped_db_gates[feature.key]) end result end
Public: Removes a feature from the set of known features.
# File lib/flipper/adapters/sequel.rb, line 66 def remove(feature) @feature_class.db.transaction do @feature_class.where(key: feature.key.to_s).delete clear(feature) end true end
Private Instance Methods
# File lib/flipper/adapters/sequel.rb, line 190 def gate_attrs(feature, gate, thing) { feature_key: feature.key.to_s, key: gate.key.to_s, value: thing.value.to_s, } end
# File lib/flipper/adapters/sequel.rb, line 198 def result_for_feature(feature, db_gates) db_gates ||= [] feature.gates.each_with_object({}) do |gate, result| result[gate.key] = case gate.data_type when :boolean if detected_db_gate = db_gates.detect { |db_gate| db_gate.key == gate.key.to_s } detected_db_gate.value end when :integer if detected_db_gate = db_gates.detect { |db_gate| db_gate.key == gate.key.to_s } detected_db_gate.value end when :set db_gates.select { |db_gate| db_gate.key == gate.key.to_s }.map(&:value).to_set else unsupported_data_type gate.data_type end end end
# File lib/flipper/adapters/sequel.rb, line 172 def set(feature, gate, thing, options = {}) clear_feature = options.fetch(:clear, false) args = { feature_key: feature.key, key: gate.key.to_s, } @gate_class.db.transaction do clear(feature) if clear_feature @gate_class.where(args).delete begin @gate_class.create(gate_attrs(feature, gate, thing)) rescue ::Sequel::UniqueConstraintViolation end end end
# File lib/flipper/adapters/sequel.rb, line 168 def unsupported_data_type(data_type) raise "#{data_type} is not supported by this adapter" end