flipper-active_record 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f11ba9f2e7fa94ab06ddddfc753ccb1b398ffc19023ab6b2f5a980ccb55bd974
4
- data.tar.gz: 2566b337548372d8d080f732dbb2824b771f5c58e429ac350ceb0afb5455fea8
3
+ metadata.gz: e7440c16ba96d1af13b04d53af4a794f2b2721ac9073f3be79399542d35f0e8b
4
+ data.tar.gz: 3bf38ab6f14dcf13cfaa53e1d8cfba1622be76cbd0cbb26313c2b135d9681b64
5
5
  SHA512:
6
- metadata.gz: 40e29c142239ff3a5f474f2f0dd6019d3bc60fcc4aaa76021715cf1dcb241c50c2d2dbf1e669cd5b2efcfa5f6740b40bea477988e25d6b5445ff4fcddd111173
7
- data.tar.gz: 6d9c313e0402d1bd197a1abc17a1aa930296f8f854c132773bebc08c6dbf5fab49a2978a4df196267ca0e29af8b5277868458ba4a7d7a35feb4efdcdb44ed1e0
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
- # Public: The name of the adapter.
34
- attr_reader :name
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 :integer
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
@@ -1,3 +1,3 @@
1
1
  module Flipper
2
- VERSION = '1.0.0'.freeze
2
+ VERSION = '1.1.1'.freeze
3
3
  end
@@ -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.string :value
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 text NOT NULL UNIQUE,
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 text NOT NULL,
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
@@ -1,4 +1,3 @@
1
- require 'helper'
2
1
  require 'active_record'
3
2
  require 'rails/generators/test_case'
4
3
  require 'generators/flipper/active_record_generator'
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.0.0
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-08-23 00:00:00.000000000 Z
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.0.0
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.0.0
26
+ version: 1.1.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activerecord
29
29
  requirement: !ruby/object:Gem::Requirement