activerecord-jdbc-adapter 1.3.7 → 1.3.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +33 -3
  3. data/Appraisals +11 -5
  4. data/Gemfile +21 -15
  5. data/History.md +31 -1
  6. data/lib/active_record/connection_adapters/mariadb_adapter.rb +1 -0
  7. data/lib/arel/visitors/firebird.rb +7 -10
  8. data/lib/arel/visitors/h2.rb +9 -0
  9. data/lib/arel/visitors/sql_server.rb +21 -2
  10. data/lib/arjdbc/h2/adapter.rb +31 -2
  11. data/lib/arjdbc/h2/connection_methods.rb +1 -1
  12. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  13. data/lib/arjdbc/jdbc/column.rb +2 -1
  14. data/lib/arjdbc/mssql/adapter.rb +40 -23
  15. data/lib/arjdbc/mssql/column.rb +4 -4
  16. data/lib/arjdbc/mysql/adapter.rb +36 -10
  17. data/lib/arjdbc/mysql/column.rb +12 -7
  18. data/lib/arjdbc/mysql/connection_methods.rb +53 -21
  19. data/lib/arjdbc/oracle/adapter.rb +22 -5
  20. data/lib/arjdbc/postgresql/adapter.rb +54 -18
  21. data/lib/arjdbc/postgresql/base/array_parser.rb +95 -0
  22. data/lib/arjdbc/postgresql/base/oid.rb +460 -0
  23. data/lib/arjdbc/postgresql/column.rb +50 -15
  24. data/lib/arjdbc/postgresql/oid_types.rb +126 -0
  25. data/lib/arjdbc/tasks/h2_database_tasks.rb +4 -2
  26. data/lib/arjdbc/version.rb +1 -1
  27. data/rakelib/02-test.rake +3 -30
  28. data/src/java/arjdbc/derby/DerbyModule.java +0 -8
  29. data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +1 -0
  30. data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +2 -0
  31. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +8 -8
  32. data/src/java/arjdbc/mssql/MSSQLModule.java +50 -19
  33. data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +1 -0
  34. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +6 -6
  35. data/src/java/arjdbc/oracle/OracleModule.java +1 -1
  36. data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +66 -2
  37. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +23 -10
  38. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +1 -0
  39. data/src/java/arjdbc/util/CallResultSet.java +826 -0
  40. data/src/java/arjdbc/util/QuotingUtils.java +14 -7
  41. metadata +8 -3
  42. data/lib/arjdbc/postgresql/array_parser.rb +0 -89
@@ -50,15 +50,15 @@ module ArJdbc
50
50
  def type_cast(value)
51
51
  return nil if value.nil?
52
52
  case type
53
- when :integer then value.delete('()').to_i rescue unquote(value).to_i rescue value ? 1 : 0
54
- when :primary_key then value == true || value == false ? value == true ? 1 : 0 : value.to_i
53
+ when :integer then ( value.is_a?(String) ? unquote(value) : (value || 0) ).to_i
54
+ when :primary_key then value.respond_to?(:to_i) ? value.to_i : ((value && 1) || 0)
55
55
  when :decimal then self.class.value_to_decimal(unquote(value))
56
56
  when :date then self.class.string_to_date(value)
57
57
  when :datetime then self.class.string_to_time(value)
58
58
  when :timestamp then self.class.string_to_time(value)
59
59
  when :time then self.class.string_to_dummy_time(value)
60
60
  when :boolean then value == true || (value =~ /^t(rue)?$/i) == 0 || unquote(value) == '1'
61
- when :binary then unquote value
61
+ when :binary then unquote(value)
62
62
  else value
63
63
  end
64
64
  end
@@ -156,7 +156,7 @@ module ArJdbc
156
156
  super(value)
157
157
  end
158
158
  end
159
-
159
+
160
160
  def string_to_binary(value)
161
161
  # this will only allow the adapter to insert binary data with a length
162
162
  # of 7K or less because of a SQL Server statement length policy ...
@@ -19,7 +19,9 @@ module ArJdbc
19
19
  # @private
20
20
  def init_connection(jdbc_connection)
21
21
  meta = jdbc_connection.meta_data
22
- if meta.driver_major_version < 5
22
+ if meta.driver_major_version == 1 # TODO check in driver code
23
+ # assumes MariaDB 1.x currently
24
+ elsif meta.driver_major_version < 5
23
25
  raise ::ActiveRecord::ConnectionNotEstablished,
24
26
  "MySQL adapter requires driver >= 5.0 got: '#{meta.driver_version}'"
25
27
  elsif meta.driver_major_version == 5 && meta.driver_minor_version < 1
@@ -328,11 +330,19 @@ module ArJdbc
328
330
  # @override
329
331
  def columns(table_name, name = nil)
330
332
  sql = "SHOW FULL COLUMNS FROM #{quote_table_name(table_name)}"
331
- column = ::ActiveRecord::ConnectionAdapters::MysqlAdapter::Column
332
333
  columns = execute(sql, name || 'SCHEMA')
334
+ strict = strict_mode?
335
+ column = jdbc_column_class
336
+ pass_cast_type = respond_to?(:lookup_cast_type)
333
337
  columns.map! do |field|
334
- column.new(field['Field'], field['Default'], field['Type'],
335
- field['Null'] == "YES", field['Collation'], field['Extra'])
338
+ sql_type = field['Type']
339
+ null = field['Null'] == "YES"
340
+ if pass_cast_type
341
+ cast_type = lookup_cast_type(sql_type)
342
+ column.new(field['Field'], field['Default'], cast_type, sql_type, null, field['Collation'], strict, field['Extra'])
343
+ else
344
+ column.new(field['Field'], field['Default'], sql_type, null, field['Collation'], strict, field['Extra'])
345
+ end
336
346
  end
337
347
  columns
338
348
  end
@@ -576,14 +586,20 @@ module ArJdbc
576
586
  return @version ||= begin
577
587
  version = []
578
588
  java_connection = jdbc_connection(true)
579
- if java_connection.is_a?(Java::ComMysqlJdbc::ConnectionImpl)
589
+ if java_connection.java_class.name == 'com.mysql.jdbc.ConnectionImpl'
580
590
  version << jdbc_connection.serverMajorVersion
581
591
  version << jdbc_connection.serverMinorVersion
582
592
  version << jdbc_connection.serverSubMinorVersion
583
593
  else
584
- warn "INFO: failed to resolve MySQL server version using: #{java_connection}"
594
+ result = execute 'SELECT VERSION()', 'SCHEMA'
595
+ result = result.first.values.first # [{"VERSION()"=>"5.5.37-0ubuntu..."}]
596
+ if match = result.match(/^(\d)\.(\d+)\.(\d+)/)
597
+ version << match[1].to_i
598
+ version << match[2].to_i
599
+ version << match[3].to_i
600
+ end
585
601
  end
586
- version
602
+ version.freeze
587
603
  end
588
604
  end
589
605
 
@@ -611,15 +627,26 @@ module ActiveRecord
611
627
  class Column < JdbcColumn
612
628
  include ::ArJdbc::MySQL::Column
613
629
 
614
- def initialize(name, default, sql_type = nil, null = true, collation = nil, strict = false, extra = "")
630
+ def initialize(name, default, sql_type = nil, null = true, collation = nil, strict = false, extra = '')
615
631
  if Hash === name
616
632
  super # first arg: config
617
633
  else
618
634
  @strict = strict; @collation = collation; @extra = extra
619
635
  super(name, default, sql_type, null)
636
+ # base 4.1: (name, default, sql_type = nil, null = true)
620
637
  end
621
638
  end
622
639
 
640
+ def initialize(name, default, cast_type, sql_type = nil, null = true, collation = nil, strict = false, extra = '')
641
+ if Hash === name
642
+ super # first arg: config
643
+ else
644
+ @strict = strict; @collation = collation; @extra = extra
645
+ super(name, default, cast_type, sql_type, null)
646
+ # base 4.2: (name, default, cast_type, sql_type = nil, null = true)
647
+ end
648
+ end if ActiveRecord::VERSION::STRING >= '4.2'
649
+
623
650
  # @note {#ArJdbc::MySQL::Column} uses this to check for boolean emulation
624
651
  def adapter
625
652
  MysqlAdapter
@@ -628,8 +655,7 @@ module ActiveRecord
628
655
  end
629
656
 
630
657
  def initialize(*args)
631
- super
632
- # configure_connection happens in super
658
+ super # configure_connection happens in super
633
659
  end
634
660
 
635
661
  def jdbc_connection_class(spec)
@@ -13,12 +13,9 @@ module ArJdbc
13
13
  attr_reader :collation, :strict, :extra
14
14
 
15
15
  def extract_default(default)
16
- if sql_type =~ /blob/i || type == :text
17
- if default.blank?
18
- return null ? nil : ''
19
- else
20
- raise ArgumentError, "#{type} columns cannot have a default value: #{default.inspect}"
21
- end
16
+ if blob_or_text_column?
17
+ return null || strict ? nil : '' if default.blank?
18
+ raise ArgumentError, "#{type} columns cannot have a default value: #{default.inspect}"
22
19
  elsif missing_default_forged_as_empty_string?(default)
23
20
  nil
24
21
  else
@@ -27,10 +24,18 @@ module ArJdbc
27
24
  end
28
25
 
29
26
  def has_default?
30
- return false if sql_type =~ /blob/i || type == :text #mysql forbids defaults on blob and text columns
27
+ return false if blob_or_text_column? #mysql forbids defaults on blob and text columns
31
28
  super
32
29
  end
33
30
 
31
+ def blob_or_text_column?
32
+ sql_type.index('blob') || type == :text
33
+ end
34
+
35
+ def case_sensitive?
36
+ collation && !collation.match(/_ci$/)
37
+ end
38
+
34
39
  def simplified_type(field_type)
35
40
  if adapter && adapter.emulate_booleans?
36
41
  return :boolean if field_type.downcase.index('tinyint(1)')
@@ -5,11 +5,14 @@ ArJdbc::ConnectionMethods.module_eval do
5
5
 
6
6
  return jndi_connection(config) if jndi_config?(config)
7
7
 
8
+ driver = config[:driver] ||=
9
+ defined?(::Jdbc::MySQL.driver_name) ? ::Jdbc::MySQL.driver_name : 'com.mysql.jdbc.Driver'
10
+
8
11
  begin
9
12
  require 'jdbc/mysql'
10
13
  ::Jdbc::MySQL.load_driver(:require) if defined?(::Jdbc::MySQL.load_driver)
11
14
  rescue LoadError # assuming driver.jar is on the class-path
12
- end
15
+ end if mysql_driver = driver[0, 10] == 'com.mysql.'
13
16
 
14
17
  config[:username] = 'root' unless config.key?(:username)
15
18
  # jdbc:mysql://[host][,failoverhost...][:port]/[database]
@@ -23,37 +26,66 @@ ArJdbc::ConnectionMethods.module_eval do
23
26
  url << "/#{config[:database]}"
24
27
  config[:url] = url
25
28
  end
26
- config[:driver] ||= defined?(::Jdbc::MySQL.driver_name) ? ::Jdbc::MySQL.driver_name : 'com.mysql.jdbc.Driver'
29
+
30
+ mariadb_driver = ! mysql_driver && driver[0, 12] == 'org.mariadb.' # org.mariadb.jdbc.Driver
27
31
 
28
32
  properties = ( config[:properties] ||= {} )
29
- properties['zeroDateTimeBehavior'] ||= 'convertToNull'
30
- properties['jdbcCompliantTruncation'] ||= 'false'
31
- properties['useUnicode'] = 'true' unless properties.key?('useUnicode') # otherwise platform default
32
- encoding = config.key?(:encoding) ? config[:encoding] : 'utf8'
33
- properties['characterEncoding'] = encoding if encoding
34
- if ! ( reconnect = config[:reconnect] ).nil?
35
- properties['autoReconnect'] ||= reconnect.to_s
36
- # properties['maxReconnects'] ||= '3'
37
- # with reconnect fail-over sets connection read-only (by default)
38
- # properties['failOverReadOnly'] ||= 'false'
33
+ if mysql_driver
34
+ properties['zeroDateTimeBehavior'] ||= 'convertToNull'
35
+ properties['jdbcCompliantTruncation'] ||= 'false'
36
+ properties['useUnicode'] = 'true' unless properties.key?('useUnicode') # otherwise platform default
37
+ encoding = config.key?(:encoding) ? config[:encoding] : 'utf8'
38
+ properties['characterEncoding'] = encoding if encoding
39
+ if ! ( reconnect = config[:reconnect] ).nil?
40
+ properties['autoReconnect'] ||= reconnect.to_s
41
+ # properties['maxReconnects'] ||= '3'
42
+ # with reconnect fail-over sets connection read-only (by default)
43
+ # properties['failOverReadOnly'] ||= 'false'
44
+ end
39
45
  end
40
46
  if config[:sslkey] || sslcert = config[:sslcert] # || config[:use_ssl]
41
- properties['useSSL'] ||= true
42
- properties['requireSSL'] ||= true
43
- properties['clientCertificateKeyStoreUrl'] ||= begin
44
- java.io.File.new(sslcert).to_url.to_s
45
- end if sslcert
46
- if sslca = config[:sslca]
47
- properties['trustCertificateKeyStoreUrl'] ||= begin
48
- java.io.File.new(sslca).to_url.to_s
47
+ properties['useSSL'] ||= true # supported by MariaDB as well
48
+ if mysql_driver
49
+ properties['requireSSL'] ||= true if mysql_driver
50
+ properties['clientCertificateKeyStoreUrl'] ||= begin
51
+ java.io.File.new(sslcert).to_url.to_s
52
+ end if sslcert
53
+ if sslca = config[:sslca]
54
+ properties['trustCertificateKeyStoreUrl'] ||= begin
55
+ java.io.File.new(sslca).to_url.to_s
56
+ end
57
+ else
58
+ properties['verifyServerCertificate'] ||= false if mysql_driver
49
59
  end
50
- else
60
+ end
61
+ if mariadb_driver
51
62
  properties['verifyServerCertificate'] ||= false
52
63
  end
53
64
  end
65
+ if socket = config[:socket]
66
+ properties['localSocket'] ||= socket if mariadb_driver
67
+ end
54
68
 
55
69
  jdbc_connection(config)
56
70
  end
57
71
  alias_method :jdbcmysql_connection, :mysql_connection
58
72
  alias_method :mysql2_connection, :mysql_connection
73
+
74
+ def mariadb_connection(config)
75
+ config[:adapter_spec] ||= ::ArJdbc::MySQL
76
+ config[:adapter_class] = ActiveRecord::ConnectionAdapters::MysqlAdapter unless config.key?(:adapter_class)
77
+
78
+ return jndi_connection(config) if jndi_config?(config)
79
+
80
+ begin
81
+ require 'jdbc/mariadb'
82
+ ::Jdbc::MariaDB.load_driver(:require) if defined?(::Jdbc::MariaDB.load_driver)
83
+ rescue LoadError # assuming driver.jar is on the class-path
84
+ end
85
+
86
+ config[:driver] ||= 'org.mariadb.jdbc.Driver'
87
+
88
+ mysql_connection(config)
89
+ end
90
+ alias_method :jdbcmariadb_connection, :mariadb_connection
59
91
  end
@@ -544,9 +544,11 @@ module ArJdbc
544
544
  end
545
545
 
546
546
  if pk && use_insert_returning? # true by default on AR <= 3.0
547
- sql = "#{sql} RETURNING #{quote_column_name(pk)}"
547
+ sql = "#{sql} RETURNING #{quote_column_name(pk)} INTO ?"
548
+ exec_insert_returning(sql, name, nil, pk)
549
+ else
550
+ execute(sql, name)
548
551
  end
549
- execute(sql, name)
550
552
  end
551
553
  protected :insert_sql
552
554
 
@@ -554,7 +556,7 @@ module ArJdbc
554
556
  def sql_for_insert(sql, pk, id_value, sequence_name, binds)
555
557
  unless id_value || pk.nil?
556
558
  if pk && use_insert_returning?
557
- sql = "#{sql} RETURNING #{quote_column_name(pk)}"
559
+ sql = "#{sql} RETURNING #{quote_column_name(pk)} INTO ?"
558
560
  end
559
561
  end
560
562
  [ sql, binds ]
@@ -577,11 +579,22 @@ module ArJdbc
577
579
  # @override
578
580
  def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
579
581
  if pk && use_insert_returning?
580
- exec_query(sql, name, binds) # due RETURNING clause
582
+ if sql.is_a?(String) && sql.index('RETURNING')
583
+ return exec_insert_returning(sql, name, binds, pk)
584
+ end
585
+ end
586
+ super(sql, name, binds) # assume no generated id for table
587
+ end
588
+
589
+ def exec_insert_returning(sql, name, binds, pk = nil)
590
+ sql = to_sql(sql, binds) if sql.respond_to?(:to_sql)
591
+ if prepared_statements?
592
+ log(sql, name, binds) { @connection.execute_insert_returning(sql, binds) }
581
593
  else
