activerecord-sqlserver-adapter 2.3.7 → 3.2.18

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.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +385 -61
  3. data/MIT-LICENSE +1 -1
  4. data/VERSION +1 -0
  5. data/lib/active_record/connection_adapters/sqlserver/core_ext/active_record.rb +42 -0
  6. data/lib/active_record/connection_adapters/sqlserver/core_ext/database_statements.rb +97 -0
  7. data/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +41 -0
  8. data/lib/active_record/connection_adapters/sqlserver/core_ext/explain_subscriber.rb +26 -0
  9. data/lib/active_record/connection_adapters/sqlserver/core_ext/odbc.rb +38 -0
  10. data/lib/active_record/connection_adapters/sqlserver/core_ext/relation.rb +19 -0
  11. data/lib/active_record/connection_adapters/sqlserver/database_limits.rb +49 -0
  12. data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +458 -0
  13. data/lib/active_record/connection_adapters/sqlserver/errors.rb +36 -0
  14. data/lib/active_record/connection_adapters/sqlserver/quoting.rb +113 -0
  15. data/lib/active_record/connection_adapters/sqlserver/schema_cache.rb +85 -0
  16. data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +376 -0
  17. data/lib/active_record/connection_adapters/sqlserver/showplan/printer_table.rb +69 -0
  18. data/lib/active_record/connection_adapters/sqlserver/showplan/printer_xml.rb +25 -0
  19. data/lib/active_record/connection_adapters/sqlserver/showplan.rb +67 -0
  20. data/lib/active_record/connection_adapters/sqlserver/utils.rb +32 -0
  21. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +344 -1055
  22. data/lib/arel/visitors/sqlserver.rb +389 -0
  23. metadata +60 -83
  24. data/README.rdoc +0 -190
  25. data/RUNNING_UNIT_TESTS +0 -65
  26. data/Rakefile +0 -41
  27. data/autotest/discover.rb +0 -4
  28. data/autotest/railssqlserver.rb +0 -16
  29. data/autotest/sqlserver.rb +0 -54
  30. data/lib/active_record/connection_adapters/sqlserver_adapter/core_ext/active_record.rb +0 -151
  31. data/lib/active_record/connection_adapters/sqlserver_adapter/core_ext/odbc.rb +0 -40
  32. data/test/cases/aaaa_create_tables_test_sqlserver.rb +0 -19
  33. data/test/cases/adapter_test_sqlserver.rb +0 -756
  34. data/test/cases/attribute_methods_test_sqlserver.rb +0 -33
  35. data/test/cases/basics_test_sqlserver.rb +0 -21
  36. data/test/cases/calculations_test_sqlserver.rb +0 -20
  37. data/test/cases/column_test_sqlserver.rb +0 -285
  38. data/test/cases/connection_test_sqlserver.rb +0 -146
  39. data/test/cases/eager_association_test_sqlserver.rb +0 -42
  40. data/test/cases/execute_procedure_test_sqlserver.rb +0 -44
  41. data/test/cases/inheritance_test_sqlserver.rb +0 -28
  42. data/test/cases/method_scoping_test_sqlserver.rb +0 -28
  43. data/test/cases/migration_test_sqlserver.rb +0 -123
  44. data/test/cases/named_scope_test_sqlserver.rb +0 -21
  45. data/test/cases/offset_and_limit_test_sqlserver.rb +0 -108
  46. data/test/cases/pessimistic_locking_test_sqlserver.rb +0 -125
  47. data/test/cases/query_cache_test_sqlserver.rb +0 -24
  48. data/test/cases/schema_dumper_test_sqlserver.rb +0 -72
  49. data/test/cases/specific_schema_test_sqlserver.rb +0 -97
  50. data/test/cases/sqlserver_helper.rb +0 -127
  51. data/test/cases/table_name_test_sqlserver.rb +0 -38
  52. data/test/cases/transaction_test_sqlserver.rb +0 -93
  53. data/test/cases/unicode_test_sqlserver.rb +0 -50
  54. data/test/cases/validations_test_sqlserver.rb +0 -35
  55. data/test/connections/native_sqlserver/connection.rb +0 -25
  56. data/test/connections/native_sqlserver_odbc/connection.rb +0 -27
  57. data/test/migrations/transaction_table/1_table_will_never_be_created.rb +0 -11
  58. data/test/schema/sqlserver_specific_schema.rb +0 -94
@@ -0,0 +1,97 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ module Sqlserver
4
+ module CoreExt
5
+ module DatabaseStatements
6
+
7
+ # This is a copy of the current (3.1.3) ActiveRecord's transaction method. We should propose
8
+ # a patch to the default transaction method to make it more callback for adapters that want to
9
+ # do deadlock retry logic. Because this is a copy, we really need to keep an eye out on this when
10
+ # upgradding the adapter.
11
+ def transaction_with_retry_deadlock_victim(options = {})
12
+ options.assert_valid_keys :requires_new, :joinable
13
+
14
+ last_transaction_joinable = defined?(@transaction_joinable) ? @transaction_joinable : nil
15
+ if options.has_key?(:joinable)
16
+ @transaction_joinable = options[:joinable]
17
+ else
18
+ @transaction_joinable = true
19
+ end
20
+ requires_new = options[:requires_new] || !last_transaction_joinable
21
+
22
+ transaction_open = false
23
+ @_current_transaction_records ||= []
24
+
25
+ begin
26
+ if block_given?
27
+ if requires_new || open_transactions == 0
28
+ if open_transactions == 0
29
+ begin_db_transaction
30
+ elsif requires_new
31
+ create_savepoint
32
+ end
33
+ increment_open_transactions
34
+ transaction_open = true
35
+ @_current_transaction_records.push([])
36
+ end
37
+ yield
38
+ end
39
+ rescue Exception => database_transaction_rollback
40
+ if transaction_open && !outside_transaction?
41
+ transaction_open = false
42
+ decrement_open_transactions
43
+ # handle deadlock victim retries at the outermost transaction
44
+ if open_transactions == 0
45
+ if database_transaction_rollback.is_a?(::ActiveRecord::DeadlockVictim)
46
+ # SQL Server has already rolled back, so rollback activerecord's history
47
+ rollback_transaction_records(true)
48
+ retry
49
+ else
50
+ rollback_db_transaction
51
+ rollback_transaction_records(true)
52
+ end
53
+ else
54
+ rollback_to_savepoint
55
+ rollback_transaction_records(false)
56
+ end
57
+ end
58
+ raise unless database_transaction_rollback.is_a?(::ActiveRecord::Rollback)
59
+ end
60
+ ensure
61
+ @transaction_joinable = last_transaction_joinable
62
+
63
+ if outside_transaction?
64
+ @open_transactions = 0
65
+ elsif transaction_open
66
+ decrement_open_transactions
67
+ begin
68
+ if open_transactions == 0
69
+ commit_db_transaction
70
+ commit_transaction_records
71
+ else
72
+ release_savepoint
73
+ save_point_records = @_current_transaction_records.pop
74
+ unless save_point_records.blank?
75
+ @_current_transaction_records.push([]) if @_current_transaction_records.empty?
76
+ @_current_transaction_records.last.concat(save_point_records)
77
+ end
78
+ end
79
+ rescue Exception => database_transaction_rollback
80
+ if open_transactions == 0
81
+ rollback_db_transaction
82
+ rollback_transaction_records(true)
83
+ else
84
+ rollback_to_savepoint
85
+ rollback_transaction_records(false)
86
+ end
87
+ raise
88
+ end
89
+ end
90
+ end
91
+
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+
@@ -0,0 +1,41 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ module Sqlserver
4
+ module CoreExt
5
+ module Explain
6
+
7
+ SQLSERVER_STATEMENT_PREFIX = "EXEC sp_executesql "
8
+ SQLSERVER_PARAM_MATCHER = /@\d+ =/
9
+
10
+ def exec_explain(queries)
11
+ unprepared_queries = queries.map { |sql, bind| [unprepare_sqlserver_statement(sql), bind] }
12
+ super(unprepared_queries)
13
+ end
14
+
15
+ private
16
+
17
+ # This is somewhat hacky, but it should reliably reformat our prepared sql statment
18
+ # which uses sp_executesql to just the first argument, then unquote it. Likewise our
19
+ # do_exec_query method should substitude the @n args withe the quoted values.
20
+ def unprepare_sqlserver_statement(sql)
21
+ if sql.starts_with?(SQLSERVER_STATEMENT_PREFIX)
22
+ executesql = sql.from(SQLSERVER_STATEMENT_PREFIX.length)
23
+ executesql_args = executesql.split(', ')
24
+ found_args = executesql_args.reject! { |arg| arg =~ SQLSERVER_PARAM_MATCHER }
25
+ executesql_args.pop if found_args && executesql_args.many?
26
+ executesql = executesql_args.join(', ').strip.match(/N'(.*)'/m)[1]
27
+ Utils.unquote_string(executesql)
28
+ else
29
+ sql
30
+ end
31
+ end
32
+
33
+
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ ActiveRecord::Base.extend ActiveRecord::ConnectionAdapters::Sqlserver::CoreExt::Explain
41
+ ActiveRecord::Relation.send :include, ActiveRecord::ConnectionAdapters::Sqlserver::CoreExt::Explain
@@ -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
@@ -0,0 +1,38 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ module Sqlserver
4
+ module CoreExt
5
+ module ODBC
6
+
7
+ module Statement
8
+
9
+ def finished?
10
+ begin
11
+ connected?
12
+ false
13
+ rescue ::ODBC::Error
14
+ true
15
+ end
16
+ end
17
+
18
+ end
19
+
20
+ module Database
21
+
22
+ def run_block(*args)
23
+ yield sth = run(*args)
24
+ sth.drop
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+
36
+ ODBC::Statement.send :include, ActiveRecord::ConnectionAdapters::Sqlserver::CoreExt::ODBC::Statement
37
+ ODBC::Database.send :include, ActiveRecord::ConnectionAdapters::Sqlserver::CoreExt::ODBC::Database
38
+
@@ -0,0 +1,19 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ module Sqlserver
4
+ module CoreExt
5
+ module Relation
6
+
7
+ private
8
+
9
+ def tables_in_string(string)
10
+ super - ['__rnt']
11
+ end
12
+
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ ActiveRecord::Relation.send :include, ActiveRecord::ConnectionAdapters::Sqlserver::CoreExt::Relation
@@ -0,0 +1,49 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ module Sqlserver
4
+ module DatabaseLimits
5
+
6
+ def table_alias_length
7
+ 128
8
+ end
9
+
10
+ def column_name_length
11
+ 128
12
+ end
13
+
14
+ def table_name_length
15
+ 128
16
+ end
17
+
18
+ def index_name_length
19
+ 128
20
+ end
21
+
22
+ def columns_per_table
23
+ 1024
24
+ end
25
+
26
+ def indexes_per_table
27
+ 999
28
+ end
29
+
30
+ def columns_per_multicolumn_index
31
+ 16
32
+ end
33
+
34
+ def in_clause_length
35
+ 65536
36
+ end
37
+
38
+ def sql_query_length
39
+ 65536 * 4096
40
+ end
41
+
42
+ def joins_per_query
43
+ 256
44
+ end
45
+
46
+ end
47
+ end
48
+ end
49
+ end