rails-sqlserver-2000-2005-adapter 2.2.0 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG CHANGED
@@ -1,25 +1,19 @@
1
1
 
2
- sqlserver_adapter.rb -- ActiveRecord adapter for Microsoft SQL Server
2
+ *MASTER* ()
3
3
 
4
- Author: Joey Gibson <joey@joeygibson.com>
5
- Date: 10/14/2004
4
+ *
6
5
 
7
- Modifications: DeLynn Berry <delynnb@megastarfinancial.com>
8
- Date: 3/22/2005
9
6
 
10
- Modifications (ODBC): Mark Imbriaco <mark.imbriaco@pobox.com>
11
- Date: 6/26/2005
7
+ *2.2.1* (November 25th, 2008)
12
8
 
13
- Modifications (Migrations): Tom Ward <tom@popdog.net>
14
- Date: 27/10/2005
9
+ * Add identity insert support for views. Cache #views so that identity #table_name_or_views_table_name
10
+ will run quickly. [Ken Collins]
15
11
 
16
- Modifications (Numerous fixes as maintainer): Ryan Tomayko <rtomayko@gmail.com>
17
- Date: Up to July 2006
12
+ * Add views support. ActiveRecord classes can use views. The connection now has a #views method and
13
+ #table_exists? will not fall back to checking views too. [Ken Collins]
18
14
 
19
- Previous maintainer: Tom Ward <tom@popdog.net>
20
15
 
16
+ *2.2.0* (November 21st, 2008)
21
17
 
18
+ * Release for rails 2.2.2. Many many changes. [Ken Collins], [Murray Steele], [Shawn Balestracci], [Joe Rafaniello]
22
19
 
23
-
24
-
25
- Current (interim/unofficial) maintainer: Shawn Balestracci <shawn@vegantech.com>
data/README.rdoc CHANGED
@@ -80,7 +80,7 @@ It should be noted that this version of the adapter was developed using both the
80
80
 
81
81
  $ gem install dbi --version 0.4.0
82
82
  $ gem install dbd-odbc --version 0.2.4
83
- $ gem install rails-sqlserver-2000-2005-adapter
83
+ $ gem install rails-sqlserver-2000-2005-adapter -s http://gems.github.com
84
84
 
85
85
  Optionally configure your gem dependencies in your rails environment.rb file.
86
86
 
@@ -167,7 +167,7 @@ module ActiveRecord
167
167
  def initialize(connection, logger, connection_options=nil)
168
168
  super(connection, logger)
169
169
  @connection_options = connection_options
170
- @sqlserver_columns_cache = {}
170
+ initialize_sqlserver_caches
171
171
  unless SUPPORTED_VERSIONS.include?(database_year)
172
172
  raise NotImplementedError, "Currently, only #{SUPPORTED_VERSIONS.to_sentence} are supported."
173
173
  end
@@ -446,6 +446,24 @@ module ActiveRecord
446
446
  select_values "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME <> 'dtproperties'"
447
447
  end
448
448
 
449
+ def views(name = nil)
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
461
+ end
462
+
463
+ def table_exists?(table_name)
464
+ super || views.include?(table_name.to_s)
465
+ end
466
+
449
467
  def indexes(table_name, name = nil)
450
468
  select("EXEC sp_helpindex #{quote_table_name(table_name)}",name).inject([]) do |indexes,index|
451
469
  if index['index_description'] =~ /primary key/
@@ -733,6 +751,7 @@ module ActiveRecord
733
751
  # IDENTITY INSERTS =========================================#
734
752
 
735
753
  def with_identity_insert_enabled(table_name, &block)
754
+ table_name = table_name_or_views_table_name(table_name)
736
755
  set_identity_insert(table_name, true)
737
756
  yield
738
757
  ensure
@@ -760,6 +779,11 @@ module ActiveRecord
760
779
  columns(table_name).detect(&:is_identity?)
761
780
  end
762
781
 
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
+
763
787
  # HELPER METHODS ===========================================#
764
788
 
765
789
  def insert_sql?(sql)
@@ -815,6 +839,12 @@ module ActiveRecord
815
839
  def remove_sqlserver_columns_cache_for(table_name)
816
840
  cache_key = unqualify_table_name(table_name)
