activerecord-sqlserver-adapter 3.2.18 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +4 -28
  3. data/VERSION +1 -1
  4. data/lib/active_record/connection_adapters/sqlserver/core_ext/active_record.rb +2 -7
  5. data/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +6 -9
  6. data/lib/active_record/connection_adapters/sqlserver/core_ext/explain_subscriber.rb +3 -25
  7. data/lib/active_record/connection_adapters/sqlserver/core_ext/odbc.rb +4 -14
  8. data/lib/active_record/connection_adapters/sqlserver/core_ext/relation.rb +1 -3
  9. data/lib/active_record/connection_adapters/sqlserver/database_limits.rb +2 -4
  10. data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +74 -80
  11. data/lib/active_record/connection_adapters/sqlserver/errors.rb +10 -14
  12. data/lib/active_record/connection_adapters/sqlserver/quoting.rb +24 -15
  13. data/lib/active_record/connection_adapters/sqlserver/schema_cache.rb +24 -19
  14. data/lib/active_record/connection_adapters/sqlserver/schema_creation.rb +28 -0
  15. data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +118 -77
  16. data/lib/active_record/connection_adapters/sqlserver/showplan.rb +10 -13
  17. data/lib/active_record/connection_adapters/sqlserver/showplan/printer_table.rb +8 -11
  18. data/lib/active_record/connection_adapters/sqlserver/showplan/printer_xml.rb +2 -5
  19. data/lib/active_record/connection_adapters/sqlserver/table_definition.rb +23 -0
  20. data/lib/active_record/connection_adapters/sqlserver/utils.rb +4 -10
  21. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +121 -247
  22. data/lib/active_record/connection_adapters/sqlserver_column.rb +116 -0
  23. data/lib/active_record/sqlserver_base.rb +28 -0
  24. data/lib/active_record/sqlserver_test_case.rb +17 -0
  25. data/lib/arel/arel_sqlserver.rb +5 -0
  26. data/lib/arel/nodes_sqlserver.rb +14 -0
  27. data/lib/arel/select_manager_sqlserver.rb +62 -0
  28. data/lib/arel/visitors/sqlserver.rb +251 -188
  29. metadata +32 -10
  30. data/lib/active_record/connection_adapters/sqlserver/core_ext/database_statements.rb +0 -97
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 518484bb28fd5a4a70ac12e7d994071c645ff0ea
4
- data.tar.gz: 1eac15ea4105d11cc1f80e4e1416e173808ae9e3
3
+ metadata.gz: e47a3b956b52f24e1dc9f743d5f91590e1fb4337
4
+ data.tar.gz: f4a3544a7539acb775ff6cfa75925f1cf615e4c3
5
5
  SHA512:
6
- metadata.gz: 1f570f10c5ec18d26353568f985bbc06b9d621f6afecc0c71e8f7ad2ee2eca80754d7c7c06cd413e7813394960abaf69d3c9832772095bba5ac5bb4638ae774a
7
- data.tar.gz: e4f8c5d50c6fb2ce27460af6ea53592438964c5c93105ee5c66ce88c7a44e050e9c4faa5a7eec13197365dc531e5be25a4e08ec0b5f696934aec88348f7bd0cd
6
+ metadata.gz: 24465af624f8c38d423bd545842e007eaf86371ea802f8259ed54e6eb5b18ddafaf884b95e93637fc608f2033533415d6ca69663f6489afcaf4d04f8518e0250
7
+ data.tar.gz: 0029cf9f6b4f6de57f61848473ef243234cd32bce09f594e09a87bca8208c88626f06bed6bd186310d4f8b4749e6b03a32e0c88eeb7e6858767d8843518a9708
data/CHANGELOG CHANGED
@@ -1,31 +1,7 @@
1
- * 3.2.18 *
2
-
3
- * Added 2017 to supported list. Fixes #601. Thanks @catks.
4
-
5
- * 3.2.17 *
6
-
7
- * Add `WITH NO_INFOMSGS` to `user_options` method. Fixes #580
8
-
9
-
10
- * 3.2.16 *
11
-
12
- * All user optons to be array/hash. Fixes #540
13
-
14
-
15
- * 3.2.15 *
16
-
17
- * Added vNext support.
18
-
19
-
20
- * 3.2.14 *
21
-
22
- * Added 2016 to supported list.
23
-
24
-
25
- * 3.2.13 *
26
-
27
- * Allow 2014 to be used.
28
-
1
+ * 4.0.0 *
2
+ * Dropped support for ruby 1.8.7
3
+ * Removed deadlock victim retry in favor of Isolation Level
4
+ * Removed auto_explain_threshold_in_seconds (not used in rails 4)
29
5
 
30
6
  * 3.2.12 *
31
7
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.2.18
1
+ 4.0.0
@@ -3,9 +3,8 @@ module ActiveRecord
3
3
  module Sqlserver
4
4
  module CoreExt
5
5
  module ActiveRecord
6
-
7
6
  extend ActiveSupport::Concern
8
-
7
+
9
8
  included do
10
9
  class_attribute :coerced_sqlserver_date_columns, :coerced_sqlserver_time_columns
11
10
  self.coerced_sqlserver_date_columns = Set.new
@@ -13,10 +12,9 @@ module ActiveRecord
13
12
  end
14
13
 
15
14
  module ClassMethods
16
-
17
15
  def execute_procedure(proc_name, *variables)
18
16
  if connection.respond_to?(:execute_procedure)
19
- connection.execute_procedure(proc_name,*variables)
17
+ connection.execute_procedure(proc_name, *variables)
20
18
  else
21
19
  []
22
20
  end
@@ -29,14 +27,11 @@ module ActiveRecord
29
27
  def coerce_sqlserver_time(*attributes)
30
28
  self.coerced_sqlserver_time_columns += attributes.map(&:to_s)
31
29
  end
32
-
33
30
  end
34
-
35
31
  end
36
32
  end
37
33
  end
38
34
  end
39
35
  end
40
36
 
41
-
42
37
  ActiveRecord::Base.send :include, ActiveRecord::ConnectionAdapters::Sqlserver::CoreExt::ActiveRecord
@@ -3,19 +3,18 @@ module ActiveRecord
3
3
  module Sqlserver
4
4
  module CoreExt
5
5
  module Explain
6
-
7
- SQLSERVER_STATEMENT_PREFIX = "EXEC sp_executesql "
6
+ SQLSERVER_STATEMENT_PREFIX = 'EXEC sp_executesql '
8
7
  SQLSERVER_PARAM_MATCHER = /@\d+ =/
9
-
8
+
10
9
  def exec_explain(queries)
11
10
  unprepared_queries = queries.map { |sql, bind| [unprepare_sqlserver_statement(sql), bind] }
12
11
  super(unprepared_queries)
13
12
  end
14
-
13
+
15
14
  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
15
+
16
+ # This is somewhat hacky, but it should reliably reformat our prepared sql statment
17
+ # which uses sp_executesql to just the first argument, then unquote it. Likewise our
19
18
  # do_exec_query method should substitude the @n args withe the quoted values.
20
19
  def unprepare_sqlserver_statement(sql)
21
20
  if sql.starts_with?(SQLSERVER_STATEMENT_PREFIX)
@@ -29,8 +28,6 @@ module ActiveRecord
29
28
  sql
30
29
  end
31
30
  end
32
-
33
-
34
31
  end
35
32
  end
36
33
  end
@@ -1,26 +1,4 @@
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
1
+ silence_warnings do
2
+ # Already defined in Rails
3
+ ActiveRecord::ExplainSubscriber::EXPLAINED_SQLS = /(select|update|delete|insert)\b/i
26
4
  end
@@ -3,36 +3,26 @@ module ActiveRecord
3
3
  module Sqlserver
4
4
  module CoreExt
