Skip to content

Commit 404f70c

Browse files
committed
Add identity insert support for views. Cache #views so that identity #table_name_or_views_table_name will run quickly.
1 parent 613fcf9 commit 404f70c

File tree

4 files changed

+62
-8
lines changed

4 files changed

+62
-8
lines changed

CHANGELOG

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11

22
*MASTER* ()
33

4-
*
4+
* Add identity insert support for views. Cache #views so that identity #table_name_or_views_table_name
5+
will run quickly. [Ken Collins]
6+
7+
* Add views support. ActiveRecord classes can use views. The connection now has a #views method and
8+
#table_exists? will not fall back to checking views too. [Ken Collins]
59

610

711
*2.2.0* (November 21st, 2008)

lib/active_record/connection_adapters/sqlserver_adapter.rb

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ def type_limitable?(type)
167167
def initialize(connection, logger, connection_options=nil)
168168
super(connection, logger)
169169
@connection_options = connection_options
170-
@sqlserver_columns_cache = {}
170+
initialize_sqlserver_caches
171171
unless SUPPORTED_VERSIONS.include?(database_year)
172172
raise NotImplementedError, "Currently, only #{SUPPORTED_VERSIONS.to_sentence} are supported."
173173
end
@@ -447,7 +447,17 @@ def tables(name = nil)
447447
end
448448

449449
def views(name = nil)
450-
select_values "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'VIEW' AND TABLE_NAME NOT IN ('sysconstraints','syssegments')"
450+
@sqlserver_views_cache ||=
451+
select_values "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME NOT IN ('sysconstraints','syssegments')"
452+
end
453+
454+
def view_information(table_name)
455+
select_one "SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = '#{table_name}'"
456+
end
457+
458+
def view_table_name(table_name)
459+
view_info = view_information(table_name)
460+
view_info ? get_table_name(view_info['VIEW_DEFINITION']) : table_name
451461
end
452462

453463
def table_exists?(table_name)
@@ -741,6 +751,7 @@ def default_name(table_name, column_name)
741751
# IDENTITY INSERTS =========================================#
742752

743753
def with_identity_insert_enabled(table_name, &block)
754+
table_name = table_name_or_views_table_name(table_name)
744755
set_identity_insert(table_name, true)
745756
yield
746757
ensure
@@ -768,6 +779,11 @@ def identity_column(table_name)
768779
columns(table_name).detect(&:is_identity?)
769780
end
770781

782+
def table_name_or_views_table_name(table_name)
783+
unquoted_table_name = unqualify_table_name(table_name)
784+
views.include?(unquoted_table_name) ? view_table_name(unquoted_table_name) : table_name
785+
end
786+
771787
# HELPER METHODS ===========================================#
772788

773789
def insert_sql?(sql)
@@ -823,6 +839,12 @@ def sql_for_association_limiting?(sql)
823839
def remove_sqlserver_columns_cache_for(table_name)
824840
cache_key = unqualify_table_name(table_name)
825841
@sqlserver_columns_cache[cache_key] = nil
842+
initialize_sqlserver_caches(false)
843+
end
844+
845+
def initialize_sqlserver_caches(reset_columns=true)
846+
@sqlserver_columns_cache = {} if reset_columns
847+
@sqlserver_views_cache = nil
826848
end
827849

828850
def column_definitions(table_name)

lib/core_ext/active_record.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module SQLServerActiveRecordExtensions
55
def self.included(klass)
66
klass.extend ClassMethods
77
class << klass
8-
alias_method_chain :reset_column_information, :sqlserver_columns_cache_support
8+
alias_method_chain :reset_column_information, :sqlserver_cache_support
99
alias_method_chain :add_order!, :sqlserver_unique_checking
1010
end
1111
end
@@ -28,9 +28,9 @@ def coerced_sqlserver_time_columns
2828
read_inheritable_attribute(:coerced_sqlserver_time_columns) || []
2929
end
3030

31-
def reset_column_information_with_sqlserver_columns_cache_support
32-
connection.instance_variable_set :@sqlserver_columns_cache, {}
33-
reset_column_information_without_sqlserver_columns_cache_support
31+
def reset_column_information_with_sqlserver_cache_support
32+
connection.send(:initialize_sqlserver_caches)
33+
reset_column_information_without_sqlserver_cache_support
3434
end
3535

3636
private

test/cases/adapter_test_sqlserver.rb

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,18 @@ def setup
369369
assert !@connection.views.include?(systable), "This systable #{systable} should not be in the views array."
370370
end
371371
end
372-
372+
373+
should 'allow the connection.view_information method to return meta data on the view' do
374+
view_info = @connection.view_information('customers_view')
375+
assert_equal('customers_view', view_info['TABLE_NAME'])
376+
assert_match(/CREATE VIEW customers_view/, view_info['VIEW_DEFINITION'])
377+
end
378+
379+
should 'allow the connection.view_table_name method to return true table_name for the view' do
380+
assert_equal 'customers', @connection.view_table_name('customers_view')
381+
assert_equal 'topics', @connection.view_table_name('topics'), 'No view here, the same table name should come back.'
382+
end
383+
373384
end
374385

375386
context 'used by a class for table_name' do
@@ -392,6 +403,23 @@ def setup
392403

393404
end
394405

406+
context 'doing identity inserts' do
407+
408+
setup do
409+
@view_insert_sql = "INSERT INTO [customers_view] ([id],[name],[balance]) VALUES (420,'Microsoft',0)"
410+
end
411+
412+
should 'respond true/tablename to #query_requires_identity_insert?' do
413+
assert_equal '[customers_view]', @connection.send(:query_requires_identity_insert?,@view_insert_sql)
414+
end
415+
416+
should 'be able to do an identity insert' do
417+
assert_nothing_raised { @connection.execute(@view_insert_sql) }
418+
assert CustomersView.find(420)
419+
end
420+
421+
end
422+
395423
end
396424

397425

0 commit comments

Comments
 (0)