flipper-sequel 1.0.0.pre → 1.1.0

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: 32ef5dc9ab6ca6df16bfdbed17b16ff64c201708d4b168a29bdd834f457048d8
4
- data.tar.gz: b8642a57b100538a43d6214d81d869fbc31a3fc1289573bf821c074c69776787
3
+ metadata.gz: 3519a5c581ad82919b61c95bf34cbd7a49175dac13264c7af7d45d0430619ba2
4
+ data.tar.gz: eb1ef47eab6e6e7d253a2aa066ac1aae9c8ef7e32f3d964fcec2749f9894ac58
5
5
  SHA512:
6
- metadata.gz: f24f9c956369d006c53e8588c3cc6f46976c2ec9646ed611ba35d07f8dd36430e63f49a1c83678c48f199938a58caac44347da67764b3dd2982ecbadf1685939
7
- data.tar.gz: 1e974806948ef0cf2482d5e3288256aa7c01d1722c2acf417d29c2706903bd1a8c0cb2cbd6fec6c9277e2b4d2809bb9667007ebfc1bd8d5fb644980d15778a24
6
+ metadata.gz: c7167b1b5af764176e44702c78f7a8c3994588eef2c47670aa6614908f2cda14d66b9e881f49f9b35ba8f853f5b1ae8c11c004ca7a9fb701e66887f2a935a219
7
+ data.tar.gz: dc2607e6ecc423924b5886a3bcaef3a58f9ba9f220dbcbeb3297178f6b4ca0214ad62f72528044df07bcac9850c8c25110ee248c1ea728350be780f87cba8f04
@@ -1,6 +1,7 @@
1
1
  require 'set'
2
2
  require 'flipper'
3
3
  require 'sequel'
4
+ require 'flipper/model/sequel'
4
5
 
5
6
  module Flipper
6
7
  module Adapters
@@ -28,12 +29,14 @@ module Flipper
28
29
  ::Sequel::Model.require_valid_table = old
29
30
  end
30
31
 
31
- # Public: The name of the adapter.
32
- attr_reader :name
32
+ VALUE_TO_TEXT_WARNING = <<-EOS
33
+ Your database needs migrated to use the latest Flipper features.
34
+ See https://github.com/flippercloud/flipper/issues/557
35
+ EOS
33
36
 
34
37
  # Public: Initialize a new Sequel adapter instance.
35
38
  #
36
- # name - The Symbol name for this adapter. Optional (default :active_record)
39
+ # name - The Symbol name for this adapter. Optional (default :sequel)
37
40
  # feature_class - The AR class responsible for the features table.
38
41
  # gate_class - The AR class responsible for the gates table.
39
42
  #
@@ -47,6 +50,8 @@ module Flipper
47
50
  @name = options.fetch(:name, :sequel)
48
51
  @feature_class = options.fetch(:feature_class) { Feature }
49
52
  @gate_class = options.fetch(:gate_class) { Gate }
53
+
54
+ warn VALUE_TO_TEXT_WARNING if value_not_text?
50
55
  end
51
56
 
52
57
  # Public: The set of known features.
@@ -129,10 +134,9 @@ module Flipper
129
134
  when :integer
130
135
  set(feature, gate, thing)
131
136
  when :set
132
- begin
133
- @gate_class.create(gate_attrs(feature, gate, thing))
134
- rescue ::Sequel::UniqueConstraintViolation
135
- end
137
+ enable_multi(feature, gate, thing)
138
+ when :json
139
+ set(feature, gate, thing, json: true)
136
140
  else
137
141
  unsupported_data_type gate.data_type
138
142
  end
@@ -153,9 +157,10 @@ module Flipper
153
157
  clear(feature)
154
158
  when :integer
155
159
  set(feature, gate, thing)
160
+ when :json
161
+ delete(feature, gate)
156
162
  when :set
157
- @gate_class.where(gate_attrs(feature, gate, thing))
158
- .delete
163
+ @gate_class.where(gate_attrs(feature, gate, thing, json: gate.data_type == :json)).delete
159
164
  else
160
165
  unsupported_data_type gate.data_type
161
166
  end
@@ -171,27 +176,37 @@ module Flipper
171
176
 
172
177
  def set(feature, gate, thing, options = {})
173
178
  clear_feature = options.fetch(:clear, false)
