activerecord-jdbc-alt-adapter 71.0.0-java → 72.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/README.md +2 -2
- data/activerecord-jdbc-adapter.gemspec +1 -1
- data/activerecord-jdbc-alt-adapter.gemspec +1 -1
- data/lib/arel/visitors/sqlserver.rb +13 -9
- data/lib/arjdbc/abstract/core.rb +10 -1
- data/lib/arjdbc/abstract/database_statements.rb +1 -1
- data/lib/arjdbc/abstract/transaction_support.rb +3 -1
- data/lib/arjdbc/jdbc/adapter.rb +0 -1
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/mssql/adapter.rb +18 -15
- data/lib/arjdbc/mssql/adapter_hash_config.rb +53 -0
- data/lib/arjdbc/mssql/column.rb +16 -7
- data/lib/arjdbc/mssql/database_statements.rb +7 -2
- data/lib/arjdbc/mssql/quoting.rb +56 -36
- data/lib/arjdbc/mssql/schema_creation.rb +16 -0
- data/lib/arjdbc/mssql/schema_statements.rb +44 -19
- data/lib/arjdbc/mssql.rb +1 -1
- data/lib/arjdbc/mysql/adapter.rb +8 -11
- data/lib/arjdbc/mysql/adapter_hash_config.rb +159 -0
- data/lib/arjdbc/mysql.rb +1 -1
- data/lib/arjdbc/postgresql/adapter.rb +17 -11
- data/lib/arjdbc/postgresql/adapter_hash_config.rb +98 -0
- data/lib/arjdbc/postgresql/base/array_encoder.rb +3 -1
- data/lib/arjdbc/postgresql/oid_types.rb +2 -2
- data/lib/arjdbc/postgresql.rb +1 -1
- data/lib/arjdbc/sqlite3/adapter.rb +193 -90
- data/lib/arjdbc/sqlite3/adapter_hash_config.rb +91 -0
- data/lib/arjdbc/sqlite3/column.rb +17 -3
- 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 +16 -1
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +5 -0
- data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +12 -2
- metadata +12 -8
- data/lib/arjdbc/jdbc/base_ext.rb +0 -17
@@ -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
@@ -24,6 +24,7 @@ require 'arjdbc/postgresql/base/array_encoder'
|
|
24
24
|
require 'arjdbc/postgresql/name'
|
25
25
|
require 'arjdbc/postgresql/database_statements'
|
26
26
|
require 'arjdbc/postgresql/schema_statements'
|
27
|
+
require "arjdbc/postgresql/adapter_hash_config"
|
27
28
|
|
28
29
|
require 'active_model'
|
29
30
|
|
@@ -344,7 +345,7 @@ module ArJdbc
|
|
344
345
|
type.typname AS name,
|
345
346
|
type.OID AS oid,
|
346
347
|
n.nspname AS schema,
|
347
|
-
|
348
|
+
array_agg(enum.enumlabel ORDER BY enum.enumsortorder) AS value
|
348
349
|
FROM pg_enum AS enum
|
349
350
|
JOIN pg_type AS type ON (type.oid = enum.enumtypid)
|
350
351
|
JOIN pg_namespace n ON type.typnamespace = n.oid
|
@@ -841,6 +842,15 @@ module ActiveRecord::ConnectionAdapters
|
|
841
842
|
# setting, you should immediately run <tt>bin/rails db:migrate</tt> to update the types in your schema.rb.
|
842
843
|
class_attribute :datetime_type, default: :timestamp
|
843
844
|
|
845
|
+
##
|
846
|
+
# :singleton-method:
|
847
|
+
# Toggles automatic decoding of date columns.
|
848
|
+
#
|
849
|
+
# ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.select_value("select '2024-01-01'::date").class #=> String
|
850
|
+
# ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.decode_dates = true
|
851
|
+
# ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.select_value("select '2024-01-01'::date").class #=> Date
|
852
|
+
class_attribute :decode_dates, default: false
|
853
|
+
|
844
854
|
# Try to use as much of the built in postgres logic as possible
|
845
855
|
# maybe someday we can extend the actual adapter
|
846
856
|
include ActiveRecord::ConnectionAdapters::PostgreSQL::ReferentialIntegrity
|
@@ -854,7 +864,11 @@ module ActiveRecord::ConnectionAdapters
|
|
854
864
|
include ArJdbc::Abstract::DatabaseStatements
|
855
865
|
include ArJdbc::Abstract::StatementCache
|
856
866
|
include ArJdbc::Abstract::TransactionSupport
|
867
|
+
include ArJdbc::PostgreSQLConfig
|
868
|
+
|
869
|
+
# NOTE: after AR refactor quote_column_name became class and instance method
|
857
870
|
include ArJdbc::PostgreSQL
|
871
|
+
extend ArJdbc::PostgreSQL
|
858
872
|
|
859
873
|
require 'arjdbc/postgresql/oid_types'
|
860
874
|
include ::ArJdbc::PostgreSQL::OIDTypes
|
@@ -900,7 +914,8 @@ module ActiveRecord::ConnectionAdapters
|
|
900
914
|
def initialize(...)
|
901
915
|
super
|
902
916
|
|
903
|
-
|
917
|
+
# assign arjdbc extra connection params
|
918
|
+
conn_params = build_connection_config(@config.compact)
|
904
919
|
|
905
920
|
@connection_parameters = conn_params
|
906
921
|
|
@@ -912,15 +927,6 @@ module ActiveRecord::ConnectionAdapters
|
|
912
927
|
self.class.type_cast_config_to_boolean(@config[:insert_returning]) : true
|
913
928
|
end
|
914
929
|
|
915
|
-
def self.database_exists?(config)
|
916
|
-
conn = ActiveRecord::Base.postgresql_connection(config)
|
917
|
-
conn && conn.really_valid?
|
918
|
-
rescue ActiveRecord::NoDatabaseError
|
919
|
-
false
|
920
|
-
ensure
|
921
|
-
conn.disconnect! if conn
|
922
|
-
end
|
923
|
-
|
924
930
|
require 'active_record/connection_adapters/postgresql/schema_definitions'
|
925
931
|
|
926
932
|
ColumnMethods = ActiveRecord::ConnectionAdapters::PostgreSQL::ColumnMethods
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ArJdbc
|
4
|
+
module PostgreSQLConfig
|
5
|
+
def build_connection_config(config)
|
6
|
+
config = config.deep_dup
|
7
|
+
|
8
|
+
load_jdbc_driver
|
9
|
+
|
10
|
+
config[:driver] ||= database_driver_name
|
11
|
+
|
12
|
+
host = (config[:host] ||= config[:hostaddr] || ENV["PGHOST"] || "localhost")
|
13
|
+
port = (config[:port] ||= ENV["PGPORT"] || 5432)
|
14
|
+
database = config[:database] || config[:dbname] || ENV["PGDATABASE"]
|
15
|
+
|
16
|
+
app = config[:application_name] || config[:appname] || config[:application]
|
17
|
+
|
18
|
+
config[:url] ||= if app
|
19
|
+
"jdbc:postgresql://#{host}:#{port}/#{database}?ApplicationName=#{app}"
|
20
|
+
else
|
21
|
+
"jdbc:postgresql://#{host}:#{port}/#{database}"
|
22
|
+
end
|
23
|
+
|
24
|
+
config[:url] << config[:pg_params] if config[:pg_params]
|
25
|
+
|
26
|
+
config[:username] ||= config[:user] || ENV["PGUSER"] || ENV_JAVA["user.name"]
|
27
|
+
config[:password] ||= ENV["PGPASSWORD"] unless config.key?(:password)
|
28
|
+
|
29
|
+
config[:properties] = build_properties(config)
|
30
|
+
|
31
|
+
config
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def load_jdbc_driver
|
37
|
+
require "jdbc/postgres"
|
38
|
+
|
39
|
+
::Jdbc::Postgres.load_driver(:require) if defined?(::Jdbc::Postgres.load_driver)
|
40
|
+
rescue LoadError
|
41
|
+
# assuming driver.jar is on the class-path
|
42
|
+
end
|
43
|
+
|
44
|
+
def database_driver_name
|
45
|
+
return ::Jdbc::Postgres.driver_name if defined?(::Jdbc::Postgres.driver_name)
|
46
|
+
|
47
|
+
"org.postgresql.Driver"
|
48
|
+
end
|
49
|
+
|
50
|
+
def build_properties(config)
|
51
|
+
properties = config[:properties] || {}
|
52
|
+
|
53
|
+
# PG :connect_timeout - maximum time to wait for connection to succeed
|
54
|
+
connect_timeout = config[:connect_timeout] || ENV["PGCONNECT_TIMEOUT"]
|
55
|
+
|
56
|
+
properties["socketTimeout"] ||= connect_timeout if connect_timeout
|
57
|
+
|
58
|
+
login_timeout = config[:login_timeout]
|
59
|
+
|
60
|
+
properties["loginTimeout"] ||= login_timeout if login_timeout
|
61
|
+
|
62
|
+
sslmode = config.key?(:sslmode) ? config[:sslmode] : config[:requiressl]
|
63
|
+
# NOTE: makes not much sense since this needs some JVM options :
|
64
|
+
sslmode = ENV["PGSSLMODE"] || ENV["PGREQUIRESSL"] if sslmode.nil?
|
65
|
+
|
66
|
+
# PG :sslmode - disable|allow|prefer|require
|
67
|
+
unless sslmode.nil? || !(sslmode == true || sslmode.to_s == "require")
|
68
|
+
# JRuby/JVM needs to be started with :
|
69
|
+
# -Djavax.net.ssl.trustStore=mystore -Djavax.net.ssl.trustStorePassword=...
|
70
|
+
# or a non-validating connection might be used (for testing) :
|
71
|
+
# :sslfactory = 'org.postgresql.ssl.NonValidatingFactory'
|
72
|
+
|
73
|
+
if config[:driver].start_with?("org.postgresql.")
|
74
|
+
properties["sslfactory"] ||= "org.postgresql.ssl.NonValidatingFactory"
|
75
|
+
end
|
76
|
+
|
77
|
+
properties["ssl"] ||= "true"
|
78
|
+
end
|
79
|
+
|
80
|
+
properties["tcpKeepAlive"] ||= config[:keepalives] if config.key?(:keepalives)
|
81
|
+
properties["kerberosServerName"] ||= config[:krbsrvname] if config[:krbsrvname]
|
82
|
+
|
83
|
+
prepared_statements = config.fetch(:prepared_statements, true)
|
84
|
+
|
85
|
+
prepared_statements = false if prepared_statements == "false"
|
86
|
+
|
87
|
+
if prepared_statements
|
88
|
+
# this makes the pgjdbc driver handle hot compatibility internally
|
89
|
+
properties["autosave"] ||= "conservative"
|
90
|
+
else
|
91
|
+
# If prepared statements are off, lets make sure they are really *off*
|
92
|
+
properties["prepareThreshold"] = 0
|
93
|
+
end
|
94
|
+
|
95
|
+
properties
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -12,7 +12,9 @@ module ActiveRecord::ConnectionAdapters::PostgreSQL::OID
|
|
12
12
|
'text'.freeze
|
13
13
|
else
|
14
14
|
base_type = name.chomp('[]').to_sym
|
15
|
-
ActiveRecord::Base.connection
|
15
|
+
ActiveRecord::Base.with_connection do |connection|
|
16
|
+
connection.native_database_types[base_type][:name]
|
17
|
+
end
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
@@ -112,8 +112,8 @@ module ArJdbc
|
|
112
112
|
m.register_type "int4", Type::Integer.new(limit: 4)
|
113
113
|
m.register_type "int8", Type::Integer.new(limit: 8)
|
114
114
|
m.register_type "oid", OID::Oid.new
|
115
|
-
m.register_type "float4", Type::Float.new
|
116
|
-
m.
|
115
|
+
m.register_type "float4", Type::Float.new(limit: 24)
|
116
|
+
m.register_type "float8", Type::Float.new
|
117
117
|
m.register_type "text", Type::Text.new
|
118
118
|
register_class_with_limit m, "varchar", Type::String
|
119
119
|
m.alias_type "char", "varchar"
|
data/lib/arjdbc/postgresql.rb
CHANGED