activerecord-jdbc-alt-adapter 71.0.0-java → 72.0.0.alpha1-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 973f3cfa750c3424b5de9105f177584edea8ebe705d50b20e4b9f6d989a4919f
4
- data.tar.gz: e7f86bfeb49f90f2767e3bdcc3e0101a58149e97421e8d7b96da8f59fc469959
3
+ metadata.gz: 9368e28d99e49de4164150e2e006ce8991be7d7aab58e6773936866f86dbbdd0
4
+ data.tar.gz: '03983c9218db6dd3a9ab278b0364ded1d9f5c315853b7ed6b543a05cca8c6c6c'
5
5
  SHA512:
6
- metadata.gz: f276911281e38f162526b603959f5798fa5d09c73284a79078376126b5fade87add2e4a4345242029a4b4e39097b5a6964651483576f51ed8bee3ac7b6e586a3
7
- data.tar.gz: 8e5d458add630631bfaa82605f20d28c80310e25787c9db2c94c1b8cc677ac8ff6e0730c97b6271a333cbfe919da8a35ad8deb7911aeedc89c3021629e0c5370
6
+ metadata.gz: 450ddae41c05f2519c53ff0ad17de0bfd3cfefa1a471775a9d27946843f2d685301ff12cbbcdd4f434f275ee4f067798fc500ff49a2f2ec79f2339dfede6fc8c
7
+ data.tar.gz: aa9aa18ad21ead09d7bab3180032c8fa71ffee37fbb43dbba6a52ac3b436da34010e229e10cf1d6eec9edb2a803addcd0585a0b8ac78bdba05281f77dc7f5924
@@ -41,7 +41,7 @@ Gem::Specification.new do |gem|
41
41
  gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
42
42
  gem.test_files = gem.files.grep(%r{^test/})
43
43
 
44
- gem.add_dependency 'activerecord', '~> 7.1.3'
44
+ gem.add_dependency "activerecord", "~> 7.2.2"
45
45
 
46
46
  #gem.add_development_dependency 'test-unit', '2.5.4'
47
47
  #gem.add_development_dependency 'test-unit-context', '>= 0.3.0'
@@ -43,7 +43,7 @@ Gem::Specification.new do |gem|
43
43
  gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
44
44
  gem.test_files = gem.files.grep(%r{^test/})
45
45
 
46
- gem.add_dependency 'activerecord', '~> 7.1.3'
46
+ gem.add_dependency "activerecord", "~> 7.2.2"
47
47
 
48
48
  #gem.add_development_dependency 'test-unit', '2.5.4'
49
49
  #gem.add_development_dependency 'test-unit-context', '>= 0.3.0'
@@ -83,15 +83,17 @@ module Arel
83
83
  @select_statement = nil
84
84
  end
85
85
 
86
- def visit_Arel_Table o, collector
86
+ def visit_Arel_Table(o, collector)
87
87
  # Apparently, o.engine.connection can actually be a different adapter
88
88
  # than sqlserver. Can be removed if fixed in ActiveRecord. See:
89
89
  # github.com/rails-sqlserver/activerecord-sqlserver-adapter/issues/450
90
90
  table_name = begin
91
- if o.class.engine.connection.respond_to?(:sqlserver?) && o.class.engine.connection.database_prefix_remote_server?
92
- remote_server_table_name(o)
93
- else
94
- quote_table_name(o.name)
91
+ o.class.engine.with_connection do |connection|
92
+ if connection.respond_to?(:sqlserver?) && connection.database_prefix_remote_server?
93
+ remote_server_table_name(o)
94
+ else
95
+ quote_table_name(o.name)
96
+ end
95
97
  end
96
98
  rescue Exception => e
97
99
  quote_table_name(o.name)
@@ -259,10 +261,12 @@ module Arel
259
261
  column_name ? t[column_name] : nil
260
262
  end
261
263
 
262
- def remote_server_table_name o
263
- ActiveRecord::ConnectionAdapters::SQLServer::Utils.extract_identifiers(
264
- "#{o.class.engine.connection.database_prefix}#{o.name}"
265
- ).quoted
264
+ def remote_server_table_name(o)
265
+ o.class.engine.with_connection do |connection|
266
+ ActiveRecord::ConnectionAdapters::SQLServer::Utils.extract_identifiers(
267
+ "#{connection.database_prefix}#{o.name}"
268
+ ).quoted
269
+ end
266
270
  end
267
271
 
268
272
  # Need to remove ordering from subqueries unless TOP/OFFSET also used. Otherwise, SQLServer
@@ -79,7 +79,7 @@ module ArJdbc
79
79
  alias :exec_delete :exec_update
80
80
 
81
81
  # overridden to support legacy binds
82
- def select_all(arel, name = nil, binds = NO_BINDS, preparable: nil, async: false)
82
+ def select_all(arel, name = nil, binds = NO_BINDS, preparable: nil, async: false, allow_retry: false)
83
83
  binds = convert_legacy_binds_to_attributes(binds) if binds.first.is_a?(Array)
84
84
  super
85
85
  end
Binary file
@@ -30,6 +30,8 @@ require 'arjdbc/mssql/errors'
30
30
  require 'arjdbc/mssql/schema_creation'
31
31
  require 'arjdbc/mssql/database_limits'
32
32
 
33
+ require "arjdbc/mssql/adapter_hash_config"
34
+
33
35
  require "arjdbc/abstract/relation_query_attribute_monkey_patch"
34
36
 
35
37
  module ActiveRecord
@@ -44,6 +46,7 @@ module ActiveRecord
44
46
  # include ArJdbc::Abstract::DatabaseStatements
45
47
  # include ArJdbc::Abstract::StatementCache
46
48
  include ArJdbc::Abstract::TransactionSupport
49
+ include ArJdbc::MSSQLConfig
47
50
 
48
51
  include MSSQL::Quoting
49
52
  include MSSQL::SchemaStatements
@@ -81,7 +84,8 @@ module ActiveRecord
81
84
  # configure_connection happens in super
82
85
  super
83
86
 
84
- conn_params = @config.compact
87
+ # assign arjdbc extra connection params
88
+ conn_params = build_connection_config(@config.compact)
85
89
 
86
90
  @raw_connection = nil
87
91
 
@@ -340,7 +344,7 @@ module ActiveRecord
340
344
 
341
345
  schemas_and_tables.map do |schema_table|
342
346
  schema, table = schema_table
343
- "#{quote_name_part(schema)}.#{quote_name_part(table)}"
347
+ "#{self.class.mssql_quote_name_part(schema)}.#{self.class.mssql_quote_name_part(table)}"
344
348
  end
345
349
  end
346
350
 
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ArJdbc
4
+ module MSSQLConfig
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
+ config[:host] ||= "localhost"
13
+ config[:connection_alive_sql] ||= "SELECT 1"
14
+ config[:lock_timeout] ||= 5000
15
+
16
+ config[:url] ||= build_connection_url(config)
17
+
18
+ config
19
+ end
20
+
21
+ private
22
+
23
+ def load_jdbc_driver
24
+ require "jdbc/mssql"
25
+
26
+ ::Jdbc::Mssql.load_driver if defined?(::Jdbc::Mssql.load_driver)
27
+ rescue LoadError
28
+ # assuming driver.jar is on the class-path
29
+ end
30
+
31
+ def database_driver_name
32
+ "com.microsoft.sqlserver.jdbc.SQLServerDriver"
33
+ end
34
+
35
+ def build_connection_url(config)
36
+ url = "".dup
37
+ url << "jdbc:sqlserver://#{config[:host]}"
38
+ url << ( config[:port] ? ":#{config[:port]};" : ';' )
39
+ url << "databaseName=#{config[:database]};" if config[:database]
40
+ url << "instanceName=#{config[:instance]};" if config[:instance]
41
+ url << "sendTimeAsDatetime=#{config[:send_time_as_datetime] || false};"
42
+ url << "loginTimeout=#{config[:login_timeout].to_i};" if config[:login_timeout]
43
+ url << "lockTimeout=#{config[:lock_timeout].to_i};"
44
+ url << "encrypt=#{config[:encrypt]};" if config.key?(:encrypt)
45
+ url << "trustServerCertificate=#{config[:trust_server_certificate]};" if config.key?(:trust_server_certificate)
46
+ app = config[:application_name] || config[:appname] || config[:application]
47
+ url << "applicationName=#{app};" if app
48
+ isc = config[:integrated_security] # Win only - needs sqljdbc_auth.dll
49
+ url << "integratedSecurity=#{isc};" unless isc.nil?
50
+ url
51
+ end
52
+ end
53
+ end
@@ -90,7 +90,7 @@ module ActiveRecord
90
90
  end
91
91
  end
92
92
 
93
- def internal_exec_query(sql, name = 'SQL', binds = [], prepare: false, async: false)
93
+ def internal_exec_query(sql, name = 'SQL', binds = [], prepare: false, async: false, allow_retry: false)
94
94
  sql = transform_query(sql)
95
95
 
96
96
  check_if_write_query(sql)
@@ -244,7 +244,7 @@ module ActiveRecord
244
244
  end
245
245
 
246
246
  def raw_jdbc_connection
247
- @raw_connection
247
+ any_raw_connection
248
248
  end
249
249
 
250
250
  # It seems the truncate_tables is mostly used for testing
@@ -4,6 +4,62 @@ module ActiveRecord
4
4
  module ConnectionAdapters
5
5
  module MSSQL
6
6
  module Quoting
7
+ extend ActiveSupport::Concern
8
+
9
+ QUOTED_COLUMN_NAMES = Concurrent::Map.new # :nodoc:
10
+ QUOTED_TABLE_NAMES = Concurrent::Map.new # :nodoc:
11
+
12
+ module ClassMethods # :nodoc:
13
+ def column_name_matcher
14
+ /
15
+ \A
16
+ (
17
+ (?:
18
+ # \[table_name\].\[column_name\] | function(one or no argument)
19
+ ((?:\w+\.|\[\w+\]\.)?(?:\w+|\[\w+\])) | \w+\((?:|\g<2>)\)
20
+ )
21
+ (?:\s+AS\s+(?:\w+|\[\w+\]))?
22
+ )
23
+ (?:\s*,\s*\g<1>)*
24
+ \z
25
+ /ix
26
+ end
27
+
28
+ def column_name_with_order_matcher
29
+ /
30
+ \A
31
+ (
32
+ (?:
33
+ # \[table_name\].\[column_name\] | function(one or no argument)
34
+ ((?:\w+\.|\[\w+\]\.)?(?:\w+|\[\w+\])) | \w+\((?:|\g<2>)\)
35
+ )
36
+ (?:\s+ASC|\s+DESC)?
37
+ )
38
+ (?:\s*,\s*\g<1>)*
39
+ \z
40
+ /ix
41
+ end
42
+
43
+ def quote_column_name(name)
44
+ QUOTED_COLUMN_NAMES[name] ||= mssql_quote_column_name(name)
45
+ end
46
+
47
+ def quote_table_name(name)
48
+ QUOTED_TABLE_NAMES[name] ||= mssql_quote_column_name(name)
49
+ end
50
+
51
+ def mssql_quote_column_name(name)
52
+ name = name.to_s.split(".")
53
+ name.map! { |n| mssql_quote_name_part(n) } # "[#{name}]"
54
+ name.join(".")
55
+ end
56
+
57
+ # Implements the quoting style for SQL Server
58
+ def mssql_quote_name_part(part)
59
+ part =~ /^\[.*\]$/ ? part : "[#{part.gsub(']', ']]')}]"
60
+ end
61
+ end
62
+
7
63
  QUOTED_TRUE = '1'
8
64
  QUOTED_FALSE = '0'
9
65
 
@@ -88,42 +144,6 @@ module ActiveRecord
88
144
  # @see #quote in old adapter
89
145
  BLOB_VALUE_MARKER = "''"
90
146
 
91
- def column_name_matcher
92
- COLUMN_NAME
93
- end
94
-
95
- def column_name_with_order_matcher
96
- COLUMN_NAME_WITH_ORDER
97
- end
98
-
99
- COLUMN_NAME = /
100
- \A
101
- (
102
- (?:
103
- # \[table_name\].\[column_name\] | function(one or no argument)
104
- ((?:\w+\.|\[\w+\]\.)?(?:\w+|\[\w+\])) | \w+\((?:|\g<2>)\)
105
- )
106
- (?:\s+AS\s+(?:\w+|\[\w+\]))?
107
- )
108
- (?:\s*,\s*\g<1>)*
109
- \z
110
- /ix
111
-
112
- COLUMN_NAME_WITH_ORDER = /
113
- \A
114
- (
115
- (?:
116
- # \[table_name\].\[column_name\] | function(one or no argument)
117
- ((?:\w+\.|\[\w+\]\.)?(?:\w+|\[\w+\])) | \w+\((?:|\g<2>)\)
118
- )
119
- (?:\s+ASC|\s+DESC)?
120
- )
121
- (?:\s*,\s*\g<1>)*
122
- \z
123
- /ix
124
-
125
- private_constant :COLUMN_NAME, :COLUMN_NAME_WITH_ORDER
126
-
127
147
  private
128
148
 
129
149
  def time_with_db_timezone(value)
@@ -182,20 +182,8 @@ module ActiveRecord
182
182
  rename_table_indexes(table_name, new_name)
183
183
  end
184
184
 
185
- # This is the same as the abstract method
186
- def quote_table_name(name)
187
- quote_column_name(name)
188
- end
189
-
190
- # This overrides the abstract method to be specific to SQL Server.
191
- def quote_column_name(name)
192
- name = name.to_s.split('.')
193
- name.map! { |n| quote_name_part(n) } # "[#{name}]"
194
- name.join('.')
195
- end
196
-
197
185
  def quote_database_name(name)
198
- quote_name_part(name.to_s)
186
+ self.class.mssql_quote_name_part(name.to_s)
199
187
  end
200
188
 
201
189
  # @private these cannot specify a limit
@@ -439,11 +427,6 @@ module ActiveRecord
439
427
  result
440
428
  end
441
429
 
442
- # Implements the quoting style for SQL Server
443
- def quote_name_part(part)
444
- part =~ /^\[.*\]$/ ? part : "[#{part.gsub(']', ']]')}]"
445
- end
446
-
447
430
  def remove_check_constraints(table_name, column_name)
448
431
  constraints = select_values "SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE where TABLE_NAME = '#{quote_string(table_name)}' and COLUMN_NAME = '#{quote_string(column_name)}'", 'SCHEMA'
449
432
  constraints.each do |constraint|
data/lib/arjdbc/mssql.rb CHANGED
@@ -6,4 +6,4 @@ module ArJdbc
6
6
  MsSQL = MSSQL # compatibility with 1.2
7
7
  end
8
8
 
9
- ArJdbc.warn_unsupported_adapter 'mssql', [7, 1] # warns on AR >= 4.2
9
+ ArJdbc.warn_unsupported_adapter "mssql", [7, 2] # warns on AR >= 4.2
@@ -11,6 +11,8 @@ 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
+
14
16
  require "arjdbc/abstract/relation_query_attribute_monkey_patch"
15
17
 
16
18
  module ActiveRecord
@@ -34,6 +36,7 @@ module ActiveRecord
34
36
  include ArJdbc::Abstract::TransactionSupport
35
37
 
36
38
  include ArJdbc::MySQL
39
+ include ArJdbc::MysqlConfig
37
40
 
38
41
  class << self
39
42
  def jdbc_connection_class
@@ -68,6 +71,9 @@ module ActiveRecord
68
71
 
69
72
  @config[:flags] ||= 0
70
73
 
74
+ # assign arjdbc extra connection params
75
+ conn_params = build_connection_config(@config.compact)
76
+
71
77
  # JDBC mysql appears to use found rows by default: https://dev.mysql.com/doc/connector-j/en/connector-j-connp-props-connection.html
72
78
  # if @config[:flags].kind_of? Array
73
79
  # @config[:flags].push "FOUND_ROWS"
@@ -75,7 +81,7 @@ module ActiveRecord
75
81
  # @config[:flags] |= ::Mysql2::Client::FOUND_ROWS
76
82
  # end
77
83
 
78
- @connection_parameters ||= @config
84
+ @connection_parameters = conn_params
79
85
  end
80
86
 
81
87
  def self.database_exists?(config)
@@ -0,0 +1,149 @@
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
+ config[:driver] ||= database_driver_name
11
+
12
+ host = (config[:host] ||= "localhost")
13
+ port = (config[:port] ||= 3306)
14
+
15
+ # jdbc:mysql://[host][,failoverhost...][:port]/[database]
16
+ # - alternate fail-over syntax: [host:port],[host:port]/[database]
17
+ config[:url] ||= "jdbc:mysql://#{host}:#{port}/#{config[:database]}"
18
+
19
+ config[:properties] = build_properties(config)
20
+
21
+ config
22
+ end
23
+
24
+ private
25
+
26
+ def load_jdbc_driver
27
+ require "jdbc/mysql"
28
+
29
+ ::Jdbc::MySQL.load_driver(:require) if defined?(::Jdbc::MySQL.load_driver)
30
+ rescue LoadError
31
+ # assuming driver.jar is on the class-path
32
+ end
33
+
34
+ def database_driver_name
35
+ return ::Jdbc::MySQL.driver_name if defined?(::Jdbc::MySQL.driver_name)
36
+
37
+ "com.mysql.jdbc.Driver"
38
+ end
39
+
40
+ def build_properties(config)
41
+ properties = config[:properties] || {}
42
+
43
+ properties["zeroDateTimeBehavior"] ||= "CONVERT_TO_NULL"
44
+
45
+ properties["jdbcCompliantTruncation"] ||= false
46
+
47
+ charset_name = convert_mysql_encoding(config)
48
+
49
+ # do not set characterEncoding
50
+ if charset_name.eql?(false)
51
+ properties["character_set_server"] = config[:encoding] || "utf8"
52
+ else
53
+ properties["characterEncoding"] = charset_name
54
+ end
55
+
56
+ # driver also executes: "SET NAMES " + (useutf8mb4 ? "utf8mb4" : "utf8")
57
+ # thus no need to do it on configure_connection :
58
+ config[:encoding] = nil if config.key?(:encoding)
59
+
60
+ properties["connectionCollation"] ||= config[:collation] if config[:collation]
61
+
62
+ properties["autoReconnect"] ||= reconnect.to_s unless config[:reconnect].nil?
63
+
64
+ properties["noDatetimeStringSync"] = true unless properties.key?("noDatetimeStringSync")
65
+
66
+ sslcert = config[:sslcert]
67
+ sslca = config[:sslca]
68
+
69
+ if config[:sslkey] || sslcert
70
+ properties["useSSL"] ||= true
71
+ properties["requireSSL"] ||= true
72
+ properties["clientCertificateKeyStoreUrl"] ||= java.io.File.new(sslcert).to_url.to_s if sslcert
73
+
74
+ if sslca
75
+ properties["trustCertificateKeyStoreUrl"] ||= java.io.File.new(sslca).to_url.to_s
76
+ else
77
+ properties["verifyServerCertificate"] ||= false
78
+ end
79
+ else
80
+ # According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection
81
+ # must be established by default if explicit option isn't set :
82
+ properties["useSSL"] ||= false
83
+ end
84
+
85
+ # disables the effect of 'useTimezone'
86
+ properties["useLegacyDatetimeCode"] = false
87
+
88
+ properties
89
+ end
90
+
91
+ # See https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-charsets.html
92
+ # to charset-name (characterEncoding=...)
93
+ def convert_mysql_encoding(config)
94
+ # NOTE: this is "better" than passing what users are used to set on MRI
95
+ # e.g. 'utf8mb4' will fail cause the driver will check for a Java charset
96
+ # ... it's smart enough to detect utf8mb4 from server variables :
97
+ # "character_set_client" && "character_set_connection" (thus UTF-8)
98
+ encoding = config.key?(:encoding) ? config[:encoding] : "utf8"
99
+
100
+ value = MYSQL_ENCODINGS[encoding]
101
+
102
+ return false if value == false
103
+
104
+ value || encoding
105
+ end
106
+
107
+ MYSQL_ENCODINGS = {
108
+ "big5" => "Big5",
109
+ "dec8" => nil,
110
+ "hp8" => nil,
111
+ "latin1" => "Cp1252",
112
+ "latin2" => "ISO8859_2",
113
+ "swe7" => nil,
114
+ "ascii" => "US-ASCII",
115
+ "ujis" => "EUC_JP",
116
+ "sjis" => "SJIS",
117
+ "hebrew" => "ISO8859_8",
118
+ "tis620" => "TIS620",
119
+ "euckr" => "EUC_KR",
120
+ "gb2312" => "EUC_CN",
121
+ "greek" => "ISO8859_7",
122
+ "cp1250" => "Cp1250",
123
+ "gbk" => "GBK",
124
+ "armscii8" => nil,
125
+ "ucs2" => "UnicodeBig",
126
+ "cp866" => "Cp866",
127
+ "keybcs2" => nil,
128
+ "macce" => "MacCentralEurope",
129
+ "macroman" => "MacRoman",
130
+ "cp1251" => "Cp1251",
131
+ "cp1256" => "Cp1256",
132
+ "cp1257" => "Cp1257",
133
+ "binary" => false,
134
+ "geostd8" => nil,
135
+ "cp932" => "Cp932",
136
+ "utf8" => "UTF-8",
137
+ "utf8mb4" => false,
138
+ "utf16" => false,
139
+ "utf32" => false,
140
+ # "cp850" => "Cp850",
141
+ # "koi8r" => "KOI8-R",
142
+ # "koi8u" => "KOI8-R",
143
+ # "latin5" => "ISO-8859-9",
144
+ # "cp852" => "CP852",
145
+ # "latin7" => "ISO-8859-13",
146
+ # "eucjpms" => "eucJP-ms"
147
+ }.freeze
148
+ end
149
+ end
data/lib/arjdbc/mysql.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  require 'arjdbc'
2
2
  require 'arjdbc/mysql/adapter'
3
- require 'arjdbc/mysql/connection_methods'
3
+ # require 'arjdbc/mysql/connection_methods'
@@ -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
 
@@ -855,6 +856,7 @@ module ActiveRecord::ConnectionAdapters
855
856
  include ArJdbc::Abstract::StatementCache
856
857
  include ArJdbc::Abstract::TransactionSupport
857
858
  include ArJdbc::PostgreSQL
859
+ include ArJdbc::PostgreSQLConfig
858
860
 
859
861
  require 'arjdbc/postgresql/oid_types'
860
862
  include ::ArJdbc::PostgreSQL::OIDTypes
@@ -900,7 +902,8 @@ module ActiveRecord::ConnectionAdapters
900
902
  def initialize(...)
901
903
  super
902
904
 
903
- conn_params = @config.compact
905
+ # assign arjdbc extra connection params
906
+ conn_params = build_connection_config(@config.compact)
904
907
 
905
908
  @connection_parameters = conn_params
906
909
 
@@ -912,15 +915,6 @@ module ActiveRecord::ConnectionAdapters
912
915
  self.class.type_cast_config_to_boolean(@config[:insert_returning]) : true
913
916
  end
914
917
 
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
918
  require 'active_record/connection_adapters/postgresql/schema_definitions'
925
919
 
926
920
  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.native_database_types[base_type][:name]
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.alias_type "float8", "float4"
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"
@@ -1,3 +1,3 @@
1
1
  require 'arjdbc'
2
2
  require 'arjdbc/postgresql/adapter'
3
- require 'arjdbc/postgresql/connection_methods'
3
+ # require 'arjdbc/postgresql/connection_methods'
@@ -17,6 +17,7 @@ require "active_record/connection_adapters/sqlite3/schema_dumper"
17
17
  require "active_record/connection_adapters/sqlite3/schema_statements"
18
18
  require "active_support/core_ext/class/attribute"
19
19
  require "arjdbc/sqlite3/column"
20
+ require "arjdbc/sqlite3/adapter_hash_config"
20
21
 
21
22
  require "arjdbc/abstract/relation_query_attribute_monkey_patch"
22
23
 
@@ -63,13 +64,6 @@ module ArJdbc
63
64
  SchemaCreation = ConnectionAdapters::SQLite3::SchemaCreation
64
65
  SQLite3Adapter = ConnectionAdapters::AbstractAdapter
65
66
 
66
- ADAPTER_NAME = 'SQLite'
67
-
68
- # DIFFERENCE: FQN
69
- include ::ActiveRecord::ConnectionAdapters::SQLite3::Quoting
70
- include ::ActiveRecord::ConnectionAdapters::SQLite3::SchemaStatements
71
- include ::ActiveRecord::ConnectionAdapters::SQLite3::DatabaseStatements
72
-
73
67
  NATIVE_DATABASE_TYPES = {
74
68
  primary_key: "integer PRIMARY KEY AUTOINCREMENT NOT NULL",
75
69
  string: { name: "varchar" },
@@ -84,7 +78,7 @@ module ArJdbc
84
78
  boolean: { name: "boolean" },
85
79
  json: { name: "json" },
86
80
  }
87
-
81
+
88
82
  class StatementPool < ConnectionAdapters::StatementPool # :nodoc:
89
83
  private
90
84
  def dealloc(stmt)
@@ -729,13 +723,41 @@ module ActiveRecord::ConnectionAdapters
729
723
  # ActiveRecord::ConnectionAdapters::SQLite3Adapter. Once we can do that we can remove the
730
724
  # module SQLite3 above and remove a majority of this file.
731
725
  class SQLite3Adapter < AbstractAdapter
726
+ ADAPTER_NAME = "SQLite"
727
+
728
+ class << self
729
+ def new_client(conn_params, adapter_instance)
730
+ jdbc_connection_class.new(conn_params, adapter_instance)
731
+ end
732
+
733
+ def dbconsole(config, options = {})
734
+ args = []
735
+
736
+ args << "-#{options[:mode]}" if options[:mode]
737
+ args << "-header" if options[:header]
738
+ args << File.expand_path(config.database, const_defined?(:Rails) && Rails.respond_to?(:root) ? Rails.root : nil)
739
+
740
+ find_cmd_and_exec("sqlite3", *args)
741
+ end
742
+
743
+ def jdbc_connection_class
744
+ ::ActiveRecord::ConnectionAdapters::SQLite3JdbcConnection
745
+ end
746
+ end
747
+
732
748
  include ArJdbc::Abstract::Core
733
749
  include ArJdbc::SQLite3
750
+ include ArJdbc::SQLite3Config
751
+
734
752
  include ArJdbc::Abstract::ConnectionManagement
735
753
  include ArJdbc::Abstract::DatabaseStatements
736
754
  include ArJdbc::Abstract::StatementCache
737
755
  include ArJdbc::Abstract::TransactionSupport
738
756
 
757
+ include ::ActiveRecord::ConnectionAdapters::SQLite3::Quoting
758
+ include ::ActiveRecord::ConnectionAdapters::SQLite3::SchemaStatements
759
+ include ::ActiveRecord::ConnectionAdapters::SQLite3::DatabaseStatements
760
+
739
761
  ##
740
762
  # :singleton-method:
741
763
  # Configure the SQLite3Adapter to be used in a strict strings mode.
@@ -749,7 +771,8 @@ module ActiveRecord::ConnectionAdapters
749
771
  def initialize(...)
750
772
  super
751
773
 
752
- conn_params = @config.compact
774
+ # assign arjdbc extra connection params
775
+ conn_params = build_connection_config(@config.compact)
753
776
 
754
777
  # NOTE: strict strings is not supported by the jdbc driver yet,
755
778
  # hope it will supported soon, I open a issue in their repository.
@@ -820,24 +843,6 @@ module ActiveRecord::ConnectionAdapters
820
843
  ::ActiveRecord::Type.register(:integer, SQLite3Integer, adapter: :sqlite3)
821
844
 
822
845
  class << self
823
- def jdbc_connection_class
824
- ::ActiveRecord::ConnectionAdapters::SQLite3JdbcConnection
825
- end
826
-
827
- def new_client(conn_params, adapter_instance)
828
- jdbc_connection_class.new(conn_params, adapter_instance)
829
- end
830
-
831
- def dbconsole(config, options = {})
832
- args = []
833
-
834
- args << "-#{options[:mode]}" if options[:mode]
835
- args << "-header" if options[:header]
836
- args << File.expand_path(config.database, const_defined?(:Rails) && Rails.respond_to?(:root) ? Rails.root : nil)
837
-
838
- find_cmd_and_exec("sqlite3", *args)
839
- end
840
-
841
846
  private
842
847
  def initialize_type_map(m)
843
848
  super
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ArJdbc
4
+ module SQLite3Config
5
+ def build_connection_config(config)
6
+ config = config.deep_dup
7
+
8
+ load_jdbc_driver
9
+
10
+ config[:driver] ||= "org.sqlite.JDBC"
11
+
12
+ parse_sqlite3_config!(config)
13
+
14
+ database = config[:database]
15
+
16
+ # NOTE: "jdbc:sqlite::memory:" syntax is supported
17
+ config[:url] ||= "jdbc:sqlite:#{database == ':memory:' ? '' : database}"
18
+ config[:connection_alive_sql] ||= "SELECT 1"
19
+
20
+ config[:properties] = build_properties(config)
21
+
22
+ config
23
+ end
24
+
25
+ private
26
+
27
+ def load_jdbc_driver
28
+ require "jdbc/sqlite3"
29
+
30
+ ::Jdbc::SQLite3.load_driver(:require) if defined?(::Jdbc::SQLite3.load_driver)
31
+ rescue LoadError
32
+ # assuming driver.jar is on the class-path
33
+ end
34
+
35
+ def build_properties(config)
36
+ properties = config[:properties] || {}
37
+
38
+ if config[:readonly]
39
+ # See
40
+ # * http://sqlite.org/c3ref/open.html
41
+ # * http://sqlite.org/c3ref/c_open_autoproxy.html
42
+ # => 0x01 = readonly, 0x40 = uri (default in JDBC)
43
+ properties[:open_mode] =
44
+ ::SQLite3::Constants::Open::READONLY | ::SQLite3::Constants::Open::URI
45
+ end
46
+
47
+ if config[:flags]
48
+ properties[:open_mode] ||= 0
49
+ properties[:open_mode] |= config[:flags]
50
+
51
+ # JDBC driver has an extra flag for it
52
+ if config[:flags] & ::SQLite3::Constants::Open::SHAREDCACHE != 0
53
+ properties[:shared_cache] = true
54
+ end
55
+ end
56
+
57
+ timeout = config[:timeout]
58
+ if timeout && timeout.to_s !~ /\A\d+\Z/
59
+ raise ActiveRecord::StatementInvalid.new(
60
+ "TypeError: Timeout must be nil or a number (got: #{timeout}).",
61
+ connection_pool: ActiveRecord::ConnectionAdapters::NullPool.new
62
+ )
63
+ end
64
+
65
+ properties["busy_timeout"] ||= timeout unless timeout.nil?
66
+
67
+ properties
68
+ end
69
+
70
+ def parse_sqlite3_config!(config)
71
+ database = (config[:database] ||= config[:dbfile])
72
+
73
+ if database != ":memory:"
74
+ # make sure to have an absolute path. Ruby and Java don't agree
75
+ # on working directory
76
+ base_dir = defined?(Rails.root) ? Rails.root : nil
77
+ config[:database] = File.expand_path(database, base_dir)
78
+ dirname = File.dirname(config[:database])
79
+ Dir.mkdir(dirname) unless File.directory?(dirname)
80
+ end
81
+ rescue Errno::ENOENT => e
82
+ if e.message.include?("No such file or directory")
83
+ raise ActiveRecord::NoDatabaseError.new(
84
+ connection_pool: ActiveRecord::ConnectionAdapters::NullPool.new
85
+ )
86
+ end
87
+
88
+ raise
89
+ end
90
+ end
91
+ end
@@ -1,3 +1,3 @@
1
1
  require 'arjdbc'
2
2
  require 'arjdbc/sqlite3/adapter'
3
- require 'arjdbc/sqlite3/connection_methods'
3
+ # require 'arjdbc/sqlite3/connection_methods'
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ArJdbc
4
- VERSION = "71.0.0"
4
+ VERSION = "72.0.0.alpha1"
5
5
  end
data/lib/arjdbc.rb CHANGED
@@ -12,8 +12,14 @@ if defined?(JRUBY_VERSION)
12
12
  rescue LoadError => e
13
13
  warn "activerecord-jdbc-adapter failed to load railtie: #{e.inspect}"
14
14
  end if defined?(Rails) && ActiveRecord::VERSION::MAJOR >= 3
15
+
16
+ ActiveSupport.on_load(:active_record) do
17
+ ActiveRecord::ConnectionAdapters.register(
18
+ "sqlserver", "ActiveRecord::ConnectionAdapters::MSSQLAdapter", "active_record/connection_adapters/mssql_adapter"
19
+ )
20
+ end
15
21
  else
16
22
  warn "activerecord-jdbc-adapter is for use with JRuby only"
17
23
  end
18
24
 
19
- require 'arjdbc/version'
25
+ require 'arjdbc/version'
metadata CHANGED
@@ -1,21 +1,21 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-jdbc-alt-adapter
3
3
  version: !ruby/object:Gem::Version
4
- version: 71.0.0
4
+ version: 72.0.0.alpha1
5
5
  platform: java
6
6
  authors:
7
7
  - Nick Sieger, Ola Bini, Karol Bucek, Jesse Chavez, and JRuby contributors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-01-26 00:00:00.000000000 Z
11
+ date: 2025-01-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: 7.1.3
18
+ version: 7.2.2
19
19
  name: activerecord
20
20
  type: :runtime
21
21
  prerelease: false
@@ -23,7 +23,7 @@ dependencies:
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 7.1.3
26
+ version: 7.2.2
27
27
  description: 'Fork of the ActiveRecord JDBC adapter with support for SQL Server and
28
28
  Azure SQL, for more information and help look at the README file in the github repository.
29
29
  AR-JDBC is a database adapter for Rails'' ActiveRecord component designed to be
@@ -110,6 +110,7 @@ files:
110
110
  - lib/arjdbc/jdbc/type_converter.rb
111
111
  - lib/arjdbc/mssql.rb
112
112
  - lib/arjdbc/mssql/adapter.rb
113
+ - lib/arjdbc/mssql/adapter_hash_config.rb
113
114
  - lib/arjdbc/mssql/column.rb
114
115
  - lib/arjdbc/mssql/connection_methods.rb
115
116
  - lib/arjdbc/mssql/database_limits.rb
@@ -134,10 +135,12 @@ files:
134
135
  - lib/arjdbc/mssql/utils.rb
135
136
  - lib/arjdbc/mysql.rb
136
137
  - lib/arjdbc/mysql/adapter.rb
138
+ - lib/arjdbc/mysql/adapter_hash_config.rb
137
139
  - lib/arjdbc/mysql/connection_methods.rb
138
140
  - lib/arjdbc/oracle/adapter.rb
139
141
  - lib/arjdbc/postgresql.rb
140
142
  - lib/arjdbc/postgresql/adapter.rb
143
+ - lib/arjdbc/postgresql/adapter_hash_config.rb
141
144
  - lib/arjdbc/postgresql/base/array_decoder.rb
142
145
  - lib/arjdbc/postgresql/base/array_encoder.rb
143
146
  - lib/arjdbc/postgresql/base/array_parser.rb
@@ -151,6 +154,7 @@ files:
151
154
  - lib/arjdbc/railtie.rb
152
155
  - lib/arjdbc/sqlite3.rb
153
156
  - lib/arjdbc/sqlite3/adapter.rb
157
+ - lib/arjdbc/sqlite3/adapter_hash_config.rb
154
158
  - lib/arjdbc/sqlite3/column.rb
155
159
  - lib/arjdbc/sqlite3/connection_methods.rb
156
160
  - lib/arjdbc/tasks.rb
@@ -231,9 +235,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
231
235
  version: '0'
232
236
  required_rubygems_version: !ruby/object:Gem::Requirement
233
237
  requirements:
234
- - - ">="
238
+ - - ">"
235
239
  - !ruby/object:Gem::Version
236
- version: '0'
240
+ version: 1.3.1
237
241
  requirements: []
238
242
  rubygems_version: 3.3.26
239
243
  signing_key: