qreport 0.0.3 → 0.0.6
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/ChangeLog +8 -0
- data/Guardfile +8 -0
- data/README.md +37 -0
- data/lib/qreport.rb +1 -1
- data/lib/qreport/connection.rb +26 -4
- data/lib/qreport/initialization.rb +10 -3
- data/lib/qreport/report_run.rb +40 -3
- data/lib/qreport/report_runner.rb +44 -29
- data/lib/qreport/version.rb +1 -1
- data/qreport.gemspec +4 -1
- data/spec/{connection_spec.rb → lib/qreport/connection_spec.rb} +1 -0
- data/spec/{report_runner_spec.rb → lib/qreport/report_runner_spec.rb} +55 -3
- metadata +57 -14
data/ChangeLog
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
2013-07-08 Kurt A. Stephens <ks.github@kurtstephens.com>
|
2
|
+
|
3
|
+
* v0.0.6: New Version: New Functionality.
|
4
|
+
* ReportRun#variant additional key.
|
5
|
+
* ReportRun#data returns all rows of from its report table.
|
6
|
+
* ReportRun.find(id) returns a ReportRun object.
|
7
|
+
* ReportRun#reload! reloads a ReportRun object.
|
8
|
+
|
1
9
|
2013-06-26 Kurt A. Stephens <ks.github@kurtstephens.com>
|
2
10
|
|
3
11
|
* v0.0.3: New Version: New Functionality.
|
data/Guardfile
ADDED
data/README.md
CHANGED
@@ -86,8 +86,45 @@ Subsequent queries with the same column signature will use "INSERT INTO users_wi
|
|
86
86
|
|
87
87
|
## Parameterizing Reports
|
88
88
|
|
89
|
+
Report queries can be parameterized using embedded ":word" tags.
|
90
|
+
Parameter arguments are saved in the report run table.
|
91
|
+
|
92
|
+
report_run.arguments = {
|
93
|
+
:interval => '30 days',
|
94
|
+
}
|
95
|
+
report_run.run! <<"END"
|
96
|
+
SELECT u.id AS "user_id"
|
97
|
+
FROM users u
|
98
|
+
WHERE
|
99
|
+
EXISTS(SELECT * FROM articles a
|
100
|
+
WHERE a.user_id = u.id AND a.created_on >= NOW() - INTERVAL :interval)
|
101
|
+
END
|
102
|
+
|
103
|
+
Arguments can also represent "matching" patterns using a ":~" tag.
|
104
|
+
Example: a Range of Time values matching a.created_on:
|
105
|
+
|
106
|
+
t = Time.now
|
107
|
+
report_run.arguments = {
|
108
|
+
:interval => (t - 86400) ... t,
|
109
|
+
}
|
110
|
+
report_run.run! <<"END"
|
111
|
+
SELECT * FROM articles a WHERe :~ {{:interval}} {{a.created_on}}
|
112
|
+
END
|
113
|
+
|
89
114
|
## Batch Processing
|
90
115
|
|
116
|
+
## Running Tests
|
117
|
+
|
118
|
+
Example setup:
|
119
|
+
|
120
|
+
$ sudo -u postgresql psql
|
121
|
+
postgres=# create role test login password 'test';
|
122
|
+
CREATE ROLE
|
123
|
+
postgres=# create database test owner test;
|
124
|
+
CREATE DATABASE
|
125
|
+
postgres=# \q
|
126
|
+
$ PGHOST=localhost PGUSER=test PGDATABSE=test PGPASSWORD=... rake
|
127
|
+
|
91
128
|
## Contributing
|
92
129
|
|
93
130
|
1. Fork it
|
data/lib/qreport.rb
CHANGED
data/lib/qreport/connection.rb
CHANGED
@@ -89,7 +89,7 @@ module Qreport
|
|
89
89
|
begin
|
90
90
|
transaction_begin
|
91
91
|
yield
|
92
|
-
rescue ::
|
92
|
+
rescue ::StandardError => exc
|
93
93
|
abort = @abort_transaction = exc
|
94
94
|
raise exc
|
95
95
|
ensure
|
@@ -135,10 +135,13 @@ module Qreport
|
|
135
135
|
end
|
136
136
|
|
137
137
|
def table_exists? name, schemaname = nil
|
138
|
-
|
138
|
+
schema_name = name.split('.', 2)
|
139
|
+
schema = schema_name.shift if schema_name.size > 1
|
140
|
+
name = schema_name.first
|
141
|
+
schema ||= schemaname || self.schemaname || 'public'
|
139
142
|
result =
|
140
143
|
run "SELECT EXISTS(SELECT * FROM pg_catalog.pg_tables WHERE tablename = :tablename AND schemaname = :schemaname) as \"exists\"",
|
141
|
-
:arguments => { :tablename => name, :schemaname =>
|
144
|
+
:arguments => { :tablename => name, :schemaname => schema }
|
142
145
|
# result.rows; pp result
|
143
146
|
result.rows[0]["exists"]
|
144
147
|
end
|
@@ -190,6 +193,8 @@ module Qreport
|
|
190
193
|
"'" << conn.escape_string(val.to_s) << QUOTE
|
191
194
|
when Time
|
192
195
|
escape_value(val.iso8601(6)) << "::timestamp"
|
196
|
+
when Range
|
197
|
+
"BETWEEN #{escape_value(val.first)} AND #{escape_value(val.last)}"
|
193
198
|
when Hash, Array
|
194
199
|
escape_value(val.to_json)
|
195
200
|
else
|
@@ -258,7 +263,7 @@ module Qreport
|
|
258
263
|
# $stderr.puts " ERROR: #{exc.inspect}\n #{exc.backtrace * "\n "}"
|
259
264
|
query.error = exc.inspect
|
260
265
|
raise exc unless options[:capture_error]
|
261
|
-
rescue ::
|
266
|
+
rescue ::StandardError => exc
|
262
267
|
@invalid = true
|
263
268
|
query.error = exc.inspect
|
264
269
|
raise exc unless options[:capture_error]
|
@@ -268,6 +273,7 @@ module Qreport
|
|
268
273
|
|
269
274
|
class Query
|
270
275
|
attr_accessor :conn, :sql, :options
|
276
|
+
attr_accessor :sql_prepared
|
271
277
|
attr_accessor :error, :cmd_status_raw, :cmd_status, :cmd_tuples
|
272
278
|
attr_accessor :nfields, :fields, :ftypes, :fmods
|
273
279
|
attr_accessor :type_names
|
@@ -324,6 +330,22 @@ module Qreport
|
|
324
330
|
$1
|
325
331
|
end
|
326
332
|
end
|
333
|
+
sql = sql_replace_match sql
|
334
|
+
end
|
335
|
+
|
336
|
+
def sql_replace_match sql
|
337
|
+
sql = sql.gsub(/:~\s*\{\{([^\}]+?)\}\}\s*\{\{([^\}]+?)\}\}/) do | m |
|
338
|
+
expr = $1
|
339
|
+
val = $2
|
340
|
+
case expr
|
341
|
+
when /\A\s*BETWEEN\b/
|
342
|
+
"(#{val} #{expr})"
|
343
|
+
when "NULL"
|
344
|
+
"(#{val} IS NULL)"
|
345
|
+
else
|
346
|
+
"(#{val} = #{expr})"
|
347
|
+
end
|
348
|
+
end
|
327
349
|
sql
|
328
350
|
end
|
329
351
|
|
@@ -5,10 +5,17 @@ module Qreport
|
|
5
5
|
def initialize opts = nil
|
6
6
|
opts ||= EMPTY_Hash
|
7
7
|
initialize_before_opts if respond_to? :initialize_before_opts
|
8
|
-
opts
|
9
|
-
send(:"#{k}=", v)
|
10
|
-
end
|
8
|
+
initialize_from_hash! opts
|
11
9
|
initialize_after_opts if respond_to? :initialize_after_opts
|
12
10
|
end
|
11
|
+
|
12
|
+
def initialize_from_hash! opts
|
13
|
+
if opts
|
14
|
+
opts.each do | k, v |
|
15
|
+
send(:"#{k}=", v)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
self
|
19
|
+
end
|
13
20
|
end
|
14
21
|
end
|
data/lib/qreport/report_run.rb
CHANGED
@@ -7,15 +7,16 @@ module Qreport
|
|
7
7
|
include Model, Initialization
|
8
8
|
|
9
9
|
attr_accessor :id
|
10
|
-
attr_accessor :name, :sql, :additional_columns
|
10
|
+
attr_accessor :name, :variant, :sql, :additional_columns
|
11
11
|
attr_accessor :description
|
12
12
|
attr_accessor :arguments
|
13
13
|
attr_accessor :report_id
|
14
|
-
attr_accessor :report_sql
|
14
|
+
attr_accessor :report_sql, :raw_sql
|
15
15
|
attr_accessor :columns, :base_columns, :column_signature
|
16
16
|
attr_accessor :report_table
|
17
17
|
attr_accessor :nrows
|
18
18
|
attr_accessor :created_at, :started_at, :finished_at
|
19
|
+
attr_accessor :verbose
|
19
20
|
|
20
21
|
# Construct report_table name from column names and types.
|
21
22
|
def report_table
|
@@ -41,10 +42,18 @@ module Qreport
|
|
41
42
|
def base_columns
|
42
43
|
@base_columns ||= EMPTY_Array
|
43
44
|
end
|
45
|
+
def base_columns= x
|
46
|
+
@base_columns = x
|
47
|
+
@columns = nil
|
48
|
+
end
|
44
49
|
|
45
50
|
def additional_columns
|
46
51
|
@additional_columns ||= EMPTY_Array
|
47
52
|
end
|
53
|
+
def additional_columns= x
|
54
|
+
@additional_columns ||= EMPTY_Array
|
55
|
+
@columns = nil
|
56
|
+
end
|
48
57
|
|
49
58
|
def columns
|
50
59
|
@columns ||=
|
@@ -84,6 +93,7 @@ CREATE TABLE -- IF NOT EXISTS
|
|
84
93
|
qr_report_runs (
|
85
94
|
id INTEGER PRIMARY KEY DEFAULT nextval('qr_report_runs_pkey')
|
86
95
|
, name VARCHAR(255) NOT NULL
|
96
|
+
, variant VARCHAR(255)
|
87
97
|
, sql TEXT NOT NULL
|
88
98
|
, description TEXT NOT NULL
|
89
99
|
, arguments TEXT NOT NULL
|
@@ -97,6 +107,7 @@ qr_report_runs (
|
|
97
107
|
, nrows INTEGER
|
98
108
|
);
|
99
109
|
CREATE INDEX qr_report_runs__name ON qr_report_runs (name);
|
110
|
+
CREATE INDEX qr_report_runs__variant ON qr_report_runs (variant);
|
100
111
|
CREATE INDEX qr_report_runs__report_table ON qr_report_runs (report_table);
|
101
112
|
CREATE INDEX qr_report_runs__created_at ON qr_report_runs (created_at);
|
102
113
|
END
|
@@ -105,6 +116,7 @@ END
|
|
105
116
|
def insert!
|
106
117
|
values = {
|
107
118
|
:name => name,
|
119
|
+
:variant => variant,
|
108
120
|
:sql => sql,
|
109
121
|
:description => description,
|
110
122
|
:arguments => (arguments || { }),
|
@@ -150,6 +162,27 @@ WHERE id = :qr_run_id
|
|
150
162
|
END
|
151
163
|
end
|
152
164
|
|
165
|
+
def self.find id
|
166
|
+
obj = new
|
167
|
+
obj.id = id
|
168
|
+
obj.reload!
|
169
|
+
end
|
170
|
+
|
171
|
+
def reload!
|
172
|
+
result = conn.run("SELECT * FROM qr_report_runs WHERE id = :id LIMIT 1", :arguments => { :id => id })
|
173
|
+
result = result.rows.first
|
174
|
+
initialize_from_hash! result
|
175
|
+
@base_columns = JSON.parse(@base_columns)
|
176
|
+
@data = nil
|
177
|
+
self
|
178
|
+
end
|
179
|
+
|
180
|
+
# Return rows from this report run's report table.
|
181
|
+
def data
|
182
|
+
@data ||=
|
183
|
+
_select
|
184
|
+
end
|
185
|
+
|
153
186
|
def select options = nil
|
154
187
|
options = _options options
|
155
188
|
_select({:order_by => 'ORDER BY qr_run_row'}.merge(options))
|
@@ -176,10 +209,14 @@ END
|
|
176
209
|
conn.run "SELECT COUNT(*) AS \"count\" from qr_report_runs WHERE report_table = :report_table",
|
177
210
|
:arguments => { :report_table => report_table }, :capture_error => true # , :verbose => true
|
178
211
|
if result.rows[0]["count"] <= 0
|
179
|
-
|
212
|
+
# drop_table!
|
180
213
|
end
|
181
214
|
end
|
182
215
|
|
216
|
+
def drop_table! options = nil
|
217
|
+
conn.run "DROP TABLE #{report_table}", :capture_error => true # , :verbose => true
|
218
|
+
end
|
219
|
+
|
183
220
|
# Deletes the actual rows for this report run.
|
184
221
|
def truncate! options = nil
|
185
222
|
options = _options options
|
@@ -8,53 +8,53 @@ require 'pp'
|
|
8
8
|
module Qreport
|
9
9
|
class ReportRunner
|
10
10
|
attr_accessor :connection, :verbose
|
11
|
+
attr_accessor :report_run, :sql, :arguments
|
12
|
+
attr_accessor :error, :error_1, :error_2
|
11
13
|
|
12
14
|
def run! report_run
|
15
|
+
@verbose ||= report_run.verbose
|
16
|
+
@report_run = report_run
|
13
17
|
report_run.created_at ||=
|
14
18
|
report_run.started_at = Time.now.utc
|
15
19
|
name = report_run.name
|
16
|
-
sql
|
20
|
+
@sql = report_run.sql.strip
|
17
21
|
|
18
|
-
arguments = report_run.arguments || { }
|
19
|
-
error = error_1 = error_2 = nrows = nil
|
22
|
+
@arguments = report_run.arguments || { }
|
23
|
+
@error = @error_1 = @error_2 = nrows = nil
|
20
24
|
|
21
25
|
Connection.current = connection
|
22
26
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
run "CREATE TEMPORARY SEQUENCE qr_row_seq"
|
27
|
+
conn.transaction do
|
28
|
+
# Create a report row sequence:
|
29
|
+
run "CREATE TEMPORARY SEQUENCE qr_row_seq"
|
30
|
+
end
|
28
31
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
+
# Rewrite query to create result table rows:
|
33
|
+
self.arguments = arguments.merge(:qr_run_id => conn.safe_sql("nextval('qr_row_seq')"))
|
34
|
+
report_run.report_sql = report_sql(sql)
|
32
35
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
result = nil
|
37
|
-
end # transaction
|
38
|
-
rescue ::Exception => exc
|
39
|
-
error = error_1 = exc
|
36
|
+
# Infer base columns, if not specified.
|
37
|
+
if report_run.base_columns.empty?
|
38
|
+
infer_base_columns!
|
40
39
|
end
|
41
40
|
|
42
41
|
# Construct report_table name from column names and types:
|
43
42
|
report_table = report_run.report_table
|
44
43
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
44
|
+
unless report_run.id
|
45
|
+
conn.transaction do
|
46
|
+
# Create new ReportRun row:
|
47
|
+
report_run.insert!
|
48
|
+
end # transaction
|
49
|
+
end
|
50
|
+
arguments[:qr_run_id] = report_run.id
|
52
51
|
|
53
52
|
unless error
|
54
53
|
# Run query into report table:
|
55
54
|
begin
|
56
55
|
conn.transaction do
|
57
56
|
unless conn.table_exists? report_table
|
57
|
+
result =
|
58
58
|
run "CREATE TABLE #{report_table} AS #{report_run.report_sql}", :arguments => arguments, :verbose => @verbose
|
59
59
|
run "CREATE INDEX #{report_table}_i1 ON #{report_table} (qr_run_id)"
|
60
60
|
run "CREATE INDEX #{report_table}_i2 ON #{report_table} (qr_run_row)"
|
@@ -65,12 +65,13 @@ module Qreport
|
|
65
65
|
else
|
66
66
|
result =
|
67
67
|
run "INSERT INTO #{report_table} #{report_run.report_sql}", :arguments => arguments, :verbose => @verbose
|
68
|
-
|
69
68
|
# Get the number of report run rows from cmd_status:
|
70
69
|
unless cs = result.cmd_status and cs[0] == 'INSERT' and cs[1] == 0 and nrows = cs[2]
|
71
70
|
raise Error, "cannot determine nrows"
|
72
71
|
end
|
73
72
|
end
|
73
|
+
report_run.raw_sql = result.sql_prepared
|
74
|
+
# $stderr.puts ">>>>>>>>>>>>>>>>>>> #{result.sql_prepared}"
|
74
75
|
# Get the number of report run rows:
|
75
76
|
unless nrows || error
|
76
77
|
result = report_run._select :COLUMNS => 'COUNT(*) AS "nrows"' #, :verbose => true
|
@@ -79,8 +80,8 @@ module Qreport
|
|
79
80
|
# pp result
|
80
81
|
result = nil
|
81
82
|
end # transaction
|
82
|
-
rescue ::
|
83
|
-
error = error_2 = exc
|
83
|
+
rescue ::StandardError => exc
|
84
|
+
@error = @error_2 = exc
|
84
85
|
end # transaction
|
85
86
|
end
|
86
87
|
|
@@ -97,8 +98,22 @@ module Qreport
|
|
97
98
|
report_run
|
98
99
|
end
|
99
100
|
|
101
|
+
def infer_base_columns!
|
102
|
+
base_columns = nil
|
103
|
+
begin
|
104
|
+
conn.transaction do
|
105
|
+
# Proof query to infer base columns:
|
106
|
+
result = run report_run.report_sql, :limit => 0, :arguments => arguments, :verbose => @verbose
|
107
|
+
base_columns = report_run.base_columns = result.columns
|
108
|
+
end # transaction
|
109
|
+
rescue ::StandardError => exc
|
110
|
+
@error = @error_1 = exc
|
111
|
+
end
|
112
|
+
base_columns
|
113
|
+
end
|
114
|
+
|
100
115
|
def report_sql sql
|
101
|
-
sql = sql.sub(/\
|
116
|
+
sql = sql.sub(/\A\s*SELECT\s+/im, <<"END"
|
102
117
|
SELECT
|
103
118
|
:qr_run_id
|
104
119
|
AS "qr_run_id"
|
data/lib/qreport/version.rb
CHANGED
data/qreport.gemspec
CHANGED
@@ -18,8 +18,11 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.require_paths = ["lib"]
|
19
19
|
|
20
20
|
gem.add_development_dependency 'rake', '>= 0.9.0'
|
21
|
-
gem.add_development_dependency 'rspec', '~> 2.12
|
21
|
+
gem.add_development_dependency 'rspec', '~> 2.12'
|
22
22
|
gem.add_development_dependency 'simplecov', '~> 0.7.1'
|
23
|
+
gem.add_development_dependency "guard", "~> 1.8.0"
|
24
|
+
gem.add_development_dependency "guard-rspec", "~> 3.0.2"
|
25
|
+
gem.add_development_dependency "cassava", "~> 0.0.1"
|
23
26
|
|
24
27
|
gem.add_dependency 'pg', '~> 0.14'
|
25
28
|
end
|
@@ -97,6 +97,7 @@ describe Qreport::Connection do
|
|
97
97
|
[ "string with \", \\, and \'", "'string with \", \\, and '''" ],
|
98
98
|
[ :a_symbol!, "'a_symbol!'", :a_symbol!.to_s ],
|
99
99
|
[ Time.parse('2011-04-27T13:23:00.000000Z'), "'2011-04-27T13:23:00.000000Z'::timestamp", Time.parse('2011-04-27T13:23:00.000000') ],
|
100
|
+
[ Time.parse('2011-04-27 13:23:00 -0500'), "'2011-04-27T13:23:00.000000-05:00'::timestamp", Time.parse('2011-04-27 13:23:00 -0500') ],
|
100
101
|
].each do | value, sql, return_value |
|
101
102
|
it "can handle encoding #{value.class.name} value #{value.inspect} as #{sql.inspect}." do
|
102
103
|
conn.escape_value(value).should == sql
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Qreport::ReportRunner do
|
4
4
|
attr :reports, :now
|
5
5
|
|
6
|
-
it "should generate
|
6
|
+
it "should generate reports" do
|
7
7
|
# conn.verbose = conn.verbose_result = true
|
8
8
|
run_reports!
|
9
9
|
reports.size.should == 4
|
@@ -28,6 +28,32 @@ describe Qreport::ReportRunner do
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
+
it "should store relevant data in qr_report_runs table" do
|
32
|
+
run_reports!
|
33
|
+
reports.values.each do | r |
|
34
|
+
r2 = r.class.find(r.id)
|
35
|
+
r2.name.should == r.name.to_s
|
36
|
+
r2.description.should == r.description
|
37
|
+
r2.variant.should == r.variant
|
38
|
+
r2.sql.should == r.sql
|
39
|
+
r2.report_table.should == r.report_table
|
40
|
+
r2.base_columns.should == r.base_columns
|
41
|
+
r2.additional_columns.should == r.additional_columns
|
42
|
+
r2.columns.should == r.columns
|
43
|
+
r2.column_signature == r.column_signature
|
44
|
+
r2.error.should == r.error
|
45
|
+
#pending "Time/timestamp timezones" do
|
46
|
+
#r2.created_at.should == r.created_at
|
47
|
+
#r2.started_at.should == r.started_at
|
48
|
+
#r2.finished_at.should == r.finished_at
|
49
|
+
#end
|
50
|
+
r2.nrows.should == r.nrows
|
51
|
+
r2.data.columns.should == r.data.columns
|
52
|
+
r2.data.rows.should == r.data.rows
|
53
|
+
r2.data.rows.size.should == r.nrows
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
31
57
|
it "should DROP TABLE after all report runs are deleted." do
|
32
58
|
run_reports!
|
33
59
|
reports.values.each do | r |
|
@@ -38,7 +64,7 @@ describe Qreport::ReportRunner do
|
|
38
64
|
|
39
65
|
it "should capture errors into ReportRun#error." do
|
40
66
|
# conn.verbose = true
|
41
|
-
report_run = Qreport::ReportRun.new(:name => :users_with_articles, :description => '10 days')
|
67
|
+
report_run = Qreport::ReportRun.new(:name => :users_with_articles, :variant => '10 days', :description => '10 days')
|
42
68
|
report_run.arguments = {
|
43
69
|
:now => conn.safe_sql("unknown_column"),
|
44
70
|
:interval => '10 days',
|
@@ -57,6 +83,24 @@ END
|
|
57
83
|
report_run.delete!
|
58
84
|
end
|
59
85
|
|
86
|
+
it "should support :~ {{PATTERN}} {{EXPR}}." do
|
87
|
+
report_run = Qreport::ReportRun.new(:name => :users_with_articles, :description => 'last 24 hours')
|
88
|
+
now = Time.now
|
89
|
+
report_run.arguments = {
|
90
|
+
:interval => (now - 86400 ... now),
|
91
|
+
}
|
92
|
+
report_run.sql = <<"END"
|
93
|
+
SELECT u.id AS "user_id"
|
94
|
+
FROM users u
|
95
|
+
WHERE
|
96
|
+
EXISTS(SELECT * FROM articles a WHERE a.user_id = u.id AND :~ {{:interval}} {{a.created_on}});
|
97
|
+
END
|
98
|
+
# report_run.verbose = true
|
99
|
+
report_run.run! conn
|
100
|
+
# report_run.raw_sql.should == ''
|
101
|
+
report_run.error.should == nil
|
102
|
+
end
|
103
|
+
|
60
104
|
def run_reports!
|
61
105
|
@reports = { }
|
62
106
|
|
@@ -69,7 +113,7 @@ END
|
|
69
113
|
END
|
70
114
|
|
71
115
|
[ '1 days', '2 days', '30 days', '60 days' ].each do | interval |
|
72
|
-
report_run = Qreport::ReportRun.new(:name => :users_with_articles, :description => interval)
|
116
|
+
report_run = Qreport::ReportRun.new(:name => :users_with_articles, :description => interval, :variant => interval)
|
73
117
|
report_run.arguments = {
|
74
118
|
:now => now,
|
75
119
|
:interval => interval,
|
@@ -156,4 +200,12 @@ END
|
|
156
200
|
} }
|
157
201
|
end
|
158
202
|
end
|
203
|
+
|
204
|
+
after :each do
|
205
|
+
if reports
|
206
|
+
reports.values.each do | r |
|
207
|
+
r.drop_table!
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
159
211
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qreport
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-07-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -34,7 +34,7 @@ dependencies:
|
|
34
34
|
requirements:
|
35
35
|
- - ~>
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version: 2.12
|
37
|
+
version: '2.12'
|
38
38
|
type: :development
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -42,7 +42,7 @@ dependencies:
|
|
42
42
|
requirements:
|
43
43
|
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version: 2.12
|
45
|
+
version: '2.12'
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
47
|
name: simplecov
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -59,6 +59,54 @@ dependencies:
|
|
59
59
|
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: 0.7.1
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: guard
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 1.8.0
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 1.8.0
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: guard-rspec
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 3.0.2
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 3.0.2
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: cassava
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 0.0.1
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 0.0.1
|
62
110
|
- !ruby/object:Gem::Dependency
|
63
111
|
name: pg
|
64
112
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,6 +134,7 @@ files:
|
|
86
134
|
- .rspec
|
87
135
|
- ChangeLog
|
88
136
|
- Gemfile
|
137
|
+
- Guardfile
|
89
138
|
- LICENSE.txt
|
90
139
|
- README.md
|
91
140
|
- Rakefile
|
@@ -98,8 +147,8 @@ files:
|
|
98
147
|
- lib/qreport/report_runner.rb
|
99
148
|
- lib/qreport/version.rb
|
100
149
|
- qreport.gemspec
|
101
|
-
- spec/connection_spec.rb
|
102
|
-
- spec/report_runner_spec.rb
|
150
|
+
- spec/lib/qreport/connection_spec.rb
|
151
|
+
- spec/lib/qreport/report_runner_spec.rb
|
103
152
|
- spec/spec_helper.rb
|
104
153
|
homepage: http://github.com/kstephens/qreport
|
105
154
|
licenses: []
|
@@ -113,18 +162,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
113
162
|
- - ! '>='
|
114
163
|
- !ruby/object:Gem::Version
|
115
164
|
version: '0'
|
116
|
-
segments:
|
117
|
-
- 0
|
118
|
-
hash: 1042479240824554319
|
119
165
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
166
|
none: false
|
121
167
|
requirements:
|
122
168
|
- - ! '>='
|
123
169
|
- !ruby/object:Gem::Version
|
124
170
|
version: '0'
|
125
|
-
segments:
|
126
|
-
- 0
|
127
|
-
hash: 1042479240824554319
|
128
171
|
requirements: []
|
129
172
|
rubyforge_project:
|
130
173
|
rubygems_version: 1.8.25
|
@@ -132,6 +175,6 @@ signing_key:
|
|
132
175
|
specification_version: 3
|
133
176
|
summary: Automatically creates materialized report tables from a SQL query.
|
134
177
|
test_files:
|
135
|
-
- spec/connection_spec.rb
|
136
|
-
- spec/report_runner_spec.rb
|
178
|
+
- spec/lib/qreport/connection_spec.rb
|
179
|
+
- spec/lib/qreport/report_runner_spec.rb
|
137
180
|
- spec/spec_helper.rb
|