Skip to content

Commit 9a4d4fd

Browse files
author
Anna
committed
2 parents 3dfff1a + 8dfd4eb commit 9a4d4fd

File tree

2 files changed

+36
-13
lines changed

2 files changed

+36
-13
lines changed

lib/active_record/connection_adapters/sqlserver/schema_statements.rb

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def columns(table_name, name = nil)
4646

4747
def rename_table(table_name, new_name)
4848
do_execute "EXEC sp_rename '#{table_name}', '#{new_name}'"
49+
rename_table_indexes(table_name, new_name)
4950
end
5051

5152
def remove_column(table_name, column_name, type = nil)
@@ -58,16 +59,25 @@ def remove_column(table_name, column_name, type = nil)
5859

5960
def change_column(table_name, column_name, type, options = {})
6061
sql_commands = []
62+
indexes = []
6163
column_object = schema_cache.columns(table_name).detect { |c| c.name.to_s == column_name.to_s }
62-
change_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
63-
change_column_sql << " NOT NULL" if options[:null] == false
64-
sql_commands << change_column_sql
64+
6565
if options_include_default?(options) || (column_object && column_object.type != type.to_sym)
66-
remove_default_constraint(table_name,column_name)
66+
remove_default_constraint(table_name,column_name)
67+
indexes = indexes(table_name).select{ |index| index.columns.include?(column_name.to_s) }
68+
remove_indexes(table_name, column_name)
6769
end
70+
sql_commands << "UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(options[:default])} WHERE #{quote_column_name(column_name)} IS NULL" if !options[:null].nil? && options[:null] == false && !options[:default].nil?
71+
sql_commands << "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
72+
sql_commands[-1] << " NOT NULL" if !options[:null].nil? && options[:null] == false
6873
if options_include_default?(options)
6974
sql_commands << "ALTER TABLE #{quote_table_name(table_name)} ADD CONSTRAINT #{default_constraint_name(table_name,column_name)} DEFAULT #{quote(options[:default])} FOR #{quote_column_name(column_name)}"
7075
end
76+
77+
#Add any removed indexes back
78+
indexes.each do |index|
79+
sql_commands << "CREATE INDEX #{quote_table_name(index.name)} ON #{quote_table_name(table_name)} (#{index.columns.collect {|c|quote_column_name(c)}.join(', ')})"
80+
end
7181
sql_commands.each { |c| do_execute(c) }
7282
end
7383

@@ -80,6 +90,12 @@ def rename_column(table_name, column_name, new_column_name)
8090
schema_cache.clear_table_cache!(table_name)
8191
detect_column_for! table_name, column_name
8292
do_execute "EXEC sp_rename '#{table_name}.#{column_name}', '#{new_column_name}', 'COLUMN'"
93+
rename_column_indexes(table_name, column_name, new_column_name)
94+
schema_cache.clear_table_cache!(table_name)
95+
end
96+
97+
def rename_index(table_name, old_name, new_name)
98+
execute "EXEC sp_rename N'#{table_name}.#{old_name}', N'#{new_name}', N'INDEX'"
8399
end
84100

85101
def remove_index!(table_name, index_name)
@@ -326,8 +342,8 @@ def views_real_column_name(table_name,column_name)
326342
# === SQLServer Specific (Identity Inserts) ===================== #
327343

328344
def query_requires_identity_insert?(sql)
329-
330-
if insert_sql?(sql)
345+
346+
if insert_sql?(sql)
331347
table_name = get_table_name(sql)
332348
id_column = identity_column(table_name)
333349
id_column && sql =~ /^\s*(INSERT|EXEC sp_executesql N'INSERT)[^(]+\([^)]*\b(#{id_column.name})\b,?[^)]*\)/i ? quote_table_name(table_name) : false
@@ -354,7 +370,7 @@ def set_identity_insert(table_name, enable = true)
354370
rescue Exception => e
355371
raise ActiveRecordError, "IDENTITY_INSERT could not be turned #{enable ? 'ON' : 'OFF'} for table #{table_name}"
356372
end
357-
373+
358374
def identity_column(table_name)
359375
schema_cache.columns(table_name).detect(&:is_identity?)
360376
end

test/cases/finder_test_sqlserver.rb

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,16 @@ class FinderTestSqlserver < ActiveRecord::TestCase
55
end
66

77
class FinderTest < ActiveRecord::TestCase
8-
8+
99
COERCED_TESTS = [
1010
:test_exists_does_not_select_columns_without_alias,
1111
:test_string_sanitation,
12-
:test_first_and_last_with_integer_should_use_sql_limit
12+
:test_first_and_last_with_integer_should_use_sql_limit,
13+
:test_take_and_first_and_last_with_integer_should_use_sql_limit
1314
]
14-
15+
1516
include SqlserverCoercedTest
16-
17+
1718
def test_coerced_exists_does_not_select_columns_without_alias
1819
assert_sql(/SELECT TOP \(1\) 1 AS one FROM \[topics\]/i) do
1920
Topic.exists?
@@ -24,11 +25,17 @@ def test_coerced_string_sanitation
2425
assert_not_equal "N'something ' 1=1'", ActiveRecord::Base.sanitize("something ' 1=1")
2526
assert_equal "N'something; select table'", ActiveRecord::Base.sanitize("something; select table")
2627
end
27-
28+
2829
def test_coerced_first_and_last_with_integer_should_use_sql_limit
2930
assert_sql(/TOP \(2\)/) { Topic.first(2).entries }
3031
assert_sql(/TOP \(5\)/) { Topic.last(5).entries }
3132
end
32-
33+
34+
def test_coerced_take_and_first_and_last_with_integer_should_use_sql_limit
35+
assert_sql(/TOP \(3\)/) { Topic.take(3).entries }
36+
assert_sql(/TOP \(2\)/) { Topic.first(2).entries }
37+
assert_sql(/TOP \(5\)/) { Topic.last(5).entries }
38+
end
39+
3340
end
3441

0 commit comments

Comments
 (0)