Permalink
Browse files

added optional dbms_output logging on each call

  • Loading branch information...
alexrothenberg committed Aug 19, 2009
1 parent fcaf4bb commit 00084e4e97d94cdab04ca1eb16275e0ed88c9490
@@ -524,7 +524,6 @@ def disconnect! #:nodoc:
@connection.logoff rescue nil
end


# DATABASE STATEMENTS ======================================
#
# see: abstract/database_statements.rb
@@ -1152,6 +1151,49 @@ def column_for(table_name, column_name)
column
end

public
# DBMS_OUTPUT =============================================
#
# PL/SQL in Oracle uses dbms_output for logging print statements
# These methods stick that output into the Rails log so Ruby and PL/SQL
# code can can be debugged together in a single application
DBMS_OUTPUT_BUFFER_SIZE = 10000 #can be 1-1000000
DBMS_LINE_MAX_SIZE = 1000
# Turn DBMS_Output logging on
def enable_dbms_output
@enable_dbms_output = true
execute "BEGIN dbms_output.enable(#{DBMS_OUTPUT_BUFFER_SIZE}); END;"
end
# Turn DBMS_Output logging off
def disable_dbms_output
@enable_dbms_output = false
execute "BEGIN dbms_output.disable(); END;"
end
# Is DBMD_Output logging enabled?
def dbms_output_enabled?
@enable_dbms_output
end

protected
def log(sql, name)
super sql, name
ensure
log_dbms_output if dbms_output_enabled?
end

private
def log_next_line_of_dbms_output
dbms_output_text, status = @connection.exec "BEGIN dbms_output.get_line(:return, :status); END;", ' '*DBMS_LINE_MAX_SIZE, 1
got_text = (status == 0)
@logger.debug "DBMS_OUTPUT: #{dbms_output_text}" if got_text
got_text
end

def log_dbms_output
while log_next_line_of_dbms_output do
end
end

end
end
end
@@ -657,3 +657,65 @@ class ::TestEmployee < ActiveRecord::Base; end
end

end

describe "logging dbms_output from plsql" do
include LoggerSpecHelper

before(:all) do
@buffer = StringIO.new
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
ActiveRecord::Base.connection.execute <<-SQL
create or replace
FUNCTION MORE_THAN_FIVE_CHARACTERS_LONG (some_text VARCHAR2) RETURN INTEGER
AS
longer_than_five INTEGER;
BEGIN
dbms_output.put_line('before the if -' || some_text || '-');
IF length(some_text) > 5 THEN
dbms_output.put_line('it is longer than 5');
longer_than_five := 1;
ELSE
dbms_output.put_line('it is 5 or shorter');
longer_than_five := 0;
END IF;
dbms_output.put_line('about to return: ' || longer_than_five);
RETURN longer_than_five;
END;
SQL
end

before(:each) do
@buffer = StringIO.new
log_to @buffer
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
@conn = ActiveRecord::Base.connection
end

it "should NOT log dbms output when dbms output is disabled" do
@conn.disable_dbms_output

@conn.select_all("select more_than_five_characters_long('hi there') is_it_long from dual").should == [{'is_it_long'=>1}]

@buffer.string.should_not match(/^DBMS_OUTPUT/)
end

it "should log dbms output lines to the rails log" do
@conn.enable_dbms_output

@conn.select_all("select more_than_five_characters_long('hi there') is_it_long from dual").should == [{'is_it_long'=>1}]

@buffer.string.should match(/^DBMS_OUTPUT: before the if -hi there-$/)
@buffer.string.should match(/^DBMS_OUTPUT: it is longer than 5$/)
@buffer.string.should match(/^DBMS_OUTPUT: about to return: 1$/)
end

it "should log dbms output lines to the rails log" do
@conn.enable_dbms_output

@conn.select_all("select more_than_five_characters_long('short') is_it_long from dual").should == [{'is_it_long'=>0}]

@buffer.string.should match(/^DBMS_OUTPUT: before the if -short-$/)
@buffer.string.should match(/^DBMS_OUTPUT: it is 5 or shorter$/)
@buffer.string.should match(/^DBMS_OUTPUT: about to return: 0$/)
end
end

0 comments on commit 00084e4

Please sign in to comment.