appstats 0.17.5 → 0.18.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.
@@ -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