5
5
  module ODBC
6
-
7
6
  module Statement
8
-
9
7
  def finished?
10
- begin
11
- connected?
12
- false
13
- rescue ::ODBC::Error
14
- true
15
- end
8
+ connected?
9
+ false
10
+ rescue ::ODBC::Error
11
+ true
16
12
  end
17
-
18
13
  end
19
14
 
20
15
  module Database
21
-
22
16
  def run_block(*args)
23
17
  yield sth = run(*args)
24
18
  sth.drop
25
19
  end
26
-
27
20
  end
28
-
29
21
  end
30
22
  end
31
23
  end
32
24
  end
33
25
  end
34
26
 
35
-
36
27
  ODBC::Statement.send :include, ActiveRecord::ConnectionAdapters::Sqlserver::CoreExt::ODBC::Statement
37
28
  ODBC::Database.send :include, ActiveRecord::ConnectionAdapters::Sqlserver::CoreExt::ODBC::Database
38
-
@@ -3,13 +3,11 @@ module ActiveRecord
3
3
  module Sqlserver
4
4
  module CoreExt
5
5
  module Relation
6
-
7
6
  private
8
-
7
+
9
8
  def tables_in_string(string)
10
9
  super - ['__rnt']
11
10
  end
12
-
13
11
  end
14
12
  end
15
13
  end
@@ -2,7 +2,6 @@ module ActiveRecord
2
2
  module ConnectionAdapters
3
3
  module Sqlserver
4
4
  module DatabaseLimits
5
-
6
5
  def table_alias_length
7
6
  128
8
7
  end
@@ -32,17 +31,16 @@ module ActiveRecord
32
31
  end
33
32
 
34
33
  def in_clause_length
35
- 65536
34
+ 65_536
36
35
  end
37
36
 
38
37
  def sql_query_length
39
- 65536 * 4096
38
+ 65_536 * 4_096
40
39
  end
41
40
 
42
41
  def joins_per_query
43
42
  256
44
43
  end
45
-
46
44
  end
47
45
  end
48
46
  end
@@ -2,69 +2,58 @@ module ActiveRecord
2
2
  module ConnectionAdapters
3
3
  module Sqlserver
4
4
  module DatabaseStatements
5
-
6
- include CoreExt::DatabaseStatements
7
-
8
- def select_rows(sql, name = nil)
9
- raw_select sql, name, [], :fetch => :rows
5
+ def select_rows(sql, name = nil, binds = [])
6
+ do_exec_query sql, name, binds, fetch: :rows
10
7
  end
11
8
 
12
9
  def execute(sql, name = nil)
13
10
  if id_insert_table_name = query_requires_identity_insert?(sql)
14
- with_identity_insert_enabled(id_insert_table_name) { do_execute(sql,name) }
11
+ with_identity_insert_enabled(id_insert_table_name) { do_execute(sql, name) }
15
12
  else
16
- do_execute(sql,name)
13
+ do_execute(sql, name)
17
14
  end
18
15
  end
19
16
 
20
17
  def exec_query(sql, name = 'SQL', binds = [], sqlserver_options = {})
21
18
  if id_insert_table_name = sqlserver_options[:insert] ? query_requires_identity_insert?(sql) : nil
22
19
  with_identity_insert_enabled(id_insert_table_name) { do_exec_query(sql, name, binds) }
20
+ elsif update_sql?(sql)
21
+ sql = strip_ident_from_update(sql)
22
+ do_exec_query(sql, name, binds)
23
23
  else
24
24
  do_exec_query(sql, name, binds)
25
25
  end
26
26
  end
27
27
 
28
- def exec_insert(sql, name, binds)
29
- exec_query sql, name, binds, :insert => true
28
+ # The abstract adapter ignores the last two parameters also
29
+ def exec_insert(sql, name, binds, _pk = nil, _sequence_name = nil)
30
+ exec_query sql, name, binds, insert: true
30
31
  end
31
32
 
