mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Improved the Oracle OCI Adapter with better performance for column reflection (from #3210), fixes to migrations (from #3476 and #3742), tweaks to unit tests (from #3610), and improved documentation (from #2446) (closes #3879) [Aggregated by schoenm@earthlink.net]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3623 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
parent
e875b0db47
commit
7a2ce50a93
6 changed files with 54 additions and 30 deletions
|
@ -1,5 +1,9 @@
|
|||
*SVN*
|
||||
|
||||
* Improved the Oracle OCI Adapter with better performance for column reflection (from #3210), fixes to migrations (from #3476 and #3742), tweaks to unit tests (from #3610), and improved documentation (from #2446) #3879 [Aggregated by schoenm@earthlink.net]
|
||||
|
||||
* Fixed that the schema_info table used by ActiveRecord::Schema.define should respect table pre- and suffixes #3834 [rubyonrails@atyp.de]
|
||||
|
||||
* Added :select option to Base.count that'll allow you to select something else than * to be counted on. Especially important for count queries using DISTINCT #3839 [skaes]
|
||||
|
||||
* Correct syntax error in mysql DDL, and make AAACreateTablesTest run first [Bob Silva]
|
||||
|
|
|
@ -56,7 +56,7 @@ begin
|
|||
value = self[c.name]
|
||||
next if value.nil? || (value == '')
|
||||
lob = connection.select_one(
|
||||
"select #{ c.name} from #{ self.class.table_name } WHERE #{ self.class.primary_key} = #{quote(id)}",
|
||||
"SELECT #{ c.name} FROM #{ self.class.table_name } WHERE #{ self.class.primary_key} = #{quote(id)}",
|
||||
'Writable Large Object')[c.name]
|
||||
lob.write value
|
||||
}
|
||||
|
@ -149,6 +149,9 @@ begin
|
|||
# * Default values that are functions (such as "SYSDATE") are not
|
||||
# supported. This is a restriction of the way ActiveRecord supports
|
||||
# default values.
|
||||
# * Support for Oracle8 is limited by Rails' use of ANSI join syntax, which
|
||||
# is supported in Oracle9i and later. You will need to use #finder_sql for
|
||||
# has_and_belongs_to_many associations to run against Oracle8.
|
||||
#
|
||||
# Options:
|
||||
#
|
||||
|
@ -167,7 +170,7 @@ begin
|
|||
|
||||
def native_database_types #:nodoc
|
||||
{
|
||||
:primary_key => "NUMBER(38) NOT NULL",
|
||||
:primary_key => "NUMBER(38) NOT NULL PRIMARY KEY",
|
||||
:string => { :name => "VARCHAR2", :limit => 255 },
|
||||
:text => { :name => "LONG" },
|
||||
:integer => { :name => "NUMBER", :limit => 38 },
|
||||
|
@ -332,10 +335,7 @@ begin
|
|||
end
|
||||
|
||||
def columns(table_name, name = nil) #:nodoc:
|
||||
table_name = table_name.to_s.upcase
|
||||
owner = table_name.include?('.') ? "'#{table_name.split('.').first}'" : "user"
|
||||
table = "'#{table_name.split('.').last}'"
|
||||
scope = (owner == "user" ? "user" : "all")
|
||||
table_info = @connection.object_info(table_name)
|
||||
|
||||
table_cols = %Q{
|
||||
select column_name, data_type, data_default, nullable,
|
||||
|
@ -343,25 +343,18 @@ begin
|
|||
'VARCHAR2', data_length,
|
||||
null) as length,
|
||||
decode(data_type, 'NUMBER', data_scale, null) as scale
|
||||
from #{scope}_catalog cat, #{scope}_synonyms syn, all_tab_columns col
|
||||
where cat.table_name = #{table}
|
||||
and syn.synonym_name (+)= cat.table_name
|
||||
and col.table_name = nvl(syn.table_name, cat.table_name)
|
||||
and col.owner = nvl(syn.table_owner, #{(scope == "all" ? "cat.owner" : "user")}) }
|
||||
|
||||
if scope == "all"
|
||||
table_cols << %Q{
|
||||
and cat.owner = #{owner}
|
||||
and syn.owner (+)= cat.owner }
|
||||
end
|
||||
from all_tab_columns
|
||||
where owner = '#{table_info.schema}'
|
||||
and table_name = '#{table_info.name}'
|
||||
}
|
||||
|
||||
select_all(table_cols, name).map do |row|
|
||||
row['data_default'].sub!(/^'(.*)'\s*$/, '\1') if row['data_default']
|
||||
OCIColumn.new(
|
||||
oci_downcase(row['column_name']),
|
||||
oci_downcase(row['column_name']),
|
||||
row['data_default'],
|
||||
row['data_type'],
|
||||
row['length'],
|
||||
row['data_type'],
|
||||
row['length'],
|
||||
row['scale'],
|
||||
row['nullable'] == 'Y'
|
||||
)
|
||||
|
@ -370,17 +363,17 @@ begin
|
|||
|
||||
def create_table(name, options = {}) #:nodoc:
|
||||
super(name, options)
|
||||
execute "CREATE SEQUENCE #{name}_seq"
|
||||
execute "CREATE SEQUENCE #{name}_seq" unless options[:id] == false
|
||||
end
|
||||
|
||||
def rename_table(name, new_name) #:nodoc:
|
||||
execute "RENAME #{name} TO #{new_name}"
|
||||
execute "RENAME #{name}_seq TO #{new_name}_seq"
|
||||
execute "RENAME #{name}_seq TO #{new_name}_seq" rescue nil
|
||||
end
|
||||
|
||||
def drop_table(name) #:nodoc:
|
||||
super(name)
|
||||
execute "DROP SEQUENCE #{name}_seq"
|
||||
execute "DROP SEQUENCE #{name}_seq" rescue nil
|
||||
end
|
||||
|
||||
def remove_index(table_name, options = {}) #:nodoc:
|
||||
|
@ -492,9 +485,10 @@ begin
|
|||
end
|
||||
|
||||
|
||||
# This OCI8 patch may not longer be required with the upcoming
|
||||
# release of version 0.2.
|
||||
class OCI8 #:nodoc:
|
||||
|
||||
# This OCI8 patch may not longer be required with the upcoming
|
||||
# release of version 0.2.
|
||||
class Cursor #:nodoc:
|
||||
alias :define_a_column_pre_ar :define_a_column
|
||||
def define_a_column(i)
|
||||
|
@ -505,6 +499,33 @@ begin
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
# missing constant from oci8
|
||||
OCI_PTYPE_UNK = 0
|
||||
|
||||
def object_info(name)
|
||||
OraObject.new describe(name.to_s, OCI_PTYPE_UNK)
|
||||
end
|
||||
|
||||
def describe(name, type)
|
||||
@desc ||= @@env.alloc(OCIDescribe)
|
||||
@desc.describeAny(@svc, name, type)
|
||||
@desc.attrGet(OCI_ATTR_PARAM)
|
||||
end
|
||||
|
||||
class OraObject
|
||||
attr_reader :schema, :name
|
||||
def initialize(info)
|
||||
case info.attrGet(OCI_ATTR_PTYPE)
|
||||
when OCI_PTYPE_TABLE, OCI_PTYPE_VIEW
|
||||
@schema = info.attrGet(OCI_ATTR_OBJ_SCHEMA)
|
||||
@name = info.attrGet(OCI_ATTR_OBJ_NAME)
|
||||
when OCI_PTYPE_SYN
|
||||
@schema = info.attrGet(OCI_ATTR_SCHEMA_NAME)
|
||||
@name = info.attrGet(OCI_ATTR_NAME)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ module ActiveRecord
|
|||
"#{k} = #{v}"
|
||||
end
|
||||
|
||||
update "UPDATE schema_info SET #{info.join(", ")}"
|
||||
update "UPDATE #{Migrator.schema_info_table_name} SET #{info.join(", ")}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -96,7 +96,7 @@ class AssociationsJoinModelTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_has_many_class_methods_called_by_method_missing
|
||||
assert_equal categories(:general), authors(:david).categories.find_by_name('General')
|
||||
assert_equal categories(:general), authors(:david).categories.find_all_by_name('General').first
|
||||
# assert_equal nil, authors(:david).categories.find_by_name('Technology')
|
||||
end
|
||||
|
||||
|
|
|
@ -17,8 +17,7 @@ create sequence companies_nonstd_seq minvalue 10000;
|
|||
create table accounts (
|
||||
id integer not null,
|
||||
firm_id integer default null references companies initially deferred disable,
|
||||
credit_limit integer default null,
|
||||
primary key (id)
|
||||
credit_limit integer default null
|
||||
);
|
||||
create sequence accounts_seq minvalue 10000;
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ class TestOracleSynonym < Test::Unit::TestCase
|
|||
|
||||
def test_oracle_synonym
|
||||
topic = Topic.new
|
||||
subject = Subject.new
|
||||
subject = Subject.new
|
||||
assert_equal(topic.attributes, subject.attributes)
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue