lib/qreport/report_runner.rb in qreport-0.0.3 vs lib/qreport/report_runner.rb in qreport-0.0.6

- old
+ new

@@ -6,83 +6,84 @@ require 'pp' module Qreport class ReportRunner attr_accessor :connection, :verbose + attr_accessor :report_run, :sql, :arguments + attr_accessor :error, :error_1, :error_2 def run! report_run + @verbose ||= report_run.verbose + @report_run = report_run report_run.created_at ||= report_run.started_at = Time.now.utc name = report_run.name - sql = report_run.sql.strip + @sql = report_run.sql.strip - arguments = report_run.arguments || { } - error = error_1 = error_2 = nrows = nil + @arguments = report_run.arguments || { } + @error = @error_1 = @error_2 = nrows = nil Connection.current = connection - begin - conn.transaction do + conn.transaction do + # Create a report row sequence: + run "CREATE TEMPORARY SEQUENCE qr_row_seq" + end - # Create a report row sequence: - run "CREATE TEMPORARY SEQUENCE qr_row_seq" + # Rewrite query to create result table rows: + self.arguments = arguments.merge(:qr_run_id => conn.safe_sql("nextval('qr_row_seq')")) + report_run.report_sql = report_sql(sql) - # Rewrite query to create result table rows: - arguments = arguments.merge(:qr_run_id => conn.safe_sql("nextval('qr_row_seq')")) - report_run.report_sql = report_sql(sql) - - # Proof query to infer base columns: - result = run report_run.report_sql, :limit => 0, :arguments => arguments, :verbose => @verbose - report_run.base_columns = result.columns - result = nil - end # transaction - rescue ::Exception => exc - error = error_1 = exc + # Infer base columns, if not specified. + if report_run.base_columns.empty? + infer_base_columns! end # Construct report_table name from column names and types: report_table = report_run.report_table - conn.transaction do - # Create new ReportRun row: - report_run.insert! - report_run_id = report_run.id - arguments[:qr_run_id] = report_run_id - report_run.report_sql = report_sql(sql) - end # transaction + unless report_run.id + conn.transaction do + # Create new ReportRun row: + report_run.insert! + end # transaction + end + arguments[:qr_run_id] = report_run.id unless error # Run query into report table: begin conn.transaction do unless conn.table_exists? report_table + result = run "CREATE TABLE #{report_table} AS #{report_run.report_sql}", :arguments => arguments, :verbose => @verbose run "CREATE INDEX #{report_table}_i1 ON #{report_table} (qr_run_id)" run "CREATE INDEX #{report_table}_i2 ON #{report_table} (qr_run_row)" run "CREATE UNIQUE INDEX #{report_table}_i3 ON #{report_table} (qr_run_id, qr_run_row)" report_run.additional_columns.each do | n, t, d | run "ALTER TABLE #{report_table} ADD COLUMN #{conn.escape_identifier(n)} #{t} DEFAULT :d", :arguments => { :d => d || nil } end else result = run "INSERT INTO #{report_table} #{report_run.report_sql}", :arguments => arguments, :verbose => @verbose - # Get the number of report run rows from cmd_status: unless cs = result.cmd_status and cs[0] == 'INSERT' and cs[1] == 0 and nrows = cs[2] raise Error, "cannot determine nrows" end end + report_run.raw_sql = result.sql_prepared + # $stderr.puts ">>>>>>>>>>>>>>>>>>> #{result.sql_prepared}" # Get the number of report run rows: unless nrows || error result = report_run._select :COLUMNS => 'COUNT(*) AS "nrows"' #, :verbose => true nrows = result.rows[0]["nrows"] || (raise Error, "cannot determine nrows") end # pp result result = nil end # transaction - rescue ::Exception => exc - error = error_2 = exc + rescue ::StandardError => exc + @error = @error_2 = exc end # transaction end conn.transaction do run "DROP SEQUENCE qr_row_seq" unless error_1 @@ -95,11 +96,25 @@ end # transaction report_run end + def infer_base_columns! + base_columns = nil + begin + conn.transaction do + # Proof query to infer base columns: + result = run report_run.report_sql, :limit => 0, :arguments => arguments, :verbose => @verbose + base_columns = report_run.base_columns = result.columns + end # transaction + rescue ::StandardError => exc + @error = @error_1 = exc + end + base_columns + end + def report_sql sql - sql = sql.sub(/\ASELECT\s+/im, <<"END" + sql = sql.sub(/\A\s*SELECT\s+/im, <<"END" SELECT :qr_run_id AS "qr_run_id" , nextval('qr_row_seq') AS "qr_run_row"