817
841
  @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
818
848
  end
819
849
 
820
850
  def column_definitions(table_name)
@@ -5,7 +5,7 @@ module ActiveRecord
5
5
  def self.included(klass)
6
6
  klass.extend ClassMethods
7
7
  class << klass
8
- alias_method_chain :reset_column_information, :sqlserver_columns_cache_support
8
+ alias_method_chain :reset_column_information, :sqlserver_cache_support
9
9
  alias_method_chain :add_order!, :sqlserver_unique_checking
10
10
  end
11
11
  end
@@ -28,9 +28,9 @@ module ActiveRecord
28
28
  read_inheritable_attribute(:coerced_sqlserver_time_columns) || []
29
29
  end
30
30
 
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
34
34
  end
35
35
 
36
36
  private
@@ -351,6 +351,78 @@ class AdapterTestSqlserver < ActiveRecord::TestCase
351
351
 
352
352
  end
353
353
 
354
+ context 'For views' do
355
+
356
+ context 'using @connection.views' do
357
+
358
+ should 'return an array' do
359
+ assert_instance_of Array, @connection.views
360
+ end
361
+
362
+ should 'find CustomersView table name' do
363
+ assert_contains @connection.views, 'customers_view'
364
+ end
365
+
366
+ should 'not contain system views' do
367
+ systables = ['sysconstraints','syssegments']
368
+ systables.each do |systable|
369
+ assert !@connection.views.include?(systable), "This systable #{systable} should not be in the views array."
370
+ end
371
+ end
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
+
384
+ end
385
+
386
+ context 'used by a class for table_name' do
387
+
388
+ should 'yield column objects' do
389
+ assert !CustomersView.columns.blank?
390
+ ['id','name','balance'].each do |colname|
391
+ assert_instance_of ActiveRecord::ConnectionAdapters::SQLServerColumn,
392
+ CustomersView.columns_hash[colname], "Column name #{colname.inspect} was not found"
393
+ end
394
+ end
395
+
396
+ should 'yield all column objects having the correct table name' do
397
+ assert CustomersView.columns.all?{ |c| c.table_name == 'customers_view' }
398
+ end
399
+
400
+ should 'respond true to table_exists?' do
401
+ assert CustomersView.table_exists?
402
+ end
403
+
404
+ end
405
+
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
+
423
+ end
424
+
425
+
354
426
 
355
427
  private
356
428
 
@@ -19,6 +19,7 @@ class TableWithRealColumn < ActiveRecord::Base; end
19
19
  class FkTestHasFk < ActiveRecord::Base ; end
20
20
  class FkTestHasPk < ActiveRecord::Base ; end
21
21
  class NumericData < ActiveRecord::Base ; self.table_name = 'numeric_data' ; end
22
+ class CustomersView < ActiveRecord::Base ; self.table_name = 'customers_view' ; end
22
23
  class SqlServerUnicode < ActiveRecord::Base ; end
23
24
  class SqlServerString < ActiveRecord::Base ; end
24
25
  class SqlServerChronic < ActiveRecord::Base
@@ -12,7 +12,6 @@ class TableNameTestSqlserver < ActiveRecord::TestCase
12
12
 
13
13
  should 'load columns with escaped table name for model' do
14
14
  assert_equal 4, Order.columns.length
15
-
16
15
  end
17
16
 
18
17
  should 'not re-escape table name if it is escaped already for SQL queries' do
@@ -61,4 +61,12 @@ ActiveRecord::Schema.define do
61
61
  # TODO: Add some different native binary types and test.
62
62
  end
63
63
 
64
+ execute "IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = 'customers_view') DROP VIEW customers_view"
65
+ execute <<-CUSTOMERSVIEW
66
+ CREATE VIEW customers_view AS
67
+ SELECT id, name, balance
68
+ FROM customers
69
+ CUSTOMERSVIEW
70
+
71
+
64
72
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-sqlserver-2000-2005-adapter
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ken Collins
@@ -13,7 +13,7 @@ autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
15
 
16
- date: 2008-11-21 00:00:00 -08:00
16
+ date: 2008-11-25 00:00:00 -08:00
17
17
  default_executable:
18
18
  dependencies: []
19
19