appstats 0.14.0 → 0.15.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/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- appstats (0.14.0)
4
+ appstats (0.15.0)
5
5
  daemons
6
6
  net-scp
7
7
  rails (>= 2.3.0)
@@ -0,0 +1,9 @@
1
+ class AddAppstatsResultsGroups < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :appstats_results, :group_by, :string
4
+ end
5
+
6
+ def self.down
7
+ remove_column :appstats_results, :group_by
8
+ end
9
+ end
data/db/schema.rb CHANGED
@@ -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 => 20110301170947) do
13
+ ActiveRecord::Schema.define(:version => 20110301195959) do
14
14
 
15
15
  create_table "appstats_actions", :force => true do |t|
16
16
  t.string "name"
@@ -119,6 +119,7 @@ ActiveRecord::Schema.define(:version => 20110301170947) do
119
119
  t.datetime "updated_at"
120
120
  t.text "contexts"
121
121
  t.text "group_query_to_sql"
122
+ t.string "group_by"
122
123
  end
123
124
 
124
125
  add_index "appstats_results", ["action"], :name => "index_appstats_results_on_action"
@@ -2,13 +2,13 @@
2
2
  module Appstats
3
3
  class Query
4
4
 
5
- @@parser_template = Appstats::Parser.new(:rules => ":operation :action :date on :host where :contexts group by :groups")
5
+ @@parser_template = Appstats::Parser.new(:rules => ":operation :action :date on :host where :contexts group by :group_by")
6
6
  @@contexts_parser_template = Appstats::Parser.new(:rules => ":context", :repeating => true, :tokenize => "and or || && = <= >= <> != ( ) like")
7
- @@groups_parser_template = Appstats::Parser.new(:rules => ":filter", :repeating => true, :tokenize => ",")
7
+ @@group_by_parser_template = Appstats::Parser.new(:rules => ":filter", :repeating => true, :tokenize => ",")
8
8
 
9
9
  @@nill_query = "select 0 from appstats_entries LIMIT 1"
10
10
  @@default = "1=1"
11
- attr_accessor :name, :query, :action, :host, :date_range, :query_to_sql, :contexts, :groups, :group_query_to_sql
11
+ attr_accessor :name, :query, :action, :host, :date_range, :query_to_sql, :contexts, :group_by, :group_query_to_sql
12
12
 
13
13
  def initialize(data = {})
14
14
  @name = data[:name]
@@ -23,14 +23,18 @@ module Appstats
23
23
 
24
24
  def run
25
25
  result = Appstats::Result.new(:name => @name, :result_type => @result_type, :query => @query, :query_as_sql => @query_to_sql, :action => @action, :host => @host, :from_date => @date_range.from_date, :to_date => @date_range.to_date, :contexts => @contexts)
26
+ result.group_by = @group_by.join(", ") unless @group_by.empty?
26
27
  result.count = ActiveRecord::Base.connection.select_one(@query_to_sql)["count(*)"].to_i
27
28
  result.save
28
29
 
29
- unless @groups.empty?
30
+ unless @group_by.empty?
30
31
  all_sub_results = ActiveRecord::Base.connection.select_all(@group_query_to_sql)
31
32
  all_sub_results.each do |data|
33
+ keys = data["context_key_filter"].split(",")
34
+ values = data["context_value_filter"].split(",")
35
+ key_values = {} and keys.each_with_index { |k,i| key_values[k] = values[i] }
32
36
  ratio_of_total = data["num"].to_f / result.count
33
- sub_result = Appstats::SubResult.new(:context_filter => data["context_filter"], :count => data["num"], :ratio_of_total => ratio_of_total)
37
+ sub_result = Appstats::SubResult.new(:context_filter => @group_by.collect { |k| key_values[k] }.join(", "), :count => data["num"], :ratio_of_total => ratio_of_total)
34
38
  sub_result.result = result
35
39
  sub_result.save
36
40
  end
@@ -113,12 +117,12 @@ module Appstats
113
117
  action.nil? ? action_name : action.name
114
118
  end
115
119
 
