appstats 0.17.5 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- appstats (0.17.5)
4
+ appstats (0.18.0)
5
5
  daemons
6
6
  net-scp
7
7
  rails (>= 2.3.0)
@@ -0,0 +1,17 @@
1
+ class AddAppstatsResultsLatestFlag < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :appstats_results, :is_latest, :boolean
4
+ add_index :appstats_results, :is_latest
5
+
6
+ ActiveRecord::Base.connection.update('update appstats_results set is_latest = false')
7
+ all = ActiveRecord::Base.connection.select_all("select concat(id,' ',max(updated_at)) as id_and_date from appstats_results group by query")
8
+ return if all.empty?
9
+ ids = all.each.collect { |e| e["id_and_date"].split[0] }.compact
10
+ ActiveRecord::Base.connection.update("update appstats_results set is_latest = '1' where id in (#{ids.join(',')})")
11
+ end
12
+
13
+ def self.down
14
+ remove_index :appstats_results, :is_latest
15
+ remove_column :appstats_results, :is_latest
16
+ end
17
+ end
@@ -10,7 +10,7 @@
10
10
  #
11
11
  # It's strongly recommended to check this file into your version control system.
12
12
 
13
- ActiveRecord::Schema.define(:version => 20110311214833) do
13
+ ActiveRecord::Schema.define(:version => 20110318203339) do
14
14
 
15
15
  create_table "appstats_actions", :force => true do |t|
16
16
  t.string "name"
@@ -125,10 +125,12 @@ ActiveRecord::Schema.define(:version => 20110311214833) do
125
125
  t.string "db_username"
126
126
  t.string "db_name"
127
127
  t.string "db_host"
128
+ t.boolean "is_latest"
128
129
  end
129
130
 
130
131
  add_index "appstats_results", ["action"], :name => "index_appstats_results_on_action"
131
132
  add_index "appstats_results", ["host"], :name => "index_appstats_results_on_host"
133
+ add_index "appstats_results", ["is_latest"], :name => "index_appstats_results_on_is_latest"
132
134
  add_index "appstats_results", ["name"], :name => "index_appstats_results_on_name"
133
135
  add_index "appstats_results", ["page"], :name => "index_appstats_results_on_page"
134
136
 
@@ -3,9 +3,8 @@ unless ARGV.any? {|a| a =~ /^gems/} # Don't load anything when running the gems:
3
3
  desc "Perform a build on the CI server"
4
4
  task :build => ['config', 'create_logs'] do
5
5
  begin
6
- Rake::Task['appstats:install:migrations'].invoke
7
- Rake::Task['db:migrate'].invoke
8
- Rake::Task['db:test:prepare'].invoke
6
+ Rake::Task['ci:db_setup'].invoke
7
+ # Rake::Task['db:test:prepare'].invoke
9
8
  Rake::Task['spec'].invoke
10
9
  Rake::Task['metrics:all'].invoke
11
10
  Rake::Task['ci:success'].invoke
@@ -15,6 +14,12 @@ unless ARGV.any? {|a| a =~ /^gems/} # Don't load anything when running the gems:
15
14
  end
16
15
  end
17
16
 
17
+ # Creates a second database for testing the multi db access
18
+ task :db_setup => ['config','create_logs'] do
19
+ Rake::Task['appstats:install:migrations'].invoke
20
+ Rake::Task['db:migrate'].invoke
21
+ end
22
+
18
23
  desc "Setup the correct database configuration files"
19
24
  task :config do
20
25
  source_db_file = '/cenx/appstats/sensitive/config.yml'
@@ -149,6 +149,14 @@ module Appstats
149
149
  return range
150
150
  end
151
151
 
152
+ m = input.match(/^(.+)\s*(year|years|quarter|quarters|month|months|week|weeks|day|days)\s*ago$/)
153
+ unless m.nil?
154
+ range.from = EntryDate.parse(input)
155
+ range.format = :fixed_point
156
+ return range
157
+ end
158
+
159
+
152
160
  m = input.match(/^previous\s*(.+)\s*(year|quarter|month|week|day)s?$/)
153
161
  unless m.nil?
154
162
  range.from = EntryDate.parse(input)
