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.
- checksums.yaml +7 -0
- data/.gitignore +35 -0
- data/.travis.yml +100 -0
- data/.yardopts +4 -0
- data/CONTRIBUTING.md +50 -0
- data/Gemfile +92 -0
- data/History.md +1191 -0
- data/LICENSE.txt +26 -0
- data/README.md +240 -0
- data/RUNNING_TESTS.md +127 -0
- data/Rakefile +336 -0
- data/Rakefile.jdbc +20 -0
- data/activerecord-jdbc-adapter.gemspec +55 -0
- data/activerecord-jdbc-alt-adapter.gemspec +56 -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/derby_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/firebird_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/h2_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/hsqldb_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/informix_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/jdbc_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/jndi_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/mariadb_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/mssql_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/mysql_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +1 -0
- data/lib/activerecord-jdbc-adapter.rb +1 -0
- data/lib/arel/visitors/compat.rb +60 -0
- data/lib/arel/visitors/db2.rb +137 -0
- data/lib/arel/visitors/derby.rb +112 -0
- data/lib/arel/visitors/firebird.rb +79 -0
- data/lib/arel/visitors/h2.rb +25 -0
- data/lib/arel/visitors/hsqldb.rb +32 -0
- 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 +294 -0
- data/lib/arel/visitors/sqlserver.rb +214 -0
- data/lib/arjdbc.rb +19 -0
- data/lib/arjdbc/abstract/connection_management.rb +35 -0
- data/lib/arjdbc/abstract/core.rb +74 -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 +4 -0
- data/lib/arjdbc/db2/adapter.rb +789 -0
- 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 +3 -0
- data/lib/arjdbc/derby/active_record_patch.rb +13 -0
- data/lib/arjdbc/derby/adapter.rb +540 -0
- data/lib/arjdbc/derby/connection_methods.rb +20 -0
- data/lib/arjdbc/derby/schema_creation.rb +15 -0
- data/lib/arjdbc/discover.rb +104 -0
- data/lib/arjdbc/firebird.rb +4 -0
- data/lib/arjdbc/firebird/adapter.rb +434 -0
- data/lib/arjdbc/firebird/connection_methods.rb +23 -0
- data/lib/arjdbc/h2.rb +3 -0
- data/lib/arjdbc/h2/adapter.rb +303 -0
- data/lib/arjdbc/h2/connection_methods.rb +27 -0
- data/lib/arjdbc/hsqldb.rb +3 -0
- data/lib/arjdbc/hsqldb/adapter.rb +297 -0
- data/lib/arjdbc/hsqldb/connection_methods.rb +28 -0
- data/lib/arjdbc/hsqldb/explain_support.rb +35 -0
- data/lib/arjdbc/hsqldb/schema_creation.rb +11 -0
- data/lib/arjdbc/informix.rb +5 -0
- data/lib/arjdbc/informix/adapter.rb +162 -0
- data/lib/arjdbc/informix/connection_methods.rb +9 -0
- data/lib/arjdbc/jdbc.rb +59 -0
- data/lib/arjdbc/jdbc/adapter.rb +475 -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 +53 -0
- data/lib/arjdbc/jdbc/column.rb +97 -0
- data/lib/arjdbc/jdbc/connection.rb +14 -0
- data/lib/arjdbc/jdbc/connection_methods.rb +37 -0
- data/lib/arjdbc/jdbc/error.rb +65 -0
- data/lib/arjdbc/jdbc/extension.rb +59 -0
- data/lib/arjdbc/jdbc/java.rb +13 -0
- data/lib/arjdbc/jdbc/railtie.rb +2 -0
- data/lib/arjdbc/jdbc/rake_tasks.rb +3 -0
- 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 +142 -0
- data/lib/arjdbc/mssql.rb +7 -0
- data/lib/arjdbc/mssql/adapter.rb +384 -0
- data/lib/arjdbc/mssql/column.rb +29 -0
- data/lib/arjdbc/mssql/connection_methods.rb +79 -0
- data/lib/arjdbc/mssql/database_statements.rb +134 -0
- data/lib/arjdbc/mssql/errors.rb +6 -0
- data/lib/arjdbc/mssql/explain_support.rb +129 -0
- data/lib/arjdbc/mssql/extensions.rb +36 -0
- data/lib/arjdbc/mssql/limit_helpers.rb +231 -0
- data/lib/arjdbc/mssql/lock_methods.rb +77 -0
- data/lib/arjdbc/mssql/old_adapter.rb +804 -0
- data/lib/arjdbc/mssql/old_column.rb +200 -0
- data/lib/arjdbc/mssql/quoting.rb +101 -0
- data/lib/arjdbc/mssql/schema_creation.rb +31 -0
- data/lib/arjdbc/mssql/schema_definitions.rb +74 -0
- data/lib/arjdbc/mssql/schema_statements.rb +329 -0
- data/lib/arjdbc/mssql/transaction.rb +69 -0
- data/lib/arjdbc/mssql/types.rb +52 -0
- data/lib/arjdbc/mssql/types/binary_types.rb +33 -0
- data/lib/arjdbc/mssql/types/date_and_time_types.rb +134 -0
- data/lib/arjdbc/mssql/types/deprecated_types.rb +40 -0
- data/lib/arjdbc/mssql/types/numeric_types.rb +71 -0
- data/lib/arjdbc/mssql/types/string_types.rb +56 -0
- data/lib/arjdbc/mssql/utils.rb +66 -0
- data/lib/arjdbc/mysql.rb +3 -0
- data/lib/arjdbc/mysql/adapter.rb +140 -0
- data/lib/arjdbc/mysql/connection_methods.rb +166 -0
- data/lib/arjdbc/oracle/adapter.rb +863 -0
- data/lib/arjdbc/postgresql.rb +3 -0
- data/lib/arjdbc/postgresql/adapter.rb +687 -0
- 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 +67 -0
- data/lib/arjdbc/postgresql/name.rb +24 -0
- data/lib/arjdbc/postgresql/oid_types.rb +266 -0
- data/lib/arjdbc/railtie.rb +11 -0
- data/lib/arjdbc/sqlite3.rb +3 -0
- data/lib/arjdbc/sqlite3/adapter.rb +678 -0
- data/lib/arjdbc/sqlite3/connection_methods.rb +59 -0
- data/lib/arjdbc/sybase.rb +2 -0
- data/lib/arjdbc/sybase/adapter.rb +47 -0
- data/lib/arjdbc/tasks.rb +13 -0
- data/lib/arjdbc/tasks/database_tasks.rb +31 -0
- data/lib/arjdbc/tasks/databases.rake +48 -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 +3 -0
- data/lib/generators/jdbc/USAGE +9 -0
- data/lib/generators/jdbc/jdbc_generator.rb +17 -0
- data/lib/jdbc_adapter.rb +2 -0
- data/lib/jdbc_adapter/rake_tasks.rb +4 -0
- data/lib/jdbc_adapter/version.rb +4 -0
- data/pom.xml +114 -0
- data/rails_generators/jdbc_generator.rb +15 -0
- data/rails_generators/templates/config/initializers/jdbc.rb +10 -0
- data/rails_generators/templates/lib/tasks/jdbc.rake +11 -0
- data/rakelib/01-tomcat.rake +51 -0
- data/rakelib/02-test.rake +132 -0
- data/rakelib/bundler_ext.rb +11 -0
- data/rakelib/db.rake +75 -0
- data/rakelib/rails.rake +223 -0
- data/src/java/arjdbc/ArJdbcModule.java +276 -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 +178 -0
- data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +152 -0
- data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +174 -0
- data/src/java/arjdbc/h2/H2Module.java +50 -0
- data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +85 -0
- data/src/java/arjdbc/hsqldb/HSQLDBModule.java +73 -0
- data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +75 -0
- data/src/java/arjdbc/jdbc/AdapterJavaService.java +43 -0
- data/src/java/arjdbc/jdbc/Callable.java +44 -0
- data/src/java/arjdbc/jdbc/ConnectionFactory.java +45 -0
- data/src/java/arjdbc/jdbc/DataSourceConnectionFactory.java +156 -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/RubyConnectionFactory.java +61 -0
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +3979 -0
- data/src/java/arjdbc/mssql/MSSQLModule.java +90 -0
- data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +508 -0
- data/src/java/arjdbc/mysql/MySQLModule.java +152 -0
- 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 +455 -0
- data/src/java/arjdbc/postgresql/ByteaUtils.java +157 -0
- data/src/java/arjdbc/postgresql/PgDateTimeUtils.java +52 -0
- data/src/java/arjdbc/postgresql/PostgreSQLModule.java +77 -0
- data/src/java/arjdbc/postgresql/PostgreSQLResult.java +192 -0
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +948 -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 +699 -0
- data/src/java/arjdbc/util/ObjectSupport.java +65 -0
- data/src/java/arjdbc/util/QuotingUtils.java +137 -0
- data/src/java/arjdbc/util/StringCache.java +63 -0
- data/src/java/arjdbc/util/StringHelper.java +145 -0
- metadata +269 -0
|
@@ -0,0 +1,687 @@
|
|
|
1
|
+
# frozen_string_literal: false
|
|
2
|
+
ArJdbc.load_java_part :PostgreSQL
|
|
3
|
+
|
|
4
|
+
require 'ipaddr'
|
|
5
|
+
require 'active_record/connection_adapters/abstract_adapter'
|
|
6
|
+
require 'active_record/connection_adapters/postgresql/column'
|
|
7
|
+
require 'active_record/connection_adapters/postgresql/explain_pretty_printer'
|
|
8
|
+
require 'active_record/connection_adapters/postgresql/quoting'
|
|
9
|
+
require 'active_record/connection_adapters/postgresql/referential_integrity'
|
|
10
|
+
require 'active_record/connection_adapters/postgresql/schema_dumper'
|
|
11
|
+
require 'active_record/connection_adapters/postgresql/schema_statements'
|
|
12
|
+
require 'active_record/connection_adapters/postgresql/type_metadata'
|
|
13
|
+
require 'active_record/connection_adapters/postgresql/utils'
|
|
14
|
+
require 'arjdbc/abstract/core'
|
|
15
|
+
require 'arjdbc/abstract/connection_management'
|
|
16
|
+
require 'arjdbc/abstract/database_statements'
|
|
17
|
+
require 'arjdbc/abstract/statement_cache'
|
|
18
|
+
require 'arjdbc/abstract/transaction_support'
|
|
19
|
+
require 'arjdbc/postgresql/base/array_decoder'
|
|
20
|
+
require 'arjdbc/postgresql/base/array_encoder'
|
|
21
|
+
require 'arjdbc/postgresql/name'
|
|
22
|
+
|
|
23
|
+
module ArJdbc
|
|
24
|
+
# Strives to provide Rails built-in PostgreSQL adapter (API) compatibility.
|
|
25
|
+
module PostgreSQL
|
|
26
|
+
|
|
27
|
+
require 'arjdbc/postgresql/column'
|
|
28
|
+
require 'arel/visitors/postgresql_jdbc'
|
|
29
|
+
# @private
|
|
30
|
+
IndexDefinition = ::ActiveRecord::ConnectionAdapters::IndexDefinition
|
|
31
|
+
|
|
32
|
+
# @private
|
|
33
|
+
ForeignKeyDefinition = ::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition
|
|
34
|
+
|
|
35
|
+
# @private
|
|
36
|
+
Type = ::ActiveRecord::Type
|
|
37
|
+
|
|
38
|
+
# @see ActiveRecord::ConnectionAdapters::JdbcAdapter#jdbc_connection_class
|
|
39
|
+
def self.jdbc_connection_class
|
|
40
|
+
::ActiveRecord::ConnectionAdapters::PostgreSQLJdbcConnection
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# @see ActiveRecord::ConnectionAdapters::JdbcAdapter#jdbc_column_class
|
|
44
|
+
def jdbc_column_class; ::ActiveRecord::ConnectionAdapters::PostgreSQLColumn end
|
|
45
|
+
|
|
46
|
+
ADAPTER_NAME = 'PostgreSQL'.freeze
|
|
47
|
+
|
|
48
|
+
def adapter_name
|
|
49
|
+
ADAPTER_NAME
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# TODO: Update this to pull info from the DatabaseMetaData object?
|
|
53
|
+
def postgresql_version
|
|
54
|
+
@postgresql_version ||=
|
|
55
|
+
begin
|
|
56
|
+
version = @connection.database_product
|
|
57
|
+
if match = version.match(/([\d\.]*\d).*?/)
|
|
58
|
+
version = match[1].split('.').map(&:to_i)
|
|
59
|
+
# PostgreSQL version representation does not have more than 4 digits
|
|
60
|
+
# From version 10 onwards, PG has changed its versioning policy to
|
|
61
|
+
# limit it to only 2 digits. i.e. in 10.x, 10 being the major
|
|
62
|
+
# version and x representing the patch release
|
|
63
|
+
# Refer to:
|
|
64
|
+
# https://www.postgresql.org/support/versioning/
|
|
65
|
+
# https://www.postgresql.org/docs/10/static/libpq-status.html -> PQserverVersion()
|
|
66
|
+
# for more info
|
|
67
|
+
|
|
68
|
+
if version.size >= 3
|
|
69
|
+
(version[0] * 100 + version[1]) * 100 + version[2]
|
|
70
|
+
elsif version.size == 2
|
|
71
|
+
if version[0] >= 10
|
|
72
|
+
version[0] * 100 * 100 + version[1]
|
|
73
|
+
else
|
|
74
|
+
(version[0] * 100 + version[1]) * 100
|
|
75
|
+
end
|
|
76
|
+
elsif version.size == 1
|
|
77
|
+
version[0] * 100 * 100
|
|
78
|
+
else
|
|
79
|
+
0
|
|
80
|
+
end
|
|
81
|
+
else
|
|
82
|
+
0
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def redshift?
|
|
88
|
+
# SELECT version() :
|
|
89
|
+
# PostgreSQL 8.0.2 on i686-pc-linux-gnu, compiled by GCC gcc (GCC) 3.4.2 20041017 (Red Hat 3.4.2-6.fc3), Redshift 1.0.647
|
|
90
|
+
if ( redshift = config[:redshift] ).nil?
|
|
91
|
+
redshift = !! (@connection.database_product || '').index('Redshift')
|
|
92
|
+
end
|
|
93
|
+
redshift
|
|
94
|
+
end
|
|
95
|
+
private :redshift?
|
|
96
|
+
|
|
97
|
+
def use_insert_returning?
|
|
98
|
+
if @use_insert_returning.nil?
|
|
99
|
+
@use_insert_returning = supports_insert_with_returning?
|
|
100
|
+
end
|
|
101
|
+
@use_insert_returning
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def set_client_encoding(encoding)
|
|
105
|
+
ActiveRecord::Base.logger.warn "client_encoding is set by the driver and should not be altered, ('#{encoding}' ignored)"
|
|
106
|
+
ActiveRecord::Base.logger.debug "Set the 'allowEncodingChanges' driver property (e.g. using config[:properties]) if you need to override the client encoding when doing a copy."
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Configures the encoding, verbosity, schema search path, and time zone of the connection.
|
|
110
|
+
# This is called on `connection.connect` and should not be called manually.
|
|
111
|
+
def configure_connection
|
|
112
|
+
#if encoding = config[:encoding]
|
|
113
|
+
# The client_encoding setting is set by the driver and should not be altered.
|
|
114
|
+
# If the driver detects a change it will abort the connection.
|
|
115
|
+
# see http://jdbc.postgresql.org/documentation/91/connect.html
|
|
116
|
+
# self.set_client_encoding(encoding)
|
|
117
|
+
#end
|
|
118
|
+
self.client_min_messages = config[:min_messages] || 'warning'
|
|
119
|
+
self.schema_search_path = config[:schema_search_path] || config[:schema_order]
|
|
120
|
+
|
|
121
|
+
# Use standard-conforming strings if available so we don't have to do the E'...' dance.
|
|
122
|
+
set_standard_conforming_strings
|
|
123
|
+
|
|
124
|
+
# If using Active Record's time zone support configure the connection to return
|
|
125
|
+
# TIMESTAMP WITH ZONE types in UTC.
|
|
126
|
+
# (SET TIME ZONE does not use an equals sign like other SET variables)
|
|
127
|
+
if ActiveRecord::Base.default_timezone == :utc
|
|
128
|
+
execute("SET time zone 'UTC'", 'SCHEMA')
|
|
129
|
+
elsif tz = local_tz
|
|
130
|
+
execute("SET time zone '#{tz}'", 'SCHEMA')
|
|
131
|
+
end unless redshift?
|
|
132
|
+
|
|
133
|
+
# SET statements from :variables config hash
|
|
134
|
+
# http://www.postgresql.org/docs/8.3/static/sql-set.html
|
|
135
|
+
(config[:variables] || {}).map do |k, v|
|
|
136
|
+
if v == ':default' || v == :default
|
|
137
|
+
# Sets the value to the global or compile default
|
|
138
|
+
execute("SET SESSION #{k} TO DEFAULT", 'SCHEMA')
|
|
139
|
+
elsif ! v.nil?
|
|
140
|
+
execute("SET SESSION #{k} TO #{quote(v)}", 'SCHEMA')
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# @private
|
|
146
|
+
ActiveRecordError = ::ActiveRecord::ActiveRecordError
|
|
147
|
+
|
|
148
|
+
NATIVE_DATABASE_TYPES = {
|
|
149
|
+
bigserial: 'bigserial',
|
|
150
|
+
primary_key: 'serial primary key',
|
|
151
|
+
bigint: { name: 'bigint' },
|
|
152
|
+
binary: { name: 'bytea' },
|
|
153
|
+
bit: { name: 'bit' },
|
|
154
|
+
bit_varying: { name: 'bit varying' },
|
|
155
|
+
boolean: { name: 'boolean' },
|
|
156
|
+
box: { name: 'box' },
|
|
157
|
+
char: { name: 'char' },
|
|
158
|
+
cidr: { name: 'cidr' },
|
|
159
|
+
circle: { name: 'circle' },
|
|
160
|
+
citext: { name: 'citext' },
|
|
161
|
+
date: { name: 'date' },
|
|
162
|
+
daterange: { name: 'daterange' },
|
|
163
|
+
datetime: { name: 'timestamp' },
|
|
164
|
+
decimal: { name: 'decimal' }, # :limit => 1000
|
|
165
|
+
float: { name: 'float' },
|
|
166
|
+
hstore: { name: 'hstore' },
|
|
167
|
+
inet: { name: 'inet' },
|
|
168
|
+
int4range: { name: 'int4range' },
|
|
169
|
+
int8range: { name: 'int8range' },
|
|
170
|
+
integer: { name: 'integer' },
|
|
171
|
+
interval: { name: 'interval' }, # This doesn't get added to AR's postgres adapter until 5.1 but it fixes broken tests in 5.0 ...
|
|
172
|
+
json: { name: 'json' },
|
|
173
|
+
jsonb: { name: 'jsonb' },
|
|
174
|
+
line: { name: 'line' },
|
|
175
|
+
lseg: { name: 'lseg' },
|
|
176
|
+
ltree: { name: 'ltree' },
|
|
177
|
+
macaddr: { name: 'macaddr' },
|
|
178
|
+
money: { name: 'money' },
|
|
179
|
+
numeric: { name: 'numeric' },
|
|
180
|
+
numrange: { name: 'numrange' },
|
|
181
|
+
path: { name: 'path' },
|
|
182
|
+
point: { name: 'point' },
|
|
183
|
+
polygon: { name: 'polygon' },
|
|
184
|
+
serial: { name: 'serial' }, # auto-inc integer, bigserial, smallserial
|
|
185
|
+
string: { name: 'character varying' },
|
|
186
|
+
text: { name: 'text' },
|
|
187
|
+
time: { name: 'time' },
|
|
188
|
+
timestamp: { name: 'timestamp' },
|
|
189
|
+
tsrange: { name: 'tsrange' },
|
|
190
|
+
tstzrange: { name: 'tstzrange' },
|
|
191
|
+
tsvector: { name: 'tsvector' },
|
|
192
|
+
uuid: { name: 'uuid' },
|
|
193
|
+
xml: { name: 'xml' }
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
def native_database_types
|
|
197
|
+
NATIVE_DATABASE_TYPES
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def valid_type?(type)
|
|
201
|
+
!native_database_types[type].nil?
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# Enable standard-conforming strings if available.
|
|
205
|
+
def set_standard_conforming_strings
|
|
206
|
+
self.standard_conforming_strings=(true)
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Enable standard-conforming strings if available.
|
|
210
|
+
def standard_conforming_strings=(enable)
|
|
211
|
+
client_min_messages = self.client_min_messages
|
|
212
|
+
begin
|
|
213
|
+
self.client_min_messages = 'panic'
|
|
214
|
+
value = enable ? "on" : "off"
|
|
215
|
+
execute("SET standard_conforming_strings = #{value}", 'SCHEMA')
|
|
216
|
+
@standard_conforming_strings = ( value == "on" )
|
|
217
|
+
rescue
|
|
218
|
+
@standard_conforming_strings = :unsupported
|
|
219
|
+
ensure
|
|
220
|
+
self.client_min_messages = client_min_messages
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def standard_conforming_strings?
|
|
225
|
+
if @standard_conforming_strings.nil?
|
|
226
|
+
client_min_messages = self.client_min_messages
|
|
227
|
+
begin
|
|
228
|
+
self.client_min_messages = 'panic'
|
|
229
|
+
value = select_one('SHOW standard_conforming_strings', 'SCHEMA')['standard_conforming_strings']
|
|
230
|
+
@standard_conforming_strings = ( value == "on" )
|
|
231
|
+
rescue
|
|
232
|
+
@standard_conforming_strings = :unsupported
|
|
233
|
+
ensure
|
|
234
|
+
self.client_min_messages = client_min_messages
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
@standard_conforming_strings == true # return false if :unsupported
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def supports_ddl_transactions?; true end
|
|
241
|
+
|
|
242
|
+
def supports_advisory_locks?; true end
|
|
243
|
+
|
|
244
|
+
def supports_explain?; true end
|
|
245
|
+
|
|
246
|
+
def supports_expression_index?; true end
|
|
247
|
+
|
|
248
|
+
def supports_foreign_keys?; true end
|
|
249
|
+
|
|
250
|
+
def supports_index_sort_order?; true end
|
|
251
|
+
|
|
252
|
+
def supports_migrations?; true end
|
|
253
|
+
|
|
254
|
+
def supports_partial_index?; true end
|
|
255
|
+
|
|
256
|
+
def supports_primary_key?; true end # Supports finding primary key on non-Active Record tables
|
|
257
|
+
|
|
258
|
+
def supports_savepoints?; true end
|
|
259
|
+
|
|
260
|
+
def supports_transaction_isolation?(level = nil); true end
|
|
261
|
+
|
|
262
|
+
def supports_views?; true end
|
|
263
|
+
|
|
264
|
+
def supports_datetime_with_precision?; true end
|
|
265
|
+
|
|
266
|
+
def supports_comments?; true end
|
|
267
|
+
|
|
268
|
+
# Does PostgreSQL support standard conforming strings?
|
|
269
|
+
def supports_standard_conforming_strings?
|
|
270
|
+
standard_conforming_strings?
|
|
271
|
+
@standard_conforming_strings != :unsupported
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
def supports_hex_escaped_bytea?
|
|
275
|
+
postgresql_version >= 90000
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def supports_materialized_views?
|
|
279
|
+
postgresql_version >= 90300
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
def supports_json?
|
|
283
|
+
postgresql_version >= 90200
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
def supports_insert_with_returning?
|
|
287
|
+
postgresql_version >= 80200
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
# Range data-types weren't introduced until PostgreSQL 9.2.
|
|
291
|
+
def supports_ranges?
|
|
292
|
+
postgresql_version >= 90200
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def supports_extensions?
|
|
296
|
+
postgresql_version >= 90200
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
def enable_extension(name)
|
|
300
|
+
execute("CREATE EXTENSION IF NOT EXISTS \"#{name}\"")
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
def disable_extension(name)
|
|
304
|
+
execute("DROP EXTENSION IF EXISTS \"#{name}\" CASCADE")
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
def extension_enabled?(name)
|
|
308
|
+
if supports_extensions?
|
|
309
|
+
rows = select_rows("SELECT EXISTS(SELECT * FROM pg_available_extensions WHERE name = '#{name}' AND installed_version IS NOT NULL)", 'SCHEMA')
|
|
310
|
+
available = rows.first.first # true/false or 't'/'f'
|
|
311
|
+
available == true || available == 't'
|
|
312
|
+
end
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
def extensions
|
|
316
|
+
if supports_extensions?
|
|
317
|
+
rows = select_rows "SELECT extname from pg_extension", "SCHEMA"
|
|
318
|
+
rows.map { |row| row.first }
|
|
319
|
+
else
|
|
320
|
+
[]
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
def index_algorithms
|
|
325
|
+
{ :concurrently => 'CONCURRENTLY' }
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
# Set the authorized user for this session.
|
|
329
|
+
def session_auth=(user)
|
|
330
|
+
clear_cache!
|
|
331
|
+
execute "SET SESSION AUTHORIZATION #{user}"
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
# Came from postgres_adapter
|
|
335
|
+
def get_advisory_lock(lock_id) # :nodoc:
|
|
336
|
+
unless lock_id.is_a?(Integer) && lock_id.bit_length <= 63
|
|
337
|
+
raise(ArgumentError, "Postgres requires advisory lock ids to be a signed 64 bit integer")
|
|
338
|
+
end
|
|
339
|
+
select_value("SELECT pg_try_advisory_lock(#{lock_id});")
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
# Came from postgres_adapter
|
|
343
|
+
def release_advisory_lock(lock_id) # :nodoc:
|
|
344
|
+
unless lock_id.is_a?(Integer) && lock_id.bit_length <= 63
|
|
345
|
+
raise(ArgumentError, "Postgres requires advisory lock ids to be a signed 64 bit integer")
|
|
346
|
+
end
|
|
347
|
+
select_value("SELECT pg_advisory_unlock(#{lock_id})")
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
# Returns the configured supported identifier length supported by PostgreSQL
|
|
351
|
+
def max_identifier_length
|
|
352
|
+
@max_identifier_length ||= select_one('SHOW max_identifier_length', 'SCHEMA'.freeze)['max_identifier_length'].to_i
|
|
353
|
+
end
|
|
354
|
+
alias table_alias_length max_identifier_length
|
|
355
|
+
alias index_name_length max_identifier_length
|
|
356
|
+
|
|
357
|
+
def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
|
|
358
|
+
val = super
|
|
359
|
+
if !use_insert_returning? && pk
|
|
360
|
+
unless sequence_name
|
|
361
|
+
table_ref = extract_table_ref_from_insert_sql(sql)
|
|
362
|
+
sequence_name = default_sequence_name(table_ref, pk)
|
|
363
|
+
return val unless sequence_name
|
|
364
|
+
end
|
|
365
|
+
last_insert_id_result(sequence_name)
|
|
366
|
+
else
|
|
367
|
+
val
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
def explain(arel, binds = [])
|
|
372
|
+
sql = "EXPLAIN #{to_sql(arel, binds)}"
|
|
373
|
+
ActiveRecord::ConnectionAdapters::PostgreSQL::ExplainPrettyPrinter.new.pp(exec_query(sql, 'EXPLAIN', binds))
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
# @note Only for "better" AR 4.0 compatibility.
|
|
377
|
+
# @private
|
|
378
|
+
def query(sql, name = nil)
|
|
379
|
+
log(sql, name) do
|
|
380
|
+
result = []
|
|
381
|
+
@connection.execute_query_raw(sql, []) do |*values|
|
|
382
|
+
# We need to use #deep_dup here because it appears that
|
|
383
|
+
# the java method is reusing an object in some cases
|
|
384
|
+
# which makes all of the entries in the "result"
|
|
385
|
+
# array end up with the same values as the last row
|
|
386
|
+
result << values.deep_dup
|
|
387
|
+
end
|
|
388
|
+
result
|
|
389
|
+
end
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
# We need to make sure to deallocate all the prepared statements
|
|
393
|
+
# since apparently calling close on the statement object
|
|
394
|
+
# doesn't always free the server resources and calling
|
|
395
|
+
# 'DISCARD ALL' fails if we are inside a transaction
|
|
396
|
+
def clear_cache!
|
|
397
|
+
super
|
|
398
|
+
@connection.execute 'DEALLOCATE ALL' if supports_statement_cache? && @connection.active?
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
def reset!
|
|
402
|
+
clear_cache!
|
|
403
|
+
reset_transaction
|
|
404
|
+
@connection.rollback # Have to deal with rollbacks differently than the AR adapter
|
|
405
|
+
@connection.execute 'DISCARD ALL'
|
|
406
|
+
@connection.configure_connection
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
def default_sequence_name(table_name, pk = "id") #:nodoc:
|
|
410
|
+
serial_sequence(table_name, pk)
|
|
411
|
+
rescue ActiveRecord::StatementInvalid
|
|
412
|
+
%Q("#{table_name}_#{pk}_seq")
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
def last_insert_id_result(sequence_name)
|
|
416
|
+
exec_query("SELECT currval('#{sequence_name}')", 'SQL')
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
def all_schemas
|
|
420
|
+
select('SELECT nspname FROM pg_namespace').map { |row| row["nspname"] }
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
# Returns the current client message level.
|
|
424
|
+
def client_min_messages
|
|
425
|
+
return nil if redshift? # not supported on Redshift
|
|
426
|
+
# Need to use #execute so we don't try to access the type map before it is initialized
|
|
427
|
+
execute('SHOW client_min_messages', 'SCHEMA').values.first.first
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
# Set the client message level.
|
|
431
|
+
def client_min_messages=(level)
|
|
432
|
+
# NOTE: for now simply ignore the writer (no warn on Redshift) so that
|
|
433
|
+
# the AR copy-pasted PpstgreSQL parts stay the same as much as possible
|
|
434
|
+
return nil if redshift? # not supported on Redshift
|
|
435
|
+
execute("SET client_min_messages TO '#{level}'", 'SCHEMA')
|
|
436
|
+
end
|
|
437
|
+
|
|
438
|
+
# ORDER BY clause for the passed order option.
|
|
439
|
+
#
|
|
440
|
+
# PostgreSQL does not allow arbitrary ordering when using DISTINCT ON,
|
|
441
|
+
# so we work around this by wrapping the SQL as a sub-select and ordering
|
|
442
|
+
# in that query.
|
|
443
|
+
def add_order_by_for_association_limiting!(sql, options)
|
|
444
|
+
return sql if options[:order].blank?
|
|
445
|
+
|
|
446
|
+
order = options[:order].split(',').collect { |s| s.strip }.reject(&:blank?)
|
|
447
|
+
order.map! { |s| 'DESC' if s =~ /\bdesc$/i }
|
|
448
|
+
order = order.zip((0...order.size).to_a).map { |s,i| "id_list.alias_#{i} #{s}" }.join(', ')
|
|
449
|
+
|
|
450
|
+
sql.replace "SELECT * FROM (#{sql}) AS id_list ORDER BY #{order}"
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
# @note #quote_string implemented as native
|
|
454
|
+
|
|
455
|
+
def escape_bytea(string)
|
|
456
|
+
return unless string
|
|
457
|
+
if supports_hex_escaped_bytea?
|
|
458
|
+
"\\x#{string.unpack("H*")[0]}"
|
|
459
|
+
else
|
|
460
|
+
result = ''
|
|
461
|
+
string.each_byte { |c| result << sprintf('\\\\%03o', c) }
|
|
462
|
+
result
|
|
463
|
+
end
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
# @override
|
|
467
|
+
def quote_table_name(name)
|
|
468
|
+
schema, name_part = extract_pg_identifier_from_name(name.to_s)
|
|
469
|
+
|
|
470
|
+
unless name_part
|
|
471
|
+
quote_column_name(schema)
|
|
472
|
+
else
|
|
473
|
+
table_name, name_part = extract_pg_identifier_from_name(name_part)
|
|
474
|
+
"#{quote_column_name(schema)}.#{quote_column_name(table_name)}"
|
|
475
|
+
end
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
# @note #quote_column_name implemented as native
|
|
479
|
+
alias_method :quote_schema_name, :quote_column_name
|
|
480
|
+
|
|
481
|
+
# Need to clear the cache even though the AR adapter doesn't for some reason
|
|
482
|
+
def remove_column(table_name, column_name, type = nil, options = {})
|
|
483
|
+
super
|
|
484
|
+
clear_cache!
|
|
485
|
+
end
|
|
486
|
+
|
|
487
|
+
# @private
|
|
488
|
+
def column_for(table_name, column_name)
|
|
489
|
+
column_name = column_name.to_s
|
|
490
|
+
for column in columns(table_name)
|
|
491
|
+
return column if column.name == column_name
|
|
492
|
+
end
|
|
493
|
+
nil
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
# Returns the list of a table's column names, data types, and default values.
|
|
497
|
+
#
|
|
498
|
+
# If the table name is not prefixed with a schema, the database will
|
|
499
|
+
# take the first match from the schema search path.
|
|
500
|
+
#
|
|
501
|
+
# Query implementation notes:
|
|
502
|
+
# - format_type includes the column size constraint, e.g. varchar(50)
|
|
503
|
+
# - ::regclass is a function that gives the id for a table name
|
|
504
|
+
def column_definitions(table_name)
|
|
505
|
+
select_rows(<<-end_sql, 'SCHEMA')
|
|
506
|
+
SELECT a.attname, format_type(a.atttypid, a.atttypmod),
|
|
507
|
+
pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
|
|
508
|
+
(SELECT c.collname FROM pg_collation c, pg_type t
|
|
509
|
+
WHERE c.oid = a.attcollation AND t.oid = a.atttypid
|
|
510
|
+
AND a.attcollation <> t.typcollation),
|
|
511
|
+
col_description(a.attrelid, a.attnum) AS comment
|
|
512
|
+
FROM pg_attribute a
|
|
513
|
+
LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
|
|
514
|
+
WHERE a.attrelid = '#{quote_table_name(table_name)}'::regclass
|
|
515
|
+
AND a.attnum > 0 AND NOT a.attisdropped
|
|
516
|
+
ORDER BY a.attnum
|
|
517
|
+
end_sql
|
|
518
|
+
end
|
|
519
|
+
private :column_definitions
|
|
520
|
+
|
|
521
|
+
def truncate(table_name, name = nil)
|
|
522
|
+
execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name
|
|
523
|
+
end
|
|
524
|
+
|
|
525
|
+
# @private
|
|
526
|
+
def column_name_for_operation(operation, node)
|
|
527
|
+
case operation
|
|
528
|
+
when 'maximum' then 'max'
|
|
529
|
+
when 'minimum' then 'min'
|
|
530
|
+
when 'average' then 'avg'
|
|
531
|
+
else operation.downcase
|
|
532
|
+
end
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
private
|
|
536
|
+
|
|
537
|
+
# Pulled from ActiveRecord's Postgres adapter and modified to use execute
|
|
538
|
+
def can_perform_case_insensitive_comparison_for?(column)
|
|
539
|
+
@case_insensitive_cache ||= {}
|
|
540
|
+
@case_insensitive_cache[column.sql_type] ||= begin
|
|
541
|
+
sql = <<-end_sql
|
|
542
|
+
SELECT exists(
|
|
543
|
+
SELECT * FROM pg_proc
|
|
544
|
+
WHERE proname = 'lower'
|
|
545
|
+
AND proargtypes = ARRAY[#{quote column.sql_type}::regtype]::oidvector
|
|
546
|
+
) OR exists(
|
|
547
|
+
SELECT * FROM pg_proc
|
|
548
|
+
INNER JOIN pg_cast
|
|
549
|
+
ON ARRAY[casttarget]::oidvector = proargtypes
|
|
550
|
+
WHERE proname = 'lower'
|
|
551
|
+
AND castsource = #{quote column.sql_type}::regtype
|
|
552
|
+
)
|
|
553
|
+
end_sql
|
|
554
|
+
select_value(sql, 'SCHEMA')
|
|
555
|
+
end
|
|
556
|
+
end
|
|
557
|
+
|
|
558
|
+
def translate_exception(exception, message)
|
|
559
|
+
case exception.message
|
|
560
|
+
when /duplicate key value violates unique constraint/
|
|
561
|
+
::ActiveRecord::RecordNotUnique.new(message)
|
|
562
|
+
when /violates foreign key constraint/
|
|
563
|
+
::ActiveRecord::InvalidForeignKey.new(message)
|
|
564
|
+
when /value too long/
|
|
565
|
+
::ActiveRecord::ValueTooLong.new(message)
|
|
566
|
+
else
|
|
567
|
+
super
|
|
568
|
+
end
|
|
569
|
+
end
|
|
570
|
+
|
|
571
|
+
# @private `Utils.extract_schema_and_table` from AR
|
|
572
|
+
def extract_schema_and_table(name)
|
|
573
|
+
result = name.scan(/[^".\s]+|"[^"]*"/)[0, 2]
|
|
574
|
+
result.each { |m| m.gsub!(/(^"|"$)/, '') }
|
|
575
|
+
result.unshift(nil) if result.size == 1 # schema == nil
|
|
576
|
+
result # [schema, table]
|
|
577
|
+
end
|
|
578
|
+
|
|
579
|
+
def extract_pg_identifier_from_name(name)
|
|
580
|
+
match_data = name[0, 1] == '"' ? name.match(/\"([^\"]+)\"/) : name.match(/([^\.]+)/)
|
|
581
|
+
|
|
582
|
+
if match_data
|
|
583
|
+
rest = name[match_data[0].length..-1]
|
|
584
|
+
rest = rest[1..-1] if rest[0, 1] == "."
|
|
585
|
+
[match_data[1], (rest.length > 0 ? rest : nil)]
|
|
586
|
+
end
|
|
587
|
+
end
|
|
588
|
+
|
|
589
|
+
def extract_table_ref_from_insert_sql(sql)
|
|
590
|
+
sql[/into\s("[A-Za-z0-9_."\[\]\s]+"|[A-Za-z0-9_."\[\]]+)\s*/im]
|
|
591
|
+
$1.strip if $1
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
def local_tz
|
|
595
|
+
@local_tz ||= execute('SHOW TIME ZONE', 'SCHEMA').first["TimeZone"]
|
|
596
|
+
end
|
|
597
|
+
|
|
598
|
+
end
|
|
599
|
+
end
|
|
600
|
+
|
|
601
|
+
require 'arjdbc/util/quoted_cache'
|
|
602
|
+
|
|
603
|
+
module ActiveRecord::ConnectionAdapters
|
|
604
|
+
|
|
605
|
+
# NOTE: seems needed on 4.x due loading of '.../postgresql/oid' which
|
|
606
|
+
# assumes: class PostgreSQLAdapter < AbstractAdapter
|
|
607
|
+
remove_const(:PostgreSQLAdapter) if const_defined?(:PostgreSQLAdapter)
|
|
608
|
+
|
|
609
|
+
class PostgreSQLAdapter < AbstractAdapter
|
|
610
|
+
|
|
611
|
+
# Try to use as much of the built in postgres logic as possible
|
|
612
|
+
# maybe someday we can extend the actual adapter
|
|
613
|
+
include ActiveRecord::ConnectionAdapters::PostgreSQL::ColumnDumper
|
|
614
|
+
include ActiveRecord::ConnectionAdapters::PostgreSQL::ReferentialIntegrity
|
|
615
|
+
include ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements
|
|
616
|
+
include ActiveRecord::ConnectionAdapters::PostgreSQL::Quoting
|
|
617
|
+
|
|
618
|
+
include Jdbc::ConnectionPoolCallbacks
|
|
619
|
+
|
|
620
|
+
include ArJdbc::Abstract::Core
|
|
621
|
+
include ArJdbc::Abstract::ConnectionManagement
|
|
622
|
+
include ArJdbc::Abstract::DatabaseStatements
|
|
623
|
+
include ArJdbc::Abstract::StatementCache
|
|
624
|
+
include ArJdbc::Abstract::TransactionSupport
|
|
625
|
+
include ArJdbc::PostgreSQL
|
|
626
|
+
|
|
627
|
+
require 'arjdbc/postgresql/oid_types'
|
|
628
|
+
include ::ArJdbc::PostgreSQL::OIDTypes
|
|
629
|
+
|
|
630
|
+
include ::ArJdbc::PostgreSQL::ColumnHelpers
|
|
631
|
+
|
|
632
|
+
include ::ArJdbc::Util::QuotedCache
|
|
633
|
+
|
|
634
|
+
# AR expects OID to be available on the adapter
|
|
635
|
+
OID = ActiveRecord::ConnectionAdapters::PostgreSQL::OID
|
|
636
|
+
|
|
637
|
+
def initialize(connection, logger = nil, connection_parameters = nil, config = {})
|
|
638
|
+
# @local_tz is initialized as nil to avoid warnings when connect tries to use it
|
|
639
|
+
@local_tz = nil
|
|
640
|
+
|
|
641
|
+
super(connection, logger, config) # configure_connection happens in super
|
|
642
|
+
|
|
643
|
+
initialize_type_map(@type_map = Type::HashLookupTypeMap.new)
|
|
644
|
+
|
|
645
|
+
@use_insert_returning = @config.key?(:insert_returning) ?
|
|
646
|
+
self.class.type_cast_config_to_boolean(@config[:insert_returning]) : nil
|
|
647
|
+
end
|
|
648
|
+
|
|
649
|
+
def arel_visitor # :nodoc:
|
|
650
|
+
Arel::Visitors::PostgreSQL.new(self)
|
|
651
|
+
end
|
|
652
|
+
|
|
653
|
+
require 'active_record/connection_adapters/postgresql/schema_definitions'
|
|
654
|
+
|
|
655
|
+
ColumnDefinition = ActiveRecord::ConnectionAdapters::PostgreSQL::ColumnDefinition
|
|
656
|
+
ColumnMethods = ActiveRecord::ConnectionAdapters::PostgreSQL::ColumnMethods
|
|
657
|
+
TableDefinition = ActiveRecord::ConnectionAdapters::PostgreSQL::TableDefinition
|
|
658
|
+
Table = ActiveRecord::ConnectionAdapters::PostgreSQL::Table
|
|
659
|
+
|
|
660
|
+
def create_table_definition(*args) # :nodoc:
|
|
661
|
+
TableDefinition.new(*args)
|
|
662
|
+
end
|
|
663
|
+
|
|
664
|
+
public :sql_for_insert
|
|
665
|
+
|
|
666
|
+
def schema_creation # :nodoc:
|
|
667
|
+
PostgreSQL::SchemaCreation.new self
|
|
668
|
+
end
|
|
669
|
+
|
|
670
|
+
def update_table_definition(table_name, base)
|
|
671
|
+
Table.new(table_name, base)
|
|
672
|
+
end
|
|
673
|
+
|
|
674
|
+
def jdbc_connection_class(spec)
|
|
675
|
+
::ArJdbc::PostgreSQL.jdbc_connection_class
|
|
676
|
+
end
|
|
677
|
+
|
|
678
|
+
private
|
|
679
|
+
|
|
680
|
+
# Prepared statements aren't schema aware so we need to make sure we
|
|
681
|
+
# store different PreparedStatement objects for different schemas
|
|
682
|
+
def sql_key(sql)
|
|
683
|
+
"#{schema_search_path}-#{sql}"
|
|
684
|
+
end
|
|
685
|
+
|
|
686
|
+
end
|
|
687
|
+
end
|