trackoid 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -183,3 +183,17 @@ MongoDB stores information in BSON format as a binary representation of a JSON s
183
183
  A year full of statistical data takes only 2.8Kb, if you store integers. If your statistical data includes floats, a year full of information takes 4.3Kb. I said "a year full of data" because Trackoid does not store information for days without data.
184
184
 
185
185
  For comparison, this README is already 8.5Kb in size.
186
+
187
+
188
+ = Revision History
189
+
190
+ 0.1.6 - Enabled support for String dates in operators. This string date must
191
+ be DateTime parseable.
192
+ For example: @spain.world_cups.inc("2010-07-11")
193
+ - Normalized Date and DateTime objects to use only Date methods.
194
+ - Added "first" / "first_date" / "last" / "last_date" accessors.
195
+ - Added "all" accessor.
196
+
197
+ 0.1.5 - Added support for namespaced models and aggregations
198
+ - Enabled "set" operations on aggregates
199
+
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.5
1
+ 0.1.6
@@ -32,8 +32,8 @@ module Mongoid #:nodoc:
32
32
  end
33
33
 
34
34
  # Update methods
35
- def add(how_much = 1, date = DateTime.now)
36
- raise Errors::ModelNotSaved, "Can't update a new record" if @owner.new_record?
35
+ def add(how_much = 1, date = Date.today)
36
+ raise Errors::ModelNotSaved, "Can't update a new record. Save first!" if @owner.new_record?
37
37
  update_data(data_for(date) + how_much, date)
38
38
  @owner.collection.update( @owner._selector,
39
39
  { (how_much > 0 ? "$inc" : "$dec") => update_hash(how_much.abs, date) },
@@ -50,15 +50,15 @@ module Mongoid #:nodoc:
50
50
  end
51
51
  end
52
52
 
53
- def inc(date = DateTime.now)
53
+ def inc(date = Date.today)
54
54
  add(1, date)
55
55
  end
56
56
 
57
- def dec(date = DateTime.now)
57
+ def dec(date = Date.today)
58
58
  add(-1, date)
59
59
  end
60
60
 
61
- def set(how_much, date = DateTime.now)
61
+ def set(how_much, date = Date.today)
62
62
  raise Errors::ModelNotSaved, "Can't update a new record" if @owner.new_record?
63
63
  update_data(how_much, date)
64
64
  @owner.collection.update( @owner._selector,
@@ -78,6 +78,14 @@ module Mongoid #:nodoc:
78
78
 
79
79
 
80
80
  # Access methods
81
+ def first
82
+ data_for(first_date)
83
+ end
84
+
85
+ def last
86
+ data_for(last_date)
87
+ end
88
+
81
89
  def today
82
90
  data_for(Date.today)
83
91
  end
@@ -88,24 +96,50 @@ module Mongoid #:nodoc:
88
96
 
89
97
  def last_days(how_much = 7)
90
98
  return [today] unless how_much > 0
91
- date, values = DateTime.now, []
99
+ date, values = Date.today, []
92
100
  (date - how_much.abs + 1).step(date) {|d| values << data_for(d) }
93
101
  values
94
102
  end
95
103
 
96
104
  def on(date)
97
- date = DateTime.parse(date) if date.is_a?(String)
98
105
  return date.collect {|d| data_for(d)} if date.is_a?(Range)
99
106
  data_for(date)
100
107
  end
101
108
 
109
+ def all
110
+ on(first_date..last_date) if first_date
111
+ end
112
+
113
+ # Utility methods
114
+ def first_date
115
+ # We are guaranteed _m and _d to exists unless @data is a malformed
116
+ # hash, so we need to do this nasty "return nil", sorry...
117
+ return nil unless _y = @data.keys.min
118
+ return nil unless _m = @data[_y].keys.min
119
+ return nil unless _d = @data[_y][_m].keys.min
120
+ Date.new(_y.to_i, _m.to_i, _d.to_i)
121
+ end
122
+
123
+ def last_date
124
+ # We are guaranteed _m and _d to exists unless @data is a malformed
125
+ # hash, so we need to do this nasty "return nil", sorry...
126
+ return nil unless _y = @data.keys.max
127
+ return nil unless _m = @data[_y].keys.max
128
+ return nil unless _d = @data[_y][_m].keys.max
129
+ Date.new(_y.to_i, _m.to_i, _d.to_i)
130
+ end
131
+
102
132
  # Private methods
103
133
  private
104
134
  def data_for(date)
135
+ return nil if date.nil?
136
+ date = normalize_date(date)
105
137
  @data.try(:[], date.year.to_s).try(:[], date.month.to_s).try(:[], date.day.to_s) || 0
106
138
  end
107
139
 
108
140
  def update_data(value, date)
141
+ return nil if date.nil?
142
+ date = normalize_date(date)
109
143
  [:year, :month].inject(@data) { |data, period|
110
144
  data[date.send(period).to_s] ||= {}
111
145
  }
@@ -117,11 +151,21 @@ module Mongoid #:nodoc:
117
151
  def date_literal(d); "#{d.year}.#{d.month}.#{d.day}"; end
118
152
 
119
153
  def update_hash(num, date)
154
+ date = normalize_date(date)
120
155
  {
121
156
  "#{@for_data}.#{date_literal(date)}" => num
122
157
  }
123
158
  end
124
159
 
160
+ def normalize_date(date)
161
+ case date
162
+ when String
163
+ Date.parse(date)
164
+ else
165
+ date
166
+ end
167
+ end
168
+
125
169
  # WARNING: This is +only+ for debugging pourposes (rspec y tal)
126
170
  def _original_hash
127
171
  @data
@@ -9,7 +9,6 @@ class Test
9
9
  end
10
10
 
11
11
  describe Mongoid::Tracking do
12
-
13
12
  before(:all) do
14
13
  @trackoid_version = File.read(File.expand_path("../VERSION", File.dirname(__FILE__)))
15
14
  end
@@ -38,7 +37,6 @@ describe Mongoid::Tracking do
38
37
  end
39
38
 
40
39
  describe "when creating a new field with stats" do
41
-
42
40
  before(:all) do
43
41
  @mock = Test.new
44
42
  end
@@ -96,11 +94,9 @@ describe Mongoid::Tracking do
96
94
  it "should not be aggregated" do
97
95
  @mock.aggregated?.should be_false
98
96
  end
99
-
100
97
  end
101
98
 
102
99
  describe "when using a model in the database" do
103
-
104
100
  before(:all) do
105
101
  Test.delete_all
106
102
  Test.create(:name => "test")
@@ -143,10 +139,84 @@ describe Mongoid::Tracking do
143
139
  @mock.visits.last_days.should == [0, 0, 0, 0, 0, 2, 2]
144
140
  end
145
141
 
142
+ it "string dates should work" do
143
+ @mock.visits.inc("2010-07-11")
144
+ @mock.visits.on("2010-07-11").should == 1
145
+ end
146
+
147
+ it "should give the first date with first_date" do
148
+ @mock.visits.first_date.should == Date.parse("2010-07-11")
149
+ end
150
+
151
+ it "should give the last date with last_date" do
152
+ @mock.visits.last_date.should == Date.today
153
+ end
154
+
155
+ it "should give the first value" do
156
+ @mock.visits.first.should == 1
157
+ end
158
+
159
+ it "should give the last value" do
160
+ @mock.visits.last.should == 2
161
+ end
146
162
  end
147
163
 
148
- context "testing accessor operations without reloading models" do
164
+ describe "Testing accessors with an empty model" do
165
+ before do
166
+ Test.delete_all
167
+ Test.create(:name => "test")
168
+ @object_id = Test.first.id
169
+ @mock = Test.first
170
+ end
171
+
172
+ it "should return nil for .first_date" do
173
+ @mock.visits.first_date.should be_nil
174
+ end
175
+
176
+ it "should return nil for .last_date" do
177
+ @mock.visits.last_date.should be_nil
178
+ end
179
+
180
+ it "should return nil for .first" do
181
+ @mock.visits.first.should be_nil
182
+ end
149
183
 
184
+ it "should return nil for .last" do
185
+ @mock.visits.last.should be_nil
186
+ end
187
+
188
+ it "should return nil for .all" do
189
+ @mock.visits.all.should be_nil
190
+ end
191
+ end
192
+
193
+ describe "Testing new range accessors with an empty model" do
194
+ before do
195
+ Test.delete_all
196
+ Test.create(:name => "test")
197
+ @object_id = Test.first.id
198
+ @mock = Test.first
199
+ end
200
+
201
+ it "should return the correct values for .all" do
202
+ @mock.visits.set(1, "2010-07-11")
203
+ @mock.visits.set(2, "2010-07-12")
204
+ @mock.visits.set(3, "2010-07-13")
205
+
206
+ @mock.visits.all.should == [1, 2, 3]
207
+ end
208
+
209
+ it "should return the correct values for .all (Take II)" do
210
+ @mock.visits.set(5, "2010-07-01")
211
+ @mock.visits.set(10, "2010-07-30")
212
+
213
+ @mock.visits.all.should == [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10]
214
+ @mock.visits.last.should == 10
215
+ @mock.visits.first.should == 5
216
+ end
217
+ end
218
+
219
+ context "testing accessor operations without reloading models" do
150
220
  before(:all) do
151
221
  Test.delete_all
152
222
  Test.create(:name => "test")
@@ -195,15 +265,10 @@ describe Mongoid::Tracking do
195
265
  # We have data for today as previous tests populated the visits field
196
266
  @mock.visits.on(Date.parse("2010-04-30")..Date.parse("2010-05-02")).should == [0, 10, 0]
197
267
  end
198
-
199
-
200
268
  end
201
269
 
202
-
203
-
204
270
  context "regression test for github issues" do
205
-
206
- it "should not raise undefined method [] for nil:NilClass for objects already saved" do
271
+ it "should not raise undefined method [] for nil:NilClass when adding a new track into an existing object" do
207
272
  class TestModel
208
273
  include Mongoid::Document
209
274
  include Mongoid::Tracking
@@ -220,7 +285,5 @@ describe Mongoid::Tracking do
220
285
  tm.something.inc
221
286
  tm.something.today.should == 1
222
287
  end
223
-
224
288
  end
225
-
226
289
  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.5"
8
+ s.version = "0.1.6"
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{2010-07-15}
12
+ s.date = %q{2010-07-16}
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
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trackoid
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 5
10
- version: 0.1.5
9
+ - 6
10
+ version: 0.1.6
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jose Miguel Perez
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-07-15 00:00:00 +02:00
18
+ date: 2010-07-16 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency