activerecord-jdbc-adapter 1.3.16 → 1.3.17

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.
@@ -0,0 +1,8 @@
1
+ module ActiveRecord::ConnectionAdapters::PostgreSQL::OID
2
+ class PGconn # emulate PGconn#unescape_bytea due #652
3
+ # NOTE: on pg gem ... PGconn = (class) PG::Connection
4
+ def self.unescape_bytea(escaped)
5
+ ArJdbc::PostgreSQL.unescape_bytea(escaped)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,131 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ module PostgreSQL
4
+ class ColumnDefinition < ActiveRecord::ConnectionAdapters::ColumnDefinition
5
+ attr_accessor :array
6
+ def array?; !!@array; end
7
+ end
8
+
9
+ module ColumnMethods
10
+ def xml(*args)
11
+ options = args.extract_options!
12
+ column(args[0], 'xml', options)
13
+ end
14
+
15
+ def tsvector(*args)
16
+ options = args.extract_options!
17
+ column(args[0], 'tsvector', options)
18
+ end
19
+
20
+ def int4range(name, options = {})
21
+ column(name, 'int4range', options)
22
+ end
23
+
24
+ def int8range(name, options = {})
25
+ column(name, 'int8range', options)
26
+ end
27
+
28
+ def tsrange(name, options = {})
29
+ column(name, 'tsrange', options)
30
+ end
31
+
32
+ def tstzrange(name, options = {})
33
+ column(name, 'tstzrange', options)
34
+ end
35
+
36
+ def numrange(name, options = {})
37
+ column(name, 'numrange', options)
38
+ end
39
+
40
+ def daterange(name, options = {})
41
+ column(name, 'daterange', options)
42
+ end
43
+
44
+ def hstore(name, options = {})
45
+ column(name, 'hstore', options)
46
+ end
47
+
48
+ def ltree(name, options = {})
49
+ column(name, 'ltree', options)
50
+ end
51
+
52
+ def inet(name, options = {})
53
+ column(name, 'inet', options)
54
+ end
55
+
56
+ def cidr(name, options = {})
57
+ column(name, 'cidr', options)
58
+ end
59
+
60
+ def macaddr(name, options = {})
61
+ column(name, 'macaddr', options)
62
+ end
63
+
64
+ def uuid(name, options = {})
65
+ column(name, 'uuid', options)
66
+ end
67
+
68
+ def json(name, options = {})
69
+ column(name, 'json', options)
70
+ end
71
+
72
+ def jsonb(name, options = {})
73
+ column(name, :jsonb, options)
74
+ end
75
+
76
+ def bit(name, options)
77
+ column(name, 'bit', options)
78
+ end
79
+
80
+ def bit_varying(name, options)
81
+ column(name, 'bit varying', options)
82
+ end
83
+ end
84
+
85
+ class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
86
+ include ColumnMethods
87
+
88
+ def primary_key(name, type = :primary_key, options = {})
89
+ return super unless type == :uuid
90
+ options[:default] = options.fetch(:default, 'uuid_generate_v4()')
91
+ options[:primary_key] = true
92
+ column name, type, options
93
+ end if ::ActiveRecord::VERSION::MAJOR > 3 # 3.2 super expects (name)
94
+
95
+ def column(name, type = nil, options = {})
96
+ super
97
+ column = self[name]
98
+ # NOTE: <= 3.1 no #new_column_definition hard-coded ColumnDef.new :
99
+ # column = self[name] || ColumnDefinition.new(@base, name, type)
100
+ # thus we simply do not support array column definitions on <= 3.1
101
+ column.array = options[:array] if column.is_a?(ColumnDefinition)
102
+ self
103
+ end
104
+
105
+ private
106
+
107
+ if ::ActiveRecord::VERSION::MAJOR > 3
108
+
109
+ def create_column_definition(name, type)
110
+ ColumnDefinition.new name, type
111
+ end
112
+
113
+ else # no #create_column_definition on 3.2
114
+
115
+ def new_column_definition(base, name, type)
116
+ definition = ColumnDefinition.new base, name, type
117
+ @columns << definition
118
+ @columns_hash[name] = definition
119
+ definition
120
+ end
121
+
122
+ end
123
+
124
+ end
125
+
126
+ class Table < ActiveRecord::ConnectionAdapters::Table
127
+ include ColumnMethods
128
+ end
129
+ end
130
+ end
131
+ end
@@ -52,6 +52,7 @@ module ArJdbc
52
52
  module Column
53
53
 
54
54
  attr_accessor :array
55
+ alias array? array
55
56
 
56
57
  def initialize(name, default, cast_type, sql_type = nil, null = true, default_function = nil,
57
58
  oid = nil, adapter = nil) # added arguments
@@ -69,7 +70,7 @@ module ArJdbc
69
70
  @default_function = default_function
70
71
  end
71
72
 
72
- end if AR42_COMPAT
73
+ end if AR42
73
74
 
74
75
  # @private (AR < 4.2 version) documented above
75
76
  module Column
@@ -83,7 +84,7 @@ module ArJdbc
83
84
  else # NOTE: AR <= 3.2 : (name, default, sql_type = nil, null = true)
84
85
  null, sql_type, oid_type = !! sql_type, oid_type, nil
85
86
  end
86
- if sql_type.to_s[-2, 2] == '[]' && ArJdbc::PostgreSQL::AR4_COMPAT
87
+ if sql_type.to_s[-2, 2] == '[]' && AR40
87
88
  @array = true if respond_to?(:array)
88
89
  super(name, default, sql_type[0..-3], null)
89
90
  else
@@ -107,20 +108,20 @@ module ArJdbc
107
108
  require 'pg_array_parser'
108
109
  base_meta.send :include, PgArrayParser
109
110
  rescue LoadError
110
- if AR42_COMPAT
111
+ if AR42
111
112
  require 'active_record/connection_adapters/postgresql/array_parser'
112
113
  else
113
114
  require 'arjdbc/postgresql/base/array_parser'
114
115
  end
115
116
  base_meta.send :include, ActiveRecord::ConnectionAdapters::PostgreSQL::ArrayParser
116
- end if AR4_COMPAT
117
+ end if AR40
117
118
 
118
119
  base_meta.send :include, Cast
119
120
 
120
121
  base.send :include, ColumnHelpers
121
122
  end
122
123
 
123
- if AR4_COMPAT && ! AR42_COMPAT
124
+ if AR40 && ! AR42
124
125
 
125
126
  # @private
126
127
  def oid_type
@@ -135,10 +136,10 @@ module ArJdbc
135
136
 
136
137
  end
137
138
 
138
- ( attr_accessor :array; def array?; array; end ) if AR4_COMPAT
139
+ ( attr_accessor :array; def array?; array; end ) if AR40
139
140
 
140
- def number?; !array && super end if AR4_COMPAT
141
- def text?; !array && super end if AR4_COMPAT
141
+ def number?; !array && super end if AR40
142
+ def text?; !array && super end if AR40
142
143
 
143
144
  # Extracts the value from a PostgreSQL column default definition.
144
145
  #
@@ -286,7 +287,7 @@ module ArJdbc
286
287
  super(value)
287
288
  end
288
289
  end
289
- end if AR4_COMPAT
290
+ end if AR40
290
291
 
291
292
  private
292
293
 
@@ -398,7 +399,7 @@ module ArJdbc
398
399
  else
399
400
  super
400
401
  end
401
- end if AR4_COMPAT
402
+ end if AR40
402
403
 
403
404
  # OID Type::Range helpers :
404
405
 
@@ -409,11 +410,11 @@ module ArJdbc
409
410
  :to => (value[-2] == ',' || t == 'infinity') ? infinity : t,
410
411
  :exclude_start => (value[0] == '('), :exclude_end => (value[-1] == ')')
411
412
  }
412
- end if AR4_COMPAT
413
+ end if AR40
413
414
 
414
415
  def infinity(options = {})
415
416
  ::Float::INFINITY * (options[:negative] ? -1 : 1)
416
- end if AR4_COMPAT
417
+ end if AR40
417
418
 
418
419
  private
419
420
 
@@ -495,7 +496,7 @@ module ArJdbc
495
496
  else
496
497
  value # Bit-string notation
497
498
  end
498
- end if AR4_COMPAT
499
+ end if AR40
499
500
 
500
501
  def hstore_to_string(object, array_member = false)
501
502
  if Hash === object
@@ -634,6 +635,6 @@ module ArJdbc
634
635
 
635
636
  end
636
637
 
637
- end unless AR42_COMPAT
638
+ end unless AR42
638
639
  end
639
640
  end
@@ -3,12 +3,18 @@ require 'thread'
3
3
  module ArJdbc
4
4
  module PostgreSQL
5
5
 
6
- if AR42_COMPAT
6
+ if AR42
7
7
  require 'active_record/connection_adapters/postgresql/oid'
8
8
  else
9
9
  require 'arjdbc/postgresql/base/oid'
10
10
  end
11
11
 
12
+ require 'arjdbc/postgresql/base/pgconn'
13
+
14
+ def self.unescape_bytea(escaped)
15
+ String.from_java_bytes Java::OrgPostgresqlUtil::PGbytea.toBytes escaped.to_java_bytes
16
+ end
17
+
12
18
  # @private
13
19
  OID = ::ActiveRecord::ConnectionAdapters::PostgreSQL::OID
14
20
 
@@ -36,12 +42,18 @@ module ArJdbc
36
42
  @extensions ||= super
37
43
  end
38
44
 
45
+ # @override
46
+ def lookup_cast_type(sql_type)
47
+ oid = execute("SELECT #{quote(sql_type)}::regtype::oid", "SCHEMA")
48
+ super oid.first['oid'].to_i
49
+ end if AR42
50
+
39
51
  def get_oid_type(oid, fmod, column_name)
40
52
  type_map.fetch(oid, fmod) {
41
53
  warn "unknown OID #{oid}: failed to recognize type of '#{column_name}'. It will be treated as String."
42
54
  type_map[oid] = OID::Identity.new
43
55
  }
44
- end unless AR42_COMPAT
56
+ end unless AR42
45
57
 
46
58
  def get_oid_type(oid, fmod, column_name, sql_type = '')
47
59
  if !type_map.key?(oid)
@@ -54,14 +66,12 @@ module ArJdbc
54
66
  type_map.register_type(oid, cast_type)
55
67
  end
56
68
  }
57
- end if AR42_COMPAT
58
-
59
- private
69
+ end if AR42
60
70
 
61
71
  @@type_map_cache = {}
62
72
  @@type_map_cache_lock = Mutex.new
63
73
 
64
- if AR42_COMPAT
74
+ if AR42
65
75
  TypeMap = ActiveRecord::Type::HashLookupTypeMap
66
76
  else
67
77
  TypeMap = OID::TypeMap
@@ -99,6 +109,8 @@ module ArJdbc
99
109
  end
100
110
  end
101
111
 
112
+ private
113
+
102
114
  def cache_type_map(type_map)
103
115
  @@type_map_cache_lock.synchronize do
104
116
  @@type_map_cache[ type_cache_key ] = type_map
@@ -148,7 +160,7 @@ module ArJdbc
148
160
  array = OID::Array.new type_map[ row['typelem'].to_i ]
149
161
  type_map[ row['oid'].to_i ] = array
150
162
  end
151
- end unless AR42_COMPAT
163
+ end unless AR42
152
164
 
153
165
  def initialize_type_map(m)
154
166
  register_class_with_limit m, 'int2', OID::Integer
@@ -219,7 +231,7 @@ module ArJdbc
219
231
  end
220
232
 
221
233
  load_additional_types(m)
222
- end if AR42_COMPAT
234
+ end if AR42
223
235
 
224
236
  def load_additional_types(type_map, oids = nil)
225
237
  if supports_ranges?
@@ -238,8 +250,9 @@ module ArJdbc
238
250
  initializer = OID::TypeMapInitializer.new(type_map)
239
251
 
240
252
  if oids
241
- query << "WHERE t.oid::integer IN (%s)" % oids.join(", ")
253
+ query << ( "WHERE t.oid::integer IN (%s)" % oids.join(", ") )
242
254
  else
255
+ # query_conditions_for_initial_load only available since AR > 4.2.1
243
256
  if initializer.respond_to?(:query_conditions_for_initial_load)
244
257
  query << initializer.query_conditions_for_initial_load(type_map)
245
258
  end
@@ -247,7 +260,7 @@ module ArJdbc
247
260
 
248
261
  records = execute(query, 'SCHEMA')
249
262
  initializer.run(records)
250
- end if AR42_COMPAT
263
+ end if AR42
251
264
 
252
265
  end
253
266
  end
@@ -1,6 +1,6 @@
1
1
  module ArJdbc
2
2
  module PostgreSQL
3
- # @private copied from native adapter 4.0/4.1
3
+ # @private copied (and adjusted) from native adapter 4.0/4.1/4.2
4
4
  class SchemaCreation < ::ActiveRecord::ConnectionAdapters::AbstractAdapter::SchemaCreation
5
5
 
6
6
  private
@@ -9,7 +9,7 @@ module ArJdbc
9
9
  sql_type = type_to_sql(o.type.to_sym, o.limit, o.precision, o.scale)
10
10
  sql = "ADD COLUMN #{quote_column_name(o.name)} #{sql_type}"
11
11
  add_column_options!(sql, column_options(o))
12
- end
12
+ end unless AR42
13
13
 
14
14
  def visit_ColumnDefinition(o)
15
15
  sql = super
@@ -18,7 +18,16 @@ module ArJdbc
18
18
  add_column_options!(sql, column_options(o))
19
19
  end
20
20
  sql
21
- end
21
+ end unless AR42
22
+
23
+ def visit_ColumnDefinition(o)
24
+ sql = super
25
+ if o.primary_key? && o.type != :primary_key
26
+ sql << " PRIMARY KEY "
27
+ add_column_options!(sql, column_options(o))
28
+ end
29
+ sql
30
+ end if AR42
22
31
 
23
32
  def add_column_options!(sql, options)
24
33
  if options[:array] || options[:column].try(:array)
@@ -32,6 +41,15 @@ module ArJdbc
32
41
  super
33
42
  end
34
43
  end
44
+
45
+ def type_for_column(column)
46
+ if column.array
47
+ @conn.lookup_cast_type("#{column.sql_type}[]")
48
+ else
49
+ super
50
+ end
51
+ end if AR42
52
+
35
53
  end
36
54
 
37
55
  def schema_creation
@@ -1,5 +1,5 @@
1
1
  module ArJdbc
2
- VERSION = "1.3.16"
2
+ VERSION = "1.3.17"
3
3
  # @deprecated
4
4
  module Version
5
5
  # @private 1.2.x compatibility
@@ -44,7 +44,7 @@ SQL
44
44
  private
45
45
 
46
46
  def sql_script(sql_content, name = 'sql_script')
47
- script = Tempfile.new(name)
47
+ require 'tempfile'; script = Tempfile.new(name)
48
48
  script.puts sql_content
49
49
  yield(script) if block_given?
50
50
  script.close
@@ -481,7 +481,7 @@ public class RubyJdbcConnection extends RubyObject {
481
481
  return getInstanceVariable("@connection");
482
482
  }
483
483
 
