statisfy 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/statisfy/counter.rb +38 -37
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1b485c63cd06fb497bc3b0426082f221b99e78ae5d95573fe4b747c0e0ddec5d
4
- data.tar.gz: 930b4574ad28f2ad09b85fe8ff3c96075bbcbf4585af7520526ba24fa77e6f21
3
+ metadata.gz: b1fc7262fee03a85f7aec7875b837371114d2205e2e88ed1d4adb372c83025a7
4
+ data.tar.gz: 14e250747429e2dc67861b13bc6c249cb07fb1a616b9248f37e69d46578c2f9b
5
5
  SHA512:
6
- metadata.gz: 4da2848076d5caf49a8c5e5084763bd5c4625b28bbcb0bb59ae7710382f558667fddbe783507fb4bb1221ba5ce9239e478946317dfbcf55963139137009b5ce7
7
- data.tar.gz: 1b1e517c2f3676253909cc2583440bdb22b84eb19baa46177c6b4572aa2c6d27ca94fe1cbfee2495e805051cf0fcdf950c69c837af8bd6ad80dd0e0e0a7c1d49
6
+ metadata.gz: 84612c386cf3ec0e0c941404cf0f74c3acba3c37f41cfc2f3ae34ab689f8ffcd603a1a16d27e7c15efc5b3ee9ab76d05a15f882a2a739b0b7ea08ff324d5dba6
7
+ data.tar.gz: 4980ac9dd156ea28aeae6f1ab1c48f6ec5804b572eca27427f05abebf82a1db747f0e9d27c97a1d5a0e100ef580083d3018e0bcf19d7a086f239145375707459
@@ -39,16 +39,12 @@ module Statisfy
39
39
  # but the `count` DSL defines them automatically based on the options provided
40
40
  #
41
41
  def apply_default_counter_options(args)
42
- define_method(:identifier, args[:uniq_by] || -> { nil })
42
+ define_method(:identifier, args[:value] || args[:uniq_by] || -> { nil })
43
43
  define_method(:scopes, args[:scopes] || Statisfy.configuration.default_scopes || -> { [] })
44
44
  define_method(:if_async, args[:if_async] || -> { true })
45
45
  define_method(:decrement?, args[:decrement_if] || -> { false })
46
- define_method(:value, args[:value] || -> {})
47
46
  define_method(:should_run?, args[:if] || -> { true })
48
- define_method(:on_destroy, args[:on_destroy]) if args[:on_destroy].present?
49
- define_method(:decrement_on_destroy?, args[:decrement_on_destroy].is_a?(Proc) ? args[:decrement_on_destroy] : lambda {
50
- args[:decrement_on_destroy] || true
51
- })
47
+ define_method(:decrement_on_destroy?, -> { args[:decrement_on_destroy] != false })
52
48
  end
53
49
 
54
50
  #
@@ -70,6 +66,10 @@ module Statisfy
70
66
  end
71
67
  end
72
68
 
69
+ def aggregate_counter?
70
+ const_get(:COUNTER_TYPE) == :aggregate
71
+ end
72
+
73
73
  def size(scope: nil, month: nil)
74
74
  redis_client.scard(key_for(scope:, month:))
75
75
  end
@@ -128,7 +128,7 @@ module Statisfy
128
128
  # This allows to run a counter increment manually
129
129
  # It is useful when you want to backfill counters
130
130
  #
131
- def initialize_with(resource, options = {})
131
+ def trigger_with(resource, options = {})
132
132
  counter = new
133
133
  counter.params = resource
134
134
 
@@ -177,36 +177,22 @@ module Statisfy
177
177
  end
178
178
 
179
179
  def process_event
180
- return if destroy_event_handled?
180
+ return decrement if can_decrement_on_destroy?
181
181
  return unless if_async
182
182
 
183
- if value.present?
184
- append(value:)
183
+ if self.class.aggregate_counter?
184
+ append
185
185
  else
186
186
  decrement? ? decrement : increment
187
187
  end
188
188
  end
189
189
 
190
- def destroy_event_handled?
191
- return false unless params[:statisfy_trigger] == :destroy && value.blank?
192
-
193
- if decrement_on_destroy?
194
- decrement
195
- return true
196
- elsif respond_to?(:on_destroy)
197
- on_destroy
198
- return true
199
- end
200
-
201
- false
202
- end
203
-
204
- def key_value
205
- value || identifier || params["id"]
190
+ def can_decrement_on_destroy?
191
+ params[:statisfy_trigger] == :destroy && !self.class.aggregate_counter? && decrement_on_destroy?
206
192
  end
207
193
 
208
- def custom_key_value?
209
- identifier.present? || value.present?
194
+ def value
195
+ identifier || params["id"]
210
196
  end
211
197
 
212
198
  #
@@ -223,15 +209,19 @@ module Statisfy
223
209
 
224
210
  def increment
225
211
  all_counters do |key|
226
- self.class.redis_client.sadd?(key, key_value)
227
- self.class.redis_client.sadd?(uniq_by_ids(key), params["id"]) if custom_key_value?
212
+ self.class.redis_client.sadd?(key, value)
213
+
214
+ # When setting a uniq_by option, we use this set to keep track of the number of unique instances
215
+ # with the same identifier.
216
+ # When there are no more instances with this identifier, we can decrement the counter
217
+ self.class.redis_client.sadd?(key_for_instance_ids(key), params["id"]) if identifier.present?
228
218
  end
229
219
  end
230
220
 
231
221
  #
232
222
  # To be used to store a list of values instead of a basic counter
233
223
  #
234
- def append(value:)
224
+ def append
235
225
  all_counters do |key|
236
226
  self.class.redis_client.rpush(key, value)
237
227
  end
@@ -240,18 +230,29 @@ module Statisfy
240
230
  # rubocop:disable Metrics/AbcSize
241
231
  def decrement
242
232
  all_counters do |key|
243
- if custom_key_value?
244
- self.class.redis_client.srem?(uniq_by_ids(key), params["id"])
245
- self.class.redis_client.srem?(key, key_value) if self.class.redis_client.scard(uniq_by_ids(key)).zero?
233
+ if identifier.present?
234
+ self.class.redis_client.srem?(key_for_instance_ids(key), params["id"])
235
+ self.class.redis_client.srem?(key, value) if no_more_instances_with_this_identifier?(key)
246
236
  else
247
- self.class.redis_client.srem?(key, key_value)
237
+ self.class.redis_client.srem?(key, value)
248
238
  end
249
239
  end
250
240
  end
251
241
  # rubocop:enable Metrics/AbcSize
252
242
 
253
- def uniq_by_ids(key)
254
- "#{key};#{key_value}"
243
+ def no_more_instances_with_this_identifier?(key)
244
+ self.class.redis_client.scard(key_for_instance_ids(key)).zero?
245
+ end
246
+
247
+ #
248
+ # This redis key is used when setting a uniq_by. It stores the list of ids of the main resource (e.g. User)
249
+ # in order to count the number of unique instances with the same identifier
250
+ #
251
+ # When the associated array becomes empty, it means that we can
252
+ # decrement the counter because there are no more instances associated with this identifier
253
+ #
254
+ def key_for_instance_ids(key)
255
+ JSON.parse(key).merge("subject_id" => identifier).to_json
255
256
  end
256
257
  end
257
258
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: statisfy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michaël Villeneuve
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-07 00:00:00.000000000 Z
11
+ date: 2023-12-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord