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

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 (76) 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/quoting.rb +26 -27
  26. data/lib/arjdbc/mssql/schema_creation.rb +1 -1
  27. data/lib/arjdbc/mssql/schema_definitions.rb +32 -17
  28. data/lib/arjdbc/mssql/schema_dumper.rb +13 -1
  29. data/lib/arjdbc/mssql/schema_statements.rb +61 -36
  30. data/lib/arjdbc/mssql/transaction.rb +2 -2
  31. data/lib/arjdbc/mssql/types/date_and_time_types.rb +6 -6
  32. data/lib/arjdbc/mssql/types/numeric_types.rb +2 -2
  33. data/lib/arjdbc/mssql.rb +1 -1
  34. data/lib/arjdbc/mysql/adapter.rb +2 -1
  35. data/lib/arjdbc/oracle/adapter.rb +4 -23
  36. data/lib/arjdbc/postgresql/adapter.rb +64 -1
  37. data/lib/arjdbc/postgresql/oid_types.rb +68 -47
  38. data/lib/arjdbc/sqlite3/adapter.rb +132 -88
  39. data/lib/arjdbc/tasks/database_tasks.rb +0 -12
  40. data/lib/arjdbc/util/serialized_attributes.rb +0 -22
  41. data/lib/arjdbc/util/table_copier.rb +2 -1
  42. data/lib/arjdbc/version.rb +1 -1
  43. data/rakelib/02-test.rake +3 -18
  44. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +17 -2
  45. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +33 -0
  46. metadata +8 -40
  47. data/lib/active_record/connection_adapters/as400_adapter.rb +0 -2
  48. data/lib/active_record/connection_adapters/db2_adapter.rb +0 -1
  49. data/lib/active_record/connection_adapters/derby_adapter.rb +0 -1
  50. data/lib/active_record/connection_adapters/informix_adapter.rb +0 -1
  51. data/lib/arel/visitors/db2.rb +0 -137
  52. data/lib/arel/visitors/derby.rb +0 -112
  53. data/lib/arel/visitors/firebird.rb +0 -79
  54. data/lib/arjdbc/db2/adapter.rb +0 -808
  55. data/lib/arjdbc/db2/as400.rb +0 -142
  56. data/lib/arjdbc/db2/column.rb +0 -131
  57. data/lib/arjdbc/db2/connection_methods.rb +0 -48
  58. data/lib/arjdbc/db2.rb +0 -4
  59. data/lib/arjdbc/derby/active_record_patch.rb +0 -13
  60. data/lib/arjdbc/derby/adapter.rb +0 -521
  61. data/lib/arjdbc/derby/connection_methods.rb +0 -20
  62. data/lib/arjdbc/derby/schema_creation.rb +0 -15
  63. data/lib/arjdbc/derby.rb +0 -3
  64. data/lib/arjdbc/firebird/adapter.rb +0 -413
  65. data/lib/arjdbc/firebird/connection_methods.rb +0 -23
  66. data/lib/arjdbc/firebird.rb +0 -4
  67. data/lib/arjdbc/informix/adapter.rb +0 -139
  68. data/lib/arjdbc/informix/connection_methods.rb +0 -9
  69. data/lib/arjdbc/sybase/adapter.rb +0 -47
  70. data/lib/arjdbc/sybase.rb +0 -2
  71. data/lib/arjdbc/tasks/db2_database_tasks.rb +0 -104
  72. data/lib/arjdbc/tasks/derby_database_tasks.rb +0 -95
  73. data/src/java/arjdbc/derby/DerbyModule.java +0 -178
  74. data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +0 -152
  75. data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +0 -174
  76. 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,
@@ -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?