statisfy 0.0.6 → 0.0.8

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: 6383d7143334e6448a05a5afb28b751f35afc830e04a2ad93dfe58a31a63a55f
4
- data.tar.gz: eaf65b189c72a4fa77a439d4aff01bd6eeacf653036194e70085823433476e4f
3
+ metadata.gz: b1fc7262fee03a85f7aec7875b837371114d2205e2e88ed1d4adb372c83025a7
4
+ data.tar.gz: 14e250747429e2dc67861b13bc6c249cb07fb1a616b9248f37e69d46578c2f9b
5
5
  SHA512:
6
- metadata.gz: ff8563a77a395cee961fbed96a2b58df75d9d284f737b30341f448cd0cd6f5e7c46b9dd64f3fc077f1c1dafc3ee8de7228f6c48d8bc195fcd5af15f22bd374ac
7
- data.tar.gz: dfb1216d2ffb054c81f9055da931bb8d0e766ff148a95cb090afbccdffd36d27c8fd72fd55d8f5b73f5f0b54e8d381e23ab8392681cf9ea4cf337aac39f5e153
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
@@ -10,14 +10,14 @@ module Statisfy
10
10
  end
11
11
 
12
12
  module ClassMethods
13
- def count(params)
13
+ def statisfy_count(params)
14
14
  raise ArgumentError, "Missing :as parameter" unless params[:as]
15
15
 
16
16
  class_name = params[:as].to_s.camelize
17
17
 
18
18
  eval <<-RUBY, binding, __FILE__, __LINE__ + 1
19
19
  class ::Statisfy::#{class_name}
20
- include Statisfy::Counter
20
+ include Statisfy::#{params[:type] == :aggregate ? "Aggregate" : "Counter"}
21
21
  end
22
22
  RUBY
23
23
 
@@ -27,9 +27,12 @@ module Statisfy
27
27
  end
28
28
  RUBY
29
29
 
30
- "::Statisfy::#{class_name}".constantize.send(__method__, **params)
30
+ "::Statisfy::#{class_name}".constantize.send(:count, **params)
31
+ end
32
+
33
+ def statisfy_aggregate(params)
34
+ statisfy_count(params.merge(type: :aggregate))
31
35
  end
32
- alias aggregate count
33
36
  end
34
37
  end
35
38
  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.6
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