activerecord-jdbc-alt-adapter 70.2.0-java → 71.0.0.alpha1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +135 -21
  3. data/.github/workflows/ruby.yml +10 -10
  4. data/.gitignore +1 -0
  5. data/.solargraph.yml +15 -0
  6. data/Gemfile +17 -4
  7. data/README.md +7 -3
  8. data/RUNNING_TESTS.md +36 -0
  9. data/activerecord-jdbc-adapter.gemspec +2 -2
  10. data/activerecord-jdbc-alt-adapter.gemspec +1 -1
  11. data/lib/arjdbc/abstract/connection_management.rb +23 -10
  12. data/lib/arjdbc/abstract/core.rb +5 -6
  13. data/lib/arjdbc/abstract/database_statements.rb +35 -25
  14. data/lib/arjdbc/abstract/statement_cache.rb +1 -6
  15. data/lib/arjdbc/abstract/transaction_support.rb +37 -9
  16. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  17. data/lib/arjdbc/jdbc/column.rb +0 -34
  18. data/lib/arjdbc/jdbc/connection_methods.rb +1 -1
  19. data/lib/arjdbc/mssql/adapter.rb +93 -80
  20. data/lib/arjdbc/mssql/column.rb +1 -0
  21. data/lib/arjdbc/mssql/connection_methods.rb +7 -55
  22. data/lib/arjdbc/mssql/database_statements.rb +182 -71
  23. data/lib/arjdbc/mssql/explain_support.rb +8 -5
  24. data/lib/arjdbc/mssql/schema_creation.rb +1 -1
  25. data/lib/arjdbc/mssql/schema_definitions.rb +10 -0
  26. data/lib/arjdbc/mssql/schema_statements.rb +19 -11
  27. data/lib/arjdbc/mssql/server_version.rb +56 -0
  28. data/lib/arjdbc/mssql/utils.rb +23 -9
  29. data/lib/arjdbc/mysql/adapter.rb +64 -22
  30. data/lib/arjdbc/sqlite3/adapter.rb +218 -135
  31. data/lib/arjdbc/sqlite3/column.rb +103 -0
  32. data/lib/arjdbc/sqlite3/connection_methods.rb +7 -2
  33. data/lib/arjdbc/tasks/mssql_database_tasks.rb +9 -5
  34. data/lib/arjdbc/version.rb +1 -1
  35. data/rakelib/02-test.rake +1 -1
  36. data/rakelib/rails.rake +2 -0
  37. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +4 -2
  38. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +2 -1
  39. metadata +9 -12
  40. data/lib/arel/visitors/sql_server/ng42.rb +0 -294
  41. data/lib/arel/visitors/sql_server.rb +0 -124
  42. data/lib/arjdbc/mssql/limit_helpers.rb +0 -231
  43. data/lib/arjdbc/mssql/lock_methods.rb +0 -77
  44. data/lib/arjdbc/mssql/old_adapter.rb +0 -804
  45. data/lib/arjdbc/mssql/old_column.rb +0 -200
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
  ArJdbc::ConnectionMethods.module_eval do
3
3
  def sqlite3_connection(config)
4
+ raise ArgumentError, 'Configuration must not be empty' if config.blank?
5
+
4
6
  config = config.deep_dup
5
7
  config[:adapter_spec] ||= ::ArJdbc::SQLite3
6
8
  config[:adapter_class] = ActiveRecord::ConnectionAdapters::SQLite3Adapter unless config.key?(:adapter_class)
@@ -18,7 +20,7 @@ ArJdbc::ConnectionMethods.module_eval do
18
20
  parse_sqlite3_config!(config)
19
21
  rescue Errno::ENOENT => error
20
22
  if error.message.include?('No such file or directory')
21
- raise ActiveRecord::NoDatabaseError
23
+ raise ActiveRecord::NoDatabaseError.new(connection_pool: ActiveRecord::ConnectionAdapters::NullPool.new)
22
24
  else
23
25
  raise
24
26
  end
@@ -50,7 +52,10 @@ ArJdbc::ConnectionMethods.module_eval do
50
52
 
51
53
  timeout = config[:timeout]
52
54
  if timeout && timeout.to_s !~ /\A\d+\Z/
