activerecord-sqlserver-adapter 4.2.18 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -223
- data/Gemfile +18 -17
- data/RAILS5-TODO.md +36 -0
- data/README.md +27 -8
- data/RUNNING_UNIT_TESTS.md +0 -17
- data/Rakefile +2 -7
- data/VERSION +1 -1
- data/activerecord-sqlserver-adapter.gemspec +1 -1
- data/appveyor.yml +0 -2
- data/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +15 -8
- data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +45 -97
- data/lib/active_record/connection_adapters/sqlserver/database_tasks.rb +1 -2
- data/lib/active_record/connection_adapters/sqlserver/quoting.rb +31 -10
- data/lib/active_record/connection_adapters/sqlserver/schema_creation.rb +0 -18
- data/lib/active_record/connection_adapters/sqlserver/schema_dumper.rb +16 -0
- data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +101 -58
- data/lib/active_record/connection_adapters/sqlserver/showplan.rb +7 -7
- data/lib/active_record/connection_adapters/sqlserver/sql_type_metadata.rb +20 -0
- data/lib/active_record/connection_adapters/sqlserver/table_definition.rb +56 -32
- data/lib/active_record/connection_adapters/sqlserver/transaction.rb +1 -1
- data/lib/active_record/connection_adapters/sqlserver/type.rb +34 -32
- data/lib/active_record/connection_adapters/sqlserver/type/big_integer.rb +4 -0
- data/lib/active_record/connection_adapters/sqlserver/type/binary.rb +6 -0
- data/lib/active_record/connection_adapters/sqlserver/type/boolean.rb +3 -0
- data/lib/active_record/connection_adapters/sqlserver/type/char.rb +9 -20
- data/lib/active_record/connection_adapters/sqlserver/type/data.rb +30 -0
- data/lib/active_record/connection_adapters/sqlserver/type/date.rb +28 -4
- data/lib/active_record/connection_adapters/sqlserver/type/datetime.rb +28 -14
- data/lib/active_record/connection_adapters/sqlserver/type/datetime2.rb +2 -2
- data/lib/active_record/connection_adapters/sqlserver/type/datetimeoffset.rb +4 -16
- data/lib/active_record/connection_adapters/sqlserver/type/decimal.rb +9 -0
- data/lib/active_record/connection_adapters/sqlserver/type/float.rb +4 -0
- data/lib/active_record/connection_adapters/sqlserver/type/integer.rb +3 -0
- data/lib/active_record/connection_adapters/sqlserver/type/money.rb +5 -1
- data/lib/active_record/connection_adapters/sqlserver/type/real.rb +4 -0
- data/lib/active_record/connection_adapters/sqlserver/type/small_integer.rb +3 -1
- data/lib/active_record/connection_adapters/sqlserver/type/small_money.rb +5 -1
- data/lib/active_record/connection_adapters/sqlserver/type/smalldatetime.rb +8 -1
- data/lib/active_record/connection_adapters/sqlserver/type/text.rb +4 -0
- data/lib/active_record/connection_adapters/sqlserver/type/time.rb +20 -8
- data/lib/active_record/connection_adapters/sqlserver/type/time_value_fractional.rb +25 -10
- data/lib/active_record/connection_adapters/sqlserver/type/timestamp.rb +4 -0
- data/lib/active_record/connection_adapters/sqlserver/type/tiny_integer.rb +3 -0
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_char.rb +6 -0
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_text.rb +4 -0
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_varchar.rb +7 -1
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_varchar_max.rb +5 -1
- data/lib/active_record/connection_adapters/sqlserver/type/uuid.rb +15 -2
- data/lib/active_record/connection_adapters/sqlserver/type/varbinary.rb +7 -1
- data/lib/active_record/connection_adapters/sqlserver/type/varbinary_max.rb +5 -1
- data/lib/active_record/connection_adapters/sqlserver/type/varchar.rb +7 -1
- data/lib/active_record/connection_adapters/sqlserver/type/varchar_max.rb +5 -1
- data/lib/active_record/connection_adapters/sqlserver/utils.rb +10 -0
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +71 -57
- data/lib/active_record/connection_adapters/sqlserver_column.rb +5 -30
- data/lib/active_record/sqlserver_base.rb +1 -5
- data/lib/arel/visitors/sqlserver.rb +11 -20
- data/test/bin/setup.sh +4 -6
- data/test/cases/adapter_test_sqlserver.rb +11 -20
- data/test/cases/coerced_tests.rb +233 -138
- data/test/cases/column_test_sqlserver.rb +244 -227
- data/test/cases/connection_test_sqlserver.rb +5 -76
- data/test/cases/fully_qualified_identifier_test_sqlserver.rb +7 -7
- data/test/cases/helper_sqlserver.rb +4 -15
- data/test/cases/pessimistic_locking_test_sqlserver.rb +1 -1
- data/test/cases/rake_test_sqlserver.rb +20 -14
- data/test/cases/schema_dumper_test_sqlserver.rb +94 -63
- data/test/cases/schema_test_sqlserver.rb +2 -2
- data/test/cases/showplan_test_sqlserver.rb +1 -1
- data/test/cases/specific_schema_test_sqlserver.rb +7 -14
- data/test/cases/transaction_test_sqlserver.rb +1 -1
- data/test/cases/uuid_test_sqlserver.rb +0 -1
- data/test/config.yml +0 -10
- data/test/migrations/transaction_table/1_table_will_never_be_created.rb +1 -1
- data/test/schema/sqlserver_specific_schema.rb +0 -16
- data/test/support/coerceable_test_sqlserver.rb +6 -2
- data/test/support/connection_reflection.rb +0 -4
- data/test/support/sql_counter_sqlserver.rb +17 -21
- metadata +9 -7
- data/lib/active_record/connection_adapters/sqlserver/core_ext/odbc.rb +0 -34
- data/lib/active_record/connection_adapters/sqlserver/schema_cache.rb +0 -114
@@ -13,8 +13,8 @@ class SchemaTestSQLServer < ActiveRecord::TestCase
|
|
13
13
|
describe 'When table is in non-dbo schema' do
|
14
14
|
|
15
15
|
it 'work with table exists' do
|
16
|
-
assert connection.
|
17
|
-
assert connection.
|
16
|
+
assert connection.data_source_exists?('test.sst_schema_natural_id')
|
17
|
+
assert connection.data_source_exists?('[test].[sst_schema_natural_id]')
|
18
18
|
end
|
19
19
|
|
20
20
|
it 'find primary key for tables with odd schema' do
|
@@ -19,7 +19,7 @@ class ShowplanTestSQLServer < ActiveRecord::TestCase
|
|
19
19
|
plan.must_include "Clustered Index Seek", 'make sure we do not showplan the sp_executesql'
|
20
20
|
end
|
21
21
|
|
22
|
-
it 'from prepared statement
|
22
|
+
it 'from prepared statement' do
|
23
23
|
plan = Car.where(name: ',').limit(1).explain
|
24
24
|
plan.must_include " SELECT [cars].* FROM [cars] WHERE [cars].[name]"
|
25
25
|
plan.must_include "TOP EXPRESSION", 'make sure we do not showplan the sp_executesql'
|
@@ -45,7 +45,7 @@ class SpecificSchemaTestSQLServer < ActiveRecord::TestCase
|
|
45
45
|
|
46
46
|
it 'default strings before save' do
|
47
47
|
default = SSTestStringDefault.new
|
48
|
-
|
48
|
+
assert_nil default.string_with_null_default
|
49
49
|
assert_equal 'null', default.string_with_pretend_null_one
|
50
50
|
assert_equal '(null)', default.string_with_pretend_null_two
|
51
51
|
assert_equal 'NULL', default.string_with_pretend_null_three
|
@@ -55,7 +55,7 @@ class SpecificSchemaTestSQLServer < ActiveRecord::TestCase
|
|
55
55
|
|
56
56
|
it 'default strings after save' do
|
57
57
|
default = SSTestStringDefault.create
|
58
|
-
|
58
|
+
assert_nil default.string_with_null_default
|
59
59
|
assert_equal 'null', default.string_with_pretend_null_one
|
60
60
|
assert_equal '(null)', default.string_with_pretend_null_two
|
61
61
|
assert_equal 'NULL', default.string_with_pretend_null_three
|
@@ -94,7 +94,7 @@ class SpecificSchemaTestSQLServer < ActiveRecord::TestCase
|
|
94
94
|
end
|
95
95
|
|
96
96
|
it 'use primary key for row table order in pagination sql' do
|
97
|
-
sql = /ORDER BY \[sst_natural_pk_data\]\.\[legacy_id\] ASC OFFSET
|
97
|
+
sql = /ORDER BY \[sst_natural_pk_data\]\.\[legacy_id\] ASC OFFSET @0 ROWS FETCH NEXT @1 ROWS ONLY/
|
98
98
|
assert_sql(sql) { SSTestNaturalPkData.limit(5).offset(5).load }
|
99
99
|
end
|
100
100
|
|
@@ -117,9 +117,10 @@ class SpecificSchemaTestSQLServer < ActiveRecord::TestCase
|
|
117
117
|
assert_sql(/@0 = 'T'/) { SSTestDatatypeMigration.where(char_col: value.new).first }
|
118
118
|
assert_sql(/@0 = 'T'/) { SSTestDatatypeMigration.where(varchar_col: value.new).first }
|
119
119
|
# Using our custom char type data.
|
120
|
-
|
121
|
-
|
122
|
-
assert_sql(/@0 = 'T'/) { SSTestDatatypeMigration.where(
|
120
|
+
type = ActiveRecord::Type::SQLServer::Char
|
121
|
+
data = ActiveRecord::Type::SQLServer::Data
|
122
|
+
assert_sql(/@0 = 'T'/) { SSTestDatatypeMigration.where(char_col: data.new('T', type.new)).first }
|
123
|
+
assert_sql(/@0 = 'T'/) { SSTestDatatypeMigration.where(varchar_col: data.new('T', type.new)).first }
|
123
124
|
# Taking care of everything.
|
124
125
|
assert_sql(/@0 = 'T'/) { SSTestDatatypeMigration.where(char_col: 'T').first }
|
125
126
|
assert_sql(/@0 = 'T'/) { SSTestDatatypeMigration.where(varchar_col: 'T').first }
|
@@ -164,12 +165,4 @@ class SpecificSchemaTestSQLServer < ActiveRecord::TestCase
|
|
164
165
|
db_uuid.must_match(acceptable_uuid)
|
165
166
|
end
|
166
167
|
|
167
|
-
# with similar table definition in two schemas
|
168
|
-
|
169
|
-
it 'returns the correct primary columns' do
|
170
|
-
connection = ActiveRecord::Base.connection
|
171
|
-
assert_equal 'field_1', connection.columns('test.sst_schema_test_mulitple_schema').detect(&:is_primary?).name
|
172
|
-
assert_equal 'field_2', connection.columns('test2.sst_schema_test_mulitple_schema').detect(&:is_primary?).name
|
173
|
-
end
|
174
|
-
|
175
168
|
end
|
data/test/config.yml
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
default_connection: dblib
|
2
1
|
|
3
2
|
default_connection_info: &default_connection_info
|
4
3
|
adapter: sqlserver
|
@@ -30,12 +29,3 @@ connections:
|
|
30
29
|
azure: <%= !ENV['ACTIVERECORD_UNITTEST_AZURE'].nil? %>
|
31
30
|
timeout: <%= ENV['ACTIVERECORD_UNITTEST_AZURE'].present? ? 20 : nil %>
|
32
31
|
|
33
|
-
odbc:
|
34
|
-
arunit:
|
35
|
-
<<: *default_connection_info
|
36
|
-
dsn: <%= ENV['ACTIVERECORD_UNITTEST_DSN'] || 'activerecord_unittest' %>
|
37
|
-
arunit2:
|
38
|
-
<<: *default_connection_info
|
39
|
-
database: activerecord_unittest2
|
40
|
-
dsn: <%= ENV['ACTIVERECORD_UNITTEST2_DSN'] || 'activerecord_unittest2' %>
|
41
|
-
|
@@ -2,7 +2,7 @@ class TableWillNeverBeCreated < ActiveRecord::Migration
|
|
2
2
|
|
3
3
|
def self.up
|
4
4
|
create_table(:sqlserver_trans_table1) { }
|
5
|
-
create_table(:sqlserver_trans_table2) { raise
|
5
|
+
create_table(:sqlserver_trans_table2) { raise('HELL') }
|
6
6
|
end
|
7
7
|
|
8
8
|
def self.down
|
@@ -204,20 +204,4 @@ ActiveRecord::Schema.define do
|
|
204
204
|
)
|
205
205
|
NATURALPKTABLESQLINOTHERSCHEMA
|
206
206
|
|
207
|
-
execute "IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'sst_schema_test_mulitple_schema' and TABLE_SCHEMA = 'test') DROP TABLE test.sst_schema_test_mulitple_schema"
|
208
|
-
execute <<-SCHEMATESTMULTIPLESCHEMA
|
209
|
-
CREATE TABLE test.sst_schema_test_mulitple_schema(
|
210
|
-
field_1 int NOT NULL PRIMARY KEY,
|
211
|
-
field_2 int,
|
212
|
-
)
|
213
|
-
SCHEMATESTMULTIPLESCHEMA
|
214
|
-
execute "IF NOT EXISTS(SELECT * FROM sys.schemas WHERE name = 'test2') EXEC sp_executesql N'CREATE SCHEMA test2'"
|
215
|
-
execute "IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'sst_schema_test_mulitple_schema' and TABLE_SCHEMA = 'test2') DROP TABLE test2.sst_schema_test_mulitple_schema"
|
216
|
-
execute <<-SCHEMATESTMULTIPLESCHEMA
|
217
|
-
CREATE TABLE test2.sst_schema_test_mulitple_schema(
|
218
|
-
field_1 int,
|
219
|
-
field_2 int NOT NULL PRIMARY KEY,
|
220
|
-
)
|
221
|
-
SCHEMATESTMULTIPLESCHEMA
|
222
|
-
|
223
207
|
end
|
@@ -25,7 +25,7 @@ module ARTest
|
|
25
25
|
undef_method(method)
|
26
26
|
once = true
|
27
27
|
end
|
28
|
-
STDOUT.puts "
|
28
|
+
STDOUT.puts "🙉 🙈 🙊 Undefined all tests: #{self.name}"
|
29
29
|
end
|
30
30
|
|
31
31
|
private
|
@@ -34,7 +34,11 @@ module ARTest
|
|
34
34
|
method = instance_methods(false).select { |m| m =~ method } if method.is_a?(Regexp)
|
35
35
|
Array(method).each do |m|
|
36
36
|
result = undef_method(m) if m && method_defined?(m)
|
37
|
-
|
37
|
+
if result.blank?
|
38
|
+
STDOUT.puts "🐳 Unfound coerced test: #{self.name}##{m}"
|
39
|
+
else
|
40
|
+
STDOUT.puts "🐵 Undefined coerced test: #{self.name}##{m}"
|
41
|
+
end
|
38
42
|
end
|
39
43
|
end
|
40
44
|
|
@@ -1,32 +1,28 @@
|
|
1
1
|
module ARTest
|
2
2
|
module SQLServer
|
3
3
|
|
4
|
-
|
4
|
+
module SqlCounterSqlserver
|
5
5
|
|
6
|
-
|
6
|
+
# Only return the log vs. log_all
|
7
|
+
def capture_sql_ss
|
8
|
+
ActiveRecord::SQLCounter.clear_log
|
9
|
+
yield
|
10
|
+
ActiveRecord::SQLCounter.log.dup
|
11
|
+
end
|
7
12
|
|
8
|
-
def ignored_sql
|
9
|
-
[ /SELECT SCOPE_IDENTITY/,
|
10
|
-
/INFORMATION_SCHEMA\.(TABLES|VIEWS|COLUMNS)/,
|
11
|
-
/SELECT @@version/,
|
12
|
-
/SELECT @@TRANCOUNT/,
|
13
|
-
/(BEGIN|COMMIT|ROLLBACK|SAVE) TRANSACTION/,
|
14
|
-
/SELECT CAST\(.* AS .*\) AS value/ ]
|
15
13
|
end
|
16
14
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
15
|
+
ignored_sql = [
|
16
|
+
/INFORMATION_SCHEMA\.(TABLES|VIEWS|COLUMNS)/im,
|
17
|
+
/SELECT @@version/,
|
18
|
+
/SELECT @@TRANCOUNT/,
|
19
|
+
/(BEGIN|COMMIT|ROLLBACK|SAVE) TRANSACTION/,
|
20
|
+
/SELECT CAST\(.* AS .*\) AS value/,
|
21
|
+
/SELECT DATABASEPROPERTYEX/im
|
22
|
+
]
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
end
|
24
|
+
sqlcounter = ObjectSpace.each_object(ActiveRecord::SQLCounter).to_a.first
|
25
|
+
sqlcounter.instance_variable_set :@ignore, Regexp.union(ignored_sql.push(sqlcounter.ignore))
|
26
26
|
|
27
27
|
end
|
28
28
|
end
|
29
|
-
|
30
|
-
ActiveRecord::SQLCounter.ignored_sql.concat ARTest::SQLServer.ignored_sql
|
31
|
-
ARTest::SQLServer.sql_counter_listenters_unsubscribe
|
32
|
-
ARTest::SQLServer.sql_counter_listenter = ActiveSupport::Notifications.subscribe 'sql.active_record', ActiveRecord::SQLCounter.new
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-sqlserver-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ken Collins
|
@@ -14,7 +14,7 @@ authors:
|
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
|
-
date: 2017-
|
17
|
+
date: 2017-01-16 00:00:00.000000000 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: activerecord
|
@@ -22,14 +22,14 @@ dependencies:
|
|
22
22
|
requirements:
|
23
23
|
- - "~>"
|
24
24
|
- !ruby/object:Gem::Version
|
25
|
-
version:
|
25
|
+
version: 5.0.0
|
26
26
|
type: :runtime
|
27
27
|
prerelease: false
|
28
28
|
version_requirements: !ruby/object:Gem::Requirement
|
29
29
|
requirements:
|
30
30
|
- - "~>"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
32
|
+
version: 5.0.0
|
33
33
|
description: ActiveRecord SQL Server Adapter. SQL Server 2012 and upward.
|
34
34
|
email:
|
35
35
|
- ken@metaskills.net
|
@@ -45,6 +45,7 @@ files:
|
|
45
45
|
- Gemfile
|
46
46
|
- Guardfile
|
47
47
|
- MIT-LICENSE
|
48
|
+
- RAILS5-TODO.md
|
48
49
|
- README.md
|
49
50
|
- RUNNING_UNIT_TESTS.md
|
50
51
|
- Rakefile
|
@@ -56,18 +57,18 @@ files:
|
|
56
57
|
- lib/active_record/connection_adapters/sqlserver/core_ext/attribute_methods.rb
|
57
58
|
- lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb
|
58
59
|
- lib/active_record/connection_adapters/sqlserver/core_ext/explain_subscriber.rb
|
59
|
-
- lib/active_record/connection_adapters/sqlserver/core_ext/odbc.rb
|
60
60
|
- lib/active_record/connection_adapters/sqlserver/database_limits.rb
|
61
61
|
- lib/active_record/connection_adapters/sqlserver/database_statements.rb
|
62
62
|
- lib/active_record/connection_adapters/sqlserver/database_tasks.rb
|
63
63
|
- lib/active_record/connection_adapters/sqlserver/errors.rb
|
64
64
|
- lib/active_record/connection_adapters/sqlserver/quoting.rb
|
65
|
-
- lib/active_record/connection_adapters/sqlserver/schema_cache.rb
|
66
65
|
- lib/active_record/connection_adapters/sqlserver/schema_creation.rb
|
66
|
+
- lib/active_record/connection_adapters/sqlserver/schema_dumper.rb
|
67
67
|
- lib/active_record/connection_adapters/sqlserver/schema_statements.rb
|
68
68
|
- lib/active_record/connection_adapters/sqlserver/showplan.rb
|
69
69
|
- lib/active_record/connection_adapters/sqlserver/showplan/printer_table.rb
|
70
70
|
- lib/active_record/connection_adapters/sqlserver/showplan/printer_xml.rb
|
71
|
+
- lib/active_record/connection_adapters/sqlserver/sql_type_metadata.rb
|
71
72
|
- lib/active_record/connection_adapters/sqlserver/table_definition.rb
|
72
73
|
- lib/active_record/connection_adapters/sqlserver/transaction.rb
|
73
74
|
- lib/active_record/connection_adapters/sqlserver/type.rb
|
@@ -75,6 +76,7 @@ files:
|
|
75
76
|
- lib/active_record/connection_adapters/sqlserver/type/binary.rb
|
76
77
|
- lib/active_record/connection_adapters/sqlserver/type/boolean.rb
|
77
78
|
- lib/active_record/connection_adapters/sqlserver/type/char.rb
|
79
|
+
- lib/active_record/connection_adapters/sqlserver/type/data.rb
|
78
80
|
- lib/active_record/connection_adapters/sqlserver/type/date.rb
|
79
81
|
- lib/active_record/connection_adapters/sqlserver/type/datetime.rb
|
80
82
|
- lib/active_record/connection_adapters/sqlserver/type/datetime2.rb
|
@@ -194,7 +196,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
194
196
|
version: '0'
|
195
197
|
requirements: []
|
196
198
|
rubyforge_project:
|
197
|
-
rubygems_version: 2.6.
|
199
|
+
rubygems_version: 2.6.4
|
198
200
|
signing_key:
|
199
201
|
specification_version: 4
|
200
202
|
summary: ActiveRecord SQL Server Adapter.
|
@@ -1,34 +0,0 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module ConnectionAdapters
|
3
|
-
module SQLServer
|
4
|
-
module CoreExt
|
5
|
-
module ODBC
|
6
|
-
|
7
|
-
module Statement
|
8
|
-
|
9
|
-
def finished?
|
10
|
-
connected?
|
11
|
-
false
|
12
|
-
rescue ::ODBC::Error
|
13
|
-
true
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
17
|
-
|
18
|
-
module Database
|
19
|
-
|
20
|
-
def run_block(*args)
|
21
|
-
yield sth = run(*args)
|
22
|
-
sth.drop
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
ODBC::Statement.send :include, ActiveRecord::ConnectionAdapters::SQLServer::CoreExt::ODBC::Statement
|
34
|
-
ODBC::Database.send :include, ActiveRecord::ConnectionAdapters::SQLServer::CoreExt::ODBC::Database
|
@@ -1,114 +0,0 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module ConnectionAdapters
|
3
|
-
module SQLServer
|
4
|
-
class SchemaCache < ActiveRecord::ConnectionAdapters::SchemaCache
|
5
|
-
|
6
|
-
def initialize(conn)
|
7
|
-
super
|
8
|
-
@views = {}
|
9
|
-
@view_information = {}
|
10
|
-
end
|
11
|
-
|
12
|
-
# Superclass Overrides
|
13
|
-
|
14
|
-
def primary_keys(table_name)
|
15
|
-
name = key(table_name)
|
16
|
-
@primary_keys[name] ||= table_exists?(table_name) ? connection.primary_key(table_name) : nil
|
17
|
-
end
|
18
|
-
|
19
|
-
def table_exists?(table_name)
|
20
|
-
name = key(table_name)
|
21
|
-
prepare_tables_and_views
|
22
|
-
return @tables[name] if @tables.key? name
|
23
|
-
table_exists = @tables[name] = connection.table_exists?(table_name)
|
24
|
-
table_exists || view_exists?(table_name)
|
25
|
-
end
|
26
|
-
|
27
|
-
def tables(name)
|
28
|
-
super(key(name))
|
29
|
-
end
|
30
|
-
|
31
|
-
def columns(table_name)
|
32
|
-
name = key(table_name)
|
33
|
-
@columns[name] ||= connection.columns(table_name)
|
34
|
-
end
|
35
|
-
|
36
|
-
def columns_hash(table_name)
|
37
|
-
name = key(table_name)
|
38
|
-
@columns_hash[name] ||= Hash[columns(table_name).map { |col|
|
39
|
-
[col.name, col]
|
40
|
-
}]
|
41
|
-
end
|
42
|
-
|
43
|
-
def clear!
|
44
|
-
super
|
45
|
-
@views.clear
|
46
|
-
@view_information.clear
|
47
|
-
end
|
48
|
-
|
49
|
-
def size
|
50
|
-
super + [@views, @view_information].map{ |x| x.size }.inject(:+)
|
51
|
-
end
|
52
|
-
|
53
|
-
def clear_table_cache!(table_name)
|
54
|
-
name = key(table_name)
|
55
|
-
@columns.delete name
|
56
|
-
@columns_hash.delete name
|
57
|
-
@primary_keys.delete name
|
58
|
-
@tables.delete name
|
59
|
-
@views.delete name
|
60
|
-
@view_information.delete name
|
61
|
-
end
|
62
|
-
|
63
|
-
def marshal_dump
|
64
|
-
super + [@views, @view_information]
|
65
|
-
end
|
66
|
-
|
67
|
-
def marshal_load(array)
|
68
|
-
@views, @view_information = array[-2..-1]
|
69
|
-
super(array[0..-3])
|
70
|
-
end
|
71
|
-
|
72
|
-
# SQL Server Specific
|
73
|
-
|
74
|
-
def view_exists?(table_name)
|
75
|
-
name = key(table_name)
|
76
|
-
prepare_tables_and_views
|
77
|
-
return @views[name] if @views.key? name
|
78
|
-
@views[name] = connection.views.include?(table_name)
|
79
|
-
end
|
80
|
-
|
81
|
-
def view_information(table_name)
|
82
|
-
name = key(table_name)
|
83
|
-
return @view_information[name] if @view_information.key? name
|
84
|
-
@view_information[name] = connection.send(:view_information, table_name)
|
85
|
-
end
|
86
|
-
|
87
|
-
|
88
|
-
private
|
89
|
-
|
90
|
-
def identifier(table_name)
|
91
|
-
SQLServer::Utils.extract_identifiers(table_name)
|
92
|
-
end
|
93
|
-
|
94
|
-
def key(table_name)
|
95
|
-
identifier(table_name).quoted
|
96
|
-
end
|
97
|
-
|
98
|
-
def prepare_tables_and_views
|
99
|
-
prepare_views if @views.empty?
|
100
|
-
prepare_tables if @tables.empty?
|
101
|
-
end
|
102
|
-
|
103
|
-
def prepare_tables
|
104
|
-
connection.tables.each { |table| @tables[key(table)] = true }
|
105
|
-
end
|
106
|
-
|
107
|
-
def prepare_views
|
108
|
-
connection.views.each { |view| @views[key(view)] = true }
|
109
|
-
end
|
110
|
-
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|