174
- args = {
175
- feature_key: feature.key,
176
- key: gate.key.to_s,
177
- }
179
+ json_feature = options.fetch(:json, false)
180
+
181
+ raise VALUE_TO_TEXT_WARNING if json_feature && value_not_text?
178
182
 
179
183
  @gate_class.db.transaction do
180
184
  clear(feature) if clear_feature
181
- @gate_class.where(args).delete
185
+ delete(feature, gate)
182
186
 
183
187
  begin
184
- @gate_class.create(gate_attrs(feature, gate, thing))
188
+ @gate_class.create(gate_attrs(feature, gate, thing, json: json_feature))
185
189
  rescue ::Sequel::UniqueConstraintViolation
186
190
  end
187
191
  end
188
192
  end
189
193
 
190
- def gate_attrs(feature, gate, thing)
194
+ def delete(feature, gate)
195
+ @gate_class.where(feature_key: feature.key, key: gate.key.to_s).delete
196
+ end
197
+
198
+ def enable_multi(feature, gate, thing)
199
+ begin
200
+ @gate_class.create(gate_attrs(feature, gate, thing, json: gate.data_type == :json))
201
+ rescue ::Sequel::UniqueConstraintViolation
202
+ end
203
+ end
204
+
205
+ def gate_attrs(feature, gate, thing, json: false)
191
206
  {
192
207
  feature_key: feature.key.to_s,
193
208
  key: gate.key.to_s,
194
- value: thing.value.to_s,
209
+ value: json ? Typecast.to_json(thing.value) : thing.value.to_s,
195
210
  }
196
211
  end
197
212
 
@@ -210,11 +225,21 @@ module Flipper
210
225
  end
211
226
  when :set
212
227
  db_gates.select { |db_gate| db_gate.key == gate.key.to_s }.map(&:value).to_set
228
+ when :json
229
+ if detected_db_gate = db_gates.detect { |db_gate| db_gate.key == gate.key.to_s }
230
+ Typecast.from_json(detected_db_gate.value)
231
+ end
213
232
  else
214
233
  unsupported_data_type gate.data_type
215
234
  end
216
235
  end
217
236
  end
237
+
238
+ # Check if value column is text instead of string
239
+ # See https://github.com/flippercloud/flipper/pull/692
240
+ def value_not_text?
241
+ "text".casecmp(@gate_class.db_schema[:value][:db_type]) != 0
242
+ end
218
243
  end
219
244
  end
220
245
  end
@@ -223,4 +248,4 @@ Flipper.configure do |config|
223
248
  config.adapter { Flipper::Adapters::Sequel.new }
224
249
  end
225
250
 
226
- Sequel::Model.include Flipper::Identifier
251
+ Sequel::Model.include Flipper::Model::Sequel
@@ -0,0 +1,12 @@
1
+ module Flipper
2
+ module Model
3
+ module Sequel
4
+ include Flipper::Identifier
5
+
6
+ # Properties used to evaluate expressions
7
+ def flipper_properties
8
+ {"type" => self.class.name}.update(to_hash.transform_keys(&:to_s))
9
+ end
10
+ end
11
+ end
12
+ end
@@ -1,3 +1,3 @@
1
1
  module Flipper
2
- VERSION = '1.0.0.pre'.freeze
2
+ VERSION = '1.1.0'.freeze
3
3
  end
@@ -9,7 +9,7 @@ class CreateFlipperTablesSequel < Sequel::Migration
9
9
  create_table :flipper_gates do |_t|
10
10
  String :feature_key, null: false
11
11
  String :key, null: false
12
- String :value
12
+ String :value, text: true
13
13
  DateTime :created_at, null: false
14
14
  DateTime :updated_at, null: false
15
15
  primary_key [:feature_key, :key, :value]
@@ -42,5 +42,9 @@ RSpec.describe Flipper::Adapters::Sequel do
42
42
  it "defines #flipper_id on Sequel::Model" do
43
43
  expect(Sequel::Model.ancestors).to include(Flipper::Identifier)
44
44
  end
45
+
46
+ it "defines #flipper_properties on Sequel::Model" do
47
+ expect(Sequel::Model.ancestors).to include(Flipper::Model::Sequel)
48
+ end
45
49
  end
46
50
  end
