activerecord-jdbc-alt-adapter 61.2.0-java → 70.0.0.rc1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +273 -0
  3. data/.gitignore +1 -0
  4. data/.travis.yml +3 -4
  5. data/Gemfile +8 -6
  6. data/README.md +2 -1
  7. data/Rakefile +1 -1
  8. data/activerecord-jdbc-adapter.gemspec +2 -2
  9. data/activerecord-jdbc-alt-adapter.gemspec +2 -2
  10. data/lib/arel/visitors/compat.rb +5 -33
  11. data/lib/arel/visitors/h2.rb +1 -13
  12. data/lib/arel/visitors/hsqldb.rb +1 -21
  13. data/lib/arel/visitors/sql_server.rb +2 -103
  14. data/lib/arjdbc/abstract/core.rb +8 -9
  15. data/lib/arjdbc/abstract/database_statements.rb +4 -4
  16. data/lib/arjdbc/discover.rb +0 -67
  17. data/lib/arjdbc/hsqldb/adapter.rb +2 -2
  18. data/lib/arjdbc/jdbc/adapter.rb +3 -3
  19. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  20. data/lib/arjdbc/jdbc/adapter_require.rb +3 -1
  21. data/lib/arjdbc/jdbc/column.rb +1 -26
  22. data/lib/arjdbc/jdbc/type_cast.rb +2 -2
  23. data/lib/arjdbc/jdbc.rb +0 -7
  24. data/lib/arjdbc/mssql/adapter.rb +134 -105
  25. data/lib/arjdbc/mssql/connection_methods.rb +0 -3
  26. data/lib/arjdbc/mssql/quoting.rb +26 -27
  27. data/lib/arjdbc/mssql/schema_creation.rb +1 -1
  28. data/lib/arjdbc/mssql/schema_definitions.rb +32 -17
  29. data/lib/arjdbc/mssql/schema_dumper.rb +13 -1
  30. data/lib/arjdbc/mssql/schema_statements.rb +61 -36
  31. data/lib/arjdbc/mssql/transaction.rb +2 -2
  32. data/lib/arjdbc/mssql/types/date_and_time_types.rb +6 -6
  33. data/lib/arjdbc/mssql/types/numeric_types.rb +2 -2
  34. data/lib/arjdbc/mssql.rb +1 -1
  35. data/lib/arjdbc/mysql/adapter.rb +2 -1
  36. data/lib/arjdbc/oracle/adapter.rb +4 -23
  37. data/lib/arjdbc/postgresql/adapter.rb +64 -1
  38. data/lib/arjdbc/postgresql/oid_types.rb +68 -47
  39. data/lib/arjdbc/sqlite3/adapter.rb +132 -88
  40. data/lib/arjdbc/tasks/database_tasks.rb +0 -12
  41. data/lib/arjdbc/util/serialized_attributes.rb +0 -22
  42. data/lib/arjdbc/util/table_copier.rb +2 -1
  43. data/lib/arjdbc/version.rb +1 -1
  44. data/rakelib/02-test.rake +3 -18
  45. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +17 -2
  46. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +33 -0
  47. metadata +8 -40
  48. data/lib/active_record/connection_adapters/as400_adapter.rb +0 -2
  49. data/lib/active_record/connection_adapters/db2_adapter.rb +0 -1
  50. data/lib/active_record/connection_adapters/derby_adapter.rb +0 -1
  51. data/lib/active_record/connection_adapters/informix_adapter.rb +0 -1
  52. data/lib/arel/visitors/db2.rb +0 -137
  53. data/lib/arel/visitors/derby.rb +0 -112
  54. data/lib/arel/visitors/firebird.rb +0 -79
  55. data/lib/arjdbc/db2/adapter.rb +0 -808
  56. data/lib/arjdbc/db2/as400.rb +0 -142
  57. data/lib/arjdbc/db2/column.rb +0 -131
  58. data/lib/arjdbc/db2/connection_methods.rb +0 -48
  59. data/lib/arjdbc/db2.rb +0 -4
  60. data/lib/arjdbc/derby/active_record_patch.rb +0 -13
  61. data/lib/arjdbc/derby/adapter.rb +0 -521
  62. data/lib/arjdbc/derby/connection_methods.rb +0 -20
  63. data/lib/arjdbc/derby/schema_creation.rb +0 -15
  64. data/lib/arjdbc/derby.rb +0 -3
  65. data/lib/arjdbc/firebird/adapter.rb +0 -413
  66. data/lib/arjdbc/firebird/connection_methods.rb +0 -23
  67. data/lib/arjdbc/firebird.rb +0 -4
  68. data/lib/arjdbc/informix/adapter.rb +0 -139
  69. data/lib/arjdbc/informix/connection_methods.rb +0 -9
  70. data/lib/arjdbc/sybase/adapter.rb +0 -47
  71. data/lib/arjdbc/sybase.rb +0 -2
  72. data/lib/arjdbc/tasks/db2_database_tasks.rb +0 -104
  73. data/lib/arjdbc/tasks/derby_database_tasks.rb +0 -95
  74. data/src/java/arjdbc/derby/DerbyModule.java +0 -178
  75. data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +0 -152
  76. data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +0 -174
  77. data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +0 -75
