activerecord-jdbc-adapter 1.3.11 → 1.3.12
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/Appraisals +2 -2
- data/Gemfile +4 -0
- data/History.md +11 -0
- data/lib/arjdbc/db2/adapter.rb +3 -0
- data/lib/arjdbc/h2/adapter.rb +4 -1
- data/lib/arjdbc/hsqldb/adapter.rb +4 -1
- data/lib/arjdbc/jdbc.rb +9 -8
- data/lib/arjdbc/jdbc/adapter.rb +46 -15
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/mssql/adapter.rb +12 -6
- data/lib/arjdbc/mysql/adapter.rb +78 -13
- data/lib/arjdbc/mysql/column.rb +20 -0
- data/lib/arjdbc/mysql/connection_methods.rb +56 -2
- data/lib/arjdbc/oracle/adapter.rb +16 -17
- data/lib/arjdbc/postgresql/adapter.rb +136 -98
- data/lib/arjdbc/postgresql/base/oid.rb +78 -146
- data/lib/arjdbc/postgresql/oid_types.rb +132 -10
- data/lib/arjdbc/sqlite3/adapter.rb +58 -9
- data/lib/arjdbc/version.rb +1 -1
- data/rakelib/02-test.rake +2 -2
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +48 -10
- data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +81 -11
- metadata +2 -2
@@ -6,11 +6,6 @@ module ActiveRecord
|
|
6
6
|
module OID
|
7
7
|
class Type
|
8
8
|
def type; end
|
9
|
-
def simplified_type(sql_type); type end
|
10
|
-
|
11
|
-
def infinity(options = {})
|
12
|
-
::Float::INFINITY * (options[:negative] ? -1 : 1)
|
13
|
-
end
|
14
9
|
end
|
15
10
|
|
16
11
|
class Identity < Type
|
@@ -19,46 +14,9 @@ module ActiveRecord
|
|
19
14
|
end
|
20
15
|
end
|
21
16
|
|
22
|
-
if ActiveRecord::VERSION::MINOR >= 2 # >= 4.2
|
23
|
-
|
24
|
-
class String < Type
|
25
|
-
def type; :string end
|
26
|
-
|
27
|
-
def type_cast(value)
|
28
|
-
return if value.nil?
|
29
|
-
|
30
|
-
value.to_s
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
else
|
35
|
-
|
36
|
-
# String, Text types do not exist in AR 4.0/4.1
|
37
|
-
# AR reports Identity for them - make it similar
|
38
|
-
|
39
|
-
class String < Identity
|
40
|
-
def type; :string end
|
41
|
-
end
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
class SpecializedString < OID::String
|
46
|
-
def type; @type end
|
47
|
-
|
48
|
-
def initialize(type)
|
49
|
-
@type = type
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
class Text < OID::String
|
54
|
-
def type; :text end
|
55
|
-
end
|
56
|
-
|
57
17
|
class Bit < Type
|
58
|
-
def type; :string end
|
59
|
-
|
60
18
|
def type_cast(value)
|
61
|
-
if
|
19
|
+
if String === value
|
62
20
|
ConnectionAdapters::PostgreSQLColumn.string_to_bit value
|
63
21
|
else
|
64
22
|
value
|
@@ -67,8 +25,6 @@ module ActiveRecord
|
|
67
25
|
end
|
68
26
|
|
69
27
|
class Bytea < Type
|
70
|
-
def type; :binary end
|
71
|
-
|
72
28
|
def type_cast(value)
|
73
29
|
return if value.nil?
|
74
30
|
PGconn.unescape_bytea value
|
@@ -76,11 +32,9 @@ module ActiveRecord
|
|
76
32
|
end
|
77
33
|
|
78
34
|
class Money < Type
|
79
|
-
def type; :decimal end
|
80
|
-
|
81
35
|
def type_cast(value)
|
82
36
|
return if value.nil?
|
83
|
-
return value unless
|
37
|
+
return value unless String === value
|
84
38
|
|
85
39
|
# Because money output is formatted according to the locale, there are two
|
86
40
|
# cases to consider (note the decimal separators):
|
@@ -122,8 +76,6 @@ module ActiveRecord
|
|
122
76
|
end
|
123
77
|
|
124
78
|
class Point < Type
|
125
|
-
def type; :string end
|
126
|
-
|
127
79
|
def type_cast(value)
|
128
80
|
if ::String === value
|
129
81
|
ConnectionAdapters::PostgreSQLColumn.string_to_point value
|
@@ -134,8 +86,6 @@ module ActiveRecord
|
|
134
86
|
end
|
135
87
|
|
136
88
|
class Array < Type
|
137
|
-
def type; @subtype.type end
|
138
|
-
|
139
89
|
attr_reader :subtype
|
140
90
|
def initialize(subtype)
|
141
91
|
@subtype = subtype
|
@@ -152,8 +102,6 @@ module ActiveRecord
|
|
152
102
|
|
153
103
|
class Range < Type
|
154
104
|
attr_reader :subtype
|
155
|
-
def simplified_type(sql_type); sql_type.to_sym end
|
156
|
-
|
157
105
|
def initialize(subtype)
|
158
106
|
@subtype = subtype
|
159
107
|
end
|
@@ -161,19 +109,23 @@ module ActiveRecord
|
|
161
109
|
def extract_bounds(value)
|
162
110
|
from, to = value[1..-2].split(',')
|
163
111
|
{
|
164
|
-
from: (value[1] == ',' || from == '-infinity') ?
|
165
|
-
to: (value[-2] == ',' || to == 'infinity') ?
|
112
|
+
from: (value[1] == ',' || from == '-infinity') ? infinity(:negative => true) : from,
|
113
|
+
to: (value[-2] == ',' || to == 'infinity') ? infinity : to,
|
166
114
|
exclude_start: (value[0] == '('),
|
167
115
|
exclude_end: (value[-1] == ')')
|
168
116
|
}
|
169
117
|
end
|
170
118
|
|
119
|
+
def infinity(options = {})
|
120
|
+
::Float::INFINITY * (options[:negative] ? -1 : 1)
|
121
|
+
end
|
122
|
+
|
171
123
|
def infinity?(value)
|
172
124
|
value.respond_to?(:infinite?) && value.infinite?
|
173
125
|
end
|
174
126
|
|
175
|
-
def
|
176
|
-
infinity?(value) ? value :
|
127
|
+
def to_integer(value)
|
128
|
+
infinity?(value) ? value : value.to_i
|
177
129
|
end
|
178
130
|
|
179
131
|
def type_cast(value)
|
@@ -181,27 +133,32 @@ module ActiveRecord
|
|
181
133
|
return value if value.is_a?(::Range)
|
182
134
|
|
183
135
|
extracted = extract_bounds(value)
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
if
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
136
|
+
|
137
|
+
case @subtype
|
138
|
+
when :date
|
139
|
+
from = ConnectionAdapters::Column.value_to_date(extracted[:from])
|
140
|
+
from += 1.day if extracted[:exclude_start]
|
141
|
+
to = ConnectionAdapters::Column.value_to_date(extracted[:to])
|
142
|
+
when :decimal
|
143
|
+
from = BigDecimal.new(extracted[:from].to_s)
|
144
|
+
# FIXME: add exclude start for ::Range, same for timestamp ranges
|
145
|
+
to = BigDecimal.new(extracted[:to].to_s)
|
146
|
+
when :time
|
147
|
+
from = ConnectionAdapters::Column.string_to_time(extracted[:from])
|
148
|
+
to = ConnectionAdapters::Column.string_to_time(extracted[:to])
|
149
|
+
when :integer
|
150
|
+
from = to_integer(extracted[:from]) rescue value ? 1 : 0
|
151
|
+
from += 1 if extracted[:exclude_start]
|
152
|
+
to = to_integer(extracted[:to]) rescue value ? 1 : 0
|
153
|
+
else
|
154
|
+
return value
|
197
155
|
end
|
156
|
+
|
198
157
|
::Range.new(from, to, extracted[:exclude_end])
|
199
158
|
end
|
200
159
|
end
|
201
160
|
|
202
161
|
class Integer < Type
|
203
|
-
def type; :integer end
|
204
|
-
|
205
162
|
def type_cast(value)
|
206
163
|
return if value.nil?
|
207
164
|
|
@@ -210,8 +167,6 @@ This is not reliable and will be removed in the future.
|
|
210
167
|
end
|
211
168
|
|
212
169
|
class Boolean < Type
|
213
|
-
def type; :boolean end
|
214
|
-
|
215
170
|
def type_cast(value)
|
216
171
|
return if value.nil?
|
217
172
|
|
@@ -221,9 +176,6 @@ This is not reliable and will be removed in the future.
|
|
221
176
|
|
222
177
|
class Timestamp < Type
|
223
178
|
def type; :timestamp; end
|
224
|
-
def simplified_type(sql_type)
|
225
|
-
:datetime
|
226
|
-
end
|
227
179
|
|
228
180
|
def type_cast(value)
|
229
181
|
return if value.nil?
|
@@ -235,7 +187,7 @@ This is not reliable and will be removed in the future.
|
|
235
187
|
end
|
236
188
|
|
237
189
|
class Date < Type
|
238
|
-
def type; :
|
190
|
+
def type; :datetime; end
|
239
191
|
|
240
192
|
def type_cast(value)
|
241
193
|
return if value.nil?
|
@@ -247,8 +199,6 @@ This is not reliable and will be removed in the future.
|
|
247
199
|
end
|
248
200
|
|
249
201
|
class Time < Type
|
250
|
-
def type; :time end
|
251
|
-
|
252
202
|
def type_cast(value)
|
253
203
|
return if value.nil?
|
254
204
|
|
@@ -259,8 +209,6 @@ This is not reliable and will be removed in the future.
|
|
259
209
|
end
|
260
210
|
|
261
211
|
class Float < Type
|
262
|
-
def type; :float end
|
263
|
-
|
264
212
|
def type_cast(value)
|
265
213
|
case value
|
266
214
|
when nil; nil
|
@@ -274,32 +222,19 @@ This is not reliable and will be removed in the future.
|
|
274
222
|
end
|
275
223
|
|
276
224
|
class Decimal < Type
|
277
|
-
def type; :decimal end
|
278
|
-
|
279
225
|
def type_cast(value)
|
280
226
|
return if value.nil?
|
281
227
|
|
282
228
|
ConnectionAdapters::Column.value_to_decimal value
|
283
229
|
end
|
284
|
-
|
285
|
-
def infinity(options = {})
|
286
|
-
BigDecimal.new("Infinity") * (options[:negative] ? -1 : 1)
|
287
|
-
end
|
288
|
-
end
|
289
|
-
|
290
|
-
class Enum < Type
|
291
|
-
def type; :enum end
|
292
|
-
|
293
|
-
def type_cast(value)
|
294
|
-
value.to_s
|
295
|
-
end
|
296
230
|
end
|
297
231
|
|
298
232
|
class Hstore < Type
|
299
|
-
def type; :hstore end
|
300
|
-
|
301
233
|
def type_cast_for_write(value)
|
302
|
-
|
234
|
+
# roundtrip to ensure uniform uniform types
|
235
|
+
# TODO: This is not an efficient solution.
|
236
|
+
stringified = ConnectionAdapters::PostgreSQLColumn.hstore_to_string(value)
|
237
|
+
type_cast(stringified)
|
303
238
|
end
|
304
239
|
|
305
240
|
def type_cast(value)
|
@@ -314,22 +249,19 @@ This is not reliable and will be removed in the future.
|
|
314
249
|
end
|
315
250
|
|
316
251
|
class Cidr < Type
|
317
|
-
def type; :cidr end
|
318
252
|
def type_cast(value)
|
319
253
|
return if value.nil?
|
320
254
|
|
321
255
|
ConnectionAdapters::PostgreSQLColumn.string_to_cidr value
|
322
256
|
end
|
323
257
|
end
|
324
|
-
class Inet < Cidr
|
325
|
-
def type; :inet end
|
326
|
-
end
|
327
258
|
|
328
259
|
class Json < Type
|
329
|
-
def type; :json end
|
330
|
-
|
331
260
|
def type_cast_for_write(value)
|
332
|
-
|
261
|
+
# roundtrip to ensure uniform uniform types
|
262
|
+
# TODO: This is not an efficient solution.
|
263
|
+
stringified = ConnectionAdapters::PostgreSQLColumn.json_to_string(value)
|
264
|
+
type_cast(stringified)
|
333
265
|
end
|
334
266
|
|
335
267
|
def type_cast(value)
|
@@ -343,13 +275,6 @@ This is not reliable and will be removed in the future.
|
|
343
275
|
end
|
344
276
|
end
|
345
277
|
|
346
|
-
class Uuid < Type
|
347
|
-
def type; :uuid end
|
348
|
-
def type_cast(value)
|
349
|
-
value.presence
|
350
|
-
end
|
351
|
-
end
|
352
|
-
|
353
278
|
class TypeMap
|
354
279
|
def initialize
|
355
280
|
@mapping = {}
|
@@ -396,7 +321,7 @@ This is not reliable and will be removed in the future.
|
|
396
321
|
}
|
397
322
|
|
398
323
|
# Register an OID type named +name+ with a typecasting object in
|
399
|
-
# +type+.
|
324
|
+
# +type+. +name+ should correspond to the `typname` column in
|
400
325
|
# the `pg_type` table.
|
401
326
|
def self.register_type(name, type)
|
402
327
|
NAMES[name] = type
|
@@ -413,48 +338,55 @@ This is not reliable and will be removed in the future.
|
|
413
338
|
end
|
414
339
|
|
415
340
|
register_type 'int2', OID::Integer.new
|
416
|
-
alias_type
|
417
|
-
alias_type
|
418
|
-
alias_type
|
341
|
+
alias_type 'int4', 'int2'
|
342
|
+
alias_type 'int8', 'int2'
|
343
|
+
alias_type 'oid', 'int2'
|
344
|
+
|
345
|
+
register_type 'daterange', OID::Range.new(:date)
|
346
|
+
register_type 'numrange', OID::Range.new(:decimal)
|
347
|
+
register_type 'tsrange', OID::Range.new(:time)
|
348
|
+
register_type 'int4range', OID::Range.new(:integer)
|
349
|
+
alias_type 'tstzrange', 'tsrange'
|
350
|
+
alias_type 'int8range', 'int4range'
|
351
|
+
|
419
352
|
register_type 'numeric', OID::Decimal.new
|
420
|
-
register_type '
|
421
|
-
alias_type '
|
422
|
-
|
423
|
-
|
424
|
-
alias_type '
|
425
|
-
|
426
|
-
|
353
|
+
register_type 'text', OID::Identity.new
|
354
|
+
alias_type 'varchar', 'text'
|
355
|
+
alias_type 'char', 'text'
|
356
|
+
alias_type 'bpchar', 'text'
|
357
|
+
alias_type 'xml', 'text'
|
358
|
+
|
359
|
+
# FIXME: why are we keeping these types as strings?
|
360
|
+
alias_type 'tsvector', 'text'
|
361
|
+
alias_type 'interval', 'text'
|
362
|
+
alias_type 'macaddr', 'text'
|
363
|
+
alias_type 'uuid', 'text'
|
364
|
+
|
365
|
+
register_type 'money', OID::Money.new
|
366
|
+
register_type 'bytea', OID::Bytea.new
|
427
367
|
register_type 'bool', OID::Boolean.new
|
428
368
|
register_type 'bit', OID::Bit.new
|
429
|
-
|
369
|
+
register_type 'varbit', OID::Bit.new
|
370
|
+
|
371
|
+
register_type 'float4', OID::Float.new
|
372
|
+
alias_type 'float8', 'float4'
|
373
|
+
|
430
374
|
register_type 'timestamp', OID::Timestamp.new
|
431
|
-
|
375
|
+
register_type 'timestamptz', OID::Timestamp.new
|
432
376
|
register_type 'date', OID::Date.new
|
433
377
|
register_type 'time', OID::Time.new
|
434
378
|
|
435
|
-
register_type '
|
436
|
-
register_type 'bytea', OID::Bytea.new
|
379
|
+
register_type 'path', OID::Identity.new
|
437
380
|
register_type 'point', OID::Point.new
|
381
|
+
register_type 'polygon', OID::Identity.new
|
382
|
+
register_type 'circle', OID::Identity.new
|
438
383
|
register_type 'hstore', OID::Hstore.new
|
439
384
|
register_type 'json', OID::Json.new
|
440
|
-
register_type '
|
441
|
-
register_type 'inet', OID::Inet.new
|
442
|
-
register_type 'uuid', OID::Uuid.new
|
443
|
-
register_type 'xml', SpecializedString.new(:xml)
|
444
|
-
register_type 'tsvector', SpecializedString.new(:tsvector)
|
445
|
-
register_type 'macaddr', SpecializedString.new(:macaddr)
|
446
|
-
register_type 'citext', SpecializedString.new(:citext)
|
447
|
-
register_type 'ltree', SpecializedString.new(:ltree)
|
385
|
+
register_type 'ltree', OID::Identity.new
|
448
386
|
|
449
|
-
|
450
|
-
alias_type '
|
451
|
-
alias_type 'path', 'varchar'
|
452
|
-
alias_type 'line', 'varchar'
|
453
|
-
alias_type 'polygon', 'varchar'
|
454
|
-
alias_type 'circle', 'varchar'
|
455
|
-
alias_type 'lseg', 'varchar'
|
456
|
-
alias_type 'box', 'varchar'
|
387
|
+
register_type 'cidr', OID::Cidr.new
|
388
|
+
alias_type 'inet', 'cidr'
|
457
389
|
end
|
458
390
|
end
|
459
391
|
end
|
460
|
-
end
|
392
|
+
end
|
@@ -1,19 +1,20 @@
|
|
1
|
-
require 'arjdbc/postgresql/base/oid' # 'active_record/connection_adapters/postgresql/oid'
|
2
1
|
require 'thread'
|
3
2
|
|
4
3
|
module ArJdbc
|
5
4
|
module PostgreSQL
|
5
|
+
|
6
|
+
if AR42_COMPAT
|
7
|
+
require 'active_record/connection_adapters/postgresql/oid'
|
8
|
+
else
|
9
|
+
require 'arjdbc/postgresql/base/oid'
|
10
|
+
end
|
11
|
+
|
6
12
|
# @private
|
7
13
|
module OIDTypes
|
8
14
|
|
9
15
|
OID = ActiveRecord::ConnectionAdapters::PostgreSQL::OID
|
10
16
|
|
11
|
-
|
12
|
-
type_map.fetch(oid, fmod) {
|
13
|
-
warn "unknown OID #{oid}: failed to recognize type of '#{column_name}'. It will be treated as String."
|
14
|
-
type_map[oid] = OID::Identity.new
|
15
|
-
}
|
16
|
-
end
|
17
|
+
Type = ActiveRecord::Type if AR42_COMPAT
|
17
18
|
|
18
19
|
# @override
|
19
20
|
def enable_extension(name)
|
@@ -36,13 +37,40 @@ module ArJdbc
|
|
36
37
|
@extensions ||= super
|
37
38
|
end
|
38
39
|
|
40
|
+
def get_oid_type(oid, fmod, column_name)
|
41
|
+
type_map.fetch(oid, fmod) {
|
42
|
+
warn "unknown OID #{oid}: failed to recognize type of '#{column_name}'. It will be treated as String."
|
43
|
+
type_map[oid] = OID::Identity.new
|
44
|
+
}
|
45
|
+
end unless AR42_COMPAT
|
46
|
+
|
47
|
+
def get_oid_type(oid, fmod, column_name, sql_type = '') # :nodoc:
|
48
|
+
if !type_map.key?(oid)
|
49
|
+
load_additional_types(type_map, [oid])
|
50
|
+
end
|
51
|
+
|
52
|
+
type_map.fetch(oid, fmod, sql_type) {
|
53
|
+
warn "unknown OID #{oid}: failed to recognize type of '#{column_name}'. It will be treated as String."
|
54
|
+
Type::Value.new.tap do |cast_type|
|
55
|
+
type_map.register_type(oid, cast_type)
|
56
|
+
end
|
57
|
+
}
|
58
|
+
end if AR42_COMPAT
|
59
|
+
|
39
60
|
private
|
40
61
|
|
41
62
|
@@type_map_cache = {}
|
42
63
|
@@type_map_cache_lock = Mutex.new
|
43
64
|
|
65
|
+
if AR42_COMPAT
|
66
|
+
TypeMap = ActiveRecord::Type::HashLookupTypeMap
|
67
|
+
else
|
68
|
+
TypeMap = OID::TypeMap
|
69
|
+
end
|
70
|
+
|
71
|
+
# @see #type_map
|
44
72
|
# @private
|
45
|
-
|
73
|
+
TypeMap.class_eval do
|
46
74
|
def dup
|
47
75
|
dup = super # make sure @mapping is not shared
|
48
76
|
dup.instance_variable_set(:@mapping, @mapping.dup)
|
@@ -56,7 +84,7 @@ module ArJdbc
|
|
56
84
|
if type_map = @@type_map_cache[ type_cache_key ]
|
57
85
|
type_map.dup
|
58
86
|
else
|
59
|
-
type_map =
|
87
|
+
type_map = TypeMap.new
|
60
88
|
initialize_type_map(type_map)
|
61
89
|
cache_type_map(type_map)
|
62
90
|
type_map
|
@@ -120,7 +148,101 @@ module ArJdbc
|
|
120
148
|
array = OID::Array.new type_map[ row['typelem'].to_i ]
|
121
149
|
type_map[ row['oid'].to_i ] = array
|
122
150
|
end
|
123
|
-
end
|
151
|
+
end unless AR42_COMPAT
|
152
|
+
|
153
|
+
def initialize_type_map(m) # :nodoc:
|
154
|
+
register_class_with_limit m, 'int2', OID::Integer
|
155
|
+
m.alias_type 'int4', 'int2'
|
156
|
+
m.alias_type 'int8', 'int2'
|
157
|
+
m.alias_type 'oid', 'int2'
|
158
|
+
m.register_type 'float4', OID::Float.new
|
159
|
+
m.alias_type 'float8', 'float4'
|
160
|
+
m.register_type 'text', Type::Text.new
|
161
|
+
register_class_with_limit m, 'varchar', Type::String
|
162
|
+
m.alias_type 'char', 'varchar'
|
163
|
+
m.alias_type 'name', 'varchar'
|
164
|
+
m.alias_type 'bpchar', 'varchar'
|
165
|
+
m.register_type 'bool', Type::Boolean.new
|
166
|
+
register_class_with_limit m, 'bit', OID::Bit
|
167
|
+
register_class_with_limit m, 'varbit', OID::BitVarying
|
168
|
+
m.alias_type 'timestamptz', 'timestamp'
|
169
|
+
m.register_type 'date', OID::Date.new
|
170
|
+
m.register_type 'time', OID::Time.new
|
171
|
+
|
172
|
+
m.register_type 'money', OID::Money.new
|
173
|
+
m.register_type 'bytea', OID::Bytea.new
|
174
|
+
m.register_type 'point', OID::Point.new
|
175
|
+
m.register_type 'hstore', OID::Hstore.new
|
176
|
+
m.register_type 'json', OID::Json.new
|
177
|
+
m.register_type 'jsonb', OID::Jsonb.new
|
178
|
+
m.register_type 'cidr', OID::Cidr.new
|
179
|
+
m.register_type 'inet', OID::Inet.new
|
180
|
+
m.register_type 'uuid', OID::Uuid.new
|
181
|
+
m.register_type 'xml', OID::Xml.new
|
182
|
+
m.register_type 'tsvector', OID::SpecializedString.new(:tsvector)
|
183
|
+
m.register_type 'macaddr', OID::SpecializedString.new(:macaddr)
|
184
|
+
m.register_type 'citext', OID::SpecializedString.new(:citext)
|
185
|
+
m.register_type 'ltree', OID::SpecializedString.new(:ltree)
|
186
|
+
|
187
|
+
# FIXME: why are we keeping these types as strings?
|
188
|
+
m.alias_type 'interval', 'varchar'
|
189
|
+
m.alias_type 'path', 'varchar'
|
190
|
+
m.alias_type 'line', 'varchar'
|
191
|
+
m.alias_type 'polygon', 'varchar'
|
192
|
+
m.alias_type 'circle', 'varchar'
|
193
|
+
m.alias_type 'lseg', 'varchar'
|
194
|
+
m.alias_type 'box', 'varchar'
|
195
|
+
|
196
|
+
m.register_type 'timestamp' do |_, _, sql_type|
|
197
|
+
precision = extract_precision(sql_type)
|
198
|
+
OID::DateTime.new(precision: precision)
|
199
|
+
end
|
200
|
+
|
201
|
+
m.register_type 'numeric' do |_, fmod, sql_type|
|
202
|
+
precision = extract_precision(sql_type)
|
203
|
+
scale = extract_scale(sql_type)
|
204
|
+
|
205
|
+
# The type for the numeric depends on the width of the field,
|
206
|
+
# so we'll do something special here.
|
207
|
+
#
|
208
|
+
# When dealing with decimal columns:
|
209
|
+
#
|
210
|
+
# places after decimal = fmod - 4 & 0xffff
|
211
|
+
# places before decimal = (fmod - 4) >> 16 & 0xffff
|
212
|
+
if fmod && (fmod - 4 & 0xffff).zero?
|
213
|
+
# FIXME: Remove this class, and the second argument to
|
214
|
+
# lookups on PG
|
215
|
+
Type::DecimalWithoutScale.new(precision: precision)
|
216
|
+
else
|
217
|
+
OID::Decimal.new(precision: precision, scale: scale)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
load_additional_types(m)
|
222
|
+
end if AR42_COMPAT
|
223
|
+
|
224
|
+
def load_additional_types(type_map, oids = nil) # :nodoc:
|
225
|
+
if supports_ranges?
|
226
|
+
query = <<-SQL
|
227
|
+
SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype
|
228
|
+
FROM pg_type as t
|
229
|
+
LEFT JOIN pg_range as r ON oid = rngtypid
|
230
|
+
SQL
|
231
|
+
else
|
232
|
+
query = <<-SQL
|
233
|
+
SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, t.typtype, t.typbasetype
|
234
|
+
FROM pg_type as t
|
235
|
+
SQL
|
236
|
+
end
|
237
|
+
|
238
|
+
if oids
|
239
|
+
query += "WHERE t.oid::integer IN (%s)" % oids.join(", ")
|
240
|
+
end
|
241
|
+
|
242
|
+
initializer = OID::TypeMapInitializer.new(type_map)
|
243
|
+
records = execute(query, 'SCHEMA')
|
244
|
+
initializer.run(records)
|
245
|
+
end if AR42_COMPAT
|
124
246
|
|
125
247
|
end
|
126
248
|
end
|