activerecord-jdbc-adapter 1.1.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/.gemtest +0 -0
  2. data/History.txt +39 -0
  3. data/Manifest.txt +3 -0
  4. data/lib/arel/visitors/firebird.rb +17 -0
  5. data/lib/arel/visitors/sql_server.rb +2 -4
  6. data/lib/arjdbc/db2/adapter.rb +8 -0
  7. data/lib/arjdbc/derby/adapter.rb +7 -3
  8. data/lib/arjdbc/firebird/adapter.rb +5 -0
  9. data/lib/arjdbc/hsqldb/adapter.rb +5 -7
  10. data/lib/arjdbc/jdbc/adapter.rb +1 -1
  11. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  12. data/lib/arjdbc/jdbc/column.rb +13 -4
  13. data/lib/arjdbc/jdbc/connection.rb +7 -5
  14. data/lib/arjdbc/jdbc/discover.rb +2 -2
  15. data/lib/arjdbc/jdbc/driver.rb +4 -13
  16. data/lib/arjdbc/jdbc/jdbc.rake +6 -2
  17. data/lib/arjdbc/mssql/adapter.rb +1 -1
  18. data/lib/arjdbc/mssql/limit_helpers.rb +13 -7
  19. data/lib/arjdbc/mysql/adapter.rb +12 -3
  20. data/lib/arjdbc/oracle/adapter.rb +16 -10
  21. data/lib/arjdbc/postgresql/adapter.rb +30 -11
  22. data/lib/arjdbc/sqlite3/adapter.rb +1 -1
  23. data/lib/arjdbc/version.rb +1 -1
  24. data/rakelib/package.rake +1 -0
  25. data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +62 -0
  26. data/src/java/arjdbc/jdbc/AdapterJavaService.java +2 -0
  27. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +59 -36
  28. data/test/models/add_not_null_column_to_table.rb +0 -3
  29. data/test/models/auto_id.rb +0 -3
  30. data/test/models/data_types.rb +5 -3
  31. data/test/models/entry.rb +0 -3
  32. data/test/models/mixed_case.rb +0 -3
  33. data/test/models/reserved_word.rb +0 -3
  34. data/test/models/string_id.rb +0 -3
  35. data/test/mysql_info_test.rb +1 -1
  36. data/test/postgres_db_create_test.rb +1 -1
  37. data/test/postgres_information_schema_leak_test.rb +29 -0
  38. data/test/postgres_schema_search_path_test.rb +5 -1
  39. data/test/postgres_simple_test.rb +25 -0
  40. data/test/simple.rb +14 -3
  41. metadata +8 -4
File without changes
@@ -1,3 +1,42 @@
1
+ == 1.1.2
2
+
3
+ - Update version of H2 driver from 1.1.107 to 1.3.153 (Ketan
4
+ Padegaonkar, Jeremy Stephens)
5
+ - Fix errors in db:test:clone_structure with PostgreSQL (Andrea Campi)
6
+ - Fixing limit for sqlServer2000 if primary key is not named 'id'
7
+ (Luca Simone)
8
+ - DB2: define jdbc_columns (fixes table_exists? bug) (Nick Kreucher)
9
+ - ACTIVERECORD_JDBC-152 - omitting limit when dumping bytea fields
10
+ (Gregor Schmidt)
11
+ - Postgres doesn't support a limit for bytea columns (Alex Tambellini)
12
+ - JRUBY-5642: Default to schema public if no schema given for postgres
13
+ (Anthony Juckel)
14
+ - Sqlite3 supports float data type so use float (Alex Tambellini)
15
+ - GH #21: Now using sqlite3 driver from
16
+ http://www.xerial.org/trac/Xerial/wiki/SQLiteJDBC (thanks Ukabu)
17
+ - GH #65: PG: Respect integer sizes (Alex Tambellini)
18
+ - GH #59: PG: Properly escape bytea-escaped string
19
+ - GH #53: oracle: allow configuration of schema through schema: key
20
+ - GH #50: PG: support multiple schema in search_path (Daniel
21
+ Schreiber)
22
+ - GH #25: Reload ArJdbc.column_types if number of constants changed
23
+ - GH #47: Allow table statistics for indexes to be approximate; speeds
24
+ up Oracle
25
+ - GH #67: Change primary_keys to use the same catalog/schema/table
26
+ separation logic as columns_internal (Marcus Brito). This change
27
+ allows set_table_name to specify a custom schema.
28
+ - GH #49: mssql: quote table names like column names
29
+ - GH #56: mssql: Fix 'select 1' behavior introduced by AR 3.0.7
30
+ - GH #55: Make decimal columns with no precision or scale stay
31
+ decimals
32
+ - GH #45: Add Arel limit support for Firebird (Systho))
33
+ - GH #39: PG: allow negative integer default values
34
+ - GH #19: Make a stub Mysql::Error class
35
+ - ACTIVERECORD_JDBC-148: mssql: Ensure regex doesn't match 'from' in a
36
+ field name
37
+ - GH#31: mssql: Remove extra code breaking mssql w/o limit
38
+ - ACTIVERECORD_JDBC-156: mssql: Logic fix for detecting select_count?
39
+
1
40
  == 1.1.1
2
41
 
3
42
  - Arel 2.0.7 compatibility: fix bugs arising from use of Arel 2.0.7 +
@@ -28,6 +28,7 @@ lib/arel/engines/sql/compilers/mssql_compiler.rb
28
28
  lib/arel/visitors/compat.rb
29
29
  lib/arel/visitors/db2.rb
30
30
  lib/arel/visitors/derby.rb
31
+ lib/arel/visitors/firebird.rb
31
32
  lib/arel/visitors/hsqldb.rb
32
33
  lib/arel/visitors/sql_server.rb
33
34
  lib/arjdbc/db2.rb
@@ -122,6 +123,7 @@ test/oracle_specific_test.rb
122
123
  test/pick_rails_version.rb
123
124
  test/postgres_db_create_test.rb
124
125
  test/postgres_drop_db_test.rb
126
+ test/postgres_information_schema_leak_test.rb
125
127
  test/postgres_mixed_case_test.rb
126
128
  test/postgres_nonseq_pkey_test.rb
127
129
  test/postgres_reserved_test.rb
@@ -155,6 +157,7 @@ test/models/reserved_word.rb
155
157
  test/models/string_id.rb
156
158
  test/models/validates_uniqueness_of_string.rb
157
159
  lib/arjdbc/jdbc/jdbc.rake
160
+ src/java/arjdbc/db2/DB2RubyJdbcConnection.java
158
161
  src/java/arjdbc/derby/DerbyModule.java
159
162
  src/java/arjdbc/h2/H2RubyJdbcConnection.java