53
- raise TypeError.new "Timeout must be nil or a number (got: #{timeout})."
55
+ raise ActiveRecord::StatementInvalid.new(
56
+ "TypeError: Timeout must be nil or a number (got: #{timeout}).",
57
+ connection_pool: ActiveRecord::ConnectionAdapters::NullPool.new
58
+ )
54
59
  end
55
60
 
56
61
  options = config[:properties]
@@ -5,10 +5,6 @@ require 'active_record/tasks/database_tasks'
5
5
  module ArJdbc
6
6
  module Tasks # :nodoc:
7
7
  class MSSQLDatabaseTasks # :nodoc:
8
- delegate :connection, to: ActiveRecord::Base
9
- delegate :establish_connection, to: ActiveRecord::Base
10
- delegate :clear_active_connections!, to: ActiveRecord::Base
11
-
12
8
  def self.using_database_configurations?
13
9
  true
14
10
  end
@@ -45,7 +41,7 @@ module ArJdbc
45
41
  end
46
42
 
47
43
  def purge
48
- clear_active_connections!
44
+ ActiveRecord::Base.connection_handler.clear_active_connections!(:all)
49
45
  drop
50
46
  create
51
47
  end
@@ -70,6 +66,14 @@ module ArJdbc
70
66
 
71
67
  attr_reader :db_config, :configuration_hash
72
68
 
69
+ def connection
70
+ ActiveRecord::Base.connection
71
+ end
72
+
73
+ def establish_connection(config = db_config)
74
+ ActiveRecord::Base.establish_connection(config)
75
+ end
76
+
73
77
  def creation_options
74
78
  {}.tap do |options|
75
79
  options[:collation] = configuration_hash[:collation] if configuration_hash.include?(:collation)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ArJdbc
4
- VERSION = '70.2.0'
4
+ VERSION = '71.0.0.alpha1'
5
5
  end
data/rakelib/02-test.rake CHANGED
@@ -40,7 +40,7 @@ def test_task_for(adapter, options = {})
40
40
  test_task.libs.push *FileList["activerecord-jdbc#{adapter}*/lib"]
41
41
  end
42
42
  test_task.libs << 'test'
43
- test_task.options = '--use-color=t'
43
+ test_task.options = '--use-color=t --progress-style=mark'
44
44
  test_task.verbose = true if $VERBOSE
45
45
  yield(test_task) if block_given?
46
46
  end
data/rakelib/rails.rake CHANGED
@@ -40,6 +40,7 @@ namespace :rails do
40
40
  File.join(root_dir, 'lib'),
41
41
  File.join(root_dir, driver, 'lib'),
42
42
  File.join(root_dir, 'test/rails'),
43
+ File.join(root_dir, 'jdbc-sqlite3', 'lib'), # Added for connection management tests which hardcode sqlite3
43
44
  ar_test_dir
44
45
  ]
45
46
 
@@ -57,6 +58,7 @@ namespace :rails do
57
58
  ruby_opts_string += " -C \"#{ar_path}\""
58
59
  ruby_opts_string += " -rbundler/setup"
59
60
  ruby_opts_string += " -rminitest -rminitest/excludes" unless ENV['NO_EXCLUDES'].eql?('true')
61
+ ruby_opts_string += " -rmonkey_patches"
60
62
  file_list = ENV["TEST"] ? FileList[ ENV["TEST"].split(',') ] : test_files_finder.call
61
63
  file_list_string = file_list.map { |fn| "\"#{fn}\"" }.join(' ')
62
64
  # test_loader_code = "-e \"ARGV.each{|f| require f}\"" # :direct
