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.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +273 -0
- data/.gitignore +1 -0
- data/.travis.yml +3 -4
- data/Gemfile +8 -6
- data/README.md +2 -1
- data/Rakefile +1 -1
- data/activerecord-jdbc-adapter.gemspec +2 -2
- data/activerecord-jdbc-alt-adapter.gemspec +2 -2
- data/lib/arel/visitors/compat.rb +5 -33
- data/lib/arel/visitors/h2.rb +1 -13
- data/lib/arel/visitors/hsqldb.rb +1 -21
- data/lib/arel/visitors/sql_server.rb +2 -103
- data/lib/arjdbc/abstract/core.rb +8 -9
- data/lib/arjdbc/abstract/database_statements.rb +4 -4
- data/lib/arjdbc/discover.rb +0 -67
- data/lib/arjdbc/hsqldb/adapter.rb +2 -2
- data/lib/arjdbc/jdbc/adapter.rb +3 -3
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/jdbc/adapter_require.rb +3 -1
- data/lib/arjdbc/jdbc/column.rb +1 -26
- data/lib/arjdbc/jdbc/type_cast.rb +2 -2
- data/lib/arjdbc/jdbc.rb +0 -7
- data/lib/arjdbc/mssql/adapter.rb +134 -105
- data/lib/arjdbc/mssql/quoting.rb +26 -27
- data/lib/arjdbc/mssql/schema_creation.rb +1 -1
- data/lib/arjdbc/mssql/schema_definitions.rb +32 -17
- data/lib/arjdbc/mssql/schema_dumper.rb +13 -1
- data/lib/arjdbc/mssql/schema_statements.rb +61 -36
- data/lib/arjdbc/mssql/transaction.rb +2 -2
- data/lib/arjdbc/mssql/types/date_and_time_types.rb +6 -6
- data/lib/arjdbc/mssql/types/numeric_types.rb +2 -2
- data/lib/arjdbc/mssql.rb +1 -1
- data/lib/arjdbc/mysql/adapter.rb +2 -1
- data/lib/arjdbc/oracle/adapter.rb +4 -23
- data/lib/arjdbc/postgresql/adapter.rb +64 -1
- data/lib/arjdbc/postgresql/oid_types.rb +68 -47
- data/lib/arjdbc/sqlite3/adapter.rb +132 -88
- data/lib/arjdbc/tasks/database_tasks.rb +0 -12
- data/lib/arjdbc/util/serialized_attributes.rb +0 -22
- data/lib/arjdbc/util/table_copier.rb +2 -1
- data/lib/arjdbc/version.rb +1 -1
- data/rakelib/02-test.rake +3 -18
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +17 -2
- data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +33 -0
- metadata +8 -40
- data/lib/active_record/connection_adapters/as400_adapter.rb +0 -2
- data/lib/active_record/connection_adapters/db2_adapter.rb +0 -1
- data/lib/active_record/connection_adapters/derby_adapter.rb +0 -1
- data/lib/active_record/connection_adapters/informix_adapter.rb +0 -1
- data/lib/arel/visitors/db2.rb +0 -137
- data/lib/arel/visitors/derby.rb +0 -112
- data/lib/arel/visitors/firebird.rb +0 -79
- data/lib/arjdbc/db2/adapter.rb +0 -808
- data/lib/arjdbc/db2/as400.rb +0 -142
- data/lib/arjdbc/db2/column.rb +0 -131
- data/lib/arjdbc/db2/connection_methods.rb +0 -48
- data/lib/arjdbc/db2.rb +0 -4
- data/lib/arjdbc/derby/active_record_patch.rb +0 -13
- data/lib/arjdbc/derby/adapter.rb +0 -521
- data/lib/arjdbc/derby/connection_methods.rb +0 -20
- data/lib/arjdbc/derby/schema_creation.rb +0 -15
- data/lib/arjdbc/derby.rb +0 -3
- data/lib/arjdbc/firebird/adapter.rb +0 -413
- data/lib/arjdbc/firebird/connection_methods.rb +0 -23
- data/lib/arjdbc/firebird.rb +0 -4
- data/lib/arjdbc/informix/adapter.rb +0 -139
- data/lib/arjdbc/informix/connection_methods.rb +0 -9
- data/lib/arjdbc/sybase/adapter.rb +0 -47
- data/lib/arjdbc/sybase.rb +0 -2
- data/lib/arjdbc/tasks/db2_database_tasks.rb +0 -104
- data/lib/arjdbc/tasks/derby_database_tasks.rb +0 -95
- data/src/java/arjdbc/derby/DerbyModule.java +0 -178
- data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +0 -152
- data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +0 -174
- data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +0 -75
data/lib/arjdbc/abstract/core.rb
CHANGED
@@ -34,7 +34,7 @@ module ArJdbc
|
|
34
34
|
raw_connection.jdbc_connection(unwrap)
|
35
35
|
end
|
36
36
|
|
37
|
-
|
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?(
|
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 = ->{
|
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
|
data/lib/arjdbc/discover.rb
CHANGED
@@ -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
|
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
|
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
|
data/lib/arjdbc/jdbc/adapter.rb
CHANGED
@@ -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 :
|
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::
|
437
|
+
# Helper to get local/UTC time (based on `ActiveRecord::default_timezone`).
|
438
438
|
def get_time(value)
|
439
|
-
get = ::ActiveRecord
|
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::
|
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
|
data/lib/arjdbc/jdbc/column.rb
CHANGED
@@ -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
|
133
|
+
ActiveRecord.default_timezone == :utc ? time : time.getlocal
|
134
134
|
else
|
135
|
-
timezone = ActiveRecord
|
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
data/lib/arjdbc/mssql/adapter.rb
CHANGED
@@ -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,
|
data/lib/arjdbc/mssql/quoting.rb
CHANGED
@@ -4,8 +4,30 @@ module ActiveRecord
|
|
4
4
|
module ConnectionAdapters
|
5
5
|
module MSSQL
|
6
6
|
module Quoting
|
7
|
-
QUOTED_TRUE = '1'
|
8
|
-
QUOTED_FALSE = '0'
|
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.
|
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
|
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 { |
|
32
|
+
statements.concat(o.foreign_keys.map { |fk| accept fk })
|
33
33
|
end
|
34
34
|
|
35
35
|
create_sql << "(#{statements.join(', ')})" if statements.present?
|