484
- @JRubyMethod(name = "active?")
484
+ @JRubyMethod(name = "active?", alias = "valid?")
485
485
  public IRubyObject active_p(final ThreadContext context) {
486
486
  IRubyObject connection = getInstanceVariable("@connection");
487
487
  if ( connection != null && ! connection.isNil() ) {
@@ -529,6 +529,36 @@ public class RubyJdbcConnection extends RubyObject {
529
529
  }
530
530
  }
531
531
 
532
+ @JRubyMethod(name = { "open?" /* "conn?" */ })
533
+ public IRubyObject open_p(final ThreadContext context) {
534
+ final Connection connection = getConnection(false);
535
+ if ( connection == null ) return context.getRuntime().getFalse();
536
+ try {
537
+ // NOTE: isClosed method generally cannot be called to determine
538
+ // whether a connection to a database is valid or invalid ...
539
+ return context.getRuntime().newBoolean( ! connection.isClosed() );
540
+ }
541
+ catch (SQLException e) {
542
+ return handleException(context, e);
543
+ }
544
+ }
545
+
546
+ @JRubyMethod(name = "close")
547
+ public IRubyObject close(final ThreadContext context) {
548
+ final Connection connection = getConnection(false);
549
+ if ( connection == null ) return context.getRuntime().getFalse();
550
+ try {
551
+ final boolean closed = connection.isClosed();
552
+ if ( closed ) return context.getRuntime().getFalse();
553
+ setConnection(null); // does connection.close();
554
+ return context.getRuntime().getTrue();
555
+ }
556
+ catch (Exception e) {
557
+ debugStackTrace(context, e);
558
+ return context.getRuntime().getNil();
559
+ }
560
+ }
561
+
532
562
  @JRubyMethod(name = "database_name")
533
563
  public IRubyObject database_name(final ThreadContext context) throws SQLException {
534
564
  final Connection connection = getConnection(true);
@@ -1032,28 +1062,38 @@ public class RubyJdbcConnection extends RubyObject {
1032
1062
  return keyNames;
1033
1063
  }
1034
1064
 
1035
- @JRubyMethod(name = "tables")
1065
+ @Deprecated //@JRubyMethod(name = "tables")
1036
1066
  public IRubyObject tables(ThreadContext context) {
1037
1067
  return tables(context, null, null, null, TABLE_TYPE);
1038
1068
  }
1039
1069
 
1040
- @JRubyMethod(name = "tables")
1070
+ @Deprecated //@JRubyMethod(name = "tables")
1041
1071
  public IRubyObject tables(ThreadContext context, IRubyObject catalog) {
1042
1072
  return tables(context, toStringOrNull(catalog), null, null, TABLE_TYPE);
1043
1073
  }
1044
1074
 
1045
- @JRubyMethod(name = "tables")
1075
+ @Deprecated //@JRubyMethod(name = "tables")
1046
1076
  public IRubyObject tables(ThreadContext context, IRubyObject catalog, IRubyObject schemaPattern) {
1047
1077
  return tables(context, toStringOrNull(catalog), toStringOrNull(schemaPattern), null, TABLE_TYPE);
1048
1078
  }
1049
1079
 
1050
- @JRubyMethod(name = "tables")
1080
+ @Deprecated //@JRubyMethod(name = "tables")
1051
1081
  public IRubyObject tables(ThreadContext context, IRubyObject catalog, IRubyObject schemaPattern, IRubyObject tablePattern) {
1052
1082
  return tables(context, toStringOrNull(catalog), toStringOrNull(schemaPattern), toStringOrNull(tablePattern), TABLE_TYPE);
1053
1083
  }
1054
1084
 
1055
- @JRubyMethod(name = "tables", required = 4, rest = true)
1056
- public IRubyObject tables(ThreadContext context, IRubyObject[] args) {
1085
+ @JRubyMethod(name = "tables", required = 0, optional = 4)
1086
+ public IRubyObject tables(final ThreadContext context, final IRubyObject[] args) {
1087
+ switch ( args.length ) {
1088
+ case 0: // ()
1089
+ return tables(context, null, null, null, TABLE_TYPE);
1090
+ case 1: // (catalog)
1091
+ return tables(context, toStringOrNull(args[0]), null, null, TABLE_TYPE);
1092
+ case 2: // (catalog, schemaPattern)
1093
+ return tables(context, toStringOrNull(args[0]), toStringOrNull(args[1]), null, TABLE_TYPE);
1094
+ case 3: // (catalog, schemaPattern, tablePattern)
1095
+ return tables(context, toStringOrNull(args[0]), toStringOrNull(args[1]), toStringOrNull(args[2]), TABLE_TYPE);
1096
+ }
1057
1097
  return tables(context, toStringOrNull(args[0]), toStringOrNull(args[1]), toStringOrNull(args[2]), getTypes(args[3]));
1058
1098
  }
1059
1099