@@ -34,7 +34,7 @@ module ArJdbc
34
34
  raw_connection.jdbc_connection(unwrap)
35
35
  end
36
36
 
37
- protected
37
+ private
38
38
 
39
39
  def translate_exception_class(e, sql, binds)
40
40
  message = "#{e.class.name}: #{e.message}"
@@ -42,16 +42,19 @@ module ArJdbc
42
42
  exception = translate_exception(
43
43
  e, message: message, sql: sql, binds: binds
44
44
  )
45
- exception.set_backtrace e.backtrace
45
+ exception.set_backtrace e.backtrace unless exception.equal?(e)
46
46
  exception
47
47
  end
48
48
 
49
+ Throwable = java.lang.Throwable
50
+ private_constant :Throwable
51
+
49
52
  def translate_exception(exception, message:, sql:, binds:)
50
53
  # override in derived class
51
54
 
52
55
  # we shall not translate native "Java" exceptions as they might
53
56
  # swallow an ArJdbc / driver bug into an AR::StatementInvalid !
54
- return exception if exception.is_a?(Java::JavaLang::Throwable)
57
+ return exception if exception.is_a?(Throwable)
55
58
 
56
59
  case exception
57
60
  when SystemExit, SignalException, NoMemoryError then exception
@@ -61,14 +64,10 @@ module ArJdbc
61
64
  end
62
65
  end
63
66
 
64
- def extract_raw_bind_values(binds)
65
- binds.map(&:value_for_database)
66
- end
67
-
68
67
  # this version of log() automatically fills type_casted_binds from binds if necessary
69
- def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil)
68
+ def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil, async: false)
70
69
  if binds.any? && (type_casted_binds.nil? || type_casted_binds.empty?)
71
- type_casted_binds = ->{ extract_raw_bind_values(binds) }
70
+ type_casted_binds = ->{ binds.map(&:value_for_database) } # extract_raw_bind_values
72
71
  end
73
72
  super
74
73
  end
@@ -30,7 +30,7 @@ module ArJdbc
30
30
 
31
31
  # It appears that at this point (AR 5.0) "prepare" should only ever be true
32
32
  # if prepared statements are enabled
33
- def exec_query(sql, name = nil, binds = NO_BINDS, prepare: false)
33
+ def exec_query(sql, name = nil, binds = NO_BINDS, prepare: false, async: false)
34
34
  if preventing_writes? && write_query?(sql)
35
35
  raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
36
36
  end
@@ -69,7 +69,7 @@ module ArJdbc
69
69
  end
70
70
  alias :exec_delete :exec_update
71
71
 
72
- def execute(sql, name = nil)
72
+ def execute(sql, name = nil, async: false)
73
73
  if preventing_writes? && write_query?(sql)
74
74
  raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
75
75
  end
@@ -77,11 +77,11 @@ module ArJdbc
77
77
  materialize_transactions
78
78
  mark_transaction_written_if_write(sql)
79
79
 
80
- log(sql, name) { @connection.execute(sql) }
80
+ log(sql, name, async: async) { @connection.execute(sql) }
81
81
  end
82
82
 
83
83
  # overridden to support legacy binds
84
- def select_all(arel, name = nil, binds = NO_BINDS, preparable: nil)
84
+ def select_all(arel, name = nil, binds = NO_BINDS, preparable: nil, async: false)
85
85
  binds = convert_legacy_binds_to_attributes(binds) if binds.first.is_a?(Array)
86
86
  super
87
87
  end
@@ -23,26 +23,6 @@ module ArJdbc
23
23
  require('arjdbc/sqlite3') || true if name =~ /sqlite/i
24
24
  end
25
25
 
26
- # Other supported adapters :
27
-
28
- extension :Derby do |name, config|
29
- if name =~ /derby/i
30
- require 'arjdbc/derby'
31
-
32
- if config && config[:username].nil? # set the database schema name (:username) :
33
- begin
34
- ArJdbc.with_meta_data_from_data_source_if_any(config) do
35
- |meta_data| config[:username] = meta_data.getUserName
36
- end
37
- rescue => e
38
- ArJdbc.warn("failed to set :username from (Derby) database meda-data: #{e.inspect}")
39
- end
40
- end
41
-
42
- true
43
- end
44
- end
45
-
46
26
  extension :H2 do |name|
47
27
  require('arjdbc/h2') || true if name =~ /\.h2\./i
48
28
  end
@@ -54,51 +34,4 @@ module ArJdbc
54
34
  extension :MSSQL do |name|
55
35
  require('arjdbc/mssql') || true if name =~ /sqlserver|tds|Microsoft SQL/i
56
36
  end
57
-
58
- extension :DB2 do |name, config|
59
- if name =~ /db2/i && name !~ /as\/?400/i && config[:url] !~ /^jdbc:derby:net:/
60
- require 'arjdbc/db2'
61
- true
62
- end
63
- end
64
-
65
- extension :AS400 do |name, config|
66
- # The native JDBC driver always returns "DB2 UDB for AS/400"
67
- if name =~ /as\/?400/i
68
- require 'arjdbc/db2'
69
- require 'arjdbc/db2/as400'
70
- true
71
- end
72
- end
73
-
74
- # NOTE: following ones are likely getting deprecated :
75
-
76
- extension :FireBird do |name|
77
- if name =~ /firebird/i
78
- require 'arjdbc/firebird'
79
- true
80
- end
81
- end
82
-
83
- extension :Sybase do |name|
84
- if name =~ /sybase|tds/i
85
- require 'arjdbc/sybase'
86
- true
87
- end
88
- end
89
-
90
- extension :Informix do |name|
91
- if name =~ /informix/i
92
- require 'arjdbc/informix'
93
- true
94
- end
95
- end
96
-
97
- extension :Mimer do |name|
98
- if name =~ /mimer/i
99
- require 'arjdbc/mimer'
100
- true
101
- end
102
- end
103
-
104
37
  end
@@ -111,7 +111,7 @@ module ArJdbc
111
111
  if column_type == :time
112
112
  "'#{value.strftime("%H:%M:%S")}'"
113
113
  #elsif column_type == :timestamp # || column_type == :datetime
114
- #value = ::ActiveRecord::Base.default_timezone == :utc ? value.getutc : value.getlocal
114
+ #value = ::ActiveRecord.default_timezone == :utc ? value.getutc : value.getlocal
115
115
  #"'#{value.strftime("%Y-%m-%d %H:%M:%S")}.#{sprintf("%06d", value.usec)}'"
116
116
  else
117
117
  super
@@ -127,7 +127,7 @@ module ArJdbc
127
127
  def quoted_date(value)
128
128
  if value.acts_like?(:time) && value.respond_to?(:usec)
129
129
  usec = sprintf("%06d", value.usec)
130
- value = ::ActiveRecord::Base.default_timezone == :utc ? value.getutc : value.getlocal
130
+ value = ::ActiveRecord.default_timezone == :utc ? value.getutc : value.getlocal
131
131
  "#{value.strftime("%Y-%m-%d %H:%M:%S")}.#{usec}"
132
132
  else
133
133
  super
@@ -431,12 +431,12 @@ module ActiveRecord
431
431
  private
432
432
 
433
433
  # Helper useful during {#quote} since AREL might pass in it's literals
434
- # to be quoted, fixed since AREL 4.0.0.beta1 : http://git.io/7gyTig
434
+ # to be quoted, fixed since AREL 4.0.0.beta1 : https://github.com/rails/arel/commit/9c514f3
435
435
  def sql_literal?(value); ::Arel::Nodes::SqlLiteral === value; end
436
436
 
437
- # Helper to get local/UTC time (based on `ActiveRecord::Base.default_timezone`).
437
+ # Helper to get local/UTC time (based on `ActiveRecord::default_timezone`).
438
438
  def get_time(value)
439
- get = ::ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
439
+ get = ::ActiveRecord.default_timezone == :utc ? :getutc : :getlocal
440
440
  value.respond_to?(get) ? value.send(get) : value
441
441
  end
442
442
 
Binary file
@@ -2,7 +2,9 @@
2
2
 
3
3
  module ActiveRecord
4
4
 