32
33
  def exec_delete(sql, name, binds)
33
- sql << "; SELECT @@ROWCOUNT AS AffectedRows"
34
+ sql << '; SELECT @@ROWCOUNT AS AffectedRows'
34
35
  super.rows.first.first
35
36
  end
36
37
 
37
38
  def exec_update(sql, name, binds)
38
- sql << "; SELECT @@ROWCOUNT AS AffectedRows"
39
+ sql << '; SELECT @@ROWCOUNT AS AffectedRows'
39
40
  super.rows.first.first
40
41
  end
41
42
 
42
- def outside_transaction?
43
- uncached { select_value('SELECT @@TRANCOUNT', 'SCHEMA') == 0 }
44
- end
45
-
46
43
  def supports_statement_cache?
47
44
  true
48
45
  end
49
46
 
50
- def transaction(options = {})
51
- if retry_deadlock_victim?
52
- block_given? ? transaction_with_retry_deadlock_victim(options) { yield } : transaction_with_retry_deadlock_victim(options)
53
- else
54
- block_given? ? super(options) { yield } : super(options)
55
- end
56
- end
57
-
58
47
  def begin_db_transaction
59
- do_execute "BEGIN TRANSACTION"
48
+ do_execute 'BEGIN TRANSACTION'
60
49
  end
61
50
 
62
51
  def commit_db_transaction
63
- disable_auto_reconnect { do_execute "COMMIT TRANSACTION" }
52
+ disable_auto_reconnect { do_execute 'COMMIT TRANSACTION' }
64
53
  end
65
54
 
66
55
  def rollback_db_transaction
67
- do_execute "IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION"
56
+ do_execute 'IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION'
68
57
  end
69
58
 
70
59
  def create_savepoint
@@ -78,12 +67,12 @@ module ActiveRecord
78
67
  disable_auto_reconnect { do_execute "ROLLBACK TRANSACTION #{current_savepoint_name}" }
79
68
  end
80
69
 
81
- def add_limit_offset!(sql, options)
70
+ def add_limit_offset!(_sql, _options)
82
71
  raise NotImplementedError, 'This has been moved to the SQLServerCompiler in Arel.'
83
72
  end
84
73
 
85
74
  def empty_insert_statement_value
86
- "DEFAULT VALUES"
75
+ 'DEFAULT VALUES'
87
76
  end
88
77
 
89
78
  def case_sensitive_modifier(node)
@@ -94,7 +83,7 @@ module ActiveRecord
94
83
 
95
84
  def execute_procedure(proc_name, *variables)
96
85
  vars = if variables.any? && variables.first.is_a?(Hash)
97
- variables.first.map { |k,v| "@#{k} = #{quote(v)}" }
86
+ variables.first.map { |k, v| "@#{k} = #{quote(v)}" }
98
87
  else
99
88
  variables.map { |v| quote(v) }
100
89
  end.join(', ')
@@ -104,41 +93,36 @@ module ActiveRecord
104
93
  case @connection_options[:mode]
105
94
  when :dblib
106
95
  result = @connection.execute(sql)
107
- result.each(:as => :hash, :cache_rows => true) do |row|
96
+ result.each(as: :hash, cache_rows: true) do |row|
108
97
  r = row.with_indifferent_access
109
98
  yield(r) if block_given?
110
99
  end
111
- result.each.map{ |row| row.is_a?(Hash) ? row.with_indifferent_access : row }
100
+ result.each.map { |row| row.is_a?(Hash) ? row.with_indifferent_access : row }
112
101
  when :odbc
113
102
  results = []
114
103
  raw_connection_run(sql) do |handle|
115
- get_rows = lambda {
116
- rows = handle_to_names_and_values handle, :fetch => :all
117
- rows.each_with_index { |r,i| rows[i] = r.with_indifferent_access }
104
+ get_rows = lambda do
105
+ rows = handle_to_names_and_values handle, fetch: :all
106
+ rows.each_with_index { |r, i| rows[i] = r.with_indifferent_access }
118
107
  results << rows
119
- }
120
- get_rows.call
121
- while handle_more_results?(handle)
122
- get_rows.call
123
108
  end