160
163
  src/java/arjdbc/informix/InformixRubyJdbcConnection.java
@@ -0,0 +1,17 @@
1
+ require 'arel/visitors/compat'
2
+
3
+ module Arel
4
+ module Visitors
5
+ class Firebird < Arel::Visitors::ToSql
6
+ def visit_Arel_Nodes_SelectStatement o
7
+ [
8
+ o.cores.map { |x| visit_Arel_Nodes_SelectCore x }.join,
9
+ ("ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?),
10
+ ("ROWS #{limit_for(o.limit)} " if o.limit),
11
+ ("TO #{o.offset} " if o.offset),
12
+ ].compact.join ' '
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -7,8 +7,8 @@ module Arel
7
7
 
8
8
  def select_count? o
9
9
  sel = o.cores.length == 1 && o.cores.first
10
- projections = sel.projections.length == 1 && sel.projections
11
- Arel::Nodes::Count === projections.first
10
+ projections = sel && sel.projections.length == 1 && sel.projections
11
+ projections && Arel::Nodes::Count === projections.first
12
12
  end
13
13
 
14
14
  # Need to mimic the subquery logic in ARel 1.x for select count with limit
@@ -30,8 +30,6 @@ module Arel
30
30
  order ||= "ORDER BY #{@connection.determine_order_clause(sql)}"
31
31
  replace_limit_offset!(sql, limit_for(o.limit).to_i, o.offset && o.offset.value.to_i, order)
32
32
  sql = "SELECT COUNT(*) AS count_id FROM (#{sql}) AS subquery" if subquery
33
- elsif order
34
- sql << " #{order}"
35
33
  else
36
34
  sql = super
37
35
  end
@@ -5,6 +5,10 @@ module ArJdbc
5
5
  lambda { |cfg, column| column.extend(::ArJdbc::DB2::Column) } ]
6
6
  end
7
7
 
8
+ def self.jdbc_connection_class
9
+ ::ActiveRecord::ConnectionAdapters::DB2JdbcConnection
10
+ end
11
+
8
12
  module Column
9
13
  def type_cast(value)
10
14
  return nil if value.nil? || value =~ /^\s*null\s*$/i
@@ -319,6 +323,10 @@ module ArJdbc
319
323
  cols
320
324
  end
321
325
 
326
+ def jdbc_columns(table_name, name = nil)
327
+ columns(table_name, name)
328
+ end
329
+
322
330
  def indexes(table_name, name = nil)
323
331
  @connection.indexes(table_name, name, db2_schema)
324
332
  end
@@ -37,9 +37,13 @@ module ::ArJdbc
37
37
 
38
38
  module Column
39
39
  def simplified_type(field_type)
40
- return :boolean if field_type =~ /smallint/i
41
- return :float if field_type =~ /real/i
42
- super
40
+ case field_type
41
+ when /smallint/i then :boolean
42
+ when /real/i then :float
43
+ when /decimal/i then :decimal
44
+ else
45
+ super
46
+ end
43
47
  end
44
48
 
45
49
  # Post process default value from JDBC into a Rails-friendly format (columns{-internal})
@@ -23,6 +23,11 @@ module ::ArJdbc
23
23
  'Firebird'
24
24
  end
25
25
 
26
+ def arel2_visitors
27
+ require 'arel/visitors/firebird'
28
+ {'firebird' => ::Arel::Visitors::Firebird, 'firebirdsql' => ::Arel::Visitors::Firebird}
29
+ end
30
+
26
31
  def modify_types(tp)
27
32
  tp[:primary_key] = 'INTEGER NOT NULL PRIMARY KEY'
28
33
  tp[:string][:limit] = 252
@@ -8,14 +8,12 @@ module ::ArJdbc
8
8
  private
9
9
  def simplified_type(field_type)
10
10
  case field_type
11
- when /longvarchar/i
12
- :text
13
- when /tinyint/i
14
- :boolean
15
- when /real/i
16
- :float
11
+ when /longvarchar/i then :text
12
+ when /tinyint/i then :boolean
13
+ when /real/i then :float
14
+ when /decimal/i then :decimal
17
15
  else
18
- super(field_type)
16
+ super
19
17
  end
20
18
  end
21
19
 
@@ -75,7 +75,7 @@ module ActiveRecord
75
75
  config[:username] ||= conn.getMetaData.getUserName
76
76
  end
77
77
  rescue
78
- conn.close
78
+ conn.close if conn
79
79
  end
80
80
  end
81
81
  nil
@@ -17,13 +17,22 @@ module ActiveRecord
17
17
  end
18
18
 
19
19
  def self.column_types
