jzimmek-reportme 0.4.2 → 0.5.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/VERSION +1 -1
- data/lib/reportme/period.rb +44 -0
- data/lib/reportme/report.rb +11 -20
- data/lib/reportme/report_factory.rb +102 -250
- data/lib/reportme/sql.rb +106 -0
- data/test/reportme_test.rb +155 -151
- metadata +4 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.0
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Reportme
|
2
|
+
|
3
|
+
class Period
|
4
|
+
|
5
|
+
def self.calc(today, wanted_periods=[:day])
|
6
|
+
|
7
|
+
today = today.to_date
|
8
|
+
|
9
|
+
r = []
|
10
|
+
|
11
|
+
wanted_periods.each do |period|
|
12
|
+
|
13
|
+
von, bis = case period
|
14
|
+
when :today
|
15
|
+
[today, today]
|
16
|
+
when :day
|
17
|
+
[today - 1.day, today - 1.day]
|
18
|
+
when :week
|
19
|
+
[today - 1.week, today - 1.day]
|
20
|
+
when :calendar_week
|
21
|
+
day_lastweek = today.to_date - 7.days
|
22
|
+
monday = day_lastweek - (day_lastweek.cwday - 1).days
|
23
|
+
[monday, monday + 6.days]
|
24
|
+
when :month
|
25
|
+
[today - 1.day - 30.days, today - 1.day]
|
26
|
+
when :calendar_month
|
27
|
+
n = today - 1.month
|
28
|
+
[n.beginning_of_month, n.end_of_month]
|
29
|
+
end
|
30
|
+
|
31
|
+
von = von.to_datetime
|
32
|
+
bis = bis.to_datetime + 23.hours + 59.minutes + 59.seconds
|
33
|
+
|
34
|
+
r << {:name => period, :von => von, :bis => bis}
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
r
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
data/lib/reportme/report.rb
CHANGED
@@ -9,7 +9,6 @@ module Reportme
|
|
9
9
|
|
10
10
|
@report_factory = report_factory
|
11
11
|
@name = name
|
12
|
-
@periods = [:today, :day, :week, :calendar_week, :month, :calendar_month]
|
13
12
|
@depends_on = []
|
14
13
|
@temporary = temporary
|
15
14
|
end
|
@@ -31,23 +30,18 @@ module Reportme
|
|
31
30
|
@depends_on
|
32
31
|
end
|
33
32
|
|
34
|
-
def periods(wanted_periods=[])
|
35
|
-
wanted_periods = wanted_periods.collect{|p| p.to_sym}
|
36
|
-
|
37
|
-
unless wanted_periods.blank?
|
38
|
-
@periods.clear
|
39
|
-
wanted_periods.each do |period|
|
40
|
-
@periods << period
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def wants_period?(period)
|
46
|
-
@periods.include?(period)
|
47
|
-
end
|
48
|
-
|
49
33
|
def sql(von, bis, period_name)
|
50
|
-
@source.call(von, bis, period_name)
|
34
|
+
raw = @source.call(von, bis, period_name)
|
35
|
+
|
36
|
+
<<-SQL
|
37
|
+
select
|
38
|
+
'#{von}' as von,
|
39
|
+
rtmp1.*
|
40
|
+
from (
|
41
|
+
#{raw}
|
42
|
+
) rtmp1
|
43
|
+
SQL
|
44
|
+
|
51
45
|
end
|
52
46
|
|
53
47
|
def table_name(period)
|
@@ -55,9 +49,6 @@ module Reportme
|
|
55
49
|
"#{prefix}#{name}_#{period}"
|
56
50
|
end
|
57
51
|
|
58
|
-
def table_exist?(period)
|
59
|
-
ActiveRecord::Base.connection.select_value("show tables like '#{table_name(period)}'") != nil
|
60
|
-
end
|
61
52
|
|
62
53
|
def select_value(sql); @report_factory.select_value(sql); end
|
63
54
|
def select_values(sql); @report_factory.select_values(sql); end
|
@@ -1,9 +1,13 @@
|
|
1
1
|
require 'reportme/report'
|
2
2
|
require 'reportme/mailer'
|
3
|
+
require 'reportme/sql'
|
4
|
+
require 'reportme/period'
|
3
5
|
|
4
6
|
module Reportme
|
5
7
|
class ReportFactory
|
6
8
|
|
9
|
+
include Sql
|
10
|
+
|
7
11
|
dsl_attr :reports, :default => lambda{ [] }
|
8
12
|
dsl_attr :subscribtions, :default => lambda{ {} }
|
9
13
|
dsl_attr :properties, :default => lambda{ {} }
|
@@ -31,46 +35,6 @@ module Reportme
|
|
31
35
|
@@init = block;
|
32
36
|
end
|
33
37
|
|
34
|
-
def self.periods(today)
|
35
|
-
|
36
|
-
today = today.to_date
|
37
|
-
|
38
|
-
r = []
|
39
|
-
p = []
|
40
|
-
|
41
|
-
# period "today" will never be generated for previous days
|
42
|
-
p << :today if today == Date.today
|
43
|
-
p += [:day, :week, :calendar_week, :month, :calendar_month]
|
44
|
-
|
45
|
-
p.each do |period|
|
46
|
-
|
47
|
-
von, bis = case period
|
48
|
-
when :today
|
49
|
-
[today, today]
|
50
|
-
when :day
|
51
|
-
[today - 1.day, today - 1.day]
|
52
|
-
when :week
|
53
|
-
[today - 1.week, today - 1.day]
|
54
|
-
when :calendar_week
|
55
|
-
day_lastweek = today.to_date - 7.days
|
56
|
-
monday = day_lastweek - (day_lastweek.cwday - 1).days
|
57
|
-
[monday, monday + 6.days]
|
58
|
-
when :month
|
59
|
-
[today - 1.day - 30.days, today - 1.day]
|
60
|
-
when :calendar_month
|
61
|
-
n = today - 1.month
|
62
|
-
[n.beginning_of_month, n.end_of_month]
|
63
|
-
end
|
64
|
-
|
65
|
-
von = von.to_datetime
|
66
|
-
bis = bis.to_datetime + 23.hours + 59.minutes + 59.seconds
|
67
|
-
|
68
|
-
r << {:name => period, :von => von, :bis => bis}
|
69
|
-
|
70
|
-
end
|
71
|
-
|
72
|
-
r
|
73
|
-
end
|
74
38
|
|
75
39
|
def report_information_table_name
|
76
40
|
"report_informations"
|
@@ -102,36 +66,23 @@ module Reportme
|
|
102
66
|
schema
|
103
67
|
end
|
104
68
|
|
105
|
-
def columns(table_name)
|
106
|
-
self.class.columns(table_name)
|
107
|
-
end
|
108
|
-
|
109
|
-
def self.columns(table_name)
|
110
|
-
sql = <<-SQL
|
111
|
-
select
|
112
|
-
column_name
|
113
|
-
from
|
114
|
-
information_schema.columns
|
115
|
-
where
|
116
|
-
table_schema = '#{schema_name}'
|
117
|
-
and table_name = '#{table_name}'
|
118
|
-
;
|
119
|
-
SQL
|
120
|
-
select_values(sql)
|
121
|
-
end
|
122
69
|
|
123
|
-
def ensure_report_tables_exist(report)
|
124
|
-
|
125
|
-
[:today, :day, :week, :calendar_week, :month, :calendar_month].each do |period|
|
126
|
-
next unless report.wants_period?(period)
|
127
|
-
|
128
|
-
unless report.table_exist?(period)
|
129
|
-
table_name = report.table_name(period)
|
130
|
-
sql = report.sql('0000-00-00 00:00:00', '0000-00-00 00:00:00', period)
|
70
|
+
def ensure_report_tables_exist(report, period_name)
|
131
71
|
|
132
|
-
|
72
|
+
table_name = report.table_name(period_name)
|
73
|
+
sql = report.sql('0000-00-00 00:00:00', '0000-00-00 00:00:00', period_name)
|
74
|
+
|
75
|
+
unless table_exist?(table_name)
|
76
|
+
exec("create table #{table_name} ENGINE=InnoDB default CHARSET=utf8 as #{sql} limit 0;")
|
77
|
+
exec("alter table #{table_name} modify von datetime;")
|
78
|
+
exec("alter table #{table_name} add index(von);")
|
79
|
+
|
80
|
+
if period_name != :day
|
81
|
+
exec("alter table #{table_name} add day date after von;")
|
82
|
+
exec("alter table #{table_name} add index(day);")
|
133
83
|
end
|
134
84
|
end
|
85
|
+
|
135
86
|
end
|
136
87
|
|
137
88
|
def ensure_report_informations_table_exist
|
@@ -149,39 +100,8 @@ module Reportme
|
|
149
100
|
ENGINE=InnoDB default CHARSET=utf8;
|
150
101
|
SQL
|
151
102
|
exec(ddl)
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
def try_report_by_daily_reports(report, period_name, _von, num_days, num_days_required)
|
156
|
-
table_name = report.table_name(period_name)
|
157
|
-
|
158
|
-
von = _von.strftime("%Y-%m-%d 00:00:00")
|
159
|
-
bis = (_von + num_days.days).strftime("%Y-%m-%d 23:59:59")
|
160
|
-
|
161
|
-
existing_daily_reports = select_value(<<-SQL
|
162
|
-
select
|
163
|
-
count(1) cnt
|
164
|
-
from
|
165
|
-
#{report_information_table_name}
|
166
|
-
where
|
167
|
-
report = '#{report.table_name(:day)}'
|
168
|
-
and von between '#{von}' and '#{(_von + num_days.days).strftime("%Y-%m-%d 00:00:00")}'
|
169
|
-
SQL
|
170
|
-
).to_i
|
171
|
-
|
172
|
-
puts "#{period_name}ly report depends on #{num_days_required} daily reports ... #{existing_daily_reports} daily found"
|
173
|
-
|
174
|
-
if existing_daily_reports == num_days_required
|
175
|
-
|
176
|
-
column_names = ["'#{von}' as von"]
|
177
|
-
column_names += columns(table_name).find_all{|c|c != "von"}.collect{|c|"d.#{c} as #{c}"}
|
178
|
-
|
179
|
-
ActiveRecord::Base.transaction do
|
180
|
-
exec("insert into #{report_information_table_name} values ('#{table_name}', '#{von}', '#{bis}', now());")
|
181
|
-
exec("insert into #{table_name} select #{column_names.join(',')} from #{report.table_name(:day)} as d where d.von between '#{von}' and '#{(_von + num_days.days).strftime("%Y-%m-%d 00:00:00")}';")
|
182
|
-
|
183
|
-
remember_report_creation(report, period_name, _von)
|
184
|
-
end
|
103
|
+
exec("alter table report_informations add index(report);")
|
104
|
+
exec("alter table report_informations add index(report, von);")
|
185
105
|
end
|
186
106
|
end
|
187
107
|
|
@@ -193,64 +113,82 @@ module Reportme
|
|
193
113
|
end
|
194
114
|
end
|
195
115
|
|
196
|
-
def
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
ReportFactory.periods(since).each do |period|
|
201
|
-
periods_queue << period
|
202
|
-
end
|
203
|
-
since += 1.day
|
204
|
-
break if since.future?
|
205
|
-
end
|
116
|
+
def historice(since=Date.today)
|
117
|
+
raise "since cannot be in the future" if since.future?
|
118
|
+
|
119
|
+
__do_and_clean :calendar_week do
|
206
120
|
|
207
|
-
|
121
|
+
loop do
|
122
|
+
|
123
|
+
run_dependency_aware(@@reports) do |report|
|
124
|
+
next if report.temporary?
|
125
|
+
__report_period(report, Period.calc(since, [:calendar_week]).first)
|
126
|
+
end
|
127
|
+
|
128
|
+
since += 1.day
|
129
|
+
break if since.future?
|
130
|
+
end
|
131
|
+
|
132
|
+
self.class.__notify_subscriber
|
133
|
+
end
|
208
134
|
end
|
209
135
|
|
210
136
|
def run(since=Date.today)
|
211
137
|
|
212
138
|
raise "since cannot be in the future" if since.future?
|
213
139
|
|
214
|
-
|
215
|
-
|
140
|
+
__do_and_clean :day, :init => true do
|
141
|
+
|
142
|
+
loop do
|
143
|
+
|
144
|
+
run_dependency_aware(@@reports) do |report|
|
145
|
+
__report_period(report, Period.calc(since, [:day]).first)
|
146
|
+
end
|
147
|
+
|
148
|
+
since += 1.day
|
149
|
+
break if since.future?
|
150
|
+
end
|
151
|
+
|
152
|
+
self.class.__notify_subscriber
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
216
156
|
|
217
|
-
|
157
|
+
def __do_and_clean(period_name, opts={}, &block)
|
218
158
|
|
159
|
+
opts = {
|
160
|
+
:init => false
|
161
|
+
}.merge(opts)
|
162
|
+
|
163
|
+
begin
|
164
|
+
@@report_creations.clear
|
165
|
+
|
166
|
+
ensure_report_informations_table_exist
|
167
|
+
|
219
168
|
validate_dependencies
|
169
|
+
|
170
|
+
@@init.call if @@init && opts[:init]
|
220
171
|
|
221
172
|
run_dependency_aware(@@reports) do |report|
|
222
|
-
ensure_report_tables_exist(report)
|
223
|
-
end
|
224
|
-
|
225
|
-
periods_queue = __fill_periods_queue(since)
|
226
|
-
|
227
|
-
# we will generate all daily reports first.
|
228
|
-
# this will speed up generation of weekly and monthly reports.
|
229
|
-
|
230
|
-
self.class.__sort_periods(periods_queue).each do |period|
|
231
|
-
run_dependency_aware(@@reports) do |report|
|
232
|
-
__report_period(report, period)
|
233
|
-
end
|
173
|
+
ensure_report_tables_exist(report, period_name)
|
234
174
|
end
|
235
|
-
|
236
|
-
|
175
|
+
|
176
|
+
|
177
|
+
block.call
|
237
178
|
ensure
|
238
179
|
@@reports.each do |report|
|
239
180
|
|
240
181
|
if report.temporary?
|
241
182
|
[:today, :day, :week, :calendar_week, :month, :calendar_month].each do |period|
|
242
|
-
|
243
183
|
table_name = report.table_name(period)
|
244
184
|
|
245
185
|
exec("delete from #{report_information_table_name} where report = '#{table_name}';")
|
246
186
|
exec("drop table if exists #{table_name};")
|
247
|
-
|
248
187
|
end
|
249
188
|
end
|
250
189
|
|
251
190
|
end
|
252
191
|
end
|
253
|
-
|
254
192
|
end
|
255
193
|
|
256
194
|
def run_dependency_aware(reports, &block)
|
@@ -290,7 +228,7 @@ module Reportme
|
|
290
228
|
|
291
229
|
end
|
292
230
|
|
293
|
-
def self.reset(report_name, periods=[:day])
|
231
|
+
def self.reset(report_name, periods=[:day, :calendar_week, :calendar_month])
|
294
232
|
|
295
233
|
report_name = report_name.to_sym
|
296
234
|
|
@@ -306,21 +244,6 @@ module Reportme
|
|
306
244
|
|
307
245
|
end
|
308
246
|
|
309
|
-
def self.__sort_periods(periods)
|
310
|
-
|
311
|
-
sorting = {
|
312
|
-
:today => 99,
|
313
|
-
:day => 1,
|
314
|
-
:week => 2,
|
315
|
-
:calendar_week => 3,
|
316
|
-
:month => 4,
|
317
|
-
:calendar_month => 5
|
318
|
-
}
|
319
|
-
|
320
|
-
periods.sort{|a, b| sorting[a[:name]] <=> sorting[b[:name]]}
|
321
|
-
|
322
|
-
end
|
323
|
-
|
324
247
|
def __dependency_hash
|
325
248
|
dependencies = {}
|
326
249
|
@@reports.each do |r|
|
@@ -337,118 +260,49 @@ module Reportme
|
|
337
260
|
|
338
261
|
def __report_period(r, period)
|
339
262
|
|
340
|
-
period_name
|
341
|
-
|
342
|
-
|
263
|
+
period_name = period[:name]
|
264
|
+
_von = period[:von]
|
265
|
+
_bis = period[:bis]
|
343
266
|
|
344
|
-
|
345
|
-
|
267
|
+
von = _von.strftime("%Y-%m-%d 00:00:00")
|
268
|
+
bis = _bis.strftime("%Y-%m-%d 23:59:59")
|
346
269
|
|
347
|
-
|
348
|
-
bis = _bis.strftime("%Y-%m-%d 23:59:59")
|
270
|
+
table_name = r.table_name(period_name)
|
349
271
|
|
350
|
-
|
272
|
+
table_exist = table_exist?(period_name)
|
273
|
+
sql = r.sql(von, bis, period_name)
|
351
274
|
|
352
|
-
|
353
|
-
sql = r.sql(von, bis, period_name)
|
354
|
-
|
355
|
-
|
356
|
-
report_exists = report_exists?(table_name, von, bis)
|
275
|
+
report_exists = report_exists?(table_name, von, bis)
|
357
276
|
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
try_report_by_daily_reports(r, :week, _von, 6, 7) if period_name == :week && !report_exists
|
363
|
-
try_report_by_daily_reports(r, :calendar_week, _von, 6, 7) if period_name == :calendar_week && !report_exists
|
364
|
-
|
365
|
-
# TODO: implement monat by daily reports
|
366
|
-
# try_report_by_daily_reports(r, :month, _von, 29 + (_von.end_of_month.day == 31 ? 1 : 0), 30) if period_name == :month && !report_exists
|
367
|
-
|
368
|
-
try_report_by_daily_reports(r, :calendar_month, _von, _bis.day - _von.day, _bis.day) if period_name == :calendar_month && !report_exists
|
369
|
-
|
370
|
-
report_exists = report_exists?(table_name, von, bis)
|
371
|
-
|
372
|
-
if !report_exists || period_name == :today
|
373
|
-
ActiveRecord::Base.transaction do
|
374
|
-
exec("insert into #{report_information_table_name} values ('#{table_name}', '#{von}', '#{bis}', now());") unless report_exists
|
375
|
-
|
376
|
-
exec("truncate #{table_name};") if period_name == :today
|
277
|
+
unless report_exists
|
278
|
+
ActiveRecord::Base.transaction do
|
279
|
+
exec("insert into #{report_information_table_name} values ('#{table_name}', '#{von}', '#{bis}', now());") unless report_exists
|
377
280
|
|
378
|
-
|
281
|
+
if period_name != :day
|
282
|
+
|
283
|
+
table_name_day = r.table_name(:day)
|
284
|
+
column_names = columns(table_name_day) - ["von"]
|
285
|
+
|
286
|
+
sql = <<-SQL
|
287
|
+
select
|
288
|
+
'#{von}' as von,
|
289
|
+
#{(column_names + ['date(von) as day']).join("\n,")}
|
290
|
+
from
|
291
|
+
#{table_name_day}
|
292
|
+
where
|
293
|
+
von between '#{von}' and '#{bis}'
|
294
|
+
group by
|
295
|
+
#{(column_names + ['date(von)']).join("\n,")}
|
296
|
+
SQL
|
379
297
|
|
380
|
-
remember_report_creation(r, period_name, _von)
|
381
298
|
end
|
382
|
-
end
|
383
299
|
|
300
|
+
exec("insert into #{table_name} #{sql};")
|
301
|
+
|
302
|
+
|
303
|
+
remember_report_creation(r, period_name, _von)
|
304
|
+
end
|
384
305
|
end
|
385
|
-
|
386
|
-
end
|
387
|
-
|
388
|
-
def exec(sql)
|
389
|
-
self.class.exec(sql)
|
390
|
-
end
|
391
|
-
|
392
|
-
def self.exec(sql)
|
393
|
-
puts "// ------------------------"
|
394
|
-
puts "exec: #{sql}"
|
395
|
-
puts "------------------------ //"
|
396
|
-
ActiveRecord::Base.connection.execute(sql)
|
397
|
-
end
|
398
|
-
|
399
|
-
def select_value(sql)
|
400
|
-
self.class.select_value(sql)
|
401
|
-
end
|
402
|
-
|
403
|
-
def self.select_value(sql)
|
404
|
-
puts "// ------------------------"
|
405
|
-
puts "select_value: #{sql}"
|
406
|
-
puts "------------------------ //"
|
407
|
-
ActiveRecord::Base.connection.select_value(sql)
|
408
|
-
end
|
409
|
-
|
410
|
-
def select_one(sql)
|
411
|
-
self.class.select_one(sql)
|
412
|
-
end
|
413
|
-
|
414
|
-
def self.select_one(sql)
|
415
|
-
puts "// ------------------------"
|
416
|
-
puts "select_one: #{sql}"
|
417
|
-
puts "------------------------ //"
|
418
|
-
ActiveRecord::Base.connection.select_one(sql)
|
419
|
-
end
|
420
|
-
|
421
|
-
def select_all(sql)
|
422
|
-
self.class.select_all(sql)
|
423
|
-
end
|
424
|
-
|
425
|
-
def self.select_all(sql)
|
426
|
-
puts "// ------------------------"
|
427
|
-
puts "select_all: #{sql}"
|
428
|
-
puts "------------------------ //"
|
429
|
-
ActiveRecord::Base.connection.select_all(sql)
|
430
|
-
end
|
431
|
-
|
432
|
-
def select_rows(sql)
|
433
|
-
self.class.select_rows(sql)
|
434
|
-
end
|
435
|
-
|
436
|
-
def self.select_rows(sql)
|
437
|
-
puts "// ------------------------"
|
438
|
-
puts "select_rows: #{sql}"
|
439
|
-
puts "------------------------ //"
|
440
|
-
ActiveRecord::Base.connection.select_rows(sql)
|
441
|
-
end
|
442
|
-
|
443
|
-
def select_values(sql)
|
444
|
-
self.class.select_values(sql)
|
445
|
-
end
|
446
|
-
|
447
|
-
def self.select_values(sql)
|
448
|
-
puts "// ------------------------"
|
449
|
-
puts "select_values: #{sql}"
|
450
|
-
puts "------------------------ //"
|
451
|
-
ActiveRecord::Base.connection.select_values(sql)
|
452
306
|
end
|
453
307
|
|
454
308
|
def self.has_subscribtion?(report_name)
|
@@ -473,8 +327,6 @@ module Reportme
|
|
473
327
|
end
|
474
328
|
|
475
329
|
def self.__notify_subscriber
|
476
|
-
|
477
|
-
|
478
330
|
@@report_creations.each do |creation|
|
479
331
|
|
480
332
|
report_name = creation[:report].name
|
data/lib/reportme/sql.rb
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
module Reportme
|
2
|
+
module Sql
|
3
|
+
|
4
|
+
def self.included(klass)
|
5
|
+
klass.extend ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
|
10
|
+
def table_exist?(table_name)
|
11
|
+
ActiveRecord::Base.connection.select_value("show tables like '#{table_name}'") != nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def columns(table_name)
|
15
|
+
sql = <<-SQL
|
16
|
+
select
|
17
|
+
column_name
|
18
|
+
from
|
19
|
+
information_schema.columns
|
20
|
+
where
|
21
|
+
table_schema = '#{schema_name}'
|
22
|
+
and table_name = '#{table_name}'
|
23
|
+
;
|
24
|
+
SQL
|
25
|
+
select_values(sql)
|
26
|
+
end
|
27
|
+
|
28
|
+
def select_values(sql)
|
29
|
+
puts "// ------------------------"
|
30
|
+
puts "select_values: #{sql}"
|
31
|
+
puts "------------------------ //"
|
32
|
+
ActiveRecord::Base.connection.select_values(sql)
|
33
|
+
end
|
34
|
+
|
35
|
+
def select_rows(sql)
|
36
|
+
puts "// ------------------------"
|
37
|
+
puts "select_rows: #{sql}"
|
38
|
+
puts "------------------------ //"
|
39
|
+
ActiveRecord::Base.connection.select_rows(sql)
|
40
|
+
end
|
41
|
+
|
42
|
+
def select_all(sql)
|
43
|
+
puts "// ------------------------"
|
44
|
+
puts "select_all: #{sql}"
|
45
|
+
puts "------------------------ //"
|
46
|
+
ActiveRecord::Base.connection.select_all(sql)
|
47
|
+
end
|
48
|
+
|
49
|
+
def select_one(sql)
|
50
|
+
puts "// ------------------------"
|
51
|
+
puts "select_one: #{sql}"
|
52
|
+
puts "------------------------ //"
|
53
|
+
ActiveRecord::Base.connection.select_one(sql)
|
54
|
+
end
|
55
|
+
|
56
|
+
def exec(sql)
|
57
|
+
puts "// ------------------------"
|
58
|
+
puts "exec: #{sql}"
|
59
|
+
puts "------------------------ //"
|
60
|
+
ActiveRecord::Base.connection.execute(sql)
|
61
|
+
end
|
62
|
+
|
63
|
+
def select_value(sql)
|
64
|
+
puts "// ------------------------"
|
65
|
+
puts "select_value: #{sql}"
|
66
|
+
puts "------------------------ //"
|
67
|
+
ActiveRecord::Base.connection.select_value(sql)
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
def exec(sql)
|
73
|
+
self.class.exec(sql)
|
74
|
+
end
|
75
|
+
|
76
|
+
def select_value(sql)
|
77
|
+
self.class.select_value(sql)
|
78
|
+
end
|
79
|
+
|
80
|
+
def select_one(sql)
|
81
|
+
self.class.select_one(sql)
|
82
|
+
end
|
83
|
+
|
84
|
+
def select_all(sql)
|
85
|
+
self.class.select_all(sql)
|
86
|
+
end
|
87
|
+
|
88
|
+
def select_rows(sql)
|
89
|
+
self.class.select_rows(sql)
|
90
|
+
end
|
91
|
+
|
92
|
+
def select_values(sql)
|
93
|
+
self.class.select_values(sql)
|
94
|
+
end
|
95
|
+
|
96
|
+
def columns(table_name)
|
97
|
+
self.class.columns(table_name)
|
98
|
+
end
|
99
|
+
|
100
|
+
def table_exist?(table_name)
|
101
|
+
self.class.table_exist?(table_name)
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
data/test/reportme_test.rb
CHANGED
@@ -34,11 +34,13 @@ class ReportmeTest < Test::Unit::TestCase
|
|
34
34
|
opts[:init].call
|
35
35
|
end
|
36
36
|
TestReport.report :visits do
|
37
|
-
|
37
|
+
|
38
|
+
# periods opts[:periods]
|
39
|
+
|
38
40
|
source do |von, bis|
|
39
41
|
<<-SQL
|
40
42
|
select
|
41
|
-
'#{von}' as von,
|
43
|
+
-- '#{von}' as von,
|
42
44
|
date(created_at) as datum,
|
43
45
|
channel,
|
44
46
|
count(1) as cnt
|
@@ -87,30 +89,30 @@ class ReportmeTest < Test::Unit::TestCase
|
|
87
89
|
end
|
88
90
|
end
|
89
91
|
|
90
|
-
should "create one visitor in the today report for channel sem" do
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
end
|
95
|
-
|
96
|
-
should "create two visitors in the today report for channel sem" do
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
end
|
102
|
-
|
103
|
-
|
104
|
-
should "create visitors in the today report for channel sem and seo" do
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
end
|
92
|
+
# should "create one visitor in the today report for channel sem" do
|
93
|
+
# exec("insert into visits values (null, 'sem', now())");
|
94
|
+
# create_visit_report_factory.run
|
95
|
+
# assert_equal 1, one("select count(1) as cnt from visits_today where channel = 'sem' and datum = curdate()")["cnt"].to_i
|
96
|
+
# end
|
97
|
+
|
98
|
+
# should "create two visitors in the today report for channel sem" do
|
99
|
+
# exec("insert into visits values (null, 'sem', now())");
|
100
|
+
# exec("insert into visits values (null, 'sem', now())");
|
101
|
+
# create_visit_report_factory.run
|
102
|
+
# assert_equal 2, one("select cnt from visits_today where channel = 'sem' and datum = curdate()")["cnt"].to_i
|
103
|
+
# end
|
104
|
+
|
105
|
+
|
106
|
+
# should "create visitors in the today report for channel sem and seo" do
|
107
|
+
# exec("insert into visits values (null, 'sem', now())");
|
108
|
+
# exec("insert into visits values (null, 'sem', now())");
|
109
|
+
# exec("insert into visits values (null, 'seo', now())");
|
110
|
+
# exec("insert into visits values (null, 'sem', now())");
|
111
|
+
# exec("insert into visits values (null, 'seo', now())");
|
112
|
+
# create_visit_report_factory.run
|
113
|
+
# assert_equal 2, one("select cnt from visits_today where channel = 'seo' and datum = curdate()")["cnt"].to_i
|
114
|
+
# assert_equal 3, one("select cnt from visits_today where channel = 'sem' and datum = curdate()")["cnt"].to_i
|
115
|
+
# end
|
114
116
|
|
115
117
|
should "create visitors in the day report for channel sem and seo" do
|
116
118
|
exec("insert into visits values (null, 'sem', date_sub(curdate(), interval 1 day));");
|
@@ -123,25 +125,25 @@ class ReportmeTest < Test::Unit::TestCase
|
|
123
125
|
assert_equal 3, one("select cnt from visits_day where channel = 'sem' and datum = date_sub(curdate(), interval 1 day)")["cnt"].to_i
|
124
126
|
end
|
125
127
|
|
126
|
-
should "report a week as 7 days since yesterday ignoring days before or after this" do
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
end
|
128
|
+
# should "report a week as 7 days since yesterday ignoring days before or after this" do
|
129
|
+
#
|
130
|
+
# # today should be ignored
|
131
|
+
# exec("insert into visits values (null, 'sem', curdate());");
|
132
|
+
#
|
133
|
+
# exec("insert into visits values (null, 'sem', date_sub(curdate(), interval 1 day));");
|
134
|
+
# exec("insert into visits values (null, 'sem', date_sub(curdate(), interval 2 day));");
|
135
|
+
# exec("insert into visits values (null, 'sem', date_sub(curdate(), interval 3 day));");
|
136
|
+
# exec("insert into visits values (null, 'sem', date_sub(curdate(), interval 4 day));");
|
137
|
+
# exec("insert into visits values (null, 'sem', date_sub(curdate(), interval 5 day));");
|
138
|
+
# exec("insert into visits values (null, 'sem', date_sub(curdate(), interval 6 day));");
|
139
|
+
# exec("insert into visits values (null, 'sem', date_sub(curdate(), interval 7 day));");
|
140
|
+
#
|
141
|
+
# # 8 days ago should be ignored
|
142
|
+
# exec("insert into visits values (null, 'sem', date_sub(curdate(), interval 8 day));");
|
143
|
+
#
|
144
|
+
# create_visit_report_factory(:periods => [:week]).run
|
145
|
+
# assert_equal 7, one("select count(1) as cnt from visits_week where channel = 'sem' and von = date_sub(curdate(), interval 7 day)")["cnt"].to_i
|
146
|
+
# end
|
145
147
|
|
146
148
|
should "create a daily report for the previous 3 days" do
|
147
149
|
|
@@ -161,34 +163,34 @@ class ReportmeTest < Test::Unit::TestCase
|
|
161
163
|
assert_equal 4, one("select count(1) as cnt from visits_day where von between date_sub(curdate(), interval 4 day) and date_sub(curdate(), interval 1 day)")["cnt"].to_i
|
162
164
|
end
|
163
165
|
|
164
|
-
should "create the weekly report by using 7 daily reports" do
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
end
|
166
|
+
# should "create the weekly report by using 7 daily reports" do
|
167
|
+
#
|
168
|
+
# # should be ignored in weekly
|
169
|
+
# exec("insert into visits values (null, 'sem', curdate());");
|
170
|
+
#
|
171
|
+
# exec("insert into visits values (null, 'sem', date_sub(curdate(), interval 1 day));");
|
172
|
+
# exec("insert into visits values (null, 'sem', date_sub(curdate(), interval 2 day));");
|
173
|
+
# exec("insert into visits values (null, 'sem', date_sub(curdate(), interval 3 day));");
|
174
|
+
# exec("insert into visits values (null, 'sem', date_sub(curdate(), interval 4 day));");
|
175
|
+
# exec("insert into visits values (null, 'sem', date_sub(curdate(), interval 5 day));");
|
176
|
+
# exec("insert into visits values (null, 'sem', date_sub(curdate(), interval 6 day));");
|
177
|
+
# exec("insert into visits values (null, 'sem', date_sub(curdate(), interval 7 day));");
|
178
|
+
#
|
179
|
+
# # should be ignored in weekly
|
180
|
+
# exec("insert into visits values (null, 'sem', date_sub(curdate(), interval 8 day));");
|
181
|
+
# # should be ignored in weekly
|
182
|
+
# exec("insert into visits values (null, 'sem', date_sub(curdate(), interval 9 day));");
|
183
|
+
#
|
184
|
+
# create_visit_report_factory(:periods => [:day]).run(10.days.ago)
|
185
|
+
#
|
186
|
+
# exec("truncate visits;")
|
187
|
+
#
|
188
|
+
# Reportme::ReportFactory.init_reset
|
189
|
+
#
|
190
|
+
# create_visit_report_factory(:periods => [:week]).run
|
191
|
+
#
|
192
|
+
# assert_equal 7, one("select count(1) as cnt from visits_week where date(von) between date_sub(curdate(), interval 7 day) and date_sub(curdate(), interval 1 day)")["cnt"].to_i
|
193
|
+
# end
|
192
194
|
|
193
195
|
should "generate the von/bis range for the periods" do
|
194
196
|
|
@@ -197,7 +199,7 @@ class ReportmeTest < Test::Unit::TestCase
|
|
197
199
|
##
|
198
200
|
|
199
201
|
periods = {}
|
200
|
-
Reportme::
|
202
|
+
Reportme::Period.calc('2009-06-01'.to_date, [:day, :week, :calendar_week, :month, :calendar_month]).each{|p| periods[p[:name]] = p}
|
201
203
|
|
202
204
|
# assert_equal '2009-06-01 00:00:00'.to_datetime, periods[:today][:von]
|
203
205
|
# assert_equal '2009-06-01 23:59:59'.to_datetime, periods[:today][:bis]
|
@@ -223,7 +225,7 @@ class ReportmeTest < Test::Unit::TestCase
|
|
223
225
|
##
|
224
226
|
|
225
227
|
periods.clear
|
226
|
-
Reportme::
|
228
|
+
Reportme::Period.calc('2009-06-24'.to_date, [:day, :week, :calendar_week, :month, :calendar_month]).each{|p| periods[p[:name]] = p}
|
227
229
|
|
228
230
|
# assert_equal '2009-06-24 00:00:00'.to_datetime, periods[:today][:von]
|
229
231
|
# assert_equal '2009-06-24 23:59:59'.to_datetime, periods[:today][:bis]
|
@@ -248,7 +250,7 @@ class ReportmeTest < Test::Unit::TestCase
|
|
248
250
|
##
|
249
251
|
|
250
252
|
periods.clear
|
251
|
-
Reportme::
|
253
|
+
Reportme::Period.calc('2009-06-30'.to_date, [:day, :week, :calendar_week, :month, :calendar_month]).each{|p| periods[p[:name]] = p}
|
252
254
|
|
253
255
|
# assert_equal '2009-06-30 00:00:00'.to_datetime, periods[:today][:von]
|
254
256
|
# assert_equal '2009-06-30 23:59:59'.to_datetime, periods[:today][:bis]
|
@@ -273,7 +275,7 @@ class ReportmeTest < Test::Unit::TestCase
|
|
273
275
|
##
|
274
276
|
|
275
277
|
periods.clear
|
276
|
-
Reportme::
|
278
|
+
Reportme::Period.calc('2009-05-01'.to_date, [:day, :week, :calendar_week, :month, :calendar_month]).each{|p| periods[p[:name]] = p}
|
277
279
|
|
278
280
|
# assert_equal '2009-05-01 00:00:00'.to_datetime, periods[:today][:von]
|
279
281
|
# assert_equal '2009-05-01 23:59:59'.to_datetime, periods[:today][:bis]
|
@@ -298,7 +300,7 @@ class ReportmeTest < Test::Unit::TestCase
|
|
298
300
|
##
|
299
301
|
|
300
302
|
periods.clear
|
301
|
-
Reportme::
|
303
|
+
Reportme::Period.calc('2009-05-15'.to_date, [:day, :week, :calendar_week, :month, :calendar_month]).each{|p| periods[p[:name]] = p}
|
302
304
|
|
303
305
|
# assert_equal '2009-05-15 00:00:00'.to_datetime, periods[:today][:von]
|
304
306
|
# assert_equal '2009-05-15 23:59:59'.to_datetime, periods[:today][:bis]
|
@@ -323,7 +325,7 @@ class ReportmeTest < Test::Unit::TestCase
|
|
323
325
|
##
|
324
326
|
|
325
327
|
periods.clear
|
326
|
-
Reportme::
|
328
|
+
Reportme::Period.calc('2009-05-31'.to_date, [:day, :week, :calendar_week, :month, :calendar_month]).each{|p| periods[p[:name]] = p}
|
327
329
|
|
328
330
|
# assert_equal '2009-05-31 00:00:00'.to_datetime, periods[:today][:von]
|
329
331
|
# assert_equal '2009-05-31 23:59:59'.to_datetime, periods[:today][:bis]
|
@@ -343,72 +345,74 @@ class ReportmeTest < Test::Unit::TestCase
|
|
343
345
|
assert_equal '2009-04-01 00:00:00'.to_datetime, periods[:calendar_month][:von]
|
344
346
|
assert_equal '2009-04-30 23:59:59'.to_datetime, periods[:calendar_month][:bis]
|
345
347
|
|
346
|
-
##
|
347
|
-
# today
|
348
|
-
##
|
349
|
-
|
350
|
-
periods.clear
|
351
|
-
today = Date.today
|
352
|
-
Reportme::
|
353
|
-
|
354
|
-
assert_equal "#{today.strftime('%Y-%m-%d')} 00:00:00".to_datetime, periods[:today][:von]
|
355
|
-
assert_equal "#{today.strftime('%Y-%m-%d')} 23:59:59".to_datetime, periods[:today][:bis]
|
356
|
-
|
348
|
+
# ##
|
349
|
+
# # today
|
350
|
+
# ##
|
351
|
+
#
|
352
|
+
# periods.clear
|
353
|
+
# today = Date.today
|
354
|
+
# Reportme::Period.calc(today).each{|p| periods[p[:name]] = p}
|
355
|
+
#
|
356
|
+
# assert_equal "#{today.strftime('%Y-%m-%d')} 00:00:00".to_datetime, periods[:today][:von]
|
357
|
+
# assert_equal "#{today.strftime('%Y-%m-%d')} 23:59:59".to_datetime, periods[:today][:bis]
|
358
|
+
#
|
357
359
|
end
|
358
360
|
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
#
|
409
|
-
|
410
|
-
|
411
|
-
|
361
|
+
# should "create the calendar_weekly report by using 7 daily reports" do
|
362
|
+
#
|
363
|
+
# # @debug = true
|
364
|
+
# # today = '2009-06-24'
|
365
|
+
# today = (Date.today - 1.day).strftime("%Y-%m-%d")
|
366
|
+
#
|
367
|
+
# # should be ignored in weekly
|
368
|
+
# exec("insert into visits values (null, 'sem', '#{today}');");
|
369
|
+
# # should be ignored in weekly
|
370
|
+
# exec("insert into visits values (null, 'sem', date_sub('#{today}', interval 1 day));");
|
371
|
+
# # should be ignored in weekly
|
372
|
+
# exec("insert into visits values (null, 'sem', date_sub('#{today}', interval 2 day));");
|
373
|
+
# exec("insert into visits values (null, 'sem', date_sub('#{today}', interval 3 day));");
|
374
|
+
# exec("insert into visits values (null, 'sem', date_sub('#{today}', interval 4 day));");
|
375
|
+
# exec("insert into visits values (null, 'sem', date_sub('#{today}', interval 5 day));");
|
376
|
+
# exec("insert into visits values (null, 'sem', date_sub('#{today}', interval 6 day));");
|
377
|
+
# exec("insert into visits values (null, 'sem', date_sub('#{today}', interval 7 day));");
|
378
|
+
# exec("insert into visits values (null, 'sem', date_sub('#{today}', interval 8 day));");
|
379
|
+
# exec("insert into visits values (null, 'sem', date_sub('#{today}', interval 9 day));");
|
380
|
+
# # should be ignored in weekly
|
381
|
+
# exec("insert into visits values (null, 'sem', date_sub('#{today}', interval 10 day));");
|
382
|
+
#
|
383
|
+
# create_visit_report_factory(:periods => [:day]).run(15.days.ago)
|
384
|
+
#
|
385
|
+
# exec("truncate visits;")
|
386
|
+
#
|
387
|
+
# Reportme::ReportFactory.init_reset
|
388
|
+
#
|
389
|
+
# d1 = Date.today
|
390
|
+
# d2 = today.to_date
|
391
|
+
#
|
392
|
+
# num_days = 0
|
393
|
+
#
|
394
|
+
# while d2.past?
|
395
|
+
# d2 += 1.day
|
396
|
+
# num_days += 1
|
397
|
+
# end
|
398
|
+
#
|
399
|
+
# create_visit_report_factory(:periods => [:calendar_week]).run(num_days.days.ago)
|
400
|
+
#
|
401
|
+
# day_lastweek = today.to_date - 7.days
|
402
|
+
#
|
403
|
+
# monday = day_lastweek - (day_lastweek.cwday - 1).days
|
404
|
+
#
|
405
|
+
# von, bis = [monday, monday + 6.days]
|
406
|
+
#
|
407
|
+
# von = von.to_datetime
|
408
|
+
# bis = bis.to_datetime + 23.hours + 59.minutes + 59.seconds
|
409
|
+
#
|
410
|
+
# sql = "select count(1) as cnt from visits_calendar_week where von between '#{von.strftime('%Y-%m-%d 00:00:00')}' and '#{bis.strftime('%Y-%m-%d 23:59:59')}'"
|
411
|
+
#
|
412
|
+
# # assert_equal 7, one("select count(1) as cnt from visits_calendar_week where von between '2009-06-15 00:00:00' and '2009-06-21 00:00:00'")["cnt"].to_i
|
413
|
+
# assert_equal 7, one(sql)["cnt"].to_i
|
414
|
+
#
|
415
|
+
# end
|
412
416
|
|
413
417
|
should "probe existing reports" do
|
414
418
|
rme = create_visit_report_factory
|
@@ -533,14 +537,14 @@ class ReportmeTest < Test::Unit::TestCase
|
|
533
537
|
assert [], hash[:report3]
|
534
538
|
end
|
535
539
|
|
536
|
-
should "sort some periods" do
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
end
|
540
|
+
# should "sort some periods" do
|
541
|
+
# assert [:day, :today], Reportme::ReportFactory.__sort_periods([{:name => :today}, {:name => :day}])
|
542
|
+
# assert [:day, :week, :today], Reportme::ReportFactory.__sort_periods([{:name => :today}, {:name => :day}, {:name => :week}])
|
543
|
+
# assert [:day, :week], Reportme::ReportFactory.__sort_periods([{:name => :week}, {:name => :day}])
|
544
|
+
# assert [:day, :week, :month, :calendar_month, :today], Reportme::ReportFactory.__sort_periods([{:name => :week}, {:name => :day}, {:name => :today}, {:name => :calendar_month}, {:name => :month}])
|
545
|
+
#
|
546
|
+
# assert [:day, :week, :week, :today, :today], Reportme::ReportFactory.__sort_periods([{:name => :week}, {:name => :today}, {:name => :today}, {:name => :week}, {:name => :day}])
|
547
|
+
# end
|
544
548
|
|
545
549
|
should "run reports in a dependency aware manner" do
|
546
550
|
class ReportDependencyAwareTestReport < Reportme::ReportFactory
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jzimmek-reportme
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jan Zimmek
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-07-
|
12
|
+
date: 2009-07-03 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -29,8 +29,10 @@ files:
|
|
29
29
|
- VERSION
|
30
30
|
- lib/reportme.rb
|
31
31
|
- lib/reportme/mailer.rb
|
32
|
+
- lib/reportme/period.rb
|
32
33
|
- lib/reportme/report.rb
|
33
34
|
- lib/reportme/report_factory.rb
|
35
|
+
- lib/reportme/sql.rb
|
34
36
|
- test/reportme_test.rb
|
35
37
|
- test/test_helper.rb
|
36
38
|
has_rdoc: false
|