109
+ get_rows.call
110
+ get_rows.call while handle_more_results?(handle)
124
111
  end
125
112
  results.many? ? results : results.first
126
113
  end
127
114
  end
128
115
  end
129
116
 
130
- def use_database(database=nil)
117
+ def use_database(database = nil)
131
118
  return if sqlserver_azure?
132
119
  database ||= @connection_options[:database]
133
- do_execute "USE #{quote_table_name(database)}" unless database.blank?
120
+ do_execute "USE #{quote_database_name(database)}" unless database.blank?
134
121
  end
135
122
 
136
123
  def user_options
137
124
  return {} if sqlserver_azure?
138
- # fixes #535
139
- rows = select_rows('DBCC USEROPTIONS WITH NO_INFOMSGS', 'SCHEMA')
140
- rows = rows.first if rows.size == 2 && rows.last.empty?
141
- rows.reduce(HashWithIndifferentAccess.new) do |values, row|
125
+ select_rows('dbcc useroptions', 'SCHEMA').reduce(HashWithIndifferentAccess.new) do |values, row|
142
126
  if row.instance_of? Hash
143
127
  set_option = row.values[0].gsub(/\s+/, '_')
144
128
  user_value = row.values[1]
@@ -151,6 +135,7 @@ module ActiveRecord
151
135
  end
152
136
  end
153
137
 
138
+ # TODO: Rails 4 now supports isolation levels
154
139
  def user_options_dateformat
155
140
  if sqlserver_azure?
156
141
  select_value 'SELECT [dateformat] FROM [sys].[syslanguages] WHERE [langid] = @@LANGID', 'SCHEMA'
@@ -161,7 +146,7 @@ module ActiveRecord
161
146
 
162
147
  def user_options_isolation_level
163
148
  if sqlserver_azure?
164
- sql = %|SELECT CASE [transaction_isolation_level]
149
+ sql = %(SELECT CASE [transaction_isolation_level]
165
150
  WHEN 0 THEN NULL
166
151
  WHEN 1 THEN 'READ UNCOMITTED'
167
152
  WHEN 2 THEN 'READ COMITTED'
@@ -169,7 +154,7 @@ module ActiveRecord
169
154
  WHEN 4 THEN 'SERIALIZABLE'
170
155
  WHEN 5 THEN 'SNAPSHOT' END AS [isolation_level]
171
156
  FROM [sys].[dm_exec_sessions]
172
- WHERE [session_id] = @@SPID|.squish
157
+ WHERE [session_id] = @@SPID).squish
173
158
  select_value sql, 'SCHEMA'
174
159
  else
175
160
  user_options['isolation_level']
@@ -185,8 +170,10 @@ module ActiveRecord
185
170
  end
186
171
 
187
172
  def run_with_isolation_level(isolation_level)
188
- raise ArgumentError, "Invalid isolation level, #{isolation_level}. Supported levels include #{valid_isolation_levels.to_sentence}." if !valid_isolation_levels.include?(isolation_level.upcase)
189
- initial_isolation_level = user_options_isolation_level || "READ COMMITTED"
173
+ unless valid_isolation_levels.include?(isolation_level.upcase)
174
+ raise ArgumentError, "Invalid isolation level, #{isolation_level}. Supported levels include #{valid_isolation_levels.to_sentence}."
175
+ end
176
+ initial_isolation_level = user_options_isolation_level || 'READ COMMITTED'
190
177
  do_execute "SET TRANSACTION ISOLATION LEVEL #{isolation_level}"
191
178
  begin
192
179
  yield
@@ -196,11 +183,11 @@ module ActiveRecord
196
183
  end
197
184
 
198
185
  def newid_function
199
- select_value "SELECT NEWID()"
186
+ select_value 'SELECT NEWID()'
200
187
  end
201
188
 
202
189
  def newsequentialid_function
203
- select_value "SELECT NEWSEQUENTIALID()"
190
+ select_value 'SELECT NEWSEQUENTIALID()'
204
191
  end
205
192
 
206
193
  def activity_stats
@@ -256,7 +243,7 @@ module ActiveRecord
256
243
  end
257
244
  end
258
245
 
259
- def recreate_database!(database=nil)
246
+ def recreate_database!(database = nil)
260
247
  current_db = current_database
261
248
  database ||= current_db
262
249
  this_db = database.to_s == current_db
@@ -271,7 +258,7 @@ module ActiveRecord
271
258
  retry_count = 0
272
259
  max_retries = 1
273
260
  begin
274
- do_execute "DROP DATABASE #{quote_table_name(database)}"
261
+ do_execute "DROP DATABASE #{quote_database_name(database)}"
275
262
  rescue ActiveRecord::StatementInvalid => err
276
263
  if err.message =~ /because it is currently in use/i
277
264
  raise if retry_count >= max_retries
@@ -286,8 +273,12 @@ module ActiveRecord
286
273
  end
287
274
  end
288
275
 
289
- def create_database(database)
290
- do_execute "CREATE DATABASE #{quote_table_name(database)}"
276
+ def create_database(database, collation = @connection_options[:collation])
277
+ if collation
278
+ do_execute "CREATE DATABASE #{quote_database_name(database)} COLLATE #{collation}"
279
+ else
280
+ do_execute "CREATE DATABASE #{quote_database_name(database)}"
281
+ end
291
282
  end
292
283
 
293
284
  def current_database
@@ -298,26 +289,26 @@ module ActiveRecord
298
289
  select_value "SELECT SERVERPROPERTY('SqlCharSetName')"
299
290
  end
300
291
 
301
-
302
292
  protected
303
293
 
304
294
  def select(sql, name = nil, binds = [])
305
- exec_query(sql, name, binds).to_a
295
+ exec_query(sql, name, binds)
306
296
  end
307
297
 
308
298
  def sql_for_insert(sql, pk, id_value, sequence_name, binds)
309
- sql = "#{sql}; SELECT CAST(SCOPE_IDENTITY() AS bigint) AS Ident"# unless binds.empty?
299
+ sql =
300
+ if pk
301
+ sql.insert(sql.index(/ (DEFAULT )?VALUES/), " OUTPUT inserted.#{pk}")
302
+ else
303
+ "#{sql}; SELECT CAST(SCOPE_IDENTITY() AS bigint) AS Ident"
304
+ end
310
305
  super
311
306
  end
312
307
 
313
- def last_inserted_id(result)
314
- super || select_value("SELECT CAST(SCOPE_IDENTITY() AS bigint) AS Ident")
315
- end
316
-
317
308
  # === SQLServer Specific ======================================== #
318
309
 
319
310
  def valid_isolation_levels
320
- ["READ COMMITTED", "READ UNCOMMITTED", "REPEATABLE READ", "SERIALIZABLE", "SNAPSHOT"]
311
+ ['READ COMMITTED', 'READ UNCOMMITTED', 'REPEATABLE READ', 'SERIALIZABLE', 'SNAPSHOT']
321
312
  end
322
313
 
323
314
  # === SQLServer Specific (Executing) ============================ #
@@ -328,11 +319,17 @@ module ActiveRecord
328
319
  end
329
320
  end
330
321
 
331
- def do_exec_query(sql, name, binds)
322
+ def do_exec_query(sql, name, binds, options = {})
323
+ # This allows non-AR code to utilize the binds
324
+ # handling code, e.g. select_rows()
325
+ if options[:fetch] != :rows
326
+ options[:ar_result] = true
327
+ end
328
+
332
329
  explaining = name == 'EXPLAIN'
333
330
  names_and_types = []
334
331
  params = []
335
- binds.each_with_index do |(column,value),index|
332
+ binds.each_with_index do |(column, value), index|
336
333
  ar_column = column.is_a?(ActiveRecord::ConnectionAdapters::Column)
337
334
  next if ar_column && column.sql_type == 'timestamp'
338
335
  v = value
@@ -345,9 +342,9 @@ module ActiveRecord
345
342
  v = value.to_i
346
343
  "@#{index} int"
347
344
  else
348
- raise "Unknown bind columns. We can account for this."
345
+ raise 'Unknown bind columns. We can account for this.'
349
346
  end
350
- quoted_value = ar_column ? quote(v,column) : quote(v,nil)
347
+ quoted_value = ar_column ? quote(v, column) : quote(v, nil)
351
348
  params << (explaining ? quoted_value : "@#{index} = #{quoted_value}")
352
349
  end
353
350
  if explaining
@@ -359,7 +356,7 @@ module ActiveRecord
359
356
  sql = "EXEC sp_executesql #{quote(sql)}"
360
357
  sql << ", #{quote(names_and_types.join(', '))}, #{params.join(', ')}" unless binds.empty?
361
358
  end
362
- raw_select sql, name, binds, :ar_result => true
359
+ raw_select sql, name, binds, options
363
360
  end
364
361
 
365
362
  def raw_connection_do(sql)
@@ -375,17 +372,15 @@ module ActiveRecord
375
372
 
376
373
  # === SQLServer Specific (Selecting) ============================ #
377
374
 
378
- def raw_select(sql, name='SQL', binds=[], options={})
379
- log(sql,name,binds) { _raw_select(sql, options) }
375
+ def raw_select(sql, name = 'SQL', binds = [], options = {})
376
+ log(sql, name, binds) { _raw_select(sql, options) }
380
377
  end
381
378
 
382
- def _raw_select(sql, options={})
383
- begin
384
- handle = raw_connection_run(sql)
385
- handle_to_names_and_values(handle, options)
386
- ensure
387
- finish_statement_handle(handle)
388
- end
379
+ def _raw_select(sql, options = {})
380
+ handle = raw_connection_run(sql)
381
+ handle_to_names_and_values(handle, options)
382
+ ensure
383
+ finish_statement_handle(handle)
389
384
  end
390
385
 
391
386
  def raw_connection_run(sql)
@@ -407,7 +402,7 @@ module ActiveRecord
407
402
  end
408
403
  end
409
404
 
410
- def handle_to_names_and_values(handle, options={})
405
+ def handle_to_names_and_values(handle, options = {})
411
406
  case @connection_options[:mode]
412
407
  when :dblib
413
408
  handle_to_names_and_values_dblib(handle, options)
@@ -416,7 +411,7 @@ module ActiveRecord
416
411
  end
417
412
  end
418
413
 
419
- def handle_to_names_and_values_dblib(handle, options={})
414
+ def handle_to_names_and_values_dblib(handle, options = {})
420
415
  query_options = {}.tap do |qo|
421
416
  qo[:timezone] = ActiveRecord::Base.default_timezone || :utc
422
417
  qo[:as] = (options[:ar_result] || options[:fetch] == :rows) ? :array : :hash
@@ -426,7 +421,7 @@ module ActiveRecord
426
421
  options[:ar_result] ? ActiveRecord::Result.new(columns, results) : results
427
422
  end
428
423
 
429
- def handle_to_names_and_values_odbc(handle, options={})
424
+ def handle_to_names_and_values_odbc(handle, options = {})
430
425
  @connection.use_utc = ActiveRecord::Base.default_timezone == :utc
431
426
  if options[:ar_result]
432
427
  columns = lowercase_schema_reflection ? handle.columns(true).map { |c| c.name.downcase } : handle.columns(true).map { |c| c.name }
@@ -451,7 +446,6 @@ module ActiveRecord
451
446
  end
452
447
  handle
453
448
  end
454
-
455
449
  end
456
450
  end
457
451
  end