trackoid 0.1.12 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -187,6 +187,27 @@ For comparison, this README is already 8.5Kb in size...
187
187
 
188
188
 
189
189
  = Revision History
190
+
191
+ 0.2.0 - Added 'reset' and 'erase' methods to tracker fields:
192
+ * Reset does the same as "set" but also sets aggregate fields.
193
+
194
+ Example:
195
+
196
+ A) model.value(aggregate_data).set(5)
197
+ B) model.value(aggregate_data).reset(5)
198
+
199
+ A will set "5" to the 'value' and to the aggregate.
200
+ B will set "5" to the 'value' and all aggregates.
201
+
202
+ * Erase resets the values in the mongo database. Note that this
203
+ is completely different of doing 'reset(0)'. (With erase you
204
+ can actually recall space from the database).
205
+
206
+ - Trackoid now uses "unsafe" mongo update calls from the driver.
207
+ Note that despite the name, trackoid is absolutely safe, the only
208
+ diference is that 'update' simply now returns inmediately, without
209
+ waiting for the OK response from the database.
210
+
190
211
  0.1.12 - Previously known as "accessors" methods, now they are promoted as
191
212
  "Reader" methods and now they live in its own Module.
192
213
  (Accessor methods are those like "today", "on", "last_days", etc,
@@ -198,14 +219,15 @@ For comparison, this README is already 8.5Kb in size...
198
219
  0.1.10 - Renamed accessor methods from "all", "last", "first" to
199
220
  "all_values", "first_value" and "last_value" so as not to
200
221
  conflict with traditional ActiveRecord accessors.
222
+
201
223
  - Aggregate methods with a key returns a single instance, not an
202
224
  Array. For example:
203
-
225
+
204
226
  @page.visits.browser("mozilla").today
205
227
  # Returns now a number instead of an Array
206
228
 
207
229
  - Arguments are now passed thru aggregator accessors. For example:
208
-
230
+
209
231
  @page.visits.brosers("mozilla").last_days(15)
210
232
  # Should correctly return now an array with 15 elements.
211
233
 
@@ -219,7 +241,11 @@ For comparison, this README is already 8.5Kb in size...
219
241
 
220
242
  0.1.6 - Enabled support for String dates in operators. This string date
221
243
  must be DateTime parseable.
222
- For example: @spain.world_cups.inc("2010-07-11")
244
+
245
+ Example:
246
+
247
+ @spain.world_cups.inc("2010-07-11")
248
+
223
249
  - Normalized Date and DateTime objects to use only Date methods.
224
250
  - Added "first" / "first_date" / "last" / "last_date" accessors.
225
251
  - Added "all" accessor.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.12
1
+ 0.2.0
@@ -48,7 +48,7 @@ module Mongoid #:nodoc:
48
48
  @owner.collection.update(
49
49
  @owner._selector,
50
50
  { (how_much > 0 ? "$inc" : "$dec") => update_hash(how_much.abs, date) },
51
- :upsert => true
51
+ :upsert => true, :safe => false
52
52
  )
53
53
  return unless @owner.aggregated?
54
54
 
@@ -59,7 +59,7 @@ module Mongoid #:nodoc:
59
59
  @owner.aggregate_klass.collection.update(
60
60
  selector,
61
61
  { (how_much > 0 ? "$inc" : "$dec") => update_hash(how_much.abs, date) },
62
- :upsert => true
62
+ :upsert => true, :safe => false
63
63
  )
64
64
  end
65
65
  end
@@ -76,9 +76,8 @@ module Mongoid #:nodoc:
76
76
  raise Errors::ModelNotSaved, "Can't update a new record" if @owner.new_record?
77
77
  update_data(how_much, date)
78
78
  @owner.collection.update(
79
- @owner._selector,
80
- { "$set" => update_hash(how_much, date) },
81
- :upsert => true
79
+ @owner._selector, { "$set" => update_hash(how_much, date) },
80
+ :upsert => true, :safe => false
82
81
  )
83
82
  return unless @owner.aggregated?
84
83
 
@@ -87,9 +86,51 @@ module Mongoid #:nodoc:
87
86
  fk = @owner.class.name.to_s.foreign_key.to_sym
88
87
  selector = { fk => @owner.id, :ns => k, :key => token.to_s }
89
88
  @owner.aggregate_klass.collection.update(
90
- selector,
91
- { "$set" => update_hash(how_much, date) },
92
- :upsert => true
89
+ selector, { "$set" => update_hash(how_much, date) },
90
+ :upsert => true, :safe => false
91
+ )
92
+ end
93
+ end
94
+
95
+ def reset(how_much, date = Date.today)
96
+ return erase(date) if how_much.nil?
97
+
98
+ # First, we use the default "set" for the tracking field
99
+ # This will also update one aggregate but... oh well...
100
+ set(how_much, date)
101
+
102
+ # Need to iterate over all aggregates and send an update or delete
103
+ # operations over all mongo records for this aggregate field
104
+ @owner.aggregate_fields.each do |(k,v)|
105
+ fk = @owner.class.name.to_s.foreign_key.to_sym
106
+ selector = { fk => @owner.id, :ns => k }
107
+ @owner.aggregate_klass.collection.update(
108
+ selector, { "$set" => update_hash(how_much, date) },
109
+ :upsert => true, :multi => true, :safe => false
110
+ )
111
+ end
112
+ end
113
+
114
+ def erase(date = Date.today)
115
+ raise Errors::ModelNotSaved, "Can't update a new record" if @owner.new_record?
116
+
117
+ # For the in memory data, we just need to set it to nil
118
+ update_data(nil, date)
119
+ @owner.collection.update(
120
+ @owner._selector,
121
+ { "$unset" => update_hash(1, date) },
122
+ :upsert => true, :safe => false
123
+ )
124
+ return unless @owner.aggregated?
125
+
126
+ # Need to iterate over all aggregates and send an update or delete
127
+ # operations over all mongo records
128
+ @owner.aggregate_fields.each do |(k,v)|
129
+ fk = @owner.class.name.to_s.foreign_key.to_sym
130
+ selector = { fk => @owner.id, :ns => k }
131
+ @owner.aggregate_klass.collection.update(
132
+ selector, { "$unset" => update_hash(1, date) },
133
+ :upsert => true, :multi => true, :safe => false
93
134
  )
94
135
  end
95
136
  end
@@ -158,7 +158,7 @@ describe Mongoid::Tracking::Aggregates do
158
158
  @object_id = SecondTestModel.first.id
159
159
  @mock = SecondTestModel.find(@object_id)
160
160
  end
161
-
161
+
162
162
  it "should correctly save all aggregation keys as strings (inc)" do
163
163
  @mock.something("test").inc
164
164
  @mock.something.aggregate_one.first.key.is_a?(String).should be_true
@@ -174,7 +174,6 @@ describe Mongoid::Tracking::Aggregates do
174
174
  @mock.something.aggregate_three.first.key.is_a?(String).should be_true
175
175
  @mock.something.aggregate_four.first.key.is_a?(String).should be_true
176
176
  end
177
-
178
177
  end
179
178
 
180
179
  describe "when tracking a model with aggregation data" do
@@ -233,8 +232,8 @@ describe Mongoid::Tracking::Aggregates do
233
232
 
234
233
  it "should work adding 1 visit with different aggregation data" do
235
234
  @mock.visits("Google Chrome").inc
236
- @mock.visits.browsers.today.should == [["mozilla", 1], ["google", 1]]
237
- @mock.visits.referers.today.should == [["firefox", 1], ["chrome", 1]]
235
+ @mock.visits.browsers.today.should =~ [["mozilla", 1], ["google", 1]]
236
+ @mock.visits.referers.today.should =~ [["firefox", 1], ["chrome", 1]]
238
237
 
239
238
  # Just for testing array manipulations
240
239
  @mock.visits.browsers.today.inject(0) {|total, c| total + c.last }.should == 2
@@ -246,22 +245,22 @@ describe Mongoid::Tracking::Aggregates do
246
245
 
247
246
  it "should work also with set" do
248
247
  @mock.visits("Google Chrome").set(5)
249
- @mock.visits.browsers.today.should == [["mozilla", 1], ["google", 5]]
250
- @mock.visits.referers.today.should == [["firefox", 1], ["chrome", 5]]
248
+ @mock.visits.browsers.today.should =~ [["mozilla", 1], ["google", 5]]
249
+ @mock.visits.referers.today.should =~ [["firefox", 1], ["chrome", 5]]
251
250
  @mock.visits.today.should == 5
252
251
  end
253
252
 
254
253
  it "let's check what happens when sorting the best browser..." do
255
254
  @mock.visits("Google Chrome").inc
256
- @mock.visits.browsers.today.should == [["mozilla", 1], ["google", 6]]
255
+ @mock.visits.browsers.today.should =~ [["mozilla", 1], ["google", 6]]
257
256
  @mock.visits.browsers.today.max {|a,b| a.second <=> b.second }.should == ["google", 6]
258
257
  end
259
258
 
260
259
  it "should work without aggregation information" do
261
260
  @mock.visits.inc
262
- @mock.visits.browsers.today.should == [["mozilla", 1], ["google", 6]]
263
- @mock.visits.referers.today.should == [["firefox", 1], ["chrome", 6]]
264
-
261
+ @mock.visits.browsers.today.should =~ [["mozilla", 1], ["google", 6]]
262
+ @mock.visits.referers.today.should =~ [["firefox", 1], ["chrome", 6]]
263
+
265
264
  # A more throughout test would check totals...
266
265
  visits_today = @mock.visits.today
267
266
  visits_today_with_browser = @mock.visits.browsers.today.inject(0) {|total, c| total + c.last }
@@ -269,6 +268,107 @@ describe Mongoid::Tracking::Aggregates do
269
268
  end
270
269
  end
271
270
 
271
+ describe "When using reset method for aggregates" do
272
+ before do
273
+ TestModel.all.map(&:destroy)
274
+ TestModel.create(:name => "test")
275
+
276
+ @object_id = TestModel.first.id
277
+ @mock = TestModel.first
278
+
279
+ @mock.visits("Mozilla Firefox").set(1, "2010-07-11")
280
+ @mock.visits("Google Chrome").set(2, "2010-07-11")
281
+ @mock.visits("Internet Explorer").set(3, "2010-07-11")
282
+
283
+ @mock.visits("Mozilla Firefox").set(4, "2010-07-14")
284
+ @mock.visits("Google Chrome").set(5, "2010-07-14")
285
+ @mock.visits("Internet Explorer").set(6, "2010-07-14")
286
+
287
+ @mock.uniques("Mozilla Firefox").set(1, "2010-07-11")
288
+ @mock.uniques("Google Chrome").set(2, "2010-07-11")
289
+ @mock.uniques("Internet Explorer").set(3, "2010-07-11")
290
+
291
+ @mock.uniques("Mozilla Firefox").set(4, "2010-07-14")
292
+ @mock.uniques("Google Chrome").set(5, "2010-07-14")
293
+ @mock.uniques("Internet Explorer").set(6, "2010-07-14")
294
+ end
295
+
296
+ it "should have the correct values when using a value" do
297
+ @mock.visits.reset(99, "2010-07-14")
298
+
299
+ @mock.visits.on("2010-07-14").should == 99
300
+ @mock.visits.browsers.all_values.should =~ [
301
+ ["mozilla", [1, 0, 0, 99]],
302
+ ["google", [2, 0, 0, 99]],
303
+ ["internet", [3, 0, 0, 99]]
304
+ ]
305
+ @mock.visits.referers.all_values.should =~ [
306
+ ["firefox", [1, 0, 0, 99]],
307
+ ["chrome", [2, 0, 0, 99]],
308
+ ["explorer", [3, 0, 0, 99]]
309
+ ]
310
+ end
311
+
312
+ it "should delete the values when using nil" do
313
+ @mock.visits.reset(nil, "2010-07-14")
314
+
315
+ @mock.visits.on("2010-07-14").should == 0
316
+ @mock.visits.browsers.all_values.should =~ [
317
+ ["mozilla", [1]],
318
+ ["google", [2]],
319
+ ["internet", [3]]
320
+ ]
321
+ @mock.visits.referers.all_values.should =~ [
322
+ ["firefox", [1]],
323
+ ["chrome", [2]],
324
+ ["explorer", [3]]
325
+ ]
326
+ end
327
+
328
+ it "erase method sould also work" do
329
+ @mock.visits.erase("2010-07-14")
330
+
331
+ @mock.visits.on("2010-07-14").should == 0
332
+ @mock.visits.browsers.all_values.should =~ [
333
+ ["mozilla", [1]],
334
+ ["google", [2]],
335
+ ["internet", [3]]
336
+ ]
337
+ end
338
+
339
+ it "should reset the correct tracking fields" do
340
+ @mock.visits.reset(99, "2010-07-14")
341
+
342
+ @mock.uniques.on("2010-07-14").should == 6
343
+ @mock.uniques.browsers.all_values.should =~ [
344
+ ["mozilla", [1, 0, 0, 4]],
345
+ ["google", [2, 0, 0, 5]],
346
+ ["internet", [3, 0, 0, 6]]
347
+ ]
348
+ @mock.uniques.referers.all_values.should =~ [
349
+ ["firefox", [1, 0, 0, 4]],
350
+ ["chrome", [2, 0, 0, 5]],
351
+ ["explorer", [3, 0, 0, 6]]
352
+ ]
353
+ end
354
+
355
+ it "should erase the correct tracking fields" do
356
+ @mock.visits.erase("2010-07-14")
357
+
358
+ @mock.uniques.on("2010-07-14").should == 6
359
+ @mock.uniques.browsers.all_values.should =~ [
360
+ ["mozilla", [1, 0, 0, 4]],
361
+ ["google", [2, 0, 0, 5]],
362
+ ["internet", [3, 0, 0, 6]]
363
+ ]
364
+ @mock.uniques.referers.all_values.should =~ [
365
+ ["firefox", [1, 0, 0, 4]],
366
+ ["chrome", [2, 0, 0, 5]],
367
+ ["explorer", [3, 0, 0, 6]]
368
+ ]
369
+ end
370
+ end
371
+
272
372
  describe "Testing all accessors" do
273
373
  before do
274
374
  TestModel.all.map(&:destroy)
@@ -280,7 +380,7 @@ describe Mongoid::Tracking::Aggregates do
280
380
  @mock.visits("Mozilla Firefox").set(1, "2010-07-11")
281
381
  @mock.visits("Google Chrome").set(2, "2010-07-12")
282
382
  @mock.visits("Internet Explorer").set(3, "2010-07-13")
283
-
383
+
284
384
  # For 'last' values
285
385
  @mock.visits("Mozilla Firefox").set(4, "2010-07-14")
286
386
  @mock.visits("Google Chrome").set(5, "2010-07-15")
@@ -290,17 +390,17 @@ describe Mongoid::Tracking::Aggregates do
290
390
  it "should return the correct values for .all_values" do
291
391
  @mock.visits.all_values.should == [1, 2, 3, 4, 5, 6]
292
392
  end
293
-
393
+
294
394
  it "should return the all values for every aggregate" do
295
- @mock.visits.browsers.all_values.should == [
395
+ @mock.visits.browsers.all_values.should =~ [
296
396
  ["mozilla", [1, 0, 0, 4]],
297
397
  ["google", [2, 0, 0, 5]],
298
398
  ["internet", [3, 0, 0, 6]]
299
399
  ]
300
400
  end
301
-
401
+
302
402
  it "should return the correct first_date for every aggregate" do
303
- @mock.visits.browsers.first_date.should == [
403
+ @mock.visits.browsers.first_date.should =~ [
304
404
  ["mozilla", Date.parse("2010-07-11")],
305
405
  ["google", Date.parse("2010-07-12")],
306
406
  ["internet", Date.parse("2010-07-13")]
@@ -308,7 +408,7 @@ describe Mongoid::Tracking::Aggregates do
308
408
  end
309
409
 
310
410
  it "should return the correct last_date for every aggregate" do
311
- @mock.visits.browsers.last_date.should == [
411
+ @mock.visits.browsers.last_date.should =~ [
312
412
  ["mozilla", Date.parse("2010-07-14")],
313
413
  ["google", Date.parse("2010-07-15")],
314
414
  ["internet", Date.parse("2010-07-16")]
@@ -316,7 +416,7 @@ describe Mongoid::Tracking::Aggregates do
316
416
  end
317
417
 
318
418
  it "should return the first value for aggregates" do
319
- @mock.visits.browsers.first_value.should == [
419
+ @mock.visits.browsers.first_value.should =~ [
320
420
  ["mozilla", 1],
321
421
  ["google", 2],
322
422
  ["internet", 3]
@@ -324,12 +424,11 @@ describe Mongoid::Tracking::Aggregates do
324
424
  end
325
425
 
326
426
  it "should return the last value for aggregates" do
327
- @mock.visits.browsers.last_value.should == [
427
+ @mock.visits.browsers.last_value.should =~ [
328
428
  ["mozilla", 4],
329
429
  ["google", 5],
330
430
  ["internet", 6]
331
431
  ]
332
432
  end
333
-
334
433
  end
335
434
  end
data/trackoid.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{trackoid}
8
- s.version = "0.1.12"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jose Miguel Perez"]
12
- s.date = %q{2011-03-24}
12
+ s.date = %q{2011-03-26}
13
13
  s.description = %q{Trackoid uses an embeddable approach to track analytics data using the poweful features of MongoDB for scalability}
14
14
  s.email = %q{josemiguel@perezruiz.com}
15
15
  s.extra_rdoc_files = [
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
8
- - 12
9
- version: 0.1.12
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Jose Miguel Perez
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-03-24 00:00:00 +01:00
17
+ date: 2011-03-26 00:00:00 +01:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency