rails-sqlserver-2000-2005-adapter 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,66 @@
1
+ require 'cases/sqlserver_helper'
2
+ require 'models/binary'
3
+
4
+ class ColumnTestSqlserver < ActiveRecord::TestCase
5
+
6
+ def setup
7
+ @column_klass = ActiveRecord::ConnectionAdapters::SQLServerColumn
8
+ end
9
+
10
+ should 'return real_number as float' do
11
+ assert_equal :float, TableWithRealColumn.columns_hash["real_number"].type
12
+ end
13
+
14
+ should 'know its #table_name and #table_klass' do
15
+ Topic.columns.each do |column|
16
+ assert_equal 'topics', column.table_name, "This column #{column.inspect} did not know it's #table_name"
17
+ assert_equal Topic, column.table_klass, "This column #{column.inspect} did not know it's #table_klass"
18
+ end
19
+ end
20
+
21
+ context 'For :binary columns' do
22
+
23
+ setup do
24
+ @binary_string = "GIF89a\001\000\001\000\200\000\000\377\377\377\000\000\000!\371\004\000\000\000\000\000,\000\000\000\000\001\000\001\000\000\002\002D\001\000;"
25
+ @saved_bdata = Binary.create!(:data => @binary_string)
26
+ end
27
+
28
+ should 'read and write binary data equally' do
29
+ assert_equal @binary_string, Binary.find(@saved_bdata).data
30
+ end
31
+
32
+ should 'quote data for sqlserver with literal 0x prefix' do
33
+ # See the output of the stored procedure: 'exec sp_datatype_info'
34
+ sqlserver_encoded_bdata = "0x47494638396101000100800000ffffff00000021f90400000000002c00000000010001000002024401003b"
35
+ assert_equal sqlserver_encoded_bdata, @column_klass.string_to_binary(@binary_string)
36
+ end
37
+
38
+ end
39
+
40
+ context 'For .columns method' do
41
+
42
+ should 'return correct scales and precisions for NumericData' do
43
+ bank_balance = NumericData.columns_hash['bank_balance']
44
+ big_bank_balance = NumericData.columns_hash['big_bank_balance']
45
+ world_population = NumericData.columns_hash['world_population']
46
+ my_house_population = NumericData.columns_hash['my_house_population']
47
+ assert_equal [2,10], [bank_balance.scale, bank_balance.precision]
48
+ assert_equal [2,15], [big_bank_balance.scale, big_bank_balance.precision]
49
+ assert_equal [0,10], [world_population.scale, world_population.precision]
50
+ assert_equal [0,2], [my_house_population.scale, my_house_population.precision]
51
+ end
52
+
53
+ should 'return correct null, limit, and default for Topic' do
54
+ tch = Topic.columns_hash
55
+ assert_equal false, tch['id'].null
56
+ assert_equal true, tch['title'].null
57
+ assert_equal 255, tch['author_name'].limit
58
+ assert_equal true, tch['approved'].default
59
+ assert_equal 0, tch['replies_count'].default
60
+ end
61
+
62
+ end
63
+
64
+
65
+
66
+ end
@@ -0,0 +1,103 @@
1
+ require 'cases/sqlserver_helper'
2
+ require 'models/reply'
3
+
4
+ class ConnectionTestSqlserver < ActiveRecord::TestCase
5
+
6
+ self.use_transactional_fixtures = false
7
+
8
+ fixtures :topics, :accounts
9
+
10
+ def setup
11
+ @connection = ActiveRecord::Base.connection
12
+ end
13
+
14
+
15
+ should 'return finished DBI statment handle from #execute without block' do
16
+ handle = @connection.execute('SELECT * FROM [topics]')
17
+ assert_instance_of DBI::StatementHandle, handle
18
+ assert handle.finished?
19
+ end
20
+
21
+ should 'finish DBI statment handle from #execute with block' do
22
+ assert_all_statements_used_are_closed do
23
+ @connection.execute('SELECT * FROM [topics]') { }
24
+ end
25
+ end
26
+
27
+ should 'return an unfinished DBI statement handler from #raw_execute' do
28
+ handle = @connection.send(:raw_execute,'SELECT * FROM [topics]')
29
+ assert_instance_of DBI::StatementHandle, handle
30
+ assert !handle.finished?
31
+ end
32
+
33
+ should 'finish connection from #raw_select' do
34
+ assert_all_statements_used_are_closed do
35
+ @connection.send(:raw_select,'SELECT * FROM [topics]')
36
+ end
37
+ end
38
+
39
+ should 'affect rows' do
40
+ assert Topic.connection.instance_variable_get("@connection")["AutoCommit"]
41
+ topic_data = { 1 => { "content" => "1 updated" }, 2 => { "content" => "2 updated" } }
42
+ updated = Topic.update(topic_data.keys, topic_data.values)
43
+ assert_equal 2, updated.size
44
+ assert_equal "1 updated", Topic.find(1).content
45
+ assert_equal "2 updated", Topic.find(2).content
46
+ assert_equal 2, Topic.delete([1, 2])
47
+ end
48
+
49
+ should 'execute without block closes statement' do
50
+ assert_all_statements_used_are_closed do
51
+ @connection.execute("SELECT 1")
52
+ end
53
+ end
54
+
55
+ should 'execute with block closes statement' do
56
+ assert_all_statements_used_are_closed do
57
+ @connection.execute("SELECT 1") do |sth|
58
+ assert !sth.finished?, "Statement should still be alive within block"
59
+ end
60
+ end
61
+ end
62
+
63
+ should 'insert with identity closes statement' do
64
+ assert_all_statements_used_are_closed do
65
+ @connection.insert("INSERT INTO accounts ([id], [firm_id],[credit_limit]) values (999, 1, 50)")
66
+ end
67
+ end
68
+
69
+ should 'insert without identity closes statement' do
70
+ assert_all_statements_used_are_closed do
71
+ @connection.insert("INSERT INTO accounts ([firm_id],[credit_limit]) values (1, 50)")
72
+ end
73
+ end
74
+
75
+ should 'active closes statement' do
76
+ assert_all_statements_used_are_closed do
77
+ @connection.active?
78
+ end
79
+ end
80
+
81
+
82
+ private
83
+
84
+ def assert_all_statements_used_are_closed(&block)
85
+ existing_handles = []
86
+ ObjectSpace.each_object(DBI::StatementHandle) {|handle| existing_handles << handle}
87
+ GC.disable
88
+ yield
89
+ used_handles = []
90
+ ObjectSpace.each_object(DBI::StatementHandle) {|handle| used_handles << handle unless existing_handles.include? handle}
91
+ assert_block "No statements were used within given block" do
92
+ used_handles.size > 0
93
+ end
94
+ ObjectSpace.each_object(DBI::StatementHandle) do |handle|
95
+ assert_block "Statement should have been closed within given block" do
96
+ handle.finished?
97
+ end
98
+ end
99
+ ensure
100
+ GC.enable
101
+ end
102
+
103
+ end
@@ -0,0 +1,22 @@
1
+ require 'cases/sqlserver_helper'
2
+ require 'models/author'
3
+ require 'models/post'
4
+ require 'models/comment'
5
+
6
+ class EagerAssociationTestSqlserver < ActiveRecord::TestCase
7
+ end
8
+
9
+ class EagerAssociationTest < ActiveRecord::TestCase
10
+
11
+ COERCED_TESTS = [:test_count_with_include]
12
+
13
+ include SqlserverCoercedTest
14
+
15
+ fixtures :authors, :posts, :comments
16
+
17
+ def test_coerced_test_count_with_include
18
+ assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "len(comments.body) > 15")
19
+ end
20
+
21
+
22
+ end
@@ -0,0 +1,28 @@
1
+ require 'cases/sqlserver_helper'
2
+ require 'models/company'
3
+
4
+ class InheritanceTestSqlserver < ActiveRecord::TestCase
5
+ end
6
+
7
+ class InheritanceTest < ActiveRecord::TestCase
8
+
9
+ COERCED_TESTS = [
10
+ :test_eager_load_belongs_to_primary_key_quoting,
11
+ :test_a_bad_type_column
12
+ ]
13
+
14
+ include SqlserverCoercedTest
15
+
16
+ def test_coerced_test_eager_load_belongs_to_primary_key_quoting
17
+ assert_sql(/\(\[companies\].\[id\] = 1\)/) do
18
+ Account.find(1, :include => :firm)
19
+ end
20
+ end
21
+
22
+ def test_coerced_test_a_bad_type_column
23
+ Company.connection.insert "INSERT INTO [companies] ([id], #{QUOTED_TYPE}, [name]) VALUES(100, 'bad_class!', 'Not happening')"
24
+ assert_raises(ActiveRecord::SubclassNotFound) { Company.find(100) }
25
+ end
26
+
27
+
28
+ end
@@ -0,0 +1,57 @@
1
+ require 'cases/sqlserver_helper'
2
+ require 'models/person'
3
+
4
+ class MigrationTestSqlserver < ActiveRecord::TestCase
5
+
6
+ context 'For transactions' do
7
+
8
+ setup do
9
+ @connection = ActiveRecord::Base.connection
10
+ @trans_test_table1 = 'sqlserver_trans_table1'
11
+ @trans_test_table2 = 'sqlserver_trans_table2'
12
+ @trans_tables = [@trans_test_table1,@trans_test_table2]
13
+ end
14
+
15
+ teardown do
16
+ @trans_tables.each do |table_name|
17
+ ActiveRecord::Migration.drop_table(table_name) if @connection.tables.include?(table_name)
18
+ end
19
+ end
20
+
21
+ should 'not create a tables if error in migrations' do
22
+ begin
23
+ ActiveRecord::Migrator.up(SQLSERVER_MIGRATIONS_ROOT+'/transaction_table')
24
+ rescue Exception => e
25
+ assert_match %r|this and all later migrations canceled|, e.message
26
+ end
27
+ assert_does_not_contain @trans_test_table1, @connection.tables
28
+ assert_does_not_contain @trans_test_table2, @connection.tables
29
+ end
30
+
31
+ end
32
+
33
+
34
+ end
35
+
36
+
37
+ class MigrationTest < ActiveRecord::TestCase
38
+
39
+ COERCED_TESTS = [:test_add_column_not_null_without_default]
40
+
41
+ include SqlserverCoercedTest
42
+
43
+
44
+ def test_coerced_test_add_column_not_null_without_default
45
+ Person.connection.create_table :testings do |t|
46
+ t.column :foo, :string
47
+ t.column :bar, :string, :null => false
48
+ end
49
+ assert_raises(ActiveRecord::StatementInvalid) do
50
+ Person.connection.execute "INSERT INTO [testings] ([foo], [bar]) VALUES ('hello', NULL)"
51
+ end
52
+ ensure
53
+ Person.connection.drop_table :testings rescue nil
54
+ end
55
+
56
+
57
+ end
@@ -0,0 +1,82 @@
1
+ require 'cases/sqlserver_helper'
2
+ require 'models/book'
3
+
4
+ class OffsetAndLimitTestSqlserver < ActiveRecord::TestCase
5
+
6
+ class Account < ActiveRecord::Base; end
7
+
8
+ def setup
9
+ @connection = ActiveRecord::Base.connection
10
+ end
11
+
12
+ context 'When selecting with limit' do
13
+
14
+ setup do
15
+ @select_sql = 'SELECT * FROM schema'
16
+ end
17
+
18
+ should 'alter SQL to limit number of records returned' do
19
+ options = { :limit => 10 }
20
+ assert_equal('SELECT TOP 10 * FROM schema', @connection.add_limit_offset!(@select_sql, options))
21
+ end
22
+
23
+ should 'only allow integers for limit' do
24
+ options = { :limit => 'ten' }
25
+ assert_raise(ArgumentError) {@connection.add_limit_offset!(@select_sql, options) }
26
+ end
27
+
28
+ should 'convert strings which look like integers to integers' do
29
+ options = { :limit => '42' }
30
+ assert_nothing_raised(ArgumentError) {@connection.add_limit_offset!(@select_sql, options)}
31
+ end
32
+
33
+ should 'not allow sql injection via limit' do
34
+ options = { :limit => '1 * FROM schema; DELETE * FROM table; SELECT TOP 10 *'}
35
+ assert_raise(ArgumentError) { @connection.add_limit_offset!(@select_sql, options) }
36
+ end
37
+
38
+ end
39
+
40
+ context 'When selecting with limit and offset' do
41
+
42
+ setup do
43
+ @select_sql = 'SELECT * FROM books'
44
+ @books = (1..10).map {|i| Book.create!}
45
+ end
46
+
47
+ teardown do
48
+ @books.each {|b| b.destroy}
49
+ end
50
+
51
+ should 'have limit if offset is passed' do
52
+ options = { :offset => 1 }
53
+ assert_raise(ArgumentError) { @connection.add_limit_offset!(@select_sql, options) }
54
+ end
55
+
56
+ should 'only allow integers for offset' do
57
+ options = { :limit => 10, :offset => 'five' }
58
+ assert_raise(ArgumentError) { @connection.add_limit_offset!(@select_sql, options)}
59
+ end
60
+
61
+ should 'convert strings which look like integers to integers' do
62
+ options = { :limit => 10, :offset => '5' }
63
+ assert_nothing_raised(ArgumentError) {@connection.add_limit_offset!(@select_sql, options)}
64
+ end
65
+
66
+ should 'alter SQL to limit number of records returned offset by specified amount' do
67
+ options = { :limit => 3, :offset => 5 }
68
+ expected_sql = %&SELECT * FROM (SELECT TOP 3 * FROM (SELECT TOP 8 * FROM books) AS tmp1) AS tmp2&
69
+ assert_equal(expected_sql, @connection.add_limit_offset!(@select_sql, options))
70
+ end
71
+
72
+ # Not really sure what an offset sql injection might look like
73
+ should 'not allow sql injection via offset' do
74
+ options = { :limit => 10, :offset => '1 * FROM schema; DELETE * FROM table; SELECT TOP 10 *'}
75
+ assert_raise(ArgumentError) { @connection.add_limit_offset!(@select_sql, options) }
76
+ end
77
+
78
+ end
79
+
80
+
81
+ end
82
+
@@ -0,0 +1,100 @@
1
+ require 'cases/sqlserver_helper'
2
+ require 'models/person'
3
+ require 'models/reader'
4
+
5
+ class PessimisticLockingTestSqlserver < ActiveRecord::TestCase
6
+
7
+ self.use_transactional_fixtures = false
8
+ fixtures :people, :readers
9
+
10
+ def setup
11
+ Person.columns; Reader.columns # Avoid introspection queries during tests.
12
+ end
13
+
14
+ context 'For simple finds with default lock option' do
15
+
16
+ should 'lock with simple find' do
17
+ assert_nothing_raised do
18
+ Person.transaction do
19
+ Person.find 1, :lock => true
20
+ end
21
+ end
22
+ end
23
+
24
+ should 'lock with scoped find' do
25
+ assert_nothing_raised do
26
+ Person.transaction do
27
+ Person.with_scope(:find => { :lock => true }) do
28
+ Person.find 1
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ should 'lock with eager find' do
35
+ assert_nothing_raised do
36
+ Person.transaction do
37
+ Person.find 1, :include => :readers, :lock => true
38
+ end
39
+ end
40
+ end
41
+
42
+ should 'reload with lock when #lock! called' do
43
+ assert_nothing_raised do
44
+ Person.transaction do
45
+ person = Person.find 1
46
+ old, person.first_name = person.first_name, 'fooman'
47
+ person.lock!
48
+ assert_equal old, person.first_name
49
+ end
50
+ end
51
+ end
52
+
53
+ end
54
+
55
+ context 'For dueling concurrent connections' do
56
+
57
+ use_concurrent_connections
58
+
59
+ should 'no locks does not wait' do
60
+ first, second = duel { Person.find 1 }
61
+ assert first.end > second.end
62
+ end
63
+
64
+ should 'that second lock waits' do
65
+ assert [0.2, 1, 5].any? { |zzz|
66
+ first, second = duel(zzz) { Person.find 1, :lock => true }
67
+ second.end > first.end
68
+ }
69
+ end
70
+
71
+ end
72
+
73
+
74
+ protected
75
+
76
+ def duel(zzz = 5)
77
+ t0, t1, t2, t3 = nil, nil, nil, nil
78
+ a = Thread.new do
79
+ t0 = Time.now
80
+ Person.transaction do
81
+ yield
82
+ sleep zzz # block thread 2 for zzz seconds
83
+ end
84
+ t1 = Time.now
85
+ end
86
+ b = Thread.new do
87
+ sleep zzz / 2.0 # ensure thread 1 tx starts first
88
+ t2 = Time.now
89
+ Person.transaction { yield }
90
+ t3 = Time.now
91
+ end
92
+ a.join
93
+ b.join
94
+ assert t1 > t0 + zzz
95
+ assert t2 > t0
96
+ assert t3 > t2
97
+ [t0.to_f..t1.to_f, t2.to_f..t3.to_f]
98
+ end
99
+
100
+ end
@@ -0,0 +1,24 @@
1
+ require 'cases/sqlserver_helper'
2
+ require 'models/task'
3
+
4
+ class QueryCacheTestSqlserver < ActiveRecord::TestCase
5
+ end
6
+
7
+ class QueryCacheTest < ActiveRecord::TestCase
8
+
9
+ COERCED_TESTS = [:test_cache_does_not_wrap_string_results_in_arrays]
10
+
11
+ include SqlserverCoercedTest
12
+
13
+ fixtures :tasks
14
+
15
+
16
+ def test_coerced_test_cache_does_not_wrap_string_results_in_arrays
17
+ Task.cache do
18
+ assert_instance_of Fixnum, Task.connection.select_value("SELECT count(*) AS count_all FROM tasks")
19
+ end
20
+ end
21
+
22
+ end
23
+
24
+
@@ -0,0 +1,40 @@
1
+ require 'cases/sqlserver_helper'
2
+
3
+ class SchemaDumperTestSqlserver < ActiveRecord::TestCase
4
+
5
+ context 'In schema dump' do
6
+
7
+ should 'include limit constraint for integer columns' do
8
+ output = standard_dump(/^(?!integer_limits)/)
9
+ assert_match %r{c_int_1.*:limit => 2}, output
10
+ assert_match %r{c_int_2.*:limit => 2}, output
11
+ assert_match %r{c_int_3.*}, output
12
+ assert_match %r{c_int_4.*}, output
13
+ assert_no_match %r{c_int_3.*:limit}, output
14
+ assert_no_match %r{c_int_4.*:limit}, output
15
+ assert_match %r{c_int_5.*:limit => 8}, output
16
+ assert_match %r{c_int_6.*:limit => 8}, output
17
+ assert_match %r{c_int_7.*:limit => 8}, output
18
+ assert_match %r{c_int_8.*:limit => 8}, output
19
+ end
20
+
21
+ should 'honor nonstandard primary keys' do
22
+ output = standard_dump
23
+ match = output.match(%r{create_table "movies"(.*)do})
24
+ assert_not_nil(match, "nonstandardpk table not found")
25
+ assert_match %r(:primary_key => "movieid"), match[1], "non-standard primary key not preserved"
26
+ end
27
+
28
+ end
29
+
30
+
31
+ private
32
+
33
+ def standard_dump(ignore_tables = [])
34
+ stream = StringIO.new
35
+ ActiveRecord::SchemaDumper.ignore_tables = [*ignore_tables]
36
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
37
+ stream.string
38
+ end
39
+
40
+ end
@@ -0,0 +1,25 @@
1
+ require 'cases/sqlserver_helper'
2
+
3
+ class StringDefault < ActiveRecord::Base; end;
4
+
5
+ class SpecificSchemaTestSqlserver < ActiveRecord::TestCase
6
+
7
+ should 'default strings before save' do
8
+ default = StringDefault.new
9
+ assert_equal nil, default.string_with_null_default
10
+ assert_equal 'null', default.string_with_pretend_null_one
11
+ assert_equal '(null)', default.string_with_pretend_null_two
12
+ assert_equal 'NULL', default.string_with_pretend_null_three
13
+ assert_equal '(NULL)', default.string_with_pretend_null_four
14
+ end
15
+
16
+ should 'default strings after save' do
17
+ default = StringDefault.create
18
+ assert_equal nil, default.string_with_null_default
19
+ assert_equal 'null', default.string_with_pretend_null_one
20
+ assert_equal '(null)', default.string_with_pretend_null_two
21
+ assert_equal 'NULL', default.string_with_pretend_null_three
22
+ assert_equal '(NULL)', default.string_with_pretend_null_four
23
+ end
24
+
25
+ end
@@ -0,0 +1,88 @@
1
+ require 'rubygems'
2
+ require 'shoulda'
3
+ require 'mocha'
4
+ require 'cases/helper'
5
+ require 'models/topic'
6
+
7
+ SQLSERVER_TEST_ROOT = File.expand_path(File.join(File.dirname(__FILE__),'..'))
8
+ SQLSERVER_ASSETS_ROOT = SQLSERVER_TEST_ROOT + "/assets"
9
+ SQLSERVER_FIXTURES_ROOT = SQLSERVER_TEST_ROOT + "/fixtures"
10
+ SQLSERVER_MIGRATIONS_ROOT = SQLSERVER_TEST_ROOT + "/migrations"
11
+ SQLSERVER_SCHEMA_ROOT = SQLSERVER_TEST_ROOT + "/schema"
12
+ ACTIVERECORD_TEST_ROOT = File.expand_path(SQLSERVER_TEST_ROOT + "/../../../../rails/activerecord/test/")
13
+
14
+ ActiveRecord::Migration.verbose = false
15
+
16
+ # Defining our classes in one place as well as soem core tests that need coercing date/time types.
17
+
18
+ class TableWithRealColumn < ActiveRecord::Base; end
19
+ class FkTestHasFk < ActiveRecord::Base ; end
20
+ class FkTestHasPk < ActiveRecord::Base ; end
21
+ class NumericData < ActiveRecord::Base ; self.table_name = 'numeric_data' ; end
22
+ class SqlServerChronic < ActiveRecord::Base
23
+ coerce_sqlserver_date :date
24
+ coerce_sqlserver_time :time
25
+ default_timezone = :utc
26
+ end
27
+ class Topic < ActiveRecord::Base
28
+ coerce_sqlserver_date :last_read
29
+ coerce_sqlserver_time :bonus_time
30
+ end
31
+ class Person < ActiveRecord::Base
32
+ coerce_sqlserver_date :favorite_day
33
+ end
34
+
35
+ # A module that we can include in classes where we want to override an active record test.
36
+
37
+ module SqlserverCoercedTest
38
+ def self.included(base)
39
+ base.extend ClassMethods
40
+ end
41
+ module ClassMethods
42
+ def coerced_tests
43
+ self.const_get(:COERCED_TESTS) rescue nil
44
+ end
45
+ def method_added(method)
46
+ undef_method(method) if coerced_tests && coerced_tests.include?(method)
47
+ end
48
+ end
49
+ end
50
+
51
+ # Change the text database type to support ActiveRecord's tests for = on text columns which
52
+ # is not supported in SQL Server text columns, so use varchar(8000) instead.
53
+
54
+ if ActiveRecord::Base.connection.sqlserver_2000?
55
+ ActiveRecord::ConnectionAdapters::SQLServerAdapter.native_text_database_type = 'varchar(8000)'
56
+ end
57
+
58
+ # Our changes/additions to ActiveRecord test helpers specific for SQL Server.
59
+
60
+ ActiveRecord::Base.connection.class.class_eval do
61
+ IGNORED_SQL << /SELECT SCOPE_IDENTITY/ << /INFORMATION_SCHEMA.TABLES/ << /INFORMATION_SCHEMA.COLUMNS/
62
+ end
63
+
64
+ ActiveRecord::ConnectionAdapters::SQLServerAdapter.class_eval do
65
+ def raw_select_with_query_record(sql, name = nil)
66
+ $queries_executed ||= []
67
+ $queries_executed << sql unless IGNORED_SQL.any? { |r| sql =~ r }
68
+ raw_select_without_query_record(sql,name)
69
+ end
70
+ alias_method_chain :raw_select, :query_record
71
+ end
72
+
73
+ module ActiveRecord
74
+ class TestCase < ActiveSupport::TestCase
75
+ def assert_sql(*patterns_to_match)
76
+ $queries_executed = []
77
+ yield
78
+ ensure
79
+ failed_patterns = []
80
+ patterns_to_match.each do |pattern|
81
+ failed_patterns << pattern unless $queries_executed.any?{ |sql| pattern === sql }
82
+ end
83
+ assert failed_patterns.empty?, "Query pattern(s) #{failed_patterns.map(&:inspect).join(', ')} not found in:\n#{$queries_executed.inspect}"
84
+ end
85
+ end
86
+ end
87
+
88
+
@@ -0,0 +1,23 @@
1
+ print "Using native SQLServer\n"
2
+ require_dependency 'models/course'
3
+ require 'logger'
4
+
5
+ ActiveRecord::Base.logger = Logger.new("debug.log")
6
+
7
+ ActiveRecord::Base.configurations = {
8
+ 'arunit' => {
9
+ :adapter => 'sqlserver',
10
+ :host => 'localhost',
11
+ :username => 'rails',
12
+ :database => 'activerecord_unittest'
13
+ },
14
+ 'arunit2' => {
15
+ :adapter => 'sqlserver',
16
+ :host => 'localhost',
17
+ :username => 'rails',
18
+ :database => 'activerecord_unittest2'
19
+ }
20
+ }
21
+
22
+ ActiveRecord::Base.establish_connection 'arunit'
23
+ Course.establish_connection 'arunit2'
@@ -0,0 +1,25 @@
1
+ print "Using native SQLServer via ODBC\n"
2
+ require_dependency 'models/course'
3
+ require 'logger'
4
+
5
+ ActiveRecord::Base.logger = Logger.new("debug.log")
6
+
7
+ ActiveRecord::Base.configurations = {
8
+ 'arunit' => {
9
+ :adapter => 'sqlserver',
10
+ :mode => 'ODBC',
11
+ :host => 'localhost',
12
+ :username => 'rails',
13
+ :dsn => 'activerecord_unittest'
14
+ },
15
+ 'arunit2' => {
16
+ :adapter => 'sqlserver',
17
+ :mode => 'ODBC',
18
+ :host => 'localhost',
19
+ :username => 'rails',
20
+ :dsn => 'activerecord_unittest2'
21
+ }
22
+ }
23
+
24
+ ActiveRecord::Base.establish_connection 'arunit'
25
+ Course.establish_connection 'arunit2'