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.
- 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/connection_methods.rb +0 -3
- 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,
|
@@ -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
|
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?
|