@@ -154,6 +154,37 @@ module Appstats
154
154
  t_parts = [:year,:month,:day]
155
155
  end
156
156
 
157
+ m = input.match(/^(\d*)\s*years?\s*ago/)
158
+ if m
159
+ t -= ago_date_offset(m).year
160
+ t_parts = [:year]
161
+ end
162
+
163
+ m = input.match(/^(\d*)\s*quarters?\s*ago/)
164
+ if m
165
+ t = t.beginning_of_quarter
166
+ ago_date_offset(m).times { t = (t - 1.day).beginning_of_quarter }
167
+ t_parts = [:year,:month,:quarter]
168
+ end
169
+
170
+ m = input.match(/^(\d*)\s*months?\s*ago/)
171
+ if m
172
+ t -= ago_date_offset(m).month
173
+ t_parts = [:year,:month]
174
+ end
175
+
176
+ m = input.match(/^(\d*)\s*weeks?\s*ago/)
177
+ if m
178
+ t = (t - ago_date_offset(m).week).beginning_of_week
179
+ t_parts = [:year,:month,:day,:week]
180
+ end
181
+
182
+ m = input.match(/^(\d*)\s*days?\s*ago/)
183
+ if m
184
+ t -= ago_date_offset(m).day
185
+ t_parts = [:year,:month,:day]
186
+ end
187
+
157
188
  unless t_parts.nil?
158
189
  t_parts.each do |label|
159
190
  if [:quarter,:week].include?(label)
@@ -191,6 +222,11 @@ module Appstats
191
222
  amount = match[2] == "" ? 1 : match[2].to_i + offset
192
223
  amount
193
224
  end
225
+
226
+ # (\d*) (year|month|...) ago
227
+ def self.ago_date_offset(match)
228
+ match[1].to_i
229
+ end
194
230
 
195
231
  end
196
232
  end
@@ -3,9 +3,11 @@ module Appstats
3
3
  set_table_name "appstats_results"
4
4
 
5
5
  attr_accessible :name, :result_type, :query, :query_to_sql, :count, :action, :host, :from_date, :to_date, :contexts, :group_by, :query_type,
6
- :db_username, :db_name, :db_host
6
+ :db_username, :db_name, :db_host, :is_latest
7
7
  has_many :sub_results, :table_name => 'appstats_subresults', :foreign_key => 'appstats_result_id', :order => 'count DESC'
8
8
 
9
+ after_save :update_is_latest
10
+
9
11
  def date_to_s
10
12
  return "" if from_date.nil? && to_date.nil?
11
13
 
@@ -65,8 +67,28 @@ module Appstats
65
67
  end
66
68
  alias_method :eql?, :==
67
69
 
70
+ def self.fix_all_is_latest
71
+ ActiveRecord::Base.connection.update('update appstats_results set is_latest = false')
72
+ all = ActiveRecord::Base.connection.select_all("select concat(id,' ',max(updated_at)) as id_and_date from appstats_results group by query")
73
+ return if all.empty?
74
+ ids = all.each.collect { |e| e["id_and_date"].split[0] }.compact
75
+ ActiveRecord::Base.connection.update("update appstats_results set is_latest = '1' where id in (#{ids.join(',')})")
76
+ end
77
+
68
78
  private
69
79
 
80
+ def update_is_latest
81
+ sql = ["update appstats_results set is_latest = false where query = ?",query]
82
+ ActiveRecord::Base.connection.update(ActiveRecord::Base.send(:sanitize_sql_array, sql))
83
+
84
+ sql = ["select id from appstats_results where query = ? order by updated_at DESC",query]
85
+ first = ActiveRecord::Base.connection.select_one(ActiveRecord::Base.send(:sanitize_sql_array, sql))
86
+ return if first.nil?
87
+
88
+ sql = ["update appstats_results set is_latest = '1' where id = ?",first["id"]]
89
+ ActiveRecord::Base.connection.update(ActiveRecord::Base.send(:sanitize_sql_array, sql))
90
+ end
91
+
70
92
  def add_commas(num)
71
93
  num.to_s.gsub(/(\d)(?=\d{3}+(\.\d*)?$)/, '\1,')
72
94
  end
@@ -1,3 +1,3 @@
1
1
  module Appstats
2
- VERSION = "0.17.5"
2
+ VERSION = "0.18.0"
3
3
  end
@@ -147,6 +147,40 @@ module Appstats
147
147
 
148
148
  end
149
149
 
150
+ describe "X (year|quarter|month|week|day)s ago" do
151
+
152
+ it "should understand last X years" do
153
+ DateRange.parse(" 1 year ago ").should == DateRange.new(:from => EntryDate.new(:year => 2009), :to => nil, :format => :fixed_point )
154
+ DateRange.parse(" 2 years ago ").should == DateRange.new(:from => EntryDate.new(:year => 2008), :to => nil, :format => :fixed_point )
155
+ DateRange.parse(" 3 years ago ").should == DateRange.new(:from => EntryDate.new(:year => 2007), :to => nil, :format => :fixed_point )
156
+ end
157
+
158
+ it "should understand last X quarters" do
159
+ DateRange.parse(" 1 quarter ago ").should == DateRange.new(:from => EntryDate.new(:year => 2009, :month => 10, :quarter => 4), :to => nil, :format => :fixed_point )
160
+ DateRange.parse(" 2 quarters ago ").should == DateRange.new(:from => EntryDate.new(:year => 2009, :month => 7, :quarter => 3), :to => nil, :format => :fixed_point )
161
+ DateRange.parse(" 3 quarters ago ").should == DateRange.new(:from => EntryDate.new(:year => 2009, :month => 4, :quarter => 2), :to => nil, :format => :fixed_point )
162
+ end
163
+
164
+ it "should understand last X months" do
165
+ DateRange.parse(" 1 month ago ").should == DateRange.new(:from => EntryDate.new(:year => 2009, :month => 12), :to => nil, :format => :fixed_point )
166
+ DateRange.parse(" 2 months ago ").should == DateRange.new(:from => EntryDate.new(:year => 2009, :month => 11), :to => nil, :format => :fixed_point )
167
+ DateRange.parse(" 3 months ago ").should == DateRange.new(:from => EntryDate.new(:year => 2009, :month => 10), :to => nil, :format => :fixed_point )
168
+ end
169
+
170
+ it "should understand last X weeks" do
171
+ DateRange.parse(" 1 week ago ").should == DateRange.new(:from => EntryDate.new(:year => 2010, :month => 1, :day => 4, :week => 1), :to => nil, :format => :fixed_point )
172
+ DateRange.parse(" 2 weeks ago ").should == DateRange.new(:from => EntryDate.new(:year => 2009, :month => 12, :day => 28, :week => 52), :to => nil, :format => :fixed_point )
173
+ DateRange.parse(" 3 weeks ago ").should == DateRange.new(:from => EntryDate.new(:year => 2009, :month => 12, :day => 21, :week => 51), :to => nil, :format => :fixed_point )
174
+ end
175
+
176
+ it "should understand last X days" do
177
+ DateRange.parse(" 1 day ago ").should == DateRange.new(:from => EntryDate.new(:year => 2010, :month => 1, :day => 14), :to => nil, :format => :fixed_point )
178
+ DateRange.parse(" 2 days ago ").should == DateRange.new(:from => EntryDate.new(:year => 2010, :month => 1, :day => 13), :to => nil, :format => :fixed_point )
179
+ DateRange.parse(" 3 days ago ").should == DateRange.new(:from => EntryDate.new(:year => 2010, :month => 1, :day => 12), :to => nil, :format => :fixed_point )
180
+ end
181
+
182
+ end
183
+
150
184
  describe "last X (year|quarter|month|week|day)s" do
151
185
 
152
186
  it "should understand last X years" do
@@ -369,6 +369,40 @@ module Appstats
369
369
  EntryDate.parse("previous 3 days").should == EntryDate.new(:year => 2010, :month => 1, :day => 12)
370
370
  end
371
371
 
372
+ describe "X (year|quarter|month|week|day)s ago" do
373
+
374
+ it "should understand last X years" do
375
+ EntryDate.parse(" 1 year ago ").should == EntryDate.new(:year => 2009)
376
+ EntryDate.parse(" 2 years ago ").should == EntryDate.new(:year => 2008)
377
+ EntryDate.parse(" 3 years ago ").should == EntryDate.new(:year => 2007)
378
+ end
379
+
380
+ it "should understand last X quarters" do
381
+ EntryDate.parse(" 1 quarter ago ").should == EntryDate.new(:year => 2009, :month => 10, :quarter => 4)
382
+ EntryDate.parse(" 2 quarters ago ").should == EntryDate.new(:year => 2009, :month => 7, :quarter => 3)
383
+ EntryDate.parse(" 3 quarters ago ").should == EntryDate.new(:year => 2009, :month => 4, :quarter => 2)
384
+ end
385
+
386
+ it "should understand last X months" do
387
+ EntryDate.parse(" 1 month ago ").should == EntryDate.new(:year => 2009, :month => 12)
388
+ EntryDate.parse(" 2 months ago ").should == EntryDate.new(:year => 2009, :month => 11)
389
+ EntryDate.parse(" 3 months ago ").should == EntryDate.new(:year => 2009, :month => 10)
390
+ end
391
+
392
+ it "should understand last X weeks" do
393
+ EntryDate.parse(" 1 week ago ").should == EntryDate.new(:year => 2010, :month => 1, :day => 4, :week => 1)
394
+ EntryDate.parse(" 2 weeks ago ").should == EntryDate.new(:year => 2009, :month => 12, :day => 28, :week => 52)
395
+ EntryDate.parse(" 3 weeks ago ").should == EntryDate.new(:year => 2009, :month => 12, :day => 21, :week => 51)
396
+ end
397
+
398
+ it "should understand last X days" do
399
+ EntryDate.parse(" 1 day ago ").should == EntryDate.new(:year => 2010, :month => 1, :day => 14)
400
+ EntryDate.parse(" 2 days ago ").should == EntryDate.new(:year => 2010, :month => 1, :day => 13)
401
+ EntryDate.parse(" 3 days ago ").should == EntryDate.new(:year => 2010, :month => 1, :day => 12)
402
+ end
403
+
404
+ end
405
+
372
406
  it "should accept garbage input" do
373
407
  EntryDate.parse("1234asdf1234 1234fds123").should == EntryDate.new
374
408
  end
@@ -193,18 +193,18 @@ module Appstats
193
193
  end
194
194
 
195
195
  it "should understand an entry without contexts" do
196
- entry = Entry.create_from_logger_string("0.17.5 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search")
196
+ entry = Entry.create_from_logger_string("0.18.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search")
197
197
  Entry.count.should == @before_count + 1
198
198
  entry.action.should == "address_search"
199
- entry.raw_entry.should == "0.17.5 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search"
199
+ entry.raw_entry.should == "0.18.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search"
200
200
  entry.occurred_at.should == Time.parse("2010-09-21 23:15:20")
201
201
  end
202
202
 
203
203
  it "should understand contexts" do
204
- entry = Entry.create_from_logger_string("0.17.5 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : app_name=Market : server=Live")
204
+ entry = Entry.create_from_logger_string("0.18.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : app_name=Market : server=Live")
205
205
  Entry.count.should == @before_count + 1
206
206
  entry.action.should == "address_filter"
207
- entry.raw_entry.should == "0.17.5 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : app_name=Market : server=Live"
207
+ entry.raw_entry.should == "0.18.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : app_name=Market : server=Live"
208
208
  entry.occurred_at.should == Time.parse("2010-09-21 23:15:20")
209
209
  entry.contexts.size.should == 2
210
210
  entry.contexts[0].context_key = "app_name"
@@ -214,10 +214,10 @@ module Appstats
214
214
  end
215
215
 
216
216
  it "should handle 'action' as a context" do
217
- entry = Entry.create_from_logger_string('0.17.5 setup[:,=,-n] 2011-02-24 12:59:57 action=page-view : action=save_ovcen : app_name=cdb')
217
+ entry = Entry.create_from_logger_string('0.18.0 setup[:,=,-n] 2011-02-24 12:59:57 action=page-view : action=save_ovcen : app_name=cdb')
218
218
  Entry.count.should == @before_count + 1
219
219
  entry.action.should == "page-view"
