Skip to content

Commit 4a72571

Browse files
committed
Azure compatibility.
* New DROP INDEX structure. * SQL Azure maps to 2010 year and uses sqlserver_azure? helper. * TinyTDS config for azure.
1 parent ce4f3ac commit 4a72571

File tree

11 files changed

+85
-30
lines changed

11 files changed

+85
-30
lines changed

CHANGELOG

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11

22
* master *
33

4+
* Azure compatibility.
5+
46
* TinyTDS enhancements for lost connections.
57

68

lib/active_record/connection_adapters/sqlserver/database_statements.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ def execute_procedure(proc_name, *variables)
104104
end
105105

106106
def use_database(database=nil)
107+
return if sqlserver_azure?
107108
database ||= @connection_options[:database]
108109
do_execute "USE #{quote_table_name(database)}" unless database.blank?
109110
end

lib/active_record/connection_adapters/sqlserver/schema_statements.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ def rename_column(table_name, column_name, new_column_name)
106106
end
107107

108108
def remove_index!(table_name, index_name)
109-
do_execute "DROP INDEX #{quote_table_name(table_name)}.#{quote_column_name(index_name)}"
109+
do_execute "DROP INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)}"
110110
end
111111

112112
def type_to_sql(type, limit = nil, precision = nil, scale = nil)

lib/active_record/connection_adapters/sqlserver_adapter.rb

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ class SQLServerAdapter < AbstractAdapter
167167
ADAPTER_NAME = 'SQLServer'.freeze
168168
VERSION = '3.0.10'.freeze
169169
DATABASE_VERSION_REGEXP = /Microsoft SQL Server\s+"?(\d{4}|\w+)"?/
170-
SUPPORTED_VERSIONS = [2005,2008,2011].freeze
170+
SUPPORTED_VERSIONS = [2005,2008,2010,2011].freeze
171171

172172
attr_reader :database_version, :database_year,
173173
:connection_supports_native_types
@@ -182,8 +182,13 @@ def initialize(logger,config)
182182
super(@connection, logger)
183183
@database_version = info_schema_query { select_value('SELECT @@version') }
184184
@database_year = begin
185-
year = DATABASE_VERSION_REGEXP.match(@database_version)[1]
186-
year == "Denali" ? 2011 : year.to_i
185+
if @database_version =~ /Microsoft SQL Azure/i
186+
@sqlserver_azure = true
187+
@database_version.match(/\s(\d{4})\s/)[1].to_i
188+
else
189+
year = DATABASE_VERSION_REGEXP.match(@database_version)[1]
190+
year == "Denali" ? 2011 : year.to_i
191+
end
187192
rescue
188193
0
189194
end
@@ -290,6 +295,10 @@ def sqlserver_2011?
290295
@database_year == 2011
291296
end
292297

298+
def sqlserver_azure?
299+
@sqlserver_azure && @database_year == 2010
300+
end
301+
293302
def version
294303
self.class::VERSION
295304
end
@@ -311,11 +320,11 @@ def native_text_database_type
311320
end
312321

313322
def native_time_database_type
314-
sqlserver_2008? ? 'time' : 'datetime'
323+
sqlserver_2005? ? 'datetime' : 'time'
315324
end
316325

317326
def native_date_database_type
318-
sqlserver_2008? ? 'date' : 'datetime'
327+
sqlserver_2005? ? 'datetime' : 'date'
319328
end
320329

321330
def native_binary_database_type
@@ -362,11 +371,22 @@ def connect
362371
:appname => appname,
363372
:login_timeout => login_timeout,
364373
:timeout => timeout,
365-
:encoding => encoding
374+
:encoding => encoding,
375+
:azure => config[:azure]
366376
}).tap do |client|
367-
client.execute("SET ANSI_DEFAULTS ON").do
368-
client.execute("SET IMPLICIT_TRANSACTIONS OFF").do
369-
client.execute("SET CURSOR_CLOSE_ON_COMMIT OFF").do
377+
if config[:azure]
378+
client.execute("SET ANSI_NULLS ON").do
379+
client.execute("SET CURSOR_CLOSE_ON_COMMIT OFF").do
380+
client.execute("SET ANSI_NULL_DFLT_ON ON").do
381+
client.execute("SET IMPLICIT_TRANSACTIONS OFF").do
382+
client.execute("SET ANSI_PADDING ON").do
383+
client.execute("SET QUOTED_IDENTIFIER ON")
384+
client.execute("SET ANSI_WARNINGS ON").do
385+
else
386+
client.execute("SET ANSI_DEFAULTS ON").do
387+
client.execute("SET CURSOR_CLOSE_ON_COMMIT OFF").do
388+
client.execute("SET IMPLICIT_TRANSACTIONS OFF").do
389+
end
370390
end
371391
when :odbc
372392
odbc = ['::ODBC','::ODBC_UTF8','::ODBC_NONE'].detect{ |odbc_ns| odbc_ns.constantize rescue nil }.constantize

test/cases/adapter_test_sqlserver.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def setup
6464

6565
should 'return a string from #database_version that matches class regexp' do
6666
assert_match @version_regexp, @connection.database_version
67-
end
67+
end unless sqlserver_azure?
6868

6969
should 'return a 4 digit year fixnum for #database_year' do
7070
assert_instance_of Fixnum, @connection.database_year
@@ -258,7 +258,7 @@ def setup
258258

259259
should 'return nil when calling #identity_column for a table_name with no identity' do
260260
assert_nil @connection.send(:identity_column,Subscriber.table_name)
261-
end
261+
end unless sqlserver_azure?
262262

263263
end
264264

@@ -339,7 +339,7 @@ def setup
339339
assert_equal 'read uncommitted', uo[:isolation_level]
340340
end
341341

342-
end
342+
end unless sqlserver_azure?
343343

344344
context "altering isolation levels" do
345345

@@ -390,7 +390,7 @@ def setup
390390
assert_nil Task.find(@t2.id).starting, 'Should be nil again from botched transaction above.'
391391
end
392392

393-
end
393+
end unless sqlserver_azure?
394394

395395
end
396396

@@ -432,11 +432,11 @@ def setup
432432

433433
setup do
434434
@desc_index_name = 'idx_credit_limit_test_desc'
435-
@connection.execute "CREATE INDEX #{@desc_index_name} ON accounts (credit_limit DESC)"
435+
@connection.execute "CREATE INDEX [#{@desc_index_name}] ON [accounts] (credit_limit DESC)"
436436
end
437437

438438
teardown do
439-
@connection.execute "DROP INDEX accounts.#{@desc_index_name}"
439+
@connection.execute "DROP INDEX [#{@desc_index_name}] ON [accounts]"
440440
end
441441

442442
should 'have indexes with descending order' do

test/cases/column_test_sqlserver.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,12 +184,12 @@ def setup
184184
should 'be able to use real sql server timestamp if you really want to' do
185185
assert_equal :binary, @ss_timestamp.type
186186
assert_equal 'timestamp', @ss_timestamp.sql_type
187-
end
187+
end unless sqlserver_azure?
188188

189189
should 'return :timestamp as a binaryish string' do
190190
chronic = SqlServerChronic.create!.reload
191191
assert_match %r|\000|, chronic.ss_timestamp
192-
end
192+
end unless sqlserver_azure?
193193

194194
end
195195

test/cases/connection_test_sqlserver.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def setup
3030
@connection.use_database
3131
assert_equal 'activerecord_unittest', @connection.current_database, 'Would default back to connection options'
3232
end
33-
end
33+
end unless sqlserver_azure?
3434

3535
context 'ODBC connection management' do
3636

test/cases/migration_test_sqlserver.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,11 @@ def setup
6363

6464
end
6565

