Skip to content
This repository
Browse code

Added a db2 adapter that only depends on the Ruby/DB2 bindings (http:…

…//raa.ruby-lang.org/project/ruby-db2/) #386 [Maik Schmidt]. Converted all the fixtures to YAML style ones.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@303 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
commit daf3e92a316c041b6b2bf331c8d2a51e710fe7bf 1 parent a6fefad
David Heinemeier Hansson dhh authored

Showing 37 changed files with 740 additions and 70 deletions. Show diff stats Hide diff stats

  1. +2 0  activerecord/CHANGELOG
  2. +6 0 activerecord/Rakefile
  3. +1 0  activerecord/install.rb
  4. +1 0  activerecord/lib/active_record.rb
  5. +1 1  activerecord/lib/active_record/associations.rb
  6. +3 3 activerecord/lib/active_record/base.rb
  7. +127 0 activerecord/lib/active_record/connection_adapters/db2_adapter.rb
  8. +1 1  activerecord/lib/active_record/fixtures.rb
  9. +357 0 activerecord/lib/active_record/vendor/db2.rb
  10. +1 1  activerecord/test/associations_test.rb
  11. +3 3 activerecord/test/base_test.rb
  12. +24 0 activerecord/test/connections/native_db2/connection.rb
  13. +21 0 activerecord/test/fixtures/companies.yml
  14. +0 6 activerecord/test/fixtures/companies/first_client
  15. +0 4 activerecord/test/fixtures/companies/first_firm
  16. +0 6 activerecord/test/fixtures/companies/second_client
  17. +7 0 activerecord/test/fixtures/courses.yml
  18. +0 2  activerecord/test/fixtures/courses/java
  19. +0 2  activerecord/test/fixtures/courses/ruby
  20. +7 0 activerecord/test/fixtures/customers.yml
  21. +0 6 activerecord/test/fixtures/customers/david
  22. +112 0 activerecord/test/fixtures/db_definitions/db2.sql
  23. +4 0 activerecord/test/fixtures/db_definitions/db22.sql
  24. +13 0 activerecord/test/fixtures/developers_projects.yml
  25. +14 0 activerecord/test/fixtures/entrants.yml
  26. +0 3  activerecord/test/fixtures/entrants/first
  27. +0 3  activerecord/test/fixtures/entrants/second
  28. +0 3  activerecord/test/fixtures/entrants/third
  29. +7 0 activerecord/test/fixtures/movies.yml
  30. +0 2  activerecord/test/fixtures/movies/first
  31. +0 2  activerecord/test/fixtures/movies/second
  32. +7 0 activerecord/test/fixtures/projects.yml
  33. +0 2  activerecord/test/fixtures/projects/action_controller
  34. +0 2  activerecord/test/fixtures/projects/active_record
  35. +21 0 activerecord/test/fixtures/topics.yml
  36. +0 10 activerecord/test/fixtures/topics/first
  37. +0 8 activerecord/test/fixtures/topics/second
2  activerecord/CHANGELOG
... ... @@ -1,5 +1,7 @@
1 1 *SVN*
2 2
  3 +* Added a db2 adapter that only depends on the Ruby/DB2 bindings (http://raa.ruby-lang.org/project/ruby-db2/) #386 [Maik Schmidt]
  4 +
3 5 * Added the final touches to the Microsoft SQL Server adapter by DeLynn Berry that makes it suitable for actual use #394 [DeLynn Barry]
4 6
5 7 * Fixed a bug in the Ruby/MySQL that caused binary content to be escaped badly and come back mangled #405 [Tobias Luetke]
6 activerecord/Rakefile
@@ -51,6 +51,12 @@ Rake::TestTask.new("test_sqlserver") { |t|
51 51 t.verbose = true
52 52 }
53 53
  54 +Rake::TestTask.new("test_db2") { |t|
  55 + t.libs << "test" << "test/connections/native_db2"
  56 + t.pattern = 'test/*_test.rb'
  57 + t.verbose = true
  58 +}
  59 +
54 60 # Generate the RDoc documentation
55 61
56 62 Rake::RDocTask.new { |rdoc|
1  activerecord/install.rb
@@ -38,6 +38,7 @@
38 38 active_record/connection_adapters/mysql_adapter.rb
39 39 active_record/connection_adapters/postgresql_adapter.rb
40 40 active_record/connection_adapters/sqlite_adapter.rb
  41 + active_record/connection_adapters/db2_adapter.rb
41 42 active_record/deprecated_associations.rb
42 43 active_record/fixtures.rb
43 44 active_record/observer.rb
1  activerecord/lib/active_record.rb
@@ -58,3 +58,4 @@
58 58 require 'active_record/connection_adapters/postgresql_adapter'
59 59 require 'active_record/connection_adapters/sqlite_adapter'
60 60 require 'active_record/connection_adapters/sqlserver_adapter'
  61 +require 'active_record/connection_adapters/db2_adapter'
2  activerecord/lib/active_record/associations.rb
@@ -577,4 +577,4 @@ def require_association_class(class_name)
577 577 end
578 578 end
579 579 end
580   -end
  580 +end
6 activerecord/lib/active_record/base.rb
@@ -311,7 +311,7 @@ def find_first(conditions = nil, orderings = nil)
311 311 sql << "ORDER BY #{orderings} " unless orderings.nil?
312 312
313 313 connection.add_limit!(sql, 1)
314   -
  314 +
315 315 record = connection.select_one(sql, "#{name} Load First")
316 316 instantiate(record) unless record.nil?
317 317 end
@@ -919,7 +919,7 @@ def ensure_proper_type
919 919 # table with a master_id foreign key can instantiate master through Client#master.
920 920 def method_missing(method_id, *arguments)
921 921 method_name = method_id.id2name
922   -
  922 +
923 923 if method_name =~ read_method? && @attributes.include?($1)
924 924 return read_attribute($1)
925 925 elsif method_name =~ read_untyped_method? && @attributes.include?($1)
@@ -959,7 +959,7 @@ def read_attribute_before_type_cast(attr_name)
959 959
960 960 # Returns true if the attribute is of a text column and marked for serialization.
961 961 def unserializable_attribute?(attr_name, column)
962   - @attributes[attr_name] && column.send(:type) == :text && @attributes[attr_name].is_a?(String) && self.class.serialized_attributes[attr_name]
  962 + @attributes[attr_name] && [:text, :string].include?(column.send(:type)) && @attributes[attr_name].is_a?(String) && self.class.serialized_attributes[attr_name]
963 963 end
964 964
965 965 # Returns the unserialized object of the attribute.
127 activerecord/lib/active_record/connection_adapters/db2_adapter.rb
... ... @@ -0,0 +1,127 @@
  1 +# db2_adapter.rb
  2 +# author: Maik Schmidt <contact@maik-schmidt.de>
  3 +
  4 +require 'active_record/connection_adapters/abstract_adapter'
  5 +
  6 +begin
  7 + require 'db2/db2cli' unless self.class.const_defined?(:DB2CLI)
  8 + require 'active_record/vendor/db2'
  9 +
  10 + module ActiveRecord
  11 + class Base
  12 + # Establishes a connection to the database that's used by
  13 + # all Active Record objects
  14 + def self.db2_connection(config) # :nodoc:
  15 + symbolize_strings_in_hash(config)
  16 + usr = config[:username]
  17 + pwd = config[:password]
  18 +
  19 + if config.has_key?(:database)
  20 + database = config[:database]
  21 + else
  22 + raise ArgumentError, "No database specified. Missing argument: database."
  23 + end
  24 +
  25 + connection = DB2::Connection.new(DB2::Environment.new)
  26 + connection.connect(database, usr, pwd)
  27 + ConnectionAdapters::DB2Adapter.new(connection)
  28 + end
  29 + end
  30 +
  31 + module ConnectionAdapters
  32 + class DB2Adapter < AbstractAdapter # :nodoc:
  33 + def select_all(sql, name = nil)
  34 + select(sql, name)
  35 + end
  36 +
  37 + def select_one(sql, name = nil)
  38 + select(sql, name).first
  39 + end
  40 +
  41 + def insert(sql, name = nil, pk = nil, id_value = nil)
  42 + execute(sql, name = nil)
  43 + id_value || last_insert_id
  44 + end
  45 +
  46 + def execute(sql, name = nil)
  47 + rows_affected = 0
  48 + log(sql, name, @connection) do |connection|
  49 + stmt = DB2::Statement.new(connection)
  50 + stmt.exec_direct(sql)
  51 + rows_affected = stmt.row_count
  52 + stmt.free
  53 + end
  54 + rows_affected
  55 + end
  56 +
  57 + alias_method :update, :execute
  58 + alias_method :delete, :execute
  59 +
  60 + def begin_db_transaction
  61 + @connection.set_auto_commit_off
  62 + end
  63 +
  64 + def commit_db_transaction
  65 + @connection.commit
  66 + @connection.set_auto_commit_on
  67 + end
  68 +
  69 + def rollback_db_transaction
  70 + @connection.rollback
  71 + @connection.set_auto_commit_on
  72 + end
  73 +
  74 + def quote_column_name(name) name; end
  75 +
  76 + def quote_string(s)
  77 + s.gsub(/'/, "''") # ' (for ruby-mode)
  78 + end
  79 +
  80 + def add_limit!(sql, limit)
  81 + sql << " FETCH FIRST #{limit} ROWS ONLY"
  82 + end
  83 +
  84 + def columns(table_name, name = nil)
  85 + stmt = DB2::Statement.new(@connection)
  86 + result = []
  87 + stmt.columns(table_name.upcase).each do |c|
  88 + c_name = c[3].downcase
  89 + c_default = c[12] == 'NULL' ? nil : c[12]
  90 + c_type = c[5].downcase
  91 + c_type += "(#{c[6]})" if !c[6].nil? && c[6] != ''
  92 + result << Column.new(c_name, c_default, c_type)
  93 + end
  94 + stmt.free
  95 + result
  96 + end
  97 +
  98 + private
  99 +
  100 + def last_insert_id
  101 + row = select_one(<<-GETID.strip)
  102 + with temp(id) as (values (identity_val_local())) select * from temp
  103 + GETID
  104 + row['id'].to_i
  105 + end
  106 +
  107 + def select(sql, name = nil)
  108 + stmt = nil
  109 + log(sql, name, @connection) do |connection|
  110 + stmt = DB2::Statement.new(connection)
  111 + stmt.exec_direct(sql)
  112 + end
  113 +
  114 + rows = []
  115 + while row = stmt.fetch_as_hash
  116 + rows << row
  117 + end
  118 + stmt.free
  119 + rows
  120 + end
  121 + end
  122 + end
  123 + end
  124 +rescue LoadError
  125 + retry if require('rubygems') rescue LoadError
  126 + # DB2 driver is unavailable.
  127 +end
2  activerecord/lib/active_record/fixtures.rb
@@ -364,4 +364,4 @@ def fixture_table_names
364 364 end
365 365 end
366 366 end
367   -end
  367 +end
357 activerecord/lib/active_record/vendor/db2.rb
... ... @@ -0,0 +1,357 @@
  1 +require 'db2/db2cli.rb'
  2 +
  3 +module DB2
  4 + module DB2Util
  5 + include DB2CLI
  6 +
  7 + def free() SQLFreeHandle(@handle_type, @handle); end
  8 + def handle() @handle; end
  9 +
  10 + def check_rc(rc)
  11 + if rc != SQL_SUCCESS and rc != SQL_SUCCESS_WITH_INFO and rc != SQL_NO_DATA_FOUND
  12 + rec = 1
  13 + msg = ''
  14 + loop do
  15 + a = SQLGetDiagRec(@handle_type, @handle, rec, 500)
  16 + break if a[0] != SQL_SUCCESS
  17 + msg << a[3] if !a[3].nil? and a[3] != '' # Create message.
  18 + rec += 1
  19 + end
  20 + raise "DB2 error: #{msg}"
  21 + end
  22 + end
  23 + end
  24 +
  25 + class Environment
  26 + include DB2Util
  27 +
  28 + def initialize
  29 + @handle_type = SQL_HANDLE_ENV
  30 + rc, @handle = SQLAllocHandle(@handle_type, SQL_NULL_HANDLE)
  31 + check_rc(rc)
  32 + end
  33 +
  34 + def data_sources(buffer_length = 1024)
  35 + retval = []
  36 + max_buffer_length = buffer_length
  37 +
  38 + a = SQLDataSources(@handle, SQL_FETCH_FIRST, SQL_MAX_DSN_LENGTH + 1, buffer_length)
  39 + retval << [a[1], a[3]]
  40 + max_buffer_length = [max_buffer_length, a[4]].max
  41 +
  42 + loop do
  43 + a = SQLDataSources(@handle, SQL_FETCH_NEXT, SQL_MAX_DSN_LENGTH + 1, buffer_length)
  44 + break if a[0] == SQL_NO_DATA_FOUND
  45 +
  46 + retval << [a[1], a[3]]
  47 + max_buffer_length = [max_buffer_length, a[4]].max
  48 + end
  49 +
  50 + if max_buffer_length > buffer_length
  51 + get_data_sources(max_buffer_length)
  52 + else
  53 + retval
  54 + end
  55 + end
  56 + end
  57 +
  58 + class Connection
  59 + include DB2Util
  60 +
  61 + def initialize(environment)
  62 + @env = environment
  63 + @handle_type = SQL_HANDLE_DBC
  64 + rc, @handle = SQLAllocHandle(@handle_type, @env.handle)
  65 + check_rc(rc)
  66 + end
  67 +
  68 + def connect(server_name, user_name = '', auth = '')
  69 + check_rc(SQLConnect(@handle, server_name, user_name, auth))
  70 + end
  71 +
  72 + def set_connect_attr(attr, value)
  73 + value += "\0" if value.class == String
  74 + check_rc(SQLSetConnectAttr(@handle, attr, value))
  75 + end
  76 +
  77 + def set_auto_commit_on
  78 + set_connect_attr(SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON)
  79 + end
  80 +
  81 + def set_auto_commit_off
  82 + set_connect_attr(SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF)
  83 + end
  84 +
  85 + def disconnect
  86 + check_rc(SQLDisconnect(@handle))
  87 + end
  88 +
  89 + def rollback
  90 + check_rc(SQLEndTran(@handle_type, @handle, SQL_ROLLBACK))
  91 + end
  92 +
  93 + def commit
  94 + check_rc(SQLEndTran(@handle_type, @handle, SQL_COMMIT))
  95 + end
  96 + end
  97 +
  98 + class Statement
  99 + include DB2Util
  100 +
  101 + def initialize(connection)
  102 + @conn = connection
  103 + @handle_type = SQL_HANDLE_STMT
  104 + @parms = [] #yun
  105 + @sql = '' #yun
  106 + @numParms = 0 #yun
  107 + @prepared = false #yun
  108 + @parmArray = [] #yun. attributes of the parameter markers
  109 + rc, @handle = SQLAllocHandle(@handle_type, @conn.handle)
  110 + check_rc(rc)
  111 + end
  112 +
  113 + def columns(table_name)
  114 + check_rc(SQLColumns(@handle, "", "%", table_name, "%"))
  115 + fetch_all
  116 + end
  117 +
  118 + def tables
  119 + check_rc(SQLTables(@handle, "", "%", "%", "TABLE"))
  120 + fetch_all
  121 + end
  122 +
  123 + def prepare(sql)
  124 + @sql = sql
  125 + check_rc(SQLPrepare(@handle, sql))
  126 + rc, @numParms = SQLNumParams(@handle) #number of question marks
  127 + check_rc(rc)
  128 + #--------------------------------------------------------------------------
  129 + # parameter attributes are stored in instance variable @parmArray so that
  130 + # they are available when execute method is called.
  131 + #--------------------------------------------------------------------------
  132 + if @numParms > 0 # get parameter marker attributes
  133 + 1.upto(@numParms) do |i| # parameter number starts from 1
  134 + rc, type, size, decimalDigits = SQLDescribeParam(@handle, i)
  135 + check_rc(rc)
  136 + @parmArray << Parameter.new(type, size, decimalDigits)
  137 + end
  138 + end
  139 + @prepared = true
  140 + self
  141 + end
  142 +
  143 + def execute(*parms)
  144 + raise "The statement was not prepared" if @prepared == false
  145 +
  146 + if parms.size == 1 and parms[0].class == Array
  147 + parms = parms[0]
  148 + end
  149 +
  150 + if @numParms != parms.size
  151 + raise "Number of parameters supplied does not match with the SQL statement"
  152 + end
  153 +
  154 + if @numParms > 0 #need to bind parameters
  155 + #--------------------------------------------------------------------
  156 + #calling bindParms may not be safe. Look comment below.
  157 + #--------------------------------------------------------------------
  158 + #bindParms(parms)
  159 +
  160 + valueArray = []
  161 + 1.upto(@numParms) do |i| # parameter number starts from 1
  162 + type = @parmArray[i - 1].class
  163 + size = @parmArray[i - 1].size
  164 + decimalDigits = @parmArray[i - 1].decimalDigits
  165 +
  166 + if parms[i - 1].class == String
  167 + valueArray << parms[i - 1]
  168 + else
  169 + valueArray << parms[i - 1].to_s
  170 + end
  171 +
  172 + rc = SQLBindParameter(@handle, i, type, size, decimalDigits, valueArray[i - 1])
  173 + check_rc(rc)
  174 + end
  175 + end
  176 +
  177 + check_rc(SQLExecute(@handle))
  178 +
  179 + if @numParms != 0
  180 + check_rc(SQLFreeStmt(@handle, SQL_RESET_PARAMS)) # Reset parameters
  181 + end
  182 +
  183 + self
  184 + end
  185 +
  186 + #-------------------------------------------------------------------------------
  187 + # The last argument(value) to SQLBindParameter is a deferred argument, that is,
  188 + # it should be available when SQLExecute is called. Even though "value" is
  189 + # local to bindParms method, it seems that it is available when SQLExecute
  190 + # is called. I am not sure whether it would still work if garbage collection
  191 + # is done between bindParms call and SQLExecute call inside the execute method
  192 + # above.
  193 + #-------------------------------------------------------------------------------
  194 + def bindParms(parms) # This is the real thing. It uses SQLBindParms
  195 + 1.upto(@numParms) do |i| # parameter number starts from 1
  196 + rc, dataType, parmSize, decimalDigits = SQLDescribeParam(@handle, i)
  197 + check_rc(rc)
  198 + if parms[i - 1].class == String
  199 + value = parms[i - 1]
  200 + else
  201 + value = parms[i - 1].to_s
  202 + end
  203 + rc = SQLBindParameter(@handle, i, dataType, parmSize, decimalDigits, value)
  204 + check_rc(rc)
  205 + end
  206 + end
  207 +
  208 + #------------------------------------------------------------------------------
  209 + # bind method does not use DB2's SQLBindParams, but replaces "?" in the
  210 + # SQL statement with the value before passing the SQL statement to DB2.
  211 + # It is not efficient and can handle only strings since it puts everything in
  212 + # quotes.
  213 + #------------------------------------------------------------------------------
  214 + def bind(sql, args) #does not use SQLBindParams
  215 + arg_index = 0
  216 + result = ""
  217 + tokens(sql).each do |part|
  218 + case part
  219 + when '?'
  220 + result << "'" + (args[arg_index]) + "'" #put it into quotes
  221 + arg_index += 1
  222 + when '??'
  223 + result << "?"
  224 + else
  225 + result << part
  226 + end
  227 + end
  228 + if arg_index < args.size
  229 + raise "Too many SQL parameters"
  230 + elsif arg_index > args.size
  231 + raise "Not enough SQL parameters"
  232 + end
  233 + result
  234 + end
  235 +
  236 + ## Break the sql string into parts.
  237 + #
  238 + # This is NOT a full lexer for SQL. It just breaks up the SQL
  239 + # string enough so that question marks, double question marks and
  240 + # quoted strings are separated. This is used when binding
  241 + # arguments to "?" in the SQL string. Note: comments are not
  242 + # handled.
  243 + #
  244 + def tokens(sql)
  245 + toks = sql.scan(/('([^'\\]|''|\\.)*'|"([^"\\]|""|\\.)*"|\?\??|[^'"?]+)/)
  246 + toks.collect { |t| t[0] }
  247 + end
  248 +
  249 + def exec_direct(sql)
  250 + check_rc(SQLExecDirect(@handle, sql))
  251 + self
  252 + end
  253 +
  254 + def set_cursor_name(name)
  255 + check_rc(SQLSetCursorName(@handle, name))
  256 + self
  257 + end
  258 +
  259 + def get_cursor_name
  260 + rc, name = SQLGetCursorName(@handle)
  261 + check_rc(rc)
  262 + name
  263 + end
  264 +
  265 + def row_count
  266 + rc, rowcount = SQLRowCount(@handle)
  267 + check_rc(rc)
  268 + rowcount
  269 + end
  270 +
  271 + def num_result_cols
  272 + rc, cols = SQLNumResultCols(@handle)
  273 + check_rc(rc)
  274 + cols
  275 + end
  276 +
  277 + def fetch_all
  278 + if block_given?
  279 + while row = fetch do
  280 + yield row
  281 + end
  282 + else
  283 + res = []
  284 + while row = fetch do
  285 + res << row
  286 + end
  287 + res
  288 + end
  289 + end
  290 +
  291 + def fetch
  292 + cols = get_col_desc
  293 + rc = SQLFetch(@handle)
  294 + if rc == SQL_NO_DATA_FOUND
  295 + SQLFreeStmt(@handle, SQL_CLOSE) # Close cursor
  296 + SQLFreeStmt(@handle, SQL_RESET_PARAMS) # Reset parameters
  297 + return nil
  298 + end
  299 + raise "ERROR" unless rc == SQL_SUCCESS
  300 +
  301 + retval = []
  302 + cols.each_with_index do |c, i|
  303 + rc, content = SQLGetData(@handle, i + 1, c[1], c[2] + 1) #yun added 1 to c[2]
  304 + retval << adjust_content(content)
  305 + end
  306 + retval
  307 + end
  308 +
  309 + def fetch_as_hash
  310 + cols = get_col_desc
  311 + rc = SQLFetch(@handle)
  312 + if rc == SQL_NO_DATA_FOUND
  313 + SQLFreeStmt(@handle, SQL_CLOSE) # Close cursor
  314 + SQLFreeStmt(@handle, SQL_RESET_PARAMS) # Reset parameters
  315 + return nil
  316 + end
  317 + raise "ERROR" unless rc == SQL_SUCCESS
  318 +
  319 + retval = {}
  320 + cols.each_with_index do |c, i|
  321 + rc, content = SQLGetData(@handle, i + 1, c[1], c[2] + 1) #yun added 1 to c[2]
  322 + retval[c[0]] = adjust_content(content)
  323 + end
  324 + retval
  325 + end
  326 +
  327 + def get_col_desc
  328 + rc, nr_cols = SQLNumResultCols(@handle)
  329 + cols = (1..nr_cols).collect do |c|
  330 + rc, name, bl, type, col_sz = SQLDescribeCol(@handle, c, 1024)
  331 + [name.downcase, type, col_sz]
  332 + end
  333 + end
  334 +
  335 + def adjust_content(c)
  336 + case c.class.to_s
  337 + when 'DB2CLI::NullClass'
  338 + return nil
  339 + when 'DB2CLI::Time'
  340 + "%02d:%02d:%02d" % [c.hour, c.minute, c.second]
  341 + when 'DB2CLI::Date'
  342 + "%04d-%02d-%02d" % [c.year, c.month, c.day]
  343 + when 'DB2CLI::Timestamp'
  344 + "%04d-%02d-%02d %02d:%02d:%02d" % [c.year, c.month, c.day, c.hour, c.minute, c.second]
  345 + else
  346 + return c
  347 + end
  348 + end
  349 + end
  350 +
  351 + class Parameter
  352 + attr_reader :type, :size, :decimalDigits
  353 + def initialize(type, size, decimalDigits)
  354 + @type, @size, @decimalDigits = type, size, decimalDigits
  355 + end
  356 + end
  357 +end
2  activerecord/test/associations_test.rb
@@ -519,7 +519,7 @@ def test_deleting_all
519 519
520 520 def test_removing_associations_on_destroy
521 521 Developer.find(1).destroy
522   - assert Developer.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = '1'").empty?
  522 + assert Developer.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = 1").empty?
523 523 end
524 524
525 525 def test_additional_columns_from_join_table
6 activerecord/test/base_test.rb
@@ -119,7 +119,7 @@ def test_create_through_factory
119 119 def test_update
120 120 topic = Topic.new
121 121 topic.title = "Another New Topic"
122   - topic.written_on = "2003-12-12 23:23"
  122 + topic.written_on = "2003-12-12 23:23:00"
123 123 topic.save
124 124 id = topic.id
125 125 assert_equal(id, topic.id)
@@ -162,7 +162,7 @@ def test_preserving_time_objects
162 162 def test_destroy
163 163 topic = Topic.new
164 164 topic.title = "Yet Another New Topic"
165   - topic.written_on = "2003-12-12 23:23"
  165 + topic.written_on = "2003-12-12 23:23:00"
166 166 topic.save
167 167 id = topic.id
168 168 topic.destroy
@@ -585,4 +585,4 @@ def test_class_level_delete
585 585 assert_raises(ActiveRecord::RecordNotFound) { Topic.find(1) }
586 586 assert_nothing_raised { Reply.find(should_be_destroyed_reply.id) }
587 587 end
588   -end
  588 +end
24 activerecord/test/connections/native_db2/connection.rb
... ... @@ -0,0 +1,24 @@
  1 +print "Using native DB2\n"
  2 +require 'fixtures/course'
  3 +require 'logger'
  4 +
  5 +ActiveRecord::Base.logger = Logger.new("debug.log")
  6 +
  7 +db1 = 'arunit'
  8 +db2 = 'arunit2'
  9 +
  10 +ActiveRecord::Base.establish_connection(
  11 + :adapter => "db2",
  12 + :host => "localhost",
  13 + :username => "arunit",
  14 + :password => "arunit",
  15 + :database => db1
  16 +)
  17 +
  18 +Course.establish_connection(
  19 + :adapter => "db2",
  20 + :host => "localhost",
  21 + :username => "arunit2",
  22 + :password => "arunit2",
  23 + :database => db2
  24 +)
21 activerecord/test/fixtures/companies.yml
... ... @@ -0,0 +1,21 @@
  1 +first_client:
  2 + id: 2
  3 + type: Client
  4 + firm_id: 1
  5 + client_of: 2
  6 + name: Summit
  7 + ruby_type: Client
  8 +
  9 +first_firm:
  10 + id: 1
  11 + type: Firm
  12 + name: 37signals
  13 + ruby_type: Firm
  14 +
  15 +second_client:
  16 + id: 3
  17 + type: Client
  18 + firm_id: 1
  19 + client_of: 1
  20 + name: Microsoft
  21 + ruby_type: Client
6 activerecord/test/fixtures/companies/first_client
... ... @@ -1,6 +0,0 @@
1   -id => 2
2   -type => Client
3   -firm_id => 1
4   -client_of => 2
5   -name => Summit
6   -ruby_type => Client
4 activerecord/test/fixtures/companies/first_firm
... ... @@ -1,4 +0,0 @@
1   -id => 1
2   -type => Firm
3   -name => 37signals
4   -ruby_type => Firm
6 activerecord/test/fixtures/companies/second_client
... ... @@ -1,6 +0,0 @@
1   -id => 3
2   -type => Client
3   -firm_id => 1
4   -client_of => 1
5   -name => Microsoft
6   -ruby_type => Client
7 activerecord/test/fixtures/courses.yml
... ... @@ -0,0 +1,7 @@
  1 +java:
  2 + id: 2
  3 + name: Java Development
  4 +
  5 +ruby:
  6 + id: 1
  7 + name: Ruby Development
2  activerecord/test/fixtures/courses/java
... ... @@ -1,2 +0,0 @@
1   -id => 2
2   -name => Java Development
2  activerecord/test/fixtures/courses/ruby
... ... @@ -1,2 +0,0 @@
1   -id => 1
2   -name => Ruby Development
7 activerecord/test/fixtures/customers.yml
... ... @@ -0,0 +1,7 @@
  1 +david:
  2 + id: 1
  3 + name: David
  4 + balance: 50
  5 + address_street: Funny Street
  6 + address_city: Scary Town
  7 + address_country: Loony Land
6 activerecord/test/fixtures/customers/david
... ... @@ -1,6 +0,0 @@
1   -id => 1
2   -name => David
3   -balance => 50
4   -address_street => Funny Street
5   -address_city => Scary Town
6   -address_country => Loony Land
112 activerecord/test/fixtures/db_definitions/db2.sql
... ... @@ -0,0 +1,112 @@
  1 +CREATE TABLE accounts (
  2 + id int generated by default as identity (start with +10000),
  3 + firm_id int default NULL,
  4 + credit_limit int default NULL,
  5 + PRIMARY KEY (id)
  6 +);
  7 +
  8 +CREATE TABLE companies (
  9 + id int generated by default as identity (start with +10000),
  10 + type varchar(50) default NULL,
  11 + ruby_type varchar(50) default NULL,
  12 + firm_id int default NULL,
  13 + name varchar(50) default NULL,
  14 + client_of int default NULL,
  15 + rating int default 1,
  16 + PRIMARY KEY (id)
  17 +);
  18 +
  19 +CREATE TABLE topics (
  20 + id int generated by default as identity (start with +10000),
  21 + title varchar(255) default NULL,
  22 + author_name varchar(255) default NULL,
  23 + author_email_address varchar(255) default NULL,
  24 + written_on timestamp default NULL,
  25 + bonus_time time default NULL,
  26 + last_read date default NULL,
  27 + content varchar(3000),
  28 + approved smallint default 1,
  29 + replies_count int default 0,
  30 + parent_id int default NULL,
  31 + type varchar(50) default NULL,
  32 + PRIMARY KEY (id)
  33 +);
  34 +
  35 +CREATE TABLE developers (
  36 + id int generated by default as identity (start with +10000),
  37 + name varchar(100) default NULL,
  38 + salary int default 70000,
  39 + PRIMARY KEY (id)
  40 +);
  41 +
  42 +CREATE TABLE projects (
  43 + id int generated by default as identity (start with +10000),
  44 + name varchar(100) default NULL,
  45 + PRIMARY KEY (id)
  46 +);
  47 +
  48 +CREATE TABLE developers_projects (
  49 + developer_id int NOT NULL,
  50 + project_id int NOT NULL,
  51 + joined_on date default NULL
  52 +);
  53 +
  54 +CREATE TABLE customers (
  55 + id int generated by default as identity (start with +10000),
  56 + name varchar(100) default NULL,
  57 + balance int default 0,
  58 + address_street varchar(100) default NULL,
  59 + address_city varchar(100) default NULL,
  60 + address_country varchar(100) default NULL,
  61 + PRIMARY KEY (id)
  62 +);
  63 +
  64 +CREATE TABLE movies (
  65 + movieid int generated by default as identity (start with +10000),
  66 + name varchar(100) default NULL,
  67 + PRIMARY KEY (movieid)
  68 +);
  69 +
  70 +CREATE TABLE subscribers (
  71 + nick varchar(100) NOT NULL,
  72 + name varchar(100) default NULL,
  73 + PRIMARY KEY (nick)
  74 +);
  75 +
  76 +CREATE TABLE booleantests (
  77 + id int generated by default as identity (start with +10000),
  78 + value int default NULL,
  79 + PRIMARY KEY (id)
  80 +);
  81 +
  82 +CREATE TABLE auto_id_tests (
  83 + auto_id int generated by default as identity (start with +10000),
  84 + value int default NULL,
  85 + PRIMARY KEY (auto_id)
  86 +);
  87 +
  88 +CREATE TABLE entrants (
  89 + id int NOT NULL PRIMARY KEY,
  90 + name varchar(255) NOT NULL,
  91 + course_id int NOT NULL
  92 +);
  93 +
  94 +CREATE TABLE colnametests (
  95 + id int generated by default as identity (start with +10000),
  96 + references int NOT NULL,
  97 + PRIMARY KEY (id)
  98 +);
  99 +
  100 +CREATE TABLE mixins (
  101 + id int generated by default as identity (start with +10000),
  102 + parent_id int default NULL,
  103 + pos int default NULL,
  104 + created_at timestamp default NULL,
  105 + updated_at timestamp default NULL,
  106 + lft int default NULL,
  107 + rgt int default NULL,
  108 + root_id int default NULL,
  109 + type varchar(40) default NULL,
  110 + PRIMARY KEY (id)
  111 +);
  112 +
4 activerecord/test/fixtures/db_definitions/db22.sql
... ... @@ -0,0 +1,4 @@
  1 +CREATE TABLE courses (
  2 + id int NOT NULL PRIMARY KEY,
  3 + name varchar(255) NOT NULL
  4 +);
13 activerecord/test/fixtures/developers_projects.yml
... ... @@ -0,0 +1,13 @@
  1 +david_action_controller:
  2 + developer_id: 1
  3 + project_id: 2
  4 + joined_on: 2004-10-10
  5 +
  6 +david_active_record:
  7 + developer_id: 1
  8 + project_id: 1
  9 + joined_on: 2004-10-10
  10 +
  11 +jamis_active_record:
  12 + developer_id: 2
  13 + project_id: 1
14 activerecord/test/fixtures/entrants.yml
... ... @@ -0,0 +1,14 @@
  1 +first:
  2 + id: 1
  3 + course_id: 1
  4 + name: Ruby Developer
  5 +
  6 +second:
  7 + id: 2
  8 + course_id: 1
  9 + name: Ruby Guru
  10 +
  11 +third:
  12 + id: 3
  13 + course_id: 2
  14 + name: Java Lover
3  activerecord/test/fixtures/entrants/first
... ... @@ -1,3 +0,0 @@
1   -id => 1
2   -course_id => 1
3   -name => Ruby Developer
3  activerecord/test/fixtures/entrants/second
... ... @@ -1,3 +0,0 @@
1   -id => 2
2   -course_id => 1
3   -name => Ruby Guru
3  activerecord/test/fixtures/entrants/third
... ... @@ -1,3 +0,0 @@
1   -id => 3
2   -course_id => 2
3   -name => Java Lover
7 activerecord/test/fixtures/movies.yml
... ... @@ -0,0 +1,7 @@
  1 +first:
  2 + movieid: 1
  3 + name: Terminator
  4 +
  5 +second:
  6 + movieid: 2
  7 + name: Gladiator
2  activerecord/test/fixtures/movies/first
... ... @@ -1,2 +0,0 @@
1   -movieid => 1
2   -name => Terminator
2  activerecord/test/fixtures/movies/second
... ... @@ -1,2 +0,0 @@
1   -movieid => 2
2   -name => Gladiator
7 activerecord/test/fixtures/projects.yml
... ... @@ -0,0 +1,7 @@
  1 +action_controller:
  2 + id: 2
  3 + name: Active Controller
  4 +
  5 +active_record:
  6 + id: 1
  7 + name: Active Record
2  activerecord/test/fixtures/projects/action_controller
... ... @@ -1,2 +0,0 @@
1   -id => 2
2   -name => Active Controller
2  activerecord/test/fixtures/projects/active_record
... ... @@ -1,2 +0,0 @@
1   -id => 1
2   -name => Active Record
21 activerecord/test/fixtures/topics.yml
... ... @@ -0,0 +1,21 @@
  1 +first:
  2 + id: 1
  3 + title: The First Topic
  4 + author_name: David
  5 + author_email_address: david@loudthinking.com
  6 + written_on: 2003-07-16 15:28:00
  7 + bonus_time: 12:13:14
  8 + last_read: 2004-04-15
  9 + content: Have a nice day
  10 + approved: 0
  11 + replies_count: 0
  12 +
  13 +second:
  14 + id: 2
  15 + title: The Second Topic's of the day
  16 + author_name: Mary
  17 + written_on: 2003-07-15 15:28:00
  18 + content: Have a great day!
  19 + approved: 1
  20 + replies_count: 2
  21 + parent_id: 1
10 activerecord/test/fixtures/topics/first
... ... @@ -1,10 +0,0 @@
1   -id => 1
2   -title => The First Topic
3   -author_name => David
4   -author_email_address => david@loudthinking.com
5   -written_on => 2003-07-16 15:28
6   -bonus_time => 12:13:14
7   -last_read => 2004-04-15
8   -content => Have a nice day
9   -approved => 0
10   -replies_count => 0
8 activerecord/test/fixtures/topics/second
... ... @@ -1,8 +0,0 @@
1   -id => 2
2   -title => The Second Topic's of the day
3   -author_name => Mary
4   -written_on => 2003-07-15 15:28
5   -content => Have a great day!
6   -approved => 1
7   -replies_count => 2
8   -parent_id => 1

0 comments on commit daf3e92

Please sign in to comment.
Something went wrong with that request. Please try again.