diff options
author | David Heinemeier Hansson <david@loudthinking.com> | 2006-02-21 00:00:29 +0000 |
---|---|---|
committer | David Heinemeier Hansson <david@loudthinking.com> | 2006-02-21 00:00:29 +0000 |
commit | 7a2ce50a9386a46387c114945354ba89c5fc9c30 (patch) | |
tree | 185cac50236c584974d02828054b9693f0b5b2b5 /activerecord/lib | |
parent | e875b0db4714a86798a8248e91bea3fb7ffefe52 (diff) | |
download | rails-7a2ce50a9386a46387c114945354ba89c5fc9c30.tar.gz rails-7a2ce50a9386a46387c114945354ba89c5fc9c30.tar.bz2 rails-7a2ce50a9386a46387c114945354ba89c5fc9c30.zip |
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
Diffstat (limited to 'activerecord/lib')
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/oci_adapter.rb | 71 | ||||
-rw-r--r-- | activerecord/lib/active_record/schema.rb | 2 |
2 files changed, 47 insertions, 26 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/oci_adapter.rb b/activerecord/lib/active_record/connection_adapters/oci_adapter.rb index 46937b034b..66931a8886 100644 --- a/activerecord/lib/active_record/connection_adapters/oci_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/oci_adapter.rb @@ -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 diff --git a/activerecord/lib/active_record/schema.rb b/activerecord/lib/active_record/schema.rb index c986380853..6e0579b586 100644 --- a/activerecord/lib/active_record/schema.rb +++ b/activerecord/lib/active_record/schema.rb @@ -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 |