Skip to content

Commit

Permalink
Change column/view cache to happen at class level. Allows connection …
Browse files Browse the repository at this point in the history
…pool to share same caches as well as the ability to expire the caches when needed. Also fix change_column so that exceptions are not raised when the column contains an existing default.
  • Loading branch information
metaskills committed Nov 2, 2009
1 parent 4d208ac commit ad83df8
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 22 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG
@@ -1,6 +1,10 @@

MASTER

* Change column/view cache to happen at class level. Allows connection pool to share same
caches as well as the ability to expire the caches when needed. Also fix change_column so
that exceptions are not raised when the column contains an existing default. [Ken Collins]

* Allow query_requires_identity_insert? method to return quoted table name in situations where the
INSERT parts are not quoted themselves. [Gary/iawgens, Richard Penwell, Ken Collins]

Expand Down
36 changes: 15 additions & 21 deletions lib/active_record/connection_adapters/sqlserver_adapter.rb
Expand Up @@ -568,13 +568,13 @@ def tables(name = nil)
end

def views(name = nil)
@sqlserver_views_cache ||=
@@sqlserver_views_cache ||=
info_schema_query { select_values("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME NOT IN ('sysconstraints','syssegments')") }
end

def view_information(table_name)
table_name = unqualify_table_name(table_name)
@sqlserver_view_information_cache[table_name] ||= begin
@@sqlserver_view_information_cache[table_name] ||= begin
view_info = info_schema_query { select_one("SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = '#{table_name}'") }
if view_info
if view_info['VIEW_DEFINITION'].blank? || view_info['VIEW_DEFINITION'].length == 4000
Expand Down Expand Up @@ -615,15 +615,15 @@ def indexes(table_name, name = nil)
def columns(table_name, name = nil)
return [] if table_name.blank?
cache_key = unqualify_table_name(table_name)
@sqlserver_columns_cache[cache_key] ||= column_definitions(table_name).collect do |ci|
@@sqlserver_columns_cache[cache_key] ||= column_definitions(table_name).collect do |ci|
sqlserver_options = ci.except(:name,:default_value,:type,:null)
SQLServerColumn.new ci[:name], ci[:default_value], ci[:type], ci[:null], sqlserver_options
end
end

def create_table(table_name, options = {})
super
remove_sqlserver_columns_cache_for(table_name)
initialize_sqlserver_caches
end

def rename_table(table_name, new_name)
Expand All @@ -632,12 +632,12 @@ def rename_table(table_name, new_name)

def drop_table(table_name, options = {})
super
remove_sqlserver_columns_cache_for(table_name)
initialize_sqlserver_caches
end

def add_column(table_name, column_name, type, options = {})
super
remove_sqlserver_columns_cache_for(table_name)
initialize_sqlserver_caches
end

def remove_column(table_name, *column_names)
Expand All @@ -647,32 +647,32 @@ def remove_column(table_name, *column_names)
remove_indexes(table_name, column_name)
do_execute "ALTER TABLE #{quote_table_name(table_name)} DROP COLUMN #{quote_column_name(column_name)}"
end
remove_sqlserver_columns_cache_for(table_name)
initialize_sqlserver_caches
end

def change_column(table_name, column_name, type, options = {})
sql_commands = []
remove_default_constraint(table_name, column_name)
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])}"
change_column_sql << " NOT NULL" if options[:null] == false
sql_commands << change_column_sql
if options_include_default?(options)
remove_default_constraint(table_name, column_name)
sql_commands << "ALTER TABLE #{quote_table_name(table_name)} ADD CONSTRAINT #{default_name(table_name,column_name)} DEFAULT #{quote(options[:default])} FOR #{quote_column_name(column_name)}"
end
sql_commands.each { |c| do_execute(c) }
remove_sqlserver_columns_cache_for(table_name)
initialize_sqlserver_caches
end

def change_column_default(table_name, column_name, default)
remove_default_constraint(table_name, column_name)
do_execute "ALTER TABLE #{quote_table_name(table_name)} ADD CONSTRAINT #{default_name(table_name, column_name)} DEFAULT #{quote(default)} FOR #{quote_column_name(column_name)}"
remove_sqlserver_columns_cache_for(table_name)
initialize_sqlserver_caches
end

def rename_column(table_name, column_name, new_column_name)
column_for(table_name,column_name)
do_execute "EXEC sp_rename '#{table_name}.#{column_name}', '#{new_column_name}', 'COLUMN'"
remove_sqlserver_columns_cache_for(table_name)
initialize_sqlserver_caches
end

def remove_index(table_name, options = {})
Expand Down Expand Up @@ -1020,16 +1020,10 @@ def sql_for_association_limiting?(sql)
end
end

def remove_sqlserver_columns_cache_for(table_name)
cache_key = unqualify_table_name(table_name)
@sqlserver_columns_cache[cache_key] = nil
initialize_sqlserver_caches(false)
end

def initialize_sqlserver_caches(reset_columns=true)
@sqlserver_columns_cache = {} if reset_columns
@sqlserver_views_cache = nil
@sqlserver_view_information_cache = {}
def initialize_sqlserver_caches
@@sqlserver_columns_cache = {}
@@sqlserver_views_cache = nil
@@sqlserver_view_information_cache = {}
end

def column_definitions(table_name)
Expand Down
20 changes: 19 additions & 1 deletion test/cases/migration_test_sqlserver.rb
Expand Up @@ -3,10 +3,13 @@

class MigrationTestSqlserver < ActiveRecord::TestCase

def setup
@connection = ActiveRecord::Base.connection
end

context 'For transactions' do

setup do
@connection = ActiveRecord::Base.connection
@trans_test_table1 = 'sqlserver_trans_table1'
@trans_test_table2 = 'sqlserver_trans_table2'
@trans_tables = [@trans_test_table1,@trans_test_table2]
Expand All @@ -30,6 +33,21 @@ class MigrationTestSqlserver < ActiveRecord::TestCase

end

context 'For changing column' do

should 'not raise exception when column contains default constraint' do
lock_version_column = Person.columns_hash['lock_version']
assert_equal :integer, lock_version_column.type
assert lock_version_column.default.present?
assert_nothing_raised { @connection.change_column 'people', 'lock_version', :string }
Person.reset_column_information
lock_version_column = Person.columns_hash['lock_version']
assert_equal :string, lock_version_column.type
assert lock_version_column.default.nil?
end

end


end

Expand Down

0 comments on commit ad83df8

Please sign in to comment.