@@ -793,7 +793,8 @@ public class RubyJdbcConnection extends RubyObject {
793
793
  // Unfortunately the result set gets closed when getMoreResults()
794
794
  // is called, so we have to process the result sets as we get them
795
795
  // this shouldn't be an issue in most cases since we're only getting 1 result set anyways
796
- result = mapExecuteResult(context, connection, resultSet);
796
+ //result = mapExecuteResult(context, connection, resultSet);
797
+ result = mapToRawResult(context, connection, resultSet, false);
797
798
  resultSet.close();
798
799
  } else {
799
800
  result = context.runtime.newFixnum(updateCount);
@@ -2735,8 +2736,9 @@ public class RubyJdbcConnection extends RubyObject {
2735
2736
  statement.setDouble(index, ((RubyNumeric) value).getDoubleValue());
2736
2737
  }
2737
2738
  else { // e.g. `BigDecimal '42.00000000000000000001'`
2739
+ Ruby runtime = context.runtime;
2738
2740
  statement.setBigDecimal(index,
2739
- RubyBigDecimal.newInstance(context, context.runtime.getModule("BigDecimal"), value, RubyFixnum.newFixnum(context.runtime, Integer.MAX_VALUE)).getValue());
2741
+ RubyBigDecimal.newInstance(context, runtime.getModule("BigDecimal"), value, RubyFixnum.zero(runtime)).getValue());
2740
2742
  }
2741
2743
  }
2742
2744
 
@@ -511,7 +511,8 @@ public class SQLite3RubyJdbcConnection extends RubyJdbcConnection {
511
511
  statement.setDouble(index, ((RubyNumeric) value).getDoubleValue());
512
512
  }
513
513
  else { // e.g. `BigDecimal '42.00000000000000000001'`
514
- RubyBigDecimal val = RubyBigDecimal.newInstance(context, context.runtime.getModule("BigDecimal"), value, RubyFixnum.newFixnum(context.runtime, Integer.MAX_VALUE));
514
+ Ruby runtime = context.runtime;
515
+ RubyBigDecimal val = RubyBigDecimal.newInstance(context, runtime.getModule("BigDecimal"), value, RubyFixnum.zero(runtime));
515
516
  statement.setString(index, val.getValue().toString());
516
517
  }
517
518
  }
metadata CHANGED
@@ -1,21 +1,21 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-jdbc-alt-adapter
3
3
  version: !ruby/object:Gem::Version
4
- version: 70.2.0
4
+ version: 71.0.0.alpha1
5
5
  platform: java
6
6
  authors:
7
7
  - Nick Sieger, Ola Bini, Karol Bucek, Jesse Chavez, and JRuby contributors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-02 00:00:00.000000000 Z
11
+ date: 2024-07-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: 7.0.0
18
+ version: 7.1.3
19
19
  name: activerecord
20
20
  type: :runtime
21
21
  prerelease: false
@@ -23,7 +23,7 @@ dependencies:
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 7.0.0
26
+ version: 7.1.3
27
27
  description: 'Fork of the ActiveRecord JDBC adapter with support for SQL Server and
28
28
  Azure SQL, for more information and help look at the README file in the github repository.
29
29
  AR-JDBC is a database adapter for Rails'' ActiveRecord component designed to be
@@ -42,6 +42,7 @@ files:
42
42
  - ".github/workflows/ruby.yml"
43
43
  - ".gitignore"
44
44
  - ".nvimlog"
45
+ - ".solargraph.yml"
45
46
  - ".travis.yml"
46
47
  - ".yardopts"
47
48
  - CONTRIBUTING.md
@@ -72,8 +73,6 @@ files:
72
73
  - lib/arel/visitors/h2.rb
73
74
  - lib/arel/visitors/hsqldb.rb
74
75
  - lib/arel/visitors/postgresql_jdbc.rb
75
- - lib/arel/visitors/sql_server.rb
76
- - lib/arel/visitors/sql_server/ng42.rb
77
76
  - lib/arel/visitors/sqlserver.rb
78
77
  - lib/arjdbc.rb
79
78
  - lib/arjdbc/abstract/connection_management.rb
@@ -118,15 +117,12 @@ files:
118
117
  - lib/arjdbc/mssql/explain_support.rb
119
118
  - lib/arjdbc/mssql/extensions/attribute_methods.rb
120
119
  - lib/arjdbc/mssql/extensions/calculations.rb
121
- - lib/arjdbc/mssql/limit_helpers.rb
122
- - lib/arjdbc/mssql/lock_methods.rb
123
- - lib/arjdbc/mssql/old_adapter.rb
124
- - lib/arjdbc/mssql/old_column.rb
125
120
  - lib/arjdbc/mssql/quoting.rb
126
121
  - lib/arjdbc/mssql/schema_creation.rb
