activerecord-jdbc-adapter 70.2-java → 72.0-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 +26 -26
- data/.gitignore +8 -0
- data/Gemfile +17 -4
- data/README.md +10 -5
- data/RUNNING_TESTS.md +36 -0
- data/activerecord-jdbc-adapter.gemspec +2 -2
- data/lib/arjdbc/abstract/connection_management.rb +25 -10
- data/lib/arjdbc/abstract/core.rb +15 -13
- data/lib/arjdbc/abstract/database_statements.rb +36 -36
- data/lib/arjdbc/abstract/relation_query_attribute_monkey_patch.rb +24 -0
- data/lib/arjdbc/abstract/statement_cache.rb +2 -7
- data/lib/arjdbc/abstract/transaction_support.rb +39 -22
- data/lib/arjdbc/jdbc/adapter.rb +0 -1
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/jdbc/column.rb +0 -34
- data/lib/arjdbc/jdbc/connection_methods.rb +1 -1
- data/lib/arjdbc/mysql/adapter.rb +108 -32
- data/lib/arjdbc/mysql/adapter_hash_config.rb +159 -0
- data/lib/arjdbc/mysql.rb +1 -1
- data/lib/arjdbc/postgresql/adapter.rb +267 -114
- data/lib/arjdbc/postgresql/adapter_hash_config.rb +98 -0
- data/lib/arjdbc/postgresql/base/array_encoder.rb +3 -1
- data/lib/arjdbc/postgresql/database_statements.rb +20 -0
- data/lib/arjdbc/postgresql/oid_types.rb +10 -29
- data/lib/arjdbc/postgresql/schema_statements.rb +57 -0
- data/lib/arjdbc/postgresql.rb +1 -1
- data/lib/arjdbc/sqlite3/adapter.rb +343 -172
- data/lib/arjdbc/sqlite3/adapter_hash_config.rb +91 -0
- data/lib/arjdbc/sqlite3/column.rb +117 -0
- data/lib/arjdbc/sqlite3/connection_methods.rb +7 -2
- data/lib/arjdbc/sqlite3/pragmas.rb +105 -0
- data/lib/arjdbc/sqlite3.rb +1 -1
- data/lib/arjdbc/version.rb +1 -1
- data/lib/arjdbc.rb +13 -1
- data/rakelib/02-test.rake +2 -2
- data/rakelib/rails.rake +2 -0
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +9 -2
- data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +12 -5
- data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +14 -3
- metadata +15 -11
- data/lib/arjdbc/jdbc/base_ext.rb +0 -17
@@ -24,23 +24,18 @@ module ArJdbc
|
|
24
24
|
|
25
25
|
# Only say we support the statement cache if we are using prepared statements
|
26
26
|
# and have a max number of statements defined
|
27
|
-
statement_limit = self.class.type_cast_config_to_integer(config[:statement_limit])
|
27
|
+
statement_limit = self.class.type_cast_config_to_integer(@config[:statement_limit])
|
28
28
|
@jdbc_statement_cache_enabled = prepared_statements && (statement_limit.nil? || statement_limit > 0)
|
29
29
|
|
30
30
|
@statements = StatementPool.new(statement_limit) # AR (5.0) expects this to be stored as @statements
|
31
31
|
end
|
32
32
|
|
33
|
-
# Clears the prepared statements cache.
|
34
|
-
def clear_cache!
|
35
|
-
@statements.clear
|
36
|
-
end
|
37
|
-
|
38
33
|
def delete_cached_statement(sql)
|
39
34
|
@statements.delete(sql_key(sql))
|
40
35
|
end
|
41
36
|
|
42
37
|
def fetch_cached_statement(sql)
|
43
|
-
@statements[sql_key(sql)] ||= @
|
38
|
+
@statements[sql_key(sql)] ||= @raw_connection.prepare_statement(sql)
|
44
39
|
end
|
45
40
|
|
46
41
|
private
|
@@ -12,11 +12,11 @@ module ArJdbc
|
|
12
12
|
# @since 1.3.0
|
13
13
|
# @override
|
14
14
|
def supports_savepoints?
|
15
|
-
@
|
15
|
+
@raw_connection.supports_savepoints?
|
16
16
|
end
|
17
17
|
|
18
18
|
def supports_transaction_isolation?
|
19
|
-
@
|
19
|
+
@raw_connection.supports_transaction_isolation?
|
20
20
|
end
|
21
21
|
|
22
22
|
########################## Transaction Interface ##########################
|
@@ -24,26 +24,44 @@ module ArJdbc
|
|
24
24
|
# Starts a database transaction.
|
25
25
|
# @override
|
26
26
|
def begin_db_transaction
|
27
|
-
log('BEGIN', 'TRANSACTION')
|
27
|
+
log('BEGIN', 'TRANSACTION') do
|
28
|
+
with_raw_connection(allow_retry: true, materialize_transactions: false) do |conn|
|
29
|
+
result = conn.begin
|
30
|
+
verified!
|
31
|
+
result
|
32
|
+
end
|
33
|
+
end
|
28
34
|
end
|
29
35
|
|
30
36
|
# Starts a database transaction.
|
31
37
|
# @param isolation the transaction isolation to use
|
32
38
|
def begin_isolated_db_transaction(isolation)
|
33
|
-
log("BEGIN ISOLATED - #{isolation}", 'TRANSACTION')
|
39
|
+
log("BEGIN ISOLATED - #{isolation}", 'TRANSACTION') do
|
40
|
+
with_raw_connection(allow_retry: true, materialize_transactions: false) do |conn|
|
41
|
+
conn.begin(isolation)
|
42
|
+
end
|
43
|
+
end
|
34
44
|
end
|
35
45
|
|
36
46
|
# Commits the current database transaction.
|
37
47
|
# @override
|
38
48
|
def commit_db_transaction
|
39
|
-
log('COMMIT', 'TRANSACTION')
|
49
|
+
log('COMMIT', 'TRANSACTION') do
|
50
|
+
with_raw_connection(allow_retry: true, materialize_transactions: false) do |conn|
|
51
|
+
conn.commit
|
52
|
+
end
|
53
|
+
end
|
40
54
|
end
|
41
55
|
|
42
56
|
# Rolls back the current database transaction.
|
43
57
|
# Called from 'rollback_db_transaction' in the AbstractAdapter
|
44
58
|
# @override
|
45
59
|
def exec_rollback_db_transaction
|
46
|
-
log('ROLLBACK', 'TRANSACTION')
|
60
|
+
log('ROLLBACK', 'TRANSACTION') do
|
61
|
+
with_raw_connection(allow_retry: true, materialize_transactions: false) do |conn|
|
62
|
+
conn.rollback
|
63
|
+
end
|
64
|
+
end
|
47
65
|
end
|
48
66
|
|
49
67
|
########################## Savepoint Interface ############################
|
@@ -55,7 +73,11 @@ module ArJdbc
|
|
55
73
|
# @since 1.3.0
|
56
74
|
# @extension added optional name parameter
|
57
75
|
def create_savepoint(name = current_savepoint_name)
|
58
|
-
log("SAVEPOINT #{name}", 'TRANSACTION')
|
76
|
+
log("SAVEPOINT #{name}", 'TRANSACTION') do
|
77
|
+
with_raw_connection(allow_retry: true, materialize_transactions: false) do |conn|
|
78
|
+
conn.create_savepoint(name)
|
79
|
+
end
|
80
|
+
end
|
59
81
|
end
|
60
82
|
|
61
83
|
# Transaction rollback to a given (previously created) save-point.
|
@@ -64,7 +86,11 @@ module ArJdbc
|
|
64
86
|
# @param name the save-point name
|
65
87
|
# @extension added optional name parameter
|
66
88
|
def exec_rollback_to_savepoint(name = current_savepoint_name)
|
67
|
-
log("ROLLBACK TO SAVEPOINT #{name}", 'TRANSACTION')
|
89
|
+
log("ROLLBACK TO SAVEPOINT #{name}", 'TRANSACTION') do
|
90
|
+
with_raw_connection(allow_retry: true, materialize_transactions: false) do |conn|
|
91
|
+
conn.rollback_savepoint(name)
|
92
|
+
end
|
93
|
+
end
|
68
94
|
end
|
69
95
|
|
70
96
|
# Release a previously created save-point.
|
@@ -73,22 +99,13 @@ module ArJdbc
|
|
73
99
|
# @param name the save-point name
|
74
100
|
# @extension added optional name parameter
|
75
101
|
def release_savepoint(name = current_savepoint_name)
|
76
|
-
log("RELEASE SAVEPOINT #{name}", 'TRANSACTION')
|
102
|
+
log("RELEASE SAVEPOINT #{name}", 'TRANSACTION') do
|
103
|
+
with_raw_connection(allow_retry: true, materialize_transactions: false) do |conn|
|
104
|
+
conn.release_savepoint(name)
|
105
|
+
end
|
106
|
+
end
|
77
107
|
end
|
78
108
|
|
79
109
|
end
|
80
110
|
end
|
81
111
|
end
|
82
|
-
|
83
|
-
# patch to avoid the usage of WeakMap
|
84
|
-
require 'active_record/connection_adapters/abstract/transaction'
|
85
|
-
module ActiveRecord
|
86
|
-
module ConnectionAdapters
|
87
|
-
class Transaction
|
88
|
-
def add_record(record, ensure_finalize = true)
|
89
|
-
@records ||= []
|
90
|
-
@records << record
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
data/lib/arjdbc/jdbc/adapter.rb
CHANGED
Binary file
|
data/lib/arjdbc/jdbc/column.rb
CHANGED
@@ -12,45 +12,11 @@ module ActiveRecord
|
|
12
12
|
# specific type.
|
13
13
|
# @see JdbcAdapter#jdbc_column_class
|
14
14
|
class JdbcColumn < Column
|
15
|
-
# @deprecated attribute writers will be removed in 1.4
|
16
|
-
attr_writer :limit, :precision # unless ArJdbc::AR42
|
17
|
-
|
18
|
-
def initialize(config, name, *args)
|
19
|
-
if self.class == JdbcColumn
|
20
|
-
# NOTE: extending classes do not want this if they do they shall call
|
21
|
-
call_discovered_column_callbacks(config) if config
|
22
|
-
default = args.shift
|
23
|
-
else # for extending classes allow ignoring first argument :
|
24
|
-
if ! config.nil? && ! config.is_a?(Hash)
|
25
|
-
default = name; name = config # initialize(name, default, *args)
|
26
|
-
else
|
27
|
-
default = args.shift
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
super(name, default, *args)
|
32
|
-
init_column(name, default, *args)
|
33
|
-
end
|
34
|
-
|
35
|
-
# Additional column initialization for sub-classes.
|
36
|
-
def init_column(*args); end
|
37
15
|
|
38
16
|
# Similar to `ActiveRecord`'s `extract_value_from_default(default)`.
|
39
17
|
# @return default value for a column (possibly extracted from driver value)
|
40
18
|
def default_value(value); value; end
|
41
19
|
|
42
|
-
protected
|
43
|
-
|
44
|
-
# @private
|
45
|
-
def call_discovered_column_callbacks(config)
|
46
|
-
dialect = (config[:dialect] || config[:driver]).to_s
|
47
|
-
for matcher, block in self.class.column_types
|
48
|
-
block.call(config, self) if matcher === dialect
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
public
|
53
|
-
|
54
20
|
# Returns the available column types
|
55
21
|
# @return [Hash] of (matcher, block) pairs
|
56
22
|
def self.column_types
|
@@ -7,7 +7,7 @@ module ArJdbc
|
|
7
7
|
|
8
8
|
def jdbc_connection(config)
|
9
9
|
adapter_class = config[:adapter_class] || ::ActiveRecord::ConnectionAdapters::JdbcAdapter
|
10
|
-
adapter_class.new(
|
10
|
+
adapter_class.new(config)
|
11
11
|
end
|
12
12
|
|
13
13
|
def jndi_connection(config); jdbc_connection(config) end
|
data/lib/arjdbc/mysql/adapter.rb
CHANGED
@@ -11,6 +11,10 @@ require 'arjdbc/abstract/database_statements'
|
|
11
11
|
require 'arjdbc/abstract/statement_cache'
|
12
12
|
require 'arjdbc/abstract/transaction_support'
|
13
13
|
|
14
|
+
require "arjdbc/mysql/adapter_hash_config"
|
15
|
+
|
16
|
+
require "arjdbc/abstract/relation_query_attribute_monkey_patch"
|
17
|
+
|
14
18
|
module ActiveRecord
|
15
19
|
module ConnectionAdapters
|
16
20
|
AbstractMysqlAdapter.class_eval do
|
@@ -23,7 +27,7 @@ module ActiveRecord
|
|
23
27
|
class Mysql2Adapter < AbstractMysqlAdapter
|
24
28
|
ADAPTER_NAME = 'Mysql2'
|
25
29
|
|
26
|
-
include Jdbc::ConnectionPoolCallbacks
|
30
|
+
# include Jdbc::ConnectionPoolCallbacks
|
27
31
|
|
28
32
|
include ArJdbc::Abstract::ConnectionManagement
|
29
33
|
include ArJdbc::Abstract::DatabaseStatements
|
@@ -32,28 +36,52 @@ module ActiveRecord
|
|
32
36
|
include ArJdbc::Abstract::TransactionSupport
|
33
37
|
|
34
38
|
include ArJdbc::MySQL
|
39
|
+
include ArJdbc::MysqlConfig
|
35
40
|
|
36
|
-
|
37
|
-
|
38
|
-
|
41
|
+
class << self
|
42
|
+
def jdbc_connection_class
|
43
|
+
::ActiveRecord::ConnectionAdapters::MySQLJdbcConnection
|
44
|
+
end
|
39
45
|
|
40
|
-
|
41
|
-
|
46
|
+
def new_client(conn_params, adapter_instance)
|
47
|
+
jdbc_connection_class.new(conn_params, adapter_instance)
|
48
|
+
end
|
42
49
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
+
private
|
51
|
+
def initialize_type_map(m)
|
52
|
+
super
|
53
|
+
|
54
|
+
m.register_type(%r(char)i) do |sql_type|
|
55
|
+
limit = extract_limit(sql_type)
|
56
|
+
Type.lookup(:string, adapter: :mysql2, limit: limit)
|
57
|
+
end
|
58
|
+
|
59
|
+
m.register_type %r(^enum)i, Type.lookup(:string, adapter: :mysql2)
|
60
|
+
m.register_type %r(^set)i, Type.lookup(:string, adapter: :mysql2)
|
61
|
+
end
|
50
62
|
end
|
51
63
|
|
52
|
-
|
53
|
-
|
54
|
-
|
64
|
+
# NOTE: redefines constant defined in abstract class however this time
|
65
|
+
# will use methods defined in the mysql abstract class and map properly
|
66
|
+
# mysql types.
|
67
|
+
TYPE_MAP = Type::TypeMap.new.tap { |m| initialize_type_map(m) }
|
55
68
|
|
69
|
+
def initialize(...)
|
56
70
|
super
|
71
|
+
|
72
|
+
@config[:flags] ||= 0
|
73
|
+
|
74
|
+
# assign arjdbc extra connection params
|
75
|
+
conn_params = build_connection_config(@config.compact)
|
76
|
+
|
77
|
+
# JDBC mysql appears to use found rows by default: https://dev.mysql.com/doc/connector-j/en/connector-j-connp-props-connection.html
|
78
|
+
# if @config[:flags].kind_of? Array
|
79
|
+
# @config[:flags].push "FOUND_ROWS"
|
80
|
+
# else
|
81
|
+
# @config[:flags] |= ::Mysql2::Client::FOUND_ROWS
|
82
|
+
# end
|
83
|
+
|
84
|
+
@connection_parameters = conn_params
|
57
85
|
end
|
58
86
|
|
59
87
|
def supports_json?
|
@@ -96,20 +124,25 @@ module ActiveRecord
|
|
96
124
|
!READ_QUERY.match?(sql)
|
97
125
|
end
|
98
126
|
|
99
|
-
def explain(arel, binds = [])
|
100
|
-
sql = "
|
101
|
-
start =
|
102
|
-
result =
|
103
|
-
elapsed =
|
127
|
+
def explain(arel, binds = [], options = [])
|
128
|
+
sql = build_explain_clause(options) + " " + to_sql(arel, binds)
|
129
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
130
|
+
result = internal_exec_query(sql, "EXPLAIN", binds)
|
131
|
+
elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
|
104
132
|
|
105
133
|
MySQL::ExplainPrettyPrinter.new.pp(result, elapsed)
|
106
134
|
end
|
107
135
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
#
|
112
|
-
|
136
|
+
def build_explain_clause(options = [])
|
137
|
+
return "EXPLAIN" if options.empty?
|
138
|
+
|
139
|
+
explain_clause = "EXPLAIN #{options.join(" ").upcase}"
|
140
|
+
|
141
|
+
if analyze_without_explain? && explain_clause.include?("ANALYZE")
|
142
|
+
explain_clause.sub("EXPLAIN ", "")
|
143
|
+
else
|
144
|
+
explain_clause
|
145
|
+
end
|
113
146
|
end
|
114
147
|
|
115
148
|
def each_hash(result) # :nodoc:
|
@@ -164,29 +197,72 @@ module ActiveRecord
|
|
164
197
|
# CONNECTION MANAGEMENT ====================================
|
165
198
|
#++
|
166
199
|
|
200
|
+
def active?
|
201
|
+
!(@raw_connection.nil? || @raw_connection.closed?) && @lock.synchronize { @raw_connection&.ping } || false
|
202
|
+
end
|
203
|
+
|
167
204
|
alias :reset! :reconnect!
|
168
205
|
|
206
|
+
# Disconnects from the database if already connected.
|
207
|
+
# Otherwise, this method does nothing.
|
208
|
+
def disconnect!
|
209
|
+
@lock.synchronize do
|
210
|
+
super
|
211
|
+
@raw_connection&.close
|
212
|
+
@raw_connection = nil
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def discard! # :nodoc:
|
217
|
+
@lock.synchronize do
|
218
|
+
super
|
219
|
+
@raw_connection&.automatic_close = false
|
220
|
+
@raw_connection = nil
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
169
224
|
#
|
170
225
|
|
171
226
|
private
|
227
|
+
# https://mariadb.com/kb/en/analyze-statement/
|
228
|
+
def analyze_without_explain?
|
229
|
+
mariadb? && database_version >= "10.1.0"
|
230
|
+
end
|
231
|
+
|
232
|
+
def text_type?(type)
|
233
|
+
TYPE_MAP.lookup(type).is_a?(Type::String) || TYPE_MAP.lookup(type).is_a?(Type::Text)
|
234
|
+
end
|
235
|
+
|
236
|
+
def configure_connection
|
237
|
+
# @raw_connection.query_options[:as] = :array
|
238
|
+
# @raw_connection.query_options[:database_timezone] = default_timezone
|
239
|
+
super
|
240
|
+
end
|
172
241
|
|
173
242
|
# e.g. "5.7.20-0ubuntu0.16.04.1"
|
174
243
|
def full_version
|
175
|
-
|
244
|
+
database_version.full_version_string
|
176
245
|
end
|
177
246
|
|
178
247
|
def get_full_version
|
179
|
-
@full_version ||=
|
180
|
-
end
|
181
|
-
|
182
|
-
def jdbc_connection_class(spec)
|
183
|
-
::ActiveRecord::ConnectionAdapters::MySQLJdbcConnection
|
248
|
+
@full_version ||= any_raw_connection.full_version
|
184
249
|
end
|
185
250
|
|
186
251
|
def jdbc_column_class
|
187
252
|
::ActiveRecord::ConnectionAdapters::MySQL::Column
|
188
253
|
end
|
189
254
|
|
255
|
+
def translate_exception(exception, message:, sql:, binds:)
|
256
|
+
case message
|
257
|
+
when /Table .* doesn't exist/i
|
258
|
+
StatementInvalid.new(message, sql: sql, binds: binds, connection_pool: @pool)
|
259
|
+
when /BLOB, TEXT, GEOMETRY or JSON column .* can't have a default value/i
|
260
|
+
StatementInvalid.new(message, sql: sql, binds: binds, connection_pool: @pool)
|
261
|
+
else
|
262
|
+
super
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
190
266
|
# defined in MySQL::DatabaseStatements which is not included
|
191
267
|
def default_insert_value(column)
|
192
268
|
super unless column.auto_increment?
|
@@ -0,0 +1,159 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ArJdbc
|
4
|
+
module MysqlConfig
|
5
|
+
def build_connection_config(config)
|
6
|
+
config = config.deep_dup
|
7
|
+
|
8
|
+
load_jdbc_driver
|
9
|
+
|
10
|
+
# don't set driver if it's explicitly set to false
|
11
|
+
# allow Java's service discovery mechanism (with connector/j 8.0)
|
12
|
+
config[:driver] ||= database_driver_name if config[:driver] != false
|
13
|
+
|
14
|
+
host = (config[:host] ||= "localhost")
|
15
|
+
port = (config[:port] ||= 3306)
|
16
|
+
|
17
|
+
# jdbc:mysql://[host][,failoverhost...][:port]/[database]
|
18
|
+
# - alternate fail-over syntax: [host:port],[host:port]/[database]
|
19
|
+
config[:url] ||= "jdbc:mysql://#{host}:#{port}/#{config[:database]}"
|
20
|
+
|
21
|
+
config[:properties] = build_properties(config)
|
22
|
+
|
23
|
+
config
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def load_jdbc_driver
|
29
|
+
require "jdbc/mysql"
|
30
|
+
|
31
|
+
::Jdbc::MySQL.load_driver(:require) if defined?(::Jdbc::MySQL.load_driver)
|
32
|
+
rescue LoadError
|
33
|
+
# assuming driver.jar is on the class-path
|
34
|
+
end
|
35
|
+
|
36
|
+
def database_driver_name
|
37
|
+
return ::Jdbc::MySQL.driver_name if defined?(::Jdbc::MySQL.driver_name)
|
38
|
+
|
39
|
+
"com.mysql.jdbc.Driver"
|
40
|
+
end
|
41
|
+
|
42
|
+
def build_properties(config)
|
43
|
+
properties = config[:properties] || {}
|
44
|
+
|
45
|
+
properties["zeroDateTimeBehavior"] ||= default_zero_date_time_behavior(config[:driver])
|
46
|
+
|
47
|
+
properties["jdbcCompliantTruncation"] ||= false
|
48
|
+
|
49
|
+
charset_name = convert_mysql_encoding(config)
|
50
|
+
|
51
|
+
# do not set characterEncoding
|
52
|
+
if charset_name.eql?(false)
|
53
|
+
properties["character_set_server"] = config[:encoding] || "utf8"
|
54
|
+
else
|
55
|
+
properties["characterEncoding"] = charset_name
|
56
|
+
end
|
57
|
+
|
58
|
+
# driver also executes: "SET NAMES " + (useutf8mb4 ? "utf8mb4" : "utf8")
|
59
|
+
# thus no need to do it on configure_connection :
|
60
|
+
config[:encoding] = nil if config.key?(:encoding)
|
61
|
+
|
62
|
+
properties["connectionCollation"] ||= config[:collation] if config[:collation]
|
63
|
+
|
64
|
+
properties["autoReconnect"] ||= reconnect.to_s unless config[:reconnect].nil?
|
65
|
+
|
66
|
+
properties["noDatetimeStringSync"] = true unless properties.key?("noDatetimeStringSync")
|
67
|
+
|
68
|
+
sslcert = config[:sslcert]
|
69
|
+
sslca = config[:sslca]
|
70
|
+
|
71
|
+
if config[:sslkey] || sslcert
|
72
|
+
properties["useSSL"] ||= true
|
73
|
+
properties["requireSSL"] ||= true
|
74
|
+
properties["clientCertificateKeyStoreUrl"] ||= java.io.File.new(sslcert).to_url.to_s if sslcert
|
75
|
+
|
76
|
+
if sslca
|
77
|
+
properties["trustCertificateKeyStoreUrl"] ||= java.io.File.new(sslca).to_url.to_s
|
78
|
+
else
|
79
|
+
properties["verifyServerCertificate"] ||= false
|
80
|
+
end
|
81
|
+
else
|
82
|
+
# According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection
|
83
|
+
# must be established by default if explicit option isn't set :
|
84
|
+
properties["useSSL"] ||= false
|
85
|
+
end
|
86
|
+
|
87
|
+
# disables the effect of 'useTimezone'
|
88
|
+
properties["useLegacyDatetimeCode"] = false
|
89
|
+
|
90
|
+
properties
|
91
|
+
end
|
92
|
+
|
93
|
+
def default_zero_date_time_behavior(driver)
|
94
|
+
return "CONVERT_TO_NULL" if driver == false
|
95
|
+
|
96
|
+
return "CONVERT_TO_NULL" if driver.start_with?("com.mysql.cj.")
|
97
|
+
|
98
|
+
"convertToNull"
|
99
|
+
end
|
100
|
+
|
101
|
+
# See https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-charsets.html
|
102
|
+
# to charset-name (characterEncoding=...)
|
103
|
+
def convert_mysql_encoding(config)
|
104
|
+
# NOTE: this is "better" than passing what users are used to set on MRI
|
105
|
+
# e.g. 'utf8mb4' will fail cause the driver will check for a Java charset
|
106
|
+
# ... it's smart enough to detect utf8mb4 from server variables :
|
107
|
+
# "character_set_client" && "character_set_connection" (thus UTF-8)
|
108
|
+
encoding = config.key?(:encoding) ? config[:encoding] : "utf8"
|
109
|
+
|
110
|
+
value = MYSQL_ENCODINGS[encoding]
|
111
|
+
|
112
|
+
return false if value == false
|
113
|
+
|
114
|
+
value || encoding
|
115
|
+
end
|
116
|
+
|
117
|
+
MYSQL_ENCODINGS = {
|
118
|
+
"big5" => "Big5",
|
119
|
+
"dec8" => nil,
|
120
|
+
"hp8" => nil,
|
121
|
+
"latin1" => "Cp1252",
|
122
|
+
"latin2" => "ISO8859_2",
|
123
|
+
"swe7" => nil,
|
124
|
+
"ascii" => "US-ASCII",
|
125
|
+
"ujis" => "EUC_JP",
|
126
|
+
"sjis" => "SJIS",
|
127
|
+
"hebrew" => "ISO8859_8",
|
128
|
+
"tis620" => "TIS620",
|
129
|
+
"euckr" => "EUC_KR",
|
130
|
+
"gb2312" => "EUC_CN",
|
131
|
+
"greek" => "ISO8859_7",
|
132
|
+
"cp1250" => "Cp1250",
|
133
|
+
"gbk" => "GBK",
|
134
|
+
"armscii8" => nil,
|
135
|
+
"ucs2" => "UnicodeBig",
|
136
|
+
"cp866" => "Cp866",
|
137
|
+
"keybcs2" => nil,
|
138
|
+
"macce" => "MacCentralEurope",
|
139
|
+
"macroman" => "MacRoman",
|
140
|
+
"cp1251" => "Cp1251",
|
141
|
+
"cp1256" => "Cp1256",
|
142
|
+
"cp1257" => "Cp1257",
|
143
|
+
"binary" => false,
|
144
|
+
"geostd8" => nil,
|
145
|
+
"cp932" => "Cp932",
|
146
|
+
"utf8" => "UTF-8",
|
147
|
+
"utf8mb4" => false,
|
148
|
+
"utf16" => false,
|
149
|
+
"utf32" => false,
|
150
|
+
# "cp850" => "Cp850",
|
151
|
+
# "koi8r" => "KOI8-R",
|
152
|
+
# "koi8u" => "KOI8-R",
|
153
|
+
# "latin5" => "ISO-8859-9",
|
154
|
+
# "cp852" => "CP852",
|
155
|
+
# "latin7" => "ISO-8859-13",
|
156
|
+
# "eucjpms" => "eucJP-ms"
|
157
|
+
}.freeze
|
158
|
+
end
|
159
|
+
end
|
data/lib/arjdbc/mysql.rb
CHANGED