activerecord-sqlserver-adapter 4.2.1 → 4.2.2
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 -0
- data/README.md +1 -8
- data/RUNNING_UNIT_TESTS.md +7 -0
- data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +1 -66
- data/lib/active_record/connection_adapters/sqlserver/database_tasks.rb +44 -0
- data/lib/active_record/connection_adapters/sqlserver/version.rb +1 -1
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +8 -11
- data/lib/active_record/tasks/sqlserver_database_tasks.rb +131 -0
- data/test/cases/coerced_tests.rb +14 -0
- data/test/cases/helper_sqlserver.rb +4 -1
- data/test/cases/rake_test_sqlserver.rb +140 -0
- metadata +6 -4
- data/test/cases/database_statements_test_sqlserver.rb +0 -57
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5811725caa7db8c0ded035b59882c3e2826b6a6
|
4
|
+
data.tar.gz: 0637b1351f167da700e236db923a624fe0a35a98
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bfef051e6a63017c57bd179dfebb7d04ab612b1a008caabe86b7a2281093a713aa302781a17f9f735f6da8ae046ebd9f9648244aa50f1ce1569ce4e518e99a6b
|
7
|
+
data.tar.gz: d0e8537fbc6a3be2f406e18ac6aa64e9e5e2eec51d0aaaed57469104bdb98652cff1b8647d7f0e6d913422273463143ff7e3ba4fc315bcf90211f5436a5eb2fb
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -8,14 +8,7 @@
|
|
8
8
|
|
9
9
|
## Code Name Kantishna
|
10
10
|
|
11
|
-
The SQL Server adapter for ActiveRecord. If you need the adapter for SQL Server 2008 or 2005, you are still in the right spot. Just install the latest 3.2.x to 4.1.x version of the adapter. We follow a rational versioning policy that tracks ActiveRecord. That means that our 4.2.x version of the adapter is only for the latest 4.2 version of Rails. We also have stable branches for each major/minor release of ActiveRecord.
|
12
|
-
|
13
|
-
|
14
|
-
#### Testing Rake Tasks Support
|
15
|
-
|
16
|
-
This is a long story, but if you are not working with a legacy database and you can trust your schema.rb to setup your local development or test database, then we have adapter level support for rails :db rake tasks. Please read this wiki page for full details.
|
17
|
-
|
18
|
-
http://wiki.github.com/rails-sqlserver/activerecord-sqlserver-adapter/rails-db-rake-tasks
|
11
|
+
The SQL Server adapter for ActiveRecord v4.2 using SQL Server 2012 or higher. If you need the adapter for SQL Server 2008 or 2005, you are still in the right spot. Just install the latest 3.2.x to 4.1.x version of the adapter. We follow a rational versioning policy that tracks ActiveRecord. That means that our 4.2.x version of the adapter is only for the latest 4.2 version of Rails. We also have stable branches for each major/minor release of ActiveRecord.
|
19
12
|
|
20
13
|
|
21
14
|
#### Executing Stored Procedures
|
data/RUNNING_UNIT_TESTS.md
CHANGED
@@ -100,6 +100,13 @@ $ bundle exec rake test:odbc
|
|
100
100
|
By default, Bundler will download the Rails git repo and use the git tag that matches the dependency version in our gemspec. If you want to test another version of Rails, you can either temporarily change the :tag for Rails in the Gemfile. Likewise, you can clone the Rails repo your self to another directory and use the `RAILS_SOURCE` environment variable.
|
101
101
|
|
102
102
|
|
103
|
+
## Troubleshooting
|
104
|
+
|
105
|
+
* Make sure your firewall is off or allows SQL Server traffic both ways, typically on port 1433.
|
106
|
+
* Ensure that you are running on a local admin login to create the Rails user.
|
107
|
+
* Possibly change the SQL Server TCP/IP properties in "SQL Server Configuration Manager -> SQL Server Network Configuration -> Protocols for MSSQLSERVER", and ensure that TCP/IP is enabled and the appropriate entries on the "IP Addresses" tab are enabled.
|
108
|
+
|
109
|
+
|
103
110
|
## Current Expected Failures
|
104
111
|
|
105
112
|
* Misc Date/Time erros when using ODBC mode.
|
@@ -192,71 +192,6 @@ module ActiveRecord
|
|
192
192
|
select_value 'SELECT NEWSEQUENTIALID()'
|
193
193
|
end
|
194
194
|
|
195
|
-
# === SQLServer Specific (Rake/Test Helpers) ==================== #
|
196
|
-
|
197
|
-
def recreate_database
|
198
|
-
remove_database_connections_and_rollback do
|
199
|
-
do_execute "EXEC sp_MSforeachtable 'DROP TABLE ?'"
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
def recreate_database!(database = nil)
|
204
|
-
database ||= current_database
|
205
|
-
drop_database(database)
|
206
|
-
create_database(database)
|
207
|
-
ensure
|
208
|
-
use_database(database)
|
209
|
-
end
|
210
|
-
|
211
|
-
def drop_database(database)
|
212
|
-
retry_count = 0
|
213
|
-
max_retries = 1
|
214
|
-
name = SQLServer::Utils.extract_identifiers(database)
|
215
|
-
begin
|
216
|
-
do_execute "
|
217
|
-
USE master
|
218
|
-
IF EXISTS (
|
219
|
-
SELECT * FROM [sys].[databases]
|
220
|
-
WHERE name = #{quote(name.object)}
|
221
|
-
) DROP DATABASE #{name}
|
222
|
-
".squish
|
223
|
-
rescue ActiveRecord::StatementInvalid => err
|
224
|
-
if err.message =~ /because it is currently in use/i
|
225
|
-
raise if retry_count >= max_retries
|
226
|
-
retry_count += 1
|
227
|
-
remove_database_connections_and_rollback(database)
|
228
|
-
retry
|
229
|
-
elsif err.message =~ /does not exist/i
|
230
|
-
nil
|
231
|
-
else
|
232
|
-
raise
|
233
|
-
end
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
|
-
def create_database(database, options = {})
|
238
|
-
name = SQLServer::Utils.extract_identifiers(database)
|
239
|
-
options = {collation: @connection_options[:collation]}.merge!(options.symbolize_keys)
|
240
|
-
options = options.select { |_, v| v.present? }
|
241
|
-
option_string = options.inject("") do |memo, (key, value)|
|
242
|
-
memo += case key
|
243
|
-
when :collation
|
244
|
-
" COLLATE #{value}"
|
245
|
-
else
|
246
|
-
""
|
247
|
-
end
|
248
|
-
end
|
249
|
-
do_execute "CREATE DATABASE #{name}#{option_string}"
|
250
|
-
end
|
251
|
-
|
252
|
-
def current_database
|
253
|
-
select_value 'SELECT DB_NAME()'
|
254
|
-
end
|
255
|
-
|
256
|
-
def charset
|
257
|
-
select_value "SELECT SERVERPROPERTY('SqlCharSetName')"
|
258
|
-
end
|
259
|
-
|
260
195
|
|
261
196
|
protected
|
262
197
|
|
@@ -265,7 +200,7 @@ module ActiveRecord
|
|
265
200
|
end
|
266
201
|
|
267
202
|
def sql_for_insert(sql, pk, id_value, sequence_name, binds)
|
268
|
-
sql = if pk
|
203
|
+
sql = if pk && self.class.use_output_inserted
|
269
204
|
quoted_pk = SQLServer::Utils.extract_identifiers(pk).quoted
|
270
205
|
sql.insert sql.index(/ (DEFAULT )?VALUES/), " OUTPUT INSERTED.#{quoted_pk}"
|
271
206
|
else
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ConnectionAdapters
|
3
|
+
module SQLServer
|
4
|
+
module DatabaseTasks
|
5
|
+
|
6
|
+
def create_database(database, options = {})
|
7
|
+
name = SQLServer::Utils.extract_identifiers(database)
|
8
|
+
options = {collation: @connection_options[:collation]}.merge!(options.symbolize_keys)
|
9
|
+
options = options.select { |_, v| v.present? }
|
10
|
+
option_string = options.inject("") do |memo, (key, value)|
|
11
|
+
memo += case key
|
12
|
+
when :collation
|
13
|
+
" COLLATE #{value}"
|
14
|
+
else
|
15
|
+
""
|
16
|
+
end
|
17
|
+
end
|
18
|
+
do_execute "CREATE DATABASE #{name}#{option_string}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def drop_database(database)
|
22
|
+
name = SQLServer::Utils.extract_identifiers(database)
|
23
|
+
do_execute "DROP DATABASE #{name}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def current_database
|
27
|
+
select_value 'SELECT DB_NAME()'
|
28
|
+
end
|
29
|
+
|
30
|
+
def charset
|
31
|
+
select_value "SELECT DATABASEPROPERTYEX(DB_NAME(), 'SqlCharSetName')"
|
32
|
+
end
|
33
|
+
|
34
|
+
def collation
|
35
|
+
select_value "SELECT DATABASEPROPERTYEX(DB_NAME(), 'Collation')"
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
|
@@ -10,6 +10,7 @@ require 'active_record/connection_adapters/sqlserver/version'
|
|
10
10
|
require 'active_record/connection_adapters/sqlserver/type'
|
11
11
|
require 'active_record/connection_adapters/sqlserver/database_limits'
|
12
12
|
require 'active_record/connection_adapters/sqlserver/database_statements'
|
13
|
+
require 'active_record/connection_adapters/sqlserver/database_tasks'
|
13
14
|
require 'active_record/connection_adapters/sqlserver/transaction'
|
14
15
|
require 'active_record/connection_adapters/sqlserver/errors'
|
15
16
|
require 'active_record/connection_adapters/sqlserver/schema_cache'
|
@@ -21,6 +22,7 @@ require 'active_record/connection_adapters/sqlserver/quoting'
|
|
21
22
|
require 'active_record/connection_adapters/sqlserver/utils'
|
22
23
|
require 'active_record/sqlserver_base'
|
23
24
|
require 'active_record/connection_adapters/sqlserver_column'
|
25
|
+
require 'active_record/tasks/sqlserver_database_tasks'
|
24
26
|
|
25
27
|
module ActiveRecord
|
26
28
|
module ConnectionAdapters
|
@@ -31,16 +33,19 @@ module ActiveRecord
|
|
31
33
|
SQLServer::DatabaseStatements,
|
32
34
|
SQLServer::Showplan,
|
33
35
|
SQLServer::SchemaStatements,
|
34
|
-
SQLServer::DatabaseLimits
|
36
|
+
SQLServer::DatabaseLimits,
|
37
|
+
SQLServer::DatabaseTasks
|
35
38
|
|
36
39
|
ADAPTER_NAME = 'SQLServer'.freeze
|
37
40
|
|
38
41
|
attr_reader :spid
|
39
42
|
|
40
43
|
cattr_accessor :cs_equality_operator, instance_accessor: false
|
44
|
+
cattr_accessor :use_output_inserted, instance_accessor: false
|
41
45
|
cattr_accessor :lowercase_schema_reflection, :showplan_option
|
42
46
|
|
43
47
|
self.cs_equality_operator = 'COLLATE Latin1_General_CS_AS_WS'
|
48
|
+
self.use_output_inserted = true
|
44
49
|
|
45
50
|
def initialize(connection, logger, pool, config)
|
46
51
|
super(connection, logger, pool)
|
@@ -250,6 +255,8 @@ module ActiveRecord
|
|
250
255
|
InvalidForeignKey.new(message, e)
|
251
256
|
when /has been chosen as the deadlock victim/i
|
252
257
|
DeadlockVictim.new(message, e)
|
258
|
+
when /database .* does not exist/i
|
259
|
+
NoDatabaseError.new(message, e)
|
253
260
|
else
|
254
261
|
super
|
255
262
|
end
|
@@ -350,16 +357,6 @@ module ActiveRecord
|
|
350
357
|
::Time::DATE_FORMATS[:_sqlserver_dateformat] = dateformat
|
351
358
|
end
|
352
359
|
|
353
|
-
def remove_database_connections_and_rollback(database = nil)
|
354
|
-
name = SQLServer::Utils.extract_identifiers(database || current_database)
|
355
|
-
do_execute "ALTER DATABASE #{name} SET SINGLE_USER WITH ROLLBACK IMMEDIATE"
|
356
|
-
begin
|
357
|
-
yield
|
358
|
-
ensure
|
359
|
-
do_execute "ALTER DATABASE #{name} SET MULTI_USER"
|
360
|
-
end if block_given?
|
361
|
-
end
|
362
|
-
|
363
360
|
end
|
364
361
|
end
|
365
362
|
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'active_record/tasks/database_tasks'
|
2
|
+
require 'shellwords'
|
3
|
+
require 'ipaddr'
|
4
|
+
require 'socket'
|
5
|
+
|
6
|
+
module ActiveRecord
|
7
|
+
module Tasks
|
8
|
+
|
9
|
+
class SQLServerDatabaseTasks
|
10
|
+
|
11
|
+
DEFAULT_COLLATION = 'SQL_Latin1_General_CP1_CI_AS'
|
12
|
+
|
13
|
+
delegate :connection, :establish_connection, :clear_active_connections!,
|
14
|
+
to: ActiveRecord::Base
|
15
|
+
|
16
|
+
def initialize(configuration)
|
17
|
+
@configuration = configuration
|
18
|
+
end
|
19
|
+
|
20
|
+
def create(master_established = false)
|
21
|
+
establish_master_connection unless master_established
|
22
|
+
connection.create_database configuration['database'], configuration.merge('collation' => default_collation)
|
23
|
+
establish_connection configuration
|
24
|
+
rescue ActiveRecord::StatementInvalid => error
|
25
|
+
if /database .* already exists/i === error.message
|
26
|
+
raise DatabaseAlreadyExists
|
27
|
+
else
|
28
|
+
raise
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def drop
|
33
|
+
establish_master_connection
|
34
|
+
connection.drop_database configuration['database']
|
35
|
+
end
|
36
|
+
|
37
|
+
def charset
|
38
|
+
connection.charset
|
39
|
+
end
|
40
|
+
|
41
|
+
def collation
|
42
|
+
connection.collation
|
43
|
+
end
|
44
|
+
|
45
|
+
def purge
|
46
|
+
clear_active_connections!
|
47
|
+
drop
|
48
|
+
create true
|
49
|
+
end
|
50
|
+
|
51
|
+
def structure_dump(filename)
|
52
|
+
command = [
|
53
|
+
"defncopy",
|
54
|
+
"-S #{Shellwords.escape(configuration['host'])}",
|
55
|
+
"-D #{Shellwords.escape(configuration['database'])}",
|
56
|
+
"-U #{Shellwords.escape(configuration['username'])}",
|
57
|
+
"-P #{Shellwords.escape(configuration['password'])}",
|
58
|
+
"-o #{Shellwords.escape(filename)}",
|
59
|
+
]
|
60
|
+
table_args = connection.tables.map { |t| Shellwords.escape(t) }
|
61
|
+
command.concat(table_args)
|
62
|
+
view_args = connection.views.map { |v| Shellwords.escape(v) }
|
63
|
+
command.concat(view_args)
|
64
|
+
raise 'Error dumping database' unless Kernel.system(command.join(' '))
|
65
|
+
dump = File.read(filename)
|
66
|
+
dump.gsub!(/^USE .*$\nGO\n/, '') # Strip db USE statements
|
67
|
+
dump.gsub!(/^GO\n/, '') # Strip db GO statements
|
68
|
+
dump.gsub!(/nvarchar\(8000\)/, 'nvarchar(4000)') # Fix nvarchar(8000) column defs
|
69
|
+
dump.gsub!(/nvarchar\(-1\)/, 'nvarchar(max)') # Fix nvarchar(-1) column defs
|
70
|
+
dump.gsub!(/text\(\d+\)/, 'text') # Fix text(16) column defs
|
71
|
+
File.open(filename, "w") { |file| file.puts dump }
|
72
|
+
end
|
73
|
+
|
74
|
+
def structure_load(filename)
|
75
|
+
connection.execute File.read(filename)
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def configuration
|
82
|
+
@configuration
|
83
|
+
end
|
84
|
+
|
85
|
+
def default_collation
|
86
|
+
configuration['collation'] || DEFAULT_COLLATION
|
87
|
+
end
|
88
|
+
|
89
|
+
def establish_master_connection
|
90
|
+
establish_connection configuration.merge('database' => 'master')
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
module DatabaseTasksSQLServer
|
96
|
+
|
97
|
+
extend ActiveSupport::Concern
|
98
|
+
|
99
|
+
module ClassMethods
|
100
|
+
|
101
|
+
LOCAL_IPADDR = [
|
102
|
+
IPAddr.new('192.168.0.0/16'),
|
103
|
+
IPAddr.new('10.0.0.0/8'),
|
104
|
+
IPAddr.new('172.16.0.0/12')
|
105
|
+
]
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def local_database?(configuration)
|
110
|
+
super || local_ipaddr?(configuration_host_ip(configuration))
|
111
|
+
end
|
112
|
+
|
113
|
+
def configuration_host_ip(configuration)
|
114
|
+
return nil unless configuration['host']
|
115
|
+
Socket::getaddrinfo(configuration['host'], 'echo', Socket::AF_INET)[0][3]
|
116
|
+
end
|
117
|
+
|
118
|
+
def local_ipaddr?(host_ip)
|
119
|
+
return false unless host_ip
|
120
|
+
LOCAL_IPADDR.any? { |ip| ip.include?(host_ip) }
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
DatabaseTasks.register_task %r{sqlserver}, SQLServerDatabaseTasks
|
128
|
+
DatabaseTasks.send :include, DatabaseTasksSQLServer
|
129
|
+
|
130
|
+
end
|
131
|
+
end
|
data/test/cases/coerced_tests.rb
CHANGED
@@ -222,6 +222,20 @@ end
|
|
222
222
|
|
223
223
|
|
224
224
|
|
225
|
+
module ActiveRecord
|
226
|
+
class DatabaseTasksCreateAllTest < ActiveRecord::TestCase
|
227
|
+
# We extend `local_database?` so that common VM IPs can be used.
|
228
|
+
coerce_tests! :test_ignores_remote_databases, :test_warning_for_remote_databases
|
229
|
+
end
|
230
|
+
class DatabaseTasksDropAllTest < ActiveRecord::TestCase
|
231
|
+
# We extend `local_database?` so that common VM IPs can be used.
|
232
|
+
coerce_tests! :test_ignores_remote_databases, :test_warning_for_remote_databases
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
|
237
|
+
|
238
|
+
|
225
239
|
class DefaultScopingTest < ActiveRecord::TestCase
|
226
240
|
|
227
241
|
# We are not doing order duplicate removal anymore.
|
@@ -15,7 +15,6 @@ module ActiveRecord
|
|
15
15
|
include ARTest::SQLServer::CoerceableTest
|
16
16
|
|
17
17
|
let(:logger) { ActiveRecord::Base.logger }
|
18
|
-
let(:connection) { ActiveRecord::Base.connection }
|
19
18
|
|
20
19
|
class << self
|
21
20
|
def connection_mode_dblib? ; ActiveRecord::Base.connection.instance_variable_get(:@connection_options)[:mode] == :dblib ; end
|
@@ -30,6 +29,10 @@ module ActiveRecord
|
|
30
29
|
def connection_mode_odbc? ; self.class.connection_mode_odbc? ; end
|
31
30
|
def sqlserver_azure? ; self.class.sqlserver_azure? ; end
|
32
31
|
|
32
|
+
def connection
|
33
|
+
ActiveRecord::Base.connection
|
34
|
+
end
|
35
|
+
|
33
36
|
end
|
34
37
|
end
|
35
38
|
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'cases/helper_sqlserver'
|
2
|
+
|
3
|
+
class SQLServerRakeTest < ActiveRecord::TestCase
|
4
|
+
|
5
|
+
self.use_transactional_fixtures = false
|
6
|
+
|
7
|
+
let(:db_tasks) { ActiveRecord::Tasks::DatabaseTasks }
|
8
|
+
let(:new_database) { 'activerecord_unittest_tasks' }
|
9
|
+
let(:default_configuration) { ARTest.connection_config['arunit'] }
|
10
|
+
let(:configuration) { default_configuration.merge('database' => new_database) }
|
11
|
+
|
12
|
+
before do
|
13
|
+
connection.disconnect!
|
14
|
+
end
|
15
|
+
|
16
|
+
after do
|
17
|
+
ActiveRecord::Base.establish_connection(default_configuration)
|
18
|
+
connection.drop_database(new_database) rescue nil
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
class SQLServerRakeCreateTest < SQLServerRakeTest
|
24
|
+
|
25
|
+
it 'establishes connection to database after create ' do
|
26
|
+
db_tasks.create configuration
|
27
|
+
connection.current_database.must_equal(new_database)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'creates database with default collation' do
|
31
|
+
db_tasks.create configuration
|
32
|
+
connection.collation.must_equal 'SQL_Latin1_General_CP1_CI_AS'
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'creates database with given collation' do
|
36
|
+
db_tasks.create configuration.merge('collation' => 'Latin1_General_CI_AS')
|
37
|
+
connection.collation.must_equal 'Latin1_General_CI_AS'
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'prints error message when database exists' do
|
41
|
+
db_tasks.create configuration
|
42
|
+
message = capture(:stderr) { db_tasks.create configuration }
|
43
|
+
message.must_match %r{activerecord_unittest_tasks already exists}
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
class SQLServerRakeDropTest < SQLServerRakeTest
|
49
|
+
|
50
|
+
it 'drops database and uses master' do
|
51
|
+
db_tasks.create configuration
|
52
|
+
db_tasks.drop configuration
|
53
|
+
connection.current_database.must_equal 'master'
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'prints error message when database does not exist' do
|
57
|
+
message = capture(:stderr) { db_tasks.drop configuration.merge('database' => 'doesnotexist') }
|
58
|
+
message.must_match %r{'doesnotexist' does not exist}
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
class SQLServerRakePurgeTest < SQLServerRakeTest
|
64
|
+
|
65
|
+
before do
|
66
|
+
db_tasks.create(configuration)
|
67
|
+
connection.create_table :users, force: true do |t|
|
68
|
+
t.string :name, :email
|
69
|
+
t.timestamps null: false
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'clears active connections, drops database, and recreates with established connection' do
|
74
|
+
connection.current_database.must_equal(new_database)
|
75
|
+
connection.tables.must_include 'users'
|
76
|
+
db_tasks.purge(configuration)
|
77
|
+
connection.current_database.must_equal(new_database)
|
78
|
+
connection.tables.wont_include 'users'
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
class SQLServerRakeCharsetTest < SQLServerRakeTest
|
84
|
+
|
85
|
+
before { db_tasks.create(configuration) }
|
86
|
+
|
87
|
+
it 'retrieves charset' do
|
88
|
+
db_tasks.charset(configuration).must_equal 'iso_1'
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
class SQLServerRakeCollationTest < SQLServerRakeTest
|
94
|
+
|
95
|
+
before { db_tasks.create(configuration) }
|
96
|
+
|
97
|
+
it 'retrieves collation' do
|
98
|
+
db_tasks.collation(configuration).must_equal 'SQL_Latin1_General_CP1_CI_AS'
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
class SQLServerRakeStructureDumpLoadTest < SQLServerRakeTest
|
104
|
+
|
105
|
+
let(:filename) { File.join ARTest::SQLServer.migrations_root, 'structure.sql' }
|
106
|
+
let(:filedata) { File.read(filename) }
|
107
|
+
|
108
|
+
before do
|
109
|
+
db_tasks.create(configuration)
|
110
|
+
connection.create_table :users, force: true do |t|
|
111
|
+
t.string :name, :email
|
112
|
+
t.text :background1
|
113
|
+
t.text_basic :background2
|
114
|
+
t.timestamps null: false
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
after do
|
119
|
+
FileUtils.rm_rf(filename)
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'dumps structure and accounts for defncopy oddities' do
|
123
|
+
db_tasks.structure_dump configuration, filename
|
124
|
+
filedata.wont_match %r{\AUSE.*\z}
|
125
|
+
filedata.wont_match %r{\AGO.*\z}
|
126
|
+
filedata.must_match %r{email\s+nvarchar\(4000\)}
|
127
|
+
filedata.must_match %r{background1\s+nvarchar\(max\)}
|
128
|
+
filedata.must_match %r{background2\s+text\s+}
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'can load dumped structure' do
|
132
|
+
db_tasks.structure_dump configuration, filename
|
133
|
+
filedata.must_match %r{CREATE TABLE dbo\.users}
|
134
|
+
db_tasks.purge(configuration)
|
135
|
+
connection.tables.wont_include 'users'
|
136
|
+
db_tasks.load_schema_for configuration, :sql, filename
|
137
|
+
connection.tables.must_include 'users'
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
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.2.
|
4
|
+
version: 4.2.2
|
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: 2015-
|
17
|
+
date: 2015-02-02 00:00:00.000000000 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: activerecord
|
@@ -180,6 +180,7 @@ files:
|
|
180
180
|
- lib/active_record/connection_adapters/sqlserver/core_ext/odbc.rb
|
181
181
|
- lib/active_record/connection_adapters/sqlserver/database_limits.rb
|
182
182
|
- lib/active_record/connection_adapters/sqlserver/database_statements.rb
|
183
|
+
- lib/active_record/connection_adapters/sqlserver/database_tasks.rb
|
183
184
|
- lib/active_record/connection_adapters/sqlserver/errors.rb
|
184
185
|
- lib/active_record/connection_adapters/sqlserver/quoting.rb
|
185
186
|
- lib/active_record/connection_adapters/sqlserver/schema_cache.rb
|
@@ -228,6 +229,7 @@ files:
|
|
228
229
|
- lib/active_record/connection_adapters/sqlserver_adapter.rb
|
229
230
|
- lib/active_record/connection_adapters/sqlserver_column.rb
|
230
231
|
- lib/active_record/sqlserver_base.rb
|
232
|
+
- lib/active_record/tasks/sqlserver_database_tasks.rb
|
231
233
|
- lib/activerecord-sqlserver-adapter.rb
|
232
234
|
- lib/arel/visitors/sqlserver.rb
|
233
235
|
- lib/arel_sqlserver.rb
|
@@ -235,13 +237,13 @@ files:
|
|
235
237
|
- test/cases/coerced_tests.rb
|
236
238
|
- test/cases/column_test_sqlserver.rb
|
237
239
|
- test/cases/connection_test_sqlserver.rb
|
238
|
-
- test/cases/database_statements_test_sqlserver.rb
|
239
240
|
- test/cases/execute_procedure_test_sqlserver.rb
|
240
241
|
- test/cases/fetch_test_sqlserver.rb
|
241
242
|
- test/cases/helper_sqlserver.rb
|
242
243
|
- test/cases/migration_test_sqlserver.rb
|
243
244
|
- test/cases/order_test_sqlserver.rb
|
244
245
|
- test/cases/pessimistic_locking_test_sqlserver.rb
|
246
|
+
- test/cases/rake_test_sqlserver.rb
|
245
247
|
- test/cases/schema_dumper_test_sqlserver.rb
|
246
248
|
- test/cases/schema_test_sqlserver.rb
|
247
249
|
- test/cases/scratchpad_test_sqlserver.rb
|
@@ -309,13 +311,13 @@ test_files:
|
|
309
311
|
- test/cases/coerced_tests.rb
|
310
312
|
- test/cases/column_test_sqlserver.rb
|
311
313
|
- test/cases/connection_test_sqlserver.rb
|
312
|
-
- test/cases/database_statements_test_sqlserver.rb
|
313
314
|
- test/cases/execute_procedure_test_sqlserver.rb
|
314
315
|
- test/cases/fetch_test_sqlserver.rb
|
315
316
|
- test/cases/helper_sqlserver.rb
|
316
317
|
- test/cases/migration_test_sqlserver.rb
|
317
318
|
- test/cases/order_test_sqlserver.rb
|
318
319
|
- test/cases/pessimistic_locking_test_sqlserver.rb
|
320
|
+
- test/cases/rake_test_sqlserver.rb
|
319
321
|
- test/cases/schema_dumper_test_sqlserver.rb
|
320
322
|
- test/cases/schema_test_sqlserver.rb
|
321
323
|
- test/cases/scratchpad_test_sqlserver.rb
|
@@ -1,57 +0,0 @@
|
|
1
|
-
require 'cases/helper_sqlserver'
|
2
|
-
|
3
|
-
class DatabaseStatementsTestSQLServer < ActiveRecord::TestCase
|
4
|
-
|
5
|
-
self.use_transactional_fixtures = false
|
6
|
-
|
7
|
-
after { connection.use_database }
|
8
|
-
|
9
|
-
it 'create database' do
|
10
|
-
connection.create_database 'activerecord_unittest3'
|
11
|
-
database_name = connection.select_value "SELECT name FROM master.dbo.sysdatabases WHERE name = 'activerecord_unittest3'"
|
12
|
-
assert_equal 'activerecord_unittest3', database_name
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'drop database' do
|
16
|
-
connection.drop_database 'activerecord_unittest3'
|
17
|
-
database_name = connection.select_value "SELECT name FROM master.dbo.sysdatabases WHERE name = 'activerecord_unittest3'"
|
18
|
-
assert_equal nil, database_name
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'create/use/drop database with name with dots' do
|
22
|
-
connection.drop_database '[activerecord.unittest]' rescue nil
|
23
|
-
connection.create_database '[activerecord.unittest]'
|
24
|
-
database_name = connection.select_value "SELECT name FROM master.dbo.sysdatabases WHERE name = 'activerecord.unittest'"
|
25
|
-
assert_equal 'activerecord.unittest', database_name
|
26
|
-
connection.use_database '[activerecord.unittest]'
|
27
|
-
connection.use_database
|
28
|
-
connection.drop_database '[activerecord.unittest]'
|
29
|
-
end
|
30
|
-
|
31
|
-
describe 'with collation' do
|
32
|
-
|
33
|
-
after { connection.drop_database 'activerecord_unittest3' }
|
34
|
-
|
35
|
-
it 'create database with default collation for the server' do
|
36
|
-
connection.create_database 'activerecord_unittest3'
|
37
|
-
default_collation = connection.select_value "SELECT SERVERPROPERTY('Collation')"
|
38
|
-
database_collation = connection.select_value "SELECT DATABASEPROPERTYEX('activerecord_unittest3', 'Collation') SQLCollation"
|
39
|
-
assert_equal default_collation, database_collation
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'create database with collation set by the method' do
|
43
|
-
connection.create_database 'activerecord_unittest3', collation: 'SQL_Latin1_General_CP1_CI_AS'
|
44
|
-
collation = connection.select_value "SELECT DATABASEPROPERTYEX('activerecord_unittest3', 'Collation') SQLCollation"
|
45
|
-
assert_equal 'SQL_Latin1_General_CP1_CI_AS', collation
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'create database with collation set by the config' do
|
49
|
-
connection.instance_variable_get(:@connection_options)[:collation] = 'SQL_Latin1_General_CP1_CI_AS'
|
50
|
-
connection.create_database 'activerecord_unittest3'
|
51
|
-
collation = connection.select_value "SELECT DATABASEPROPERTYEX('activerecord_unittest3', 'Collation') SQLCollation"
|
52
|
-
assert_equal 'SQL_Latin1_General_CP1_CI_AS', collation
|
53
|
-
end
|
54
|
-
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|