Skip to content

Commit 8bccbaa

Browse files
committed
Merge pull request #331 from veracross/rails-4-1-0
Rails 4.1 Support
2 parents e3bcabf + d176046 commit 8bccbaa

21 files changed

+178
-73
lines changed

Gemfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ group :development do
4141
gem 'bcrypt-ruby', '~> 3.0.0'
4242
gem 'bench_press'
4343
gem 'mocha'
44-
gem 'minitest-spec-rails'
44+
# TODO: Change back when it's ready
45+
gem 'minitest-spec-rails', git: "https://github.com/metaskills/minitest-spec-rails.git"
4546
gem 'nokogiri'
4647
gem 'rake', '~> 0.9.2'
4748
gem 'rubocop'

Rakefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ AREL_PATH = Gem.loaded_specs['arel'].full_gem_path
66
# Notes for cross compile:
77
# $ gcla ; bundle install ; rake compile ; rake cross compile ; rake cross native gem
88

9+
# Since the Gemfile for this project requires, rails, it ends up causing
10+
# Rails.env to be defined, which affects some of the unit tests. We fix this
11+
# by setting the RAILS_ENV to "default_env"
12+
ENV['RAILS_ENV'] = 'default_env'
13+
914
def test_libs
1015
['lib',
1116
'test',

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
4.0.0
1+
4.1.0.pre
Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
1-
$LOAD_PATH.push File.expand_path('../lib', __FILE__)
1+
$:.push File.expand_path("../lib", __FILE__)
22

33
Gem::Specification.new do |s|
44
s.platform = Gem::Platform::RUBY
5-
s.name = 'activerecord-sqlserver-adapter'
6-
s.version = File.read(File.expand_path('../VERSION', __FILE__)).strip
7-
s.summary = 'ActiveRecord SQL Server Adapter. For SQL Server 2005 And Higher.'
8-
s.description = 'ActiveRecord SQL Server Adapter. For SQL Server 2005 And Higher.'
9-
10-
s.authors = ['Ken Collins', 'Anna Carey', 'Murray Steele', 'Shawn Balestracci', 'Joe Rafaniello', 'Tom Ward']
11-
s.email = 'ken@metaskills.net'
12-
s.homepage = 'http://github.com/rails-sqlserver/activerecord-sqlserver-adapter'
13-
14-
s.files = Dir['CHANGELOG', 'MIT-LICENSE', 'README.rdoc', 'VERSION', 'lib/**/*']
5+
s.name = "activerecord-sqlserver-adapter"
6+
s.version = File.read(File.expand_path("../VERSION",__FILE__)).strip
7+
s.summary = "ActiveRecord SQL Server Adapter. For SQL Server 2005 And Higher."
8+
s.description = "ActiveRecord SQL Server Adapter. For SQL Server 2005 And Higher."
9+
10+
s.authors = ['Ken Collins', 'Murray Steele', 'Shawn Balestracci', 'Joe Rafaniello', 'Tom Ward']
11+
s.email = "ken@metaskills.net"
12+
s.homepage = "http://github.com/rails-sqlserver/activerecord-sqlserver-adapter"
13+
14+
s.files = Dir['CHANGELOG', 'MIT-LICENSE', 'README.rdoc', 'VERSION', 'lib/**/*' ]
1515
s.require_path = 'lib'
1616
s.rubyforge_project = 'activerecord-sqlserver-adapter'
17-
18-
s.add_dependency('activerecord', '~> 4.0.0')
19-
s.add_dependency('arel', '~> 4.0.1')
17+
18+
s.add_dependency('activerecord', '~> 4.1.0')
19+
s.add_dependency('arel')
2020
end
21+

lib/active_record/connection_adapters/sqlserver/database_statements.rb

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,15 @@ def rollback_db_transaction
5656
do_execute 'IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION'
5757
end
5858

59-
def create_savepoint
60-
disable_auto_reconnect { do_execute "SAVE TRANSACTION #{current_savepoint_name}" }
59+
def create_savepoint(name = current_savepoint_name)
60+
disable_auto_reconnect { do_execute "SAVE TRANSACTION #{name}" }
6161
end
6262

63-
def release_savepoint
63+
def release_savepoint(name = current_savepoint_name)
6464
end
6565

66-
def rollback_to_savepoint
67-
disable_auto_reconnect { do_execute "ROLLBACK TRANSACTION #{current_savepoint_name}" }
66+
def rollback_to_savepoint(name = current_savepoint_name)
67+
disable_auto_reconnect { do_execute "ROLLBACK TRANSACTION #{name}" }
6868
end
6969

7070
def add_limit_offset!(_sql, _options)
@@ -334,7 +334,11 @@ def do_exec_query(sql, name, binds, options = {})
334334
next if ar_column && column.sql_type == 'timestamp'
335335
v = value
336336
names_and_types << if ar_column
337-
v = value.to_i if column.is_integer? && value.present?
337+
if column.is_integer? && value.present?
338+
v = value.to_i
339+
# Reset the casted value to the bind as required by Rails 4.1
340+
binds[index] = [column, v]
341+
end
338342
"@#{index} #{column.sql_type_for_statement}"
339343
elsif column.acts_like?(:string)
340344
"@#{index} nvarchar(max)"

lib/active_record/connection_adapters/sqlserver/quoting.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def substitute_at(column, index)
6767
if column.respond_to?(:sql_type) && column.sql_type == 'timestamp'
6868
nil
6969
else
70-
Arel.sql "@#{index}"
70+
Arel::Nodes::BindParam.new "@#{index}"
7171
end
7272
end
7373

lib/active_record/connection_adapters/sqlserver/schema_creation.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,34 @@ def add_column_options!(sql, options)
2222
super
2323
end
2424
end
25+
26+
def visit_TableDefinition(o)
27+
quoted_name = "#{quote_table_name((o.temporary ? '#' : '') + o.name.to_s)} "
28+
29+
if o.as
30+
if o.as.is_a?(ActiveRecord::Relation)
31+
select = o.as.to_sql
32+
elsif o.as.is_a?(String)
33+
select = o.as
34+
else
35+
raise "Only able to generate a table from a SELECT statement passed as a String or ActiveRecord::Relation"
36+
end
37+
38+
create_sql = 'SELECT * INTO '
39+
create_sql << quoted_name
40+
create_sql << 'FROM ('
41+
create_sql << select
42+
create_sql << ') AS __sq'
43+
44+
else
45+
create_sql = "CREATE TABLE "
46+
create_sql << quoted_name
47+
create_sql << "(#{o.columns.map { |c| accept c }.join(', ')}) "
48+
create_sql << "#{o.options}"
49+
end
50+
51+
create_sql
52+
end
2553
end
2654
end
2755
end

lib/active_record/connection_adapters/sqlserver/schema_statements.rb

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ def table_exists?(table_name)
1616
super || tables.include?(unquoted_table_name) || views.include?(unquoted_table_name)
1717
end
1818

19+
def create_table(table_name, options = {})
20+
res = super
21+
schema_cache.clear_table_cache!(table_name)
22+
res
23+
end
24+
1925
def indexes(table_name, name = nil)
2026
data = select("EXEC sp_helpindex #{quote(table_name)}", name) rescue []
2127
data.reduce([]) do |indexes, index|
@@ -256,7 +262,7 @@ def column_definitions(table_name)
256262
nil
257263
else
258264
match_data = ci[:default_value].match(/\A\(+N?'?(.*?)'?\)+\Z/m)
259-
match_data ? match_data[1] : nil
265+
match_data ? match_data[1].gsub("''", "'") : nil
260266
end
261267
ci[:null] = ci[:is_nullable].to_i == 1
262268
ci.delete(:is_nullable)
@@ -408,8 +414,8 @@ def identity_column(table_name)
408414

409415
private
410416

411-
def create_table_definition(name, temporary, options)
412-
TableDefinition.new native_database_types, name, temporary, options
417+
def create_table_definition(name, temporary, options, as = nil)
418+
TableDefinition.new native_database_types, name, temporary, options, as
413419
end
414420
end
415421
end

test/cases/adapter_test_sqlserver.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -812,5 +812,7 @@ class AdapterTest < ActiveRecord::TestCase
812812
# This is not run for PostgreSQL at the rails level and the same should happen for SQL Server
813813
# Until that patch is made to rails we are preventing this test from running in this gem.
814814
include SqlserverCoercedTest
815+
816+
fixtures :authors
815817
end
816818
end

test/cases/bind_parameter_test_sqlserver.rb

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,33 @@
11
require 'cases/sqlserver_helper'
22
require 'models/topic'
3-
4-
class BindParameterTestSqlserver < ActiveRecord::TestCase
5-
end
6-
7-
class ActiveRecord::BindParameterTest < ActiveRecord::TestCase
8-
9-
fixtures :topics
10-
11-
COERCED_TESTS = [
12-
:test_binds_are_logged
13-
]
14-
15-
include SqlserverCoercedTest
16-
17-
# TODO: put a real test here
18-
def test_coerced_binds_are_logged
19-
assert true, 'they are!'
3+
require 'models_sqlserver/topic'
4+
require 'cases/bind_parameter_test'
5+
6+
# We don't coerce here because these tests are located inside of an if block
7+
# and don't seem to be able to be properly overriden with the coerce
8+
# functionality
9+
module ActiveRecord
10+
class BindParameterTest
11+
def test_binds_are_logged
12+
sub = @connection.substitute_at(@pk, 0)
13+
binds = [[@pk, 1]]
14+
sql = "select * from topics where id = #{sub}"
15+
16+
@connection.exec_query(sql, 'SQL', binds)
17+
18+
message = @listener.calls.find { |args| args[4][:sql].include? sql }
19+
assert_equal binds, message[4][:binds]
20+
end
21+
22+
def test_binds_are_logged_after_type_cast
23+
sub = @connection.substitute_at(@pk, 0)
24+
binds = [[@pk, "3"]]
25+
sql = "select * from topics where id = #{sub}"
26+
27+
@connection.exec_query(sql, 'SQL', binds)
28+
29+
message = @listener.calls.find { |args| args[4][:sql].include? sql }
30+
assert_equal [[@pk, 3]], message[4][:binds]
31+
end
2032
end
21-
22-
2333
end
24-
25-

0 commit comments

Comments
 (0)