5
- if defined? ConnectionAdapters::ConnectionSpecification::Resolver # 4.0
5
+ if defined? ConnectionAdapters::ConnectionHandler # 6.1
6
+ ConnectionAdapters::ConnectionHandler
7
+ elsif defined? ConnectionAdapters::ConnectionSpecification::Resolver # 4.0, # 5.x, # 6.0
6
8
  ConnectionAdapters::ConnectionSpecification::Resolver
7
9
  elsif defined? Base::ConnectionSpecification::Resolver # 3.2
8
10
  Base::ConnectionSpecification::Resolver
@@ -28,21 +28,6 @@ module ActiveRecord
28
28
  end
29
29
  end
30
30
 
31
- if ArJdbc::AR52
32
- # undefined method `cast' for #<ActiveRecord::ConnectionAdapters::SqlTypeMetadata> on AR52
33
- else
34
- default = args[0].cast(default)
35
-
36
- sql_type = args.delete_at(1)
37
- type = args.delete_at(0)
38
-
39
- args.unshift(SqlTypeMetadata.new(:sql_type => sql_type, :type => type))
40
- end
41
-
42
- # super <= 4.1: (name, default, sql_type = nil, null = true)
43
- # super >= 4.2: (name, default, cast_type, sql_type = nil, null = true)
44
- # super >= 5.0: (name, default, sql_type_metadata = nil, null = true)
45
-
46
31
  super(name, default, *args)
47
32
  init_column(name, default, *args)
48
33
  end
@@ -80,18 +65,8 @@ module ActiveRecord
80
65
  end
81
66
 
82
67
  class << self
83
-
84
- include Jdbc::TypeCast if ::ActiveRecord::VERSION::STRING >= '4.2'
85
-
86
- if ActiveRecord::VERSION::MAJOR > 3 && ActiveRecord::VERSION::STRING < '4.2'
87
-
88
- # @private provides compatibility between AR 3.x/4.0 API
89
- def string_to_date(value); value_to_date(value) end
90
-
91
- end
92
-
68
+ include Jdbc::TypeCast
93
69
  end
94
-
95
70
  end
96
71
  end
97
72
  end
@@ -130,9 +130,9 @@ module ActiveRecord::ConnectionAdapters
130
130
  return nil unless time
131
131
 
132
132
  time -= offset
133
- ActiveRecord::Base.default_timezone == :utc ? time : time.getlocal
133
+ ActiveRecord.default_timezone == :utc ? time : time.getlocal
134
134
  else
135
- timezone = ActiveRecord::Base.default_timezone
135
+ timezone = ActiveRecord.default_timezone
136
136
  Time.public_send(timezone, year, mon, mday, hour, min, sec, microsec) rescue nil
137
137
  end
138
138
  end
data/lib/arjdbc/jdbc.rb CHANGED
@@ -1,13 +1,6 @@
1
1
  require 'active_support/deprecation'
2
2
 
3
3
  module ArJdbc
4
-
5
- # @private
6
- AR42 = ::ActiveRecord::VERSION::STRING >= '4.2'
7
-
8
- # @private
9
- AR52 = ::ActiveRecord::VERSION::STRING >= '5.2'
10
-
11
4
  class << self
12
5
 
13
6
  # @private Internal API
@@ -143,13 +143,32 @@ module ActiveRecord
143
143
  def supports_insert_on_conflict?
144
144
  false
145
145
  end
146
+
146
147
  alias supports_insert_on_duplicate_skip? supports_insert_on_conflict?
147
148
  alias supports_insert_on_duplicate_update? supports_insert_on_conflict?
148
149
  alias supports_insert_conflict_target? supports_insert_on_conflict?
149
150
 
151
+ def supports_insert_returning?
152
+ true
153
+ end
154
+
150
155
  def build_insert_sql(insert) # :nodoc:
151
156
  # TODO: hope we can implement an upsert like feature
152
- "INSERT #{insert.into} #{insert.values_list}"
157
+ # "INSERT #{insert.into} #{insert.values_list}"
158
+ sql = +"INSERT #{insert.into}"
159
+
160
+ if returning = insert.send(:insert_all).returning
161
+ returning_sql = if returning.is_a?(String)
162
+ returning
163
+ else
164
+ returning.map { |column| "INSERTED.#{quote_column_name(column)}" }.join(', ')
165
+ end
166
+
167
+ sql << " OUTPUT #{returning_sql}"
168
+ end
169
+
170
+ sql << " #{insert.values_list}"
171
+ sql
153
172
  end
154
173
 
155
174
  # Overrides abstract method which always returns false
@@ -158,7 +177,7 @@ module ActiveRecord
158
177
  end
159
178
 
160
179
  def clear_cache!
161
- reload_type_map
180
+ # reload_type_map
162
181
  super
163
182
  end
164
183
 
@@ -309,8 +328,121 @@ module ActiveRecord
309
328
  end
310
329
  end
311
330
 
331
+ class << self
332
+ private
333
+
334
+ # This method is called indirectly by the abstract method
335
+ # 'fetch_type_metadata' which then it is called by the java part when
336
+ # calculating a table's columns.
337
+ def initialize_type_map(map)
338
+ # Build the type mapping from SQL Server to ActiveRecord
339
+
340
+ # Integer types.
341
+ map.register_type 'int', MSSQL::Type::Integer.new(limit: 4)
342
+ map.register_type 'tinyint', MSSQL::Type::TinyInteger.new(limit: 1)
343
+ map.register_type 'smallint', MSSQL::Type::SmallInteger.new(limit: 2)
344
+ map.register_type 'bigint', MSSQL::Type::BigInteger.new(limit: 8)
345
+
346
+ # Exact Numeric types.
347
+ map.register_type %r{\Adecimal}i do |sql_type|
348
+ scale = extract_scale(sql_type)
349
+ precision = extract_precision(sql_type)
350
+ if scale == 0
351
+ MSSQL::Type::DecimalWithoutScale.new(precision: precision)
352
+ else
353
+ MSSQL::Type::Decimal.new(precision: precision, scale: scale)
354
+ end
355
+ end
356
+ map.register_type %r{\Amoney\z}i, MSSQL::Type::Money.new
357
+ map.register_type %r{\Asmallmoney\z}i, MSSQL::Type::SmallMoney.new
358
+
359
+ # Approximate Numeric types.
360
+ map.register_type %r{\Afloat\z}i, MSSQL::Type::Float.new
361
+ map.register_type %r{\Areal\z}i, MSSQL::Type::Real.new
362
+
363
+ # Character strings CHAR and VARCHAR (it can become Unicode UTF-8)
364
+ map.register_type 'varchar(max)', MSSQL::Type::VarcharMax.new
365
+ map.register_type %r{\Avarchar\(\d+\)} do |sql_type|
366
+ limit = extract_limit(sql_type)
367
+ MSSQL::Type::Varchar.new(limit: limit)
368
+ end
369
+ map.register_type %r{\Achar\(\d+\)} do |sql_type|
370
+ limit = extract_limit(sql_type)
371
+ MSSQL::Type::Char.new(limit: limit)
372
+ end
373
+
374
+ # Character strings NCHAR and NVARCHAR (by default Unicode UTF-16)
375
+ map.register_type %r{\Anvarchar\(\d+\)} do |sql_type|
376
+ limit = extract_limit(sql_type)
377
+ MSSQL::Type::Nvarchar.new(limit: limit)
378
+ end
379
+ map.register_type %r{\Anchar\(\d+\)} do |sql_type|
380
+ limit = extract_limit(sql_type)
381
+ MSSQL::Type::Nchar.new(limit: limit)
382
+ end
383
+ map.register_type 'nvarchar(max)', MSSQL::Type::NvarcharMax.new
384
+ map.register_type 'nvarchar(4000)', MSSQL::Type::Nvarchar.new
385
+
386
+ # Binary data types.
387
+ map.register_type 'varbinary(max)', MSSQL::Type::VarbinaryMax.new
388
+ register_class_with_limit map, %r{\Abinary\(\d+\)}, MSSQL::Type::BinaryBasic
389
+ register_class_with_limit map, %r{\Avarbinary\(\d+\)}, MSSQL::Type::Varbinary
390
+
391
+ # Miscellaneous types, Boolean, XML, UUID
392
+ # FIXME The xml data needs to be reviewed and fixed
393
+ map.register_type 'bit', MSSQL::Type::Boolean.new
394
+ map.register_type %r{\Auniqueidentifier\z}i, MSSQL::Type::UUID.new
395
+ map.register_type %r{\Axml\z}i, MSSQL::Type::XML.new
396
+
397
+ # Date and time types
398
+ map.register_type 'date', MSSQL::Type::Date.new
399
+ map.register_type 'datetime', MSSQL::Type::DateTime.new
400
+ map.register_type 'smalldatetime', MSSQL::Type::SmallDateTime.new
401
+ register_class_with_precision map, %r{\Atime\(\d+\)}i, MSSQL::Type::Time
402
+ map.register_type 'time(7)', MSSQL::Type::Time.new
403
+ register_class_with_precision map, %r{\Adatetime2\(\d+\)}i, MSSQL::Type::DateTime2
404
+ # map.register_type 'datetime2(7)', MSSQL::Type::DateTime2.new
405
+
406
+ # TODO: we should have identity separated from the sql_type
407
+ # let's say in another attribute (this will help to pass more AR tests),
408
+ # also we add collation attribute per column.
409
+ # aliases
410
+ map.alias_type 'int identity', 'int'
411
+ map.alias_type 'bigint identity', 'bigint'
412
+ map.alias_type 'integer', 'int'
413
+ map.alias_type 'integer', 'int'
414
+ map.alias_type 'INTEGER', 'int'
415
+ map.alias_type 'TINYINT', 'tinyint'
416
+ map.alias_type 'SMALLINT', 'smallint'
417
+ map.alias_type 'BIGINT', 'bigint'
418
+ map.alias_type %r{\Anumeric}i, 'decimal'
419
+ map.alias_type %r{\Anumber}i, 'decimal'
420
+ map.alias_type %r{\Adouble\z}i, 'float'
421
+ map.alias_type 'string', 'nvarchar(4000)'
422
+ map.alias_type %r{\Aboolean\z}i, 'bit'
423
+ map.alias_type 'DATE', 'date'
424
+ map.alias_type 'DATETIME', 'datetime'
425
+ map.alias_type 'SMALLDATETIME', 'smalldatetime'
426
+ map.alias_type %r{\Atime\z}i, 'time(7)'
427
+ map.alias_type %r{\Abinary\z}i, 'varbinary(max)'
428
+ map.alias_type %r{\Ablob\z}i, 'varbinary(max)'
429
+ map.alias_type %r{\Adatetime2\z}i, 'datetime2(7)'
430
+
431
+ # Deprecated SQL Server types.
432
+ map.register_type 'text', MSSQL::Type::Text.new
433
+ map.register_type 'ntext', MSSQL::Type::Ntext.new
434
+ map.register_type 'image', MSSQL::Type::Image.new
435
+ end
436
+ end
437
+
438
+ TYPE_MAP = Type::TypeMap.new.tap { |m| initialize_type_map(m) }
439
+
312
440
  private
313
441
 
442
+ def type_map
443
+ TYPE_MAP
444
+ end
445
+
314
446
  def translate_exception(exception, message:, sql:, binds:)
315
447
  case message
316
448
  when /no connection available/i
@@ -334,109 +466,6 @@ module ActiveRecord
334
466
  end
335
467
  end
336
468
 
337
- # This method is called indirectly by the abstract method
338
- # 'fetch_type_metadata' which then it is called by the java part when
339
- # calculating a table's columns.
340
- def initialize_type_map(map = type_map)
341
- # Build the type mapping from SQL Server to ActiveRecord
342
-
343
- # Integer types.
344
- map.register_type 'int', MSSQL::Type::Integer.new(limit: 4)
345
- map.register_type 'tinyint', MSSQL::Type::TinyInteger.new(limit: 1)
346
- map.register_type 'smallint', MSSQL::Type::SmallInteger.new(limit: 2)
347
- map.register_type 'bigint', MSSQL::Type::BigInteger.new(limit: 8)
348
-
349
- # Exact Numeric types.
350
- map.register_type %r{\Adecimal}i do |sql_type|
351
- scale = extract_scale(sql_type)
352
- precision = extract_precision(sql_type)
353
- if scale == 0
354
- MSSQL::Type::DecimalWithoutScale.new(precision: precision)
355
- else
356
- MSSQL::Type::Decimal.new(precision: precision, scale: scale)
357
- end
358
- end
359
- map.register_type %r{\Amoney\z}i, MSSQL::Type::Money.new
360
- map.register_type %r{\Asmallmoney\z}i, MSSQL::Type::SmallMoney.new
361
-
362
- # Approximate Numeric types.
363
- map.register_type %r{\Afloat\z}i, MSSQL::Type::Float.new
364
- map.register_type %r{\Areal\z}i, MSSQL::Type::Real.new
365
-
366
- # Character strings CHAR and VARCHAR (it can become Unicode UTF-8)
367
- map.register_type 'varchar(max)', MSSQL::Type::VarcharMax.new
368
- map.register_type %r{\Avarchar\(\d+\)} do |sql_type|
369
- limit = extract_limit(sql_type)
370
- MSSQL::Type::Varchar.new(limit: limit)
371
- end
372
- map.register_type %r{\Achar\(\d+\)} do |sql_type|
373
- limit = extract_limit(sql_type)
374
- MSSQL::Type::Char.new(limit: limit)
375
- end
376
-
377
- # Character strings NCHAR and NVARCHAR (by default Unicode UTF-16)
378
- map.register_type %r{\Anvarchar\(\d+\)} do |sql_type|
379
- limit = extract_limit(sql_type)
380
- MSSQL::Type::Nvarchar.new(limit: limit)
381
- end
382
- map.register_type %r{\Anchar\(\d+\)} do |sql_type|
383
- limit = extract_limit(sql_type)
384
- MSSQL::Type::Nchar.new(limit: limit)
385
- end
386
- map.register_type 'nvarchar(max)', MSSQL::Type::NvarcharMax.new
387
- map.register_type 'nvarchar(4000)', MSSQL::Type::Nvarchar.new
388
-
389
- # Binary data types.
390
- map.register_type 'varbinary(max)', MSSQL::Type::VarbinaryMax.new
391
- register_class_with_limit map, %r{\Abinary\(\d+\)}, MSSQL::Type::BinaryBasic
392
- register_class_with_limit map, %r{\Avarbinary\(\d+\)}, MSSQL::Type::Varbinary
393
-
394
- # Miscellaneous types, Boolean, XML, UUID
395
- # FIXME The xml data needs to be reviewed and fixed
396
- map.register_type 'bit', MSSQL::Type::Boolean.new
397
- map.register_type %r{\Auniqueidentifier\z}i, MSSQL::Type::UUID.new
398
- map.register_type %r{\Axml\z}i, MSSQL::Type::XML.new
399
-
400
- # Date and time types
401
- map.register_type 'date', MSSQL::Type::Date.new
402
- map.register_type 'datetime', MSSQL::Type::DateTime.new
403
- map.register_type 'smalldatetime', MSSQL::Type::SmallDateTime.new
404
- register_class_with_precision map, %r{\Atime\(\d+\)}i, MSSQL::Type::Time
405
- map.register_type 'time(7)', MSSQL::Type::Time.new
406
- register_class_with_precision map, %r{\Adatetime2\(\d+\)}i, MSSQL::Type::DateTime2
407
- map.register_type 'datetime2(7)', MSSQL::Type::DateTime2.new
408
-
409
- # TODO: we should have identity separated from the sql_type
410
- # let's say in another attribute (this will help to pass more AR tests),
411
- # also we add collation attribute per column.
412
- # aliases
413
- map.alias_type 'int identity', 'int'
414
- map.alias_type 'bigint identity', 'bigint'
415
- map.alias_type 'integer', 'int'
416
- map.alias_type 'integer', 'int'
417
- map.alias_type 'INTEGER', 'int'
418
- map.alias_type 'TINYINT', 'tinyint'
419
- map.alias_type 'SMALLINT', 'smallint'
420
- map.alias_type 'BIGINT', 'bigint'
421
- map.alias_type %r{\Anumeric}i, 'decimal'
422
- map.alias_type %r{\Anumber}i, 'decimal'
423
- map.alias_type %r{\Adouble\z}i, 'float'
424
- map.alias_type 'string', 'nvarchar(4000)'
425
- map.alias_type %r{\Aboolean\z}i, 'bit'
426
- map.alias_type 'DATE', 'date'
427
- map.alias_type 'DATETIME', 'datetime'
428
- map.alias_type 'SMALLDATETIME', 'smalldatetime'
429
- map.alias_type %r{\Atime\z}i, 'time(7)'
430
- map.alias_type %r{\Abinary\z}i, 'varbinary(max)'
431
- map.alias_type %r{\Ablob\z}i, 'varbinary(max)'
432
- map.alias_type %r{\Adatetime2\z}i, 'datetime2(7)'
433
-
434
- # Deprecated SQL Server types.
435
- map.register_type 'text', MSSQL::Type::Text.new
436
- map.register_type 'ntext', MSSQL::Type::Ntext.new
437
- map.register_type 'image', MSSQL::Type::Image.new
438
- end
439
-
440
469
  # Returns an array of Column objects for the table specified by +table_name+.
