提交 40bdbba4 编写于 作者: J Jeremy Kemper

Oracle: use nonblocking queries if allow_concurrency is set, fix pessimistic...

Oracle: use nonblocking queries if allow_concurrency is set, fix pessimistic locking, don't guess date vs. time by default (set OracleAdapter.emulate_dates = true for the old behavior), adapter cleanup. Closes #5635.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4574 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
上级 9f3625dd
*SVN*
* Oracle: use nonblocking queries if allow_concurrency is set, fix pessimistic locking, don't guess date vs. time by default (set OracleAdapter.emulate_dates = true for the old behavior), adapter cleanup. #5635 [schoenm@earthlink.net]
* Fixed a few Oracle issues: Allows Oracle's odd date handling to still work consistently within #to_xml, Passes test that hardcode insert statement by dropping the :id column, Updated RUNNING_UNIT_TESTS with Oracle instructions, Corrects method signature for #exec #5294 [schoenm@earthlink.net]
* Added :group to available options for finds done on associations #5516 [mike@michaeldewey.org]
......
......@@ -113,7 +113,7 @@ def self.string_to_time(string)
time_hash[:sec_fraction] = microseconds(time_hash)
time_array = time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction)
# treat 0000-00-00 00:00:00 as nil
Time.send(Base.default_timezone, *time_array) rescue nil
Time.send(Base.default_timezone, *time_array) rescue DateTime.new(*time_array[0..5]) rescue nil
end
def self.string_to_dummy_time(string)
......
......@@ -76,57 +76,29 @@ def write_lobs() #:nodoc:
module ConnectionAdapters #:nodoc:
class OracleColumn < Column #:nodoc:
alias_method :super_initialize, :initialize
# overridden to add the concept of scale, required to differentiate
# between integer and float fields
def initialize(name, default, sql_type = nil, null = true, scale = nil)
@scale = scale
super_initialize(name, default, sql_type, null)
super(name, default, sql_type, null)
end
def type_cast(value)
return nil if value.nil? || value =~ /^\s*null\s*$/i
case type
when :string then value
when :integer then defined?(value.to_i) ? value.to_i : (value ? 1 : 0)
when :boolean then cast_to_boolean(value)
when :float then value.to_f
when :datetime then cast_to_date_or_time(value)
when :time then cast_to_time(value)
else value
end
return nil if value =~ /^\s*null\s*$/i
return guess_date_or_time(value) if type == :datetime && OracleAdapter.emulate_dates
super
end
private
def simplified_type(field_type)
return :boolean if (OracleAdapter.emulate_booleans && field_type =~ /num/i && @limit == 1)
return :boolean if OracleAdapter.emulate_booleans && field_type == 'NUMBER(1)'
case field_type
when /char/i : :string
when /num|float|double|dec|real|int/i : @scale == 0 ? :integer : :float
when /date|time/i : @name =~ /_at$/ ? :time : :datetime
when /clob/i : :text
when /blob/i : :binary
when /num/i : @scale == 0 ? :integer : :float
when /date|time/i : :datetime
else super
end
end
def cast_to_boolean(value)
return value if value.is_a? TrueClass or value.is_a? FalseClass
value.to_i == 0 ? false : true
end
def cast_to_date_or_time(value)
return value if value.is_a? Date
return nil if value.blank?
guess_date_or_time((value.is_a? Time) ? value : cast_to_time(value))
end
def cast_to_time(value)
return value if value.is_a? Time
time_array = ParseDate.parsedate value
time_array[0] ||= 2000; time_array[1] ||= 1; time_array[2] ||= 1;
Time.send(Base.default_timezone, *time_array) rescue nil
end
def guess_date_or_time(value)
(value.hour == 0 and value.min == 0 and value.sec == 0) ?
Date.new(value.year, value.month, value.day) : value
......@@ -171,6 +143,9 @@ class OracleAdapter < AbstractAdapter
@@emulate_booleans = true
cattr_accessor :emulate_booleans
@@emulate_dates = false
cattr_accessor :emulate_dates
def adapter_name #:nodoc:
'Oracle'
end
......@@ -209,28 +184,26 @@ def quote_column_name(name) #:nodoc:
name =~ /[A-Z]/ ? "\"#{name}\"" : name
end
def quote_string(string) #:nodoc:
string.gsub(/'/, "''")
def quote_string(s) #:nodoc:
s.gsub(/'/, "''")
end
def quote(value, column = nil) #:nodoc:
return value.quoted_id if value.respond_to?(:quoted_id)
if column && [:text, :binary].include?(column.type)
%Q{empty_#{ column.sql_type rescue 'blob' }()}
else
case value
when String : %Q{'#{quote_string(value)}'}
when NilClass : 'null'
when TrueClass : '1'
when FalseClass : '0'
when Numeric : value.to_s
when Date, Time : %Q{'#{value.strftime("%Y-%m-%d %H:%M:%S")}'}
else %Q{'#{quote_string(value.to_yaml)}'}
end
super
end
end
def quoted_true
"1"
end
def quoted_false
"0"
end
# CONNECTION MANAGEMENT ====================================
#
......@@ -567,11 +540,12 @@ def describe(name)
# The OracleConnectionFactory factors out the code necessary to connect and
# configure an Oracle/OCI connection.
class OracleConnectionFactory #:nodoc:
def new_connection(username, password, database)
def new_connection(username, password, database, async)
conn = OCI8.new username, password, database
conn.exec %q{alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS'}
conn.exec %q{alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS'} rescue nil
conn.autocommit = true
conn.non_blocking = true if async
conn
end
end
......@@ -596,9 +570,10 @@ class << self
def initialize(config, factory = OracleConnectionFactory.new)
@active = true
@username, @password, @database = config[:username], config[:password], config[:database]
@username, @password, @database, = config[:username], config[:password], config[:database]
@async = config[:allow_concurrency]
@factory = factory
@connection = @factory.new_connection @username, @password, @database
@connection = @factory.new_connection @username, @password, @database, @async
super @connection
end
......@@ -617,7 +592,7 @@ def ping
def reset!
logoff rescue nil
begin
@connection = @factory.new_connection @username, @password, @database
@connection = @factory.new_connection @username, @password, @database, @async
__setobj__ @connection
@active = true
rescue
......
......@@ -1621,6 +1621,12 @@ def test_join_table_alias
end
def test_join_with_group
assert_equal 2, Developer.find(:all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL', :group => "developers.name").size
group = Developer.columns.inject([]) do |g, c|
g << "developers.#{c.name}"
g << "developers_projects_2.#{c.name}"
end
Project.columns.each { |c| group << "projects.#{c.name}" }
assert_equal 3, Developer.find(:all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL', :group => group.join(",")).size
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册