flipper-active_record 1.0.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/flipper-active_record.gemspec +8 -1
- data/lib/flipper/adapters/active_record.rb +31 -6
- data/lib/flipper/version.rb +1 -1
- data/lib/generators/flipper/templates/migration.erb +1 -1
- data/spec/flipper/adapters/active_record_spec.rb +16 -4
- data/test/adapters/active_record_test.rb +2 -2
- data/test_rails/generators/flipper/active_record_generator_test.rb +0 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e7440c16ba96d1af13b04d53af4a794f2b2721ac9073f3be79399542d35f0e8b
|
4
|
+
data.tar.gz: 3bf38ab6f14dcf13cfaa53e1d8cfba1622be76cbd0cbb26313c2b135d9681b64
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ae73ab2931ebaa6ab45e8f12d75fd16859b7c35fe83c09311b51c3dd43243106db50588dd7605f9e98a8d1611305861fcf3f082561b06dceab042d21f67e56fd
|
7
|
+
data.tar.gz: 707051b6ad52cbbe0a50e817ba06d39ddb30cc42c1f7585e890d4c4f378bbd8775e519212cf38c43fe49907245c3e25da618e3644081dc5afcca3056d7b90b8b
|
@@ -1,9 +1,16 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
require File.expand_path('../lib/flipper/version', __FILE__)
|
3
3
|
require File.expand_path('../lib/flipper/metadata', __FILE__)
|
4
|
+
require "set"
|
5
|
+
|
6
|
+
# Files that should exist in main flipper gem.
|
7
|
+
main_flipper_active_record_files = Set[
|
8
|
+
"lib/flipper/model/active_record.rb",
|
9
|
+
"spec/flipper/model/active_record_spec.rb",
|
10
|
+
]
|
4
11
|
|
5
12
|
flipper_active_record_files = lambda do |file|
|
6
|
-
file =~ /active_record/
|
13
|
+
file =~ /active_record/ && !main_flipper_active_record_files.include?(file)
|
7
14
|
end
|
8
15
|
|
9
16
|
Gem::Specification.new do |gem|
|
@@ -19,6 +19,8 @@ module Flipper
|
|
19
19
|
"flipper_features",
|
20
20
|
Model.table_name_suffix,
|
21
21
|
].join
|
22
|
+
|
23
|
+
has_many :gates, foreign_key: "feature_key", primary_key: "key"
|
22
24
|
end
|
23
25
|
|
24
26
|
# Private: Do not use outside of this adapter.
|
@@ -30,8 +32,10 @@ module Flipper
|
|
30
32
|
].join
|
31
33
|
end
|
32
34
|
|
33
|
-
|
34
|
-
|
35
|
+
VALUE_TO_TEXT_WARNING = <<-EOS
|
36
|
+
Your database needs migrated to use the latest Flipper features.
|
37
|
+
See https://github.com/flippercloud/flipper/issues/557
|
38
|
+
EOS
|
35
39
|
|
36
40
|
# Public: Initialize a new ActiveRecord adapter instance.
|
37
41
|
#
|
@@ -49,6 +53,8 @@ module Flipper
|
|
49
53
|
@name = options.fetch(:name, :active_record)
|
50
54
|
@feature_class = options.fetch(:feature_class) { Feature }
|
51
55
|
@gate_class = options.fetch(:gate_class) { Gate }
|
56
|
+
|
57
|
+
warn VALUE_TO_TEXT_WARNING if value_not_text?
|
52
58
|
end
|
53
59
|
|
54
60
|
# Public: The set of known features.
|
@@ -156,6 +162,8 @@ module Flipper
|
|
156
162
|
set(feature, gate, thing, clear: true)
|
157
163
|
when :integer
|
158
164
|
set(feature, gate, thing)
|
165
|
+
when :json
|
166
|
+
set(feature, gate, thing, json: true)
|
159
167
|
when :set
|
160
168
|
enable_multi(feature, gate, thing)
|
161
169
|
else
|
@@ -178,6 +186,8 @@ module Flipper
|
|
178
186
|
clear(feature)
|
179
187
|
when :integer
|
180
188
|
set(feature, gate, thing)
|
189
|
+
when :json
|
190
|
+
delete(feature, gate)
|
181
191
|
when :set
|
182
192
|
with_connection(@gate_class) do
|
183
193
|
@gate_class.where(feature_key: feature.key, key: gate.key, value: thing.value).destroy_all
|
@@ -198,15 +208,20 @@ module Flipper
|
|
198
208
|
|
199
209
|
def set(feature, gate, thing, options = {})
|
200
210
|
clear_feature = options.fetch(:clear, false)
|
211
|
+
json_feature = options.fetch(:json, false)
|
212
|
+
|
213
|
+
raise VALUE_TO_TEXT_WARNING if json_feature && value_not_text?
|
214
|
+
|
201
215
|
with_connection(@gate_class) do
|
202
216
|
@gate_class.transaction do
|
203
217
|
clear(feature) if clear_feature
|
218
|
+
delete(feature, gate)
|
204
219
|
@gate_class.where(feature_key: feature.key, key: gate.key).destroy_all
|
205
220
|
begin
|
206
221
|
@gate_class.create! do |g|
|
207
222
|
g.feature_key = feature.key
|
208
223
|
g.key = gate.key
|
209
|
-
g.value = thing.value.to_s
|
224
|
+
g.value = json_feature ? Typecast.to_json(thing.value) : thing.value.to_s
|
210
225
|
end
|
211
226
|
rescue ::ActiveRecord::RecordNotUnique
|
212
227
|
# assume this happened concurrently with the same thing and its fine
|
@@ -218,6 +233,10 @@ module Flipper
|
|
218
233
|
nil
|
219
234
|
end
|
220
235
|
|
236
|
+
def delete(feature, gate)
|
237
|
+
@gate_class.where(feature_key: feature.key, key: gate.key).destroy_all
|
238
|
+
end
|
239
|
+
|
221
240
|
def enable_multi(feature, gate, thing)
|
222
241
|
with_connection(@gate_class) do
|
223
242
|
@gate_class.create! do |g|
|
@@ -238,13 +257,13 @@ module Flipper
|
|
238
257
|
feature.gates.each do |gate|
|
239
258
|
result[gate.key] =
|
240
259
|
case gate.data_type
|
241
|
-
when :boolean
|
260
|
+
when :boolean, :integer
|
242
261
|
if row = gates.detect { |key, value| !key.nil? && key.to_sym == gate.key }
|
243
262
|
row.last
|
244
263
|
end
|
245
|
-
when :
|
264
|
+
when :json
|
246
265
|
if row = gates.detect { |key, value| !key.nil? && key.to_sym == gate.key }
|
247
|
-
row.last
|
266
|
+
Typecast.from_json(row.last)
|
248
267
|
end
|
249
268
|
when :set
|
250
269
|
gates.select { |key, value| !key.nil? && key.to_sym == gate.key }.map(&:last).to_set
|
@@ -255,6 +274,12 @@ module Flipper
|
|
255
274
|
result
|
256
275
|
end
|
257
276
|
|
277
|
+
# Check if value column is text instead of string
|
278
|
+
# See https://github.com/flippercloud/flipper/pull/692
|
279
|
+
def value_not_text?
|
280
|
+
@gate_class.column_for_attribute(:value).type != :text
|
281
|
+
end
|
282
|
+
|
258
283
|
def with_connection(model = @feature_class, &block)
|
259
284
|
model.connection_pool.with_connection(&block)
|
260
285
|
end
|
data/lib/flipper/version.rb
CHANGED
@@ -9,7 +9,7 @@ class CreateFlipperTables < ActiveRecord::Migration<%= migration_version %>
|
|
9
9
|
create_table :flipper_gates do |t|
|
10
10
|
t.string :feature_key, null: false
|
11
11
|
t.string :key, null: false
|
12
|
-
t.
|
12
|
+
t.text :value
|
13
13
|
t.timestamps null: false
|
14
14
|
end
|
15
15
|
add_index :flipper_gates, [:feature_key, :key, :value], unique: true
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'flipper/adapters/active_record'
|
2
|
+
require 'active_support/core_ext/kernel'
|
2
3
|
|
3
4
|
# Turn off migration logging for specs
|
4
5
|
ActiveRecord::Migration.verbose = false
|
@@ -15,7 +16,7 @@ RSpec.describe Flipper::Adapters::ActiveRecord do
|
|
15
16
|
ActiveRecord::Base.connection.execute <<-SQL
|
16
17
|
CREATE TABLE flipper_features (
|
17
18
|
id integer PRIMARY KEY,
|
18
|
-
key
|
19
|
+
key string NOT NULL UNIQUE,
|
19
20
|
created_at datetime NOT NULL,
|
20
21
|
updated_at datetime NOT NULL
|
21
22
|
)
|
@@ -25,7 +26,7 @@ RSpec.describe Flipper::Adapters::ActiveRecord do
|
|
25
26
|
CREATE TABLE flipper_gates (
|
26
27
|
id integer PRIMARY KEY,
|
27
28
|
feature_key text NOT NULL,
|
28
|
-
key
|
29
|
+
key string NOT NULL,
|
29
30
|
value text DEFAULT NULL,
|
30
31
|
created_at datetime NOT NULL,
|
31
32
|
updated_at datetime NOT NULL
|
@@ -44,13 +45,24 @@ RSpec.describe Flipper::Adapters::ActiveRecord do
|
|
44
45
|
|
45
46
|
it_should_behave_like 'a flipper adapter'
|
46
47
|
|
48
|
+
it "should load actor ids fine" do
|
49
|
+
flipper.enable_percentage_of_time(:foo, 1)
|
50
|
+
|
51
|
+
ActiveRecord::Base.connection.execute <<-SQL
|
52
|
+
INSERT INTO flipper_gates (feature_key, key, value, created_at, updated_at)
|
53
|
+
VALUES ("foo", "actors", "Organization;4", time(), time())
|
54
|
+
SQL
|
55
|
+
|
56
|
+
flipper = Flipper.new(subject)
|
57
|
+
flipper.preload([:foo])
|
58
|
+
end
|
59
|
+
|
47
60
|
context 'requiring "flipper-active_record"' do
|
48
61
|
before do
|
49
62
|
Flipper.configuration = nil
|
50
63
|
Flipper.instance = nil
|
51
64
|
|
52
|
-
load 'flipper/adapters/active_record.rb'
|
53
|
-
ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)
|
65
|
+
silence_warnings { load 'flipper/adapters/active_record.rb' }
|
54
66
|
end
|
55
67
|
|
56
68
|
it 'configures itself' do
|
@@ -11,8 +11,6 @@ class ActiveRecordTest < MiniTest::Test
|
|
11
11
|
database: ':memory:')
|
12
12
|
|
13
13
|
def setup
|
14
|
-
@adapter = Flipper::Adapters::ActiveRecord.new
|
15
|
-
|
16
14
|
ActiveRecord::Base.connection.execute <<-SQL
|
17
15
|
CREATE TABLE flipper_features (
|
18
16
|
id integer PRIMARY KEY,
|
@@ -36,6 +34,8 @@ class ActiveRecordTest < MiniTest::Test
|
|
36
34
|
ActiveRecord::Base.connection.execute <<-SQL
|
37
35
|
CREATE UNIQUE INDEX index_gates_on_keys_and_value on flipper_gates (feature_key, key, value)
|
38
36
|
SQL
|
37
|
+
|
38
|
+
@adapter = Flipper::Adapters::ActiveRecord.new
|
39
39
|
end
|
40
40
|
|
41
41
|
def teardown
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flipper-active_record
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Nunemaker
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-12-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: flipper
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.
|
19
|
+
version: 1.1.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.
|
26
|
+
version: 1.1.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activerecord
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|