diff options
author | David Heinemeier Hansson <david@loudthinking.com> | 2005-07-24 14:01:35 +0000 |
---|---|---|
committer | David Heinemeier Hansson <david@loudthinking.com> | 2005-07-24 14:01:35 +0000 |
commit | 14ea312808599001674784a839bf7cf5a8eea872 (patch) | |
tree | 9875456d3eba2ceb2f86909ee280333e2dfefa94 | |
parent | 1ae0a53d861c43dff8883fc956a08404c23f180c (diff) | |
download | rails-14ea312808599001674784a839bf7cf5a8eea872.tar.gz rails-14ea312808599001674784a839bf7cf5a8eea872.tar.bz2 rails-14ea312808599001674784a839bf7cf5a8eea872.zip |
Made Oracle a first-class connection adapter by adhering closer to idiomatic Oracle style #1798 [The Gang of Oracles]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1912 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
18 files changed, 235 insertions, 59 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index 0aac9bc6c0..d23b69aa16 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,5 +1,15 @@ *SVN* +* Default sequence names for Oracle changed to #{table_name}_seq, which is the most commonly used standard. In addition, a new method ActiveRecord::Base#set_sequence_name allows the developer to set the sequence name per model. This is a non-backwards-compatible change -- anyone using the old-style "rails_sequence" will need to either create new sequences, or set: ActiveRecord::Base.set_sequence_name = "rails_sequence" #1798 + +* OCIAdapter now properly handles synonyms, which are commonly used to separate out the schema owner from the application user #1798 + +* Fixed the handling of camelCase columns names in Oracle #1798 + +* Implemented for OCI the Rakefile tasks of :clone_structure_to_test, :db_structure_dump, and :purge_test_database, which enable Oracle folks to enjoy all the agile goodness of Rails for testing. Note that the current implementation is fairly limited -- only tables and sequences are cloned, not constraints or indexes. A full clone in Oracle generally requires some manual effort, and is version-specific. Post 9i, Oracle recommends the use of the DBMS_METADATA package, though that approach requires editing of the physical characteristics generated #1798 + +* Fixed the handling of multiple blob columns in Oracle if one or more of them are null #1798 + * Added support for calling constrained class methods on has_many and has_and_belongs_to_many collections #1764 [Tobias Luetke] class Comment < AR:B diff --git a/activerecord/Rakefile b/activerecord/Rakefile index e74a777589..cbeaedb231 100755 --- a/activerecord/Rakefile +++ b/activerecord/Rakefile @@ -22,23 +22,11 @@ PKG_FILES = FileList[ desc "Default Task" -task :default => [ :test_ruby_mysql, :test_mysql_ruby, :test_sqlite, :test_sqlite3, :test_postgresql ] +task :default => [ :test_mysql, :test_sqlite, :test_postgresql ] # Run the unit tests -Rake::TestTask.new("test_ruby_mysql") { |t| - t.libs << "test" << "test/connections/native_mysql" - t.pattern = 'test/*_test{,_mysql}.rb' - t.verbose = true -} - -Rake::TestTask.new("test_mysql_ruby") { |t| - t.libs << "test" << "test/connections/native_mysql" - t.pattern = 'test/*_test{,_mysql}.rb' - t.verbose = true -} - -for adapter in %w( postgresql sqlite sqlite3 sqlserver sqlserver_odbc db2 oci ) +for adapter in %w( mysql postgresql sqlite sqlite3 sqlserver sqlserver_odbc db2 oci ) Rake::TestTask.new("test_#{adapter}") { |t| t.libs << "test" << "test/connections/native_#{adapter}" t.pattern = "test/*_test{,_#{adapter}}.rb" diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 20ccd9a623..84bf0cdcff 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -569,6 +569,11 @@ module ActiveRecord #:nodoc: "type" end + # Defines the sequence_name (for Oracle) -- can be overridden in subclasses. + def sequence_name + "#{table_name}_seq" + end + # Sets the table name to use to the given value, or (if the value # is nil or false) to the value returned by the given block. # @@ -612,6 +617,25 @@ module ActiveRecord #:nodoc: end alias :inheritance_column= :set_inheritance_column + # Sets the name of the sequence to use when generating ids to the given + # value, or (if the value is nil or false) to the value returned by the + # given block. Currently useful only when using Oracle, which requires + # explicit sequences. + # + # Setting the sequence name when using other dbs will have no effect. + # If a sequence name is not explicitly set when using Oracle, it will + # default to the commonly used pattern of: #{table_name}_seq + # + # Example: + # + # class Project < ActiveRecord::Base + # set_sequence_name "projectseq" # default would have been "project_seq" + # end + def set_sequence_name( value=nil, &block ) + define_attr_method :sequence_name, value, &block + end + alias :sequence_name= :set_sequence_name + # Turns the +table_name+ back into a class name following the reverse rules of +table_name+. def class_name(table_name = table_name) # :nodoc: # remove any prefix and/or suffix from the table name @@ -1193,7 +1217,7 @@ module ActiveRecord #:nodoc: "(#{quoted_column_names.join(', ')}) " + "VALUES(#{attributes_with_quotes.values.join(', ')})", "#{self.class.name} Create", - self.class.primary_key, self.id + self.class.primary_key, self.id, self.class.sequence_name ) @new_record = false diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index ff34c63fa1..7a680c3101 100755 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -279,7 +279,7 @@ module ActiveRecord def columns(table_name, name = nil) end # Returns the last auto-generated ID from the affected table. - def insert(sql, name = nil, pk = nil, id_value = nil) end + def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) end # Executes the update statement and returns the number of rows affected. def update(sql, name = nil) end diff --git a/activerecord/lib/active_record/connection_adapters/db2_adapter.rb b/activerecord/lib/active_record/connection_adapters/db2_adapter.rb index a80a227a6d..b31e205fc8 100644 --- a/activerecord/lib/active_record/connection_adapters/db2_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/db2_adapter.rb @@ -44,7 +44,7 @@ begin select(sql, name).first end - def insert(sql, name = nil, pk = nil, id_value = nil) + def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) execute(sql, name = nil) id_value || last_insert_id end diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb index 71329705b7..6dbf315396 100755 --- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb @@ -109,7 +109,7 @@ module ActiveRecord columns end - def insert(sql, name = nil, pk = nil, id_value = nil) + def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) execute(sql, name = nil) id_value || @connection.insert_id end diff --git a/activerecord/lib/active_record/connection_adapters/oci_adapter.rb b/activerecord/lib/active_record/connection_adapters/oci_adapter.rb index 3988d1aa96..194e5d0062 100644 --- a/activerecord/lib/active_record/connection_adapters/oci_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/oci_adapter.rb @@ -15,7 +15,7 @@ # Do what you want with this code, at your own peril, but if any significant portion of my code # remains then please acknowledge my contribution. # Copyright 2005 Graham Jenkins -# $Revision: 1.2 $ + require 'active_record/connection_adapters/abstract_adapter' begin @@ -77,8 +77,8 @@ begin # It has also been tested against a 9i database. # # Usage notes: - # * Key generation uses a sequence "rails_sequence" for all tables. (I couldn't find a simple - # and safe way of passing table-specific sequence information to the adapter.) + # * Key generation assumes a "${table_name}_seq" sequence is available for all tables; the + # sequence name can be changed using ActiveRecord::Base.set_sequence_name # * Oracle uses DATE or TIMESTAMP datatypes for both dates and times. Consequently I have had to # resort to some hacks to get data converted to Date or Time in Ruby. # If the column_name ends in _time it's created as a Ruby Time. Else if the @@ -106,31 +106,82 @@ begin def quote(value, column = nil) if column and column.type == :binary then %Q{empty_#{ column.sql_type }()} else case value - when String then %Q{'#{quote_string(value)}'} + when String then %Q{'#{quote_string(value)}'} when NilClass then 'null' when TrueClass then '1' when FalseClass then '0' - when Numeric then value.to_s + when Numeric then value.to_s when Date, Time then %Q{'#{value.strftime("%Y-%m-%d %H:%M:%S")}'} - else %Q{'#{quote_string(value.to_yaml)}'} + else %Q{'#{quote_string(value.to_yaml)}'} + end + end + end + + # camelCase column names need to be quoted; not that anyone using Oracle + # would really do this, but handling this case means we pass the test... + def quote_column_name(name) + name =~ /[A-Z]/ ? "\"#{name}\"" : name + end + + def structure_dump + s = select_all("select sequence_name from user_sequences").inject("") do |structure, seq| + structure << "create sequence #{seq.to_a.first.last};\n\n" + end + + select_all("select table_name from user_tables").inject(s) do |structure, table| + ddl = "create table #{table.to_a.first.last} (\n " + cols = select_all(%Q{ + select column_name, data_type, data_length, data_precision, data_scale, data_default, nullable + from user_tab_columns + where table_name = '#{table.to_a.first.last}' + order by column_id + }).map do |row| + col = "#{row['column_name'].downcase} #{row['data_type'].downcase}" + if row['data_type'] =='NUMBER' and !row['data_precision'].nil? + col << "(#{row['data_precision'].to_i}" + col << ",#{row['data_scale'].to_i}" if !row['data_scale'].nil? + col << ')' + elsif row['data_type'].include?('CHAR') + col << "(#{row['data_length'].to_i})" + end + col << " default #{row['data_default']}" if !row['data_default'].nil? + col << ' not null' if row['nullable'] == 'N' + col end + ddl << cols.join(",\n ") + ddl << ");\n\n" + structure << ddl + end + end + + def structure_drop + s = select_all("select sequence_name from user_sequences").inject("") do |drop, seq| + drop << "drop sequence #{seq.to_a.first.last};\n\n" + end + + select_all("select table_name from user_tables").inject(s) do |drop, table| + drop << "drop table #{table.to_a.first.last} cascade constraints;\n\n" end end def select_all(sql, name = nil) offset = sql =~ /OFFSET (\d+)$/ ? $1.to_i : 0 sql, limit = $1, $2.to_i if sql =~ /(.*)(?: LIMIT[= ](\d+))(\s*OFFSET \d+)?$/ + if limit sql = "select * from (select raw_sql_.*, rownum raw_rnum_ from (#{sql}) raw_sql_ where rownum <= #{offset+limit}) where raw_rnum_ > #{offset}" elsif offset > 0 sql = "select * from (select raw_sql_.*, rownum raw_rnum_ from (#{sql}) raw_sql_) where raw_rnum_ > #{offset}" end + cursor = log(sql, name) { @connection.exec sql } - cols = cursor.get_col_names.map { |x| x.downcase } + cols = cursor.get_col_names.map { |x| oci_downcase(x) } rows = [] + while row = cursor.fetch hash = Hash.new - cols.each_with_index { |col, i| + + cols.each_with_index do |col, i| hash[col] = case row[i] when OCI8::LOB name == 'Writable Large Object' ? row[i]: row[i].read @@ -139,9 +190,11 @@ begin row[i].to_date : row[i].to_time else row[i] end unless col == 'raw_rnum_' - } + end + rows << hash end + rows ensure cursor.close if cursor @@ -153,25 +206,34 @@ begin end def columns(table_name, name = nil) - cols = select_all(%Q{ + select_all(%Q{ select column_name, data_type, data_default, data_length, data_scale - from user_tab_columns where table_name = '#{table_name.upcase}'} - ).map { |row| - OCIColumn.new row['column_name'].downcase, row['data_default'], - row['data_length'], row['data_type'], row['data_scale'] - } - cols + from user_catalog cat, user_synonyms syn, all_tab_columns col + where cat.table_name = '#{table_name.upcase}' + and syn.synonym_name (+)= cat.table_name + and col.owner = nvl(syn.table_owner, user) + and col.table_name = nvl(syn.table_name, cat.table_name)} + ).map do |row| + OCIColumn.new( + oci_downcase(row['column_name']), + row['data_default'], + row['data_length'], + row['data_type'], + row['data_scale'] + ) + end end - def insert(sql, name = nil, pk = nil, id_value = nil) + def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) if pk.nil? # Who called us? What does the sql look like? No idea! execute sql, name elsif id_value # Pre-assigned id log(sql, name) { @connection.exec sql } else # Assume the sql contains a bind-variable for the id - id_value = select_one("select rails_sequence.nextval id from dual")['id'] + id_value = select_one("select #{sequence_name}.nextval id from dual")['id'] log(sql, name) { @connection.exec sql, id_value } end + id_value end @@ -201,18 +263,31 @@ begin def adapter_name() 'OCI' end + + private + # Oracle column names by default are case-insensitive, but treated as upcase; + # for neatness, we'll downcase within Rails. EXCEPT that folks CAN quote + # their column names when creating Oracle tables, which makes then case-sensitive. + # I don't know anybody who does this, but we'll handle the theoretical case of a + # camelCase column name. I imagine other dbs handle this different, since there's a + # unit test that's currently failing test_oci. + def oci_downcase(column_name) + column_name =~ /[a-z]/ ? column_name : column_name.downcase + end end end end module ActiveRecord class Base - def self.oci_connection(config) #:nodoc: - conn = OCI8.new config[:username], config[:password], config[:host] - 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'} - conn.autocommit = true - ConnectionAdapters::OCIAdapter.new conn, logger + class << self + def oci_connection(config) #:nodoc: + conn = OCI8.new config[:username], config[:password], config[:host] + 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'} + conn.autocommit = true + ConnectionAdapters::OCIAdapter.new conn, logger + end end alias :attributes_with_quotes_pre_oci :attributes_with_quotes #:nodoc: @@ -231,9 +306,10 @@ begin # After setting large objects to empty, select the OCI8::LOB and write back the data def write_lobs() #:nodoc: - if connection.class == ConnectionAdapters::OCIAdapter + if connection.is_a?(ConnectionAdapters::OCIAdapter) self.class.columns.select { |c| c.type == :binary }.each { |c| - break unless value = self[c.name] + 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)}", 'Writable Large Object' diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index b7ba2431c4..25539e2617 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -95,7 +95,7 @@ module ActiveRecord end end - def insert(sql, name = nil, pk = nil, id_value = nil) + def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) execute(sql, name) table = sql.split(" ", 4)[2] return id_value || last_insert_id(table, pk) diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb index 212e11de4e..5e3ef53c82 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb @@ -123,7 +123,7 @@ module ActiveRecord @connection.changes end - def insert(sql, name = nil, pk = nil, id_value = nil) + def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) execute(sql, name = nil) id_value || @connection.last_insert_row_id end diff --git a/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb index 7b68283e57..7d4c00b85d 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb @@ -204,7 +204,7 @@ module ActiveRecord columns end - def insert(sql, name = nil, pk = nil, id_value = nil) + def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) begin table_name = get_table_name(sql) col = get_identity_column(table_name) diff --git a/activerecord/test/base_test.rb b/activerecord/test/base_test.rb index d91a719f72..b6e2b2f7b7 100755 --- a/activerecord/test/base_test.rb +++ b/activerecord/test/base_test.rb @@ -571,7 +571,7 @@ class BasicsTest < Test::Unit::TestCase def test_multiparameter_mass_assignment_protector task = Task.new - time = Time.mktime(0) + time = Time.mktime(2000, 1, 1, 1) task.starting = time attributes = { "starting(1i)" => "2004", "starting(2i)" => "6", "starting(3i)" => "24" } task.attributes = attributes diff --git a/activerecord/test/fixtures/company.rb b/activerecord/test/fixtures/company.rb index c7655fb1dd..5af39c1297 100755 --- a/activerecord/test/fixtures/company.rb +++ b/activerecord/test/fixtures/company.rb @@ -1,5 +1,6 @@ class Company < ActiveRecord::Base attr_protected :rating + set_sequence_name :companies_nonstd_seq validates_presence_of :name end diff --git a/activerecord/test/fixtures/db_definitions/oci.drop.sql b/activerecord/test/fixtures/db_definitions/oci.drop.sql index 532a2f4208..52b377398d 100644 --- a/activerecord/test/fixtures/db_definitions/oci.drop.sql +++ b/activerecord/test/fixtures/db_definitions/oci.drop.sql @@ -1,9 +1,11 @@ drop table accounts; drop table companies; drop table topics; +drop synonym subjects; +drop table developers_projects; +drop table computers; drop table developers; drop table projects; -drop table developers_projects; drop table customers; drop table movies; drop table subscribers; @@ -14,10 +16,36 @@ drop table colnametests; drop table mixins; drop table people; drop table binaries; -drop table posts; drop table comments; drop table authors; -drop table computers; -drop table categories; +drop table tasks; drop table categories_posts; -drop sequence rails_sequence; +drop table categories; +drop table posts; +drop table fk_test_has_pk; +drop table fk_test_has_fk; +drop sequence accounts_seq; +drop sequence companies_nonstd_seq; +drop sequence topics_seq; +drop sequence developers_seq; +drop sequence projects_seq; +drop sequence developers_projects_seq; +drop sequence customers_seq; +drop sequence movies_seq; +drop sequence subscribers_seq; +drop sequence booleantests_seq; +drop sequence auto_id_tests_seq; +drop sequence entrants_seq; +drop sequence colnametests_seq; +drop sequence mixins_seq; +drop sequence people_seq; +drop sequence binaries_seq; +drop sequence posts_seq; +drop sequence comments_seq; +drop sequence authors_seq; +drop sequence tasks_seq; +drop sequence computers_seq; +drop sequence categories_seq; +drop sequence categories_posts_seq; +drop sequence fk_test_has_pk_seq; +drop sequence fk_test_has_fk_seq; diff --git a/activerecord/test/fixtures/db_definitions/oci.sql b/activerecord/test/fixtures/db_definitions/oci.sql index 0923651dfc..8abdc0e6ae 100644 --- a/activerecord/test/fixtures/db_definitions/oci.sql +++ b/activerecord/test/fixtures/db_definitions/oci.sql @@ -1,5 +1,3 @@ -create sequence rails_sequence minvalue 10000; - create table companies ( id integer not null, type varchar(50) default null, @@ -12,12 +10,17 @@ create table companies ( primary key (id) ); +-- non-standard sequence name used to test set_sequence_name +-- +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) ); +create sequence accounts_seq minvalue 10000; create table topics ( id integer not null, @@ -50,6 +53,9 @@ create table topics ( type varchar(50) default null, primary key (id) ); +create sequence topics_seq minvalue 10000; + +create synonym subjects for topics; create table developers ( id integer not null, @@ -59,6 +65,7 @@ create table developers ( updated_at timestamp default null, primary key (id) ); +create sequence developers_seq minvalue 10000; create table projects ( id integer not null, @@ -66,6 +73,7 @@ create table projects ( type varchar(255) default null, primary key (id) ); +create sequence projects_seq minvalue 10000; create table developers_projects ( developer_id integer not null references developers initially deferred disable, @@ -79,6 +87,7 @@ create table developers_projects ( project_id integer not null references projects initially deferred disable, joined_on date default null ); +create sequence developers_projects_seq minvalue 10000; create table customers ( id integer not null, @@ -90,42 +99,49 @@ create table customers ( gps_location varchar(100) default null, primary key (id) ); +create sequence customers_seq minvalue 10000; create table movies ( movieid integer not null, name varchar(100) default null, primary key (movieid) ); +create sequence movies_seq minvalue 10000; create table subscribers ( nick varchar(100) not null, name varchar(100) default null, primary key (nick) ); +create sequence subscribers_seq minvalue 10000; create table booleantests ( id integer not null, value integer default null, primary key (id) ); +create sequence booleantests_seq minvalue 10000; create table auto_id_tests ( auto_id integer not null, value integer default null, primary key (auto_id) ); +create sequence auto_id_tests_seq minvalue 10000; create table entrants ( id integer not null primary key, name varchar(255) not null, course_id integer not null ); +create sequence entrants_seq minvalue 10000; create table colnametests ( id integer not null, references integer not null, primary key (id) ); +create sequence colnametests_seq minvalue 10000; create table mixins ( id integer not null, @@ -152,6 +168,7 @@ create table mixins ( updated_at date default null, primary key (id) ); +create sequence mixins_seq minvalue 10000; create table people ( id integer not null, @@ -159,18 +176,21 @@ create table people ( lock_version integer default 0, primary key (id) ); +create sequence people_seq minvalue 10000; create table binaries ( id integer not null, data blob null, primary key (id) ); +create sequence binaries_seq minvalue 10000; create table computers ( id integer not null primary key, developer integer not null references developers initially deferred disable, - extendedWarranty integer not null + "extendedWarranty" integer not null ); +create sequence computers_seq minvalue 10000; create table posts ( id integer not null primary key, @@ -179,6 +199,7 @@ create table posts ( type varchar(255) default null, body varchar(3000) default null ); +create sequence posts_seq minvalue 10000; create table comments ( id integer not null primary key, @@ -186,34 +207,41 @@ create table comments ( type varchar(255) default null, body varchar(3000) default null ); +create sequence comments_seq minvalue 10000; create table authors ( id integer not null primary key, name varchar(255) default null ); +create sequence authors_seq minvalue 10000; create table tasks ( id integer not null primary key, starting date default null, ending date default null ); +create sequence tasks_seq minvalue 10000; create table categories ( id integer not null primary key, name varchar(255) default null, type varchar(255) default null ); +create sequence categories_seq minvalue 10000; create table categories_posts ( category_id integer not null references categories initially deferred disable, post_id integer not null references posts initially deferred disable ); +create sequence categories_posts_seq minvalue 10000; create table fk_test_has_pk ( id integer not null primary key ); +create sequence fk_test_has_pk_seq minvalue 10000; create table fk_test_has_fk ( id integer not null primary key, fk_id integer not null references fk_test_has_fk initially deferred disable ); +create sequence fk_test_has_fk_seq minvalue 10000; diff --git a/activerecord/test/fixtures/db_definitions/oci2.drop.sql b/activerecord/test/fixtures/db_definitions/oci2.drop.sql index 7277a52552..abe7e55c31 100644 --- a/activerecord/test/fixtures/db_definitions/oci2.drop.sql +++ b/activerecord/test/fixtures/db_definitions/oci2.drop.sql @@ -1,2 +1,2 @@ drop table courses; -drop sequence rails_sequence; +drop sequence courses_seq; diff --git a/activerecord/test/fixtures/db_definitions/oci2.sql b/activerecord/test/fixtures/db_definitions/oci2.sql index 5ac62b0062..3c171f4f14 100644 --- a/activerecord/test/fixtures/db_definitions/oci2.sql +++ b/activerecord/test/fixtures/db_definitions/oci2.sql @@ -1,6 +1,6 @@ -create sequence rails_sequence minvalue 10000; - create table courses ( id int not null primary key, name varchar(255) not null ); + +create sequence courses_seq minvalue 10000; diff --git a/activerecord/test/fixtures/subject.rb b/activerecord/test/fixtures/subject.rb new file mode 100644 index 0000000000..3502943f3a --- /dev/null +++ b/activerecord/test/fixtures/subject.rb @@ -0,0 +1,4 @@ +# used for OracleSynonymTest, see test/synonym_test_oci.rb +# +class Subject < ActiveRecord::Base +end diff --git a/activerecord/test/synonym_test_oci.rb b/activerecord/test/synonym_test_oci.rb new file mode 100644 index 0000000000..4d4776c363 --- /dev/null +++ b/activerecord/test/synonym_test_oci.rb @@ -0,0 +1,17 @@ +require 'abstract_unit' +require 'fixtures/topic' +require 'fixtures/subject' + +# confirm that synonyms work just like tables; in this case +# the "subjects" table in Oracle (defined in oci.sql) is just +# a synonym to the "topics" table + +class TestOracleSynonym < Test::Unit::TestCase + + def test_oracle_synonym + topic = Topic.new + subject = Subject.new + assert_equal(topic.attributes, subject.attributes) + end + +end |