activerecord-jdbc-alt-adapter 61.1.0-java → 70.0.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 +4 -4
- data/.github/workflows/main.yml +166 -0
- data/.github/workflows/ruby.yml +273 -0
- data/.gitignore +1 -0
- data/.travis.yml +3 -4
- data/Gemfile +9 -7
- data/README.md +5 -1
- data/Rakefile +1 -1
- data/activerecord-jdbc-adapter.gemspec +2 -2
- data/activerecord-jdbc-alt-adapter.gemspec +2 -2
- data/lib/arel/visitors/compat.rb +5 -33
- data/lib/arel/visitors/h2.rb +1 -13
- data/lib/arel/visitors/hsqldb.rb +1 -21
- data/lib/arel/visitors/sql_server.rb +2 -103
- data/lib/arjdbc/abstract/core.rb +8 -9
- data/lib/arjdbc/abstract/database_statements.rb +12 -4
- data/lib/arjdbc/discover.rb +0 -67
- data/lib/arjdbc/hsqldb/adapter.rb +2 -2
- data/lib/arjdbc/jdbc/adapter.rb +3 -3
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/jdbc/adapter_require.rb +3 -1
- data/lib/arjdbc/jdbc/column.rb +1 -26
- data/lib/arjdbc/jdbc/type_cast.rb +2 -2
- data/lib/arjdbc/jdbc.rb +0 -7
- data/lib/arjdbc/mssql/adapter.rb +138 -108
- data/lib/arjdbc/mssql/connection_methods.rb +3 -0
- data/lib/arjdbc/mssql/quoting.rb +26 -27
- data/lib/arjdbc/mssql/schema_creation.rb +1 -1
- data/lib/arjdbc/mssql/schema_definitions.rb +32 -17
- data/lib/arjdbc/mssql/schema_dumper.rb +13 -1
- data/lib/arjdbc/mssql/schema_statements.rb +61 -36
- data/lib/arjdbc/mssql/transaction.rb +2 -2
- data/lib/arjdbc/mssql/types/date_and_time_types.rb +6 -6
- data/lib/arjdbc/mssql/types/numeric_types.rb +2 -2
- data/lib/arjdbc/mssql.rb +1 -1
- data/lib/arjdbc/mysql/adapter.rb +2 -1
- data/lib/arjdbc/oracle/adapter.rb +4 -23
- data/lib/arjdbc/postgresql/adapter.rb +153 -4
- data/lib/arjdbc/postgresql/oid_types.rb +155 -108
- data/lib/arjdbc/sqlite3/adapter.rb +152 -99
- data/lib/arjdbc/tasks/database_tasks.rb +0 -12
- data/lib/arjdbc/tasks/mssql_database_tasks.rb +1 -1
- data/lib/arjdbc/util/serialized_attributes.rb +0 -22
- data/lib/arjdbc/util/table_copier.rb +2 -1
- data/lib/arjdbc/version.rb +1 -1
- data/rakelib/02-test.rake +3 -18
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +17 -2
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +5 -0
- data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +33 -0
- metadata +7 -38
- data/lib/active_record/connection_adapters/as400_adapter.rb +0 -2
- data/lib/active_record/connection_adapters/db2_adapter.rb +0 -1
- data/lib/active_record/connection_adapters/derby_adapter.rb +0 -1
- data/lib/active_record/connection_adapters/informix_adapter.rb +0 -1
- data/lib/arel/visitors/db2.rb +0 -137
- data/lib/arel/visitors/derby.rb +0 -112
- data/lib/arel/visitors/firebird.rb +0 -79
- data/lib/arjdbc/db2/adapter.rb +0 -808
- data/lib/arjdbc/db2/as400.rb +0 -142
- data/lib/arjdbc/db2/column.rb +0 -131
- data/lib/arjdbc/db2/connection_methods.rb +0 -48
- data/lib/arjdbc/db2.rb +0 -4
- data/lib/arjdbc/derby/active_record_patch.rb +0 -13
- data/lib/arjdbc/derby/adapter.rb +0 -521
- data/lib/arjdbc/derby/connection_methods.rb +0 -20
- data/lib/arjdbc/derby/schema_creation.rb +0 -15
- data/lib/arjdbc/derby.rb +0 -3
- data/lib/arjdbc/firebird/adapter.rb +0 -413
- data/lib/arjdbc/firebird/connection_methods.rb +0 -23
- data/lib/arjdbc/firebird.rb +0 -4
- data/lib/arjdbc/informix/adapter.rb +0 -139
- data/lib/arjdbc/informix/connection_methods.rb +0 -9
- data/lib/arjdbc/sybase/adapter.rb +0 -47
- data/lib/arjdbc/sybase.rb +0 -2
- data/lib/arjdbc/tasks/db2_database_tasks.rb +0 -104
- data/lib/arjdbc/tasks/derby_database_tasks.rb +0 -95
- data/src/java/arjdbc/derby/DerbyModule.java +0 -178
- data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +0 -152
- data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +0 -174
- data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +0 -75
@@ -1,5 +1,4 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
2
|
require 'thread'
|
4
3
|
|
5
4
|
module ArJdbc
|
@@ -91,8 +90,23 @@ module ArJdbc
|
|
91
90
|
end
|
92
91
|
|
93
92
|
def get_oid_type(oid, fmod, column_name, sql_type = '') # :nodoc:
|
94
|
-
|
95
|
-
|
93
|
+
# Note: type_map is storing a bunch of oid type prefixed with a namespace even
|
94
|
+
# if they are not namespaced (e.g. ""."oidvector"). builtin types which are
|
95
|
+
# common seem to not be prefixed (e.g. "varchar"). OID numbers are also keys
|
96
|
+
# but JDBC never returns those. So the current scheme is to check with
|
97
|
+
# what we got and that covers number and plain strings and otherwise we will
|
98
|
+
# wrap with the namespace form.
|
99
|
+
found = type_map.key?(oid)
|
100
|
+
|
101
|
+
if !found
|
102
|
+
key = oid.kind_of?(String) && oid != "oid" ? "\"\".\"#{oid}\"" : oid
|
103
|
+
found = type_map.key?(key)
|
104
|
+
|
105
|
+
if !found
|
106
|
+
load_additional_types([oid])
|
107
|
+
else
|
108
|
+
oid = key
|
109
|
+
end
|
96
110
|
end
|
97
111
|
|
98
112
|
type_map.fetch(oid, fmod, sql_type) {
|
@@ -103,132 +117,165 @@ module ArJdbc
|
|
103
117
|
}
|
104
118
|
end
|
105
119
|
|
120
|
+
def reload_type_map
|
121
|
+
type_map.clear
|
122
|
+
initialize_type_map
|
123
|
+
end
|
124
|
+
|
125
|
+
def initialize_type_map_inner(m)
|
126
|
+
m.register_type "int2", Type::Integer.new(limit: 2)
|
127
|
+
m.register_type "int4", Type::Integer.new(limit: 4)
|
128
|
+
m.register_type "int8", Type::Integer.new(limit: 8)
|
129
|
+
m.register_type "oid", OID::Oid.new
|
130
|
+
m.register_type "float4", Type::Float.new
|
131
|
+
m.alias_type "float8", "float4"
|
132
|
+
m.register_type "text", Type::Text.new
|
133
|
+
register_class_with_limit m, "varchar", Type::String
|
134
|
+
m.alias_type "char", "varchar"
|
135
|
+
m.alias_type "name", "varchar"
|
136
|
+
m.alias_type "bpchar", "varchar"
|
137
|
+
m.register_type "bool", Type::Boolean.new
|
138
|
+
register_class_with_limit m, "bit", OID::Bit
|
139
|
+
register_class_with_limit m, "varbit", OID::BitVarying
|
140
|
+
m.register_type "date", OID::Date.new
|
141
|
+
|
142
|
+
m.register_type "money", OID::Money.new
|
143
|
+
m.register_type "bytea", OID::Bytea.new
|
144
|
+
m.register_type "point", OID::Point.new
|
145
|
+
m.register_type "hstore", OID::Hstore.new
|
146
|
+
m.register_type "json", Type::Json.new
|
147
|
+
m.register_type "jsonb", OID::Jsonb.new
|
148
|
+
m.register_type "cidr", OID::Cidr.new
|
149
|
+
m.register_type "inet", OID::Inet.new
|
150
|
+
m.register_type "uuid", OID::Uuid.new
|
151
|
+
m.register_type "xml", OID::Xml.new
|
152
|
+
m.register_type "tsvector", OID::SpecializedString.new(:tsvector)
|
153
|
+
m.register_type "macaddr", OID::Macaddr.new
|
154
|
+
m.register_type "citext", OID::SpecializedString.new(:citext)
|
155
|
+
m.register_type "ltree", OID::SpecializedString.new(:ltree)
|
156
|
+
m.register_type "line", OID::SpecializedString.new(:line)
|
157
|
+
m.register_type "lseg", OID::SpecializedString.new(:lseg)
|
158
|
+
m.register_type "box", OID::SpecializedString.new(:box)
|
159
|
+
m.register_type "path", OID::SpecializedString.new(:path)
|
160
|
+
m.register_type "polygon", OID::SpecializedString.new(:polygon)
|
161
|
+
m.register_type "circle", OID::SpecializedString.new(:circle)
|
162
|
+
m.register_type "regproc", OID::Enum.new
|
163
|
+
# FIXME: adding this vector type leads to quoting not handlign Array data in quoting.
|
164
|
+
#m.register_type "_int4", OID::Vector.new(",", m.lookup("int4"))
|
165
|
+
register_class_with_precision m, "time", Type::Time
|
166
|
+
register_class_with_precision m, "timestamp", OID::Timestamp
|
167
|
+
register_class_with_precision m, "timestamptz", OID::TimestampWithTimeZone
|
168
|
+
|
169
|
+
m.register_type "numeric" do |_, fmod, sql_type|
|
170
|
+
precision = extract_precision(sql_type)
|
171
|
+
scale = extract_scale(sql_type)
|
172
|
+
|
173
|
+
# The type for the numeric depends on the width of the field,
|
174
|
+
# so we'll do something special here.
|
175
|
+
#
|
176
|
+
# When dealing with decimal columns:
|
177
|
+
#
|
178
|
+
# places after decimal = fmod - 4 & 0xffff
|
179
|
+
# places before decimal = (fmod - 4) >> 16 & 0xffff
|
180
|
+
if fmod && (fmod - 4 & 0xffff).zero?
|
181
|
+
# FIXME: Remove this class, and the second argument to
|
182
|
+
# lookups on PG
|
183
|
+
Type::DecimalWithoutScale.new(precision: precision)
|
184
|
+
else
|
185
|
+
OID::Decimal.new(precision: precision, scale: scale)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
m.register_type "interval" do |*args, sql_type|
|
190
|
+
precision = extract_precision(sql_type)
|
191
|
+
OID::Interval.new(precision: precision)
|
192
|
+
end
|
193
|
+
|
194
|
+
# pgjdbc returns these if the column is auto-incrmenting
|
195
|
+
m.alias_type 'serial', 'int4'
|
196
|
+
m.alias_type 'bigserial', 'int8'
|
197
|
+
end
|
198
|
+
|
199
|
+
|
200
|
+
# We differ from AR here because we will initialize type_map when adapter initializes
|
106
201
|
def type_map
|
107
202
|
@type_map
|
108
203
|
end
|
109
204
|
|
110
|
-
def
|
111
|
-
|
112
|
-
|
113
|
-
initialize_type_map(@type_map)
|
114
|
-
end
|
205
|
+
def initialize_type_map(m = type_map)
|
206
|
+
initialize_type_map_inner(m)
|
207
|
+
load_additional_types
|
115
208
|
end
|
116
209
|
|
117
210
|
private
|
118
211
|
|
119
|
-
def
|
120
|
-
register_class_with_limit
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
register_class_with_limit m, 'varbit', OID::BitVarying
|
134
|
-
m.alias_type 'timestamptz', 'timestamp'
|
135
|
-
m.register_type 'date', OID::Date.new
|
136
|
-
|
137
|
-
m.register_type 'money', OID::Money.new
|
138
|
-
m.register_type 'bytea', OID::Bytea.new
|
139
|
-
m.register_type 'point', OID::Point.new
|
140
|
-
m.register_type 'hstore', OID::Hstore.new
|
141
|
-
m.register_type 'json', Type::Json.new
|
142
|
-
m.register_type 'jsonb', OID::Jsonb.new
|
143
|
-
m.register_type 'cidr', OID::Cidr.new
|
144
|
-
m.register_type 'inet', OID::Inet.new
|
145
|
-
m.register_type 'uuid', OID::Uuid.new
|
146
|
-
m.register_type 'xml', OID::Xml.new
|
147
|
-
m.register_type 'tsvector', OID::SpecializedString.new(:tsvector)
|
148
|
-
m.register_type 'macaddr', OID::Macaddr.new
|
149
|
-
m.register_type 'citext', OID::SpecializedString.new(:citext)
|
150
|
-
m.register_type 'ltree', OID::SpecializedString.new(:ltree)
|
151
|
-
m.register_type 'line', OID::SpecializedString.new(:line)
|
152
|
-
m.register_type 'lseg', OID::SpecializedString.new(:lseg)
|
153
|
-
m.register_type 'box', OID::SpecializedString.new(:box)
|
154
|
-
m.register_type 'path', OID::SpecializedString.new(:path)
|
155
|
-
m.register_type 'polygon', OID::SpecializedString.new(:polygon)
|
156
|
-
m.register_type 'circle', OID::SpecializedString.new(:circle)
|
157
|
-
|
158
|
-
m.register_type 'interval' do |*args, sql_type|
|
159
|
-
precision = extract_precision(sql_type)
|
160
|
-
OID::Interval.new(precision: precision)
|
212
|
+
def register_class_with_limit(...)
|
213
|
+
::ActiveRecord::ConnectionAdapters::AbstractAdapter.send(:register_class_with_limit, ...)
|
214
|
+
end
|
215
|
+
|
216
|
+
def register_class_with_precision(...)
|
217
|
+
::ActiveRecord::ConnectionAdapters::AbstractAdapter.send(:register_class_with_precision, ...)
|
218
|
+
end
|
219
|
+
|
220
|
+
def load_additional_types(oids = nil) # :nodoc:
|
221
|
+
initializer = ArjdbcTypeMapInitializer.new(type_map)
|
222
|
+
load_types_queries(initializer, oids) do |query|
|
223
|
+
execute_and_clear(query, "SCHEMA", []) do |records|
|
224
|
+
initializer.run(records)
|
225
|
+
end
|
161
226
|
end
|
227
|
+
end
|
162
228
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
#
|
173
|
-
# When dealing with decimal columns:
|
174
|
-
#
|
175
|
-
# places after decimal = fmod - 4 & 0xffff
|
176
|
-
# places before decimal = (fmod - 4) >> 16 & 0xffff
|
177
|
-
if fmod && (fmod - 4 & 0xffff).zero?
|
178
|
-
# FIXME: Remove this class, and the second argument to
|
179
|
-
# lookups on PG
|
180
|
-
Type::DecimalWithoutScale.new(precision: precision)
|
229
|
+
def load_types_queries(initializer, oids)
|
230
|
+
query = <<~SQL
|
231
|
+
SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype
|
232
|
+
FROM pg_type as t
|
233
|
+
LEFT JOIN pg_range as r ON oid = rngtypid
|
234
|
+
SQL
|
235
|
+
if oids
|
236
|
+
if oids.all? { |e| e.kind_of? Numeric }
|
237
|
+
yield query + "WHERE t.oid IN (%s)" % oids.join(", ")
|
181
238
|
else
|
182
|
-
|
239
|
+
in_list = oids.map { |e| %Q{'#{e}'} }.join(", ")
|
240
|
+
yield query + "WHERE t.typname IN (%s)" % in_list
|
183
241
|
end
|
242
|
+
else
|
243
|
+
yield query + initializer.query_conditions_for_known_type_names
|
244
|
+
yield query + initializer.query_conditions_for_known_type_types
|
245
|
+
yield query + initializer.query_conditions_for_array_types
|
184
246
|
end
|
185
|
-
|
186
|
-
load_additional_types(m)
|
187
|
-
|
188
|
-
# pgjdbc returns these if the column is auto-incrmenting
|
189
|
-
m.alias_type 'serial', 'int4'
|
190
|
-
m.alias_type 'bigserial', 'int8'
|
191
247
|
end
|
192
248
|
|
193
|
-
def
|
194
|
-
|
249
|
+
def update_typemap_for_default_timezone
|
250
|
+
if @default_timezone != ActiveRecord.default_timezone && @timestamp_decoder
|
251
|
+
decoder_class = ActiveRecord.default_timezone == :utc ?
|
252
|
+
PG::TextDecoder::TimestampUtc :
|
253
|
+
PG::TextDecoder::TimestampWithoutTimeZone
|
195
254
|
|
196
|
-
|
197
|
-
|
198
|
-
SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype,
|
199
|
-
ns.nspname, ns.nspname = ANY(current_schemas(true)) in_ns
|
200
|
-
FROM pg_type as t
|
201
|
-
LEFT JOIN pg_range as r ON oid = rngtypid
|
202
|
-
JOIN pg_namespace AS ns ON t.typnamespace = ns.oid
|
203
|
-
SQL
|
204
|
-
else
|
205
|
-
query = <<-SQL
|
206
|
-
SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, t.typtype, t.typbasetype,
|
207
|
-
ns.nspname, ns.nspname = ANY(current_schemas(true)) in_ns
|
208
|
-
FROM pg_type as t
|
209
|
-
JOIN pg_namespace AS ns ON t.typnamespace = ns.oid
|
210
|
-
SQL
|
211
|
-
end
|
255
|
+
@timestamp_decoder = decoder_class.new(@timestamp_decoder.to_h)
|
256
|
+
@connection.type_map_for_results.add_coder(@timestamp_decoder)
|
212
257
|
|
213
|
-
|
214
|
-
if oid.is_a? Numeric || oid.match(/^\d+$/)
|
215
|
-
# numeric OID
|
216
|
-
query += "WHERE t.oid = %s" % oid
|
258
|
+
@default_timezone = ActiveRecord.default_timezone
|
217
259
|
|
218
|
-
|
219
|
-
|
220
|
-
|
260
|
+
# if default timezone has changed, we need to reconfigure the connection
|
261
|
+
# (specifically, the session time zone)
|
262
|
+
configure_connection
|
263
|
+
end
|
264
|
+
end
|
221
265
|
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
else
|
227
|
-
query += initializer.query_conditions_for_initial_load
|
266
|
+
def extract_scale(sql_type)
|
267
|
+
case sql_type
|
268
|
+
when /\((\d+)\)/ then 0
|
269
|
+
when /\((\d+)(,(\d+))\)/ then $3.to_i
|
228
270
|
end
|
271
|
+
end
|
272
|
+
|
273
|
+
def extract_precision(sql_type)
|
274
|
+
$1.to_i if sql_type =~ /\((\d+)(,\d+)?\)/
|
275
|
+
end
|
229
276
|
|
230
|
-
|
231
|
-
|
277
|
+
def extract_limit(sql_type)
|
278
|
+
$1.to_i if sql_type =~ /\((.*)\)/
|
232
279
|
end
|
233
280
|
|
234
281
|
# Support arrays/ranges for defining attributes that don't exist in the db
|