activerecord-sqlserver-adapter 3.2.10 → 3.2.11
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 +89 -69
- data/VERSION +1 -1
- data/lib/active_record/connection_adapters/sqlserver/core_ext/explain_subscriber.rb +26 -0
- data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +43 -33
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +103 -95
- metadata +10 -9
data/CHANGELOG
CHANGED
@@ -1,4 +1,24 @@
|
|
1
1
|
|
2
|
+
* 3.2.11 *
|
3
|
+
|
4
|
+
* Handle "No such column" when renaming some columns in the migrations. Fixes #237. Thanks @michelgrootjans.
|
5
|
+
* Update regex for `RecordNotUnique` exception. Fixes #257. Thanks @pbatorre.
|
6
|
+
* Pass tds_version to TinyTDS. Fixes #233. Thanks @denispeplin.
|
7
|
+
* Use CONCAT_NULL_YIELDS_NULL for all TinyTDS connections. Fixes #262. Thanks @noel.
|
8
|
+
* Fix for Azure SQL. Fixed #263. Thanks @eklipse2k8.
|
9
|
+
* Drop shoulda and use minitest-spec-rails!!!
|
10
|
+
* Test TinyTDS 0.6.0.
|
11
|
+
* Fixed the unit tests due to changes in ActiveRecord that removes blank config values.
|
12
|
+
* Fixed explain tests that were failing due to changes in ExplainSubscriber, cause was regex
|
13
|
+
* Fixed change_column to update existing table column rows with new default value if there are any NULL values
|
14
|
+
and the column does not accept nulls
|
15
|
+
* Fixed change_column to drop and add indexes if the colun type is changes
|
16
|
+
* Fixed string_to_binary and binary_to_string in some cases where the binary data is not UTF-8
|
17
|
+
* Fixing generating profile report to create output dir if needed, and code change for printing report
|
18
|
+
* Adding ruby-prof to Gemfile, needed when running profile test cases
|
19
|
+
* Updating mocha to work with newer ActiveRecord test cases
|
20
|
+
|
21
|
+
|
2
22
|
* 3.2.10 *
|
3
23
|
|
4
24
|
* Remove connection defaults for host/username/password. Since we want to suppoert Windows Authentication
|
@@ -67,7 +87,7 @@
|
|
67
87
|
|
68
88
|
* 3.2.0 *
|
69
89
|
|
70
|
-
* ActiveRecord explain (SHOWPLAN) support.
|
90
|
+
* ActiveRecord explain (SHOWPLAN) support.
|
71
91
|
http://youtu.be/ckb3YYZZZ2Q
|
72
92
|
|
73
93
|
* Remove our log_info_schema_queries config since we are not hooking properly into AR's 'SCHEMA' names.
|
@@ -86,7 +106,7 @@
|
|
86
106
|
|
87
107
|
* 3.1.4 *
|
88
108
|
|
89
|
-
* Use INFORMATION_SCHEMA.KEY_COLUMN_USAGE for schema reflection speed.
|
109
|
+
* Use INFORMATION_SCHEMA.KEY_COLUMN_USAGE for schema reflection speed.
|
90
110
|
Fixes #125. [Wüthrich Hannes @hwuethrich]
|
91
111
|
|
92
112
|
* New deadlock victim retry using the #retry_deadlock_victim config. [Jason Frey, Joe Rafaniello]
|
@@ -98,10 +118,10 @@
|
|
98
118
|
|
99
119
|
* Add methods for sqlserver's #product_version, #product_level, #edition and include them in inspect.
|
100
120
|
Fixes #145 [Jason Frey, Joe Rafaniello]
|
101
|
-
|
102
|
-
* Handle statements that cannot be retried on a new database connection by not reconnecting.
|
121
|
+
|
122
|
+
* Handle statements that cannot be retried on a new database connection by not reconnecting.
|
103
123
|
Fixes #147 [Jason Frey, Joe Rafaniello]
|
104
|
-
|
124
|
+
|
105
125
|
* Added connection#spid for debugging. Fixes #144 [Jason Frey, Joe Rafaniello]
|
106
126
|
|
107
127
|
* Add ENV['TEST_FILES'] to Rakefile for easy single case tests. [Jason Frey, Joe Rafaniello]
|
@@ -117,7 +137,7 @@
|
|
117
137
|
|
118
138
|
* 3.1.3 *
|
119
139
|
|
120
|
-
* Distinguish between identity and primary key key columns during schema reflection. Allows us
|
140
|
+
* Distinguish between identity and primary key key columns during schema reflection. Allows us
|
121
141
|
us to only do identity inserts when technically needed. Fixes #139 [chadcf] & [joncanady]
|
122
142
|
|
123
143
|
|
@@ -138,7 +158,7 @@
|
|
138
158
|
|
139
159
|
* Make #rollback_db_transaction smarter.
|
140
160
|
|
141
|
-
* Provide a method to override for the quoted string prefix. Not a config because trumping this method will
|
161
|
+
* Provide a method to override for the quoted string prefix. Not a config because trumping this method will
|
142
162
|
have drastically bad results. Fixes #124
|
143
163
|
|
144
164
|
* Allow :limit/:offset to be used with fully qualified table and column in :select.
|
@@ -151,12 +171,12 @@
|
|
151
171
|
* Make auto reconnect duration configurable. Fixes #109 [David Chelimsky]
|
152
172
|
|
153
173
|
* Quote most time objects to use ISO8601 format to be multi-language dateformat compatible. The [datetime] data type is
|
154
|
-
automatically limited to milliseconds while [time] & [datetimeoffset] have full support. Even included a Date/Time
|
174
|
+
automatically limited to milliseconds while [time] & [datetimeoffset] have full support. Even included a Date/Time
|
155
175
|
ActiveSupport formatter that is used per the language settings of the connection.
|
156
176
|
|
157
177
|
* Include a visit_Arel_Nodes_UpdateStatement method in our Arel visitor to add a limit/top for update
|
158
178
|
that has order and no limit/top. https://github.com/rails/rails/commit/787194ee43ab1fb0a7dc8bfbbfbd5079b047d833
|
159
|
-
|
179
|
+
|
160
180
|
* Allow drop_database to be called even when DB does not exist.
|
161
181
|
|
162
182
|
* Remove totally broken ADONET connection mode. Want it back, submit a patch.
|
@@ -218,7 +238,7 @@
|
|
218
238
|
* Support for ActiveRecord v3.0.3 and ARel v2.0.7
|
219
239
|
|
220
240
|
|
221
|
-
* 3.0.7 *
|
241
|
+
* 3.0.7 *
|
222
242
|
|
223
243
|
* Properly quote table names when reflecting on views.
|
224
244
|
|
@@ -258,7 +278,7 @@
|
|
258
278
|
|
259
279
|
* 3.0.1
|
260
280
|
|
261
|
-
* Support DSN'less connections. Resolves ticket 38.
|
281
|
+
* Support DSN'less connections. Resolves ticket 38.
|
262
282
|
|
263
283
|
* Support upcoming ruby odbc 0.99992
|
264
284
|
|
@@ -289,14 +309,14 @@
|
|
289
309
|
|
290
310
|
* 2.3.5
|
291
311
|
|
292
|
-
* Initial IronRuby ADONET connection mode support baked right in. Removed most &block
|
293
|
-
parameters, no handle/request object yielded anymore. Better abstraction and compliance
|
294
|
-
per the ActiveRecord abstract adapter to not yielding handles for #execute and only for
|
295
|
-
low level #select. Better wrapping of all queries at lowest level in #log so exceptions
|
296
|
-
at anytime can be handled correctly by core AR. Critical for System::Data's command
|
297
|
-
readers. Better abstraction for introspecting on #connection_mode. Added support for
|
312
|
+
* Initial IronRuby ADONET connection mode support baked right in. Removed most &block
|
313
|
+
parameters, no handle/request object yielded anymore. Better abstraction and compliance
|
314
|
+
per the ActiveRecord abstract adapter to not yielding handles for #execute and only for
|
315
|
+
low level #select. Better wrapping of all queries at lowest level in #log so exceptions
|
316
|
+
at anytime can be handled correctly by core AR. Critical for System::Data's command
|
317
|
+
readers. Better abstraction for introspecting on #connection_mode. Added support for
|
298
318
|
running singular test cases via TextMate's Command-R. [Ken Collins]
|
299
|
-
|
319
|
+
|
300
320
|
* Force a binary encoding on values coming in and out of those columns for ruby 1.9.
|
301
321
|
Fixes ticket #33 [Jeroen Zwartepoorte]
|
302
322
|
|
@@ -315,22 +335,22 @@
|
|
315
335
|
* For tables that named with schema(ex. rails.users), they could not get length of column.
|
316
336
|
column of varchar(40) gets length => nil. Ticket #27 & #15 [Ken Tachiya]
|
317
337
|
|
318
|
-
* Altered limited_update_conditions regex conditions, the .* would greedily fail
|
338
|
+
* Altered limited_update_conditions regex conditions, the .* would greedily fail
|
319
339
|
if the where_sql had WHERE in a table or field, etc. [Ransom Briggs]
|
320
340
|
|
321
|
-
* Changing test to allow ENV['ARUNIT_DB_NAME'] as the database name for the test units.
|
341
|
+
* Changing test to allow ENV['ARUNIT_DB_NAME'] as the database name for the test units.
|
322
342
|
Matches up with AR conventions. [Ransom Briggs]
|
323
343
|
|
324
344
|
|
325
345
|
2.3.3
|
326
|
-
|
327
|
-
* Revert #ad83df82 and again cache column information at the connection's instance. The
|
346
|
+
|
347
|
+
* Revert #ad83df82 and again cache column information at the connection's instance. The
|
328
348
|
previous commit was causing all sorts of view and schema reflection problems. [Ken Collins]
|
329
349
|
|
330
350
|
|
331
351
|
2.3.2
|
332
352
|
|
333
|
-
* Insert queries that include the word "insert" as a partial column name with the word
|
353
|
+
* Insert queries that include the word "insert" as a partial column name with the word
|
334
354
|
"id" as a value were falsely being matched as identity inserts. [Sean Caffery/bfabry]
|
335
355
|
|
336
356
|
* Delegate all low level #raw_connection calls to #raw_connection_run and #raw_connection_do
|
@@ -348,10 +368,10 @@
|
|
348
368
|
* Coerce a few tests that were failing in 2.3.x [Ken Collins]
|
349
369
|
|
350
370
|
* Change column/view cache to happen at class level. Allows connection pool to share same
|
351
|
-
caches as well as the ability to expire the caches when needed. Also fix change_column so
|
371
|
+
caches as well as the ability to expire the caches when needed. Also fix change_column so
|
352
372
|
that exceptions are not raised when the column contains an existing default. [Ken Collins]
|
353
373
|
|
354
|
-
* Allow query_requires_identity_insert? method to return quoted table name in situations where the
|
374
|
+
* Allow query_requires_identity_insert? method to return quoted table name in situations where the
|
355
375
|
INSERT parts are not quoted themselves. [Gary/iawgens, Richard Penwell, Ken Collins]
|
356
376
|
|
357
377
|
* Fixed namespace in calling test_sqlserver_odbc within test_unicode_types. [Gary/iawgens]
|
@@ -363,7 +383,7 @@
|
|
363
383
|
|
364
384
|
* Support Identity-key-column judgement on multiple schema environment [Ken Tachiya]
|
365
385
|
|
366
|
-
* Add support for tinyint data types. In MySQL all these types would be boolean, however in
|
386
|
+
* Add support for tinyint data types. In MySQL all these types would be boolean, however in
|
367
387
|
our adapter, they will use the full 1 => 255 Fixnum value as you would expect. [Ken Collins]
|
368
388
|
|
369
389
|
|
@@ -381,10 +401,10 @@
|
|
381
401
|
|
382
402
|
* Implement a new remove_default_constraint method that uses sp_helpconstraint [Ken Collins]
|
383
403
|
|
384
|
-
* Use a lazy match in add_order_by_for_association_limiting! to allow sub selects to be used. Resolves
|
404
|
+
* Use a lazy match in add_order_by_for_association_limiting! to allow sub selects to be used. Resolves
|
385
405
|
ticket #11.
|
386
406
|
|
387
|
-
* Add default rake task back for testing. Runs the namespaced sqlserver:test_sqlserver_odbc.
|
407
|
+
* Add default rake task back for testing. Runs the namespaced sqlserver:test_sqlserver_odbc.
|
388
408
|
Resolves ticket #10 [Ken Collins]
|
389
409
|
|
390
410
|
* Default value detection in column_definitions is kinder to badly formatted, or long winded user
|
@@ -397,7 +417,7 @@
|
|
397
417
|
|
398
418
|
* Leave quoted column names as is. Resolves ticket #36 [Vince Puzzella]
|
399
419
|
|
400
|
-
* Changing add_limit! in ActiveRecord::Base for SQLServer so that it passes through any scoped :order
|
420
|
+
* Changing add_limit! in ActiveRecord::Base for SQLServer so that it passes through any scoped :order
|
401
421
|
parameters. Resolves ticket #35 [Murray Steele]
|
402
422
|
|
403
423
|
|
@@ -410,45 +430,45 @@
|
|
410
430
|
|
411
431
|
* 2.2.17 * (May 14th, 2009)
|
412
432
|
|
413
|
-
* Add simplified type recognition for varchar(max) and nvarchar(max) under SQL Server 2005 to be a
|
433
|
+
* Add simplified type recognition for varchar(max) and nvarchar(max) under SQL Server 2005 to be a
|
414
434
|
:text type. This ensures schema dumper does the right thing. Fixes ticket #30. [Ken Collins]
|
415
435
|
|
416
|
-
* Tested ruby 1.9, ruby-odbc 0.9996, and DBI 0.4.1. Also added correct support for UTF-8 character
|
417
|
-
encoding going in and out of the DB. See before gist http://gist.github.com/111709 and after gist
|
436
|
+
* Tested ruby 1.9, ruby-odbc 0.9996, and DBI 0.4.1. Also added correct support for UTF-8 character
|
437
|
+
encoding going in and out of the DB. See before gist http://gist.github.com/111709 and after gist
|
418
438
|
http://gist.github.com/111719 [Ken Collins]
|
419
439
|
|
420
440
|
|
421
441
|
* 2.2.16 * (April 21st, 2009)
|
422
442
|
|
423
|
-
* Make add_limit_offset! only add locking hints (for tally) when the :lock option is present. Added tests
|
424
|
-
to make sure tally SQL is augmented correctly and tests to make sure that add_lock! is doing what it needs
|
443
|
+
* Make add_limit_offset! only add locking hints (for tally) when the :lock option is present. Added tests
|
444
|
+
to make sure tally SQL is augmented correctly and tests to make sure that add_lock! is doing what it needs
|
425
445
|
for deep sub selects in paginated results. [Ken Collins]
|
426
446
|
|
427
|
-
* Add auto reconnect support utilizing a new #with_auto_reconnect block. By default each query run through
|
428
|
-
the adapter will automatically reconnect at standard intervals, logging attempts along the way, till success
|
429
|
-
or the original exception bubbles up. See docs for more details. Resolves ticket #18 [Ken Collins]
|
447
|
+
* Add auto reconnect support utilizing a new #with_auto_reconnect block. By default each query run through
|
448
|
+
the adapter will automatically reconnect at standard intervals, logging attempts along the way, till success
|
449
|
+
or the original exception bubbles up. See docs for more details. Resolves ticket #18 [Ken Collins]
|
430
450
|
|
431
|
-
* Update internal helper method #orders_and_dirs_set to cope with an order clause like "description desc". This
|
451
|
+
* Update internal helper method #orders_and_dirs_set to cope with an order clause like "description desc". This
|
432
452
|
resolves ticket #26 [Ken Collins]
|
433
453
|
|
434
|
-
* Provide support for running queries at different isolation levels using #run_with_isolation_level method
|
435
|
-
that can take a block or not. Also implement a #user_options method that reflects on the current user
|
454
|
+
* Provide support for running queries at different isolation levels using #run_with_isolation_level method
|
455
|
+
that can take a block or not. Also implement a #user_options method that reflects on the current user
|
436
456
|
session values. Resolves #20 [Murray Steele]
|
437
457
|
|
438
458
|
|
439
459
|
* 2.2.15 * (March 23rd, 2009)
|
440
460
|
|
441
|
-
* Better add_lock! method that can add the lock to just about all the elements in the statement. This
|
442
|
-
could be eager loaded associations, joins, etc. Done so that paginated results can easily add lock
|
443
|
-
options for performance. Note, the tally count in add_limit_offset! use "WITH (NOLOCK)" explicitly
|
461
|
+
* Better add_lock! method that can add the lock to just about all the elements in the statement. This
|
462
|
+
could be eager loaded associations, joins, etc. Done so that paginated results can easily add lock
|
463
|
+
options for performance. Note, the tally count in add_limit_offset! use "WITH (NOLOCK)" explicitly
|
444
464
|
as it can not hurt and is needed. [Ken Collins]
|
445
465
|
|
446
466
|
|
447
467
|
* 2.2.14 * (March 17th, 2009)
|
448
468
|
|
449
|
-
* Rails2.3 - Back passing tests on 2.2 work. Includes: (1) Created new test helpers that check ActiveRecord
|
450
|
-
version strings so we can conditionally run 2.2 and 2.3 tests. (2) Making TransactionTestSqlserver use Ship vs
|
451
|
-
Bird model. Also made it conditional run a few blocks for different versions of ActiveRecord. (3) Previous
|
469
|
+
* Rails2.3 - Back passing tests on 2.2 work. Includes: (1) Created new test helpers that check ActiveRecord
|
470
|
+
version strings so we can conditionally run 2.2 and 2.3 tests. (2) Making TransactionTestSqlserver use Ship vs
|
471
|
+
Bird model. Also made it conditional run a few blocks for different versions of ActiveRecord. (3) Previous
|
452
472
|
JoinDependency#aliased_table_name_for is now only patched in ActiveRecord equal or greater than 2.3. [Ken Collins]
|
453
473
|
|
454
474
|
* Rails2.3 - Implement new savepoint support [Ken Collins]
|
@@ -460,24 +480,24 @@
|
|
460
480
|
* Rails2.3 - Implement a custom ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation#aliased_table_name_for
|
461
481
|
method that uses a Regexp.escape so that table/column quoting does not get ignored. [Ken Collins]
|
462
482
|
|
463
|
-
* Rails2.3 - Implement #outside_transaction? and a new transaction test case to test some SQL Server
|
483
|
+
* Rails2.3 - Implement #outside_transaction? and a new transaction test case to test some SQL Server
|
464
484
|
basic support while implementing this method. Future home of some savepoint tests too. [Ken Collins]
|
465
485
|
|
466
|
-
* Rails2.3 - Coerced tests that ensure hash conditions on referenced tables are considered when eager
|
486
|
+
* Rails2.3 - Coerced tests that ensure hash conditions on referenced tables are considered when eager
|
467
487
|
loading with limit/offset. Information on these changes and the ticket in rails are.
|
468
488
|
http://github.com/rails/rails/commit/9a4d557713acb0fc8e80f61af18094034aca029a
|
469
489
|
http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/1404-conditions_tables-doesnt-understand-condition-hashes
|
470
490
|
|
471
491
|
* Rails2.3 - Add coerced tests for true/false attributes in selects use SQL Server case statement. [Ken Collins]
|
472
492
|
|
473
|
-
* Making sure that smalldatetime types are OK to use. Also fixed a bug in the #view_information method that
|
474
|
-
checks to see if a view definition is equal to 4000 chars, meaning that it is most likely truncated and
|
493
|
+
* Making sure that smalldatetime types are OK to use. Also fixed a bug in the #view_information method that
|
494
|
+
checks to see if a view definition is equal to 4000 chars, meaning that it is most likely truncated and
|
475
495
|
needs to use the backup method of sp_helptext to get it's view definition. [Ken Collins]
|
476
496
|
|
477
497
|
|
478
498
|
* 2.2.13 * (February 10th, 2009)
|
479
499
|
|
480
|
-
* Update #indexes to use unqualified table name. Fixes cases where users may decide to use table
|
500
|
+
* Update #indexes to use unqualified table name. Fixes cases where users may decide to use table
|
481
501
|
name prefixes like 'dbo.'. [Ken Collins]
|
482
502
|
|
483
503
|
|
@@ -493,11 +513,11 @@
|
|
493
513
|
|
494
514
|
* 2.2.9 * (January 22nd, 2009)
|
495
515
|
|
496
|
-
* Fixing a small bug in the deprecated DBI::Timestamp conversion so it correctly converts nanosecond whole
|
497
|
-
numbers to back to pre type cast SQL Server milliseconds, ultimately allow ruby's Time#usec which is
|
516
|
+
* Fixing a small bug in the deprecated DBI::Timestamp conversion so it correctly converts nanosecond whole
|
517
|
+
numbers to back to pre type cast SQL Server milliseconds, ultimately allow ruby's Time#usec which is
|
498
518
|
microseconds to be correct. [Ken Collins]
|
499
|
-
|
500
|
-
* Sometimes views are more than 4000 chars long and will return NULL for the VIEW_DEFINITION. If so, use
|
519
|
+
|
520
|
+
* Sometimes views are more than 4000 chars long and will return NULL for the VIEW_DEFINITION. If so, use
|
501
521
|
sp_helptext procedure as a backup method. [Ken Collins]
|
502
522
|
|
503
523
|
|
@@ -508,13 +528,13 @@
|
|
508
528
|
|
509
529
|
* 2.2.7 (January 9th, 2009)
|
510
530
|
|
511
|
-
* Created a connection#execute_procedure method that takes can take any number of ruby objects as variables
|
512
|
-
and quotes them according to the connection's rules. Also added an ActiveRecord::Base class level core
|
513
|
-
extension that hooks into this. It also checks if the connection responds to #execute_procedure and if
|
531
|
+
* Created a connection#execute_procedure method that takes can take any number of ruby objects as variables
|
532
|
+
and quotes them according to the connection's rules. Also added an ActiveRecord::Base class level core
|
533
|
+
extension that hooks into this. It also checks if the connection responds to #execute_procedure and if
|
514
534
|
not returns an empty array. [Ken Collins]
|
515
535
|
|
516
|
-
* Added a #enable_default_unicode_types class attribute access to make all new added or changed string types
|
517
|
-
like :string/:text default to unicode/national data types. See the README for full details. Added a rake
|
536
|
+
* Added a #enable_default_unicode_types class attribute access to make all new added or changed string types
|
537
|
+
like :string/:text default to unicode/national data types. See the README for full details. Added a rake
|
518
538
|
task that assists setting this to true when running tests. [Ken Collins]
|
519
539
|
|
520
540
|
|
@@ -525,15 +545,15 @@
|
|
525
545
|
|
526
546
|
* 2.2.5 (January 4th, 2009)
|
527
547
|
|
528
|
-
* Added a log_info_schema_queries class attribute and make all queries to INFORMATION_SCHEMA silent by
|
548
|
+
* Added a log_info_schema_queries class attribute and make all queries to INFORMATION_SCHEMA silent by
|
529
549
|
default. [Ken Collins]
|
530
550
|
|
531
551
|
* Fix millisecond support in datetime columns. ODBC::Timestamp incorrectly takes SQL Server milliseconds
|
532
|
-
and applies them as nanoseconds. We cope with this at the DBI layer by using SQLServerDBI::Type::SqlserverTimestamp
|
533
|
-
class to parse the before type cast value appropriately. Also update the adapters #quoted_date method
|
552
|
+
and applies them as nanoseconds. We cope with this at the DBI layer by using SQLServerDBI::Type::SqlserverTimestamp
|
553
|
+
class to parse the before type cast value appropriately. Also update the adapters #quoted_date method
|
534
554
|
to work more simply by converting ruby's #usec milliseconds to SQL Server microseconds. [Ken Collins]
|
535
555
|
|
536
|
-
* Core extensions for ActiveRecord now reflect on the connection before doing SQL Server things. Now
|
556
|
+
* Core extensions for ActiveRecord now reflect on the connection before doing SQL Server things. Now
|
537
557
|
this adapter is compatible for using with other adapters. [Ken Collins]
|
538
558
|
|
539
559
|
|
@@ -544,9 +564,9 @@
|
|
544
564
|
|
545
565
|
* 2.2.3 (December 5th, 2008)
|
546
566
|
|
547
|
-
* Changing back to using real table name in column_definitions. Makes sure views get back only the columns
|
548
|
-
that are defined for them with correct names, etc. Now supporting views by looking for NULL default and
|
549
|
-
then if table name is a view, perform a targeted with sub select to the real table name and column name
|
567
|
+
* Changing back to using real table name in column_definitions. Makes sure views get back only the columns
|
568
|
+
that are defined for them with correct names, etc. Now supporting views by looking for NULL default and
|
569
|
+
then if table name is a view, perform a targeted with sub select to the real table name and column name
|
550
570
|
to find true default. [Ken Collins]
|
551
571
|
|
552
572
|
* Ensure that add_limit_offset! does not alter sub queries. [Erik Bryn]
|
@@ -561,10 +581,10 @@
|
|
561
581
|
|
562
582
|
2.2.1 (November 25th, 2008)
|
563
583
|
|
564
|
-
* Add identity insert support for views. Cache #views so that identity #table_name_or_views_table_name
|
584
|
+
* Add identity insert support for views. Cache #views so that identity #table_name_or_views_table_name
|
565
585
|
will run quickly. [Ken Collins]
|
566
586
|
|
567
|
-
* Add views support. ActiveRecord classes can use views. The connection now has a #views method and
|
587
|
+
* Add views support. ActiveRecord classes can use views. The connection now has a #views method and
|
568
588
|
#table_exists? will now fall back to checking views too. [Ken Collins]
|
569
589
|
|
570
590
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.2.
|
1
|
+
3.2.11
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ConnectionAdapters
|
3
|
+
module Sqlserver
|
4
|
+
module CoreExt
|
5
|
+
class ExplainSubscriber
|
6
|
+
def call(*args)
|
7
|
+
if queries = Thread.current[:available_queries_for_explain]
|
8
|
+
payload = args.last
|
9
|
+
queries << payload.values_at(:sql, :binds) unless ignore_sqlserver_payload?(payload)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
IGNORED_PAYLOADS = %w(SCHEMA EXPLAIN CACHE)
|
14
|
+
SQLSERVER_EXPLAINED_SQLS = /(select|update|delete|insert)/i
|
15
|
+
|
16
|
+
# Need to modify the regex for the TSQL generated by this adapter so we can explain the proper sql statements
|
17
|
+
def ignore_sqlserver_payload?(payload)
|
18
|
+
payload[:exception] || IGNORED_PAYLOADS.include?(payload[:name]) || payload[:sql] !~ SQLSERVER_EXPLAINED_SQLS
|
19
|
+
end
|
20
|
+
|
21
|
+
ActiveSupport::Notifications.subscribe("sql.active_record", new)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -2,7 +2,7 @@ module ActiveRecord
|
|
2
2
|
module ConnectionAdapters
|
3
3
|
module Sqlserver
|
4
4
|
module SchemaStatements
|
5
|
-
|
5
|
+
|
6
6
|
def native_database_types
|
7
7
|
@native_database_types ||= initialize_native_database_types.freeze
|
8
8
|
end
|
@@ -43,11 +43,11 @@ module ActiveRecord
|
|
43
43
|
SQLServerColumn.new ci[:name], ci[:default_value], ci[:type], ci[:null], sqlserver_options
|
44
44
|
end
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
def rename_table(table_name, new_name)
|
48
48
|
do_execute "EXEC sp_rename '#{table_name}', '#{new_name}'"
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
def remove_column(table_name, *column_names)
|
52
52
|
raise ArgumentError.new("You must specify at least one column name. Example: remove_column(:people, :first_name)") if column_names.empty?
|
53
53
|
ActiveSupport::Deprecation.warn 'Passing array to remove_columns is deprecated, please use multiple arguments, like: `remove_columns(:posts, :foo, :bar)`', caller if column_names.flatten!
|
@@ -61,16 +61,25 @@ module ActiveRecord
|
|
61
61
|
|
62
62
|
def change_column(table_name, column_name, type, options = {})
|
63
63
|
sql_commands = []
|
64
|
+
indexes = []
|
64
65
|
column_object = schema_cache.columns[table_name].detect { |c| c.name.to_s == column_name.to_s }
|
65
|
-
|
66
|
-
change_column_sql << " NOT NULL" if options[:null] == false
|
67
|
-
sql_commands << change_column_sql
|
66
|
+
|
68
67
|
if options_include_default?(options) || (column_object && column_object.type != type.to_sym)
|
69
|
-
|
68
|
+
remove_default_constraint(table_name,column_name)
|
69
|
+
indexes = indexes(table_name).select{ |index| index.columns.include?(column_name.to_s) }
|
70
|
+
remove_indexes(table_name, column_name)
|
70
71
|
end
|
72
|
+
sql_commands << "UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(options[:default])} WHERE #{quote_column_name(column_name)} IS NULL" if !options[:null].nil? && options[:null] == false && !options[:default].nil?
|
73
|
+
sql_commands << "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
|
74
|
+
sql_commands[-1] << " NOT NULL" if !options[:null].nil? && options[:null] == false
|
71
75
|
if options_include_default?(options)
|
72
76
|
sql_commands << "ALTER TABLE #{quote_table_name(table_name)} ADD CONSTRAINT #{default_constraint_name(table_name,column_name)} DEFAULT #{quote(options[:default])} FOR #{quote_column_name(column_name)}"
|
73
77
|
end
|
78
|
+
|
79
|
+
#Add any removed indexes back
|
80
|
+
indexes.each do |index|
|
81
|
+
sql_commands << "CREATE INDEX #{quote_table_name(index.name)} ON #{quote_table_name(table_name)} (#{index.columns.collect {|c|quote_column_name(c)}.join(', ')})"
|
82
|
+
end
|
74
83
|
sql_commands.each { |c| do_execute(c) }
|
75
84
|
end
|
76
85
|
|
@@ -80,10 +89,11 @@ module ActiveRecord
|
|
80
89
|
end
|
81
90
|
|
82
91
|
def rename_column(table_name, column_name, new_column_name)
|
92
|
+
schema_cache.clear_table_cache!(table_name)
|
83
93
|
detect_column_for! table_name, column_name
|
84
94
|
do_execute "EXEC sp_rename '#{table_name}.#{column_name}', '#{new_column_name}', 'COLUMN'"
|
85
95
|
end
|
86
|
-
|
96
|
+
|
87
97
|
def remove_index!(table_name, index_name)
|
88
98
|
do_execute "DROP INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)}"
|
89
99
|
end
|
@@ -104,27 +114,27 @@ module ActiveRecord
|
|
104
114
|
end
|
105
115
|
end
|
106
116
|
|
107
|
-
def change_column_null(table_name, column_name,
|
117
|
+
def change_column_null(table_name, column_name, allow_null, default = nil)
|
108
118
|
column = detect_column_for! table_name, column_name
|
109
|
-
|
119
|
+
if !allow_null.nil? && allow_null == false && !default.nil?
|
110
120
|
do_execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
|
111
121
|
end
|
112
122
|
sql = "ALTER TABLE #{table_name} ALTER COLUMN #{quote_column_name(column_name)} #{type_to_sql column.type, column.limit, column.precision, column.scale}"
|
113
|
-
sql << " NOT NULL"
|
123
|
+
sql << " NOT NULL" if !allow_null.nil? && allow_null == false
|
114
124
|
do_execute sql
|
115
125
|
end
|
116
|
-
|
126
|
+
|
117
127
|
# === SQLServer Specific ======================================== #
|
118
|
-
|
128
|
+
|
119
129
|
def views
|
120
130
|
tables('VIEW')
|
121
131
|
end
|
122
|
-
|
123
|
-
|
132
|
+
|
133
|
+
|
124
134
|
protected
|
125
|
-
|
135
|
+
|
126
136
|
# === SQLServer Specific ======================================== #
|
127
|
-
|
137
|
+
|
128
138
|
def initialize_native_database_types
|
129
139
|
{
|
130
140
|
:primary_key => "int NOT NULL IDENTITY(1,1) PRIMARY KEY",
|
@@ -156,7 +166,7 @@ module ActiveRecord
|
|
156
166
|
table_schema = Utils.unqualify_table_schema(table_name)
|
157
167
|
table_name = Utils.unqualify_table_name(table_name)
|
158
168
|
sql = %{
|
159
|
-
SELECT DISTINCT
|
169
|
+
SELECT DISTINCT
|
160
170
|
#{lowercase_schema_reflection_sql('columns.TABLE_NAME')} AS table_name,
|
161
171
|
#{lowercase_schema_reflection_sql('columns.COLUMN_NAME')} AS name,
|
162
172
|
columns.DATA_TYPE AS type,
|
@@ -172,7 +182,7 @@ module ActiveRecord
|
|
172
182
|
WHEN columns.IS_NULLABLE = 'YES' THEN 1
|
173
183
|
ELSE NULL
|
174
184
|
END AS [is_nullable],
|
175
|
-
CASE
|
185
|
+
CASE
|
176
186
|
WHEN KCU.COLUMN_NAME IS NOT NULL AND TC.CONSTRAINT_TYPE = N'PRIMARY KEY' THEN 1
|
177
187
|
ELSE NULL
|
178
188
|
END AS [is_primary],
|
@@ -240,7 +250,7 @@ module ActiveRecord
|
|
240
250
|
ci
|
241
251
|
end
|
242
252
|
end
|
243
|
-
|
253
|
+
|
244
254
|
def remove_check_constraints(table_name, column_name)
|
245
255
|
constraints = select_values "SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE where TABLE_NAME = '#{quote_string(table_name)}' and COLUMN_NAME = '#{quote_string(column_name)}'", 'SCHEMA'
|
246
256
|
constraints.each do |constraint|
|
@@ -262,9 +272,9 @@ module ActiveRecord
|
|
262
272
|
remove_index(table_name, {:name => index.name})
|
263
273
|
end
|
264
274
|
end
|
265
|
-
|
275
|
+
|
266
276
|
# === SQLServer Specific (Misc Helpers) ========================= #
|
267
|
-
|
277
|
+
|
268
278
|
def get_table_name(sql)
|
269
279
|
if sql =~ /^\s*(INSERT|EXEC sp_executesql N'INSERT)\s+INTO\s+([^\(\s]+)\s*|^\s*update\s+([^\(\s]+)\s*/i
|
270
280
|
$2 || $3
|
@@ -274,29 +284,29 @@ module ActiveRecord
|
|
274
284
|
nil
|
275
285
|
end
|
276
286
|
end
|
277
|
-
|
287
|
+
|
278
288
|
def default_constraint_name(table_name, column_name)
|
279
289
|
"DF_#{table_name}_#{column_name}"
|
280
290
|
end
|
281
|
-
|
291
|
+
|
282
292
|
def detect_column_for!(table_name, column_name)
|
283
293
|
unless column = schema_cache.columns[table_name].detect { |c| c.name == column_name.to_s }
|
284
294
|
raise ActiveRecordError, "No such column: #{table_name}.#{column_name}"
|
285
295
|
end
|
286
296
|
column
|
287
297
|
end
|
288
|
-
|
298
|
+
|
289
299
|
def lowercase_schema_reflection_sql(node)
|
290
300
|
lowercase_schema_reflection ? "LOWER(#{node})" : node
|
291
301
|
end
|
292
|
-
|
302
|
+
|
293
303
|
# === SQLServer Specific (View Reflection) ====================== #
|
294
|
-
|
304
|
+
|
295
305
|
def view_table_name(table_name)
|
296
306
|
view_info = schema_cache.view_information(table_name)
|
297
307
|
view_info ? get_table_name(view_info['VIEW_DEFINITION']) : table_name
|
298
308
|
end
|
299
|
-
|
309
|
+
|
300
310
|
def view_information(table_name)
|
301
311
|
table_name = Utils.unqualify_table_name(table_name)
|
302
312
|
view_info = select_one "SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = '#{table_name}'", 'SCHEMA'
|
@@ -313,18 +323,18 @@ module ActiveRecord
|
|
313
323
|
end
|
314
324
|
view_info
|
315
325
|
end
|
316
|
-
|
326
|
+
|
317
327
|
def table_name_or_views_table_name(table_name)
|
318
328
|
unquoted_table_name = Utils.unqualify_table_name(table_name)
|
319
329
|
schema_cache.view_names.include?(unquoted_table_name) ? view_table_name(unquoted_table_name) : unquoted_table_name
|
320
330
|
end
|
321
|
-
|
331
|
+
|
322
332
|
def views_real_column_name(table_name,column_name)
|
323
333
|
view_definition = schema_cache.view_information(table_name)[:VIEW_DEFINITION]
|
324
334
|
match_data = view_definition.match(/([\w-]*)\s+as\s+#{column_name}/im)
|
325
335
|
match_data ? match_data[1] : column_name
|
326
336
|
end
|
327
|
-
|
337
|
+
|
328
338
|
# === SQLServer Specific (Identity Inserts) ===================== #
|
329
339
|
|
330
340
|
def query_requires_identity_insert?(sql)
|
@@ -336,11 +346,11 @@ module ActiveRecord
|
|
336
346
|
false
|
337
347
|
end
|
338
348
|
end
|
339
|
-
|
349
|
+
|
340
350
|
def insert_sql?(sql)
|
341
351
|
!(sql =~ /^\s*(INSERT|EXEC sp_executesql N'INSERT)/i).nil?
|
342
352
|
end
|
343
|
-
|
353
|
+
|
344
354
|
def with_identity_insert_enabled(table_name)
|
345
355
|
table_name = quote_table_name(table_name_or_views_table_name(table_name))
|
346
356
|
set_identity_insert(table_name, true)
|
@@ -8,6 +8,7 @@ require 'active_record/connection_adapters/abstract_adapter'
|
|
8
8
|
require 'active_record/connection_adapters/sqlserver/core_ext/active_record'
|
9
9
|
require 'active_record/connection_adapters/sqlserver/core_ext/database_statements'
|
10
10
|
require 'active_record/connection_adapters/sqlserver/core_ext/explain'
|
11
|
+
require 'active_record/connection_adapters/sqlserver/core_ext/explain_subscriber'
|
11
12
|
require 'active_record/connection_adapters/sqlserver/core_ext/relation'
|
12
13
|
require 'active_record/connection_adapters/sqlserver/database_limits'
|
13
14
|
require 'active_record/connection_adapters/sqlserver/database_statements'
|
@@ -19,9 +20,9 @@ require 'active_record/connection_adapters/sqlserver/quoting'
|
|
19
20
|
require 'active_record/connection_adapters/sqlserver/utils'
|
20
21
|
|
21
22
|
module ActiveRecord
|
22
|
-
|
23
|
+
|
23
24
|
class Base
|
24
|
-
|
25
|
+
|
25
26
|
def self.sqlserver_connection(config) #:nodoc:
|
26
27
|
config = config.symbolize_keys
|
27
28
|
config.reverse_merge! :mode => :dblib
|
@@ -38,21 +39,21 @@ module ActiveRecord
|
|
38
39
|
end
|
39
40
|
ConnectionAdapters::SQLServerAdapter.new(nil, logger, nil, config.merge(:mode=>mode))
|
40
41
|
end
|
41
|
-
|
42
|
+
|
42
43
|
protected
|
43
|
-
|
44
|
+
|
44
45
|
def self.did_retry_sqlserver_connection(connection,count)
|
45
46
|
logger.info "CONNECTION RETRY: #{connection.class.name} retry ##{count}."
|
46
47
|
end
|
47
|
-
|
48
|
+
|
48
49
|
def self.did_lose_sqlserver_connection(connection)
|
49
50
|
logger.info "CONNECTION LOST: #{connection.class.name}"
|
50
51
|
end
|
51
|
-
|
52
|
+
|
52
53
|
end
|
53
|
-
|
54
|
+
|
54
55
|
module ConnectionAdapters
|
55
|
-
|
56
|
+
|
56
57
|
class SQLServerColumn < Column
|
57
58
|
|
58
59
|
def initialize(name, default, sql_type = nil, null = true, sqlserver_options = {})
|
@@ -60,39 +61,42 @@ module ActiveRecord
|
|
60
61
|
super(name, default, sql_type, null)
|
61
62
|
@primary = @sqlserver_options[:is_identity] || @sqlserver_options[:is_primary]
|
62
63
|
end
|
63
|
-
|
64
|
+
|
64
65
|
class << self
|
65
|
-
|
66
|
+
|
66
67
|
def string_to_binary(value)
|
67
68
|
"0x#{value.unpack("H*")[0]}"
|
68
69
|
end
|
69
|
-
|
70
|
+
|
70
71
|
def binary_to_string(value)
|
72
|
+
if value.respond_to?(:force_encoding) && value.encoding != Encoding::ASCII_8BIT
|
73
|
+
value = value.force_encoding(Encoding::ASCII_8BIT)
|
74
|
+
end
|
71
75
|
value =~ /[^[:xdigit:]]/ ? value : [value].pack('H*')
|
72
76
|
end
|
73
|
-
|
77
|
+
|
74
78
|
end
|
75
|
-
|
79
|
+
|
76
80
|
def is_identity?
|
77
81
|
@sqlserver_options[:is_identity]
|
78
82
|
end
|
79
|
-
|
83
|
+
|
80
84
|
def is_primary?
|
81
85
|
@sqlserver_options[:is_primary]
|
82
86
|
end
|
83
|
-
|
87
|
+
|
84
88
|
def is_utf8?
|
85
89
|
!!(@sql_type =~ /nvarchar|ntext|nchar/i)
|
86
90
|
end
|
87
|
-
|
91
|
+
|
88
92
|
def is_integer?
|
89
93
|
!!(@sql_type =~ /int/i)
|
90
94
|
end
|
91
|
-
|
95
|
+
|
92
96
|
def is_real?
|
93
97
|
!!(@sql_type =~ /real/i)
|
94
98
|
end
|
95
|
-
|
99
|
+
|
96
100
|
def sql_type_for_statement
|
97
101
|
if is_integer? || is_real?
|
98
102
|
sql_type.sub(/\((\d+)?\)/,'')
|
@@ -100,15 +104,15 @@ module ActiveRecord
|
|
100
104
|
sql_type
|
101
105
|
end
|
102
106
|
end
|
103
|
-
|
107
|
+
|
104
108
|
def default_function
|
105
109
|
@sqlserver_options[:default_function]
|
106
110
|
end
|
107
|
-
|
111
|
+
|
108
112
|
def table_name
|
109
113
|
@sqlserver_options[:table_name]
|
110
114
|
end
|
111
|
-
|
115
|
+
|
112
116
|
def table_klass
|
113
117
|
@table_klass ||= begin
|
114
118
|
table_name.classify.constantize
|
@@ -117,14 +121,14 @@ module ActiveRecord
|
|
117
121
|
end
|
118
122
|
(@table_klass && @table_klass < ActiveRecord::Base) ? @table_klass : nil
|
119
123
|
end
|
120
|
-
|
124
|
+
|
121
125
|
def database_year
|
122
126
|
@sqlserver_options[:database_year]
|
123
127
|
end
|
124
|
-
|
125
|
-
|
128
|
+
|
129
|
+
|
126
130
|
private
|
127
|
-
|
131
|
+
|
128
132
|
def extract_limit(sql_type)
|
129
133
|
case sql_type
|
130
134
|
when /^smallint/i
|
@@ -139,7 +143,7 @@ module ActiveRecord
|
|
139
143
|
super
|
140
144
|
end
|
141
145
|
end
|
142
|
-
|
146
|
+
|
143
147
|
def simplified_type(field_type)
|
144
148
|
case field_type
|
145
149
|
when /real/i then :float
|
@@ -153,7 +157,7 @@ module ActiveRecord
|
|
153
157
|
else super
|
154
158
|
end
|
155
159
|
end
|
156
|
-
|
160
|
+
|
157
161
|
def simplified_datetime
|
158
162
|
if database_year >= 2008
|
159
163
|
:datetime
|
@@ -165,33 +169,33 @@ module ActiveRecord
|
|
165
169
|
:datetime
|
166
170
|
end
|
167
171
|
end
|
168
|
-
|
172
|
+
|
169
173
|
end #class SQLServerColumn
|
170
|
-
|
174
|
+
|
171
175
|
class SQLServerAdapter < AbstractAdapter
|
172
|
-
|
176
|
+
|
173
177
|
include Sqlserver::Quoting
|
174
178
|
include Sqlserver::DatabaseStatements
|
175
179
|
include Sqlserver::Showplan
|
176
180
|
include Sqlserver::SchemaStatements
|
177
181
|
include Sqlserver::DatabaseLimits
|
178
182
|
include Sqlserver::Errors
|
179
|
-
|
183
|
+
|
180
184
|
VERSION = File.read(File.expand_path("../../../../VERSION",__FILE__)).strip
|
181
185
|
ADAPTER_NAME = 'SQLServer'.freeze
|
182
186
|
DATABASE_VERSION_REGEXP = /Microsoft SQL Server\s+"?(\d{4}|\w+)"?/
|
183
187
|
SUPPORTED_VERSIONS = [2005,2008,2010,2011,2012]
|
184
|
-
|
188
|
+
|
185
189
|
attr_reader :database_version, :database_year, :spid, :product_level, :product_version, :edition
|
186
|
-
|
190
|
+
|
187
191
|
cattr_accessor :native_text_database_type, :native_binary_database_type, :native_string_database_type,
|
188
192
|
:enable_default_unicode_types, :auto_connect, :retry_deadlock_victim,
|
189
193
|
:cs_equality_operator, :lowercase_schema_reflection, :auto_connect_duration,
|
190
194
|
:showplan_option
|
191
|
-
|
195
|
+
|
192
196
|
self.enable_default_unicode_types = true
|
193
|
-
|
194
|
-
|
197
|
+
|
198
|
+
|
195
199
|
def initialize(connection, logger, pool, config)
|
196
200
|
super(connection, logger, pool)
|
197
201
|
# AbstractAdapter Responsibility
|
@@ -203,9 +207,10 @@ module ActiveRecord
|
|
203
207
|
connect
|
204
208
|
@database_version = select_value 'SELECT @@version', 'SCHEMA'
|
205
209
|
@database_year = begin
|
206
|
-
if @database_version =~ /
|
210
|
+
if @database_version =~ /Azure/i
|
207
211
|
@sqlserver_azure = true
|
208
|
-
@database_version.match(/\s(
|
212
|
+
@database_version.match(/\s-\s([0-9.]+)/)[1]
|
213
|
+
year = 2012
|
209
214
|
else
|
210
215
|
year = DATABASE_VERSION_REGEXP.match(@database_version)[1]
|
211
216
|
year == "Denali" ? 2011 : year.to_i
|
@@ -218,58 +223,58 @@ module ActiveRecord
|
|
218
223
|
@edition = select_value "SELECT CAST(SERVERPROPERTY('edition') AS VARCHAR(128))", 'SCHEMA'
|
219
224
|
initialize_dateformatter
|
220
225
|
use_database
|
221
|
-
unless SUPPORTED_VERSIONS.include?(@database_year)
|
226
|
+
unless (@sqlserver_azure == true || SUPPORTED_VERSIONS.include?(@database_year))
|
222
227
|
raise NotImplementedError, "Currently, only #{SUPPORTED_VERSIONS.to_sentence} are supported. We got back #{@database_version}."
|
223
228
|
end
|
224
229
|
end
|
225
|
-
|
230
|
+
|
226
231
|
# === Abstract Adapter ========================================== #
|
227
|
-
|
232
|
+
|
228
233
|
def adapter_name
|
229
234
|
ADAPTER_NAME
|
230
235
|
end
|
231
|
-
|
236
|
+
|
232
237
|
def supports_migrations?
|
233
238
|
true
|
234
239
|
end
|
235
|
-
|
240
|
+
|
236
241
|
def supports_primary_key?
|
237
242
|
true
|
238
243
|
end
|
239
|
-
|
244
|
+
|
240
245
|
def supports_count_distinct?
|
241
246
|
true
|
242
247
|
end
|
243
|
-
|
248
|
+
|
244
249
|
def supports_ddl_transactions?
|
245
250
|
true
|
246
251
|
end
|
247
|
-
|
252
|
+
|
248
253
|
def supports_bulk_alter?
|
249
254
|
false
|
250
255
|
end
|
251
|
-
|
256
|
+
|
252
257
|
def supports_savepoints?
|
253
258
|
true
|
254
259
|
end
|
255
|
-
|
260
|
+
|
256
261
|
def supports_index_sort_order?
|
257
262
|
true
|
258
263
|
end
|
259
|
-
|
264
|
+
|
260
265
|
def supports_explain?
|
261
266
|
true
|
262
267
|
end
|
263
|
-
|
268
|
+
|
264
269
|
def disable_referential_integrity
|
265
270
|
do_execute "EXEC sp_MSforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'"
|
266
271
|
yield
|
267
272
|
ensure
|
268
273
|
do_execute "EXEC sp_MSforeachtable 'ALTER TABLE ? CHECK CONSTRAINT ALL'"
|
269
274
|
end
|
270
|
-
|
275
|
+
|
271
276
|
# === Abstract Adapter (Connection Management) ================== #
|
272
|
-
|
277
|
+
|
273
278
|
def active?
|
274
279
|
case @connection_options[:mode]
|
275
280
|
when :dblib
|
@@ -296,13 +301,13 @@ module ActiveRecord
|
|
296
301
|
@connection.disconnect rescue nil
|
297
302
|
end
|
298
303
|
end
|
299
|
-
|
304
|
+
|
300
305
|
def reset!
|
301
306
|
remove_database_connections_and_rollback { }
|
302
307
|
end
|
303
|
-
|
308
|
+
|
304
309
|
# === Abstract Adapter (Misc Support) =========================== #
|
305
|
-
|
310
|
+
|
306
311
|
def pk_and_sequence_for(table_name)
|
307
312
|
idcol = identity_column(table_name)
|
308
313
|
idcol ? [idcol.name,nil] : nil
|
@@ -311,85 +316,85 @@ module ActiveRecord
|
|
311
316
|
def primary_key(table_name)
|
312
317
|
identity_column(table_name).try(:name) || schema_cache.columns[table_name].detect(&:is_primary?).try(:name)
|
313
318
|
end
|
314
|
-
|
319
|
+
|
315
320
|
# === SQLServer Specific (DB Reflection) ======================== #
|
316
|
-
|
321
|
+
|
317
322
|
def sqlserver?
|
318
323
|
true
|
319
324
|
end
|
320
|
-
|
325
|
+
|
321
326
|
def sqlserver_2005?
|
322
327
|
@database_year == 2005
|
323
328
|
end
|
324
|
-
|
329
|
+
|
325
330
|
def sqlserver_2008?
|
326
331
|
@database_year == 2008
|
327
332
|
end
|
328
|
-
|
333
|
+
|
329
334
|
def sqlserver_2011?
|
330
335
|
@database_year == 2011
|
331
336
|
end
|
332
|
-
|
337
|
+
|
333
338
|
def sqlserver_2012?
|
334
339
|
@database_year == 2012
|
335
340
|
end
|
336
|
-
|
341
|
+
|
337
342
|
def sqlserver_azure?
|
338
343
|
@sqlserver_azure
|
339
344
|
end
|
340
|
-
|
345
|
+
|
341
346
|
def version
|
342
347
|
self.class::VERSION
|
343
348
|
end
|
344
|
-
|
349
|
+
|
345
350
|
def inspect
|
346
351
|
"#<#{self.class} version: #{version}, year: #{@database_year}, product_level: #{@product_level.inspect}, product_version: #{@product_version.inspect}, edition: #{@edition.inspect}, connection_options: #{@connection_options.inspect}>"
|
347
352
|
end
|
348
|
-
|
353
|
+
|
349
354
|
def auto_connect
|
350
355
|
@@auto_connect.is_a?(FalseClass) ? false : true
|
351
356
|
end
|
352
|
-
|
357
|
+
|
353
358
|
def auto_connect_duration
|
354
359
|
@@auto_connect_duration ||= 10
|
355
360
|
end
|
356
|
-
|
361
|
+
|
357
362
|
def retry_deadlock_victim
|
358
363
|
@@retry_deadlock_victim.is_a?(FalseClass) ? false : true
|
359
364
|
end
|
360
365
|
alias :retry_deadlock_victim? :retry_deadlock_victim
|
361
|
-
|
366
|
+
|
362
367
|
def native_string_database_type
|
363
|
-
@@native_string_database_type || (enable_default_unicode_types ? 'nvarchar' : 'varchar')
|
368
|
+
@@native_string_database_type || (enable_default_unicode_types ? 'nvarchar' : 'varchar')
|
364
369
|
end
|
365
|
-
|
370
|
+
|
366
371
|
def native_text_database_type
|
367
372
|
@@native_text_database_type || enable_default_unicode_types ? 'nvarchar(max)' : 'varchar(max)'
|
368
373
|
end
|
369
|
-
|
374
|
+
|
370
375
|
def native_time_database_type
|
371
376
|
sqlserver_2005? ? 'datetime' : 'time'
|
372
377
|
end
|
373
|
-
|
378
|
+
|
374
379
|
def native_date_database_type
|
375
380
|
sqlserver_2005? ? 'datetime' : 'date'
|
376
381
|
end
|
377
|
-
|
382
|
+
|
378
383
|
def native_binary_database_type
|
379
384
|
@@native_binary_database_type || 'varbinary(max)'
|
380
385
|
end
|
381
|
-
|
386
|
+
|
382
387
|
def cs_equality_operator
|
383
388
|
@@cs_equality_operator || 'COLLATE Latin1_General_CS_AS_WS'
|
384
389
|
end
|
385
|
-
|
390
|
+
|
386
391
|
protected
|
387
|
-
|
392
|
+
|
388
393
|
# === Abstract Adapter (Misc Support) =========================== #
|
389
|
-
|
394
|
+
|
390
395
|
def translate_exception(e, message)
|
391
396
|
case message
|
392
|
-
when /cannot insert duplicate key .* with unique index/i
|
397
|
+
when /(cannot insert duplicate key .* with unique index) | (violation of unique key constraint)/i
|
393
398
|
RecordNotUnique.new(message,e)
|
394
399
|
when /conflicted with the foreign key constraint/i
|
395
400
|
InvalidForeignKey.new(message,e)
|
@@ -401,9 +406,9 @@ module ActiveRecord
|
|
401
406
|
super
|
402
407
|
end
|
403
408
|
end
|
404
|
-
|
409
|
+
|
405
410
|
# === SQLServer Specific (Connection Management) ================ #
|
406
|
-
|
411
|
+
|
407
412
|
def connect
|
408
413
|
config = @connection_options
|
409
414
|
@connection = case config[:mode]
|
@@ -412,13 +417,14 @@ module ActiveRecord
|
|
412
417
|
login_timeout = config[:login_timeout].present? ? config[:login_timeout].to_i : nil
|
413
418
|
timeout = config[:timeout].present? ? config[:timeout].to_i/1000 : nil
|
414
419
|
encoding = config[:encoding].present? ? config[:encoding] : nil
|
415
|
-
TinyTds::Client.new({
|
420
|
+
TinyTds::Client.new({
|
416
421
|
:dataserver => config[:dataserver],
|
417
422
|
:host => config[:host],
|
418
423
|
:port => config[:port],
|
419
424
|
:username => config[:username],
|
420
425
|
:password => config[:password],
|
421
426
|
:database => config[:database],
|
427
|
+
:tds_version => config[:tds_version],
|
422
428
|
:appname => appname,
|
423
429
|
:login_timeout => login_timeout,
|
424
430
|
:timeout => timeout,
|
@@ -439,6 +445,7 @@ module ActiveRecord
|
|
439
445
|
client.execute("SET IMPLICIT_TRANSACTIONS OFF").do
|
440
446
|
end
|
441
447
|
client.execute("SET TEXTSIZE 2147483647").do
|
448
|
+
client.execute("SET CONCAT_NULL_YIELDS_NULL ON").do
|
442
449
|
end
|
443
450
|
when :odbc
|
444
451
|
if config[:dsn].include?(';')
|
@@ -449,7 +456,7 @@ module ActiveRecord
|
|
449
456
|
ODBC::Database.new.drvconnect(driver)
|
450
457
|
else
|
451
458
|
ODBC.connect config[:dsn], config[:username], config[:password]
|
452
|
-
end.tap do |c|
|
459
|
+
end.tap do |c|
|
453
460
|
begin
|
454
461
|
c.use_time = true
|
455
462
|
c.use_utc = ActiveRecord::Base.default_timezone == :utc
|
@@ -463,20 +470,20 @@ module ActiveRecord
|
|
463
470
|
rescue
|
464
471
|
raise unless @auto_connecting
|
465
472
|
end
|
466
|
-
|
473
|
+
|
467
474
|
# Override this method so every connection can be configured to your needs.
|
468
|
-
# For example:
|
475
|
+
# For example:
|
469
476
|
# raw_connection_do "SET TEXTSIZE #{64.megabytes}"
|
470
477
|
# raw_connection_do "SET CONCAT_NULL_YIELDS_NULL ON"
|
471
478
|
def configure_connection
|
472
479
|
end
|
473
|
-
|
480
|
+
|
474
481
|
# Override this method so every connection can have a unique name. Max 30 characters. Used by TinyTDS only.
|
475
482
|
# For example:
|
476
483
|
# "myapp_#{$$}_#{Thread.current.object_id}".to(29)
|
477
484
|
def configure_application_name
|
478
485
|
end
|
479
|
-
|
486
|
+
|
480
487
|
def initialize_dateformatter
|
481
488
|
@database_dateformat = user_options_dateformat
|
482
489
|
a, b, c = @database_dateformat.each_char.to_a
|
@@ -485,7 +492,7 @@ module ActiveRecord
|
|
485
492
|
::Date::DATE_FORMATS[:_sqlserver_dateformat] = dateformat
|
486
493
|
::Time::DATE_FORMATS[:_sqlserver_dateformat] = dateformat
|
487
494
|
end
|
488
|
-
|
495
|
+
|
489
496
|
def remove_database_connections_and_rollback(database=nil)
|
490
497
|
database ||= current_database
|
491
498
|
do_execute "ALTER DATABASE #{quote_table_name(database)} SET SINGLE_USER WITH ROLLBACK IMMEDIATE"
|
@@ -495,7 +502,7 @@ module ActiveRecord
|
|
495
502
|
do_execute "ALTER DATABASE #{quote_table_name(database)} SET MULTI_USER"
|
496
503
|
end if block_given?
|
497
504
|
end
|
498
|
-
|
505
|
+
|
499
506
|
def with_sqlserver_error_handling
|
500
507
|
begin
|
501
508
|
yield
|
@@ -507,22 +514,23 @@ module ActiveRecord
|
|
507
514
|
raise
|
508
515
|
end
|
509
516
|
end
|
510
|
-
|
517
|
+
|
511
518
|
def disable_auto_reconnect
|
512
519
|
old_auto_connect, self.class.auto_connect = self.class.auto_connect, false
|
513
520
|
yield
|
514
521
|
ensure
|
515
522
|
self.class.auto_connect = old_auto_connect
|
516
523
|
end
|
517
|
-
|
524
|
+
|
518
525
|
def auto_reconnected?
|
519
526
|
return false unless auto_connect
|
520
527
|
@auto_connecting = true
|
521
528
|
count = 0
|
522
529
|
while count <= (auto_connect_duration / 2)
|
523
|
-
|
530
|
+
result = reconnect!
|
524
531
|
ActiveRecord::Base.did_retry_sqlserver_connection(self,count)
|
525
|
-
return true if
|
532
|
+
return true if result
|
533
|
+
sleep 2** count
|
526
534
|
count += 1
|
527
535
|
end
|
528
536
|
ActiveRecord::Base.did_lose_sqlserver_connection(self)
|
@@ -530,10 +538,10 @@ module ActiveRecord
|
|
530
538
|
ensure
|
531
539
|
@auto_connecting = false
|
532
540
|
end
|
533
|
-
|
541
|
+
|
534
542
|
end #class SQLServerAdapter < AbstractAdapter
|
535
|
-
|
543
|
+
|
536
544
|
end #module ConnectionAdapters
|
537
|
-
|
545
|
+
|
538
546
|
end #module ActiveRecord
|
539
547
|
|
metadata
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-sqlserver-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.2.10
|
5
4
|
prerelease:
|
5
|
+
version: 3.2.11
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Ken Collins
|
@@ -13,24 +13,24 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date:
|
16
|
+
date: 2013-07-07 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: activerecord
|
20
20
|
requirement: !ruby/object:Gem::Requirement
|
21
|
-
none: false
|
22
21
|
requirements:
|
23
22
|
- - ~>
|
24
23
|
- !ruby/object:Gem::Version
|
25
24
|
version: 3.2.0
|
26
|
-
type: :runtime
|
27
|
-
prerelease: false
|
28
|
-
version_requirements: !ruby/object:Gem::Requirement
|
29
25
|
none: false
|
26
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
27
|
requirements:
|
31
28
|
- - ~>
|
32
29
|
- !ruby/object:Gem::Version
|
33
30
|
version: 3.2.0
|
31
|
+
none: false
|
32
|
+
prerelease: false
|
33
|
+
type: :runtime
|
34
34
|
description: ActiveRecord SQL Server Adapter. For SQL Server 2005 And Higher.
|
35
35
|
email: ken@metaskills.net
|
36
36
|
executables: []
|
@@ -43,6 +43,7 @@ files:
|
|
43
43
|
- lib/active_record/connection_adapters/sqlserver/core_ext/active_record.rb
|
44
44
|
- lib/active_record/connection_adapters/sqlserver/core_ext/database_statements.rb
|
45
45
|
- lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb
|
46
|
+
- lib/active_record/connection_adapters/sqlserver/core_ext/explain_subscriber.rb
|
46
47
|
- lib/active_record/connection_adapters/sqlserver/core_ext/odbc.rb
|
47
48
|
- lib/active_record/connection_adapters/sqlserver/core_ext/relation.rb
|
48
49
|
- lib/active_record/connection_adapters/sqlserver/database_limits.rb
|
@@ -65,20 +66,20 @@ rdoc_options: []
|
|
65
66
|
require_paths:
|
66
67
|
- lib
|
67
68
|
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
-
none: false
|
69
69
|
requirements:
|
70
70
|
- - ! '>='
|
71
71
|
- !ruby/object:Gem::Version
|
72
72
|
version: '0'
|
73
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
73
|
none: false
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
75
|
requirements:
|
76
76
|
- - ! '>='
|
77
77
|
- !ruby/object:Gem::Version
|
78
78
|
version: '0'
|
79
|
+
none: false
|
79
80
|
requirements: []
|
80
81
|
rubyforge_project: activerecord-sqlserver-adapter
|
81
|
-
rubygems_version: 1.8.
|
82
|
+
rubygems_version: 1.8.25
|
82
83
|
signing_key:
|
83
84
|
specification_version: 3
|
84
85
|
summary: ActiveRecord SQL Server Adapter. For SQL Server 2005 And Higher.
|