582
- super(sql, name, binds) # assume no generated id for table
594
+ log(sql, name) { @connection.execute_insert_returning(sql, nil) }
583
595
  end
584
596
  end
597
+ # private :exec_insert_returning
585
598
 
586
599
  def next_id_value(sql, sequence_name = nil)
587
600
  # Assume the SQL contains a bind-variable for the ID
@@ -670,6 +683,10 @@ module ActiveRecord::ConnectionAdapters
670
683
 
671
684
  class OracleColumn < JdbcColumn
672
685
  include ::ArJdbc::Oracle::Column
686
+
687
+ # def returning_id?; @returning_id ||= nil end
688
+ # def returning_id!; @returning_id = true end
689
+
673
690
  end
674
691
 
675
692
  end
@@ -158,6 +158,9 @@ module ArJdbc
158
158
  when 'point'
159
159
  column_class = ::ActiveRecord::ConnectionAdapters::PostgreSQLColumn
160
160
  column_class.point_to_string(value)
161
+ when 'json'
162
+ column_class = ::ActiveRecord::ConnectionAdapters::PostgreSQLColumn
163
+ column_class.json_to_string(value)
161
164
  else
162
165
  return super(value, column) unless column.array?
163
166
  column_class = ::ActiveRecord::ConnectionAdapters::PostgreSQLColumn
@@ -822,10 +825,8 @@ module ArJdbc
822
825
  when String
823
826
  return "E'#{escape_bytea(value)}'::bytea" if column.type == :binary
824
827
  return "xml '#{quote_string(value)}'" if column.type == :xml
825
- if column.respond_to?(:sql_type) && column.sql_type[0, 3] == 'bit'
826
- quote_bit(value)
827
- else super
828
- end
828
+ sql_type = column.respond_to?(:sql_type) && column.sql_type
829
+ sql_type && sql_type[0, 3] == 'bit' ? quote_bit(value) : super
829
830
  when Array
830
831
  if AR4_COMPAT && column.array? # will be always falsy in AR < 4.0
831
832
  column_class = ::ActiveRecord::ConnectionAdapters::PostgreSQLColumn
@@ -833,6 +834,9 @@ module ArJdbc
833
834
  elsif column.type == :json # only in AR-4.0
834
835
  column_class = ::ActiveRecord::ConnectionAdapters::PostgreSQLColumn
835
836
  super(column_class.json_to_string(value), column)
837
+ elsif column.type == :point # only in AR-4.0
838
+ column_class = ::ActiveRecord::ConnectionAdapters::PostgreSQLColumn
839
+ super(column_class.point_to_string(value), column)
836
840
  else super
837
841
  end
838
842
  when Hash
@@ -891,14 +895,13 @@ module ArJdbc
891
895
  end if PostgreSQL::AR4_COMPAT
892
896
 
893
897
  def escape_bytea(string)
894
- if string
895
- if supports_hex_escaped_bytea?
896
- "\\\\x#{string.unpack("H*")[0]}"
897
- else
898
- result = ''
899
- string.each_byte { |c| result << sprintf('\\\\%03o', c) }
900
- result
901
- end
898
+ return unless string
899
+ if supports_hex_escaped_bytea?
900
+ "\\\\x#{string.unpack("H*")[0]}"
901
+ else
902
+ result = ''
903
+ string.each_byte { |c| result << sprintf('\\\\%03o', c) }
904
+ result
902
905
  end
903
906
  end
904
907
 
@@ -917,13 +920,23 @@ module ArJdbc
917
920
  # @override
918
921
  def quote_table_name_for_assignment(table, attr)
919
922
  quote_column_name(attr)
920
- end if ::ActiveRecord::VERSION::MAJOR > 3
923
+ end if ::ActiveRecord::VERSION::MAJOR >= 4
921
924
 
922
925
  # @override
923
926
  def quote_column_name(name)
924
927
  %("#{name.to_s.gsub("\"", "\"\"")}")
925
928
  end
926
929
 
930
+ # @private
931
+ def quote_default_value(value, column)
932
+ # Do not quote function default values for UUID columns
933
+ if column.type == :uuid && value =~ /\(\)/
934
+ value
935
+ else
936
+ quote(value, column)
937
+ end
938
+ end
939
+
927
940
  # Quote date/time values for use in SQL input.
928
941
  # Includes microseconds if the value is a Time responding to `usec`.
929
942
  # @override
@@ -1017,12 +1030,20 @@ module ArJdbc
1017
1030
 
1018
1031
  # Changes the default value of a table column.
1019
1032
  def change_column_default(table_name, column_name, default)
1020
- execute "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} SET DEFAULT #{quote(default)}"
1033
+ if column = column_for(table_name, column_name) # (backwards) compatible with AR 3.x - 4.x
1034
+ execute "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} SET DEFAULT #{quote_default_value(default, column)}"
1035
+ else
1036
+ execute "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} SET DEFAULT #{quote(default)}"
1037
+ end
1021
1038
  end # unless const_defined? :SchemaCreation
1022
1039
 
1023
1040
  def change_column_null(table_name, column_name, null, default = nil)
1024
1041
  unless null || default.nil?
1025
- execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
1042
+ if column = column_for(table_name, column_name) # (backwards) compatible with AR 3.x - 4.x
1043
+ execute "UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote_default_value(default, column)} WHERE #{quote_column_name(column_name)} IS NULL"
1044
+ else
1045
+ execute "UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL"
1046
+ end
1026
1047
  end
1027
1048
  execute("ALTER TABLE #{quote_table_name(table_name)} ALTER #{quote_column_name(column_name)} #{null ? 'DROP' : 'SET'} NOT NULL")
1028
1049
  end # unless const_defined? :SchemaCreation
@@ -1061,10 +1082,15 @@ module ArJdbc
1061
1082
  elsif default =~ /^\(([-+]?[\d\.]+)\)$/ # e.g. "(-1)" for a negative default
1062
1083
  default = $1
1063
1084
  end
1064
- klass.new(name, default, oid, type, ! notnull)
1085
+ klass.new(name, default, oid, type, ! notnull, fmod, self)
1065
1086
  end
1066
1087
  end
1067
1088
 
1089
+ # @private
1090
+ def column_for(table_name, column_name)
1091
+ columns(table_name).detect { |c| c.name == column_name.to_s }
1092
+ end
1093
+
1068
1094
  # Returns the list of a table's column names, data types, and default values.
1069
1095
  #
1070
1096
  # If the table name is not prefixed with a schema, the database will
@@ -1237,8 +1263,12 @@ module ActiveRecord::ConnectionAdapters
1237
1263
  class PostgreSQLColumn < JdbcColumn
1238
1264
  include ::ArJdbc::PostgreSQL::Column
1239
1265
 
1240
- def initialize(name, default, oid_type = nil, sql_type = nil, null = true)
1241
- if oid_type.is_a?(Integer) then @oid_type = oid_type
1266
+ def initialize(name, default, oid_type = nil, sql_type = nil, null = true,
1267
+ fmod = nil, adapter = nil) # added due resolving #oid_type
1268
+ if oid_type.is_a?(Integer) # the "main" if branch (on AR 4.x)
1269
+ @oid = oid_type; @fmod = fmod; @adapter = adapter # see Column#oid_type
1270
+ elsif oid_type.respond_to?(:type_cast) # MRI compatibility
1271
+ @oid_type = oid_type; # @fmod = fmod; @adapter = adapter
1242
1272
  else # NOTE: AR <= 3.2 : (name, default, sql_type = nil, null = true)
1243
1273
  null, sql_type, oid_type = !! sql_type, oid_type, nil
1244
1274
  end
@@ -1261,11 +1291,17 @@ module ActiveRecord::ConnectionAdapters
1261
1291
 
1262
1292
  end
1263
1293
 
1294
+ # NOTE: seems needed on 4.x due loading of '.../postgresql/oid' which
1295
+ # assumes: class PostgreSQLAdapter < AbstractAdapter
1264
1296
  remove_const(:PostgreSQLAdapter) if const_defined?(:PostgreSQLAdapter)
1265
1297
 
1266
1298
  class PostgreSQLAdapter < JdbcAdapter
1267
1299
  include ::ArJdbc::PostgreSQL
1268
1300
  include ::ArJdbc::PostgreSQL::ExplainSupport
1301
+
1302
+ require 'arjdbc/postgresql/oid_types' if ::ArJdbc::PostgreSQL::AR4_COMPAT
1303
+ include ::ArJdbc::PostgreSQL::OIDTypes if ::ArJdbc::PostgreSQL.const_defined?(:OIDTypes)
1304
+
1269
1305
  include ::ArJdbc::Util::QuotedCache
1270
1306
 
1271
1307
  def initialize(*args)