127
122
  - lib/arjdbc/mssql/schema_definitions.rb
128
123
  - lib/arjdbc/mssql/schema_dumper.rb
129
124
  - lib/arjdbc/mssql/schema_statements.rb
125
+ - lib/arjdbc/mssql/server_version.rb
130
126
  - lib/arjdbc/mssql/transaction.rb
131
127
  - lib/arjdbc/mssql/types.rb
132
128
  - lib/arjdbc/mssql/types/binary_types.rb
@@ -152,6 +148,7 @@ files:
152
148
  - lib/arjdbc/railtie.rb
153
149
  - lib/arjdbc/sqlite3.rb
154
150
  - lib/arjdbc/sqlite3/adapter.rb
151
+ - lib/arjdbc/sqlite3/column.rb
155
152
  - lib/arjdbc/sqlite3/connection_methods.rb
156
153
  - lib/arjdbc/tasks.rb
157
154
  - lib/arjdbc/tasks/database_tasks.rb
@@ -231,9 +228,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
231
228
  version: '0'
232
229
  required_rubygems_version: !ruby/object:Gem::Requirement
233
230
  requirements:
234
- - - ">="
231
+ - - ">"
235
232
  - !ruby/object:Gem::Version
236
- version: '0'
233
+ version: 1.3.1
237
234
  requirements: []
238
235
  rubygems_version: 3.3.26
239
236
  signing_key:
@@ -1,294 +0,0 @@
1
- module Arel
2
- module Visitors
3
- class SQLServerNG < SQLServer # Arel::Visitors::ToSql
4
-
5
- OFFSET = " OFFSET "
6
- ROWS = " ROWS"
7
- FETCH = " FETCH NEXT "
8
- FETCH0 = " FETCH FIRST (SELECT 0) "
9
- ROWS_ONLY = " ROWS ONLY"
10
-
11
- private
12
-
13
- # SQLServer ToSql/Visitor (Overides)
14
-
15
- #def visit_Arel_Nodes_BindParam o, collector
16
- # collector.add_bind(o) { |i| "@#{i-1}" }
17
- #end
18
-
19
- def visit_Arel_Nodes_Bin o, collector
20
- visit o.expr, collector
21
- if o.expr.val.is_a? Numeric
22
- collector
23
- else
24
- collector << " #{::ArJdbc::MSSQL.cs_equality_operator} "
25
- end
26
- end
27
-
28
- def visit_Arel_Nodes_UpdateStatement(o, a)
29
- if o.orders.any? && o.limit.nil?
30
- o.limit = Nodes::Limit.new(9_223_372_036_854_775_807)
31
- end
32
- super
33
- end
34
-
35
- def visit_Arel_Nodes_Lock o, collector
36
- o.expr = Arel.sql('WITH(UPDLOCK)') if o.expr.to_s =~ /FOR UPDATE/
37
- collector << SPACE
38
- visit o.expr, collector
39
- end
40
-
41
- def visit_Arel_Nodes_Offset o, collector
42
- collector << OFFSET
43
- visit o.expr, collector
44
- collector << ROWS
45
- end
46
-
47
- def visit_Arel_Nodes_Limit o, collector
48
- if node_value(o) == 0
49
- collector << FETCH0
50
- collector << ROWS_ONLY
51
- else
52
- collector << FETCH
53
- visit o.expr, collector
54
- collector << ROWS_ONLY
55
- end
56
- end
57
-
58
- def visit_Arel_Nodes_SelectStatement o, collector
59
- distinct_One_As_One_Is_So_Not_Fetch o
60
-
61
- set_select_statement_lock o.lock
62
-
63
- if o.with
64
- collector = visit o.with, collector
65
- collector << SPACE
66
- end
67
-
68
- return _visit_Arel_Nodes_SelectStatement(o, collector) if ! o.limit && ! o.offset
69
-
70
- # collector = o.cores.inject(collector) { |c,x|
71
- # visit_Arel_Nodes_SelectCore(x, c)
72
- # }
73
-
74
- unless o.orders.empty?
75
- select_order_by = do_visit_columns o.orders, collector, 'ORDER BY '
76
- end
77
-
78
- select_count = false
79
- collector = o.cores.inject(collector) do |c, x|
80
- unless core_order_by = select_order_by
81
- core_order_by = generate_order_by determine_order_by(o, x)
82
- end
83
-
84
- if select_count? x
85
- x.projections = [ Arel::Nodes::SqlLiteral.new(over_row_num(core_order_by)) ]
86
- select_count = true
87
- else
88
- # NOTE: this should really be added here and we should built the
89
- # wrapping SQL but than #replace_limit_offset! assumes it does that
90
- # ... MS-SQL adapter code seems to be 'hacked' by a lot of people
91
- #x.projections << Arel::Nodes::SqlLiteral.new(over_row_num(select_order_by))
92
- end if core_order_by
93
- visit_Arel_Nodes_SelectCore(x, c)
94
- end
95
- # END collector = o.cores.inject(collector) { |c,x|
96
-
97
- # collector = visit_Orders_And_Let_Fetch_Happen o, collector
98
- # collector = visit_Make_Fetch_Happen o, collector
99
- # collector # __method__ END
100
-
101
- self.class.collector_proxy(collector) do |sql|
102
- select_order_by ||= "ORDER BY #{@connection.determine_order_clause(sql)}"
103
- replace_limit_offset!(sql, limit_for(o.limit), o.offset && o.offset.value.to_i, select_order_by)
104
- sql = "SELECT COUNT(*) AS count_id FROM (#{sql}) AS subquery" if select_count
105
- sql
106
- end
107
-
108
- ensure
109
- set_select_statement_lock nil
110
- end
111
-
112
- def visit_Arel_Nodes_JoinSource o, collector
113
- if o.left
114
- collector = visit o.left, collector
115
- collector = visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector
116
- end
117
- if o.right.any?
118
- collector << " " if o.left
119
- collector = inject_join o.right, collector, ' '
120
- end
121
- collector
122
- end
123
-
124
- def visit_Arel_Nodes_OuterJoin o, collector
125
- collector << "LEFT OUTER JOIN "
126
- collector = visit o.left, collector
127
- collector = visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector, space: true
128
- collector << " "
129
- visit o.right, collector
130
- end
131
-
132
- # SQLServer ToSql/Visitor (Additions)
133
-
134
- def visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector, options = {}
135
- if lock = select_statement_lock
136
- collector = visit lock, collector
137
- collector << SPACE if options[:space]
138
- end
139
- collector
140
- end
141
-
142
- def visit_Orders_And_Let_Fetch_Happen o, collector
143
- make_Fetch_Possible_And_Deterministic o
144
- unless o.orders.empty?
145
- collector << SPACE
146
- collector << ORDER_BY
147
- len = o.orders.length - 1
148
- o.orders.each_with_index { |x, i|
149
- collector = visit(x, collector)
150
- collector << COMMA unless len == i
151
- }
152
- end
153
- collector
154
- end
155
-
156
- def visit_Make_Fetch_Happen o, collector
157
- o.offset = Nodes::Offset.new(0) if o.limit && !o.offset
158
- collector = visit o.offset, collector if o.offset
159
- collector = visit o.limit, collector if o.limit
160
- collector
161
- end
162
-
163
- # SQLServer Helpers
164
-
165
- # attr_reader :select_statement_lock
166
- def select_statement_lock
167
- Thread.current[:'Arel::Visitors::SQLServerNG.select_statement_lock']
168
- end
169
-
170
- def set_select_statement_lock(lock) # @select_statement_lock = lock
171
- Thread.current[:'Arel::Visitors::SQLServerNG.select_statement_lock'] = lock
172
- end
173
-
174
- def make_Fetch_Possible_And_Deterministic o
175
- return if o.limit.nil? && o.offset.nil?
176
- if o.orders.empty? # ORDER BY mandatory with OFFSET FETCH clause
177
- t = table_From_Statement o
178
- pk = primary_Key_From_Table t
179
- return unless pk
180
- # Prefer deterministic vs a simple `(SELECT NULL)` expr.
181
- o.orders = [ pk.asc ]
182
- end
183
- end
184
-
185
- def distinct_One_As_One_Is_So_Not_Fetch o
186
- core = o.cores.first
187
- distinct = Nodes::Distinct === core.set_quantifier
188
- oneasone = core.projections.all? { |x| x == ActiveRecord::FinderMethods::ONE_AS_ONE }
189
- limitone = node_value(o.limit) == 1
190
- if distinct && oneasone && limitone && !o.offset
191
- core.projections = [Arel.sql("TOP(1) 1 AS [one]")]
192
- o.limit = nil
193
- end
194
- end
195
-
196
- def table_From_Statement o
197
- core = o.cores.first
198
- if Arel::Table === core.from
199
- core.from
200
- elsif Arel::Nodes::SqlLiteral === core.from
201
- Arel::Table.new(core.from)
202
- elsif Arel::Nodes::JoinSource === core.source
203
- Arel::Nodes::SqlLiteral === core.source.left ? Arel::Table.new(core.source.left, @engine) : core.source.left
204
- end
205
- end
206
-
207
- def primary_Key_From_Table t
208
- return unless t
209
- return t.primary_key if t.primary_key
210
- if engine_pk = t.engine.primary_key
211
- pk = t.engine.arel_table[engine_pk]
212
- return pk if pk
213
- end
214
- pk = t.engine.connection.schema_cache.primary_keys(t.engine.table_name)
215
- return pk if pk
216
- column_name = t.engine.columns.first.try(:name)
217
- column_name ? t[column_name] : nil
218
- end
219
-
220
- def determine_order_by o, x
221
- if o.orders.any?
222
- o.orders
223
- elsif x.groups.any?
224
- x.groups
225
- else
226
- pk = find_left_table_pk(x)
227
- pk ? [ pk ] : nil # []
228
- end
229
- end
230
-
231
- def generate_order_by orders
232
- do_visit_columns orders, nil, 'ORDER BY '
233
- end
234
-
235
- SQLString = ActiveRecord::ConnectionAdapters::AbstractAdapter::SQLString
236
- # BindCollector = ActiveRecord::ConnectionAdapters::AbstractAdapter::BindCollector
237
-
238
- def self.collector_proxy(collector, &block)
239
- if collector.is_a?(SQLString)
240
- return SQLStringProxy.new(collector, block)
241
- end
242
- BindCollectorProxy.new(collector, block)
243
- end
244
-
245
- class BindCollectorProxy < ActiveRecord::ConnectionAdapters::AbstractAdapter::BindCollector
246
-
247
- def initialize(collector, block); @delegate = collector; @block = block end
248
-
249
- def << str; @delegate << str; self end
250
-
251
- def add_bind bind; @delegate.add_bind bind; self end
252
-
253
- def value; @delegate.value; end
254
-
255
- #def substitute_binds bvs; @delegate.substitute_binds(bvs); self end
256
-
257
- def compile(bvs, conn)
258
- _yield_str @delegate.compile(bvs, conn)
259
- end
260
-
261
- private
262
-
263
- def method_missing(name, *args, &block); @delegate.send(name, args, &block) end
264
-
265
- def _yield_str(str); @block ? @block.call(str) : str end
266
-
267
- end
268
-
269
- class SQLStringProxy < ActiveRecord::ConnectionAdapters::AbstractAdapter::SQLString
270
-
271
- def initialize(collector, block); @delegate = collector; @block = block end
272
-
273
- def << str; @delegate << str; self end
274
-
275
- def add_bind bind; @delegate.add_bind bind; self end
276
-
277
- def compile(bvs, conn)
278
- _yield_str @delegate.compile(bvs, conn)
279
- end
280
-
281
- private
282
-
283
- def method_missing(name, *args, &block); @delegate.send(name, args, &block) end
284
-
285
- def _yield_str(str); @block ? @block.call(str) : str end
286
-
287
- end
288
-
289
- end
290
- end
291
- end
292
-
293
- # FIXME: Arel::Visitors::VISITORS is not defined anymore
294
- # Arel::Visitors::VISITORS['mssql'] = Arel::Visitors::VISITORS['sqlserver'] = Arel::Visitors::SQLServerNG
@@ -1,124 +0,0 @@
1
- require 'arel/visitors/compat'
2
-
3
- module Arel
4
- module Visitors
5
- ToSql.class_eval do
6
- alias_method :_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement
7
- end
8
- # @note AREL set's up `Arel::Visitors::MSSQL` but its not usable as is ...
9
- # @private
10
- class SQLServer < const_defined?(:MSSQL) ? MSSQL : ToSql
11
-
12
- private
13
-
14
- # @private
15
- MAX_LIMIT_VALUE = 9_223_372_036_854_775_807
16
-
17
- def visit_Arel_Nodes_UpdateStatement(*args) # [o] AR <= 4.0 [o, a] on 4.1
18
- o = args.first
19
- if o.orders.any? && o.limit.nil?
20
- o.limit = Nodes::Limit.new(MAX_LIMIT_VALUE)
21
- end
22
- super
23
- end
24
-
25
- def visit_Arel_Nodes_Top o, a = nil
26
- # `top` wouldn't really work here:
27
- # User.select("distinct first_name").limit(10)
28
- # would generate "select top 10 distinct first_name from users",
29
- # which is invalid should be "select distinct top 10 first_name ..."
30
- a || ''
31
- end
32
-
33
- private
34
-
35
- def self.possibly_private_method_defined?(name)
36
- private_method_defined?(name) || method_defined?(name)
37
- end
38
-
39
- def select_count? x
40
- x.projections.length == 1 && Arel::Nodes::Count === x.projections.first
41
- end unless possibly_private_method_defined? :select_count?
42
-
43
- def determine_order_by x, a
44
- unless x.groups.empty?
45
- do_visit_columns x.groups, a, 'ORDER BY '
46
- else
47
- table_pk = find_left_table_pk(x)
48
- table_pk && "ORDER BY #{table_pk}"
49
- end
50
- end
51
-
52
- def find_left_table_pk o
53
- primary_key_from_table table_from_select_core(o)
54
- end
55
-
56
- def do_visit_columns(colls, a, sql)
57
- last = colls.size - 1
58
- colls.each_with_index do |x, i|
59
- sql << do_visit(x, a); sql << ', ' unless i == last
60
- end
61
- sql
62
- end
63
-
64
- def do_visit_columns(colls, a, sql)
65
- prefix = sql
66
- sql = Arel::Collectors::PlainString.new
67
- sql << prefix if prefix
68
-
69
- last = colls.size - 1
70
- colls.each_with_index do |x, i|
71
- visit(x, sql); sql << ', ' unless i == last
72
- end
73
- sql.value
74
- end
75
-
76
- def over_row_num order_by
77
- "ROW_NUMBER() OVER (#{order_by}) as _row_num"
78
- end # unless possibly_private_method_defined? :row_num_literal
79
-
80
- def table_from_select_core core
81
- if Arel::Table === core.from
82
- core.from
83
- elsif Arel::Nodes::SqlLiteral === core.from
84
- Arel::Table.new(core.from, @engine)
85
- elsif Arel::Nodes::JoinSource === core.source
86
- Arel::Nodes::SqlLiteral === core.source.left ? Arel::Table.new(core.source.left, @engine) : core.source.left
87
- end
88
- end
89
-
90
- def primary_key_from_table t
91
- return unless t
92
- return t.primary_key if t.primary_key
93
-
94
- engine = t.engine
95
- if engine_pk = engine.primary_key
96
- pk = engine.arel_table[engine_pk]
97
- return pk if pk
98
- end
99
-
100
- pk = (@primary_keys ||= {}).fetch(table_name = engine.table_name) do
101
- pk_name = @connection.primary_key(table_name)
102
- # some tables might be without primary key
103
- @primary_keys[table_name] = pk_name && t[pk_name]
104
- end
105
- return pk if pk
106
-
107
- column_name = engine.columns.first.try(:name)
108
- column_name && t[column_name]
109
- end
110
-
111
- include ArJdbc::MSSQL::LockMethods
112
-
113
- include ArJdbc::MSSQL::LimitHelpers::SqlServerReplaceLimitOffset
114
-
115
- end
116
-
117
- class SQLServer2000 < SQLServer
118
- include ArJdbc::MSSQL::LimitHelpers::SqlServer2000ReplaceLimitOffset
119
- end
120
-
121
- load 'arel/visitors/sql_server/ng42.rb'
122
-
123
- end
124
- end