rails-sqlserver-2000-2005-adapter 2.2.13 → 2.2.14

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.
data/CHANGELOG CHANGED
@@ -1,7 +1,38 @@
1
1
 
2
2
  MASTER
3
3
 
4
- *
4
+ *
5
+
6
+
7
+ * 2.2.14 * (March 17th, 2009)
8
+
9
+ * Rails2.3 - Back passing tests on 2.2 work. Includes: (1) Created new test helpers that check ActiveRecord
10
+ version strings so we can conditionally run 2.2 and 2.3 tests. (2) Making TransactionTestSqlserver use Ship vs
11
+ Bird model. Also made it conditional run a few blocks for different versions of ActiveRecord. (3) Previous
12
+ JoinDependency#aliased_table_name_for is now only patched in ActiveRecord equal or greater than 2.3. [Ken Collins]
13
+
14
+ * Rails2.3 - Implement new savepoint support [Ken Collins]
15
+ http://rails.lighthouseapp.com/projects/8994/tickets/383
16
+ http://www.codeproject.com/KB/database/sqlservertransactions.aspx
17
+
18
+ * Rails2.3 - Coerce NestedScopingTest#test_merged_scoped_find to use correct regexp for adapter. [Ken Collins]
19
+
20
+ * Rails2.3 - Implement a custom ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation#aliased_table_name_for
21
+ method that uses a Regexp.escape so that table/column quoting does not get ignored. [Ken Collins]
22
+
23
+ * Rails2.3 - Implement #outside_transaction? and a new transaction test case to test some SQL Server
24
+ basic support while implementing this method. Future home of some savepoint tests too. [Ken Collins]
25
+
26
+ * Rails2.3 - Coerced tests that ensure hash conditions on referenced tables are considered when eager
27
+ loading with limit/offset. Information on these changes and the ticket in rails are.
28
+ http://github.com/rails/rails/commit/9a4d557713acb0fc8e80f61af18094034aca029a
29
+ http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/1404-conditions_tables-doesnt-understand-condition-hashes
30
+
31
+ * Rails2.3 - Add coerced tests for true/false attributes in selects use SQL Server case statement. [Ken Collins]
32
+
33
+ * Making sure that smalldatetime types are OK to use. Also fixed a bug in the #view_information method that
34
+ checks to see if a view definition is equal to 4000 chars, meaning that it is most likely truncated and
35
+ needs to use the backup method of sp_helptext to get it's view definition. [Ken Collins]
5
36
 
6
37
 
7
38
  * 2.2.13 * (February 10th, 2009)
data/README.rdoc CHANGED
@@ -6,6 +6,7 @@ The SQL Server adapter for rails is back for ActiveRecord 2.2 and up! We are cur
6
6
 
7
7
  == What's New
8
8
 
9
+ * Now supports both rails 2.2 & 2.3!!!
9
10
  * An ActiveRecord::Base.execute_procedure method that can be used by classes.
10
11
  * Enabled support for DDL transactions.
11
12
  * Micro second support. Time#usec is automatically converted to SQL Server's 3.33 millisecond limitation.
@@ -150,7 +150,7 @@ module ActiveRecord
150
150
  class SQLServerAdapter < AbstractAdapter
151
151
 
152
152
  ADAPTER_NAME = 'SQLServer'.freeze
153
- VERSION = '2.2.13'.freeze
153
+ VERSION = '2.2.14'.freeze
154
154
  DATABASE_VERSION_REGEXP = /Microsoft SQL Server\s+(\d{4})/
155
155
  SUPPORTED_VERSIONS = [2000,2005].freeze
156
156
  LIMITABLE_TYPES = ['string','integer','float','char','nchar','varchar','nvarchar'].freeze
@@ -189,6 +189,10 @@ module ActiveRecord
189
189
  true
190
190
  end
191
191
 
192
+ def supports_savepoints?
193
+ true
194
+ end
195
+
192
196
  def database_version
193
197
  @database_version ||= info_schema_query { select_value('SELECT @@version') }
194
198
  end
@@ -342,6 +346,10 @@ module ActiveRecord
342
346
  end
343
347
  end
344
348
 
349
+ def outside_transaction?
350
+ info_schema_query { select_value("SELECT @@TRANCOUNT") == 0 }
351
+ end
352
+
345
353
  def begin_db_transaction
346
354
  do_execute "BEGIN TRANSACTION"
347
355
  end
@@ -354,6 +362,17 @@ module ActiveRecord
354
362
  do_execute "ROLLBACK TRANSACTION" rescue nil
355
363
  end
356
364
 
365
+ def create_savepoint
366
+ do_execute "SAVE TRANSACTION #{current_savepoint_name}"
367
+ end
368
+
369
+ def release_savepoint
370
+ end
371
+
372
+ def rollback_to_savepoint
373
+ do_execute "ROLLBACK TRANSACTION #{current_savepoint_name}"
374
+ end
375
+
357
376
  def add_limit_offset!(sql, options)
358
377
  # Validate and/or convert integers for :limit and :offets options.
359
378
  if options[:offset]
@@ -485,7 +504,9 @@ module ActiveRecord
485
504
  @sqlserver_view_information_cache[table_name] ||= begin
486
505
  view_info = info_schema_query { select_one("SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = '#{table_name}'") }
487
506
  if view_info
488
- view_info['VIEW_DEFINITION'] ||= info_schema_query { select_values("EXEC sp_helptext #{table_name}").join }
507
+ if view_info['VIEW_DEFINITION'].blank? || view_info['VIEW_DEFINITION'].length == 4000
508
+ view_info['VIEW_DEFINITION'] = info_schema_query { select_values("EXEC sp_helptext #{table_name}").join }
509
+ end
489
510
  end
490
511
  view_info
491
512
  end
@@ -1,3 +1,5 @@
1
+ require 'active_record/version'
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLServerActiveRecordExtensions
@@ -81,3 +83,51 @@ module ActiveRecord
81
83
  end
82
84
 
83
85
  ActiveRecord::Base.send :include, ActiveRecord::ConnectionAdapters::SQLServerActiveRecordExtensions
86
+
87
+
88
+
89
+
90
+ if ActiveRecord::VERSION::MAJOR == 2 && ActiveRecord::VERSION::MINOR >= 3
91
+
92
+ require 'active_record/associations'
93
+ module ActiveRecord
94
+ module ConnectionAdapters
95
+ module SQLServerJoinAssociationChanges
96
+
97
+ def self.included(klass)
98
+ klass.class_eval do
99
+ include InstanceMethods
100
+ alias_method_chain :aliased_table_name_for, :sqlserver_support
101
+ end
102
+ end
103
+
104
+ module InstanceMethods
105
+
106
+ protected
107
+
108
+ # An exact copy, except this method has a Regexp escape on the quoted table name.
109
+ def aliased_table_name_for_with_sqlserver_support(name,suffix=nil)
110
+ if !parent.table_joins.blank? && parent.table_joins.to_s.downcase =~ %r{join(\s+\w+)?\s+#{Regexp.escape(active_record.connection.quote_table_name(name.downcase))}\son}i
111
+ @join_dependency.table_aliases[name] += 1
112
+ end
113
+ unless @join_dependency.table_aliases[name].zero?
114
+ # if the table name has been used, then use an alias
115
+ name = active_record.connection.table_alias_for "#{pluralize(reflection.name)}_#{parent_table_name}#{suffix}"
116
+ table_index = @join_dependency.table_aliases[name]
117
+ @join_dependency.table_aliases[name] += 1
118
+ name = name[0..active_record.connection.table_alias_length-3] + "_#{table_index+1}" if table_index > 0
119
+ else
120
+ @join_dependency.table_aliases[name] += 1
121
+ end
122
+ name
123
+ end
124
+
125
+ end
126
+
127
+ end
128
+ end
129
+ end
130
+ ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation.send :include, ActiveRecord::ConnectionAdapters::SQLServerJoinAssociationChanges
131
+
132
+ end
133
+
@@ -0,0 +1,33 @@
1
+ require 'cases/sqlserver_helper'
2
+ require 'models/topic'
3
+
4
+ class AttributeMethodsTestSqlserver < ActiveRecord::TestCase
5
+ end
6
+
7
+ class AttributeMethodsTest < ActiveRecord::TestCase
8
+
9
+ COERCED_TESTS = [
10
+ :test_typecast_attribute_from_select_to_false,
11
+ :test_typecast_attribute_from_select_to_true
12
+ ]
13
+
14
+ include SqlserverCoercedTest
15
+
16
+ fixtures :topics
17
+
18
+
19
+ def test_coerced_typecast_attribute_from_select_to_false
20
+ topic = Topic.create(:title => 'Budget')
21
+ topic = Topic.find(:first, :select => "topics.*, CASE WHEN 1=2 THEN 1 ELSE 0 END as is_test")
22
+ assert !topic.is_test?
23
+ end
24
+
25
+ def test_coerced_typecast_attribute_from_select_to_true
26
+ topic = Topic.create(:title => 'Budget')
27
+ topic = Topic.find(:first, :select => "topics.*, CASE WHEN 2=2 THEN 1 ELSE 0 END as is_test")
28
+ assert topic.is_test?
29
+ end
30
+
31
+
32
+ end
33
+
@@ -158,6 +158,7 @@ class ColumnTestSqlserver < ActiveRecord::TestCase
158
158
  @date = SqlServerChronic.columns_hash['date']
159
159
  @time = SqlServerChronic.columns_hash['time']
160
160
  @datetime = SqlServerChronic.columns_hash['datetime']
161
+ @smalldatetime = SqlServerChronic.columns_hash['smalldatetime']
161
162
  end
162
163
 
163
164
  should 'have correct simplified type for uncast datetime' do
@@ -176,6 +177,23 @@ class ColumnTestSqlserver < ActiveRecord::TestCase
176
177
  assert_equal nil, @datetime.limit
177
178
  end
178
179
 
180
+ context 'For smalldatetime types' do
181
+
182
+ should 'have created that type using rails migrations' do
183
+ assert_equal 'smalldatetime', @smalldatetime.sql_type
184
+ end
185
+
186
+ should 'be able to insert column without truncation warnings or the like' do
187
+ SqlServerChronic.create! :smalldatetime => Time.now
188
+ end
189
+
190
+ should 'be able to update column without truncation warnings or the like' do
191
+ ssc = SqlServerChronic.create! :smalldatetime => 2.days.ago
192
+ ssc.update_attributes! :smalldatetime => Time.now
193
+ end
194
+
195
+ end
196
+
179
197
  context 'which have coerced types' do
180
198
 
181
199
  setup do
@@ -8,7 +8,11 @@ end
8
8
 
9
9
  class EagerAssociationTest < ActiveRecord::TestCase
10
10
 
11
- COERCED_TESTS = [:test_count_with_include]
11
+ COERCED_TESTS = [
12
+ :test_count_with_include,
13
+ :test_eager_with_has_many_and_limit_and_high_offset_and_multiple_array_conditions,
14
+ :test_eager_with_has_many_and_limit_and_high_offset_and_multiple_hash_conditions
15
+ ]
12
16
 
13
17
  include SqlserverCoercedTest
14
18
 
@@ -18,5 +22,21 @@ class EagerAssociationTest < ActiveRecord::TestCase
18
22
  assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "len(comments.body) > 15")
19
23
  end
20
24
 
25
+ def test_coerced_eager_with_has_many_and_limit_and_high_offset_and_multiple_array_conditions
26
+ assert_queries(2) do
27
+ posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :offset => 10,
28
+ :conditions => [ "authors.name = ? and comments.body = ?", 'David', 'go crazy' ])
29
+ assert_equal 0, posts.size
30
+ end
31
+ end
32
+
33
+ def test_coerced_eager_with_has_many_and_limit_and_high_offset_and_multiple_hash_conditions
34
+ assert_queries(2) do
35
+ posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :offset => 10,
36
+ :conditions => { 'authors.name' => 'David', 'comments.body' => 'go crazy' })
37
+ assert_equal 0, posts.size
38
+ end
39
+ end unless active_record_2_point_2?
40
+
21
41
 
22
42
  end
@@ -0,0 +1,28 @@
1
+ require 'cases/sqlserver_helper'
2
+ require 'models/developer'
3
+
4
+ class MethodScopingTestSqlServer < ActiveRecord::TestCase
5
+ end
6
+
7
+ class NestedScopingTest < ActiveRecord::TestCase
8
+
9
+ COERCED_TESTS = [:test_merged_scoped_find]
10
+
11
+ include SqlserverCoercedTest
12
+
13
+ fixtures :developers
14
+
15
+ def test_coerced_test_merged_scoped_find
16
+ poor_jamis = developers(:poor_jamis)
17
+ Developer.with_scope(:find => { :conditions => "salary < 100000" }) do
18
+ Developer.with_scope(:find => { :offset => 1, :order => 'id asc' }) do
19
+ assert_sql /ORDER BY id ASC/ do
20
+ assert_equal(poor_jamis, Developer.find(:first, :order => 'id asc'))
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+
@@ -3,6 +3,7 @@ require 'shoulda'
3
3
  require 'mocha'
4
4
  require 'cases/helper'
5
5
  require 'models/topic'
6
+ require 'active_record/version'
6
7
 
7
8
  SQLSERVER_TEST_ROOT = File.expand_path(File.join(File.dirname(__FILE__),'..'))
8
9
  SQLSERVER_ASSETS_ROOT = SQLSERVER_TEST_ROOT + "/assets"
@@ -77,7 +78,7 @@ end
77
78
  # Our changes/additions to ActiveRecord test helpers specific for SQL Server.
78
79
 
79
80
  ActiveRecord::Base.connection.class.class_eval do
80
- IGNORED_SQL << /SELECT SCOPE_IDENTITY/ << /INFORMATION_SCHEMA.TABLES/ << /INFORMATION_SCHEMA.COLUMNS/
81
+ IGNORED_SQL << /SELECT SCOPE_IDENTITY/ << /INFORMATION_SCHEMA.TABLES/ << /INFORMATION_SCHEMA.COLUMNS/ << /^SELECT @@TRANCOUNT/
81
82
  end
82
83
 
83
84
  ActiveRecord::ConnectionAdapters::SQLServerAdapter.class_eval do
@@ -94,6 +95,8 @@ module ActiveRecord
94
95
  class << self
95
96
  def sqlserver_2000? ; ActiveRecord::Base.connection.sqlserver_2000? ; end
96
97
  def sqlserver_2005? ; ActiveRecord::Base.connection.sqlserver_2005? ; end
98
+ def active_record_2_point_2? ; ActiveRecord::VERSION::MAJOR == 2 && ActiveRecord::VERSION::MINOR == 2 ; end
99
+ def active_record_2_point_3? ; ActiveRecord::VERSION::MAJOR == 2 && ActiveRecord::VERSION::MINOR == 3 ; end
97
100
  end
98
101
  def assert_sql(*patterns_to_match)
99
102
  $queries_executed = []
@@ -107,6 +110,8 @@ module ActiveRecord
107
110
  end
108
111
  def sqlserver_2000? ; self.class.sqlserver_2000? ; end
109
112
  def sqlserver_2005? ; self.class.sqlserver_2005? ; end
113
+ def active_record_2_point_2? ; self.class.active_record_2_point_2? ; end
114
+ def active_record_2_point_3? ; self.class.active_record_2_point_3? ; end
110
115
  end
111
116
  end
112
117
 
@@ -0,0 +1,93 @@
1
+ require 'cases/sqlserver_helper'
2
+ require 'models/ship'
3
+ require 'models/developer'
4
+
5
+ class TransactionTestSqlserver < ActiveRecord::TestCase
6
+
7
+ self.use_transactional_fixtures = false
8
+
9
+ setup :delete_ships
10
+
11
+ context 'Testing transaction basics' do
12
+
13
+ should 'allow ActiveRecord::Rollback to work in 1 transaction block' do
14
+ Ship.transaction do
15
+ Ship.create! :name => 'Black Pearl'
16
+ raise ActiveRecord::Rollback
17
+ end
18
+ assert_no_ships
19
+ end
20
+
21
+ should 'allow nested transactions to totally rollback' do
22
+ begin
23
+ Ship.transaction do
24
+ Ship.create! :name => 'Black Pearl'
25
+ Ship.transaction do
26
+ Ship.create! :name => 'Flying Dutchman'
27
+ raise 'HELL'
28
+ end
29
+ end
30
+ rescue Exception => e
31
+ assert_no_ships
32
+ end
33
+ end
34
+
35
+ end
36
+
37
+ context 'Testing #outside_transaction?' do
38
+
39
+ should 'work in simple usage' do
40
+ assert Ship.connection.outside_transaction?
41
+ Ship.connection.begin_db_transaction
42
+ assert !Ship.connection.outside_transaction?
43
+ Ship.connection.rollback_db_transaction
44
+ assert Ship.connection.outside_transaction?
45
+ end
46
+
47
+ should 'work inside nested transactions' do
48
+ assert Ship.connection.outside_transaction?
49
+ Ship.transaction do
50
+ assert !Ship.connection.outside_transaction?
51
+ Ship.transaction do
52
+ assert !Ship.connection.outside_transaction?
53
+ end
54
+ end
55
+ assert Ship.connection.outside_transaction?
56
+ end
57
+
58
+ should 'not call rollback if no transaction is active' do
59
+ assert_raise RuntimeError do
60
+ Ship.transaction do
61
+ Ship.connection.rollback_db_transaction
62
+ Ship.connection.expects(:rollback_db_transaction).never
63
+ raise "Rails doesn't scale!"
64
+ end
65
+ end
66
+ end
67
+
68
+ should 'test_open_transactions_count_is_reset_to_zero_if_no_transaction_active' do
69
+ Ship.transaction do
70
+ Ship.transaction do
71
+ Ship.connection.rollback_db_transaction
72
+ end
73
+ assert_equal 0, Ship.connection.open_transactions
74
+ end
75
+ assert_equal 0, Ship.connection.open_transactions
76
+ end
77
+
78
+ end unless active_record_2_point_2?
79
+
80
+
81
+
82
+ protected
83
+
84
+ def delete_ships
85
+ Ship.delete_all
86
+ end
87
+
88
+ def assert_no_ships
89
+ assert Ship.count.zero?, "Expected Ship to have no models but it did have:\n#{Ship.all.inspect}"
90
+ end
91
+
92
+ end
93
+
@@ -25,6 +25,7 @@ ActiveRecord::Schema.define do
25
25
  t.column :time, :time
26
26
  t.column :datetime, :datetime
27
27
  t.column :timestamp, :timestamp
28
+ t.column :smalldatetime, :smalldatetime
28
29
  end
29
30
 
30
31
  create_table(:fk_test_has_fks, :force => true) { |t| t.column(:fk_id, :integer, :null => false) }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-sqlserver-2000-2005-adapter
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.13
4
+ version: 2.2.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ken Collins
@@ -13,7 +13,7 @@ autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
15
 
16
- date: 2009-02-08 00:00:00 -08:00
16
+ date: 2009-03-17 00:00:00 -07:00
17
17
  default_executable:
18
18
  dependencies: []
19
19
 
@@ -71,6 +71,7 @@ summary: SQL Server 2000 & 2005 Adapter For Rails.
71
71
  test_files:
72
72
  - test/cases/aaaa_create_tables_test_sqlserver.rb
73
73
  - test/cases/adapter_test_sqlserver.rb
74
+ - test/cases/attribute_methods_test_sqlserver.rb
74
75
  - test/cases/basics_test_sqlserver.rb
75
76
  - test/cases/calculations_test_sqlserver.rb
76
77
  - test/cases/column_test_sqlserver.rb
@@ -78,6 +79,7 @@ test_files:
78
79
  - test/cases/eager_association_test_sqlserver.rb
79
80
  - test/cases/execute_procedure_test_sqlserver.rb
80
81
  - test/cases/inheritance_test_sqlserver.rb
82
+ - test/cases/method_scoping_test_sqlserver.rb
81
83
  - test/cases/migration_test_sqlserver.rb
82
84
  - test/cases/offset_and_limit_test_sqlserver.rb
83
85
  - test/cases/pessimistic_locking_test_sqlserver.rb
@@ -86,6 +88,7 @@ test_files:
86
88
  - test/cases/specific_schema_test_sqlserver.rb
87
89
  - test/cases/sqlserver_helper.rb
88
90
  - test/cases/table_name_test_sqlserver.rb
91
+ - test/cases/transaction_test_sqlserver.rb
89
92
  - test/cases/unicode_test_sqlserver.rb
90
93
  - test/connections/native_sqlserver/connection.rb
91
94
  - test/connections/native_sqlserver_odbc/connection.rb