activerecord-jdbc-alt-adapter 50.3.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.
Files changed (198) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +35 -0
  3. data/.travis.yml +100 -0
  4. data/.yardopts +4 -0
  5. data/CONTRIBUTING.md +50 -0
  6. data/Gemfile +92 -0
  7. data/History.md +1191 -0
  8. data/LICENSE.txt +26 -0
  9. data/README.md +240 -0
  10. data/RUNNING_TESTS.md +127 -0
  11. data/Rakefile +336 -0
  12. data/Rakefile.jdbc +20 -0
  13. data/activerecord-jdbc-adapter.gemspec +55 -0
  14. data/activerecord-jdbc-alt-adapter.gemspec +56 -0
  15. data/lib/active_record/connection_adapters/as400_adapter.rb +2 -0
  16. data/lib/active_record/connection_adapters/db2_adapter.rb +1 -0
  17. data/lib/active_record/connection_adapters/derby_adapter.rb +1 -0
  18. data/lib/active_record/connection_adapters/firebird_adapter.rb +1 -0
  19. data/lib/active_record/connection_adapters/h2_adapter.rb +1 -0
  20. data/lib/active_record/connection_adapters/hsqldb_adapter.rb +1 -0
  21. data/lib/active_record/connection_adapters/informix_adapter.rb +1 -0
  22. data/lib/active_record/connection_adapters/jdbc_adapter.rb +1 -0
  23. data/lib/active_record/connection_adapters/jndi_adapter.rb +1 -0
  24. data/lib/active_record/connection_adapters/mariadb_adapter.rb +1 -0
  25. data/lib/active_record/connection_adapters/mssql_adapter.rb +1 -0
  26. data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -0
  27. data/lib/active_record/connection_adapters/mysql_adapter.rb +1 -0
  28. data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -0
  29. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -0
  30. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +1 -0
  31. data/lib/activerecord-jdbc-adapter.rb +1 -0
  32. data/lib/arel/visitors/compat.rb +60 -0
  33. data/lib/arel/visitors/db2.rb +137 -0
  34. data/lib/arel/visitors/derby.rb +112 -0
  35. data/lib/arel/visitors/firebird.rb +79 -0
  36. data/lib/arel/visitors/h2.rb +25 -0
  37. data/lib/arel/visitors/hsqldb.rb +32 -0
  38. data/lib/arel/visitors/postgresql_jdbc.rb +6 -0
  39. data/lib/arel/visitors/sql_server.rb +225 -0
  40. data/lib/arel/visitors/sql_server/ng42.rb +294 -0
  41. data/lib/arel/visitors/sqlserver.rb +214 -0
  42. data/lib/arjdbc.rb +19 -0
  43. data/lib/arjdbc/abstract/connection_management.rb +35 -0
  44. data/lib/arjdbc/abstract/core.rb +74 -0
  45. data/lib/arjdbc/abstract/database_statements.rb +64 -0
  46. data/lib/arjdbc/abstract/statement_cache.rb +58 -0
  47. data/lib/arjdbc/abstract/transaction_support.rb +86 -0
  48. data/lib/arjdbc/db2.rb +4 -0
  49. data/lib/arjdbc/db2/adapter.rb +789 -0
  50. data/lib/arjdbc/db2/as400.rb +130 -0
  51. data/lib/arjdbc/db2/column.rb +167 -0
  52. data/lib/arjdbc/db2/connection_methods.rb +44 -0
  53. data/lib/arjdbc/derby.rb +3 -0
  54. data/lib/arjdbc/derby/active_record_patch.rb +13 -0
  55. data/lib/arjdbc/derby/adapter.rb +540 -0
  56. data/lib/arjdbc/derby/connection_methods.rb +20 -0
  57. data/lib/arjdbc/derby/schema_creation.rb +15 -0
  58. data/lib/arjdbc/discover.rb +104 -0
  59. data/lib/arjdbc/firebird.rb +4 -0
  60. data/lib/arjdbc/firebird/adapter.rb +434 -0
  61. data/lib/arjdbc/firebird/connection_methods.rb +23 -0
  62. data/lib/arjdbc/h2.rb +3 -0
  63. data/lib/arjdbc/h2/adapter.rb +303 -0
  64. data/lib/arjdbc/h2/connection_methods.rb +27 -0
  65. data/lib/arjdbc/hsqldb.rb +3 -0
  66. data/lib/arjdbc/hsqldb/adapter.rb +297 -0
  67. data/lib/arjdbc/hsqldb/connection_methods.rb +28 -0
  68. data/lib/arjdbc/hsqldb/explain_support.rb +35 -0
  69. data/lib/arjdbc/hsqldb/schema_creation.rb +11 -0
  70. data/lib/arjdbc/informix.rb +5 -0
  71. data/lib/arjdbc/informix/adapter.rb +162 -0
  72. data/lib/arjdbc/informix/connection_methods.rb +9 -0
  73. data/lib/arjdbc/jdbc.rb +59 -0
  74. data/lib/arjdbc/jdbc/adapter.rb +475 -0
  75. data/lib/arjdbc/jdbc/adapter_require.rb +46 -0
  76. data/lib/arjdbc/jdbc/base_ext.rb +15 -0
  77. data/lib/arjdbc/jdbc/callbacks.rb +53 -0
  78. data/lib/arjdbc/jdbc/column.rb +97 -0
  79. data/lib/arjdbc/jdbc/connection.rb +14 -0
  80. data/lib/arjdbc/jdbc/connection_methods.rb +37 -0
  81. data/lib/arjdbc/jdbc/error.rb +65 -0
  82. data/lib/arjdbc/jdbc/extension.rb +59 -0
  83. data/lib/arjdbc/jdbc/java.rb +13 -0
  84. data/lib/arjdbc/jdbc/railtie.rb +2 -0
  85. data/lib/arjdbc/jdbc/rake_tasks.rb +3 -0
  86. data/lib/arjdbc/jdbc/serialized_attributes_helper.rb +3 -0
  87. data/lib/arjdbc/jdbc/type_cast.rb +166 -0
  88. data/lib/arjdbc/jdbc/type_converter.rb +142 -0
  89. data/lib/arjdbc/mssql.rb +7 -0
  90. data/lib/arjdbc/mssql/adapter.rb +384 -0
  91. data/lib/arjdbc/mssql/column.rb +29 -0
  92. data/lib/arjdbc/mssql/connection_methods.rb +79 -0
  93. data/lib/arjdbc/mssql/database_statements.rb +134 -0
  94. data/lib/arjdbc/mssql/errors.rb +6 -0
  95. data/lib/arjdbc/mssql/explain_support.rb +129 -0
  96. data/lib/arjdbc/mssql/extensions.rb +36 -0
  97. data/lib/arjdbc/mssql/limit_helpers.rb +231 -0
  98. data/lib/arjdbc/mssql/lock_methods.rb +77 -0
  99. data/lib/arjdbc/mssql/old_adapter.rb +804 -0
  100. data/lib/arjdbc/mssql/old_column.rb +200 -0
  101. data/lib/arjdbc/mssql/quoting.rb +101 -0
  102. data/lib/arjdbc/mssql/schema_creation.rb +31 -0
  103. data/lib/arjdbc/mssql/schema_definitions.rb +74 -0
  104. data/lib/arjdbc/mssql/schema_statements.rb +329 -0
  105. data/lib/arjdbc/mssql/transaction.rb +69 -0
  106. data/lib/arjdbc/mssql/types.rb +52 -0
  107. data/lib/arjdbc/mssql/types/binary_types.rb +33 -0
  108. data/lib/arjdbc/mssql/types/date_and_time_types.rb +134 -0
  109. data/lib/arjdbc/mssql/types/deprecated_types.rb +40 -0
  110. data/lib/arjdbc/mssql/types/numeric_types.rb +71 -0
  111. data/lib/arjdbc/mssql/types/string_types.rb +56 -0
  112. data/lib/arjdbc/mssql/utils.rb +66 -0
  113. data/lib/arjdbc/mysql.rb +3 -0
  114. data/lib/arjdbc/mysql/adapter.rb +140 -0
  115. data/lib/arjdbc/mysql/connection_methods.rb +166 -0
  116. data/lib/arjdbc/oracle/adapter.rb +863 -0
  117. data/lib/arjdbc/postgresql.rb +3 -0
  118. data/lib/arjdbc/postgresql/adapter.rb +687 -0
  119. data/lib/arjdbc/postgresql/base/array_decoder.rb +26 -0
  120. data/lib/arjdbc/postgresql/base/array_encoder.rb +25 -0
  121. data/lib/arjdbc/postgresql/base/array_parser.rb +95 -0
  122. data/lib/arjdbc/postgresql/base/pgconn.rb +11 -0
  123. data/lib/arjdbc/postgresql/column.rb +51 -0
  124. data/lib/arjdbc/postgresql/connection_methods.rb +67 -0
  125. data/lib/arjdbc/postgresql/name.rb +24 -0
  126. data/lib/arjdbc/postgresql/oid_types.rb +266 -0
  127. data/lib/arjdbc/railtie.rb +11 -0
  128. data/lib/arjdbc/sqlite3.rb +3 -0
  129. data/lib/arjdbc/sqlite3/adapter.rb +678 -0
  130. data/lib/arjdbc/sqlite3/connection_methods.rb +59 -0
  131. data/lib/arjdbc/sybase.rb +2 -0
  132. data/lib/arjdbc/sybase/adapter.rb +47 -0
  133. data/lib/arjdbc/tasks.rb +13 -0
  134. data/lib/arjdbc/tasks/database_tasks.rb +31 -0
  135. data/lib/arjdbc/tasks/databases.rake +48 -0
  136. data/lib/arjdbc/tasks/db2_database_tasks.rb +104 -0
  137. data/lib/arjdbc/tasks/derby_database_tasks.rb +95 -0
  138. data/lib/arjdbc/tasks/h2_database_tasks.rb +31 -0
  139. data/lib/arjdbc/tasks/hsqldb_database_tasks.rb +70 -0
  140. data/lib/arjdbc/tasks/jdbc_database_tasks.rb +169 -0
  141. data/lib/arjdbc/tasks/mssql_database_tasks.rb +46 -0
  142. data/lib/arjdbc/util/quoted_cache.rb +60 -0
  143. data/lib/arjdbc/util/serialized_attributes.rb +98 -0
  144. data/lib/arjdbc/util/table_copier.rb +110 -0
  145. data/lib/arjdbc/version.rb +3 -0
  146. data/lib/generators/jdbc/USAGE +9 -0
  147. data/lib/generators/jdbc/jdbc_generator.rb +17 -0
  148. data/lib/jdbc_adapter.rb +2 -0
  149. data/lib/jdbc_adapter/rake_tasks.rb +4 -0
  150. data/lib/jdbc_adapter/version.rb +4 -0
  151. data/pom.xml +114 -0
  152. data/rails_generators/jdbc_generator.rb +15 -0
  153. data/rails_generators/templates/config/initializers/jdbc.rb +10 -0
  154. data/rails_generators/templates/lib/tasks/jdbc.rake +11 -0
  155. data/rakelib/01-tomcat.rake +51 -0
  156. data/rakelib/02-test.rake +132 -0
  157. data/rakelib/bundler_ext.rb +11 -0
  158. data/rakelib/db.rake +75 -0
  159. data/rakelib/rails.rake +223 -0
  160. data/src/java/arjdbc/ArJdbcModule.java +276 -0
  161. data/src/java/arjdbc/db2/DB2Module.java +76 -0
  162. data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +126 -0
  163. data/src/java/arjdbc/derby/DerbyModule.java +178 -0
  164. data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +152 -0
  165. data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +174 -0
  166. data/src/java/arjdbc/h2/H2Module.java +50 -0
  167. data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +85 -0
  168. data/src/java/arjdbc/hsqldb/HSQLDBModule.java +73 -0
  169. data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +75 -0
  170. data/src/java/arjdbc/jdbc/AdapterJavaService.java +43 -0
  171. data/src/java/arjdbc/jdbc/Callable.java +44 -0
  172. data/src/java/arjdbc/jdbc/ConnectionFactory.java +45 -0
  173. data/src/java/arjdbc/jdbc/DataSourceConnectionFactory.java +156 -0
  174. data/src/java/arjdbc/jdbc/DriverConnectionFactory.java +63 -0
  175. data/src/java/arjdbc/jdbc/DriverWrapper.java +119 -0
  176. data/src/java/arjdbc/jdbc/JdbcResult.java +130 -0
  177. data/src/java/arjdbc/jdbc/RubyConnectionFactory.java +61 -0
  178. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +3979 -0
  179. data/src/java/arjdbc/mssql/MSSQLModule.java +90 -0
  180. data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +508 -0
  181. data/src/java/arjdbc/mysql/MySQLModule.java +152 -0
  182. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +294 -0
  183. data/src/java/arjdbc/oracle/OracleModule.java +80 -0
  184. data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +455 -0
  185. data/src/java/arjdbc/postgresql/ByteaUtils.java +157 -0
  186. data/src/java/arjdbc/postgresql/PgDateTimeUtils.java +52 -0
  187. data/src/java/arjdbc/postgresql/PostgreSQLModule.java +77 -0
  188. data/src/java/arjdbc/postgresql/PostgreSQLResult.java +192 -0
  189. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +948 -0
  190. data/src/java/arjdbc/sqlite3/SQLite3Module.java +73 -0
  191. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +525 -0
  192. data/src/java/arjdbc/util/CallResultSet.java +826 -0
  193. data/src/java/arjdbc/util/DateTimeUtils.java +699 -0
  194. data/src/java/arjdbc/util/ObjectSupport.java +65 -0
  195. data/src/java/arjdbc/util/QuotingUtils.java +137 -0
  196. data/src/java/arjdbc/util/StringCache.java +63 -0
  197. data/src/java/arjdbc/util/StringHelper.java +145 -0
  198. metadata +269 -0
@@ -0,0 +1,26 @@
1
+ # This implements a basic decoder to work around ActiveRecord's dependence on the pg gem
2
+ module ActiveRecord::ConnectionAdapters::PostgreSQL::OID
3
+ class Array < ActiveModel::Type::Value
4
+ module PG
5
+ module TextDecoder
6
+ class Array
7
+ # Loads pg_array_parser if available. String parsing can be
8
+ # performed quicker by a native extension, which will not create
9
+ # a large amount of Ruby objects that will need to be garbage
10
+ # collected. pg_array_parser has a C and Java extension
11
+ begin
12
+ require 'pg_array_parser'
13
+ include PgArrayParser
14
+ rescue LoadError
15
+ require_relative 'array_parser'
16
+ include ActiveRecord::ConnectionAdapters::PostgreSQL::ArrayParser
17
+ end
18
+
19
+ def initialize(name:, delimiter:); end
20
+
21
+ alias_method :decode, :parse_pg_array
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,25 @@
1
+ # This implements a basic encoder to work around ActiveRecord's dependence on the pg gem
2
+ module ActiveRecord::ConnectionAdapters::PostgreSQL::OID
3
+ class Array < ActiveModel::Type::Value
4
+ module PG
5
+ module TextEncoder
6
+ class Array
7
+
8
+ def initialize(name:, delimiter:)
9
+ @type = if name == 'string[]'.freeze
10
+ 'text'.freeze
11
+ else
12
+ base_type = name.chomp('[]'.freeze).to_sym
13
+ ActiveRecord::Base.connection.native_database_types[base_type][:name]
14
+ end
15
+ end
16
+
17
+ def encode(values)
18
+ ActiveRecord::Base.connection.jdbc_connection.create_array_of(@type, values.to_java).to_s
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,95 @@
1
+ # based on active_record/connection_adapters/postgresql/array_parser.rb
2
+ # until it's some day shareable with Rails ... this is not public API !
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module PostgreSQL
6
+ module ArrayParser
7
+
8
+ DOUBLE_QUOTE = '"'
9
+ BACKSLASH = "\\"
10
+ COMMA = ','
11
+ BRACKET_OPEN = '{'
12
+ BRACKET_CLOSE = '}'
13
+
14
+ def parse_pg_array(string)
15
+ local_index = 0
16
+ array = []
17
+ while(local_index < string.length)
18
+ case string[local_index]
19
+ when BRACKET_OPEN
20
+ local_index,array = parse_array_contents(array, string, local_index + 1)
21
+ when BRACKET_CLOSE
22
+ return array
23
+ end
24
+ local_index += 1
25
+ end
26
+
27
+ array
28
+ end
29
+
30
+ private
31
+
32
+ def parse_array_contents(array, string, index)
33
+ is_escaping = false
34
+ is_quoted = false
35
+ was_quoted = false
36
+ current_item = ''
37
+
38
+ local_index = index
39
+ while local_index
40
+ token = string[local_index]
41
+ if is_escaping
42
+ current_item << token
43
+ is_escaping = false
44
+ else
45
+ if is_quoted
46
+ case token
47
+ when DOUBLE_QUOTE
48
+ is_quoted = false
49
+ was_quoted = true
50
+ when BACKSLASH
51
+ is_escaping = true
52
+ else
53
+ current_item << token
54
+ end
55
+ else
56
+ case token
57
+ when BACKSLASH
58
+ is_escaping = true
59
+ when COMMA
60
+ add_item_to_array(array, current_item, was_quoted)
61
+ current_item = ''
62
+ was_quoted = false
63
+ when DOUBLE_QUOTE
64
+ is_quoted = true
65
+ when BRACKET_OPEN
66
+ internal_items = []
67
+ local_index,internal_items = parse_array_contents(internal_items, string, local_index + 1)
68
+ array.push(internal_items)
69
+ when BRACKET_CLOSE
70
+ add_item_to_array(array, current_item, was_quoted)
71
+ return local_index,array
72
+ else
73
+ current_item << token
74
+ end
75
+ end
76
+ end
77
+
78
+ local_index += 1
79
+ end
80
+ return local_index,array
81
+ end
82
+
83
+ def add_item_to_array(array, current_item, quoted)
84
+ return if !quoted && current_item.length == 0
85
+
86
+ if !quoted && current_item == 'NULL'
87
+ array.push nil
88
+ else
89
+ array.push current_item
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,11 @@
1
+ module ActiveRecord::ConnectionAdapters::PostgreSQL::OID
2
+ class Bytea < ActiveModel::Type::Binary
3
+ module PG
4
+ class Connection # emulate PG::Connection#unescape_bytea due #652
5
+ def self.unescape_bytea(escaped)
6
+ ArJdbc::PostgreSQL.unescape_bytea(escaped)
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,51 @@
1
+ module ArJdbc
2
+ module PostgreSQL
3
+
4
+ # @private these are defined on the Adapter class since 4.2
5
+ module ColumnHelpers
6
+
7
+ def extract_limit(sql_type) # :nodoc:
8
+ case sql_type
9
+ when /^bigint/i, /^int8/i then 8
10
+ when /^smallint/i then 2
11
+ when /^timestamp/i then nil
12
+ else
13
+ super
14
+ end
15
+ end
16
+
17
+ # Extracts the value from a PostgreSQL column default definition.
18
+ def extract_value_from_default(default) # :nodoc:
19
+ case default
20
+ # Quoted types
21
+ when /\A[\(B]?'(.*)'.*::"?([\w. ]+)"?(?:\[\])?\z/m
22
+ # The default 'now'::date is CURRENT_DATE
23
+ if $1 == "now".freeze && $2 == "date".freeze
24
+ nil
25
+ else
26
+ $1.gsub("''".freeze, "'".freeze)
27
+ end
28
+ # Boolean types
29
+ when 'true'.freeze, 'false'.freeze
30
+ default
31
+ # Numeric types
32
+ when /\A\(?(-?\d+(\.\d*)?)\)?(::bigint)?\z/
33
+ $1
34
+ # Object identifier types
35
+ when /\A-?\d+\z/
36
+ $1
37
+ else
38
+ # Anything else is blank, some user type, or some function
39
+ # and we can't know the value of that, so return nil.
40
+ nil
41
+ end
42
+ end
43
+
44
+ def extract_default_function(default_value, default) # :nodoc:
45
+ default if ! default_value && ( %r{\w+\(.*\)|\(.*\)::\w+} === default )
46
+ end
47
+
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+ ArJdbc::ConnectionMethods.module_eval do
3
+ def postgresql_connection(config)
4
+ # NOTE: this isn't "really" necessary but Rails (in tests) assumes being able to :
5
+ # ActiveRecord::Base.postgresql_connection ActiveRecord::Base.configurations['arunit'].merge(:insert_returning => false)
6
+ # ... while using symbols by default but than configurations returning string keys ;(
7
+ config = symbolize_keys_if_necessary(config)
8
+
9
+ config[:adapter_spec] ||= ::ArJdbc::PostgreSQL
10
+ config[:adapter_class] = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter unless config.key?(:adapter_class)
11
+
12
+ return jndi_connection(config) if jndi_config?(config)
13
+
14
+ begin
15
+ require 'jdbc/postgres'
16
+ ::Jdbc::Postgres.load_driver(:require) if defined?(::Jdbc::Postgres.load_driver)
17
+ rescue LoadError # assuming driver.jar is on the class-path
18
+ end
19
+ driver = config[:driver] ||= 'org.postgresql.Driver'
20
+
21
+ host = config[:host] ||= ( config[:hostaddr] || ENV['PGHOST'] || 'localhost' )
22
+ port = config[:port] ||= ( ENV['PGPORT'] || 5432 )
23
+ database = config[:database] || config[:dbname] || ENV['PGDATABASE']
24
+
25
+ config[:url] ||= "jdbc:postgresql://#{host}:#{port}/#{database}"
26
+ config[:url] << config[:pg_params] if config[:pg_params]
27
+
28
+ config[:username] ||= ( config[:user] || ENV['PGUSER'] || ENV_JAVA['user.name'] )
29
+ config[:password] ||= ENV['PGPASSWORD'] unless config.key?(:password)
30
+ properties = ( config[:properties] ||= {} )
31
+ # PG :connect_timeout - maximum time to wait for connection to succeed
32
+ if connect_timeout = ( config[:connect_timeout] || ENV['PGCONNECT_TIMEOUT'] )
33
+ properties['socketTimeout'] ||= connect_timeout
34
+ end
35
+ if login_timeout = config[:login_timeout]
36
+ properties['loginTimeout'] ||= login_timeout
37
+ end
38
+ sslmode = config.key?(:sslmode) ? config[:sslmode] : config[:requiressl]
39
+ # NOTE: makes not much sense since this needs some JVM options :
40
+ sslmode = ENV['PGSSLMODE'] || ENV['PGREQUIRESSL'] if sslmode.nil?
41
+ unless sslmode.nil? # PG :sslmode - disable|allow|prefer|require
42
+ # JRuby/JVM needs to be started with :
43
+ # -Djavax.net.ssl.trustStore=mystore -Djavax.net.ssl.trustStorePassword=...
44
+ # or a non-validating connection might be used (for testing) :
45
+ # :sslfactory = 'org.postgresql.ssl.NonValidatingFactory'
46
+ if sslmode == true || sslmode.to_s == 'require'
47
+ properties['sslfactory'] ||= 'org.postgresql.ssl.NonValidatingFactory' if driver.start_with?('org.postgresql.')
48
+ properties['ssl'] ||= 'true'
49
+ end
50
+ end
51
+ properties['tcpKeepAlive'] ||= config[:keepalives] if config.key?(:keepalives)
52
+ properties['kerberosServerName'] ||= config[:krbsrvname] if config[:krbsrvname]
53
+
54
+ prepared_statements = config.fetch(:prepared_statements) { true }
55
+ prepared_statements = false if prepared_statements == 'false'
56
+ if prepared_statements
57
+ # this makes the pgjdbc driver handle hot compatibility internally
58
+ properties['autosave'] ||= 'conservative'
59
+ else
60
+ # If prepared statements are off, lets make sure they are really *off*
61
+ properties['prepareThreshold'] = 0
62
+ end
63
+
64
+ jdbc_connection(config)
65
+ end
66
+ alias_method :jdbcpostgresql_connection, :postgresql_connection
67
+ end
@@ -0,0 +1,24 @@
1
+ # This patches the Name class so that it doesn't use pg gem specific quoting
2
+ module ActiveRecord
3
+ module ConnectionAdapters
4
+ module PostgreSQL
5
+ class Name
6
+
7
+ def quoted
8
+ if schema
9
+ "#{quote_identifier(schema)}#{SEPARATOR}#{quote_identifier(identifier)}"
10
+ else
11
+ quote_identifier(identifier)
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def quote_identifier(name)
18
+ %("#{name.to_s.gsub("\"", "\"\"")}")
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,266 @@
1
+ require 'thread'
2
+
3
+ module ArJdbc
4
+ module PostgreSQL
5
+
6
+ require 'active_record/connection_adapters/postgresql/oid'
7
+ require 'arjdbc/postgresql/base/pgconn'
8
+
9
+ # @private
10
+ OID = ::ActiveRecord::ConnectionAdapters::PostgreSQL::OID
11
+
12
+ # this version makes sure to register the types by name as well
13
+ # we still need to version with OID since it's used from SchemaStatements as well
14
+ class ArjdbcTypeMapInitializer < OID::TypeMapInitializer
15
+ private
16
+
17
+ def name_with_ns(row)
18
+ if row['in_ns']
19
+ row['typname']
20
+ else
21
+ %Q("#{row['nspname']}"."#{row['typname']}")
22
+ end
23
+ end
24
+
25
+ def register_enum_type(row)
26
+ super
27
+ register name_with_ns(row), OID::Enum.new
28
+ end
29
+
30
+ def register_array_type(row)
31
+ super
32
+ register_with_subtype(name_with_ns(row), row['typelem'].to_i) do |subtype|
33
+ OID::Array.new(subtype, row['typdelim'])
34
+ end
35
+ end
36
+
37
+ def register_range_type(row)
38
+ super
39
+ name = name_with_ns(row)
40
+ register_with_subtype(name, row['rngsubtype'].to_i) do |subtype|
41
+ OID::Range.new(subtype, name.to_sym)
42
+ end
43
+ end
44
+
45
+ def register_domain_type(row)
46
+ if base_type = @store.lookup(row['typbasetype'].to_i)
47
+ register row['oid'], base_type
48
+ register name_with_ns(row), base_type
49
+ else
50
+ warn "unknown base type (OID: #{row['typbasetype']}) for domain #{row['typname']}."
51
+ end
52
+ end
53
+
54
+ def register_composite_type(row)
55
+ if subtype = @store.lookup(row['typelem'].to_i)
56
+ register row['oid'], OID::Vector.new(row['typdelim'], subtype)
57
+ register name_with_ns(row), OID::Vector.new(row['typdelim'], subtype)
58
+ end
59
+ end
60
+
61
+ def assert_valid_registration(oid, oid_type)
62
+ ret = super
63
+ ret == 0 ? oid : ret
64
+ end
65
+ end
66
+
67
+ # @private
68
+ module OIDTypes
69
+
70
+ # @override
71
+ def enable_extension(name)
72
+ result = super(name)
73
+ @extensions = nil
74
+ reload_type_map
75
+ result
76
+ end
77
+
78
+ # @override
79
+ def disable_extension(name)
80
+ result = super(name)
81
+ @extensions = nil
82
+ reload_type_map
83
+ result
84
+ end
85
+
86
+ # @override
87
+ def extensions
88
+ @extensions ||= super
89
+ end
90
+
91
+ # @override
92
+ def lookup_cast_type(sql_type)
93
+ oid = execute("SELECT #{quote(sql_type)}::regtype::oid", "SCHEMA")
94
+ super oid.first['oid'].to_i
95
+ end
96
+
97
+ def get_oid_type(oid, fmod, column_name, sql_type = '') # :nodoc:
98
+ if !type_map.key?(oid)
99
+ load_additional_types(type_map, oid)
100
+ end
101
+
102
+ type_map.fetch(oid, fmod, sql_type) {
103
+ warn "unknown OID #{oid}: failed to recognize type of '#{column_name}'. It will be treated as String."
104
+ Type::Value.new.tap do |cast_type|
105
+ type_map.register_type(oid, cast_type)
106
+ end
107
+ }
108
+ end
109
+
110
+ def type_map
111
+ @type_map
112
+ end
113
+
114
+ def reload_type_map
115
+ if ( @type_map ||= nil )
116
+ @type_map.clear
117
+ initialize_type_map(@type_map)
118
+ end
119
+ end
120
+
121
+ private
122
+
123
+ def initialize_type_map(m)
124
+ register_class_with_limit m, 'int2', Type::Integer
125
+ register_class_with_limit m, 'int4', Type::Integer
126
+ register_class_with_limit m, 'int8', Type::Integer
127
+ m.alias_type 'oid', 'int2'
128
+ m.register_type 'float4', Type::Float.new
129
+ m.alias_type 'float8', 'float4'
130
+ m.register_type 'text', Type::Text.new
131
+ register_class_with_limit m, 'varchar', Type::String
132
+ m.alias_type 'char', 'varchar'
133
+ m.alias_type 'name', 'varchar'
134
+ m.alias_type 'bpchar', 'varchar'
135
+ m.register_type 'bool', Type::Boolean.new
136
+ register_class_with_limit m, 'bit', OID::Bit
137
+ register_class_with_limit m, 'varbit', OID::BitVarying
138
+ m.alias_type 'timestamptz', 'timestamp'
139
+ m.register_type 'date', Type::Date.new
140
+
141
+ m.register_type 'money', OID::Money.new
142
+ m.register_type 'bytea', OID::Bytea.new
143
+ m.register_type 'point', OID::Point.new
144
+ m.register_type 'hstore', OID::Hstore.new
145
+ m.register_type 'json', OID::Json.new
146
+ m.register_type 'jsonb', OID::Jsonb.new
147
+ m.register_type 'cidr', OID::Cidr.new
148
+ m.register_type 'inet', OID::Inet.new
149
+ m.register_type 'uuid', OID::Uuid.new
150
+ m.register_type 'xml', OID::Xml.new
151
+ m.register_type 'tsvector', OID::SpecializedString.new(:tsvector)
152
+ m.register_type 'macaddr', OID::SpecializedString.new(:macaddr)
153
+ m.register_type 'citext', OID::SpecializedString.new(:citext)
154
+ m.register_type 'ltree', OID::SpecializedString.new(:ltree)
155
+ m.register_type 'line', OID::SpecializedString.new(:line)
156
+ m.register_type 'lseg', OID::SpecializedString.new(:lseg)
157
+ m.register_type 'box', OID::SpecializedString.new(:box)
158
+ m.register_type 'path', OID::SpecializedString.new(:path)
159
+ m.register_type 'polygon', OID::SpecializedString.new(:polygon)
160
+ m.register_type 'circle', OID::SpecializedString.new(:circle)
161
+
162
+ #m.alias_type 'interval', 'varchar' # in Rails 5.0
163
+ # This is how Rails 5.1 handles it.
164
+ # In 5.0 SpecializedString doesn't take a precision option 5.0 actually leaves it as a regular String
165
+ # but we need it specialized to support prepared statements
166
+ # m.register_type 'interval' do |_, _, sql_type|
167
+ # precision = extract_precision(sql_type)
168
+ # OID::SpecializedString.new(:interval, precision: precision)
169
+ # end
170
+ m.register_type 'interval', OID::SpecializedString.new(:interval)
171
+
172
+ register_class_with_precision m, 'time', Type::Time
173
+ register_class_with_precision m, 'timestamp', OID::DateTime
174
+
175
+ m.register_type 'numeric' do |_, fmod, sql_type|
176
+ precision = extract_precision(sql_type)
177
+ scale = extract_scale(sql_type)
178
+
179
+ # The type for the numeric depends on the width of the field,
180
+ # so we'll do something special here.
181
+ #
182
+ # When dealing with decimal columns:
183
+ #
184
+ # places after decimal = fmod - 4 & 0xffff
185
+ # places before decimal = (fmod - 4) >> 16 & 0xffff
186
+ if fmod && (fmod - 4 & 0xffff).zero?
187
+ # FIXME: Remove this class, and the second argument to
188
+ # lookups on PG
189
+ Type::DecimalWithoutScale.new(precision: precision)
190
+ else
191
+ OID::Decimal.new(precision: precision, scale: scale)
192
+ end
193
+ end
194
+
195
+ load_additional_types(m)
196
+
197
+ # pgjdbc returns these if the column is auto-incrmenting
198
+ m.alias_type 'serial', 'int4'
199
+ m.alias_type 'bigserial', 'int8'
200
+ end
201
+
202
+ def load_additional_types(type_map, oid = nil) # :nodoc:
203
+ initializer = ArjdbcTypeMapInitializer.new(type_map)
204
+
205
+ if supports_ranges?
206
+ query = <<-SQL
207
+ SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype,
208
+ ns.nspname, ns.nspname = ANY(current_schemas(true)) in_ns
209
+ FROM pg_type as t
210
+ LEFT JOIN pg_range as r ON oid = rngtypid
211
+ JOIN pg_namespace AS ns ON t.typnamespace = ns.oid
212
+ SQL
213
+ else
214
+ query = <<-SQL
215
+ SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, t.typtype, t.typbasetype,
216
+ ns.nspname, ns.nspname = ANY(current_schemas(true)) in_ns
217
+ FROM pg_type as t
218
+ JOIN pg_namespace AS ns ON t.typnamespace = ns.oid
219
+ SQL
220
+ end
221
+
222
+ if oid
223
+ if oid.is_a? Numeric || oid.match(/^\d+$/)
224
+ # numeric OID
225
+ query += "WHERE t.oid::integer = %s" % oid
226
+
227
+ elsif m = oid.match(/"?(\w+)"?\."?(\w+)"?/)
228
+ # namespace and type name
229
+ query += "WHERE ns.nspname = '%s' AND t.typname = '%s'" % [m[1], m[2]]
230
+
231
+ else
232
+ # only type name
233
+ query += "WHERE t.typname = '%s' AND ns.nspname = ANY(current_schemas(true))" % oid
234
+ end
235
+ else
236
+ query += initializer.query_conditions_for_initial_load(type_map)
237
+ end
238
+
239
+ records = execute(query, 'SCHEMA')
240
+ initializer.run(records)
241
+ end
242
+
243
+ # Support arrays/ranges for defining attributes that don't exist in the db
244
+ ActiveRecord::Type.add_modifier({ array: true }, OID::Array, adapter: :postgresql)
245
+ ActiveRecord::Type.add_modifier({ range: true }, OID::Range, adapter: :postgresql)
246
+ ActiveRecord::Type.register(:bit, OID::Bit, adapter: :postgresql)
247
+ ActiveRecord::Type.register(:bit_varying, OID::BitVarying, adapter: :postgresql)
248
+ ActiveRecord::Type.register(:binary, OID::Bytea, adapter: :postgresql)
249
+ ActiveRecord::Type.register(:cidr, OID::Cidr, adapter: :postgresql)
250
+ ActiveRecord::Type.register(:datetime, OID::DateTime, adapter: :postgresql)
251
+ ActiveRecord::Type.register(:decimal, OID::Decimal, adapter: :postgresql)
252
+ ActiveRecord::Type.register(:enum, OID::Enum, adapter: :postgresql)
253
+ ActiveRecord::Type.register(:hstore, OID::Hstore, adapter: :postgresql)
254
+ ActiveRecord::Type.register(:inet, OID::Inet, adapter: :postgresql)
255
+ ActiveRecord::Type.register(:json, OID::Json, adapter: :postgresql)
256
+ ActiveRecord::Type.register(:jsonb, OID::Jsonb, adapter: :postgresql)
257
+ ActiveRecord::Type.register(:money, OID::Money, adapter: :postgresql)
258
+ ActiveRecord::Type.register(:point, OID::Rails51Point, adapter: :postgresql)
259
+ ActiveRecord::Type.register(:legacy_point, OID::Point, adapter: :postgresql)
260
+ ActiveRecord::Type.register(:uuid, OID::Uuid, adapter: :postgresql)
261
+ ActiveRecord::Type.register(:vector, OID::Vector, adapter: :postgresql)
262
+ ActiveRecord::Type.register(:xml, OID::Xml, adapter: :postgresql)
263
+
264
+ end
265
+ end
266
+ end