diff options
18 files changed, 558 insertions, 32 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index cb8217b3e1..1fb60d0e6d 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,5 +1,20 @@ *SVN* +* Added an Oracle adapter that works with the Oracle bindings by Yoshida (http://raa.ruby-lang.org/project/oracle/) #564 [Maik Schmidt] + + A number of caveats: + + 1. You have to create a sequence for every table that need an auto-generated primary key. + The sequence name is built by appending "_id" to the according table_name, + i.e. if you have a table called "employees", you have to create a sequence called "employees_id". + + 2. The data type TIME is not supported, because Oracle does not support it. + + 3. Binary data (BLOBs etc.) are currently not supported. Will be fixed soon. + + 4. LIMIT clauses with OFFSET are not supported, because I could not find a way to simulate this behaviour using ROWNUM and "SELECT *". + + * Fixed Base#clone for use with PostgreSQL #565 [hanson@surgery.wisc.edu] diff --git a/activerecord/Rakefile b/activerecord/Rakefile index 863a65f021..f599224dbc 100755 --- a/activerecord/Rakefile +++ b/activerecord/Rakefile @@ -63,6 +63,12 @@ Rake::TestTask.new("test_db2") { |t| t.verbose = true } +Rake::TestTask.new("test_oracle") { |t| + t.libs << "test" << "test/connections/native_oracle" + t.pattern = 'test/*_test.rb' + t.verbose = true +} + # Generate the RDoc documentation Rake::RDocTask.new { |rdoc| diff --git a/activerecord/install.rb b/activerecord/install.rb index 7b04e952b6..020f7bc18a 100644 --- a/activerecord/install.rb +++ b/activerecord/install.rb @@ -37,6 +37,7 @@ files = %w- active_record/connection_adapters/abstract_adapter.rb active_record/connection_adapters/db2_adapter.rb active_record/connection_adapters/mysql_adapter.rb + active_record/connection_adapters/oracle_adapter.rb active_record/connection_adapters/postgresql_adapter.rb active_record/connection_adapters/sqlite_adapter.rb active_record/connection_adapters/sqlserver_adapter.rb @@ -65,6 +66,7 @@ files = %w- active_record/timestamp.rb active_record/transactions.rb active_record/validations.rb + active_record/vendor/db2.rb active_record/vendor/mysql.rb active_record/vendor/mysql411.rb active_record/vendor/simple.rb diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb index 0b7a6b4c76..a1dde6bf5b 100755 --- a/activerecord/lib/active_record.rb +++ b/activerecord/lib/active_record.rb @@ -60,3 +60,4 @@ require 'active_record/connection_adapters/postgresql_adapter' require 'active_record/connection_adapters/sqlite_adapter' require 'active_record/connection_adapters/sqlserver_adapter' require 'active_record/connection_adapters/db2_adapter' +require 'active_record/connection_adapters/oracle_adapter' diff --git a/activerecord/lib/active_record/connection_adapters/db2_adapter.rb b/activerecord/lib/active_record/connection_adapters/db2_adapter.rb index 18c27144e6..867b17eaa0 100644 --- a/activerecord/lib/active_record/connection_adapters/db2_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/db2_adapter.rb @@ -1,5 +1,4 @@ -# db2_adapter.rb -# author: Maik Schmidt <contact@maik-schmidt.de> +# Author: Maik Schmidt <contact@maik-schmidt.de> require 'active_record/connection_adapters/abstract_adapter' @@ -100,30 +99,31 @@ begin end private - def last_insert_id - row = select_one(<<-GETID.strip) - with temp(id) as (values (identity_val_local())) select * from temp - GETID - row['id'].to_i + + def last_insert_id + row = select_one(<<-GETID.strip) + with temp(id) as (values (identity_val_local())) select * from temp + GETID + row['id'].to_i + end + + def select(sql, name = nil) + stmt = nil + log(sql, name, @connection) do |connection| + stmt = DB2::Statement.new(connection) + stmt.exec_direct(sql + " with ur") end - def select(sql, name = nil) - stmt = nil - log(sql, name, @connection) do |connection| - stmt = DB2::Statement.new(connection) - stmt.exec_direct(sql + " with ur") - end - - rows = [] - while row = stmt.fetch_as_hash - rows << row - end - stmt.free - rows + rows = [] + while row = stmt.fetch_as_hash + rows << row end + stmt.free + rows + end end end end rescue LoadError # DB2 driver is unavailable. -end
\ No newline at end of file +end diff --git a/activerecord/lib/active_record/connection_adapters/oracle_adapter.rb b/activerecord/lib/active_record/connection_adapters/oracle_adapter.rb new file mode 100644 index 0000000000..f000cc131c --- /dev/null +++ b/activerecord/lib/active_record/connection_adapters/oracle_adapter.rb @@ -0,0 +1,244 @@ +# Author: Maik Schmidt <contact@maik-schmidt.de> +require 'active_record/connection_adapters/abstract_adapter' +require 'date' + +begin + require 'oracle' unless self.class.const_defined?(:ORAconn) + + module ActiveRecord + class Base + # Establishes a connection to the database that's used by + # all Active Record objects + def self.oracle_connection(config) # :nodoc: + symbolize_strings_in_hash(config) + usr = config[:username] || '' + pwd = config[:password] || '' + db = config[:database] || '' + + connection = ORAconn.logon(usr, pwd, db) + cursor = connection.open + cursor.parse("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD'") + rows_affected = cursor.exec + cursor.close + ConnectionAdapters::OracleAdapter.new(connection) + end + end + + module ConnectionAdapters + class OracleAdapter < AbstractAdapter + def select_all(sql, name = nil) + select(sql, name) + end + + def select_one(sql, name = nil) + select(sql, name).first + end + + # Oracle does not support auto-generated columns, so we have to use + # sequences. Every insert is followed by a select statement, which + # returns the current sequence value. The statements are encapsulated + # in an anonymous PL/SQL block (supported since Oracle 7.3) to prevent + # race conditions and to maximize performance. + def insert(sql, name = nil, pk = nil, id_value = nil) + new_id = nil + if !id_value.nil? + execute(sql, name) + new_id = id_value + else + pk_col = pk || ActiveRecord::Base::primary_key + if sql !~ Regexp.new('\b' + pk_col + '\b') + seq_name = sql.sub(/^\s*insert\s+?into\s+(\S+).*$/im, '\1') + "_id" + sql.sub!(/(into\s+.*?\()/im, '\1' + "#{pk_col}, ") + sql.sub!(/(values\s*\()/im, '\1' + "#{seq_name}.nextval, ") + new_id = ' ' * 40 # Enough space for String representation of ID? + log(sql, name, @connection) do |connection| + cursor = connection.open + s = "begin #{sql}; select #{seq_name}.currval into :new_id from dual; end;" + cursor.parse(s) + cursor.bindrv(':new_id', new_id) + cursor.exec + cursor.close + new_id = new_id.to_i + end + else + execute(sql, name) + end + end + new_id + end + + def execute(sql, name = nil) + rows_affected = 0 + log(sql, name, @connection) do |connection| + cursor = connection.open + cursor.parse(sql) + rows_affected = cursor.exec + cursor.close + end + rows_affected + end + + alias_method :update, :execute + alias_method :delete, :execute + + def begin_db_transaction + @connection.commitoff + end + + def commit_db_transaction + @connection.commit + @connection.commiton + end + + def rollback_db_transaction + @connection.rollback + @connection.commiton + end + + def quote_column_name(name) name; end + + def quote(value, column = nil) + if column && column.type == :timestamp && value.class.to_s == "String" + begin + value = DateTime.parse(value) + rescue => ex + # Value cannot be parsed. + end + end + + case value + when String + if column && column.type == :binary + "'#{quote_string(column.string_to_binary(value))}'" # ' (for ruby-mode) + else + "'#{quote_string(value)}'" # ' (for ruby-mode) + end + when NilClass then "NULL" + when TrueClass then (column && column.type == :boolean ? "'t'" : "1") + when FalseClass then (column && column.type == :boolean ? "'f'" : "0") + when Float, Fixnum, Bignum then value.to_s + when Date then "to_date('#{value.strftime("%Y-%m-%d")}', 'YYYY-MM-DD')" + when Time, DateTime then "to_date('#{value.strftime("%Y-%m-%d %H:%M:%S")}', 'YYYY-MM-DD HH24:MI:SS')" + else "'#{quote_string(value.to_yaml)}'" + end + end + + def quote_string(s) + s.gsub(/'/, "''") # ' (for ruby-mode) + end + + def add_limit!(sql, limit) + l, o = limit.to_s.scan(/\d+/) + if o.nil? + sql.sub!(/^.*$/im, "select * from (#{sql}) where rownum <= #{l}") + else + raise ArgumentError, "LIMIT clauses with OFFSET are not supported yet!" + end + end + + def columns(table_name, name = nil) + sql = <<-SQL + select column_name, + data_type, + data_length, + data_precision, + data_default + from user_tab_columns + where table_name = upper('#{table_name}') + SQL + result = [] + cols = select_all(sql, name) + cols.each do |c| + name = c['column_name'].downcase + default = c['data_default'] + default = (default == 'NULL') ? nil : default + type = get_sql_type(c['data_type'], c['data_length']) + result << Column.new(name, default, type) + end + result + end + + private + + def get_sql_type(type_name, type_length) + case type_name + when /timestamp/i + return "TIMESTAMP" + when /number/i + return "INT" + when /date/i + return "DATE" + else + return "#{type_name}(#{type_length})" + end + end + + def select(sql, name = nil) + col_names = [] + cursor = nil + log(sql, name, @connection) do |connection| + cursor = connection.open + col_names = parse(cursor, sql) + cursor.exec + end + + rows = [] + while cursor.fetch do + row = {} + col_names.each_with_index do |name, i| + row[name] = cursor.getCol(i + 1)[0] + end + rows << row + end + cursor.close + rows + end + + VARCHAR2 = 1 + NUMBER = 2 + INTEGER = 3 ## external + FLOAT = 4 ## external + LONG = 8 + ROWID = 11 + DATE = 12 + RAW = 23 + LONG_RAW = 24 + UNSIGNED_INT = 68 ## external + CHAR = 96 + MLSLABEL = 105 + + def parse(cursor, sql) + cursor.parse(sql) + colnr = 1 + col_names = [] + loop { + colinfo = cursor.describe(colnr) + break if colinfo.nil? + + col_names << colinfo[2].downcase + collength, coltype = colinfo[3], colinfo[1] + + collength, coltype = case coltype + when NUMBER + [40, VARCHAR2] + when VARCHAR2, CHAR + [(collength * 1.5).ceil, VARCHAR2] + when LONG + [65535, LONG] + when LONG_RAW + [65535, LONG_RAW] + else + [collength, VARCHAR2] + end + + cursor.define(colnr, collength, coltype) + colnr += 1 + } + col_names + end + end + end + end +rescue LoadError + # Oracle driver is unavailable. +end diff --git a/activerecord/test/base_test.rb b/activerecord/test/base_test.rb index 8e69eb01a4..cbccacdbf5 100755 --- a/activerecord/test/base_test.rb +++ b/activerecord/test/base_test.rb @@ -176,6 +176,10 @@ class BasicsTest < Test::Unit::TestCase "The last_read attribute should be of the Date class" ) + # Oracle does not have a TIME datatype. + if ActiveRecord::ConnectionAdapters.const_defined? :OracleAdapter + return true if ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::OracleAdapter) + end assert_kind_of( Time, Topic.find(1).bonus_time, "The bonus_time attribute should be of the Time class" @@ -381,6 +385,11 @@ class BasicsTest < Test::Unit::TestCase end def test_utc_as_time_zone + # Oracle does not have a TIME datatype. + if ActiveRecord::ConnectionAdapters.const_defined? :OracleAdapter + return true if ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::OracleAdapter) + end + Topic.default_timezone = :utc attributes = { "bonus_time" => "5:42:00AM" } topic = Topic.find(1) @@ -506,6 +515,11 @@ class BasicsTest < Test::Unit::TestCase end def test_attributes_on_dummy_time + # Oracle does not have a TIME datatype. + if ActiveRecord::ConnectionAdapters.const_defined? :OracleAdapter + return true if ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::OracleAdapter) + end + attributes = { "bonus_time" => "5:42:00AM" } diff --git a/activerecord/test/binary_test.rb b/activerecord/test/binary_test.rb index 1e74b023bf..d635621cef 100644 --- a/activerecord/test/binary_test.rb +++ b/activerecord/test/binary_test.rb @@ -13,6 +13,10 @@ class BinaryTest < Test::Unit::TestCase if ActiveRecord::ConnectionAdapters.const_defined? :DB2Adapter return true if ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::DB2Adapter) end + + if ActiveRecord::ConnectionAdapters.const_defined? :OracleAdapter + return true if ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::OracleAdapter) + end bin = Binary.new bin.data = @data @@ -27,10 +31,10 @@ class BinaryTest < Test::Unit::TestCase db_bin = Binary.find(bin.id) assert db_bin.data == bin.data, - "Loaded binary data differes from memory version" + "Loaded binary data differs from memory version" assert db_bin.data == File.new(File.dirname(__FILE__)+"/fixtures/associations.png","rb").read, - "Loaded binary data differes from file version" + "Loaded binary data differs from file version" end private diff --git a/activerecord/test/column_alias_test.rb b/activerecord/test/column_alias_test.rb index 06a0a7f3b0..1c84e119f3 100644 --- a/activerecord/test/column_alias_test.rb +++ b/activerecord/test/column_alias_test.rb @@ -5,8 +5,15 @@ class TestColumnAlias < Test::Unit::TestCase def test_column_alias topic = Topic.find(1) - records = topic.connection.select_all("SELECT id AS pk FROM topics LIMIT 1") - assert_equal(records[0].keys[0], "pk") + if ActiveRecord::ConnectionAdapters.const_defined? :OracleAdapter + if ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::OracleAdapter) + records = topic.connection.select_all("SELECT id AS pk FROM topics WHERE ROWNUM < 2") + assert_equal(records[0].keys[0], "pk") + end + else + records = topic.connection.select_all("SELECT id AS pk FROM topics LIMIT 1") + assert_equal(records[0].keys[0], "pk") + end end end diff --git a/activerecord/test/connections/native_oracle/connection.rb b/activerecord/test/connections/native_oracle/connection.rb new file mode 100644 index 0000000000..7e4cc5b574 --- /dev/null +++ b/activerecord/test/connections/native_oracle/connection.rb @@ -0,0 +1,24 @@ +print "Using native Oracle\n" +require 'fixtures/course' +require 'logger' + +ActiveRecord::Base.logger = Logger.new("debug.log") + +db1 = 'local' +db2 = 'local' + +ActiveRecord::Base.establish_connection( + :adapter => "oracle", + :host => "localhost", + :username => "arunit", + :password => "arunit", + :database => db1 +) + +Course.establish_connection( + :adapter => "oracle", + :host => "localhost", + :username => "arunit2", + :password => "arunit2", + :database => db2 +) diff --git a/activerecord/test/finder_test.rb b/activerecord/test/finder_test.rb index 5944717132..1f6a58dee6 100755 --- a/activerecord/test/finder_test.rb +++ b/activerecord/test/finder_test.rb @@ -34,10 +34,16 @@ class FinderTest < Test::Unit::TestCase end def test_find_all_with_prepared_limit_and_offset - entrants = Entrant.find_all nil, "id ASC", ["? OFFSET ?", 2, 1] - - assert_equal(2, entrants.size) - assert_equal(@entrants["second"]["name"], entrants.first.name) + if ActiveRecord::ConnectionAdapters.const_defined? :OracleAdapter + if ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::OracleAdapter) + assert_raises(ArgumentError) { Entrant.find_all nil, "id ASC", ["? OFFSET ?", 2, 1] } + end + else + entrants = Entrant.find_all nil, "id ASC", ["? OFFSET ?", 2, 1] + + assert_equal(2, entrants.size) + assert_equal(@entrants["second"]["name"], entrants.first.name) + end end def test_find_with_entire_select_statement diff --git a/activerecord/test/fixtures/db_definitions/create_oracle_db.bat b/activerecord/test/fixtures/db_definitions/create_oracle_db.bat new file mode 100644 index 0000000000..25c7e18856 --- /dev/null +++ b/activerecord/test/fixtures/db_definitions/create_oracle_db.bat @@ -0,0 +1,5 @@ +sqlplus arunit/arunit @ drop_oracle_tables +sqlplus arunit/arunit @ oracle +sqlplus arunit2/arunit2 @ drop_oracle_tables2 +sqlplus arunit2/arunit2 @ oracle2 + diff --git a/activerecord/test/fixtures/db_definitions/create_oracle_db.sh b/activerecord/test/fixtures/db_definitions/create_oracle_db.sh new file mode 100644 index 0000000000..25c7e18856 --- /dev/null +++ b/activerecord/test/fixtures/db_definitions/create_oracle_db.sh @@ -0,0 +1,5 @@ +sqlplus arunit/arunit @ drop_oracle_tables +sqlplus arunit/arunit @ oracle +sqlplus arunit2/arunit2 @ drop_oracle_tables2 +sqlplus arunit2/arunit2 @ oracle2 + diff --git a/activerecord/test/fixtures/db_definitions/drop_oracle_tables.sql b/activerecord/test/fixtures/db_definitions/drop_oracle_tables.sql new file mode 100644 index 0000000000..b300d13485 --- /dev/null +++ b/activerecord/test/fixtures/db_definitions/drop_oracle_tables.sql @@ -0,0 +1,35 @@ +DROP TABLE accounts; +DROP SEQUENCE accounts_id; +DROP TABLE companies; +DROP SEQUENCE companies_id; +DROP TABLE topics; +DROP SEQUENCE topics_id; +DROP TABLE developers; +DROP SEQUENCE developers_id; +DROP TABLE projects; +DROP SEQUENCE projects_id; +DROP TABLE developers_projects; +DROP SEQUENCE developers_projects_id; +DROP TABLE customers; +DROP SEQUENCE customers_id; +DROP TABLE movies; +DROP SEQUENCE movies_id; +DROP TABLE subscribers; +DROP SEQUENCE subscribers_id; +DROP TABLE booleantests; +DROP SEQUENCE booleantests_id; +DROP TABLE auto_id_tests; +DROP SEQUENCE auto_id_tests_id; +DROP TABLE entrants; +DROP SEQUENCE entrants_id; +DROP TABLE colnametests; +DROP SEQUENCE colnametests_id; +DROP TABLE mixins; +DROP SEQUENCE mixins_id; +DROP TABLE people; +DROP SEQUENCE people_id; +DROP TABLE binaries; +DROP SEQUENCE binaries_id; +DROP TABLE computers; +DROP SEQUENCE computers_id; +EXIT; diff --git a/activerecord/test/fixtures/db_definitions/drop_oracle_tables2.sql b/activerecord/test/fixtures/db_definitions/drop_oracle_tables2.sql new file mode 100644 index 0000000000..934026dc89 --- /dev/null +++ b/activerecord/test/fixtures/db_definitions/drop_oracle_tables2.sql @@ -0,0 +1,3 @@ +DROP TABLE courses; +DROP SEQUENCE courses_id; +EXIT; diff --git a/activerecord/test/fixtures/db_definitions/oracle.sql b/activerecord/test/fixtures/db_definitions/oracle.sql new file mode 100644 index 0000000000..31e66e8532 --- /dev/null +++ b/activerecord/test/fixtures/db_definitions/oracle.sql @@ -0,0 +1,149 @@ +CREATE TABLE accounts ( + id int NOT NULL, + firm_id int default NULL, + credit_limit int default NULL, + PRIMARY KEY (id) +); +CREATE SEQUENCE accounts_id MINVALUE 10000; + +CREATE TABLE companies ( + id int NOT NULL, + type varchar(50) default NULL, + ruby_type varchar(50) default NULL, + firm_id int default NULL, + name varchar(50) default NULL, + client_of int default NULL, + rating int default 1, + PRIMARY KEY (id) +); +CREATE SEQUENCE companies_id MINVALUE 10000; + +CREATE TABLE topics ( + id int NOT NULL, + title varchar(255) default NULL, + author_name varchar(255) default NULL, + author_email_address varchar(255) default NULL, + written_on timestamp default NULL, + bonus_time timestamp default NULL, + last_read date default NULL, + content varchar(3000), + approved smallint default 1, + replies_count int default 0, + parent_id int default NULL, + type varchar(50) default NULL, + PRIMARY KEY (id) +); +CREATE SEQUENCE topics_id MINVALUE 10000; + +CREATE TABLE developers ( + id int NOT NULL, + name varchar(100) default NULL, + salary int default 70000, + PRIMARY KEY (id) +); +CREATE SEQUENCE developers_id MINVALUE 10000; + +CREATE TABLE projects ( + id int NOT NULL, + name varchar(100) default NULL, + PRIMARY KEY (id) +); +CREATE SEQUENCE projects_id MINVALUE 10000; + +CREATE TABLE developers_projects ( + developer_id int NOT NULL, + project_id int NOT NULL, + joined_on date default NULL +); +CREATE SEQUENCE developers_projects_id MINVALUE 10000; + +CREATE TABLE customers ( + id int NOT NULL, + name varchar(100) default NULL, + balance int default 0, + address_street varchar(100) default NULL, + address_city varchar(100) default NULL, + address_country varchar(100) default NULL, + PRIMARY KEY (id) +); +CREATE SEQUENCE customers_id MINVALUE 10000; + +CREATE TABLE movies ( + movieid int NOT NULL, + name varchar(100) default NULL, + PRIMARY KEY (movieid) +); +CREATE SEQUENCE movies_id MINVALUE 10000; + +CREATE TABLE subscribers ( + nick varchar(100) NOT NULL, + name varchar(100) default NULL, + PRIMARY KEY (nick) +); +CREATE SEQUENCE subscribers_id MINVALUE 10000; + +CREATE TABLE booleantests ( + id int NOT NULL, + value int default NULL, + PRIMARY KEY (id) +); +CREATE SEQUENCE booleantests_id MINVALUE 10000; + +CREATE TABLE auto_id_tests ( + auto_id int NOT NULL, + value int default NULL, + PRIMARY KEY (auto_id) +); +CREATE SEQUENCE auto_id_tests_id MINVALUE 10000; + +CREATE TABLE entrants ( + id int NOT NULL PRIMARY KEY, + name varchar(255) NOT NULL, + course_id int NOT NULL +); +CREATE SEQUENCE entrants_id MINVALUE 10000; + +CREATE TABLE colnametests ( + id int NOT NULL, + references int NOT NULL, + PRIMARY KEY (id) +); +CREATE SEQUENCE colnametests_id MINVALUE 10000; + +CREATE TABLE mixins ( + id int NOT NULL, + parent_id int default NULL, + pos int default NULL, + created_at timestamp default NULL, + updated_at timestamp default NULL, + lft int default NULL, + rgt int default NULL, + root_id int default NULL, + type varchar(40) default NULL, + PRIMARY KEY (id) +); +CREATE SEQUENCE mixins_id MINVALUE 10000; + +CREATE TABLE people ( + id int NOT NULL, + first_name varchar(40) NOT NULL, + lock_version int default 0, + PRIMARY KEY (id) +); +CREATE SEQUENCE people_id MINVALUE 10000; + +CREATE TABLE binaries ( + id int NOT NULL, + data blob, + PRIMARY KEY (id) +); +CREATE SEQUENCE binaries_id MINVALUE 10000; + +CREATE TABLE computers ( + id int, + developer int NOT NULL, + PRIMARY KEY (id) +); +CREATE SEQUENCE computers_id MINVALUE 10000; + +EXIT; diff --git a/activerecord/test/fixtures/db_definitions/oracle2.sql b/activerecord/test/fixtures/db_definitions/oracle2.sql new file mode 100644 index 0000000000..e0bfde022c --- /dev/null +++ b/activerecord/test/fixtures/db_definitions/oracle2.sql @@ -0,0 +1,7 @@ +CREATE TABLE courses ( + id int NOT NULL PRIMARY KEY, + name varchar(255) NOT NULL +); +CREATE SEQUENCE courses_id MINVALUE 10000; + +EXIT; diff --git a/activerecord/test/fixtures/topics.yml b/activerecord/test/fixtures/topics.yml index d4e5a57291..cd4dfa3638 100644 --- a/activerecord/test/fixtures/topics.yml +++ b/activerecord/test/fixtures/topics.yml @@ -3,8 +3,7 @@ first: title: The First Topic author_name: David author_email_address: david@loudthinking.com - written_on: 2003-07-16 15:28:00 - bonus_time: '12:13:14' + written_on: 2003-07-16t15:28:00.00+01:00 last_read: 2004-04-15 content: Have a nice day approved: 0 @@ -14,7 +13,7 @@ second: id: 2 title: The Second Topic's of the day author_name: Mary - written_on: 2003-07-15 15:28:00 + written_on: 2003-07-15t15:28:00.00+01:00 content: Have a nice day approved: 1 replies_count: 2 |