@@ -0,0 +1,46 @@
1
+ require 'flipper/model/sequel'
2
+
3
+ RSpec.describe Flipper::Model::Sequel do
4
+ before(:each) do
5
+ Sequel::Model.db.run <<-SQL
6
+ CREATE TABLE users (
7
+ id integer PRIMARY KEY,
8
+ name string NOT NULL,
9
+ age integer,
10
+ is_confirmed boolean,
11
+ created_at datetime NOT NULL,
12
+ updated_at datetime NOT NULL
13
+ )
14
+ SQL
15
+
16
+ @User = Class.new(::Sequel::Model(:users)) do
17
+ include Flipper::Model::Sequel
18
+ plugin :timestamps, update_on_create: true
19
+
20
+
21
+ def self.name
22
+ 'User'
23
+ end
24
+ end
25
+ end
26
+
27
+ after(:each) do
28
+ Sequel::Model.db.run("DROP table IF EXISTS `users`")
29
+ end
30
+
31
+ describe "flipper_properties" do
32
+ subject { @User.create(name: "Test", age: 22, is_confirmed: true) }
33
+
34
+ it "includes all attributes" do
35
+ expect(subject.flipper_properties).to eq({
36
+ "type" => "User",
37
+ "id" => subject.id,
38
+ "name" => "Test",
39
+ "age" => 22,
40
+ "is_confirmed" => true,
41
+ "created_at" => subject.created_at,
42
+ "updated_at" => subject.updated_at
43
+ })
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,5 @@
1
+ # Setup sequel for sequel adapter and model specs. We don't want this to happen
2
+ # multiple times or it causes failures. So it lives here.
3
+ require "sequel"
4
+ Sequel::Model.db = Sequel.sqlite(':memory:')
5
+ Sequel.extension :migration, :core_extensions
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flipper-sequel
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.pre
4
+ version: 1.1.0
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-02 00:00:00.000000000 Z
11
+ date: 2023-12-08 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.pre
19
+ version: 1.1.0
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.pre
26
+ version: 1.1.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: sequel
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -55,9 +55,12 @@ files:
55
55
  - flipper-sequel.gemspec
56
56
  - lib/flipper-sequel.rb
57
57
  - lib/flipper/adapters/sequel.rb
58
+ - lib/flipper/model/sequel.rb
58
59
  - lib/flipper/version.rb
59
60
  - lib/generators/flipper/templates/sequel_migration.rb
60
61
  - spec/flipper/adapters/sequel_spec.rb
62
+ - spec/flipper/model/sequel_spec.rb
63
+ - spec/support/sequel_setup.rb
61
64
  - test/adapters/sequel_test.rb
62
65
  homepage: https://www.flippercloud.io/docs/adapters/sequel
63
66
  licenses:
@@ -65,9 +68,9 @@ licenses:
65
68
  metadata:
66
69
  documentation_uri: https://www.flippercloud.io/docs
67
70
  homepage_uri: https://www.flippercloud.io
68
- source_code_uri: https://github.com/jnunemaker/flipper
69
- bug_tracker_uri: https://github.com/jnunemaker/flipper/issues
70
- changelog_uri: https://github.com/jnunemaker/flipper/blob/main/Changelog.md
71
+ source_code_uri: https://github.com/flippercloud/flipper
72
+ bug_tracker_uri: https://github.com/flippercloud/flipper/issues
73
+ changelog_uri: https://github.com/flippercloud/flipper/blob/main/Changelog.md
71
74
  post_install_message:
72
75
  rdoc_options: []
73
76
  require_paths:
@@ -79,14 +82,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
79
82
  version: '0'
80
83
  required_rubygems_version: !ruby/object:Gem::Requirement
81
84
  requirements:
82
- - - ">"
85
+ - - ">="
83
86
  - !ruby/object:Gem::Version
84
- version: 1.3.1
87
+ version: '0'
85
88
  requirements: []
86
- rubygems_version: 3.3.7
89
+ rubygems_version: 3.4.10
87
90
  signing_key:
88
91
  specification_version: 4
89
92
  summary: Sequel adapter for Flipper
90
93
  test_files:
91
94
  - spec/flipper/adapters/sequel_spec.rb
95
+ - spec/flipper/model/sequel_spec.rb
96
+ - spec/support/sequel_setup.rb
92
97
  - test/adapters/sequel_test.rb