220
- entry.raw_entry.should == "0.17.5 setup[:,=,-n] 2011-02-24 12:59:57 action=page-view : action=save_ovcen : app_name=cdb"
220
+ entry.raw_entry.should == "0.18.0 setup[:,=,-n] 2011-02-24 12:59:57 action=page-view : action=save_ovcen : app_name=cdb"
221
221
  entry.occurred_at.should == Time.parse("2011-02-24 12:59:57")
222
222
  entry.contexts.size.should == 2
223
223
  entry.contexts[0].context_key = "action"
@@ -228,10 +228,10 @@ module Appstats
228
228
  end
229
229
 
230
230
  it "should handle multiple of the same 'context'" do
231
- entry = Entry.create_from_logger_string('0.17.5 setup[:,=,-n] 2011-02-24 12:59:57 action=page-view : app_name=market : app_name=cdb')
231
+ entry = Entry.create_from_logger_string('0.18.0 setup[:,=,-n] 2011-02-24 12:59:57 action=page-view : app_name=market : app_name=cdb')
232
232
  Entry.count.should == @before_count + 1
233
233
  entry.action.should == "page-view"
234
- entry.raw_entry.should == "0.17.5 setup[:,=,-n] 2011-02-24 12:59:57 action=page-view : app_name=market : app_name=cdb"
234
+ entry.raw_entry.should == "0.18.0 setup[:,=,-n] 2011-02-24 12:59:57 action=page-view : app_name=market : app_name=cdb"
235
235
  entry.occurred_at.should == Time.parse("2011-02-24 12:59:57")
236
236
  entry.contexts.size.should == 2
237
237
  entry.contexts[0].context_key = "app_name"
@@ -122,12 +122,12 @@ module Appstats
122
122
 
123
123
  it "should accept numbers" do
124
124
  Appstats::Logger.entry(5, :blah => 6)
125
- Appstats::Logger.raw_read.should == ["0.17.5 setup[:,=,-n] 2010-09-21 23:15:20 action=5 : blah=6"]
125
+ Appstats::Logger.raw_read.should == ["0.18.0 setup[:,=,-n] 2010-09-21 23:15:20 action=5 : blah=6"]
126
126
  end
127
127
 
128
128
  it "should accept arrays" do
129
129
  Appstats::Logger.entry('search', :provider => [ 'one', 'two' ])
130
- Appstats::Logger.raw_read.should == ["0.17.5 setup[:,=,-n] 2010-09-21 23:15:20 action=search : provider=one : provider=two"]
130
+ Appstats::Logger.raw_read.should == ["0.18.0 setup[:,=,-n] 2010-09-21 23:15:20 action=search : provider=one : provider=two"]
131
131
  end
132
132
 
133
133
 
@@ -137,7 +137,7 @@ module Appstats
137
137
 
138
138
  it "should look similar to regular entry" do
139
139
  Appstats::Logger.exception_entry(RuntimeError.new("blah"),:on => "login")
140
- Appstats::Logger.raw_read.should == ["0.17.5 setup[:,=,-n] 2010-09-21 23:15:20 action=appstats-exception : error=blah : on=login"]
140
+ Appstats::Logger.raw_read.should == ["0.18.0 setup[:,=,-n] 2010-09-21 23:15:20 action=appstats-exception : error=blah : on=login"]
141
141
  end
142
142
 
143
143
  end
@@ -154,47 +154,47 @@ module Appstats
154
154
 
155
155
  it "should handle a statistics entry" do
156
156
  expected = { :action => "address_search", :timestamp => "2010-09-21 23:15:20" }
157
- actual = Appstats::Logger.entry_to_hash("0.17.5 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search")
157
+ actual = Appstats::Logger.entry_to_hash("0.18.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search")
158
158
  actual.should == expected
159
159
  end
160
160
 
161
161
  it "should handle contexts" do
162
162
  expected = { :action => "address_filter", :timestamp => "2010-09-21 23:15:20", :server => "Live", :app_name => 'Market' }
163
- actual = Appstats::Logger.entry_to_hash("0.17.5 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : app_name=Market : server=Live")
163
+ actual = Appstats::Logger.entry_to_hash("0.18.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : app_name=Market : server=Live")
164
164
  actual.should == expected
165
165
  end
166
166
 
167
167
  it "should handle multiple actions" do
168
168
  expected = { :action => ["address_filter", "blah"], :timestamp => "2010-09-21 23:15:20", :server => "Live", :app_name => 'Market' }
169
- actual = Appstats::Logger.entry_to_hash("0.17.5 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : action=blah : app_name=Market : server=Live")
169
+ actual = Appstats::Logger.entry_to_hash("0.18.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : action=blah : app_name=Market : server=Live")
170
170
  actual.should == expected
171
171
  end
172
172
 
173
173
  it "should handle multiple of same context" do
174
174
  expected = { :action => "address_filter", :timestamp => "2010-09-21 23:15:20", :server => "Live", :app_name => ['Sin','Market'] }
175
- actual = Appstats::Logger.entry_to_hash("0.17.5 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : app_name=Sin : app_name=Market : server=Live")
175
+ actual = Appstats::Logger.entry_to_hash("0.18.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : app_name=Sin : app_name=Market : server=Live")
176
176
  actual.should == expected
177
177
  end
178
178
 
179
179
  it "should handle no actions" do
180
180
  expected = { :action => "UNKNOWN_ACTION", :timestamp => "2010-09-21 23:15:20", :server => "Live", :app_name => 'Market' }
181
- actual = Appstats::Logger.entry_to_hash("0.17.5 setup[:,=,-n] 2010-09-21 23:15:20 app_name=Market : server=Live")
181
+ actual = Appstats::Logger.entry_to_hash("0.18.0 setup[:,=,-n] 2010-09-21 23:15:20 app_name=Market : server=Live")
182
182
  actual.should == expected
183
183
  end
184
184
 
185
185
  it "should handle actions with the delimiter (and change the delimiter)" do
186
186
  expected = { :action => "address:=search-n", :timestamp => "2010-09-21 23:15:20" }
187
- actual = Appstats::Logger.entry_to_hash("0.17.5 setup[::,==,--n] 2010-09-21 23:15:20 action==address:=search-n")
187
+ actual = Appstats::Logger.entry_to_hash("0.18.0 setup[::,==,--n] 2010-09-21 23:15:20 action==address:=search-n")
188
188
  actual.should == expected
189
189
 
190
190
  expected = { :action => "address::search==--n", :timestamp => "2010-09-21 23:15:20" }
191
- actual = Appstats::Logger.entry_to_hash("0.17.5 setup[:::,===,---n] 2010-09-21 23:15:20 action===address::search==--n")
191
+ actual = Appstats::Logger.entry_to_hash("0.18.0 setup[:::,===,---n] 2010-09-21 23:15:20 action===address::search==--n")
192
192
  actual.should == expected
193
193
  end
194
194
 
195
195
  it "should handle contexts with the delimiter (and change the delimiter)" do
196
196
  expected = { :action => "address", :timestamp => "2010-09-21 23:15:20", :server => "market:eval=-n" }
197
- actual = Appstats::Logger.entry_to_hash("0.17.5 setup[::,==,--n] 2010-09-21 23:15:20 action==address :: server==market:eval=-n")
197
+ actual = Appstats::Logger.entry_to_hash("0.18.0 setup[::,==,--n] 2010-09-21 23:15:20 action==address :: server==market:eval=-n")
198
198
  actual.should == expected
199
199
  end
200
200
 
@@ -203,66 +203,66 @@ module Appstats
203
203
  describe "#entry_to_s" do
204
204
 
205
205
  it "should handle a statistics entry" do
206
- expected = "0.17.5 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search"
206
+ expected = "0.18.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search"
207
207
  actual = Appstats::Logger.entry_to_s("address_search")
208
208
  actual.should == expected
209
209
  end
210
210
 
211
211
  it "should handle numbers" do
212
- expected = "0.17.5 setup[:,=,-n] 2010-09-21 23:15:20 action=1 : note=2.2"
212
+ expected = "0.18.0 setup[:,=,-n] 2010-09-21 23:15:20 action=1 : note=2.2"
213
213
  actual = Appstats::Logger.entry_to_s(1,:note => 2.2)
214
214
  actual.should == expected
215
215
  end
216
216
 
217
217
  it "should handle default contexts" do
218
218
  Appstats::Logger.default_contexts[:app_name] = "market"
219
- expected = "0.17.5 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search : app_name=market"
219
+ expected = "0.18.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search : app_name=market"
220
220
  actual = Appstats::Logger.entry_to_s("address_search")
221
221
  actual.should == expected
222
222
  end
223
223
 
224
224
  it "should handle contexts (and sort them by symbol)" do
225
- expected = "0.17.5 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : app_name=Market : server=Live"
225
+ expected = "0.18.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : app_name=Market : server=Live"
226
226
  actual = Appstats::Logger.entry_to_s("address_filter", { :server => "Live", :app_name => 'Market' })
227
227
  actual.should == expected
228
228
  end
229
229
 
230
230
  it "should handle actions with the delimiter (and change the delimiter)" do
231
- expected = "0.17.5 setup[::,==,--n] 2010-09-21 23:15:20 action==address:=search-n"
231
+ expected = "0.18.0 setup[::,==,--n] 2010-09-21 23:15:20 action==address:=search-n"
232
232
  actual = Appstats::Logger.entry_to_s("address:=search-n")
233
233
  actual.should == expected
234
234
 
235
- expected = "0.17.5 setup[:::,===,---n] 2010-09-21 23:15:20 action===address::search==--n"
235
+ expected = "0.18.0 setup[:::,===,---n] 2010-09-21 23:15:20 action===address::search==--n"
236
236
  actual = Appstats::Logger.entry_to_s("address::search==--n")
237
237
  actual.should == expected
238
238
  end
239
239
 
240
240
  it "should handle contexts with the delimiter (and change the delimiter)" do
241
- expected = "0.17.5 setup[::,==,--n] 2010-09-21 23:15:20 action==address :: server==market:eval=-n"
241
+ expected = "0.18.0 setup[::,==,--n] 2010-09-21 23:15:20 action==address :: server==market:eval=-n"
242
242
  actual = Appstats::Logger.entry_to_s("address", :server => 'market:eval=-n')
243
243
  actual.should == expected
244
244
  end
245
245
 
246
246
  it "should ignore spaces" do
247
- expected = "0.17.5 setup[:,=,-n] 2010-09-21 23:15:20 action=address search"
247
+ expected = "0.18.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address search"
248
248
  actual = Appstats::Logger.entry_to_s("address search")
249
249
  actual.should == expected
250
250
  end
251
251
 
252
252
  it "should convert newlines in action" do
253
- expected = "0.17.5 setup[:,=,-n] 2010-09-21 23:15:20 action=address_-nsearch"
253
+ expected = "0.18.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_-nsearch"
254
254
  actual = Appstats::Logger.entry_to_s("address_\nsearch")
255
255
  actual.should == expected
256
256
  end
257
257
 
258
258
  it "should convert newlines in context" do
259
- expected = "0.17.5 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search : blah=some-nlong-nstatement"
259
+ expected = "0.18.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search : blah=some-nlong-nstatement"
260
260
  actual = Appstats::Logger.entry_to_s("address_search",:blah => "some\nlong\nstatement")
261
261
  actual.should == expected
262
262
  end
263
263
 
264
264
  it "should convert newlines based on the delimiter" do
265
- expected = "0.17.5 setup[::,==,--n] 2010-09-21 23:15:20 action==address:=--nsearch-n"
265
+ expected = "0.18.0 setup[::,==,--n] 2010-09-21 23:15:20 action==address:=--nsearch-n"
266
266
  actual = Appstats::Logger.entry_to_s("address:=\nsearch-n")
267
267
  actual.should == expected
268
268
  end
@@ -25,10 +25,12 @@ module Appstats
25
25
  @result.db_username.should == nil
26
26
  @result.db_name.should == nil
27
27
  @result.db_host.should == nil
28
+ @result.is_latest.should == nil
29
+ @result.is_latest?.should == false
28
30
  end
29
31
 
30
32
  it "should set on constructor" do
31
- result = Appstats::Result.new(:name => 'a', :result_type => 'b', :query => 'c', :query_to_sql => 'd', :count => 10, :action => 'e', :host => 'f', :contexts => 'g', :from_date => Time.parse("2010-01-02"), :to_date => Time.parse("2010-02-03"), :group_by => "a,b", :query_type => 'h', :db_username => 'i', :db_name => 'j', :db_host => 'k')
33
+ result = Appstats::Result.new(:name => 'a', :result_type => 'b', :query => 'c', :query_to_sql => 'd', :count => 10, :action => 'e', :host => 'f', :contexts => 'g', :from_date => Time.parse("2010-01-02"), :to_date => Time.parse("2010-02-03"), :group_by => "a,b", :query_type => 'h', :db_username => 'i', :db_name => 'j', :db_host => 'k', :is_latest => true)
32
34
  result.name.should == 'a'
33
35
  result.result_type.should == 'b'
34
36
  result.query.should == 'c'
@@ -44,6 +46,8 @@ module Appstats
44
46
  result.db_username.should == "i"
45
47
  result.db_name.should == "j"
46
48
  result.db_host.should == "k"
49
+ result.is_latest?.should == true
50
+ result.is_latest.should == true
47
51
  end
48
52
 
49
53
  end
@@ -188,6 +192,59 @@ module Appstats
188
192
 
189
193
  end
190
194
 
195
+ describe "#after_save" do
196
+
197
+ before(:each) do
198
+ Appstats::Result.delete_all
199
+ end
200
+
201
+ it "should only fix yourself" do
202
+ Time.stub!(:now).and_return(Time.parse('2011-09-21 23:15:20'))
203
+ new_result = Appstats::Result.create(:query => '# x')
204
+ another_new_result = Appstats::Result.create(:query => '# y')
205
+ Time.stub!(:now).and_return(Time.parse('2010-09-21 23:15:20'))
206
+ another_old_result = Appstats::Result.create(:query => '# y')
207
+ ActiveRecord::Base.connection.update('update appstats_results set is_latest = null')
208
+
209
+ old_result = Appstats::Result.create(:query => '# x')
210
+
211
+ new_result.reload and old_result.reload and another_new_result.reload and another_old_result.reload
212
+ new_result.is_latest?.should == true
213
+ old_result.is_latest?.should == false
214
+ another_new_result.is_latest?.should == false
215
+ another_old_result.is_latest?.should == false
216
+ end
217
+
218
+ end
219
+
220
+ describe "#fix_all_is_latest" do
221
+
222
+ before(:each) do
223
+ Appstats::Result.delete_all
224
+ end
225
+
226
+ it "should work for no results" do
227
+ Appstats::Result.fix_all_is_latest
228
+ end
229
+
230
+ it "should fix all resutls" do
231
+ Time.stub!(:now).and_return(Time.parse('2011-09-21 23:15:20'))
232
+ new_result = Appstats::Result.create(:query => '# x')
233
+ Time.stub!(:now).and_return(Time.parse('2010-09-21 23:15:20'))
234
+ old_result = Appstats::Result.create(:query => '# x')
235
+ another_result = Appstats::Result.create(:query => '# y')
236
+ ActiveRecord::Base.connection.update('update appstats_results set is_latest = null')
237
+
238
+ Appstats::Result.fix_all_is_latest
239
+
240
+ new_result.reload and old_result.reload and another_result.reload
241
+ new_result.is_latest?.should == true
242
+ old_result.is_latest?.should == false
243
+ another_result.is_latest?.should == true
244
+ end
245
+
246
+ end
247
+
191
248
  describe "#count_to_s" do
192
249
 
193
250
  it "should handle nil" do
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appstats
3
3
  version: !ruby/object:Gem::Version
4
- hash: 81
4
+ hash: 87
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 17
9
- - 5
10
- version: 0.17.5
8
+ - 18
9
+ - 0
10
+ version: 0.18.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Andrew Forward
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-03-17 00:00:00 -04:00
18
+ date: 2011-03-18 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -179,6 +179,7 @@ files:
179
179
  - db/migrations/20110301212017_add_appstats_results_query_type.rb
180
180
  - db/migrations/20110301230757_rename_appstats_results_query_as_sql_to_query_to_sql.rb
181
181
  - db/migrations/20110311214833_add_appstats_results_db_connection.rb
182
+ - db/migrations/20110318203339_add_appstats_results_latest_flag.rb
182
183
  - db/schema.rb
183
184
  - lib/appstats.rb
184
185
  - lib/appstats/action.rb