Skip to content

Instantly share code, notes, and snippets.

@ppdeassis
Created June 18, 2013 14:35
Show Gist options
  • Save ppdeassis/5805874 to your computer and use it in GitHub Desktop.
Save ppdeassis/5805874 to your computer and use it in GitHub Desktop.
A Ruby class to acces an Oracle database
################################################################################
require 'oci8'
require 'iconv'
################################################################################
class OracleReader
################################################################################
def initialize(server, username, password)
# Open the connection.
@connection = OCI8.new(username, password, server)
end
################################################################################
def query(sql_select, options = {})
self.class.get_query_default_options(options)
cursor = @connection.exec(sql_select)
rows = []
begin
while (row = cursor.fetch_hash)
row.each do |key, value|
row[key] = value.read if options[:preload_clobs] && value.is_a?(OCI8::CLOB)
end
rows << row
end
ensure
cursor.close
end
rows.map { |row|
row.inject Hash.new do |memo, column|
memo[column[0].downcase] =
case column[1]
when OraDate then ruby_date_with_timezone_support(column[1])
when String then options[:encoding_to_from] ? Iconv.conv(options[:encoding_to_from][0], options[:encoding_to_from][1], column[1]) : column[1]
else column[1]
end
memo
end
}.map(&:symbolize_keys!)
end
################################################################################
def close
# Close the connection.
@connection.logoff
end
################################################################################
# Given a username, password, Oracle DB URL (e.g. '//172.16.202.191:1521/SITES')
# and a SQL select string, this method performs a query and returns an array
# with the resulting rows. Each entry in this array is a hash with column names
# transformed into symbols as keys. For example:
#
# >> sql = 'SELECT c.txt_titulo_conteudo AS title FROM pwa_adm.conteudo c WHERE c.dat_inc >= (SYSDATE-2)'
# >> data = OracleReader.connect_and_query('//172.16.202.191:1521/SITES', 'ANL_ABD', 'ANL_ABD', sql)
# >> data[16][:title] # => "Toyota tem lucro maior e eleva estimativas mesmo com recall"
def self.connect_and_query(server, username, password, sql_select, options = {})
get_query_default_options(options)
connection = self.new(server, username, password)
begin
connection.query(sql_select, options)
ensure
connection.close
end
end
################################################################################
protected
################################################################################
def ruby_date_with_timezone_support(oracle_date)
Time.zone.local(oracle_date.year, oracle_date.month, oracle_date.day, oracle_date.hour, oracle_date.minute, oracle_date.second)
end
################################################################################
def self.get_query_default_options(options)
options.reverse_merge!(
:encoding_to_from => nil,
:preload_clobs => true
)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment