flipper-active_record 1.2.1 → 1.3.0.pre

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d93623f7da8df34acc676d8a7f20fdc983eca967539edcb6c2aae35247828eb1
4
- data.tar.gz: 2060a98a8c7aba7dd54d62d5d1fad78fd6ca0f8a2136c9c264070383fd23c851
3
+ metadata.gz: 7c5c569d1b6a5074ed23b730cb49012e31ea81ec72d0d1ee3bc7fd220e9d8de7
4
+ data.tar.gz: 66c02755000391fc1ffd56944dad2e9ee5b8e563437cfe4fd4a6ccd437eb6aed
5
5
  SHA512:
6
- metadata.gz: ad53eda1a2aa9e11f719e9a5916f060a9cc628f450b60c3a991777b3ae9bc1a5968009c396fbda779406c979b8129d427cd5e217a1ecc5718497823f528241b1
7
- data.tar.gz: a99ace899778db6f3120c8909e78afc595a57524a56759c0bba67a8b65e4721fc82c0fd4603f0a672dc4459216742533cc881ea8f7344bdadcb00aae5fb8ce96
6
+ metadata.gz: db8c6b8e49eb66d7e680236c000c7b5333ed43f55ede52d868aa1cdf54e6729d7c42c289fa6e9eefa456afd8dbf9227c85385fa05bdab303f5d2520ca00634ad
7
+ data.tar.gz: 3607f280b38cc442d142d17a4d56e1f1584bb4e1ca298fa52a03ee5b53d2c4adf86f1a25e8fd784df9d835357d34fe5cd76366b80c7cf92c29c3847e093ec665
@@ -6,10 +6,13 @@ require 'benchmark/ips'
6
6
 
7
7
  flipper = Flipper.new(Flipper::Adapters::ActiveRecord.new)
8
8
 
9
- 2000.times do |i|
10
- flipper.enable_actor :foo, Flipper::Actor.new("User;#{i}")
9
+ 10.times do |n|
10
+ 2000.times do |i|
11
+ flipper.enable_actor 'feature' + n.to_s, Flipper::Actor.new("User;#{i}")
12
+ end
11
13
  end
12
14
 
13
15
  Benchmark.ips do |x|
14
16
  x.report("get_all") { flipper.preload_all }
17
+ x.report("features") { flipper.features }
15
18
  end
@@ -59,7 +59,7 @@ module Flipper
59
59
 
60
60
  # Public: The set of known features.
61
61
  def features
62
- with_connection(@feature_class) { @feature_class.all.map(&:key).to_set }
62
+ with_connection(@feature_class) { @feature_class.distinct.pluck(:key).to_set }
63
63
  end
64
64
 
65
65
  # Public: Adds a feature to the set of known features.
@@ -68,9 +68,9 @@ module Flipper
68
68
  # race condition, but add is only used by enable/disable which happen
69
69
  # super rarely, so it shouldn't matter in practice
70
70
  @feature_class.transaction do
71
- unless @feature_class.where(key: feature.key).first
71
+ unless @feature_class.where(key: feature.key).exists?
72
72
  begin
73
- @feature_class.create! { |f| f.key = feature.key }
73
+ @feature_class.create!(key: feature.key)
74
74
  rescue ::ActiveRecord::RecordNotUnique
75
75
  end
76
76
  end
@@ -1,5 +1,5 @@
1
1
  module Flipper
2
- VERSION = '1.2.1'.freeze
2
+ VERSION = '1.3.0.pre'.freeze
3
3
 
4
4
  REQUIRED_RUBY_VERSION = '2.6'.freeze
5
5
  NEXT_REQUIRED_RUBY_VERSION = '3.0'.freeze
@@ -1,5 +1,4 @@
1
1
  SpecHelpers.silence { require 'flipper/adapters/active_record' }
2
- require 'active_support/core_ext/kernel'
3
2
 
4
3
  # Turn off migration logging for specs
5
4
  ActiveRecord::Migration.verbose = false
@@ -17,212 +16,217 @@ RSpec.describe Flipper::Adapters::ActiveRecord do
17
16
 
