class Flippant::Adapter::Postgres
Constants
- DEFAULT_TABLE
Attributes
table[R]
Public Class Methods
new(table: DEFAULT_TABLE)
click to toggle source
# File lib/flippant/adapters/postgres.rb, line 13 def initialize(table: DEFAULT_TABLE) @table = table end
Public Instance Methods
add(feature)
click to toggle source
# File lib/flippant/adapters/postgres.rb, line 17 def add(feature) exec("INSERT INTO #{table} (name) VALUES ($1) ON CONFLICT (name) DO NOTHING", [feature]) end
breakdown(actor = :all)
click to toggle source
# File lib/flippant/adapters/postgres.rb, line 21 def breakdown(actor = :all) result = exec("SELECT jsonb_object_agg(name, rules) FROM #{table}") object = JSON.parse(result.values.flatten.first || "{}") object.each_with_object({}) do |(fkey, rules), memo| memo[fkey] = actor == :all ? rules : Rules.enabled_for_actor?(rules, actor) end end
clear()
click to toggle source
# File lib/flippant/adapters/postgres.rb, line 30 def clear exec("TRUNCATE #{table} RESTART IDENTITY") end
disable(feature, group, values)
click to toggle source
# File lib/flippant/adapters/postgres.rb, line 34 def disable(feature, group, values) if values.empty? exec("UPDATE #{table} SET rules = rules - $1 WHERE name = $2", [group, feature]) else command = <<~SQL UPDATE #{table} SET rules = jsonb_set(rules, $1, array_to_json( ARRAY( SELECT UNNEST(ARRAY(SELECT jsonb_array_elements(COALESCE(rules#>$1, '[]'::jsonb)))) EXCEPT SELECT UNNEST(ARRAY(SELECT jsonb_array_elements($2))) ) )::jsonb) WHERE name = $3 SQL exec(command, [encode_array([group]), encode_json(values), feature]) end end
enable(feature, group, values)
click to toggle source
# File lib/flippant/adapters/postgres.rb, line 53 def enable(feature, group, values) command = <<~SQL INSERT INTO #{table} AS t (name, rules) VALUES ($1, $2) ON CONFLICT (name) DO UPDATE SET rules = jsonb_set(t.rules, $3, array_to_json( ARRAY( SELECT DISTINCT(UNNEST(ARRAY( SELECT jsonb_array_elements(COALESCE(t.rules#>$3, '[]'::jsonb)) ) || $4)) ) )::jsonb) SQL exec(command, [feature, encode_json(group => values), encode_array([group]), encode_array(values)]) end
enabled?(feature, actor)
click to toggle source
# File lib/flippant/adapters/postgres.rb, line 72 def enabled?(feature, actor) result = exec("SELECT rules FROM #{table} WHERE name = $1", [feature]) object = JSON.parse(result.values.flatten.first || "[]") Rules.enabled_for_actor?(object, actor) end
exists?(feature, group = nil)
click to toggle source
# File lib/flippant/adapters/postgres.rb, line 79 def exists?(feature, group = nil) result = if group.nil? exec("SELECT EXISTS (SELECT 1 FROM #{table} WHERE name = $1)", [feature]) else exec("SELECT EXISTS (SELECT 1 FROM #{table} WHERE name = $1 " \ "AND rules ? $2)", [feature, group]) end result.values.first == [true] end
features(group = :all)
click to toggle source
# File lib/flippant/adapters/postgres.rb, line 93 def features(group = :all) result = if group == :all exec("SELECT name FROM #{table} ORDER BY name ASC") else exec("SELECT name FROM #{table} WHERE rules ? $1 ORDER BY name ASC", [group]) end result.values.flatten end
load(loaded)
click to toggle source
# File lib/flippant/adapters/postgres.rb, line 104 def load(loaded) transaction do |client| loaded.each do |feature, rules| client.exec_params( "INSERT INTO #{table} AS t (name, rules) VALUES ($1, $2)", [feature, encode_json(rules)] ) end end end
remove(feature)
click to toggle source
# File lib/flippant/adapters/postgres.rb, line 125 def remove(feature) exec("DELETE FROM #{table} WHERE name = $1", [feature]) end
rename(old_name, new_name)
click to toggle source
# File lib/flippant/adapters/postgres.rb, line 115 def rename(old_name, new_name) transaction do |client| client.exec_params("DELETE FROM #{table} WHERE name = $1", [new_name]) client.exec_params("UPDATE #{table} SET name = $1 WHERE name = $2", [new_name, old_name]) end end
setup()
click to toggle source
# File lib/flippant/adapters/postgres.rb, line 129 def setup exec <<~SQL CREATE TABLE IF NOT EXISTS #{table} ( name text NOT NULL CHECK (name <> ''), rules jsonb NOT NULL DEFAULT '{}'::jsonb, CONSTRAINT unique_name UNIQUE(name) ) SQL end
Private Instance Methods
conn() { |client| ... }
click to toggle source
# File lib/flippant/adapters/postgres.rb, line 141 def conn pool.with_connection do |connection| client = connection.raw_connection yield client end end
encode_array(value)
click to toggle source
# File lib/flippant/adapters/postgres.rb, line 169 def encode_array(value) PG::TextEncoder::Array.new.encode(value) end
encode_json(value)
click to toggle source
# File lib/flippant/adapters/postgres.rb, line 173 def encode_json(value) PG::TextEncoder::JSON.new.encode(value) end
exec(sql, params = [])
click to toggle source
# File lib/flippant/adapters/postgres.rb, line 149 def exec(sql, params = []) conn do |client| if params.empty? client.exec(sql) else client.exec_params(sql, params) end end end
pool()
click to toggle source
# File lib/flippant/adapters/postgres.rb, line 159 def pool ActiveRecord::Base.connection_pool end
transaction(&block)
click to toggle source
# File lib/flippant/adapters/postgres.rb, line 163 def transaction(&block) conn do |client| client.transaction(&block) end end