From 4978d1dce781f7ab81826cec5e3df4ae2cfd1bd7 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Mon, 13 Nov 2006 19:23:32 +0000 Subject: Oracle: automatically detect the primary key. Closes #6594. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@5514 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- activerecord/CHANGELOG | 2 ++ .../connection_adapters/oracle_adapter.rb | 27 ++++++++++++++++++---- activerecord/test/schema_dumper_test.rb | 2 +- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index f00de668e4..84a30de2fd 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* Oracle: automatically detect the primary key. #6594 [vesaria, Michael Schoen] + * Oracle: to increase performance, prefetch 100 rows and enable similar cursor sharing. Both are configurable in database.yml. #6607 [philbogle@gmail.com, Michael Schoen] * Don't inspect unloaded associations. #2905 [lmarlow] diff --git a/activerecord/lib/active_record/connection_adapters/oracle_adapter.rb b/activerecord/lib/active_record/connection_adapters/oracle_adapter.rb index 2453781e53..cf77dfa7bf 100644 --- a/activerecord/lib/active_record/connection_adapters/oracle_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/oracle_adapter.rb @@ -314,9 +314,8 @@ begin def columns(table_name, name = nil) #:nodoc: (owner, table_name) = @connection.describe(table_name) - raise "Could not describe #{table_name}. Does it exist?" unless owner and table_name - table_cols = %Q{ + table_cols = <<-SQL select column_name as name, data_type as sql_type, data_default, nullable, decode(data_type, 'NUMBER', data_precision, 'FLOAT', data_precision, @@ -327,7 +326,7 @@ begin where owner = '#{owner}' and table_name = '#{table_name}' order by column_id - } + SQL select_all(table_cols, name).map do |row| limit, scale = row['limit'], row['scale'] @@ -386,6 +385,25 @@ begin execute "ALTER TABLE #{table_name} DROP COLUMN #{column_name}" end + # Find a table's primary key and sequence. + # *Note*: Only primary key is implemented - sequence will be nil. + def pk_and_sequence_for(table_name) + (owner, table_name) = @connection.describe(table_name) + + pks = select_values(<<-SQL, 'Primary Key') + select cc.column_name + from all_constraints c, all_cons_columns cc + where c.owner = '#{owner}' + and c.table_name = '#{table_name}' + and c.constraint_type = 'P' + and cc.owner = c.owner + and cc.constraint_name = c.constraint_name + SQL + + # only support single column keys + pks.size == 1 ? [oracle_downcase(pks.first), nil] : nil + end + def structure_dump #:nodoc: s = select_all("select sequence_name from user_sequences").inject("") do |structure, seq| structure << "create sequence #{seq.to_a.first.last};\n\n" @@ -531,7 +549,7 @@ begin def describe(name) @desc ||= @@env.alloc(OCIDescribe) @desc.attrSet(OCI_ATTR_DESC_PUBLIC, -1) if VERSION >= '0.1.14' - @desc.describeAny(@svc, name.to_s, OCI_PTYPE_UNK) rescue return nil + @desc.describeAny(@svc, name.to_s, OCI_PTYPE_UNK) rescue raise %Q{"DESC #{name}" failed; does it exist?} info = @desc.attrGet(OCI_ATTR_PARAM) case info.attrGet(OCI_ATTR_PTYPE) @@ -543,6 +561,7 @@ begin schema = info.attrGet(OCI_ATTR_SCHEMA_NAME) name = info.attrGet(OCI_ATTR_NAME) describe(schema + '.' + name) + else raise %Q{"DESC #{name}" failed; not a table or view.} end end diff --git a/activerecord/test/schema_dumper_test.rb b/activerecord/test/schema_dumper_test.rb index 3ca6febb89..016f66077d 100644 --- a/activerecord/test/schema_dumper_test.rb +++ b/activerecord/test/schema_dumper_test.rb @@ -47,7 +47,7 @@ if ActiveRecord::Base.connection.respond_to?(:tables) def test_schema_dump_includes_not_null_columns stream = StringIO.new - ActiveRecord::SchemaDumper.ignore_tables = [/^[^s]/] + ActiveRecord::SchemaDumper.ignore_tables = [/^[^r]/] ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream) output = stream.string assert_match %r{:null => false}, output -- cgit v1.2.3