18
17
  [
19
18
  {
20
- adapter: "sqlite3",
21
- database: ":memory:"
19
+ "adapter" => "sqlite3",
20
+ "database" => ":memory:"
22
21
  },
23
22
 
24
23
  {
25
- adapter: "mysql2",
26
- encoding: "utf8mb4",
27
- username: ENV["MYSQL_USER"] || "root",
28
- password: ENV["MYSQL_PASSWORD"] || "",
29
- database: ENV["MYSQL_DATABASE"] || "flipper_test",
30
- port: ENV["DB_PORT"] || 3306
24
+ "adapter" => "mysql2",
25
+ "encoding" => "utf8mb4",
26
+ "username" => ENV["MYSQL_USER"] || "root",
27
+ "password" => ENV["MYSQL_PASSWORD"] || "",
28
+ "database" => ENV["MYSQL_DATABASE"] || "flipper_test",
29
+ "port" => ENV["DB_PORT"] || 3306
31
30
  },
32
31
 
33
32
  {
34
- adapter: "postgresql",
35
- encoding: "unicode",
36
- host: "127.0.0.1",
37
- username: ENV["POSTGRES_USER"] || "",
38
- password: ENV["POSTGRES_PASSWORD"] || "",
39
- database: ENV["POSTGRES_DATABASE"] || "flipper_test",
33
+ "adapter" => "postgresql",
34
+ "encoding" => "unicode",
35
+ "host" => "127.0.0.1",
36
+ "username" => ENV["POSTGRES_USER"] || "",
37
+ "password" => ENV["POSTGRES_PASSWORD"] || "",
38
+ "database" => ENV["POSTGRES_DATABASE"] || "flipper_test",
40
39
  }
41
40
  ].each do |config|
42
- config = config.with_indifferent_access
43
-
44
- context "with #{config[:adapter]}" do
45
- before(:all) do
46
- silence { ActiveRecord::Tasks::DatabaseTasks.create(config) }
47
- end
48
-
49
- before(:each) do
50
- skip_on_error(ActiveRecord::ConnectionNotEstablished, "#{config[:adapter]} not available") do
51
- ActiveRecord::Base.establish_connection(config)
52
- CreateFlipperTables.migrate(:up)
53
- end
54
- end
55
-
56
- after(:each) do
57
- ActiveRecord::Tasks::DatabaseTasks.purge(config)
58
- ActiveRecord::Base.connection.close
59
- end
60
-
61
- after(:all) do
62
- silence { ActiveRecord::Tasks::DatabaseTasks.drop(config) }
63
- end
64
-
65
- it_should_behave_like 'a flipper adapter'
66
-
67
- it "works when table doesn't exist" do
68
- CreateFlipperTables.migrate(:down)
69
-
70
- Flipper.configuration = nil
71
- Flipper.instance = nil
72
-
73
- expect {
74
- silence do
75
- load 'flipper/adapters/active_record.rb'
76
- Flipper::Adapters::ActiveRecord.new
41
+ context "with #{config['adapter']}" do
42
+ context "with tables created" do
43
+ before(:all) do
44
+ skip_on_error(ActiveRecord::ConnectionNotEstablished, "#{config['adapter']} not available") do
45
+ silence { ActiveRecord::Tasks::DatabaseTasks.create(config) }
77
46
  end
78
- }.not_to raise_error
79
- end
80
-
81
- it "should load actor ids fine" do
82
- flipper.enable_percentage_of_time(:foo, 1)
83
-
84
- Flipper::Adapters::ActiveRecord::Gate.create!(
85
- feature_key: "foo",
86
- key: "actors",
87
- value: "Organization;4",
88
- )
89
47
 
90
- flipper = Flipper.new(subject)
91
- flipper.preload([:foo])
92
- end
93
-
94
- context 'requiring "flipper-active_record"' do
95
- before do
96
48
  Flipper.configuration = nil
97
- Flipper.instance = nil
49
+ end
98
50
 
99
- silence { load 'flipper/adapters/active_record.rb' }
51
+ before(:each) do
52
+ skip_on_error(ActiveRecord::ConnectionNotEstablished, "#{config['adapter']} not available") do
53
+ ActiveRecord::Base.establish_connection(config)
54
+ CreateFlipperTables.migrate(:up)
55
+ end
100
56
  end
101
57
 
102
- it 'configures itself' do
103
- expect(Flipper.adapter.adapter).to be_a(Flipper::Adapters::ActiveRecord)
58
+ after(:each) do
59
+ ActiveRecord::Tasks::DatabaseTasks.purge(config)
60
+ ActiveRecord::Base.connection.close
104
61
  end
105
- end
106
62
 
107
- context "ActiveRecord connection_pool" do
108
- before do
109
- ActiveRecord::Base.clear_active_connections!
63
+ after(:all) do
64
+ silence { ActiveRecord::Tasks::DatabaseTasks.drop(config) } unless $skip
110
65
  end
111
66
 
112
- context "#features" do
113
- it "does not hold onto connections" do
114
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
115
- subject.features
116
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
117
- end
67
+ it_should_behave_like 'a flipper adapter'
118
68
 
119
- it "does not release previously held connection" do
120
- ActiveRecord::Base.connection # establish a new connection
121
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
122
- subject.features
123
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
124
- end
69
+ it "should load actor ids fine" do
70
+ flipper.enable_percentage_of_time(:foo, 1)
71
+
72
+ Flipper::Adapters::ActiveRecord::Gate.create!(
73
+ feature_key: "foo",
74
+ key: "actors",
75
+ value: "Organization;4",
76
+ )
77
+
78
+ flipper = Flipper.new(subject)
79
+ flipper.preload([:foo])
125
80
  end
126
81
 
127
- context "#get_all" do
128
- it "does not hold onto connections" do
129
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
130
- subject.get_all
131
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
82
+ context "ActiveRecord connection_pool" do
83
+ before do
84
+ ActiveRecord::Base.connection_handler.clear_active_connections!
132
85
  end
133
86
 
134
- it "does not release previously held connection" do
135
- ActiveRecord::Base.connection # establish a new connection
136
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
137
- subject.get_all
138
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
87
+ context "#features" do
88
+ it "does not hold onto connections" do
89
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
90
+ subject.features
91
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
92
+ end
93
+
94
+ it "does not release previously held connection" do
95
+ ActiveRecord::Base.connection # establish a new connection
96
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
97
+ subject.features
98
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
99
+ end
139
100
  end
140
- end
141
101
 
142
- context "#add / #remove / #clear" do
143
- let(:feature) { Flipper::Feature.new(:search, subject) }
144
-
145
- it "does not hold onto connections" do
146
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
147
- subject.add(feature)
148
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
149
- subject.remove(feature)
150
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
151
- subject.clear(feature)
152
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
102
+ context "#get_all" do
103
+ it "does not hold onto connections" do
104
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
105
+ subject.get_all
106
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
107
+ end
108
+
109
+ it "does not release previously held connection" do
110
+ ActiveRecord::Base.connection # establish a new connection
111
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
112
+ subject.get_all
113
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
114
+ end
153
115
  end
154
116
 
155
- it "does not release previously held connection" do
156
- ActiveRecord::Base.connection # establish a new connection
157
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
158
- subject.add(feature)
159
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
160
- subject.remove(feature)
161
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
162
- subject.clear(feature)
163
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
117
+ context "#add / #remove / #clear" do
118
+ let(:feature) { Flipper::Feature.new(:search, subject) }
119
+
120
+ it "does not hold onto connections" do
121
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
122
+ subject.add(feature)
123
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
124
+ subject.remove(feature)
125
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
126
+ subject.clear(feature)
127
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
128
+ end
129
+
130
+ it "does not release previously held connection" do
131
+ ActiveRecord::Base.connection # establish a new connection
132
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
133
+ subject.add(feature)
134
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
135
+ subject.remove(feature)
136
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
137
+ subject.clear(feature)
138
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
139
+ end
164
140
  end
165
- end
166
141
 
167
- context "#get_multi" do
168
- let(:feature) { Flipper::Feature.new(:search, subject) }
142
+ context "#get_multi" do
143
+ let(:feature) { Flipper::Feature.new(:search, subject) }
144
+
145
+ it "does not hold onto connections" do
146
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
147
+ subject.get_multi([feature])
148
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
149
+ end
150
+
151
+ it "does not release previously held connection" do
152
+ ActiveRecord::Base.connection # establish a new connection
153
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
154
+ subject.get_multi([feature])
155
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
156
+ end
157
+ end
169
158
 
170
- it "does not hold onto connections" do
171
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
172
- subject.get_multi([feature])
173
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
159
+ context "#enable/#disable boolean" do
160
+ let(:feature) { Flipper::Feature.new(:search, subject) }
161
+ let(:gate) { feature.gate(:boolean)}
162
+
163
+ it "does not hold onto connections" do
164
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
165
+ subject.enable(feature, gate, gate.wrap(true))
166
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
167
+ subject.disable(feature, gate, gate.wrap(false))
168
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
169
+ end
170
+
171
+ it "does not release previously held connection" do
172
+ ActiveRecord::Base.connection # establish a new connection
173
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
174
+ subject.enable(feature, gate, gate.wrap(true))
175
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
176
+ subject.disable(feature, gate, gate.wrap(false))
177
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
178
+ end
174
179
  end
175
180
 
176
- it "does not release previously held connection" do
177
- ActiveRecord::Base.connection # establish a new connection
178
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
179
- subject.get_multi([feature])
180
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
181
+ context "#enable/#disable set" do
182
+ let(:feature) { Flipper::Feature.new(:search, subject) }
183
+ let(:gate) { feature.gate(:group) }
184
+
185
+ it "does not hold onto connections" do
186
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
187
+ subject.enable(feature, gate, gate.wrap(:admin))
188
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
189
+ subject.disable(feature, gate, gate.wrap(:admin))
190
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
191
+ end
192
+
193
+ it "does not release previously held connection" do
194
+ ActiveRecord::Base.connection # establish a new connection
195
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
196
+ subject.enable(feature, gate, gate.wrap(:admin))
197
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
198
+ subject.disable(feature, gate, gate.wrap(:admin))
199
+ expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
200
+ end
181
201
  end
182
202
  end
183
203
 
184
- context "#enable/#disable boolean" do
185
- let(:feature) { Flipper::Feature.new(:search, subject) }
186
- let(:gate) { feature.gate(:boolean)}
204
+ context 'requiring "flipper-active_record"' do
205
+ before do
206
+ Flipper.configuration = nil
207
+ Flipper.instance = nil
187
208
 
188
- it "does not hold onto connections" do
189
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
190
- subject.enable(feature, gate, gate.wrap(true))
191
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
192
- subject.disable(feature, gate, gate.wrap(false))
193
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
209
+ silence { load 'flipper/adapters/active_record.rb' }
194
210
  end
195
211
 
196
- it "does not release previously held connection" do
197
- ActiveRecord::Base.connection # establish a new connection
198
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
199
- subject.enable(feature, gate, gate.wrap(true))
200
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
201
- subject.disable(feature, gate, gate.wrap(false))
202
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
212
+ it 'configures itself' do
213
+ expect(Flipper.adapter.adapter).to be_a(Flipper::Adapters::ActiveRecord)
203
214
  end
204
215
  end
216
+ end
205
217
 
206
- context "#enable/#disable set" do
207
- let(:feature) { Flipper::Feature.new(:search, subject) }
208
- let(:gate) { feature.gate(:group) }
218
+ it "works when table doesn't exist" do
209
219
 
210
- it "does not hold onto connections" do
211
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
212
- subject.enable(feature, gate, gate.wrap(:admin))
213
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
214
- subject.disable(feature, gate, gate.wrap(:admin))
215
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
216
- end
220
+ Flipper.configuration = nil
221
+ Flipper.instance = nil
217
222
 
218
- it "does not release previously held connection" do
219
- ActiveRecord::Base.connection # establish a new connection
220
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
221
- subject.enable(feature, gate, gate.wrap(:admin))
222
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
223
- subject.disable(feature, gate, gate.wrap(:admin))
224
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
225
- end
223
+ Flipper::Adapters.send(:remove_const, :ActiveRecord) if Flipper::Adapters.const_defined?(:ActiveRecord)
224
+
225
+ silence do
226
+ expect {
227
+ load 'flipper/adapters/active_record.rb'
228
+ Flipper::Adapters::ActiveRecord.new
229
+ }.not_to raise_error
226
230
  end
227
231
  end
228
232
  end
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.2.1
4
+ version: 1.3.0.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Nunemaker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-15 00:00:00.000000000 Z
11
+ date: 2024-03-14 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.2.1
19
+ version: 1.3.0.pre
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.2.1
26
+ version: 1.3.0.pre
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activerecord
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -74,7 +74,7 @@ metadata:
74
74
  homepage_uri: https://www.flippercloud.io
75
75
  source_code_uri: https://github.com/flippercloud/flipper
76
76
  bug_tracker_uri: https://github.com/flippercloud/flipper/issues
77
- changelog_uri: https://github.com/flippercloud/flipper/releases/tag/v1.2.1
77
+ changelog_uri: https://github.com/flippercloud/flipper/releases/tag/v1.3.0.pre
78
78
  post_install_message:
79
79
  rdoc_options: []
80
80
  require_paths: