activerecord-jdbc-adapter 1.0.3-java → 50.1-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 +7 -0
- data/.gitignore +33 -0
- data/.travis.yml +79 -0
- data/.yardopts +4 -0
- data/CONTRIBUTING.md +50 -0
- data/Gemfile +91 -0
- data/History.md +1191 -0
- data/LICENSE.txt +22 -17
- data/README.md +169 -0
- data/RUNNING_TESTS.md +127 -0
- data/Rakefile +294 -5
- data/Rakefile.jdbc +20 -0
- data/activerecord-jdbc-adapter.gemspec +55 -0
- data/lib/active_record/connection_adapters/as400_adapter.rb +2 -0
- data/lib/active_record/connection_adapters/db2_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/firebird_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/mariadb_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +1 -0
- data/lib/activerecord-jdbc-adapter.rb +0 -5
- data/lib/arel/visitors/compat.rb +60 -0
- data/lib/arel/visitors/db2.rb +128 -6
- data/lib/arel/visitors/derby.rb +103 -10
- data/lib/arel/visitors/firebird.rb +79 -0
- data/lib/arel/visitors/h2.rb +25 -0
- data/lib/arel/visitors/hsqldb.rb +18 -10
- data/lib/arel/visitors/postgresql_jdbc.rb +6 -0
- data/lib/arel/visitors/sql_server.rb +225 -0
- data/lib/arel/visitors/sql_server/ng42.rb +293 -0
- data/lib/arjdbc.rb +11 -21
- data/lib/arjdbc/abstract/connection_management.rb +35 -0
- data/lib/arjdbc/abstract/core.rb +64 -0
- data/lib/arjdbc/abstract/database_statements.rb +64 -0
- data/lib/arjdbc/abstract/statement_cache.rb +58 -0
- data/lib/arjdbc/abstract/transaction_support.rb +86 -0
- data/lib/arjdbc/db2.rb +3 -1
- data/lib/arjdbc/db2/adapter.rb +630 -250
- data/lib/arjdbc/db2/as400.rb +130 -0
- data/lib/arjdbc/db2/column.rb +167 -0
- data/lib/arjdbc/db2/connection_methods.rb +44 -0
- data/lib/arjdbc/derby.rb +1 -5
- data/lib/arjdbc/derby/active_record_patch.rb +13 -0
- data/lib/arjdbc/derby/adapter.rb +409 -217
- data/lib/arjdbc/derby/connection_methods.rb +16 -14
- data/lib/arjdbc/derby/schema_creation.rb +15 -0
- data/lib/arjdbc/discover.rb +62 -50
- data/lib/arjdbc/firebird.rb +3 -1
- data/lib/arjdbc/firebird/adapter.rb +365 -62
- data/lib/arjdbc/firebird/connection_methods.rb +23 -0
- data/lib/arjdbc/h2.rb +2 -3
- data/lib/arjdbc/h2/adapter.rb +273 -6
- data/lib/arjdbc/h2/connection_methods.rb +23 -8
- data/lib/arjdbc/hsqldb.rb +2 -3
- data/lib/arjdbc/hsqldb/adapter.rb +204 -77
- data/lib/arjdbc/hsqldb/connection_methods.rb +24 -10
- data/lib/arjdbc/hsqldb/explain_support.rb +35 -0
- data/lib/arjdbc/hsqldb/schema_creation.rb +11 -0
- data/lib/arjdbc/informix.rb +4 -2
- data/lib/arjdbc/informix/adapter.rb +78 -54
- data/lib/arjdbc/informix/connection_methods.rb +8 -9
- data/lib/arjdbc/jdbc.rb +59 -2
- data/lib/arjdbc/jdbc/adapter.rb +356 -166
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/jdbc/adapter_require.rb +46 -0
- data/lib/arjdbc/jdbc/base_ext.rb +15 -0
- data/lib/arjdbc/jdbc/callbacks.rb +27 -18
- data/lib/arjdbc/jdbc/column.rb +79 -20
- data/lib/arjdbc/jdbc/connection.rb +5 -119
- data/lib/arjdbc/jdbc/connection_methods.rb +32 -4
- data/lib/arjdbc/jdbc/error.rb +65 -0
- data/lib/arjdbc/jdbc/extension.rb +41 -29
- data/lib/arjdbc/jdbc/java.rb +5 -6
- data/lib/arjdbc/jdbc/jdbc.rake +3 -126
- data/lib/arjdbc/jdbc/railtie.rb +2 -9
- data/lib/arjdbc/jdbc/rake_tasks.rb +3 -10
- data/lib/arjdbc/jdbc/serialized_attributes_helper.rb +3 -0
- data/lib/arjdbc/jdbc/type_cast.rb +166 -0
- data/lib/arjdbc/jdbc/type_converter.rb +35 -19
- data/lib/arjdbc/mssql.rb +6 -3
- data/lib/arjdbc/mssql/adapter.rb +630 -298
- data/lib/arjdbc/mssql/column.rb +200 -0
- data/lib/arjdbc/mssql/connection_methods.rb +66 -17
- data/lib/arjdbc/mssql/explain_support.rb +99 -0
- data/lib/arjdbc/mssql/limit_helpers.rb +189 -50
- data/lib/arjdbc/mssql/lock_methods.rb +77 -0
- data/lib/arjdbc/mssql/types.rb +343 -0
- data/lib/arjdbc/mssql/utils.rb +82 -0
- data/lib/arjdbc/mysql.rb +2 -3
- data/lib/arjdbc/mysql/adapter.rb +86 -356
- data/lib/arjdbc/mysql/connection_methods.rb +159 -23
- data/lib/arjdbc/oracle/adapter.rb +714 -263
- data/lib/arjdbc/postgresql.rb +2 -3
- data/lib/arjdbc/postgresql/_bc_time_cast_patch.rb +24 -0
- data/lib/arjdbc/postgresql/adapter.rb +570 -400
- data/lib/arjdbc/postgresql/base/array_decoder.rb +26 -0
- data/lib/arjdbc/postgresql/base/array_encoder.rb +25 -0
- data/lib/arjdbc/postgresql/base/array_parser.rb +95 -0
- data/lib/arjdbc/postgresql/base/pgconn.rb +11 -0
- data/lib/arjdbc/postgresql/column.rb +51 -0
- data/lib/arjdbc/postgresql/connection_methods.rb +57 -18
- data/lib/arjdbc/postgresql/name.rb +24 -0
- data/lib/arjdbc/postgresql/oid_types.rb +192 -0
- data/lib/arjdbc/railtie.rb +11 -0
- data/lib/arjdbc/sqlite3.rb +2 -3
- data/lib/arjdbc/sqlite3/adapter.rb +518 -198
- data/lib/arjdbc/sqlite3/connection_methods.rb +49 -24
- data/lib/arjdbc/sybase.rb +2 -2
- data/lib/arjdbc/sybase/adapter.rb +7 -6
- data/lib/arjdbc/tasks.rb +13 -0
- data/lib/arjdbc/tasks/database_tasks.rb +52 -0
- data/lib/arjdbc/tasks/databases.rake +91 -0
- data/lib/arjdbc/tasks/databases3.rake +215 -0
- data/lib/arjdbc/tasks/databases4.rake +39 -0
- data/lib/arjdbc/tasks/db2_database_tasks.rb +104 -0
- data/lib/arjdbc/tasks/derby_database_tasks.rb +95 -0
- data/lib/arjdbc/tasks/h2_database_tasks.rb +31 -0
- data/lib/arjdbc/tasks/hsqldb_database_tasks.rb +70 -0
- data/lib/arjdbc/tasks/jdbc_database_tasks.rb +169 -0
- data/lib/arjdbc/tasks/mssql_database_tasks.rb +46 -0
- data/lib/arjdbc/util/quoted_cache.rb +60 -0
- data/lib/arjdbc/util/serialized_attributes.rb +98 -0
- data/lib/arjdbc/util/table_copier.rb +110 -0
- data/lib/arjdbc/version.rb +1 -6
- data/lib/generators/jdbc/USAGE +9 -0
- data/lib/generators/jdbc/jdbc_generator.rb +8 -0
- data/lib/jdbc_adapter.rb +1 -1
- data/lib/jdbc_adapter/rake_tasks.rb +3 -2
- data/lib/jdbc_adapter/version.rb +2 -1
- data/pom.xml +114 -0
- data/rails_generators/jdbc_generator.rb +1 -1
- data/rails_generators/templates/config/initializers/jdbc.rb +8 -5
- data/rails_generators/templates/lib/tasks/jdbc.rake +7 -4
- data/rakelib/01-tomcat.rake +51 -0
- data/rakelib/02-test.rake +132 -0
- data/rakelib/bundler_ext.rb +11 -0
- data/rakelib/compile.rake +67 -22
- data/rakelib/db.rake +61 -0
- data/rakelib/rails.rake +204 -29
- data/src/java/arjdbc/ArJdbcModule.java +286 -0
- data/src/java/arjdbc/db2/DB2Module.java +76 -0
- data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +126 -0
- data/src/java/arjdbc/derby/DerbyModule.java +99 -243
- data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +152 -0
- data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +174 -0
- data/src/java/arjdbc/{jdbc/JdbcConnectionFactory.java → h2/H2Module.java} +20 -6
- data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +27 -12
- data/src/java/arjdbc/hsqldb/HSQLDBModule.java +73 -0
- data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +7 -6
- data/src/java/arjdbc/jdbc/AdapterJavaService.java +7 -29
- data/src/java/arjdbc/jdbc/Callable.java +44 -0
- data/src/java/arjdbc/jdbc/ConnectionFactory.java +132 -0
- data/src/java/arjdbc/jdbc/DataSourceConnectionFactory.java +157 -0
- data/src/java/arjdbc/jdbc/DriverConnectionFactory.java +63 -0
- data/src/java/arjdbc/jdbc/DriverWrapper.java +119 -0
- data/src/java/arjdbc/jdbc/JdbcResult.java +130 -0
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +3622 -948
- data/src/java/arjdbc/mssql/MSSQLModule.java +90 -0
- data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +181 -0
- data/src/java/arjdbc/mysql/MySQLModule.java +99 -81
- data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +294 -0
- data/src/java/arjdbc/oracle/OracleModule.java +80 -0
- data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +387 -17
- data/src/java/arjdbc/postgresql/ByteaUtils.java +157 -0
- data/src/java/arjdbc/postgresql/PgResultSetMetaDataWrapper.java +23 -0
- data/src/java/arjdbc/postgresql/PostgreSQLModule.java +77 -0
- data/src/java/arjdbc/postgresql/PostgreSQLResult.java +184 -0
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +952 -0
- data/src/java/arjdbc/sqlite3/SQLite3Module.java +73 -0
- data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +525 -0
- data/src/java/arjdbc/util/CallResultSet.java +826 -0
- data/src/java/arjdbc/util/DateTimeUtils.java +580 -0
- data/src/java/arjdbc/util/ObjectSupport.java +65 -0
- data/src/java/arjdbc/util/QuotingUtils.java +138 -0
- data/src/java/arjdbc/util/StringCache.java +63 -0
- data/src/java/arjdbc/util/StringHelper.java +159 -0
- metadata +245 -268
- data/History.txt +0 -369
- data/Manifest.txt +0 -180
- data/README.txt +0 -181
- data/lib/active_record/connection_adapters/oracle_adapter.rb +0 -1
- data/lib/arel/engines/sql/compilers/db2_compiler.rb +0 -9
- data/lib/arel/engines/sql/compilers/derby_compiler.rb +0 -6
- data/lib/arel/engines/sql/compilers/h2_compiler.rb +0 -6
- data/lib/arel/engines/sql/compilers/hsqldb_compiler.rb +0 -15
- data/lib/arel/engines/sql/compilers/jdbc_compiler.rb +0 -6
- data/lib/arel/engines/sql/compilers/mssql_compiler.rb +0 -46
- data/lib/arel/visitors/mssql.rb +0 -44
- data/lib/arjdbc/jdbc/compatibility.rb +0 -51
- data/lib/arjdbc/jdbc/core_ext.rb +0 -24
- data/lib/arjdbc/jdbc/discover.rb +0 -18
- data/lib/arjdbc/jdbc/driver.rb +0 -44
- data/lib/arjdbc/jdbc/missing_functionality_helper.rb +0 -87
- data/lib/arjdbc/jdbc/quoted_primary_key.rb +0 -28
- data/lib/arjdbc/jdbc/require_driver.rb +0 -16
- data/lib/arjdbc/mimer.rb +0 -2
- data/lib/arjdbc/mimer/adapter.rb +0 -142
- data/lib/arjdbc/mssql/tsql_helper.rb +0 -61
- data/lib/arjdbc/oracle.rb +0 -3
- data/lib/arjdbc/oracle/connection_methods.rb +0 -11
- data/lib/pg.rb +0 -4
- data/rakelib/package.rake +0 -92
- data/rakelib/test.rake +0 -81
- data/src/java/arjdbc/jdbc/SQLBlock.java +0 -48
- data/src/java/arjdbc/mssql/MssqlRubyJdbcConnection.java +0 -127
- data/src/java/arjdbc/postgresql/PostgresqlRubyJdbcConnection.java +0 -57
- data/src/java/arjdbc/sqlite3/Sqlite3RubyJdbcConnection.java +0 -64
- data/test/abstract_db_create.rb +0 -117
- data/test/activerecord/connection_adapters/type_conversion_test.rb +0 -31
- data/test/activerecord/connections/native_jdbc_mysql/connection.rb +0 -25
- data/test/db/db2.rb +0 -11
- data/test/db/derby.rb +0 -12
- data/test/db/h2.rb +0 -11
- data/test/db/hsqldb.rb +0 -13
- data/test/db/informix.rb +0 -11
- data/test/db/jdbc.rb +0 -11
- data/test/db/jndi_config.rb +0 -40
- data/test/db/logger.rb +0 -3
- data/test/db/mssql.rb +0 -9
- data/test/db/mysql.rb +0 -10
- data/test/db/oracle.rb +0 -34
- data/test/db/postgres.rb +0 -9
- data/test/db/sqlite3.rb +0 -11
- data/test/db2_simple_test.rb +0 -66
- data/test/derby_migration_test.rb +0 -68
- data/test/derby_multibyte_test.rb +0 -12
- data/test/derby_simple_test.rb +0 -99
- data/test/generic_jdbc_connection_test.rb +0 -29
- data/test/h2_simple_test.rb +0 -41
- data/test/has_many_through.rb +0 -79
- data/test/helper.rb +0 -5
- data/test/hsqldb_simple_test.rb +0 -6
- data/test/informix_simple_test.rb +0 -48
- data/test/jdbc_common.rb +0 -25
- data/test/jndi_callbacks_test.rb +0 -40
- data/test/jndi_test.rb +0 -25
- data/test/manualTestDatabase.rb +0 -191
- data/test/models/add_not_null_column_to_table.rb +0 -12
- data/test/models/auto_id.rb +0 -18
- data/test/models/data_types.rb +0 -28
- data/test/models/entry.rb +0 -43
- data/test/models/mixed_case.rb +0 -25
- data/test/models/reserved_word.rb +0 -18
- data/test/models/string_id.rb +0 -18
- data/test/models/validates_uniqueness_of_string.rb +0 -19
- data/test/mssql_db_create_test.rb +0 -26
- data/test/mssql_identity_insert_test.rb +0 -19
- data/test/mssql_legacy_types_test.rb +0 -58
- data/test/mssql_limit_offset_test.rb +0 -136
- data/test/mssql_multibyte_test.rb +0 -18
- data/test/mssql_simple_test.rb +0 -55
- data/test/mysql_db_create_test.rb +0 -27
- data/test/mysql_info_test.rb +0 -113
- data/test/mysql_multibyte_test.rb +0 -10
- data/test/mysql_nonstandard_primary_key_test.rb +0 -42
- data/test/mysql_simple_test.rb +0 -49
- data/test/oracle_simple_test.rb +0 -18
- data/test/oracle_specific_test.rb +0 -83
- data/test/pick_rails_version.rb +0 -3
- data/test/postgres_db_create_test.rb +0 -32
- data/test/postgres_drop_db_test.rb +0 -16
- data/test/postgres_mixed_case_test.rb +0 -29
- data/test/postgres_nonseq_pkey_test.rb +0 -38
- data/test/postgres_reserved_test.rb +0 -22
- data/test/postgres_schema_search_path_test.rb +0 -44
- data/test/postgres_simple_test.rb +0 -51
- data/test/postgres_table_alias_length_test.rb +0 -15
- data/test/simple.rb +0 -546
- data/test/sqlite3_simple_test.rb +0 -233
- data/test/sybase_jtds_simple_test.rb +0 -28
|
@@ -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
|
|
@@ -1,21 +1,60 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
|
16
18
|
end
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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']
|
|
20
24
|
|
|
25
|
+
config[:url] ||= "jdbc:postgresql://#{host}:#{port}/#{database}"
|
|
26
|
+
config[:url] << config[:pg_params] if config[:pg_params]
|
|
21
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
|
+
# If prepared statements are off, lets make sure they are really *off*
|
|
55
|
+
properties['prepareThreshold'] ||= 0 unless config[:prepared_statements]
|
|
56
|
+
|
|
57
|
+
jdbc_connection(config)
|
|
58
|
+
end
|
|
59
|
+
alias_method :jdbcpostgresql_connection, :postgresql_connection
|
|
60
|
+
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,192 @@
|
|
|
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
|
+
# @private
|
|
13
|
+
module OIDTypes
|
|
14
|
+
|
|
15
|
+
# @override
|
|
16
|
+
def enable_extension(name)
|
|
17
|
+
result = super(name)
|
|
18
|
+
@extensions = nil
|
|
19
|
+
reload_type_map
|
|
20
|
+
result
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# @override
|
|
24
|
+
def disable_extension(name)
|
|
25
|
+
result = super(name)
|
|
26
|
+
@extensions = nil
|
|
27
|
+
reload_type_map
|
|
28
|
+
result
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @override
|
|
32
|
+
def extensions
|
|
33
|
+
@extensions ||= super
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# @override
|
|
37
|
+
def lookup_cast_type(sql_type)
|
|
38
|
+
oid = execute("SELECT #{quote(sql_type)}::regtype::oid", "SCHEMA")
|
|
39
|
+
super oid.first['oid'].to_i
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def get_oid_type(oid, fmod, column_name, sql_type = '') # :nodoc:
|
|
43
|
+
if !type_map.key?(oid)
|
|
44
|
+
load_additional_types(type_map, [oid])
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
type_map.fetch(oid, fmod, sql_type) {
|
|
48
|
+
warn "unknown OID #{oid}: failed to recognize type of '#{column_name}'. It will be treated as String."
|
|
49
|
+
Type::Value.new.tap do |cast_type|
|
|
50
|
+
type_map.register_type(oid, cast_type)
|
|
51
|
+
end
|
|
52
|
+
}
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def type_map
|
|
56
|
+
@type_map
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def reload_type_map
|
|
60
|
+
if ( @type_map ||= nil )
|
|
61
|
+
@type_map.clear
|
|
62
|
+
initialize_type_map(@type_map)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
def initialize_type_map(m)
|
|
69
|
+
register_class_with_limit m, 'int2', Type::Integer
|
|
70
|
+
register_class_with_limit m, 'int4', Type::Integer
|
|
71
|
+
register_class_with_limit m, 'int8', Type::Integer
|
|
72
|
+
m.alias_type 'oid', 'int2'
|
|
73
|
+
m.register_type 'float4', Type::Float.new
|
|
74
|
+
m.alias_type 'float8', 'float4'
|
|
75
|
+
m.register_type 'text', Type::Text.new
|
|
76
|
+
register_class_with_limit m, 'varchar', Type::String
|
|
77
|
+
m.alias_type 'char', 'varchar'
|
|
78
|
+
m.alias_type 'name', 'varchar'
|
|
79
|
+
m.alias_type 'bpchar', 'varchar'
|
|
80
|
+
m.register_type 'bool', Type::Boolean.new
|
|
81
|
+
register_class_with_limit m, 'bit', OID::Bit
|
|
82
|
+
register_class_with_limit m, 'varbit', OID::BitVarying
|
|
83
|
+
m.alias_type 'timestamptz', 'timestamp'
|
|
84
|
+
m.register_type 'date', Type::Date.new
|
|
85
|
+
|
|
86
|
+
m.register_type 'money', OID::Money.new
|
|
87
|
+
m.register_type 'bytea', OID::Bytea.new
|
|
88
|
+
m.register_type 'point', OID::Point.new
|
|
89
|
+
m.register_type 'hstore', OID::Hstore.new
|
|
90
|
+
m.register_type 'json', OID::Json.new
|
|
91
|
+
m.register_type 'jsonb', OID::Jsonb.new
|
|
92
|
+
m.register_type 'cidr', OID::Cidr.new
|
|
93
|
+
m.register_type 'inet', OID::Inet.new
|
|
94
|
+
m.register_type 'uuid', OID::Uuid.new
|
|
95
|
+
m.register_type 'xml', OID::Xml.new
|
|
96
|
+
m.register_type 'tsvector', OID::SpecializedString.new(:tsvector)
|
|
97
|
+
m.register_type 'macaddr', OID::SpecializedString.new(:macaddr)
|
|
98
|
+
m.register_type 'citext', OID::SpecializedString.new(:citext)
|
|
99
|
+
m.register_type 'ltree', OID::SpecializedString.new(:ltree)
|
|
100
|
+
m.register_type 'line', OID::SpecializedString.new(:line)
|
|
101
|
+
m.register_type 'lseg', OID::SpecializedString.new(:lseg)
|
|
102
|
+
m.register_type 'box', OID::SpecializedString.new(:box)
|
|
103
|
+
m.register_type 'path', OID::SpecializedString.new(:path)
|
|
104
|
+
m.register_type 'polygon', OID::SpecializedString.new(:polygon)
|
|
105
|
+
m.register_type 'circle', OID::SpecializedString.new(:circle)
|
|
106
|
+
|
|
107
|
+
#m.alias_type 'interval', 'varchar' # in Rails 5.0
|
|
108
|
+
# This is how Rails 5.1 handles it.
|
|
109
|
+
# In 5.0 SpecializedString doesn't take a precision option 5.0 actually leaves it as a regular String
|
|
110
|
+
# but we need it specialized to support prepared statements
|
|
111
|
+
# m.register_type 'interval' do |_, _, sql_type|
|
|
112
|
+
# precision = extract_precision(sql_type)
|
|
113
|
+
# OID::SpecializedString.new(:interval, precision: precision)
|
|
114
|
+
# end
|
|
115
|
+
m.register_type 'interval', OID::SpecializedString.new(:interval)
|
|
116
|
+
|
|
117
|
+
register_class_with_precision m, 'time', Type::Time
|
|
118
|
+
register_class_with_precision m, 'timestamp', OID::DateTime
|
|
119
|
+
|
|
120
|
+
m.register_type 'numeric' do |_, fmod, sql_type|
|
|
121
|
+
precision = extract_precision(sql_type)
|
|
122
|
+
scale = extract_scale(sql_type)
|
|
123
|
+
|
|
124
|
+
# The type for the numeric depends on the width of the field,
|
|
125
|
+
# so we'll do something special here.
|
|
126
|
+
#
|
|
127
|
+
# When dealing with decimal columns:
|
|
128
|
+
#
|
|
129
|
+
# places after decimal = fmod - 4 & 0xffff
|
|
130
|
+
# places before decimal = (fmod - 4) >> 16 & 0xffff
|
|
131
|
+
if fmod && (fmod - 4 & 0xffff).zero?
|
|
132
|
+
# FIXME: Remove this class, and the second argument to
|
|
133
|
+
# lookups on PG
|
|
134
|
+
Type::DecimalWithoutScale.new(precision: precision)
|
|
135
|
+
else
|
|
136
|
+
OID::Decimal.new(precision: precision, scale: scale)
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
load_additional_types(m)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def load_additional_types(type_map, oids = nil) # :nodoc:
|
|
144
|
+
initializer = OID::TypeMapInitializer.new(type_map)
|
|
145
|
+
|
|
146
|
+
if supports_ranges?
|
|
147
|
+
query = <<-SQL
|
|
148
|
+
SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype
|
|
149
|
+
FROM pg_type as t
|
|
150
|
+
LEFT JOIN pg_range as r ON oid = rngtypid
|
|
151
|
+
SQL
|
|
152
|
+
else
|
|
153
|
+
query = <<-SQL
|
|
154
|
+
SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, t.typtype, t.typbasetype
|
|
155
|
+
FROM pg_type as t
|
|
156
|
+
SQL
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
if oids
|
|
160
|
+
query += "WHERE t.oid::integer IN (%s)" % oids.join(", ")
|
|
161
|
+
else
|
|
162
|
+
query += initializer.query_conditions_for_initial_load(type_map)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
records = execute(query, 'SCHEMA')
|
|
166
|
+
initializer.run(records)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Support arrays/ranges for defining attributes that don't exist in the db
|
|
170
|
+
ActiveRecord::Type.add_modifier({ array: true }, OID::Array, adapter: :postgresql)
|
|
171
|
+
ActiveRecord::Type.add_modifier({ range: true }, OID::Range, adapter: :postgresql)
|
|
172
|
+
ActiveRecord::Type.register(:bit, OID::Bit, adapter: :postgresql)
|
|
173
|
+
ActiveRecord::Type.register(:bit_varying, OID::BitVarying, adapter: :postgresql)
|
|
174
|
+
ActiveRecord::Type.register(:binary, OID::Bytea, adapter: :postgresql)
|
|
175
|
+
ActiveRecord::Type.register(:cidr, OID::Cidr, adapter: :postgresql)
|
|
176
|
+
ActiveRecord::Type.register(:datetime, OID::DateTime, adapter: :postgresql)
|
|
177
|
+
ActiveRecord::Type.register(:decimal, OID::Decimal, adapter: :postgresql)
|
|
178
|
+
ActiveRecord::Type.register(:enum, OID::Enum, adapter: :postgresql)
|
|
179
|
+
ActiveRecord::Type.register(:hstore, OID::Hstore, adapter: :postgresql)
|
|
180
|
+
ActiveRecord::Type.register(:inet, OID::Inet, adapter: :postgresql)
|
|
181
|
+
ActiveRecord::Type.register(:json, OID::Json, adapter: :postgresql)
|
|
182
|
+
ActiveRecord::Type.register(:jsonb, OID::Jsonb, adapter: :postgresql)
|
|
183
|
+
ActiveRecord::Type.register(:money, OID::Money, adapter: :postgresql)
|
|
184
|
+
ActiveRecord::Type.register(:point, OID::Rails51Point, adapter: :postgresql)
|
|
185
|
+
ActiveRecord::Type.register(:legacy_point, OID::Point, adapter: :postgresql)
|
|
186
|
+
ActiveRecord::Type.register(:uuid, OID::Uuid, adapter: :postgresql)
|
|
187
|
+
ActiveRecord::Type.register(:vector, OID::Vector, adapter: :postgresql)
|
|
188
|
+
ActiveRecord::Type.register(:xml, OID::Xml, adapter: :postgresql)
|
|
189
|
+
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|