116
- def parse_groups(raw_input)
117
- group_parser = @@groups_parser_template.dup
120
+ def parse_group_by(raw_input)
121
+ group_parser = @@group_by_parser_template.dup
118
122
  return if (raw_input.blank? || !group_parser.parse(raw_input))
119
123
  group_parser.raw_results.each do |entry|
120
124
  next if entry.kind_of?(String)
121
- @groups<< entry[:filter]
125
+ @group_by<< entry[:filter]
122
126
  end
123
127
  end
124
128
 
@@ -135,7 +139,7 @@ module Appstats
135
139
  @date_range = DateRange.parse(parser.results[:date])
136
140
  @host = parser.results[:host]
137
141
  @contexts = parser.results[:contexts]
138
- parse_groups(parser.results[:groups])
142
+ parse_group_by(parser.results[:group_by])
139
143
 
140
144
  if @operation == "#"
141
145
  @query_to_sql = "select count(*) from appstats_entries"
@@ -145,10 +149,10 @@ module Appstats
145
149
  @query_to_sql += " and #{Query.contexts_filter_to_sql(@contexts)}" unless @contexts.nil?
146
150
  end
147
151
 
148
- unless @groups.empty?
152
+ unless @group_by.empty?
149
153
  query_to_sql_with_id = @query_to_sql.sub("count(*)","id")
150
- group_as_sql = @groups.collect { |g| "'#{Query.sqlclean(g)}'" }.join(',')
151
- @group_query_to_sql = "select context_filter, count(*) num from (select group_concat(appstats_contexts.context_value separator ', ') as context_filter, appstats_entry_id from appstats_contexts where context_key in (#{group_as_sql}) and appstats_entry_id in ( #{query_to_sql_with_id} ) group by appstats_entry_id) results group by context_filter;"
154
+ group_as_sql = @group_by.collect { |g| "'#{Query.sqlclean(g)}'" }.join(',')
155
+ @group_query_to_sql = "select context_key_filter, context_value_filter, count(*) num from (select group_concat(appstats_contexts.context_key) as context_key_filter, group_concat(appstats_contexts.context_value) as context_value_filter, appstats_entry_id from appstats_contexts where context_key in (#{group_as_sql}) and appstats_entry_id in ( #{query_to_sql_with_id} ) group by appstats_entry_id) results group by context_value_filter;"
152
156
  end
153
157
 
154
158
  @query_to_sql
@@ -174,7 +178,7 @@ module Appstats
174
178
  @host = nil
175
179
  nil_query
176
180
  @date_range = DateRange.new
177
- @groups = []
181
+ @group_by = []
178
182
  end
179
183
 
180
184
  end
@@ -2,7 +2,7 @@ module Appstats
2
2
  class Result < ActiveRecord::Base
3
3
  set_table_name "appstats_results"
4
4
 
5
- attr_accessible :name, :result_type, :query, :query_as_sql, :count, :action, :host, :from_date, :to_date, :contexts
5
+ attr_accessible :name, :result_type, :query, :query_as_sql, :count, :action, :host, :from_date, :to_date, :contexts, :group_by
6
6
  has_many :sub_results, :table_name => 'appstats_subresults', :foreign_key => 'appstats_result_id', :order => 'count DESC'
7
7
 
8
8
  def date_to_s
@@ -47,7 +47,7 @@ module Appstats
47
47
  private
48
48
 
49
49
  def state
50
- [name, result_type, query, query_as_sql, count, action, host, from_date, to_date,contexts]
50
+ [name, result_type, query, query_as_sql, count, action, host, from_date, to_date,contexts,group_by]
51
51
  end
52
52
 
53
53
 
@@ -1,3 +1,3 @@
1
1
  module Appstats
2
- VERSION = "0.14.0"
2
+ VERSION = "0.15.0"
3
3
  end
data/spec/entry_spec.rb CHANGED
@@ -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.14.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search")
196
+ entry = Entry.create_from_logger_string("0.15.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.14.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search"
199
+ entry.raw_entry.should == "0.15.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.14.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : app_name=Market : server=Live")
204
+ entry = Entry.create_from_logger_string("0.15.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.14.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : app_name=Market : server=Live"
207
+ entry.raw_entry.should == "0.15.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.14.0 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.15.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.14.0 setup[:,=,-n] 2011-02-24 12:59:57 action=page-view : action=save_ovcen : app_name=cdb"
220
+ entry.raw_entry.should == "0.15.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.14.0 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.15.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.14.0 setup[:,=,-n] 2011-02-24 12:59:57 action=page-view : app_name=market : app_name=cdb"
234
+ entry.raw_entry.should == "0.15.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"
data/spec/logger_spec.rb CHANGED
@@ -115,12 +115,12 @@ module Appstats
115
115
 
116
116
  it "should accept numbers" do
117
117
  Appstats::Logger.entry(5, :blah => 6)
118
- Appstats::Logger.raw_read.should == ["0.14.0 setup[:,=,-n] 2010-09-21 23:15:20 action=5 : blah=6"]
118
+ Appstats::Logger.raw_read.should == ["0.15.0 setup[:,=,-n] 2010-09-21 23:15:20 action=5 : blah=6"]
119
119
  end
120
120
 
121
121
  it "should accept arrays" do
122
122
  Appstats::Logger.entry('search', :provider => [ 'one', 'two' ])
123
- Appstats::Logger.raw_read.should == ["0.14.0 setup[:,=,-n] 2010-09-21 23:15:20 action=search : provider=one : provider=two"]
123
+ Appstats::Logger.raw_read.should == ["0.15.0 setup[:,=,-n] 2010-09-21 23:15:20 action=search : provider=one : provider=two"]
124
124
  end
125
125
 
126
126
 
@@ -130,7 +130,7 @@ module Appstats
130
130
 
131
131
  it "should look similar to regular entry" do
132
132
  Appstats::Logger.exception_entry(RuntimeError.new("blah"),:on => "login")
133
- Appstats::Logger.raw_read.should == ["0.14.0 setup[:,=,-n] 2010-09-21 23:15:20 action=appstats-exception : error=blah : on=login"]
133
+ Appstats::Logger.raw_read.should == ["0.15.0 setup[:,=,-n] 2010-09-21 23:15:20 action=appstats-exception : error=blah : on=login"]
134
134
  end
135
135
 
136
136
  end
@@ -147,47 +147,47 @@ module Appstats
147
147
 
148
148
  it "should handle a statistics entry" do
149
149
  expected = { :action => "address_search", :timestamp => "2010-09-21 23:15:20" }
150
- actual = Appstats::Logger.entry_to_hash("0.14.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search")
150
+ actual = Appstats::Logger.entry_to_hash("0.15.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search")
151
151
  actual.should == expected
152
152
  end
153
153
 
154
154
  it "should handle contexts" do
155
155
  expected = { :action => "address_filter", :timestamp => "2010-09-21 23:15:20", :server => "Live", :app_name => 'Market' }
156
- actual = Appstats::Logger.entry_to_hash("0.14.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : app_name=Market : server=Live")
156
+ actual = Appstats::Logger.entry_to_hash("0.15.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : app_name=Market : server=Live")
157
157
  actual.should == expected
158
158
  end
159
159
 
160
160
  it "should handle multiple actions" do
161
161
  expected = { :action => ["address_filter", "blah"], :timestamp => "2010-09-21 23:15:20", :server => "Live", :app_name => 'Market' }
162
- actual = Appstats::Logger.entry_to_hash("0.14.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : action=blah : app_name=Market : server=Live")
162
+ actual = Appstats::Logger.entry_to_hash("0.15.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : action=blah : app_name=Market : server=Live")
163
163
  actual.should == expected
164
164
  end
165
165
 
166
166
  it "should handle multiple of same context" do
167
167
  expected = { :action => "address_filter", :timestamp => "2010-09-21 23:15:20", :server => "Live", :app_name => ['Sin','Market'] }
168
- actual = Appstats::Logger.entry_to_hash("0.14.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : app_name=Sin : app_name=Market : server=Live")
168
+ actual = Appstats::Logger.entry_to_hash("0.15.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : app_name=Sin : app_name=Market : server=Live")
169
169
  actual.should == expected
170
170
  end
171
171
 
172
172
  it "should handle no actions" do
173
173
  expected = { :action => "UNKNOWN_ACTION", :timestamp => "2010-09-21 23:15:20", :server => "Live", :app_name => 'Market' }
174
- actual = Appstats::Logger.entry_to_hash("0.14.0 setup[:,=,-n] 2010-09-21 23:15:20 app_name=Market : server=Live")
174
+ actual = Appstats::Logger.entry_to_hash("0.15.0 setup[:,=,-n] 2010-09-21 23:15:20 app_name=Market : server=Live")
175
175
  actual.should == expected
176
176
  end
177
177
 
178
178
  it "should handle actions with the delimiter (and change the delimiter)" do
179
179
  expected = { :action => "address:=search-n", :timestamp => "2010-09-21 23:15:20" }
180
- actual = Appstats::Logger.entry_to_hash("0.14.0 setup[::,==,--n] 2010-09-21 23:15:20 action==address:=search-n")
180
+ actual = Appstats::Logger.entry_to_hash("0.15.0 setup[::,==,--n] 2010-09-21 23:15:20 action==address:=search-n")
181
181
  actual.should == expected
182
182
 
183
183
  expected = { :action => "address::search==--n", :timestamp => "2010-09-21 23:15:20" }
184
- actual = Appstats::Logger.entry_to_hash("0.14.0 setup[:::,===,---n] 2010-09-21 23:15:20 action===address::search==--n")
184
+ actual = Appstats::Logger.entry_to_hash("0.15.0 setup[:::,===,---n] 2010-09-21 23:15:20 action===address::search==--n")
185
185
  actual.should == expected
186
186
  end
187
187
 
188
188
  it "should handle contexts with the delimiter (and change the delimiter)" do
189
189
  expected = { :action => "address", :timestamp => "2010-09-21 23:15:20", :server => "market:eval=-n" }
190
- actual = Appstats::Logger.entry_to_hash("0.14.0 setup[::,==,--n] 2010-09-21 23:15:20 action==address :: server==market:eval=-n")
190
+ actual = Appstats::Logger.entry_to_hash("0.15.0 setup[::,==,--n] 2010-09-21 23:15:20 action==address :: server==market:eval=-n")
191
191
  actual.should == expected
192
192
  end
193
193
 
@@ -196,66 +196,66 @@ module Appstats
196
196
  describe "#entry_to_s" do
197
197
 
198
198
  it "should handle a statistics entry" do
199
- expected = "0.14.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search"
199
+ expected = "0.15.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search"
200
200
  actual = Appstats::Logger.entry_to_s("address_search")
201
201
  actual.should == expected
202
202
  end
203
203
 
204
204
  it "should handle numbers" do
205
- expected = "0.14.0 setup[:,=,-n] 2010-09-21 23:15:20 action=1 : note=2.2"
205
+ expected = "0.15.0 setup[:,=,-n] 2010-09-21 23:15:20 action=1 : note=2.2"
206
206
  actual = Appstats::Logger.entry_to_s(1,:note => 2.2)
207
207
  actual.should == expected
208
208
  end
209
209
 
210
210
  it "should handle default contexts" do
211
211
  Appstats::Logger.default_contexts[:app_name] = "market"
212
- expected = "0.14.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search : app_name=market"
212
+ expected = "0.15.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search : app_name=market"
213
213
  actual = Appstats::Logger.entry_to_s("address_search")
214
214
  actual.should == expected
215
215
  end
216
216
 
217
217
  it "should handle contexts (and sort them by symbol)" do
218
- expected = "0.14.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : app_name=Market : server=Live"
218
+ expected = "0.15.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : app_name=Market : server=Live"
219
219
  actual = Appstats::Logger.entry_to_s("address_filter", { :server => "Live", :app_name => 'Market' })
220
220
  actual.should == expected
221
221
  end
222
222
 
223
223
  it "should handle actions with the delimiter (and change the delimiter)" do
224
- expected = "0.14.0 setup[::,==,--n] 2010-09-21 23:15:20 action==address:=search-n"
224
+ expected = "0.15.0 setup[::,==,--n] 2010-09-21 23:15:20 action==address:=search-n"
225
225
  actual = Appstats::Logger.entry_to_s("address:=search-n")
226
226
  actual.should == expected
227
227
 
228
- expected = "0.14.0 setup[:::,===,---n] 2010-09-21 23:15:20 action===address::search==--n"
228
+ expected = "0.15.0 setup[:::,===,---n] 2010-09-21 23:15:20 action===address::search==--n"
229
229
  actual = Appstats::Logger.entry_to_s("address::search==--n")
230
230
  actual.should == expected
231
231
  end
232
232
 
233
233
  it "should handle contexts with the delimiter (and change the delimiter)" do
234
- expected = "0.14.0 setup[::,==,--n] 2010-09-21 23:15:20 action==address :: server==market:eval=-n"
234
+ expected = "0.15.0 setup[::,==,--n] 2010-09-21 23:15:20 action==address :: server==market:eval=-n"
235
235
  actual = Appstats::Logger.entry_to_s("address", :server => 'market:eval=-n')
236
236
  actual.should == expected
237
237
  end
238
238
 
239
239
  it "should ignore spaces" do
240
- expected = "0.14.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address search"
240
+ expected = "0.15.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address search"
241
241
  actual = Appstats::Logger.entry_to_s("address search")
242
242
  actual.should == expected
243
243
  end
244
244
 
245
245
  it "should convert newlines in action" do
246
- expected = "0.14.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_-nsearch"
246
+ expected = "0.15.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_-nsearch"
247
247
  actual = Appstats::Logger.entry_to_s("address_\nsearch")
248
248
  actual.should == expected
249
249
  end
250
250
 
251
251
  it "should convert newlines in context" do
252
- expected = "0.14.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search : blah=some-nlong-nstatement"
252
+ expected = "0.15.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search : blah=some-nlong-nstatement"
253
253
  actual = Appstats::Logger.entry_to_s("address_search",:blah => "some\nlong\nstatement")
254
254
  actual.should == expected
255
255
  end
256
256
 
257
257
  it "should convert newlines based on the delimiter" do
258
- expected = "0.14.0 setup[::,==,--n] 2010-09-21 23:15:20 action==address:=--nsearch-n"
258
+ expected = "0.15.0 setup[::,==,--n] 2010-09-21 23:15:20 action==address:=--nsearch-n"
259
259
  actual = Appstats::Logger.entry_to_s("address:=\nsearch-n")
260
260
  actual.should == expected
261
261
  end
data/spec/query_spec.rb CHANGED
@@ -32,7 +32,7 @@ module Appstats
32
32
  query.action.should == nil
33
33
  query.host.should == nil
34
34
  query.date_range.should == DateRange.new
35
- query.groups.should == []
35
+ query.group_by.should == []
36
36
  query.group_query_to_sql.should == nil
37
37
  end
38
38
 
@@ -41,7 +41,7 @@ module Appstats
41
41
  query.action.should == "myblahs"
42
42
  query.host.should == "xyz.localnet"
43
43
  query.date_range.should == DateRange.parse("today")
44
- query.groups.should == []
44
+ query.group_by.should == []
45
45
  query.group_query_to_sql.should == nil
46
46
  end
47
47
 
@@ -50,7 +50,7 @@ module Appstats
50
50
  query.action.should == "myblahs"
51
51
  query.host.should == "xyz.localnet"
52
52
  query.date_range.should == DateRange.new
53
- query.groups.should == []
53
+ query.group_by.should == []
54
54
  query.group_query_to_sql.should == nil
55
55
  end
56
56
 
@@ -59,7 +59,7 @@ module Appstats
59
59
  query.action.should == "myblahs"
60
60
  query.host.should == "xyz.localnet"
61
61
  query.date_range.should == DateRange.new
62
- query.groups.should == []
62
+ query.group_by.should == []
63
63
  query.group_query_to_sql.should == nil
64
64
  end
65
65
 
@@ -67,12 +67,12 @@ module Appstats
67
67
 
68
68
  it "should handle single entry" do
69
69
  query = Appstats::Query.new(:query => "# myblahs group by aa")
70
- query.groups.should == ["aa"]
70
+ query.group_by.should == ["aa"]
71
71
  end
72
72
 
73
73
  it "should handle multi-entry" do
74
74
  query = Appstats::Query.new(:query => "# myblahs group by aa,bbbb")
75
- query.groups.should == ["aa","bbbb"]
75
+ query.group_by.should == ["aa","bbbb"]
76
76
  end
77
77
 
78
78
  end
@@ -91,14 +91,14 @@ module Appstats
91
91
  query = Appstats::Query.new(:query => "# blahs")
92
92
  result = query.run
93
93
  result.new_record?.should == false
94
- result.should == Appstats::Result.new(:result_type => "on_demand", :query => "# blahs", :query_as_sql => query.query_to_sql, :count => 0, :action => "blahs")
94
+ result.should == Appstats::Result.new(:result_type => "on_demand", :query => "# blahs", :query_as_sql => query.query_to_sql, :count => 0, :action => "blahs", :group_by => nil)
95
95
  end
96
96
 
97
97
  it "should set name and result_type if provided" do
98
98
  query = Appstats::Query.new(:name => "x", :result_type => "some_reason", :query => "# blahs")
99
99
  result = query.run
100
100
  result.new_record?.should == false
101
- result.should == Appstats::Result.new(:name => "x", :result_type => "some_reason", :query => "# blahs", :query_as_sql => query.query_to_sql, :count => 0, :action => "blahs")
101
+ result.should == Appstats::Result.new(:name => "x", :result_type => "some_reason", :query => "# blahs", :query_as_sql => query.query_to_sql, :count => 0, :action => "blahs", :group_by => nil)
102
102
  end
103
103
 
104
104
  it "should track contexts" do
@@ -185,13 +185,13 @@ module Appstats
185
185
 
186
186
  describe "group sub results" do
187
187
 
188
- it "should not create sub results if no groups" do
188
+ it "should not create sub results if no group_by" do
189
189
  query = Appstats::Query.new(:query => "# myblahs last day")
190
190
  result = query.run
191
191
  result.sub_results.should == []
192
192
  end
193
193
 
194
- it "should track sub results as required" do
194
+ it "should track sub results for single group by" do
195
195
  Appstats::Entry.create_from_logger("myblahs",:service_provider => "a", :ignore => "1")
196
196
  Appstats::Entry.create_from_logger("myblahs",:service_provider => "a", :ignore => "1")
197
197
  Appstats::Entry.create_from_logger("myblahs",:service_provider => "a", :ignore => "2")
@@ -200,14 +200,29 @@ module Appstats
200
200
  query = Appstats::Query.new(:query => "# myblahs group by service_provider")
201
201
  result = query.run
202
202
  result.count.should == 4
203
+ result.group_by.should == "service_provider"
203
204
  result.sub_results.size.should == 2
204
205
 
205
206
  result.sub_results[0].should == SubResult.new(:context_filter => "a", :count => 3, :ratio_of_total => 0.75)
206
207
  result.sub_results[1].should == SubResult.new(:context_filter => "b", :count => 1, :ratio_of_total => 0.25)
207
-
208
-
209
208
  end
210
209
 
210
+ it "should track sub results for multiple group by" do
211
+ Appstats::Entry.create_from_logger("myblahs",:service_provider => "a", :user => "1")
212
+ Appstats::Entry.create_from_logger("myblahs",:service_provider => "a", :user => "1")
213
+ Appstats::Entry.create_from_logger("myblahs",:service_provider => "a", :user => "2")
214
+ Appstats::Entry.create_from_logger("myblahs",:service_provider => "b", :user => "1")
215
+
216
+ query = Appstats::Query.new(:query => "# myblahs group by service_provider,user")
217
+ result = query.run
218
+ result.count.should == 4
219
+ result.group_by.should == "service_provider, user"
220
+ result.sub_results.size.should == 3
221
+
222
+ result.sub_results[0].should == SubResult.new(:context_filter => "a, 1", :count => 2, :ratio_of_total => 0.50)
223
+ result.sub_results[1].should == SubResult.new(:context_filter => "b, 1", :count => 1, :ratio_of_total => 0.25)
224
+ result.sub_results[2].should == SubResult.new(:context_filter => "a, 2", :count => 1, :ratio_of_total => 0.25)
225
+ end
211
226
 
212
227
  end
213
228
 
@@ -315,26 +330,26 @@ module Appstats
315
330
 
316
331
  it "should support 1 filter" do
317
332
  query = Appstats::Query.new(:query => "# myblahs group by aa")
318
- expected = "select context_filter, count(*) num from (select group_concat(appstats_contexts.context_value separator ', ') as context_filter, appstats_entry_id from appstats_contexts where context_key in ('aa') and appstats_entry_id in ( #{@template} ) group by appstats_entry_id) results group by context_filter;"
333
+ expected = "select context_key_filter, context_value_filter, count(*) num from (select group_concat(appstats_contexts.context_key) as context_key_filter, group_concat(appstats_contexts.context_value) as context_value_filter, appstats_entry_id from appstats_contexts where context_key in ('aa') and appstats_entry_id in ( #{@template} ) group by appstats_entry_id) results group by context_value_filter;"
319
334
  query.group_query_to_sql.should == expected
320
335
  end
321
336
 
322
337
  it "should support surrounding quotes" do
323
338
  query = Appstats::Query.new(:query => "# myblahs group by 'aa'")
324
- expected = "select context_filter, count(*) num from (select group_concat(appstats_contexts.context_value separator ', ') as context_filter, appstats_entry_id from appstats_contexts where context_key in ('aa') and appstats_entry_id in ( #{@template} ) group by appstats_entry_id) results group by context_filter;"
339
+ expected = "select context_key_filter, context_value_filter, count(*) num from (select group_concat(appstats_contexts.context_key) as context_key_filter, group_concat(appstats_contexts.context_value) as context_value_filter, appstats_entry_id from appstats_contexts where context_key in ('aa') and appstats_entry_id in ( #{@template} ) group by appstats_entry_id) results group by context_value_filter;"
325
340
  query.group_query_to_sql.should == expected
326
341
  end
327
342
 
328
343
  it "should support inner quotes" do
329
344
  query = Appstats::Query.new(:query => "# myblahs group by a's")
330
- expected = "select context_filter, count(*) num from (select group_concat(appstats_contexts.context_value separator ', ') as context_filter, appstats_entry_id from appstats_contexts where context_key in ('a''s') and appstats_entry_id in ( #{@template} ) group by appstats_entry_id) results group by context_filter;"
345
+ expected = "select context_key_filter, context_value_filter, count(*) num from (select group_concat(appstats_contexts.context_key) as context_key_filter, group_concat(appstats_contexts.context_value) as context_value_filter, appstats_entry_id from appstats_contexts where context_key in ('a''s') and appstats_entry_id in ( #{@template} ) group by appstats_entry_id) results group by context_value_filter;"
331
346
  query.group_query_to_sql.should == expected
332
347
  end
333
348
 
334
349
 
335
350
  it "should support many filters" do
336
351
  query = Appstats::Query.new(:query => "# myblahs group by aa, bbb")
337
- expected = "select context_filter, count(*) num from (select group_concat(appstats_contexts.context_value separator ', ') as context_filter, appstats_entry_id from appstats_contexts where context_key in ('aa','bbb') and appstats_entry_id in ( #{@template} ) group by appstats_entry_id) results group by context_filter;"
352
+ expected = "select context_key_filter, context_value_filter, count(*) num from (select group_concat(appstats_contexts.context_key) as context_key_filter, group_concat(appstats_contexts.context_value) as context_value_filter, appstats_entry_id from appstats_contexts where context_key in ('aa','bbb') and appstats_entry_id in ( #{@template} ) group by appstats_entry_id) results group by context_value_filter;"
338
353
  query.group_query_to_sql.should == expected
339
354
  end
340
355
 
data/spec/result_spec.rb CHANGED
@@ -20,10 +20,11 @@ module Appstats
20
20
  @result.contexts.should == nil
21
21
  @result.from_date.should == nil
22
22
  @result.to_date.should == nil
23
+ @result.group_by.should == nil
23
24
  end
24
25
 
25
26
  it "should set on constructor" do
26
- result = Appstats::Result.new(:name => 'a', :result_type => 'b', :query => 'c', :query_as_sql => 'd', :count => 10, :action => 'e', :host => 'f', :contexts => 'g', :from_date => Time.parse("2010-01-02"), :to_date => Time.parse("2010-02-03"))
27
+ result = Appstats::Result.new(:name => 'a', :result_type => 'b', :query => 'c', :query_as_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")
27
28
  result.name.should == 'a'
28
29
  result.result_type.should == 'b'
29
30
  result.query.should == 'c'
@@ -34,6 +35,7 @@ module Appstats
34
35
  result.contexts.should == 'g'
35
36
  result.from_date_to_s.should == '2010-01-02'
36
37
  result.to_date_to_s.should == '2010-02-03'
38
+ result.group_by.should == "a,b"
37
39
  end
38
40
 
39
41
  end
@@ -41,16 +43,16 @@ module Appstats
41
43
  describe "#==" do
42
44
 
43
45
  it "should be equal on all attributes" do
44
- result = Appstats::Result.new(:name => 'a', :result_type => 'b', :query => 'c', :query_as_sql => 'd', :count => 10, :action => 'e', :host => 'f', :contexts => 'g', :from_date => Time.parse("2010-01-02"), :to_date => Time.parse("2010-02-03"))
45
- same_result = Appstats::Result.new(:name => 'a', :result_type => 'b', :query => 'c', :query_as_sql => 'd', :count => 10, :action => 'e', :host => 'f', :contexts => 'g', :from_date => Time.parse("2010-01-02"), :to_date => Time.parse("2010-02-03"))
46
+ result = Appstats::Result.new(:name => 'a', :result_type => 'b', :query => 'c', :query_as_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")
47
+ same_result = Appstats::Result.new(:name => 'a', :result_type => 'b', :query => 'c', :query_as_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")
46
48
  (result == same_result).should == true
47
49
  end
48
50
 
49
51
  it "should be not equal if diferent attributes" do
50
- result = Appstats::Result.new(:name => 'a', :result_type => 'b', :query => 'c', :query_as_sql => 'd', :count => 10, :action => 'e', :host => 'f', :contexts => 'g', :from_date => Time.parse("2010-01-02"), :to_date => Time.parse("2010-02-03"))
52
+ result = Appstats::Result.new(:name => 'a', :result_type => 'b', :query => 'c', :query_as_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")
51
53
 
52
- [:name,:result_type,:query,:query_as_sql,:count,:action,:host,:contexts,:from_date,:to_date].each do |attr|
53
- different_result = Appstats::Result.new(:name => 'a', :result_type => 'b', :query => 'c', :query_as_sql => 'd', :count => 10, :action => 'e', :host => 'f', :contexts => 'g', :from_date => Time.parse("2010-01-02"), :to_date => Time.parse("2010-02-03"))
54
+ [:name,:result_type,:query,:query_as_sql,:count,:action,:host,:contexts,:from_date,:to_date,:group_by].each do |attr|
55
+ different_result = Appstats::Result.new(:name => 'a', :result_type => 'b', :query => 'c', :query_as_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")
54
56
 
55
57
  if [:from_date,:to_date].include?(attr)
56
58
  different_result.send("#{attr}=",Time.parse("2011-01-02"))
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: 39
4
+ hash: 35
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 14
8
+ - 15
9
9
  - 0
10
- version: 0.14.0
10
+ version: 0.15.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Andrew Forward
@@ -161,6 +161,7 @@ files:
161
161
  - db/migrations/20110225192624_add_appstats_log_collector_local_filename.rb
162
162
  - db/migrations/20110301170733_add_appstats_results_group_query_to_sql.rb
163
163
  - db/migrations/20110301170947_create_appstats_sub_results.rb
164
+ - db/migrations/20110301195959_add_appstats_results_groups.rb
164
165
  - db/schema.rb
165
166
  - lib/appstats.rb
166
167
  - lib/appstats/action.rb