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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/activerecord-jdbc-adapter.gemspec +1 -1
  4. data/activerecord-jdbc-alt-adapter.gemspec +1 -1
  5. data/lib/arel/visitors/sqlserver.rb +13 -9
  6. data/lib/arjdbc/abstract/core.rb +10 -1
  7. data/lib/arjdbc/abstract/database_statements.rb +1 -1
  8. data/lib/arjdbc/abstract/transaction_support.rb +3 -1
  9. data/lib/arjdbc/jdbc/adapter.rb +0 -1
  10. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  11. data/lib/arjdbc/mssql/adapter.rb +18 -15
  12. data/lib/arjdbc/mssql/adapter_hash_config.rb +53 -0
  13. data/lib/arjdbc/mssql/column.rb +16 -7
  14. data/lib/arjdbc/mssql/database_statements.rb +7 -2
  15. data/lib/arjdbc/mssql/quoting.rb +56 -36
  16. data/lib/arjdbc/mssql/schema_creation.rb +16 -0
  17. data/lib/arjdbc/mssql/schema_statements.rb +44 -19
  18. data/lib/arjdbc/mssql.rb +1 -1
  19. data/lib/arjdbc/mysql/adapter.rb +8 -11
  20. data/lib/arjdbc/mysql/adapter_hash_config.rb +159 -0
  21. data/lib/arjdbc/mysql.rb +1 -1
  22. data/lib/arjdbc/postgresql/adapter.rb +17 -11
  23. data/lib/arjdbc/postgresql/adapter_hash_config.rb +98 -0
  24. data/lib/arjdbc/postgresql/base/array_encoder.rb +3 -1
  25. data/lib/arjdbc/postgresql/oid_types.rb +2 -2
  26. data/lib/arjdbc/postgresql.rb +1 -1
  27. data/lib/arjdbc/sqlite3/adapter.rb +193 -90
  28. data/lib/arjdbc/sqlite3/adapter_hash_config.rb +91 -0
  29. data/lib/arjdbc/sqlite3/column.rb +17 -3
  30. data/lib/arjdbc/sqlite3/pragmas.rb +105 -0
  31. data/lib/arjdbc/sqlite3.rb +1 -1
  32. data/lib/arjdbc/version.rb +1 -1
  33. data/lib/arjdbc.rb +16 -1
  34. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +5 -0
  35. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +12 -2
  36. metadata +12 -8
  37. 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
@@ -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
 
@@ -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
- string_agg(enum.enumlabel, ',' ORDER BY enum.enumsortorder) AS value
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
- conn_params = @config.compact
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.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'