66+
if ActiveRecord::TestCase.sqlserver_azure?
67+
class MigrationTest < ActiveRecord::TestCase
68+
COERCED_TESTS = [:test_migrator_db_has_no_schema_migrations_table]
69+
include SqlserverCoercedTest
70+
def test_coerced_test_migrator_db_has_no_schema_migrations_table ; assert true ; end
71+
end
72+
end
6673

test/cases/sqlserver_helper.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ def connection_mode_odbc? ; ActiveRecord::Base.connection.instance_variable_get(
9898
def connection_mode_adonet? ; ActiveRecord::Base.connection.instance_variable_get(:@connection_options)[:mode] == :adonet ; end
9999
def sqlserver_2005? ; ActiveRecord::Base.connection.sqlserver_2005? ; end
100100
def sqlserver_2008? ; ActiveRecord::Base.connection.sqlserver_2008? ; end
101+
def sqlserver_azure? ; ActiveRecord::Base.connection.sqlserver_azure? ; end
101102
def ruby_19? ; RUBY_VERSION >= '1.9' ; end
102103
end
103104
def assert_sql(*patterns_to_match)
@@ -115,6 +116,7 @@ def connection_mode_odbc? ; self.class.connection_mode_odbc? ; end
115116
def connection_mode_adonet? ; self.class.connection_mode_adonet? ; end
116117
def sqlserver_2005? ; self.class.sqlserver_2005? ; end
117118
def sqlserver_2008? ; self.class.sqlserver_2008? ; end
119+
def sqlserver_azure? ; self.class.sqlserver_azure? ; end
118120
def ruby_19? ; self.class.ruby_19? ; end
119121
def with_enable_default_unicode_types?
120122
ActiveRecord::ConnectionAdapters::SQLServerAdapter.enable_default_unicode_types.is_a?(TrueClass)

test/connections/native_sqlserver_dblib/connection.rb

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
print "Using SQLServer via DBLIB to #{ENV['TINYTDS_UNIT_DATASERVER']}\n"
1+
print "Using SQLServer via DBLIB to #{ENV['ACTIVERECORD_UNITTEST_DATASERVER']}\n"
22
require_dependency 'models/course'
33
require 'logger'
44

@@ -9,20 +9,22 @@
99
'arunit' => {
1010
:adapter => 'sqlserver',
1111
:mode => 'dblib',
12-
:dataserver => ENV['TINYTDS_UNIT_DATASERVER'],
13-
:username => 'rails',
14-
:password => '',
12+
:dataserver => ENV['ACTIVERECORD_UNITTEST_DATASERVER'],
13+
:username => ENV['ACTIVERECORD_UNITTEST_USER'] || 'rails',
14+
:password => ENV['ACTIVERECORD_UNITTEST_PASS'] || '',
1515
:database => 'activerecord_unittest',
16-
:appname => 'SQLServerUnit'
16+
:appname => 'SQLServerAdptrUnit',
17+
:azure => !ENV['ACTIVERECORD_UNITTEST_AZURE'].nil?
1718
},
1819
'arunit2' => {
1920
:adapter => 'sqlserver',
2021
:mode => 'dblib',
21-
:dataserver => ENV['TINYTDS_UNIT_DATASERVER'],
22-
:username => 'rails',
23-
:password => '',
22+
:dataserver => ENV['ACTIVERECORD_UNITTEST_DATASERVER'],
23+
:username => ENV['ACTIVERECORD_UNITTEST_USER'] || 'rails',
24+
:password => ENV['ACTIVERECORD_UNITTEST_PASS'] || '',
2425
:database => 'activerecord_unittest2',
25-
:appname => 'SQLServerUnit2'
26+
:appname => 'SQLServerAdptrUnit2',
27+
:azure => !ENV['ACTIVERECORD_UNITTEST_AZURE'].nil?
2628
}
2729
}
2830

0 commit comments

Comments
 (0)