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 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.
@@ -0,0 +1,8 @@
1
+ # -*- ruby -*-
2
+ guard 'rspec' do
3
+ watch(%r{^spec/.+_spec\.rb$})
4
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
5
+ watch('spec/spec_helper.rb') { "spec" }
6
+ watch(%r{^lib/.*/connection.rb$}) { "spec" }
7
+ end
8
+
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
@@ -4,5 +4,5 @@ module Qreport
4
4
  EMPTY_Hash = {}.freeze
5
5
  EMPTY_Array = [].freeze
6
6
  EMPTY_String = ''.freeze
7
- class Error < ::Exception; end
7
+ class Error < ::StandardError; end
8
8
  end
@@ -89,7 +89,7 @@ module Qreport
89
89
  begin
90
90
  transaction_begin
91
91
  yield
92
- rescue ::Exception => exc
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
- schemaname ||= self.schemaname
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 => 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 ::Exception => exc
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.each do | k, v |
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
@@ -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
- conn.run "-- DROP TABLE #{report_table}", :capture_error => true # , :verbose => true
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 = report_run.sql.strip
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
- begin
24
- conn.transaction do
25
-
26
- # Create a report row sequence:
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
- # Rewrite query to create result table rows:
30
- arguments = arguments.merge(:qr_run_id => conn.safe_sql("nextval('qr_row_seq')"))
31
- report_run.report_sql = report_sql(sql)
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
- # Proof query to infer base columns:
34
- result = run report_run.report_sql, :limit => 0, :arguments => arguments, :verbose => @verbose
35
- report_run.base_columns = result.columns
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
- conn.transaction do
46
- # Create new ReportRun row:
47
- report_run.insert!
48
- report_run_id = report_run.id
49
- arguments[:qr_run_id] = report_run_id
50
- report_run.report_sql = report_sql(sql)
51
- end # transaction
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 ::Exception => exc
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(/\ASELECT\s+/im, <<"END"
116
+ sql = sql.sub(/\A\s*SELECT\s+/im, <<"END"
102
117
  SELECT
103
118
  :qr_run_id
104
119
  AS "qr_run_id"
@@ -1,3 +1,3 @@
1
1
  module Qreport
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.6"
3
3
  end
@@ -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.0'
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 two reports" do
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.3
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-06-26 00:00:00.000000000 Z
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.0
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.0
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