441
470
  # See the concrete implementation for details on the expected parameter values.
442
471
  # NOTE: This is ready, all implemented in the java part of adapter,
@@ -78,15 +78,12 @@ ArJdbc::ConnectionMethods.module_eval do
78
78
  url << "sendTimeAsDatetime=#{config[:send_time_as_datetime] || false};"
79
79
  url << "loginTimeout=#{config[:login_timeout].to_i};" if config[:login_timeout]
80
80
  url << "lockTimeout=#{config[:lock_timeout].to_i};"
81
- url << "encrypt=#{config[:encrypt]};" if config.key?(:encrypt)
82
- url << "trustServerCertificate=#{config[:trust_server_certificate]};" if config.key?(:trust_server_certificate)
83
81
  app = config[:appname] || config[:application]
84
82
  url << "applicationName=#{app};" if app
85
83
  isc = config[:integrated_security] # Win only - needs sqljdbc_auth.dll
86
84
  url << "integratedSecurity=#{isc};" unless isc.nil?
87
85
  url
88
86
  end
89
-
90
87
  jdbc_connection(config)
91
88
  end
92
89
  alias_method :jdbcsqlserver_connection, :sqlserver_connection
@@ -4,8 +4,30 @@ module ActiveRecord
4
4
  module ConnectionAdapters
5
5
  module MSSQL
6
6
  module Quoting
7
- QUOTED_TRUE = '1'.freeze
8
- QUOTED_FALSE = '0'.freeze
7
+ QUOTED_TRUE = '1'
8
+ QUOTED_FALSE = '0'
9
+
10
+ def quote(value)
11
+ # FIXME: this needs improvements to handle other custom types.
12
+ # Also check if it's possible insert integer into a NVARCHAR
13
+ case value
14
+ when ActiveRecord::Type::Binary::Data
15
+ "0x#{value.hex}"
16
+ # when SomeOtherBinaryData then BLOB_VALUE_MARKER
17
+ # when SomeOtherData then "yyy"
18
+ when String, ActiveSupport::Multibyte::Chars
19
+ "N'#{quote_string(value)}'"
20
+ # when OnlyTimeType then "'#{quoted_time(value)}'"
21
+ when Date, Time
22
+ "'#{quoted_date(value)}'"
23
+ when TrueClass
24
+ quoted_true
25
+ when FalseClass
26
+ quoted_false
27
+ else
28
+ super
29
+ end
30
+ end
9
31
 
10
32
  # Quote date/time values for use in SQL input, includes microseconds
11
33
  # with three digits only if the value is a Time responding to usec.
@@ -15,7 +37,7 @@ module ActiveRecord
15
37
  value = time_with_db_timezone(value)
16
38
  end
17
39
 
18
- result = value.to_s(:db)
40
+ result = value.to_fs(:db)
19
41
 
20
42
  if value.respond_to?(:usec) && value.usec > 0
21
43
  "#{result}.#{sprintf("%06d", value.usec)}"
@@ -105,7 +127,7 @@ module ActiveRecord
105
127
  private
106
128
 
107
129
  def time_with_db_timezone(value)
108
- zone_conv_method = if ActiveRecord::Base.default_timezone == :utc
130
+ zone_conv_method = if ActiveRecord.default_timezone == :utc
109
131
  :getutc
110
132
  else
111
133
  :getlocal
@@ -117,29 +139,6 @@ module ActiveRecord
117
139
  value
118
140
  end
119
141
  end
120
-
121
- # @override
122
- # FIXME: it need to be improved to handle other custom types.
123
- # Also check if it's possible insert integer into a NVARCHAR
124
- def _quote(value)
125
- case value
126
- when ActiveRecord::Type::Binary::Data
127
- "0x#{value.hex}"
128
- # when SomeOtherBinaryData then BLOB_VALUE_MARKER
129
- # when SomeOtherData then "yyy"
130
- when String, ActiveSupport::Multibyte::Chars
131
- "N'#{quote_string(value)}'"
132
- # when OnlyTimeType then "'#{quoted_time(value)}'"
133
- when Date, Time
134
- "'#{quoted_date(value)}'"
135
- when TrueClass
136
- quoted_true
137
- when FalseClass
138
- quoted_false
139
- else
140
- super
141
- end
142
- end
143
142
  end
144
143
  end
145
144
  end
@@ -29,7 +29,7 @@ module ActiveRecord
29
29
  end
30
30
 
31
31
  if supports_foreign_keys?
32
- statements.concat(o.foreign_keys.map { |to_table, options| foreign_key_in_create(o.name, to_table, options) })
32
+ statements.concat(o.foreign_keys.map { |fk| accept fk })
33
33
  end
34
34
 
35
35
  create_sql << "(#{statements.join(', ')})" if statements.present?