20
- @column_types ||= ::ArJdbc.constants.map{|c|
21
- ::ArJdbc.const_get c }.select{ |c|
22
- c.respond_to? :column_selector }.map{|c|
23
- c.column_selector }.inject({}) { |h,val|
20
+ # GH #25: reset the column types if the # of constants changed
21
+ # since last call
22
+ if ::ArJdbc.constants.size != driver_constants.size
23
+ @driver_constants = nil
24
+ @column_types = nil
25
+ end
26
+ @column_types ||= driver_constants.select {|c|
27
+ c.respond_to? :column_selector }.map {|c|
28
+ c.column_selector }.inject({}) {|h,val|
24
29
  h[val[0]] = val[1]; h }
25
30
  end
26
31
 
32
+ def self.driver_constants
33
+ @driver_constants ||= ::ArJdbc.constants.map {|c| ::ArJdbc.const_get c }
34
+ end
35
+
27
36
  protected
28
37
  def call_discovered_column_callbacks(config)
29
38
  dialect = config[:dialect] || config[:driver]
@@ -5,7 +5,7 @@ module ActiveRecord
5
5
  attr_reader :config
6
6
 
7
7
  def config=(config)
8
- @config = config.symbolize_keys!
8
+ @config = config.symbolize_keys
9
9
  end
10
10
 
11
11
  def configure_connection
@@ -62,9 +62,7 @@ module ActiveRecord
62
62
  user = config[:username].to_s
63
63
  pass = config[:password].to_s
64
64
  url = configure_url
65
-
66
- jdbc_driver = JdbcDriver.new(driver)
67
- jdbc_driver.load
65
+ jdbc_driver = (config[:driver_instance] ||= JdbcDriver.new(driver))
68
66
  @connection_factory = JdbcConnectionFactory.impl do
69
67
  jdbc_driver.connection(url, user, pass)
70
68
  end
@@ -90,13 +88,17 @@ module ActiveRecord
90
88
  rescue ::ActiveRecord::ActiveRecordError
91
89
  raise
92
90
  rescue Exception => e
93
- raise "The driver encountered an unknown error: #{e}"
91
+ raise ::ActiveRecord::JDBCError.new("The driver encountered an unknown error: #{e}").tap do |err|
92
+ err.errno = 0
93
+ err.sql_exception = e
94
+ end
94
95
  end
95
96
 
96
97
  def adapter=(adapter)
97
98
  @adapter = adapter
98
99
  @native_database_types = dup_native_types
99
100
  @adapter.modify_types(@native_database_types)
101
+ @adapter.config.replace(config)
100
102
  end
101
103
 
102
104
  # Duplicate all native types into new hash structure so it can be modified
@@ -1,7 +1,7 @@
1
1
  module ArJdbc
2
2
  def self.discover_extensions
3
- if defined?(::Gem)
4
- files = Gem.find_files('arjdbc/discover')
3
+ if defined?(::Gem) && ::Gem.respond_to?(:find_files)
4
+ files = ::Gem.find_files('arjdbc/discover')
5
5
  else
6
6
  files = $LOAD_PATH.map do |p|
7
7
  discover = File.join(p, 'arjdbc','discover.rb')
@@ -3,6 +3,7 @@ module ActiveRecord
3
3
  class JdbcDriver
4
4
  def initialize(name)
5
5
  @name = name
6
+ @driver = driver_class.new
6
7
  end
7
8
 
8
9
  def driver_class
@@ -12,32 +13,22 @@ module ActiveRecord
12
13
  unless Jdbc.const_defined?(driver_class_const)
13
14
  driver_class_name = @name
14
15
  Jdbc.module_eval do
15
- include_class(driver_class_name) { driver_class_const }
16
+ java_import(driver_class_name) { driver_class_const }
16
17
  end
17
18
  end
18
19
  end
19
20
  driver_class = Jdbc.const_get(driver_class_const)
20
- raise "You specify a driver for your JDBC connection" unless driver_class
21
+ raise "You must specify a driver for your JDBC connection" unless driver_class
21
22
  driver_class
22
23
  end
23
24
  end
24
25
 
25
- def load
26
- Jdbc::DriverManager.registerDriver(create)
27
- end
28
-
29
26
  def connection(url, user, pass)
30
- Jdbc::DriverManager.getConnection(url, user, pass)
31
- rescue
32
27
  # bypass DriverManager to get around problem with dynamically loaded jdbc drivers
33
28
  props = java.util.Properties.new
34
29
  props.setProperty("user", user)
35
30
  props.setProperty("password", pass)
36
- create.connect(url, props)
37
- end
38
-
39
- def create
40
- driver_class.new
31
+ @driver.connect(url, props)
41
32
  end
42
33
  end
43
34
  end
@@ -54,8 +54,12 @@ namespace :db do
54
54
  if config['adapter'] =~ /postgresql/i
55
55
  config = config.dup
56
56
  if config['url']
57
- db = config['url'][/\/([^\/]*)$/, 1]
58
- config['url'][/\/([^\/]*)$/, 1] = 'postgres' if db
57
+ url = config['url'].dup
58
+ db = url[/\/([^\/]*)$/, 1]
59
+ if db
60
+ url[/\/([^\/]*)$/, 1] = 'postgres'
61
+ config['url'] = url
62
+ end
59
63
  else
60
64
  db = config['database']
61
65
  config['database'] = 'postgres'
@@ -217,7 +217,7 @@ module ::ArJdbc
217
217
  end
218
218
 
219
219
  def quote_table_name(name)
220
- name
220
+ quote_column_name(name)
221
221
  end
222
222
 
223
223
  def quote_column_name(name)
@@ -5,7 +5,7 @@ module ::ArJdbc
5
5
  def get_table_name(sql)
6
6
  if sql =~ /^\s*insert\s+into\s+([^\(\s,]+)\s*|^\s*update\s+([^\(\s,]+)\s*/i
7
7
  $1
8
- elsif sql =~ /from\s+([^\(\s,]+)\s*/i
8
+ elsif sql =~ /\bfrom\s+([^\(\s,]+)\s*/i
9
9
  $1
10
10
  else
11
11
  nil
@@ -31,14 +31,15 @@ module ::ArJdbc
31
31
  rest = rest_of_query[/FROM/i=~ rest_of_query.. -1]
32
32
  #need the table name for avoiding amiguity
33
33
  table_name = LimitHelpers.get_table_name(sql)
34
+ primary_key = order[/(\w*id\w*)/i]
34
35
  #I am not sure this will cover all bases. but all the tests pass
35
- new_order = "ORDER BY #{order}, #{table_name}.id" if order.index("#{table_name}.id").nil?
36
+ new_order = "ORDER BY #{order}, #{table_name}.#{primary_key}" if order.index("#{table_name}.#{primary_key}").nil?
36
37
  new_order ||= order
37
38
 
38
39
  if (rest_of_query.match(/WHERE/).nil?)
39
- new_sql = "#{select} TOP #{limit} #{rest_of_query} WHERE #{table_name}.id NOT IN (#{select} TOP #{offset} #{table_name}.id #{rest} #{new_order}) #{order} "
40
+ new_sql = "#{select} TOP #{limit} #{rest_of_query} WHERE #{table_name}.#{primary_key} NOT IN (#{select} TOP #{offset} #{table_name}.#{primary_key} #{rest} #{new_order}) #{order} "
40
41
  else
41
- new_sql = "#{select} TOP #{limit} #{rest_of_query} AND #{table_name}.id NOT IN (#{select} TOP #{offset} #{table_name}.id #{rest} #{new_order}) #{order} "
42
+ new_sql = "#{select} TOP #{limit} #{rest_of_query} AND #{table_name}.#{primary_key} NOT IN (#{select} TOP #{offset} #{table_name}.#{primary_key} #{rest} #{new_order}) #{order} "
42
43
  end
43
44
 
44
45
  sql.replace(new_sql)
@@ -67,10 +68,15 @@ module ::ArJdbc
67
68
  end_row = offset + limit.to_i
68
69
  find_select = /\b(SELECT(?:\s+DISTINCT)?)\b(.*)/im
69
70
  whole, select, rest_of_query = find_select.match(sql).to_a
70
- if rest_of_query.strip!.first == '*'
71
- from_table = /.*FROM\s*\b(\w*)\b/i.match(rest_of_query).to_a[1]
71
+ rest_of_query.strip!
72
+ if rest_of_query.first == "1"
73
+ rest_of_query[0] = "*"
72
74
  end
73
- new_sql = "#{select} t.* FROM (SELECT ROW_NUMBER() OVER(#{order}) AS _row_num, #{from_table + '.' if from_table}#{rest_of_query}"
75
+ if rest_of_query.first == "*"
76
+ from_table = LimitHelpers.get_table_name(rest_of_query)
77
+ rest_of_query = from_table + '.' + rest_of_query
78
+ end
79
+ new_sql = "#{select} t.* FROM (SELECT ROW_NUMBER() OVER(#{order}) AS _row_num, #{rest_of_query}"
74
80
  new_sql << ") AS t WHERE t._row_num BETWEEN #{start_row.to_s} AND #{end_row.to_s}"
75
81
  sql.replace(new_sql)
76
82
  end
@@ -39,9 +39,13 @@ module ::ArJdbc
39
39
  end
40
40
 
41
41
  def simplified_type(field_type)
42
- return :boolean if field_type =~ /tinyint\(1\)|bit/i
43
- return :string if field_type =~ /enum/i
44
- super
42
+ case field_type
43
+ when /tinyint\(1\)|bit/i then :boolean
44
+ when /enum/i then :string
45
+ when /decimal/i then :decimal
46
+ else
47
+ super
48
+ end
45
49
  end
46
50
 
47
51
  def extract_limit(sql_type)
@@ -410,6 +414,11 @@ module ActiveRecord::ConnectionAdapters
410
414
  end
411
415
 
412
416
  module Mysql # :nodoc:
417
+ remove_const(:Error) if const_defined?(:Error)
418
+
419
+ class Error < ::ActiveRecord::JDBCError
420
+ end
421
+
413
422
  def self.client_version
414
423
  50400 # faked out for AR tests
415
424
  end
@@ -23,9 +23,9 @@ module ::ArJdbc
23
23
  end
24
24
  require 'arjdbc/jdbc/quoted_primary_key'
25
25
  ActiveRecord::Base.extend ArJdbc::QuotedPrimaryKeyExtension
26
- mod.class.class_eval do
27
- alias_chained_method :insert, :query_dirty, :insert
28
- alias_chained_method :columns, :query_cache, :columns
26
+ (class << mod; self; end).class_eval do
27
+ alias_chained_method :insert, :query_dirty, :ora_insert
28
+ alias_chained_method :columns, :query_cache, :ora_columns
29
29
  end
30
30
  end
31
31
 
@@ -68,6 +68,7 @@ module ::ArJdbc
68
68
  end
69
69
 
70
70
  def self.guess_date_or_time(value)
71
+ return value if Date === value
71
72
  (value && value.hour == 0 && value.min == 0 && value.sec == 0) ?
72
73
  Date.new(value.year, value.month, value.day) : value
73
74
  end
@@ -128,7 +129,7 @@ module ::ArJdbc
128
129
 
129
130
  def create_table(name, options = {}) #:nodoc:
130
131
  super(name, options)
131
- seq_name = options[:sequence_name] || "#{name}_seq"
132
+ seq_name = options[:sequence_name] || default_sequence_name(name)
132
133
  start_value = options[:sequence_start_value] || 10000
133
134
  raise ActiveRecord::StatementInvalid.new("name #{seq_name} too long") if seq_name.length > table_alias_length
134
135
  execute "CREATE SEQUENCE #{seq_name} START WITH #{start_value}" unless options[:id] == false
@@ -140,8 +141,8 @@ module ::ArJdbc
140
141
  end
141
142
 
142
143
  def drop_table(name, options = {}) #:nodoc:
143
- super(name)
144
- seq_name = options[:sequence_name] || "#{name}_seq"
144
+ super(name) rescue nil
145
+ seq_name = options[:sequence_name] || default_sequence_name(name)
145
146
  execute "DROP SEQUENCE #{seq_name}" rescue nil
146
147
  end
147
148
 
@@ -162,7 +163,7 @@ module ::ArJdbc
162
163
  defined?(::Arel::SqlLiteral) && ::Arel::SqlLiteral === value
163
164
  end
164
165
 
165
- def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
166
+ def ora_insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
166
167
  if (id_value && !sql_literal?(id_value)) || pk.nil?
167
168
  # Pre-assigned id or table without a primary key
168
169
  # Presence of #to_sql means an Arel literal bind variable
@@ -333,7 +334,7 @@ module ::ArJdbc
333
334
  @connection.tables(nil, oracle_schema)
334
335
  end
335
336
 
336
- def columns(table_name, name=nil)
337
+ def ora_columns(table_name, name=nil)
337
338
  @connection.columns_internal(table_name, name, oracle_schema)
338
339
  end
339
340
 
@@ -394,10 +395,15 @@ module ::ArJdbc
394
395
  end
395
396
 
396
397
  private
397
- # In Oracle, schemas are created under your username:
398
+ # In Oracle, schemas are usually created under your username:
398
399
  # http://www.oracle.com/technology/obe/2day_dba/schema/schema.htm
400
+ # But allow separate configuration as "schema:" anyway (GH #53)
399
401
  def oracle_schema
400
- @config[:username].to_s if @config[:username]
402
+ if @config[:schema]
403
+ @config[:schema].to_s
404
+ elsif @config[:username]
405
+ @config[:username].to_s
406
+ end
401
407
  end
402
408
 
403
409
  def select(sql, name=nil)
@@ -5,8 +5,9 @@ end
5
5
  module ::ArJdbc
6
6
  module PostgreSQL
7
7
  def self.extended(mod)
8
- mod.class.class_eval do
9
- alias_chained_method :insert, :query_dirty, :insert
8
+ (class << mod; self; end).class_eval do
9
+ alias_chained_method :insert, :query_dirty, :pg_insert
10
+ alias_chained_method :columns, :query_cache, :pg_columns
10
11
  end
11
12
  end
12
13
 
@@ -28,9 +29,13 @@ module ::ArJdbc
28
29
 
29
30
  def extract_limit(sql_type)
30
31
  case sql_type
31
- when /^bigint/i; 8
32
+ when /^int2/i; 2
32
33
  when /^smallint/i; 2
33
- when /^(bool|text|date|time)/i; nil # ACTIVERECORD_JDBC-135,139
34
+ when /^int4/i; nil
35
+ when /^integer/i; nil
36
+ when /^int8/i; 8
37
+ when /^bigint/i; 8
38
+ when /^(bool|text|date|time|bytea)/i; nil # ACTIVERECORD_JDBC-135,139
34
39
  else super
35
40
  end
36
41
  end
@@ -43,6 +48,7 @@ module ::ArJdbc
43
48
  return :float if field_type =~ /^(?:real|double precision)$/i
44
49
  return :binary if field_type =~ /^bytea/i
45
50
  return :boolean if field_type =~ /^bool/i
51
+ return :decimal if field_type == 'numeric(131089)'
46
52
  super
47
53
  end
48
54
 
@@ -65,7 +71,7 @@ module ::ArJdbc
65
71
  return $1 if value =~ /^'(.*)'::(bpchar|text|character varying|bytea)$/
66
72
 
67
73
  # Numeric values
68
- return value if value =~ /^-?[0-9]+(\.[0-9]*)?/
74
+ return value.delete("()") if value =~ /^\(?-?[0-9]+(\.[0-9]*)?\)?/
69
75
 
70
76
  # Fixed dates / timestamp
71
77
  return $1 if value =~ /^'(.+)'::(date|timestamp)/
@@ -239,7 +245,7 @@ module ::ArJdbc
239
245
  nil
240
246
  end
241
247
 
242
- def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
248
+ def pg_insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
243
249
  # Extract the table from the insert sql. Yuck.
244
250
  table = sql.split(" ", 4)[2].gsub('"', '')
245
251
 
@@ -273,14 +279,27 @@ module ::ArJdbc
273
279
  id_value
274
280
  end
275
281
 
276
- def columns(table_name, name=nil)
282
+ def pg_columns(table_name, name=nil)
277
283
  schema_name = @config[:schema_search_path]
278
284
  if table_name =~ /\./
279
285
  parts = table_name.split(/\./)
280
286
  table_name = parts.pop
281
287
  schema_name = parts.join(".")
282
288
  end
283
- @connection.columns_internal(table_name, name, schema_name)
289
+ schema_list = if schema_name.nil?
290
+ []
291
+ else
292
+ schema_name.split(/\s*,\s*/)
293
+ end
294
+ while schema_list.size > 1
295
+ s = schema_list.shift
296
+ begin
297
+ return @connection.columns_internal(table_name, name, s)
298
+ rescue ActiveRecord::JDBCError=>ignored_for_next_schema
299
+ end
300
+ end
301
+ s = schema_list.shift
302
+ return @connection.columns_internal(table_name, name, s)
284
303
  end
285
304
 
286
305
  # From postgresql_adapter.rb
@@ -418,7 +437,7 @@ module ::ArJdbc
418
437
  return super unless column
419
438
 
420
439
  if value.kind_of?(String) && column.type == :binary
421
- "'#{escape_bytea(value)}'"
440
+ "E'#{escape_bytea(value)}'"
422
441
  elsif value.kind_of?(String) && column.sql_type == 'xml'
423
442
  "xml '#{quote_string(value)}'"
424
443
  elsif value.kind_of?(Numeric) && column.sql_type == 'money'
@@ -557,9 +576,9 @@ module ::ArJdbc
557
576
  def translate_exception(exception, message)
558
577
  case exception.message
559
578
  when /duplicate key value violates unique constraint/
560
- RecordNotUnique.new(message, exception)
579
+ ::ActiveRecord::RecordNotUnique.new(message, exception)
561
580
  when /violates foreign key constraint/
562
- InvalidForeignKey.new(message, exception)
581
+ ::ActiveRecord::InvalidForeignKey.new(message, exception)
563
582
  else
564
583
  super
565
584
  end
@@ -108,7 +108,7 @@ module ::ArJdbc
108
108
  tp[:primary_key] = "integer primary key autoincrement not null"
109
109
  tp[:string] = { :name => "varchar", :limit => 255 }
110
110
  tp[:text] = { :name => "text" }
111
- tp[:float] = { :name => "decimal" }
111
+ tp[:float] = { :name => "float" }
112
112
  tp[:decimal] = { :name => "decimal" }
113
113
  tp[:datetime] = { :name => "datetime" }
114
114
  tp[:timestamp] = { :name => "datetime" }
@@ -1,6 +1,6 @@
1
1
  module ArJdbc
2
2
  module Version
3
- VERSION = "1.1.1"
3
+ VERSION = "1.1.2"
4
4
  end
5
5
  end
6
6
  # Compatibility with older versions of ar-jdbc for other extensions out there
@@ -12,6 +12,7 @@ require File.dirname(__FILE__) + "/../lib/arjdbc/version"
12
12
  begin
13
13
  require 'hoe'
14
14
  Hoe.plugin :gemcutter
15
+ Hoe.plugin :rubyforge
15
16
  hoe = Hoe.spec("activerecord-jdbc-adapter") do |p|
16
17
  p.version = ArJdbc::Version::VERSION
17
18
  p.spec_extras[:files] = MANIFEST
@@ -0,0 +1,62 @@
1
+ /*
2
+ **** BEGIN LICENSE BLOCK *****
3
+ * Copyright (c) 2006-2010 Nick Sieger <nick@nicksieger.com>
4
+ * Copyright (c) 2006-2007 Ola Bini <ola.bini@gmail.com>
5
+ * Copyright (c) 2008-2009 Thomas E Enebo <enebo@acm.org>
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining
8
+ * a copy of this software and associated documentation files (the
9
+ * "Software"), to deal in the Software without restriction, including
10
+ * without limitation the rights to use, copy, modify, merge, publish,
11
+ * distribute, sublicense, and/or sell copies of the Software, and to
12
+ * permit persons to whom the Software is furnished to do so, subject to
13
+ * the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
+ ***** END LICENSE BLOCK *****/
26
+ package arjdbc.db2;
27
+
28
+ import org.jruby.Ruby;
29
+ import org.jruby.RubyClass;
30
+ import org.jruby.runtime.ObjectAllocator;
31
+ import org.jruby.runtime.builtin.IRubyObject;
32
+
33
+ import arjdbc.jdbc.RubyJdbcConnection;
34
+
35
+ /**
36
+ *
37
+ * @author mikestone
38
+ */
39
+ public class DB2RubyJdbcConnection extends RubyJdbcConnection {
40
+ protected DB2RubyJdbcConnection(Ruby runtime, RubyClass metaClass) {
41
+ super(runtime, metaClass);
42
+ }
43
+
44
+ @Override
45
+ protected boolean databaseSupportsSchemas() {
46
+ return true;
47
+ }
48
+
49
+ public static RubyClass createDB2JdbcConnectionClass(Ruby runtime, RubyClass jdbcConnection) {
50
+ RubyClass clazz = RubyJdbcConnection.getConnectionAdapters(runtime).defineClassUnder("DB2JdbcConnection",
51
+ jdbcConnection, DB2_JDBCCONNECTION_ALLOCATOR);
52
+ clazz.defineAnnotatedMethods(DB2RubyJdbcConnection.class);
53
+
54
+ return clazz;
55
+ }
56
+
57
+ private static ObjectAllocator DB2_JDBCCONNECTION_ALLOCATOR = new ObjectAllocator() {
58
+ public IRubyObject allocate(Ruby runtime, RubyClass klass) {
59
+ return new DB2RubyJdbcConnection(runtime, klass);
60
+ }
61
+ };
62
+ }
@@ -28,6 +28,7 @@ package arjdbc.jdbc;
28
28
 
29
29
  import java.io.IOException;
30
30
 
31
+ import arjdbc.db2.DB2RubyJdbcConnection;
31
32
  import arjdbc.derby.DerbyModule;
32
33
  import arjdbc.h2.H2RubyJdbcConnection;
33
34
  import arjdbc.informix.InformixRubyJdbcConnection;
@@ -57,6 +58,7 @@ public class AdapterJavaService implements BasicLibraryService {
57
58
  Sqlite3RubyJdbcConnection.createSqlite3JdbcConnectionClass(runtime, jdbcConnection);
58
59
  H2RubyJdbcConnection.createH2JdbcConnectionClass(runtime, jdbcConnection);
59
60
  MySQLRubyJdbcConnection.createMySQLJdbcConnectionClass(runtime, jdbcConnection);
61
+ DB2RubyJdbcConnection.createDB2JdbcConnectionClass(runtime, jdbcConnection);
60
62
  RubyModule arJdbc = runtime.getOrCreateModule("ArJdbc");
61
63
  rubyApi = JavaEmbedUtils.newObjectAdapter();
62
64
  MySQLModule.load(arJdbc);
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  **** BEGIN LICENSE BLOCK *****
3
- * Copyright (c) 2006-2010 Nick Sieger <nick@nicksieger.com>
3
+ * Copyright (c) 2006-2011 Nick Sieger <nick@nicksieger.com>
4
4
  * Copyright (c) 2006-2007 Ola Bini <ola.bini@gmail.com>
5
5
  * Copyright (c) 2008-2009 Thomas E Enebo <enebo@acm.org>
6
6
  *
@@ -122,45 +122,20 @@ public class RubyJdbcConnection extends RubyObject {
122
122
  public Object call(Connection c) throws SQLException {
123
123
  ResultSet results = null, pkeys = null;
124
124
  try {
125
- String table_name = rubyApi.convertToRubyString(args[0]).getUnicodeValue();
126
- String schemaName = null;
127
-
128
- final String[] name_parts = table_name.split( "\\." );
129
- if ( name_parts.length > 3 ) {
130
- throw new SQLException("Table name '" + table_name + "' should not contain more than 2 '.'");
131
- }
132
-
133
- DatabaseMetaData metadata = c.getMetaData();
134
- String clzName = metadata.getClass().getName().toLowerCase();
135
- boolean isDB2 = clzName.indexOf("db2") != -1 || clzName.indexOf("as400") != -1;
136
-
137
- String catalog = c.getCatalog();
138
- if( name_parts.length == 2 ) {
139
- schemaName = name_parts[0];
140
- table_name = name_parts[1];
141
- }
142
- else if ( name_parts.length == 3 ) {
143
- catalog = name_parts[0];
144
- schemaName = name_parts[1];
145
- table_name = name_parts[2];
146
- }
147
-
148
- if(args.length > 2 && schemaName == null) schemaName = toStringOrNull(args[2]);
149
-
150
- if (schemaName != null) schemaName = caseConvertIdentifierForJdbc(metadata, schemaName);
151
- table_name = caseConvertIdentifierForJdbc(metadata, table_name);
152
-
153
- if (schemaName != null && !isDB2 && !databaseSupportsSchemas()) { catalog = schemaName; }
125
+ String defaultSchema = args.length > 2 ? toStringOrNull(args[2]) : null;
126
+ String tableName = rubyApi.convertToRubyString(args[0]).getUnicodeValue();
127
+ TableNameComponents components = extractTableNameComponents(c, defaultSchema, tableName);
154
128
 
155
129
  String[] tableTypes = new String[]{"TABLE","VIEW","SYNONYM"};
156
130
  RubyArray matchingTables = (RubyArray) tableLookupBlock(context.getRuntime(),
157
- catalog, schemaName, table_name, tableTypes, false).call(c);
131
+ components.catalog, components.schema, components.table, tableTypes, false).call(c);
158
132
  if (matchingTables.isEmpty()) {
159
- throw new SQLException("Table " + table_name + " does not exist");
133
+ throw new SQLException("Table " + tableName + " does not exist");
160
134
  }
161
135
 
162
- results = metadata.getColumns(catalog,schemaName,table_name,null);
163
- pkeys = metadata.getPrimaryKeys(catalog,schemaName,table_name);
136
+ DatabaseMetaData metadata = c.getMetaData();
137
+ results = metadata.getColumns(components.catalog, components.schema, components.table, null);
138
+ pkeys = metadata.getPrimaryKeys(components.catalog, components.schema, components.table);
164
139
  return unmarshal_columns(context, metadata, results, pkeys);
165
140
  } finally {
166
141
  close(results);
@@ -387,7 +362,7 @@ public class RubyJdbcConnection extends RubyObject {
387
362
  ResultSet resultSet = null;
388
363
  List indexes = new ArrayList();
389
364
  try {
390
- resultSet = metadata.getIndexInfo(null, schemaName, tableName, false, false);
365
+ resultSet = metadata.getIndexInfo(null, schemaName, tableName, false, true);
391
366
  List primaryKeys = primaryKeys(context, tableName);
392
367
  String currentIndex = null;
393
368
  RubyModule indexDefinitionClass = getConnectionAdapters(runtime).getClass("IndexDefinition");
@@ -486,7 +461,8 @@ public class RubyJdbcConnection extends RubyObject {
486
461
  ResultSet resultSet = null;
487
462
  List keyNames = new ArrayList();
488
463
  try {
489
- resultSet = metadata.getPrimaryKeys(null, null, tableName);
464
+ TableNameComponents components = extractTableNameComponents(c, null, tableName);
465
+ resultSet = metadata.getPrimaryKeys(components.catalog, components.schema, components.table);
490
466
 
491
467
  while (resultSet.next()) {
492
468
  keyNames.add(RubyString.newUnicodeString(runtime,
@@ -1272,6 +1248,41 @@ public class RubyJdbcConnection extends RubyObject {
1272
1248
  return true;
1273
1249
  }
1274
1250
 
1251
+ private TableNameComponents extractTableNameComponents(Connection connection, String defaultSchema, String tableName) throws SQLException {
1252
+ String schemaName = null;
1253
+
1254
+ final String[] name_parts = tableName.split("\\.");
1255
+ if (name_parts.length > 3) {
1256
+ throw new SQLException("Table name '" + tableName + "' should not contain more than 2 '.'");
1257
+ }
1258
+
1259
+ DatabaseMetaData metadata = connection.getMetaData();
1260
+ String clzName = metadata.getClass().getName().toLowerCase();
1261
+ boolean isPostgres = clzName.contains("postgresql");
1262
+
1263
+ String catalog = connection.getCatalog();
1264
+ if (name_parts.length == 2) {
1265
+ schemaName = name_parts[0];
1266
+ tableName = name_parts[1];
1267
+ } else if (name_parts.length == 3) {
1268
+ catalog = name_parts[0];
1269
+ schemaName = name_parts[1];
1270
+ tableName = name_parts[2];
1271
+ }
1272
+
1273
+ if (schemaName == null && defaultSchema != null) schemaName = defaultSchema;
1274
+
1275
+ // The postgres JDBC driver will default to searching every schema if no
1276
+ // schema search path is given. Default to the public schema instead.
1277
+ if (schemaName == null && isPostgres) schemaName = "public";
1278
+ if (schemaName != null) schemaName = caseConvertIdentifierForJdbc(metadata, schemaName);
1279
+ tableName = caseConvertIdentifierForJdbc(metadata, tableName);
1280
+
1281
+ if (schemaName != null && !databaseSupportsSchemas()) { catalog = schemaName; }
1282
+
1283
+ return new TableNameComponents(catalog, schemaName, tableName);
1284
+ }
1285
+
1275
1286
  public static class ColumnData {
1276
1287
  public IRubyObject name;
1277
1288
  public int index;
@@ -1302,4 +1313,16 @@ public class RubyJdbcConnection extends RubyObject {
1302
1313
  return columns;
1303
1314
  }
1304
1315
  }
1316
+
1317
+ private static class TableNameComponents {
1318
+ private String catalog;
1319
+ private String schema;
1320
+ private String table;
1321
+
1322
+ private TableNameComponents(String catalog, String schema, String table) {
1323
+ this.catalog = catalog;
1324
+ this.schema = schema;
1325
+ this.table = table;
1326
+ }
1327
+ }
1305
1328
  }
@@ -1,6 +1,3 @@
1
- require 'rubygems'
2
- require 'active_record'
3
-
4
1
  class AddNotNullColumnToTable < ActiveRecord::Migration
5
2
  def self.up
6
3
  add_column :entries, :color, :string, :null => false, :default => "blue"
@@ -1,6 +1,3 @@
1
- require 'rubygems'
2
- require 'active_record'
3
-
4
1
  class CreateAutoIds < ActiveRecord::Migration
5
2
  def self.up
6
3
  create_table "auto_ids", :force => true do |t|
@@ -1,6 +1,3 @@
1
- require 'rubygems'
2
- require 'active_record'
3
-
4
1
  class DbTypeMigration < ActiveRecord::Migration
5
2
  def self.up
6
3
  create_table "db_types", :force => true do |t|
@@ -10,11 +7,16 @@ class DbTypeMigration < ActiveRecord::Migration
10
7
  t.column :sample_time, :time
11
8
  t.column :sample_decimal, :decimal, :precision => 15, :scale => 0
12
9
  t.column :sample_small_decimal, :decimal, :precision => 3, :scale => 2
10
+ t.column :sample_default_decimal, :decimal
13
11
  t.column :sample_float, :float
14
12
  t.column :sample_binary, :binary
15
13
  t.column :sample_boolean, :boolean
16
14
  t.column :sample_string, :string, :default => ''
17
15
  t.column :sample_integer, :integer, :limit => 5
16
+ t.column :sample_integer_with_limit_2, :integer, :limit => 2
17
+ t.column :sample_integer_with_limit_8, :integer, :limit => 8
18
+ t.column :sample_integer_no_limit, :integer
19
+ t.column :sample_integer_negative_default, :integer, :default => -1
18
20
  t.column :sample_text, :text
19
21
  end
20
22
  end
@@ -1,6 +1,3 @@
1
- require 'rubygems'
2
- require 'active_record'
3
-
4
1
  class CreateEntries < ActiveRecord::Migration
5
2
  def self.up
6
3
  create_table "entries", :force => true do |t|
@@ -1,6 +1,3 @@
1
- require 'rubygems'
2
- require 'active_record'
3
-
4
1
  module Migration
5
2
  class MixedCase < ActiveRecord::Migration
6
3
 
@@ -1,6 +1,3 @@
1
- require 'rubygems'
2
- require 'active_record'
3
-
4
1
  class CreateReservedWords < ActiveRecord::Migration
5
2
  def self.up
6
3
  create_table "reserved_words", :force => true do |t|
@@ -1,6 +1,3 @@
1
- require 'rubygems'
2
- require 'active_record'
3
-
4
1
  class CreateStringIds < ActiveRecord::Migration
5
2
  def self.up
6
3
  create_table "string_ids", :force => true, :id => false do |t|
@@ -81,7 +81,7 @@ class MysqlInfoTest < Test::Unit::TestCase
81
81
  dump = strio.string
82
82
  dump.grep(/datetime/).each {|line| assert line !~ /limit/ }
83
83
  end
84
-
84
+
85
85
  def test_schema_dump_should_not_have_limits_on_date
86
86
  strio = StringIO.new
87
87
  ActiveRecord::SchemaDumper::dump(@connection, strio)
@@ -11,7 +11,7 @@ class PostgresDbCreateTest < Test::Unit::TestCase
11
11
  if find_executable?("psql")
12
12
  def test_rake_db_create
13
13
  Rake::Task["db:create"].invoke
14
- output = `psql -c '\\l'`
14
+ output = `psql -d template1 -c '\\l'`
15
15
  assert output =~ /#{@db_name}/m
16
16
  end
17
17
 
@@ -0,0 +1,29 @@
1
+ require 'jdbc_common'
2
+ require 'db/postgres'
3
+
4
+ class CreateISLSchema < ActiveRecord::Migration
5
+ def self.up
6
+ execute "CREATE TABLE domains (id int, name varchar(16))"
7
+ end
8
+
9
+ def self.down
10
+ execute "DROP TABLE domains"
11
+ end
12
+ end
13
+
14
+ class Domain < ActiveRecord::Base
15
+ end
16
+
17
+ class PostgresInformationSchemaLeakTest < Test::Unit::TestCase
18
+ def setup
19
+ CreateISLSchema.up
20
+ end
21
+
22
+ def teardown
23
+ CreateISLSchema.down
24
+ end
25
+
26
+ def test_columns
27
+ assert_equal(%w{id name}, Domain.column_names)
28
+ end
29
+ end
@@ -16,7 +16,7 @@ class CreateSchema < ActiveRecord::Migration
16
16
  end
17
17
 
18
18
  class Person < ActiveRecord::Base
19
- establish_connection POSTGRES_CONFIG.merge(:schema_search_path => 'test')
19
+ establish_connection POSTGRES_CONFIG.merge(:schema_search_path => 'test,public')
20
20
  end
21
21
 
22
22
  class PostgresSchemaSearchPathTest < Test::Unit::TestCase
@@ -41,4 +41,8 @@ class PostgresSchemaSearchPathTest < Test::Unit::TestCase
41
41
  Person.find_by_wrongname("Alex")
42
42
  end
43
43
  end
44
+ def test_column_information
45
+ assert Person.columns.map{|col| col.name}.include?("name")
46
+ assert !Person.columns.map{|col| col.name}.include?("wrongname")
47
+ end
44
48
  end
@@ -56,10 +56,35 @@ class PostgresSchemaDumperTest < Test::Unit::TestCase
56
56
  lines.each {|line| assert line !~ /limit/ }
57
57
  end
58
58
 
59
+
60
+ def test_schema_dump_should_not_have_limits_on_binaries
61
+ lines = @dump.grep(/binary/)
62
+ assert !lines.empty?, 'no binary type definitions found'
63
+ lines.each {|line| assert line !~ /limit/, 'binary definition contains limit' }
64
+ end
65
+
59
66
  # http://kenai.com/jira/browse/ACTIVERECORD_JDBC-139
60
67
  def test_schema_dump_should_not_have_limits_on_text_or_date
61
68
  lines = @dump.grep(/date|text/)
62
69
  assert !lines.empty?
63
70
  lines.each {|line| assert line !~ /limit/ }
64
71
  end
72
+
73
+ def test_schema_dump_integer_with_no_limit_should_have_no_limit
74
+ lines = @dump.grep(/sample_integer_no_limit/)
75
+ assert !lines.empty?
76
+ lines.each {|line| assert line !~ /:limit/ }
77
+ end
78
+
79
+ def test_schema_dump_integer_with_limit_2_should_have_limit_2
80
+ lines = @dump.grep(/sample_integer_with_limit_2/)
81
+ assert !lines.empty?
82
+ lines.each {|line| assert line =~ /limit => 2/ }
83
+ end
84
+
85
+ def test_schema_dump_integer_with_limit_8_should_have_limit_8
86
+ lines = @dump.grep(/sample_integer_with_limit_8/)
87
+ assert !lines.empty?
88
+ lines.each {|line| assert line =~ /limit => 8/ }
89
+ end
65
90
  end
@@ -256,6 +256,17 @@ module SimpleTestMethods
256
256
  assert_equal binary_string, e.sample_binary
257
257
  end
258
258
 
259
+ def test_default_decimal_should_keep_fractional_part
260
+ expected = 7.3
261
+ actual = DbType.create(:sample_default_decimal => expected).sample_default_decimal
262
+ assert_equal expected, actual
263
+ end
264
+
265
+ def test_negative_default_value
266
+ assert_equal -1, DbType.columns_hash['sample_integer_negative_default'].default
267
+ assert_equal -1, DbType.new.sample_integer_negative_default
268
+ end
269
+
259
270
  def test_indexes
260
271
  # Only test indexes if we have implemented it for the particular adapter
261
272
  if @connection.respond_to?(:indexes)
@@ -461,14 +472,14 @@ module MultibyteTestMethods
461
472
  def setup
462
473
  super
463
474
  config = ActiveRecord::Base.connection.config
464
- jdbc_driver = ActiveRecord::ConnectionAdapters::JdbcDriver.new(config[:driver])
465
- jdbc_driver.load
466
- @java_con = jdbc_driver.connection(config[:url], config[:username], config[:password])
475
+ @jdbc_driver = ActiveRecord::ConnectionAdapters::JdbcDriver.new(config[:driver])
476
+ @java_con = @jdbc_driver.connection(config[:url], config[:username], config[:password])
467
477
  @java_con.setAutoCommit(true)
468
478
  end
469
479
 
470
480
  def teardown
471
481
  @java_con.close
482
+ @jdbc_driver = nil
472
483
  super
473
484
  end
474
485
 
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: activerecord-jdbc-adapter
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 1.1.1
5
+ version: 1.1.2
6
6
  platform: ruby
7
7
  authors:
8
8
  - Nick Sieger, Ola Bini and JRuby contributors
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-01-14 00:00:00 -06:00
13
+ date: 2011-06-20 00:00:00 -05:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -32,7 +32,7 @@ dependencies:
32
32
  requirements:
33
33
  - - ">="
34
34
  - !ruby/object:Gem::Version
35
- version: 2.6.2
35
+ version: 2.9.4
36
36
  type: :development
37
37
  version_requirements: *id002
38
38
  description: |-
@@ -80,6 +80,7 @@ files:
80
80
  - lib/arel/visitors/compat.rb
81
81
  - lib/arel/visitors/db2.rb
82
82
  - lib/arel/visitors/derby.rb
83
+ - lib/arel/visitors/firebird.rb
83
84
  - lib/arel/visitors/hsqldb.rb
84
85
  - lib/arel/visitors/sql_server.rb
85
86
  - lib/arjdbc/db2.rb
@@ -174,6 +175,7 @@ files:
174
175
  - test/pick_rails_version.rb
175
176
  - test/postgres_db_create_test.rb
176
177
  - test/postgres_drop_db_test.rb
178
+ - test/postgres_information_schema_leak_test.rb
177
179
  - test/postgres_mixed_case_test.rb
178
180
  - test/postgres_nonseq_pkey_test.rb
179
181
  - test/postgres_reserved_test.rb
@@ -207,6 +209,7 @@ files:
207
209
  - test/models/string_id.rb
208
210
  - test/models/validates_uniqueness_of_string.rb
209
211
  - lib/arjdbc/jdbc/jdbc.rake
212
+ - src/java/arjdbc/db2/DB2RubyJdbcConnection.java
210
213
  - src/java/arjdbc/derby/DerbyModule.java
211
214
  - src/java/arjdbc/h2/H2RubyJdbcConnection.java
212
215
  - src/java/arjdbc/informix/InformixRubyJdbcConnection.java
@@ -228,6 +231,7 @@ files:
228
231
  - rails_generators/jdbc_generator.rb
229
232
  - rails_generators/templates/config/initializers/jdbc.rb
230
233
  - rails_generators/templates/lib/tasks/jdbc.rake
234
+ - .gemtest
231
235
  has_rdoc: true
232
236
  homepage: http://jruby-extras.rubyforge.org/activerecord-jdbc-adapter
233
237
  licenses: []
@@ -256,7 +260,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
256
260
  requirements: []
257
261
 
258
262
  rubyforge_project: jruby-extras
259
- rubygems_version: 1.4.2
263
+ rubygems_version: 1.5.1
260
264
  signing_key:
261
265
  specification_version: 3
262
266
  summary: JDBC adapter for ActiveRecord, for use within JRuby on Rails.