trackoid 0.1.12 → 0.2.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.
- data/README.rdoc +29 -3
- data/VERSION +1 -1
- data/lib/trackoid/tracker.rb +49 -8
- data/spec/aggregates_spec.rb +118 -19
- data/trackoid.gemspec +2 -2
- metadata +4 -4
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
|
-
|
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
|
+
0.2.0
|
data/lib/trackoid/tracker.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
92
|
-
|
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
|
data/spec/aggregates_spec.rb
CHANGED
@@ -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
|
237
|
-
@mock.visits.referers.today.should
|
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
|
250
|
-
@mock.visits.referers.today.should
|
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
|
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
|
263
|
-
@mock.visits.referers.today.should
|
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.
|
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-
|
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
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
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-
|
17
|
+
date: 2011-03-26 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|