activerecord-sqlserver-adapter 7.2.9 → 8.0.0

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 (30) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +10 -6
  3. data/CHANGELOG.md +5 -67
  4. data/Dockerfile.ci +1 -1
  5. data/Gemfile +2 -0
  6. data/README.md +16 -17
  7. data/VERSION +1 -1
  8. data/activerecord-sqlserver-adapter.gemspec +2 -2
  9. data/docker-compose.ci.yml +0 -1
  10. data/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb +1 -1
  11. data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +50 -56
  12. data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +129 -118
  13. data/lib/active_record/connection_adapters/sqlserver/showplan.rb +1 -0
  14. data/lib/active_record/connection_adapters/sqlserver/type/time.rb +3 -2
  15. data/lib/active_record/connection_adapters/sqlserver/utils.rb +0 -4
  16. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +17 -27
  17. data/test/cases/adapter_test_sqlserver.rb +36 -38
  18. data/test/cases/coerced_tests.rb +153 -60
  19. data/test/cases/helper_sqlserver.rb +0 -8
  20. data/test/cases/optimizer_hints_test_sqlserver.rb +1 -2
  21. data/test/cases/schema_test_sqlserver.rb +0 -6
  22. data/test/cases/showplan_test_sqlserver.rb +2 -2
  23. data/test/cases/specific_schema_test_sqlserver.rb +6 -6
  24. data/test/cases/view_test_sqlserver.rb +3 -9
  25. data/test/support/query_assertions.rb +0 -22
  26. metadata +11 -15
  27. data/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb +0 -29
  28. data/test/cases/temp_test_sqlserver.rb +0 -9
  29. data/test/cases/temporary_table_test_sqlserver.rb +0 -19
  30. data/test/fixtures/sst_customers_view.yml +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aeac1dd3621ed52e93f365fefbca8a0e83ffcfbdac6b01907260efa98db1069f
4
- data.tar.gz: daa368ec2b8e38e25aaab374640a29e7d6a5482a78609b32cabefdc716a01b78
3
+ metadata.gz: 926f65915d98bb3c271370883fa89891fc575b5c6801cd8c235386c078d34bf5
4
+ data.tar.gz: 0a932a9d5edf0d3932e3f0ba44328ed77a033a1223f05699e8f4caa79116ac56
5
5
  SHA512:
6
- metadata.gz: 0ca3530b11fd81b695bde3264fd2daaa221c7f21a7c6e86cbfef14bdf4a60b4aba26238aec58c2456d953fb1aa933c27c0800978061ad71889b0e92fc6a4ebf7
7
- data.tar.gz: 5b3b6bbf751511101b26d319554ec1f394fc0d4a76250812146e7400a342b31aa60cb314406f4352f27a49b04fdfa79cf41c7cba12c916b866df6254bf0ddf03
6
+ metadata.gz: ee45540a8d2ae57dc69a35048f4ccfbf01bcfc91e177e57405b19ccb8a3279eef7b752c22dee20c4171c8bb4e2cb0fcaadb99cd6c25d139fd2ef53577a5cb23a
7
+ data.tar.gz: 9184a7041e5de445103bcd47832352614897865f0ef49e83067b553786d089be73eb73c34dfaf3f102e02804ee7d8d40803d5582430ebfeecbe95f568b0b7cb7
@@ -1,12 +1,17 @@
1
1
  name: CI
2
2
 
3
- on: [push, pull_request]
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ pull_request:
7
+ branches: [ main ]
8
+ schedule:
9
+ - cron: '0 4 * * 1'
4
10
 
5
11
  jobs:
6
12
  test:
7
13
  name: Run test suite
8
- runs-on: ubuntu-latest
9
- timeout-minutes: 10
14
+ runs-on: ubuntu-20.04 # TODO: Change back to 'ubuntu-latest' when https://github.com/microsoft/mssql-docker/issues/899 resolved.
10
15
 
11
16
  env:
12
17
  COMPOSE_FILE: docker-compose.ci.yml
@@ -15,9 +20,8 @@ jobs:
15
20
  fail-fast: false
16
21
  matrix:
17
22
  ruby:
18
- - 3.1.6
19
- - 3.2.4
20
- - 3.3.2
23
+ - 3.3.4
24
+ - 3.2.5
21
25
 
22
26
  steps:
23
27
  - name: Checkout code
data/CHANGELOG.md CHANGED
@@ -1,74 +1,12 @@
1
- ## v7.2.9
2
-
3
- #### Fixed
4
-
5
- - [#1371](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1371) Fixed query logging so that filter parameters are respected.
6
-
7
- ## v7.2.8
8
-
9
- #### Fixed
10
-
11
- - [#1365](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1365) Verify connection before retrieving the database version.
12
-
13
- ## v7.2.7
1
+ ## v8.0.0
14
2
 
15
3
  #### Changed
16
4
 
17
- - [#1341](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1341) Support more Azure services by changing language source.
18
-
19
- #### Fixed
20
-
21
- - [#1357](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1357) Support cross database inserts.
22
-
23
- ## v7.2.6
24
-
25
- #### Fixed
26
-
27
- - [#1333](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1333) Enable identity insert on view's base table for fixtures.
28
-
29
- ## v7.2.5
30
-
31
- #### Fixed
32
-
33
- - [#1308](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1308) Fix retrieval of temporary table's column information.
34
-
35
- ## v7.2.4
5
+ - [#1216](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1216) Refactor adapter interface to match abstract adapter
6
+ - [#1225](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1225) Drop support to Ruby 3.1
36
7
 
37
8
  #### Fixed
38
9
 
39
- - [#1270](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1270) Fix parsing of raw table name from SQL with extra parentheses
40
-
41
- ## v7.2.3
42
-
43
- #### Fixed
44
-
45
- - [#1262](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1262) Fix distinct alias when multiple databases used.
46
-
47
- ## v7.2.2
48
-
49
- #### Fixed
50
-
51
- - [#1244](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1244) Allow INSERT statements with SELECT notation
52
- - [#1247](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1247) Fix queries with date and date-time placeholder conditions
53
- - [#1249](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1249) Binary basic columns should be limitable
54
- - [#1255](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1255) Fixed the ordering of optimizer hints in the generated SQL
55
-
56
- ## v7.2.1
57
-
58
- #### Fixed
59
-
60
- - [#1231](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1231) Enable identity insert on view's base table
61
-
62
- ## v7.2.0
63
-
64
- #### Added
65
-
66
- - [#1178](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1178) Support encrypting binary columns
67
-
68
- #### Changed
69
-
70
- - [#1153](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1153) Only support Ruby v3.1+
71
- - [#1196](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1196) Use default inspect for database adapter
72
-
10
+ - [#1215](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1215) Fix mismatched foreign key errors
73
11
 
74
- Please check [7-1-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/7-1-stable/CHANGELOG.md) for previous changes.
12
+ Please check [7-2-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/7-2-stable/CHANGELOG.md) for previous changes.
data/Dockerfile.ci CHANGED
@@ -9,6 +9,6 @@ WORKDIR $WORKDIR
9
9
 
10
10
  COPY . $WORKDIR
11
11
 
12
- RUN RAILS_BRANCH=7-2-stable bundle install --jobs `expr $(cat /proc/cpuinfo | grep -c "cpu cores") - 1` --retry 3
12
+ RUN bundle install --jobs `expr $(cat /proc/cpuinfo | grep -c "cpu cores") - 1` --retry 3
13
13
 
14
14
  CMD ["sh"]
data/Gemfile CHANGED
@@ -18,6 +18,8 @@ if ENV["RAILS_SOURCE"]
18
18
  gemspec path: ENV["RAILS_SOURCE"]
19
19
  elsif ENV["RAILS_BRANCH"]
20
20
  gem "rails", github: "rails/rails", branch: ENV["RAILS_BRANCH"]
21
+ elsif ENV["RAILS_COMMIT"]
22
+ gem "rails", github: "rails/rails", ref: ENV["RAILS_COMMIT"]
21
23
  else
22
24
  # Need to get rails source because the gem doesn't include tests
23
25
  version = ENV["RAILS_VERSION"] || begin
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # ActiveRecord SQL Server Adapter. For SQL Server 2012 And Higher.
1
+ # ActiveRecord SQL Server Adapter
2
2
 
3
3
  * [![CI](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/actions/workflows/ci.yml/badge.svg)](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/actions/workflows/ci.yml) - CI
4
4
  * [![Gem Version](http://img.shields.io/gem/v/activerecord-sqlserver-adapter.svg)](https://rubygems.org/gems/activerecord-sqlserver-adapter) - Gem Version
@@ -8,15 +8,18 @@
8
8
 
9
9
  The SQL Server adapter for ActiveRecord using SQL Server 2012 or higher.
10
10
 
11
- Interested in older versions? We follow a rational versioning policy that tracks Rails. That means that our 7.x version
12
- of the adapter is only for the latest 7.x version of Rails. If you need the adapter for SQL Server 2008 or 2005, you
13
- are still in the right spot. Just install the latest 3.2.x to 4.1.x version of the adapter that matches your Rails
14
- version. We also have stable branches for each major/minor release of ActiveRecord. For older versions, please check
15
- their stable branches.
11
+ We follow a rational versioning policy that tracks Rails. That means that our 7.x version of the adapter is only
12
+ for the latest 7.x version of Rails. We also have stable branches for each major/minor release of ActiveRecord.
13
+
14
+ We support the versions of the adapter that are in the Rails [Bug Fixes](https://rubyonrails.org/maintenance)
15
+ maintenance group.
16
+
17
+ See [Rubygems](https://rubygems.org/gems/activerecord-sqlserver-adapter/versions) for the latest version of the adapter for each Rails release.
16
18
 
17
19
  | Adapter Version | Rails Version | Support | Branch |
18
20
  |-----------------|---------------|----------------|-------------------------------------------------------------------------------------------------|
19
- | `7.2.x` | `7.2.x` | Active | [main](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/main) |
21
+ | `8.0.0` | `8.0.x` | Active | [main](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/main) |
22
+ | `7.2.x` | `7.2.x` | Active | [7-2-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/7-2-stable) |
20
23
  | `7.1.x` | `7.1.x` | Active | [7-1-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/7-1-stable) |
21
24
  | `7.0.x` | `7.0.x` | Ended | [7-0-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/7-0-stable) |
22
25
  | `6.1.x` | `6.1.x` | Ended | [6-1-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/6-1-stable) |
@@ -26,7 +29,6 @@ their stable branches.
26
29
  | `4.2.x` | `4.2.x` | Ended | [4-2-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/4-2-stable) |
27
30
  | `4.1.x` | `4.1.x` | Ended | [4-1-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/4-1-stable) |
28
31
 
29
- See [Rubygems](https://rubygems.org/gems/activerecord-sqlserver-adapter/versions) for the latest version of the adapter for each Rails release.
30
32
 
31
33
  #### Native Data Type Support
32
34
 
@@ -103,16 +105,14 @@ configuration then implement the `configure_connection` method in an initializer
103
105
  example we are setting the `TEXTSIZE` to 64 megabytes.
104
106
 
105
107
  ```ruby
106
- module ActiveRecord
107
- module ConnectionAdapters
108
- class SQLServerAdapter < AbstractAdapter
109
- def configure_connection
110
- super
111
- @raw_connection.execute("SET TEXTSIZE #{64.megabytes}").do
112
- end
108
+ ActiveRecord::ConnectionAdapters::SQLServerAdapter.prepend(
109
+ Module.new do
110
+ def configure_connection
111
+ super
112
+ @raw_connection.execute("SET TEXTSIZE #{64.megabytes}").do
113
113
  end
114
114
  end
115
- end
115
+ )
116
116
  ```
117
117
 
118
118
  #### Configure Application Name
@@ -262,7 +262,6 @@ Many many people have contributed. If you do not see your name here and it shoul
262
262
 
263
263
  You can see an up-to-date list of contributors here: http://github.com/rails-sqlserver/activerecord-sqlserver-adapter/contributors
264
264
 
265
-
266
265
  ## License
267
266
 
268
267
  ActiveRecord SQL Server Adapter is released under the [MIT License](https://opensource.org/licenses/MIT).
data/VERSION CHANGED
@@ -1 +1 @@
1
- 7.2.9
1
+ 8.0.0
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
7
7
  spec.platform = Gem::Platform::RUBY
8
8
  spec.version = version
9
9
 
10
- spec.required_ruby_version = ">= 3.1.0"
10
+ spec.required_ruby_version = ">= 3.2.0"
11
11
 
12
12
  spec.license = "MIT"
13
13
  spec.authors = ["Ken Collins", "Anna Carey", "Will Bond", "Murray Steele", "Shawn Balestracci", "Joe Rafaniello", "Tom Ward", "Aidan Haran"]
@@ -27,6 +27,6 @@ Gem::Specification.new do |spec|
27
27
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
28
28
  spec.require_paths = ["lib"]
29
29
 
30
- spec.add_dependency "activerecord", "~> 7.2.0"
30
+ spec.add_dependency "activerecord", "~> 8.0.0"
31
31
  spec.add_dependency "tiny_tds"
32
32
  end
@@ -5,7 +5,6 @@ services:
5
5
  ci:
6
6
  environment:
7
7
  - ACTIVERECORD_UNITTEST_HOST=sqlserver
8
- - RAILS_BRANCH=7-2-stable
9
8
  build:
10
9
  context: .
11
10
  dockerfile: Dockerfile.ci
@@ -11,7 +11,7 @@ module ActiveRecord
11
11
  private
12
12
 
13
13
  def construct_relation_for_exists(conditions)
14
- klass.with_connection do |connection|
14
+ model.with_connection do |connection|
15
15
  if connection.sqlserver?
16
16
  _construct_relation_for_exists(conditions)
17
17
  else
@@ -13,48 +13,42 @@ module ActiveRecord
13
13
  !READ_QUERY.match?(sql.b)
14
14
  end
15
15
 
16
- def raw_execute(sql, name, async: false, allow_retry: false, materialize_transactions: true)
17
- log(sql, name, async: async) do |notification_payload|
18
- with_raw_connection(allow_retry: allow_retry, materialize_transactions: materialize_transactions) do |conn|
19
- result = if id_insert_table_name = query_requires_identity_insert?(sql)
20
- with_identity_insert_enabled(id_insert_table_name, conn) { internal_raw_execute(sql, conn, perform_do: true) }
21
- else
22
- internal_raw_execute(sql, conn, perform_do: true)
23
- end
24
- verified!
25
- notification_payload[:row_count] = result
26
- result
27
- end
16
+ def perform_query(raw_connection, sql, binds, type_casted_binds, prepare:, notification_payload:, batch:)
17
+ result = if id_insert_table_name = query_requires_identity_insert?(sql)
18
+ # If the table name is a view, we need to get the base table name for enabling identity insert.
19
+ id_insert_table_name = view_table_name(id_insert_table_name) if view_exists?(id_insert_table_name)
20
+
21
+ with_identity_insert_enabled(id_insert_table_name, raw_connection) do
22
+ internal_exec_sql_query(sql, raw_connection)
23
+ end
24
+ else
25
+ internal_exec_sql_query(sql, raw_connection)
26
+ end
27
+
28
+ verified!
29
+ notification_payload[:row_count] = result.count
30
+ result
31
+ end
32
+
33
+ def cast_result(raw_result)
34
+ if raw_result.columns.empty?
35
+ ActiveRecord::Result.empty
36
+ else
37
+ ActiveRecord::Result.new(raw_result.columns, raw_result.rows)
28
38
  end
29
39
  end
30
40
 
31
- def internal_exec_query(sql, name = "SQL", binds = [], prepare: false, async: false, allow_retry: false)
32
- sql = transform_query(sql)
33
-
34
- check_if_write_query(sql)
35
- mark_transaction_written_if_write(sql)
36
-
37
- type_casted_binds = type_casted_binds(binds)
38
- log(sql, name, binds, type_casted_binds, async: async) do |notification_payload|
39
- unless without_prepared_statement?(binds)
40
- types, params = sp_executesql_types_and_parameters(binds)
41
- sql = sp_executesql_sql(sql, types, params, name)
42
- end
43
-
44
- with_raw_connection do |conn|
45
- result = if id_insert_table_name = query_requires_identity_insert?(sql)
46
- with_identity_insert_enabled(id_insert_table_name, conn) do
47
- internal_exec_sql_query(sql, conn)
48
- end
49
- else
50
- internal_exec_sql_query(sql, conn)
51
- end
41
+ def affected_rows(raw_result)
42
+ raw_result.first['AffectedRows']
43
+ end
52
44
 
53
- verified!
54
- notification_payload[:row_count] = result.count
55
- result
56
- end
45
+ def raw_execute(sql, name = nil, binds = [], prepare: false, async: false, allow_retry: false, materialize_transactions: true, batch: false)
46
+ unless binds.nil? || binds.empty?
47
+ types, params = sp_executesql_types_and_parameters(binds)
48
+ sql = sp_executesql_sql(sql, types, params, name)
57
49
  end
50
+
51
+ super
58
52
  end
59
53
 
60
54
  def internal_exec_sql_query(sql, conn)
@@ -64,14 +58,14 @@ module ActiveRecord
64
58
  finish_statement_handle(handle)
65
59
  end
66
60
 
67
- def exec_delete(sql, name, binds)
61
+ def exec_delete(sql, name = nil, binds = [])
68
62
  sql = sql.dup << "; SELECT @@ROWCOUNT AS AffectedRows"
69
- super(sql, name, binds).rows.first.first
63
+ super(sql, name, binds)
70
64
  end
71
65
 
72
- def exec_update(sql, name, binds)
66
+ def exec_update(sql, name = nil, binds = [])
73
67
  sql = sql.dup << "; SELECT @@ROWCOUNT AS AffectedRows"
74
- super(sql, name, binds).rows.first.first
68
+ super(sql, name, binds)
75
69
  end
76
70
 
77
71
  def begin_db_transaction
@@ -154,7 +148,7 @@ module ActiveRecord
154
148
  returning_sql = if returning.is_a?(String)
155
149
  returning
156
150
  else
157
- returning.map { |column| "INSERTED.#{quote_column_name(column)}" }.join(", ")
151
+ Array(returning).map { |column| "INSERTED.#{quote_column_name(column)}" }.join(", ")
158
152
  end
159
153
  sql << " OUTPUT #{returning_sql}"
160
154
  end
@@ -192,14 +186,11 @@ module ActiveRecord
192
186
  end
193
187
 
194
188
  def with_identity_insert_enabled(table_name, conn)
195
- # If the table name is a view, we need to get the base table name for enabling identity insert.
196
- table_name = view_table_name(table_name) if view_exists?(table_name)
197
- quoted_table_name = quote_table_name(table_name)
198
-
199
- set_identity_insert(quoted_table_name, conn, true)
189
+ table_name = quote_table_name(table_name)
190
+ set_identity_insert(table_name, conn, true)
200
191
  yield
201
192
  ensure
202
- set_identity_insert(quoted_table_name, conn, false)
193
+ set_identity_insert(table_name, conn, false)
203
194
  end
204
195
 
205
196
  def use_database(database = nil)
@@ -229,7 +220,7 @@ module ActiveRecord
229
220
 
230
221
  def user_options_dateformat
231
222
  if sqlserver_azure?
232
- select_value "SELECT [dateformat] FROM [sys].[syslanguages] WHERE [name] = @@LANGUAGE", "SCHEMA"
223
+ select_value "SELECT [dateformat] FROM [sys].[syslanguages] WHERE [langid] = @@LANGID", "SCHEMA"
233
224
  else
234
225
  user_options["dateformat"]
235
226
  end
@@ -333,10 +324,13 @@ module ActiveRecord
333
324
 
334
325
  def sp_executesql_sql_type(attr)
335
326
  if attr.respond_to?(:type)
336
- return attr.type.sqlserver_type if attr.type.respond_to?(:sqlserver_type)
327
+ type = attr.type.is_a?(ActiveRecord::Normalization::NormalizedValueType) ? attr.type.cast_type : attr.type
328
+ type = type.subtype if type.serialized?
329
+
330
+ return type.sqlserver_type if type.respond_to?(:sqlserver_type)
337
331
 
338
- if attr.type.is_a?(ActiveRecord::Encryption::EncryptedAttributeType) && attr.type.instance_variable_get(:@cast_type).respond_to?(:sqlserver_type)
339
- return attr.type.instance_variable_get(:@cast_type).sqlserver_type
332
+ if type.is_a?(ActiveRecord::Encryption::EncryptedAttributeType) && type.instance_variable_get(:@cast_type).respond_to?(:sqlserver_type)
333
+ return type.instance_variable_get(:@cast_type).sqlserver_type
340
334
  end
341
335
  end
342
336
 
@@ -376,6 +370,7 @@ module ActiveRecord
376
370
  sql = "EXEC sp_executesql #{quote(sql)}"
377
371
  sql += ", #{types}, #{params}" unless params.empty?
378
372
  end
373
+
379
374
  sql.freeze
380
375
  end
381
376
 
@@ -453,10 +448,9 @@ module ActiveRecord
453
448
  # TinyTDS returns false instead of raising an exception if connection fails.
454
449
  # Getting around this by raising an exception ourselves while PR
455
450
  # https://github.com/rails-sqlserver/tiny_tds/pull/469 is not released.
456
- def internal_raw_execute(sql, conn, perform_do: false)
457
- result = conn.execute(sql).tap do |_result|
458
- raise TinyTds::Error, "failed to execute statement" if _result.is_a?(FalseClass)
459
- end
451
+ def internal_raw_execute(sql, raw_connection, perform_do: false)
452
+ result = raw_connection.execute(sql)
453
+ raise TinyTds::Error, "failed to execute statement" if result.is_a?(FalseClass)
460
454
 
461
455
  perform_do ? result.do : result
462
456
  end