activerecord-jdbc-adapter 0.8.2 → 0.9

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,24 @@
1
+ == 0.9
2
+
3
+ - Now updated to support ActiveRecord 2.2. JNDI-based connections will
4
+ automatically connect/disconnect for every AR connection pool
5
+ checkout/checkin. For best results, set your pool: parameter >= the
6
+ actual maximum size of the JNDI connection pool. (We'll look at how
7
+ to eliminate the need to configure AR's pool in the future.)
8
+ - NEW! Informix support courtesy of Javier Fernandez-Ivern.
9
+ - Backport another Oracle CLOB issue, thanks Edson C�sar.
10
+ - Rubyforge #22018: chomp final trailing semicolon for oracle
11
+ - JRUBY-2848: Fix NPE error in set_native_database_types
12
+ - Rework oracle lob saving callback to be Rails 2.1 friendly (assist
13
+ from court3nay)
14
+ - JRUBY-2715: Add create/drop database methods to Postgres (Peter Williams)
15
+ - JRUBY-3183: Fix structure dump for Postgres (Ryan Bell)
16
+ - JRUBY-3184: recreate_database for test database working for PG (Ryan Bell)
17
+ - JRUBY-3186: disable referential integrity for PG (Ryan Bell)
18
+ - Authoritative repository now hosted at
19
+ git://github.com/nicksieger/activerecord-jdbc-adapter.git; rubyforge
20
+ svn trunk cleaned out.
21
+
1
22
  == 0.8.2
2
23
 
3
24
  - Added an optional config key called :dialect. Using :dialect allows you to
@@ -145,4 +166,4 @@
145
166
 
146
167
  == 0.0.1
147
168
 
148
- - Initial, very alpha release
169
+ - Initial, very alpha release
data/Manifest.txt CHANGED
@@ -7,6 +7,7 @@ lib/active_record/connection_adapters/cachedb_adapter.rb
7
7
  lib/active_record/connection_adapters/derby_adapter.rb
8
8
  lib/active_record/connection_adapters/h2_adapter.rb
9
9
  lib/active_record/connection_adapters/hsqldb_adapter.rb
10
+ lib/active_record/connection_adapters/informix_adapter.rb
10
11
  lib/active_record/connection_adapters/jdbc_adapter.rb
11
12
  lib/active_record/connection_adapters/jdbc_adapter_spec.rb
12
13
  lib/active_record/connection_adapters/jndi_adapter.rb
@@ -19,6 +20,7 @@ lib/jdbc_adapter/jdbc_db2.rb
19
20
  lib/jdbc_adapter/jdbc_derby.rb
20
21
  lib/jdbc_adapter/jdbc_firebird.rb
21
22
  lib/jdbc_adapter/jdbc_hsqldb.rb
23
+ lib/jdbc_adapter/jdbc_informix.rb
22
24
  lib/jdbc_adapter/jdbc_mimer.rb
23
25
  lib/jdbc_adapter/jdbc_mssql.rb
24
26
  lib/jdbc_adapter/jdbc_mysql.rb
@@ -40,6 +42,7 @@ test/db/db2.rb
40
42
  test/db/derby.rb
41
43
  test/db/h2.rb
42
44
  test/db/hsqldb.rb
45
+ test/db/informix.rb
43
46
  test/db/jdbc.rb
44
47
  test/db/jndi_config.rb
45
48
  test/db/logger.rb
@@ -55,9 +58,11 @@ test/generic_jdbc_connection_test.rb
55
58
  test/h2_simple_test.rb
56
59
  test/has_many_through.rb
57
60
  test/hsqldb_simple_test.rb
61
+ test/informix_simple_test.rb
58
62
  test/jdbc_adapter/jdbc_db2_test.rb
59
63
  test/jdbc_adapter/jdbc_sybase_test.rb
60
64
  test/jdbc_common.rb
65
+ test/jndi_callbacks_test.rb
61
66
  test/jndi_test.rb
62
67
  test/manualTestDatabase.rb
63
68
  test/minirunit/testConnect.rb
data/README.txt CHANGED
@@ -1,6 +1,6 @@
1
- ActiveRecord-JDBC is a database adapter for Rails' ActiveRecord component that can be used with JRuby[http://www.jruby.org/]. It allows use of virtually any JDBC-compliant database with your JRuby on Rails application.
2
-
3
- ActiveRecord-JDBC is a sub-project of jruby-extras at RubyForge.
1
+ activerecord-jdbc-adapter is a database adapter for Rails' ActiveRecord
2
+ component that can be used with JRuby[http://www.jruby.org/]. It allows use of
3
+ virtually any JDBC-compliant database with your JRuby on Rails application.
4
4
 
5
5
  == Databases
6
6
 
@@ -27,16 +27,21 @@ What's there, and what is not there:
27
27
  * HSQLDB - Complete
28
28
  * H2 - Complete
29
29
  * SQLite3 - work in progress
30
+ * Informix - Fairly complete support, all tests pass and migrations appear to work. Comments welcome.
30
31
 
31
- Other databases will require testing and likely a custom configuration module. Please join the jruby-extras mailing-list[http://rubyforge.org/mail/?group_id=2014] to help us discover support for more databases.
32
+ Other databases will require testing and likely a custom configuration module.
33
+ Please join the jruby-extras
34
+ mailing-list[http://rubyforge.org/mail/?group_id=2014] to help us discover
35
+ support for more databases.
32
36
 
33
37
  == Using ActiveRecord JDBC
34
38
 
35
39
  === Inside Rails
36
40
 
37
- To use ActiveRecord-JDBC with JRuby on Rails:
41
+ To use activerecord-jdbc-adapter with JRuby on Rails:
38
42
 
39
- 1. Choose the adapter you wish to gem install. The following pre-packaged adapters are available:
43
+ 1. Choose the adapter you wish to gem install. The following pre-packaged
44
+ adapters are available:
40
45
 
41
46
  * base jdbc (<tt>activerecord-jdbc-adapter</tt>). Supports all available databases via JDBC, but requires you to download and manually install the database vendor's JDBC driver .jar file.
42
47
  * mysql (<tt>activerecord-jdbcmysql-adapter</tt>)
@@ -45,7 +50,12 @@ To use ActiveRecord-JDBC with JRuby on Rails:
45
50
  * hsqldb (<tt>activerecord-jdbchsqldb-adapter</tt>)
46
51
  * h2 (<tt>activerecord-jdbch2-adapter</tt>)
47
52
 
48
- 2. If you're using Rails 2.0, you may skip to the next step. For Rails prior to version 2.0, you'll need to add one-time setup to your config/environment.rb file in your Rails application. Add the following lines just before the <code>Rails::Initializer</code>. (If you're using ActiveRecord-JDBC under the old gem name used in versions 0.5 and earlier, replace 'activerecord-jdbc-adapter' with 'ActiveRecord-JDBC' below.)
53
+ 2. If you're using Rails 2.0, you may skip to the next step. For Rails prior to
54
+ version 2.0, you'll need to add one-time setup to your config/environment.rb
55
+ file in your Rails application. Add the following lines just before the
56
+ <code>Rails::Initializer</code>. (If you're using activerecord-jdbc-adapter
57
+ under the old gem name used in versions 0.5 and earlier (ActiveRecord-JDBC),
58
+ replace 'activerecord-jdbc-adapter' with 'ActiveRecord-JDBC' below.)
49
59
 
50
60
  if RUBY_PLATFORM =~ /java/
51
61
  require 'rubygems'
@@ -53,8 +63,11 @@ To use ActiveRecord-JDBC with JRuby on Rails:
53
63
  require 'jdbc_adapter'
54
64
  end
55
65
 
56
- 3. Configure your database.yml to use the <code>jdbc</code> adapter.
57
- For mysql, postgres, derby, oracle, hsqldb and h2 you can simply configure the database in the normal Rails style. If you use one of the convenience 'activerecord-jdbcXXX-adapter' adapters, be sure and put a 'jdbc' prefix in front of the databas adapter name as below.
66
+ 3. Configure your database.yml to use the <code>jdbc</code> adapter. For mysql,
67
+ postgres, derby, oracle, hsqldb, h2, and informix you can simply configure
68
+ the database in the normal Rails style. If you use one of the convenience
69
+ 'activerecord-jdbcXXX-adapter' adapters, be sure and put a 'jdbc' prefix in
70
+ front of the databas adapter name as below.
58
71
 
59
72
  development:
60
73
  adapter: jdbcmysql
@@ -63,7 +76,8 @@ For mysql, postgres, derby, oracle, hsqldb and h2 you can simply configure the d
63
76
  hostname: localhost
64
77
  database: weblog_development
65
78
 
66
- For other databases, you'll need to know the database driver class and URL. Example:
79
+ For other databases, you'll need to know the database driver class and URL.
80
+ Example:
67
81
 
68
82
  development:
69
83
  adapter: jdbc
@@ -78,11 +92,13 @@ For other databases, you'll need to know the database driver class and URL. Exa
78
92
 
79
93
  jruby -S gem install activerecord-jdbc-adapter
80
94
 
81
- If you wish to use the adapter for a specific database, you can install it directly and a driver gem will be installed as well:
95
+ If you wish to use the adapter for a specific database, you can install it
96
+ directly and a driver gem will be installed as well:
82
97
 
83
98
  jruby -S gem install activerecord-jdbcderby-adapter
84
99
 
85
- 2. If using ActiveRecord 2.0 (Rails 2.0) or greater, you can skip to the next step. Otherwise, ensure the following code gets executed in your script:
100
+ 2. If using ActiveRecord 2.0 (Rails 2.0) or greater, you can skip to the next
101
+ step. Otherwise, ensure the following code gets executed in your script:
86
102
 
87
103
  require 'rubygems'
88
104
  gem 'activerecord-jdbc-adapter'
@@ -104,16 +120,29 @@ For other databases, you'll need to know the database driver class and URL. Exa
104
120
  :url => 'jdbc:derby:test_ar;create=true'
105
121
  )
106
122
 
123
+ == Getting the source
124
+
125
+ The source for activerecord-jdbc-adapter is available using git.
126
+
127
+ git clone git://github.com/nicksieger/activerecord-jdbc-adapter.git
128
+
107
129
  == Running AR-JDBC's Tests
108
130
 
109
- Drivers for 4 open-source databases are included. Provided you have MySQL installed, you can simply type <tt>jruby -S rake</tt> to run the tests. A database named <tt>weblog_development</tt> is needed beforehand with a connection user of "blog" and password empty.
131
+ Drivers for 4 open-source databases are included. Provided you have MySQL
132
+ installed, you can simply type <tt>jruby -S rake</tt> to run the tests. A
133
+ database named <tt>weblog_development</tt> is needed beforehand with a
134
+ connection user of "blog" and password empty.
110
135
 
111
136
  == Authors
112
137
 
113
- This project was written by Nick Sieger <nick@nicksieger.com> and Ola Bini <ola@ologix.com> with lots of help from the JRuby community.
138
+ This project was written by Nick Sieger <nick@nicksieger.com> and Ola Bini
139
+ <olabini@gmail.com> with lots of help from the JRuby community.
114
140
 
115
141
  == License
116
142
 
117
- ActiveRecord-JDBC is released under a BSD license. See the LICENSE file included with the distribution for details.
143
+ activerecord-jdbc-adapter is released under a BSD license. See the LICENSE file
144
+ included with the distribution for details.
118
145
 
119
- Open-source driver gems for ActiveRecord JDBC are licensed under the same license the database's drivers are licensed. See each driver gem's LICENSE.txt file for details.
146
+ Open-source driver gems for activerecord-jdbc-adapter are licensed under the
147
+ same license the database's drivers are licensed. See each driver gem's
148
+ LICENSE.txt file for details.
data/Rakefile CHANGED
@@ -53,7 +53,7 @@ FileList['drivers/*'].each do |d|
53
53
  end
54
54
 
55
55
  Rake::TestTask.new(:test_jdbc) do |t|
56
- t.test_files = FileList['test/generic_jdbc_connection_test.rb']
56
+ t.test_files = FileList['test/generic_jdbc_connection_test.rb', 'test/jndi_callbacks_test.rb']
57
57
  t.libs << 'test' << 'drivers/mysql/lib'
58
58
  end
59
59
 
@@ -89,6 +89,12 @@ Rake::TestTask.new(:test_mssql) do | t |
89
89
  t.libs << 'test'
90
90
  end
91
91
 
92
+ # Ensure that the Informix driver is on your classpath before launching rake
93
+ Rake::TestTask.new(:test_informix) do |t|
94
+ t.test_files = FileList[ 'test/informix_simple_test.rb' ]
95
+ t.libs << 'test'
96
+ end
97
+
92
98
  # Tests for JDBC adapters that don't require a database.
93
99
  Rake::TestTask.new(:test_jdbc_adapters) do | t |
94
100
  t.test_files = FileList[ 'test/jdbc_adapter/jdbc_sybase_test.rb' ]
@@ -170,4 +176,4 @@ end
170
176
  end
171
177
 
172
178
  require 'rake/clean'
173
- CLEAN.include 'derby*', 'test.db.*','test/reports', 'test.sqlite3','lib/**/*.jar','manifest.mf'
179
+ CLEAN.include 'derby*', 'test.db.*','test/reports', 'test.sqlite3','lib/**/*.jar','manifest.mf', '*.log'
@@ -0,0 +1 @@
1
+ require 'active_record/connection_adapters/jdbc_adapter'
@@ -124,6 +124,7 @@ module ActiveRecord
124
124
  lambda {|r| r['type_name'] =~ /^varchar$/i},
125
125
  lambda {|r| r['type_name'] =~ /varying/i}],
126
126
  :text => [ lambda {|r| [Jdbc::Types::LONGVARCHAR, Jdbc::Types::CLOB].include?(r['data_type'].to_i)},
127
+ lambda {|r| r['type_name'] =~ /^text$/i}, # For Informix
127
128
  lambda {|r| r['type_name'] =~ /^(text|clob)$/i},
128
129
  lambda {|r| r['type_name'] =~ /^character large object$/i},
129
130
  lambda {|r| r['sql_data_type'] == 2005}],
@@ -156,6 +157,7 @@ module ActiveRecord
156
157
  lambda {|r| r['type_name'] =~ /^integer/i}], #Num of milliseconds for SQLite3 JDBC Driver
157
158
  :time => [ lambda {|r| Jdbc::Types::TIME == r['data_type'].to_i},
158
159
  lambda {|r| r['type_name'] =~ /^time$/i},
160
+ lambda {|r| r['type_name'] =~ /^datetime/i}, # For Informix
159
161
  lambda {|r| r['type_name'] =~ /^date/i},
160
162
  lambda {|r| r['type_name'] =~ /^integer/i}], #Num of milliseconds for SQLite3 JDBC Driver
161
163
  :date => [ lambda {|r| Jdbc::Types::DATE == r['data_type'].to_i},
@@ -372,6 +374,10 @@ module ActiveRecord
372
374
  end
373
375
  end
374
376
 
377
+ def jndi_connection?
378
+ @jndi_connection
379
+ end
380
+
375
381
  private
376
382
  def configure_jndi
377
383
  jndi = @config[:jndi].to_s
@@ -383,6 +389,7 @@ module ActiveRecord
383
389
  unless @config[:driver]
384
390
  @config[:driver] = connection.meta_data.connection.java_class.name
385
391
  end
392
+ @jndi_connection = true
386
393
  end
387
394
 
388
395
  def configure_jdbc
@@ -407,32 +414,68 @@ module ActiveRecord
407
414
  jdbc_driver.connection(url, user, pass)
408
415
  end
409
416
  end
410
-
411
417
  end
412
418
 
413
- module ShadowCoreMethods
414
- def alias_chained_method(meth, feature, target)
415
- if instance_methods.include?("#{meth}_without_#{feature}")
416
- alias_method "#{meth}_without_#{feature}".to_sym, target
417
- else
418
- alias_method meth, target
419
+ class JdbcAdapter < AbstractAdapter
420
+ module ShadowCoreMethods
421
+ def alias_chained_method(meth, feature, target)
422
+ if instance_methods.include?("#{meth}_without_#{feature}")
423
+ alias_method "#{meth}_without_#{feature}".to_sym, target
424
+ else
425
+ alias_method meth, target
426
+ end
419
427
  end
420
428
  end
421
- end
422
429
 
423
- module CompatibilityMethods
424
- def self.needed?(base)
425
- !base.instance_methods.include?("quote_table_name")
430
+ module CompatibilityMethods
431
+ def self.needed?(base)
432
+ !base.instance_methods.include?("quote_table_name")
433
+ end
434
+
435
+ def quote_table_name(name)
436
+ quote_column_name(name)
437
+ end
438
+ end
439
+
440
+ module ConnectionPoolCallbacks
441
+ def self.included(base)
442
+ base.checkin :on_checkin
443
+ base.checkout :on_checkout
444
+ end
445
+
446
+ def self.needed?
447
+ ActiveRecord::Base.respond_to?(:connection_pool)
448
+ end
449
+
450
+ def on_checkin
451
+ # default implementation does nothing
452
+ end
453
+
454
+ def on_checkout
455
+ # default implementation does nothing
456
+ end
426
457
  end
427
458
 
428
- def quote_table_name(name)
429
- quote_column_name(name)
459
+ module JndiConnectionPoolCallbacks
460
+ def self.prepare(adapter, conn)
461
+ if ActiveRecord::Base.respond_to?(:connection_pool) && conn.jndi_connection?
462
+ adapter.extend self
463
+ conn.disconnect! # disconnect initial connection in JdbcConnection#initialize
464
+ end
465
+ end
466
+
467
+ def on_checkin
468
+ disconnect!
469
+ end
470
+
471
+ def on_checkout
472
+ reconnect!
473
+ end
430
474
  end
431
- end
432
475
 
433
- class JdbcAdapter < AbstractAdapter
434
476
  extend ShadowCoreMethods
435
477
  include CompatibilityMethods if CompatibilityMethods.needed?(self)
478
+ include ConnectionPoolCallbacks if ConnectionPoolCallbacks.needed?
436
479
 
437
480
  attr_reader :config
438
481
 
@@ -452,6 +495,7 @@ module ActiveRecord
452
495
  end
453
496
  end
454
497
  connection.adapter = self
498
+ JndiConnectionPoolCallbacks.prepare(self, connection)
455
499
  end
456
500
 
457
501
  def modify_types(tp)
@@ -11,3 +11,4 @@ require 'jdbc_adapter/jdbc_mssql'
11
11
  require 'jdbc_adapter/jdbc_cachedb'
12
12
  require 'jdbc_adapter/jdbc_sqlite3'
13
13
  require 'jdbc_adapter/jdbc_sybase'
14
+ require 'jdbc_adapter/jdbc_informix'
@@ -64,17 +64,30 @@ namespace :db do
64
64
  namespace :test do
65
65
  redefine_task :clone_structure => [ "db:structure:dump", "db:test:purge" ] do
66
66
  abcs = ActiveRecord::Base.configurations
67
+ abcs['test']['pg_params'] = '?allowEncodingChanges=true' if abcs['test']['adapter'] =~ /postgresql/i
67
68
  ActiveRecord::Base.establish_connection(abcs["test"])
68
69
  ActiveRecord::Base.connection.execute('SET foreign_key_checks = 0') if abcs["test"]["adapter"] =~ /mysql/i
69
70
  IO.readlines("db/#{RAILS_ENV}_structure.sql").join.split(";\n\n").each do |ddl|
70
- ActiveRecord::Base.connection.execute(ddl)
71
+ ActiveRecord::Base.connection.execute(ddl.chomp(';'))
71
72
  end
72
73
  end
73
74
 
74
75
  redefine_task :purge => :environment do
75
76
  abcs = ActiveRecord::Base.configurations
76
- ActiveRecord::Base.establish_connection(abcs["test"])
77
- db = ActiveRecord::Base.connection.database_name
77
+ config = abcs['test'].dup
78
+ if config['adapter'] =~ /postgresql/i
79
+ if config['url']
80
+ db = config['url'][/\/([^\/]*)$/, 1]
81
+ config['url'][/\/([^\/]*)$/, 1] if db_name
82
+ else
83
+ db = config['database']
84
+ config['database'] = 'postgres'
85
+ end
86
+ ActiveRecord::Base.establish_connection(config)
87
+ else
88
+ ActiveRecord::Base.establish_connection(config)
89
+ db = ActiveRecord::Base.connection.database_name
90
+ end
78
91
  ActiveRecord::Base.connection.recreate_database(db)
79
92
  end
80
93
  end
File without changes
@@ -5,23 +5,26 @@ module ::JdbcSpec
5
5
  config[:driver] ||= "org.hsqldb.jdbcDriver"
6
6
  embedded_driver(config)
7
7
  end
8
-
8
+
9
9
  def h2_connection(config)
10
10
  config[:url] ||= "jdbc:h2:#{config[:database]}"
11
11
  config[:driver] ||= "org.h2.Driver"
12
12
  embedded_driver(config)
13
13
  end
14
14
  end
15
-
15
+
16
16
  module HSQLDB
17
17
  def self.column_selector
18
18
  [/hsqldb|\.h2\./i, lambda {|cfg,col| col.extend(::JdbcSpec::HSQLDB::Column)}]
19
19
  end
20
20
 
21
21
  def self.adapter_selector
22
- [/hsqldb|\.h2\./i, lambda {|cfg,adapt| adapt.extend(::JdbcSpec::HSQLDB)}]
22
+ [/hsqldb|\.h2\./i, lambda do |cfg,adapt|
23
+ adapt.extend(::JdbcSpec::HSQLDB)
24
+ def adapt.h2_adapter; true; end if cfg[:driver] =~ /\.h2\./
25
+ end]
23
26
  end
24
-
27
+
25
28
  module Column
26
29
  def type_cast(value)
27
30
  return nil if value.nil? || value =~ /^\s*null\s*$/i
@@ -93,10 +96,12 @@ module ::JdbcSpec
93
96
 
94
97
  def quote(value, column = nil) # :nodoc:
95
98
  return value.quoted_id if value.respond_to?(:quoted_id)
96
-
99
+
97
100
  case value
98
101
  when String
99
- if column && column.type == :binary
102
+ if respond_to?(:h2_adapter) && value.empty?
103
+ "NULL"
104
+ elsif column && column.type == :binary
100
105
  "'#{quote_string(value).unpack("C*").collect {|v| v.to_s(16)}.join}'"
101
106
  else
102
107
  "'#{quote_string(value)}'"
@@ -0,0 +1,148 @@
1
+ module ::ActiveRecord
2
+ class Base
3
+ after_save :write_lobs
4
+
5
+ private
6
+ def write_lobs
7
+ if connection.is_a?(JdbcSpec::Informix)
8
+ self.class.columns.each do |c|
9
+ if [:text, :binary].include? c.type
10
+ value = self[c.name]
11
+ value = value.to_yaml if unserializable_attribute?(c.name, c)
12
+
13
+ unless value.nil? || (value == '')
14
+ connection.write_large_object(c.type == :binary,
15
+ c.name,
16
+ self.class.table_name,
17
+ self.class.primary_key,
18
+ quote_value(id),
19
+ value)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ module ::JdbcSpec
29
+ module ActiveRecordExtensions
30
+ def informix_connection(config)
31
+ config[:port] ||= 9088
32
+ config[:url] ||= "jdbc:informix-sqli://#{config[:host]}:#{config[:port]}/#{config[:database]}:INFORMIXSERVER=#{config[:servername]}"
33
+ config[:driver] = 'com.informix.jdbc.IfxDriver'
34
+ jdbc_connection(config)
35
+ end
36
+ end
37
+
38
+ module Informix
39
+ def self.extended(base)
40
+ @@db_major_version = base.select_one("SELECT dbinfo('version', 'major') version FROM systables WHERE tabid = 1")['version'].to_i
41
+ end
42
+
43
+ def self.column_selector
44
+ [ /informix/i,
45
+ lambda { |cfg, column| column.extend(::JdbcSpec::Informix::Column) } ]
46
+ end
47
+
48
+ def self.adapter_selector
49
+ [ /informix/i,
50
+ lambda { |cfg, adapter| adapter.extend(::JdbcSpec::Informix) } ]
51
+ end
52
+
53
+ module Column
54
+ private
55
+ # TODO: Test all Informix column types.
56
+ def simplified_type(field_type)
57
+ if field_type =~ /serial/i
58
+ :primary_key
59
+ else
60
+ super
61
+ end
62
+ end
63
+ end
64
+
65
+ def modify_types(tp)
66
+ tp[:primary_key] = "SERIAL PRIMARY KEY"
67
+ tp[:string] = { :name => "VARCHAR", :limit => 255 }
68
+ tp[:integer] = { :name => "INTEGER" }
69
+ tp[:float] = { :name => "FLOAT" }
70
+ tp[:decimal] = { :name => "DECIMAL" }
71
+ tp[:datetime] = { :name => "DATETIME YEAR TO FRACTION(5)" }
72
+ tp[:timestamp] = { :name => "DATETIME YEAR TO FRACTION(5)" }
73
+ tp[:time] = { :name => "DATETIME HOUR TO FRACTION(5)" }
74
+ tp[:date] = { :name => "DATE" }
75
+ tp[:binary] = { :name => "BYTE" }
76
+ tp[:boolean] = { :name => "BOOLEAN" }
77
+ tp
78
+ end
79
+
80
+ def prefetch_primary_key?(table_name = nil)
81
+ true
82
+ end
83
+
84
+ def supports_migrations?
85
+ true
86
+ end
87
+
88
+ def default_sequence_name(table, column)
89
+ "#{table}_seq"
90
+ end
91
+
92
+ def add_limit_offset!(sql, options)
93
+ if options[:limit]
94
+ limit = "FIRST #{options[:limit]}"
95
+ # SKIP available only in IDS >= 10
96
+ offset = (@@db_major_version >= 10 && options[:offset]?
97
+ "SKIP #{options[:offset]}" : "")
98
+ sql.sub!(/^select /i, "SELECT #{offset} #{limit} ")
99
+ end
100
+ sql
101
+ end
102
+
103
+ def next_sequence_value(sequence_name)
104
+ select_one("SELECT #{sequence_name}.nextval id FROM systables WHERE tabid=1")['id']
105
+ end
106
+
107
+ # TODO: Add some smart quoting for newlines in string and text fields.
108
+ def quote_string(string)
109
+ string.gsub(/\'/, "''")
110
+ end
111
+
112
+ def quote(value, column = nil)
113
+ if column && [:binary, :text].include?(column.type)
114
+ # LOBs are updated separately by an after_save trigger.
115
+ "NULL"
116
+ elsif column && column.type == :date
117
+ "'#{value.mon}/#{value.day}/#{value.year}'"
118
+ else
119
+ super
120
+ end
121
+ end
122
+
123
+ def create_table(name, options = {})
124
+ super(name, options)
125
+ execute("CREATE SEQUENCE #{name}_seq")
126
+ end
127
+
128
+ def rename_table(name, new_name)
129
+ execute("RENAME TABLE #{name} TO #{new_name}")
130
+ execute("RENAME SEQUENCE #{name}_seq TO #{new_name}_seq")
131
+ end
132
+
133
+ def drop_table(name)
134
+ super(name)
135
+ execute("DROP SEQUENCE #{name}_seq")
136
+ end
137
+
138
+ def remove_index(table_name, options = {})
139
+ @connection.execute_update("DROP INDEX #{index_name(table_name, options)}")
140
+ end
141
+
142
+ private
143
+ def select(sql, name = nil)
144
+ # Informix does not like "= NULL", "!= NULL", or "<> NULL".
145
+ execute(sql.gsub(/(!=|<>)\s*null/i, "IS NOT NULL").gsub(/=\s*null/i, "IS NULL"), name)
146
+ end
147
+ end # module Informix
148
+ end # module ::JdbcSpec
@@ -1,8 +1,5 @@
1
1
  module ::ActiveRecord
2
2
  class Base
3
- # After setting large objects to empty, write data back with a helper method
4
- alias after_save_without_oracle_lob after_save
5
-
6
3
  def after_save_with_oracle_lob() #:nodoc:
7
4
  if connection.is_a?(JdbcSpec::Oracle)
8
5
  self.class.columns.select { |c| c.sql_type =~ /LOB\(|LOB$/i }.each { |c|
@@ -13,10 +10,7 @@ module ::ActiveRecord
13
10
  connection.write_large_object(c.type == :binary, c.name, self.class.table_name, self.class.primary_key, quote_value(id), value)
14
11
  }
15
12
  end
16
- after_save_without_oracle_lob
17
13
  end
18
-
19
- alias after_save after_save_with_oracle_lob
20
14
  end
21
15
  end
22
16
 
@@ -29,8 +23,13 @@ module ::JdbcSpec
29
23
  jdbc_connection(config)
30
24
  end
31
25
  end
32
-
26
+
33
27
  module Oracle
28
+ def self.extended(mod)
29
+ ActiveRecord::Base.after_save :after_save_with_oracle_lob unless @lob_callback_added
30
+ @lob_callback_added = true
31
+ end
32
+
34
33
  def self.column_selector
35
34
  [/oracle/i, lambda {|cfg,col| col.extend(::JdbcSpec::Oracle::Column)}]
36
35
  end
@@ -54,17 +53,31 @@ module ::JdbcSpec
54
53
  def type_cast(value)
55
54
  return nil if value.nil?
56
55
  case type
57
- when :string then value
58
- when :integer then defined?(value.to_i) ? value.to_i : (value ? 1 : 0)
56
+ when :string then value
57
+ when :integer then defined?(value.to_i) ? value.to_i : (value ? 1 : 0)
59
58
  when :primary_key then defined?(value.to_i) ? value.to_i : (value ? 1 : 0)
60
- when :float then value.to_f
61
- when :datetime then JdbcSpec::Oracle::Column.cast_to_date_or_time(value)
62
- when :time then JdbcSpec::Oracle::Column.cast_to_time(value)
63
- when :decimal then self.class.value_to_decimal(value)
64
- when :boolean then self.class.value_to_boolean(value)
59
+ when :float then value.to_f
60
+ when :datetime then JdbcSpec::Oracle::Column.cast_to_date_or_time(value)
61
+ when :time then JdbcSpec::Oracle::Column.cast_to_time(value)
62
+ when :decimal then self.class.value_to_decimal(value)
63
+ when :boolean then self.class.value_to_boolean(value)
65
64
  else value
66
65
  end
67
66
  end
67
+
68
+ def type_cast_code(var_name)
69
+ case type
70
+ when :string then nil
71
+ when :integer then "(#{var_name}.to_i rescue #{var_name} ? 1 : 0)"
72
+ when :primary_key then "(#{var_name}.to_i rescue #{var_name} ? 1 : 0)"
73
+ when :float then "#{var_name}.to_f"
74
+ when :datetime then "JdbcSpec::Oracle::Column.cast_to_date_or_time(#{var_name})"
75
+ when :time then "JdbcSpec::Oracle::Column.cast_to_time(#{var_name})"
76
+ when :decimal then "#{self.class.name}.value_to_decimal(#{var_name})"
77
+ when :boolean then "#{self.class.name}.value_to_boolean(#{var_name})"
78
+ else nil
79
+ end
80
+ end
68
81
 
69
82
  private
70
83
  def simplified_type(field_type)
@@ -188,12 +201,20 @@ module ::JdbcSpec
188
201
  execute "ALTER TABLE #{table_name} MODIFY #{column_name} DEFAULT #{quote(default)}"
189
202
  end
190
203
 
204
+ def add_column_options!(sql, options) #:nodoc:
205
+ # handle case of defaults for CLOB columns, which would otherwise get "quoted" incorrectly
206
+ if options_include_default?(options) && (column = options[:column]) && column.type == :text
207
+ sql << " DEFAULT #{quote(options.delete(:default))}"
208
+ end
209
+ super
210
+ end
211
+
191
212
  def change_column(table_name, column_name, type, options = {}) #:nodoc:
192
213
  change_column_sql = "ALTER TABLE #{table_name} MODIFY #{column_name} #{type_to_sql(type, options[:limit])}"
193
214
  add_column_options!(change_column_sql, options)
194
215
  execute(change_column_sql)
195
216
  end
196
-
217
+
197
218
  def rename_column(table_name, column_name, new_column_name) #:nodoc:
198
219
  execute "ALTER TABLE #{table_name} RENAME COLUMN #{column_name} to #{new_column_name}"
199
220
  end
@@ -328,6 +349,14 @@ module ::JdbcSpec
328
349
  end
329
350
  end
330
351
 
352
+ def quoted_true #:nodoc:
353
+ '1'
354
+ end
355
+
356
+ def quoted_false #:nodoc:
357
+ '0'
358
+ end
359
+
331
360
  private
332
361
  def select(sql, name=nil)
333
362
  records = execute(sql,name)
@@ -7,6 +7,7 @@ module ::JdbcSpec
7
7
  config[:host] ||= "localhost"
8
8
  config[:port] ||= 5432
9
9
  config[:url] ||= "jdbc:postgresql://#{config[:host]}:#{config[:port]}/#{config[:database]}"
10
+ config[:url] << config[:pg_params] if config[:pg_params]
10
11
  config[:driver] ||= "org.postgresql.Driver"
11
12
  jdbc_connection(config)
12
13
  end
@@ -20,7 +21,7 @@ module ::JdbcSpec
20
21
  def self.adapter_selector
21
22
  [/postgre/i, lambda {|cfg,adapt| adapt.extend(::JdbcSpec::PostgreSQL)}]
22
23
  end
23
-
24
+
24
25
  module Column
25
26
  def type_cast(value)
26
27
  case type
@@ -30,7 +31,7 @@ module ::JdbcSpec
30
31
  end
31
32
 
32
33
  def simplified_type(field_type)
33
- return :integer if field_type =~ /^serial/i
34
+ return :integer if field_type =~ /^serial/i
34
35
  return :string if field_type =~ /\[\]$/i || field_type =~ /^interval/i
35
36
  return :string if field_type =~ /^(?:point|lseg|box|"?path"?|polygon|circle)/i
36
37
  return :datetime if field_type =~ /^timestamp/i
@@ -39,7 +40,7 @@ module ::JdbcSpec
39
40
  return :boolean if field_type =~ /^bool/i
40
41
  super
41
42
  end
42
-
43
+
43
44
  def cast_to_boolean(value)
44
45
  if value == true || value == false
45
46
  value
@@ -70,16 +71,16 @@ module ::JdbcSpec
70
71
  # Boolean types
71
72
  return "t" if value =~ /true/i
72
73
  return "f" if value =~ /false/i
73
-
74
+
74
75
  # Char/String/Bytea type values
75
76
  return $1 if value =~ /^'(.*)'::(bpchar|text|character varying|bytea)$/
76
-
77
+
77
78
  # Numeric values
78
79
  return value if value =~ /^-?[0-9]+(\.[0-9]*)?/
79
-
80
+
80
81
  # Fixed dates / timestamp
81
82
  return $1 if value =~ /^'(.+)'::(date|timestamp)/
82
-
83
+
83
84
  # Anything else is blank, some user type, or some function
84
85
  # and we can't know the value of that, so return nil.
85
86
  return nil
@@ -93,7 +94,7 @@ module ::JdbcSpec
93
94
  tp[:boolean][:limit] = nil
94
95
  tp
95
96
  end
96
-
97
+
97
98
  def default_sequence_name(table_name, pk = nil)
98
99
  default_pk, default_seq = pk_and_sequence_for(table_name)
99
100
  default_seq || "#{table_name}_#{pk || default_pk || 'id'}_seq"
@@ -216,34 +217,41 @@ module ::JdbcSpec
216
217
  Integer(select_value("SELECT currval('#{sequence_name}')"))
217
218
  end
218
219
 
219
- # the point here is really just to empty the database, not recreate it
220
- # so we delete all tables
221
220
  def recreate_database(name)
222
- tables.each{|t| drop_table(t)}
221
+ drop_database(name)
222
+ create_database(name)
223
223
  end
224
-
225
- def structure_dump
226
- abcs = ActiveRecord::Base.configurations
227
224
 
228
- database = nil
229
- if abcs[RAILS_ENV]["url"] =~ /\/([^\/]*)$/
230
- database = $1
231
- else
232
- raise "Could not figure out what database this url is for #{abcs[RAILS_ENV]["url"]}"
225
+ def create_database(name, options = {})
226
+ execute "CREATE DATABASE \"#{name}\" ENCODING='#{options[:encoding] || 'utf8'}'"
227
+ end
228
+
229
+ def drop_database(name)
230
+ execute "DROP DATABASE \"#{name}\""
231
+ end
232
+
233
+ def structure_dump
234
+ database = @config[:database]
235
+ if database.nil?
236
+ if @config[:url] =~ /\/([^\/]*)$/
237
+ database = $1
238
+ else
239
+ raise "Could not figure out what database this url is for #{@config["url"]}"
240
+ end
233
241
  end
234
-
235
- ENV['PGHOST'] = abcs[RAILS_ENV]["host"] if abcs[RAILS_ENV]["host"]
236
- ENV['PGPORT'] = abcs[RAILS_ENV]["port"].to_s if abcs[RAILS_ENV]["port"]
237
- ENV['PGPASSWORD'] = abcs[RAILS_ENV]["password"].to_s if abcs[RAILS_ENV]["password"]
238
- search_path = abcs[RAILS_ENV]["schema_search_path"]
242
+
243
+ ENV['PGHOST'] = @config[:host] if @config[:host]
244
+ ENV['PGPORT'] = @config[:port].to_s if @config[:port]
245
+ ENV['PGPASSWORD'] = @config[:password].to_s if @config[:password]
246
+ search_path = @config[:schema_search_path]
239
247
  search_path = "--schema=#{search_path}" if search_path
240
248
 
241
249
  @connection.connection.close
242
250
  begin
243
251
  file = "db/#{RAILS_ENV}_structure.sql"
244
- `pg_dump -i -U "#{abcs[RAILS_ENV]["username"]}" -s -x -O -f #{file} #{search_path} #{database}`
252
+ `pg_dump -i -U "#{@config[:username]}" -s -x -O -f #{file} #{search_path} #{database}`
245
253
  raise "Error dumping database" if $?.exitstatus == 1
246
-
254
+
247
255
  # need to patch away any references to SQL_ASCII as it breaks the JDBC driver
248
256
  lines = File.readlines(file)
249
257
  File.open(file, "w") do |io|
@@ -254,9 +262,9 @@ module ::JdbcSpec
254
262
  end
255
263
  ensure
256
264
  reconnect!
257
- end
265
+ end
258
266
  end
259
-
267
+
260
268
  def _execute(sql, name = nil)
261
269
  case sql.strip
262
270
  when /\A\(?\s*(select|show)/i:
@@ -265,7 +273,7 @@ module ::JdbcSpec
265
273
  @connection.execute_update(sql)
266
274
  end
267
275
  end
268
-
276
+
269
277
  # SELECT DISTINCT clause for a given set of columns and a given ORDER BY clause.
270
278
  #
271
279
  # PostgreSQL requires the ORDER BY columns in the select list for distinct queries, and
@@ -288,22 +296,22 @@ module ::JdbcSpec
288
296
  end
289
297
 
290
298
  # ORDER BY clause for the passed order option.
291
- #
299
+ #
292
300
  # PostgreSQL does not allow arbitrary ordering when using DISTINCT ON, so we work around this
293
301
  # by wrapping the sql as a sub-select and ordering in that query.
294
302
  def add_order_by_for_association_limiting!(sql, options)
295
303
  return sql if options[:order].blank?
296
-
304
+
297
305
  order = options[:order].split(',').collect { |s| s.strip }.reject(&:blank?)
298
306
  order.map! { |s| 'DESC' if s =~ /\bdesc$/i }
299
307
  order = order.zip((0...order.size).to_a).map { |s,i| "id_list.alias_#{i} #{s}" }.join(', ')
300
-
308
+
301
309
  sql.replace "SELECT * FROM (#{sql}) AS id_list ORDER BY #{order}"
302
310
  end
303
311
 
304
312
  def quote(value, column = nil)
305
313
  return value.quoted_id if value.respond_to?(:quoted_id)
306
-
314
+
307
315
  if value.kind_of?(String) && column && column.type == :binary
308
316
  "'#{escape_bytea(value)}'"
309
317
  elsif column && column.type == :primary_key
@@ -320,7 +328,7 @@ module ::JdbcSpec
320
328
  result
321
329
  end
322
330
  end
323
-
331
+
324
332
  def quote_column_name(name)
325
333
  %("#{name}")
326
334
  end
@@ -329,10 +337,17 @@ module ::JdbcSpec
329
337
  value.strftime("%Y-%m-%d %H:%M:%S")
330
338
  end
331
339
 
340
+ def disable_referential_integrity(&block) #:nodoc:
341
+ execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} DISABLE TRIGGER ALL" }.join(";"))
342
+ yield
343
+ ensure
344
+ execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} ENABLE TRIGGER ALL" }.join(";"))
345
+ end
346
+
332
347
  def rename_table(name, new_name)
333
348
  execute "ALTER TABLE #{name} RENAME TO #{new_name}"
334
349
  end
335
-
350
+
336
351
  def add_column(table_name, column_name, type, options = {})
337
352
  execute("ALTER TABLE #{table_name} ADD #{column_name} #{type_to_sql(type, options[:limit])}")
338
353
  change_column_default(table_name, column_name, options[:default]) unless options[:default].nil?
@@ -355,23 +370,23 @@ module ::JdbcSpec
355
370
  commit_db_transaction
356
371
  end
357
372
  change_column_default(table_name, column_name, options[:default]) unless options[:default].nil?
358
- end
359
-
373
+ end
374
+
360
375
  def change_column_default(table_name, column_name, default) #:nodoc:
361
376
  execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET DEFAULT '#{default}'"
362
377
  end
363
-
378
+
364
379
  def rename_column(table_name, column_name, new_column_name) #:nodoc:
365
380
  execute "ALTER TABLE #{table_name} RENAME COLUMN #{column_name} TO #{new_column_name}"
366
381
  end
367
-
382
+
368
383
  def remove_index(table_name, options) #:nodoc:
369
384
  execute "DROP INDEX #{index_name(table_name, options)}"
370
385
  end
371
386
 
372
387
  def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc:
373
388
  return super unless type.to_s == 'integer'
374
-
389
+
375
390
  if limit.nil? || limit == 4
376
391
  'integer'
377
392
  elsif limit < 4
@@ -384,5 +399,5 @@ module ::JdbcSpec
384
399
  def tables
385
400
  @connection.tables(database_name, nil, nil, ["TABLE"])
386
401
  end
387
- end
402
+ end
388
403
  end
@@ -1,5 +1,5 @@
1
1
  module JdbcAdapter
2
2
  module Version
3
- VERSION = "0.8.2"
3
+ VERSION = "0.9"
4
4
  end
5
- end
5
+ end
@@ -235,7 +235,7 @@ public class JdbcAdapterInternalService implements BasicLibraryService {
235
235
  Throwable toWrap = null;
236
236
  boolean autoCommit = false;
237
237
  while (i < tries) {
238
- Connection c = getConnection(recv);
238
+ Connection c = getConnection(recv, true);
239
239
  try {
240
240
  autoCommit = c.getAutoCommit();
241
241
  return block.call(c);
@@ -370,7 +370,7 @@ public class JdbcAdapterInternalService implements BasicLibraryService {
370
370
  @JRubyMethod(name = "set_native_database_types")
371
371
  public static IRubyObject set_native_database_types(IRubyObject recv) throws SQLException, IOException {
372
372
  Ruby runtime = recv.getRuntime();
373
- IRubyObject types = unmarshal_result_downcase(recv, getConnection(recv).getMetaData().getTypeInfo());
373
+ IRubyObject types = unmarshal_result_downcase(recv, getConnection(recv, true).getMetaData().getTypeInfo());
374
374
  IRubyObject typeConverter = ((RubyModule) (runtime.getModule("ActiveRecord").getConstant("ConnectionAdapters"))).getConstant("JdbcTypeConverter");
375
375
  IRubyObject value = rubyApi.callMethod(rubyApi.callMethod(typeConverter, "new", types), "choose_best_types");
376
376
  rubyApi.setInstanceVariable(recv, "@native_types", value);
@@ -379,9 +379,9 @@ public class JdbcAdapterInternalService implements BasicLibraryService {
379
379
 
380
380
  @JRubyMethod(name = "database_name")
381
381
  public static IRubyObject database_name(IRubyObject recv) throws SQLException {
382
- String name = getConnection(recv).getCatalog();
382
+ String name = getConnection(recv, true).getCatalog();
383
383
  if(null == name) {
384
- name = getConnection(recv).getMetaData().getUserName();
384
+ name = getConnection(recv, true).getMetaData().getUserName();
385
385
  if(null == name) {
386
386
  name = "db1";
387
387
  }
@@ -391,13 +391,13 @@ public class JdbcAdapterInternalService implements BasicLibraryService {
391
391
 
392
392
  @JRubyMethod(name = "begin")
393
393
  public static IRubyObject begin(IRubyObject recv) throws SQLException {
394
- getConnection(recv).setAutoCommit(false);
394
+ getConnection(recv, true).setAutoCommit(false);
395
395
  return recv.getRuntime().getNil();
396
396
  }
397
397
 
398
398
  @JRubyMethod(name = "commit")
399
399
  public static IRubyObject commit(IRubyObject recv) throws SQLException {
400
- Connection c = getConnection(recv);
400
+ Connection c = getConnection(recv, true);
401
401
  if (!c.getAutoCommit()) {
402
402
  try {
403
403
  c.commit();
@@ -410,7 +410,7 @@ public class JdbcAdapterInternalService implements BasicLibraryService {
410
410
 
411
411
  @JRubyMethod(name = "rollback")
412
412
  public static IRubyObject rollback(IRubyObject recv) throws SQLException {
413
- Connection c = getConnection(recv);
413
+ Connection c = getConnection(recv, true);
414
414
  if (!c.getAutoCommit()) {
415
415
  try {
416
416
  c.rollback();
@@ -1057,7 +1057,15 @@ public class JdbcAdapterInternalService implements BasicLibraryService {
1057
1057
  }
1058
1058
 
1059
1059
  private static Connection getConnection(IRubyObject recv) {
1060
+ return getConnection(recv, false);
1061
+ }
1062
+
1063
+ private static Connection getConnection(IRubyObject recv, boolean error) {
1060
1064
  Connection conn = (Connection) recv.dataGetStruct();
1065
+ if(error && conn == null) {
1066
+ RubyClass err = recv.getRuntime().getModule("ActiveRecord").getClass("ConnectionNotEstablished");
1067
+ throw new RaiseException(recv.getRuntime(), err, "no connection available", false);
1068
+ }
1061
1069
  return conn;
1062
1070
  }
1063
1071
 
data/test/db/cachedb.rb CHANGED
File without changes
data/test/db/h2.rb CHANGED
@@ -4,6 +4,9 @@ config = {
4
4
  }
5
5
 
6
6
  ActiveRecord::Base.establish_connection(config)
7
+ logger = Logger.new 'h2-testdb.log'
8
+ logger.level = Logger::DEBUG
9
+ ActiveRecord::Base.logger = logger
7
10
 
8
11
  at_exit {
9
12
  # Clean up hsqldb when done
@@ -0,0 +1,11 @@
1
+ config = {
2
+ :username => 'blog',
3
+ :password => 'blog',
4
+ :adapter => 'informix',
5
+ :servername => 'ol_weblog',
6
+ :database => 'weblog_development',
7
+ :host => 'localhost',
8
+ :port => '9088'
9
+ }
10
+
11
+ ActiveRecord::Base.establish_connection(config)
@@ -0,0 +1,48 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # To run this script, run the following:
4
+ #
5
+ # CREATE DATABASE weblog_development;
6
+ #
7
+ # TODO: Finish the explanation.
8
+
9
+ require 'jdbc_common'
10
+ require 'db/informix'
11
+
12
+ class InformixSimpleTest < Test::Unit::TestCase
13
+ include SimpleTestMethods
14
+
15
+ # Informix does not like "= NULL".
16
+ def test_equals_null
17
+ Entry.create!(:title => "Foo")
18
+ entry = Entry.find(:first, :conditions => ["content = NULL"])
19
+ assert_equal "Foo", entry.title
20
+ end
21
+
22
+ # Informix does not like "!= NULL" or "<> NULL".
23
+ def test_not_equals_null
24
+ Entry.create!(:title => "Foo", :content => "Bar")
25
+ entry = Entry.find_by_title("Foo", :conditions => ["content != NULL"])
26
+ assert_equal "Foo", entry.title
27
+ entry = Entry.find_by_title("Foo", :conditions => ["content <> NULL"])
28
+ assert_equal "Foo", entry.title
29
+ end
30
+ end
31
+
32
+ class InformixMultibyteTest < Test::Unit::TestCase
33
+ include MultibyteTestMethods
34
+
35
+ # Overriding the included test since we can't create text fields via a
36
+ # simple insert in Informix.
37
+ def test_select_multibyte_string
38
+ Entry.create!(:title => 'テスト', :content => '本文')
39
+ entry = Entry.find(:first)
40
+ assert_equal "テスト", entry.title
41
+ assert_equal "本文", entry.content
42
+ assert_equal entry, Entry.find_by_title("テスト")
43
+ end
44
+ end
45
+
46
+ class InformixHasManyThroughTest < Test::Unit::TestCase
47
+ include HasManyThroughMethods
48
+ end
data/test/jdbc_common.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  require 'rubygems'
2
- # Specify version of activerecord here if desired
3
- # gem 'activerecord', '=2.1'
2
+ # Specify version of activerecord with ENV['AR_VERSION'] if desired
3
+ gem 'activerecord', ENV['AR_VERSION'] if ENV['AR_VERSION']
4
4
  require 'jdbc_adapter'
5
+ puts "Using activerecord version #{ActiveRecord::VERSION::STRING}"
6
+ puts "Specify version with AR_VERSION=={version} or RUBYLIB={path}"
5
7
  require 'models/auto_id'
6
8
  require 'models/entry'
7
9
  require 'models/add_not_null_column_to_table'
@@ -0,0 +1,38 @@
1
+ require 'jdbc_common'
2
+
3
+ begin
4
+ require 'mocha'
5
+
6
+ class JndiConnectionPoolCallbacksTest < Test::Unit::TestCase
7
+ def setup
8
+ @connection = mock "JdbcConnection"
9
+ @connection.stubs(:jndi_connection?).returns(true)
10
+ @connection.stubs(:adapter=)
11
+ @logger = mock "logger"
12
+ @config = { :jndi => "jdbc/some_pool", :adapter => "mysql" }
13
+ Entry.connection_pool.disconnect!
14
+ assert !Entry.connection_pool.connected?
15
+ class << Entry.connection_pool; public :instance_variable_set; end
16
+ end
17
+
18
+ def teardown
19
+ @connection.stubs(:disconnect!)
20
+ Entry.connection_pool.disconnect!
21
+ end
22
+
23
+ def test_should_call_hooks_on_checkout_and_checkin
24
+ @connection.expects(:disconnect!)
25
+ @adapter = ActiveRecord::ConnectionAdapters::JdbcAdapter.new @connection, @logger, @config
26
+ Entry.connection_pool.instance_variable_set "@connections", [@adapter]
27
+
28
+ @connection.expects(:reconnect!)
29
+ Entry.connection_pool.checkout
30
+
31
+ @connection.expects(:disconnect!)
32
+ Entry.connection_pool.checkin @adapter
33
+ end
34
+ end
35
+
36
+ rescue LoadError
37
+ warn "mocha not found, disabling mocha-based tests"
38
+ end if ActiveRecord::Base.respond_to?(:connection_pool)
File without changes
data/test/simple.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  ActiveRecord::Schema.verbose = false
2
3
 
3
4
  module MigrationSetup
@@ -138,6 +139,7 @@ module SimpleTestMethods
138
139
  def test_disconnect
139
140
  assert_equal 1, Entry.count
140
141
  ActiveRecord::Base.clear_active_connections!
142
+ ActiveRecord::Base.connection_pool.disconnect! if ActiveRecord::Base.respond_to?(:connection_pool)
141
143
  assert !ActiveRecord::Base.connected?
142
144
  assert_equal 1, Entry.count
143
145
  assert ActiveRecord::Base.connected?
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-jdbc-adapter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.2
4
+ version: "0.9"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Sieger, Ola Bini and JRuby contributors
@@ -9,11 +9,11 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-06-17 00:00:00 -07:00
12
+ date: 2008-11-26 00:00:00 -06:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
16
- description: ActiveRecord-JDBC is a database adapter for Rails' ActiveRecord component that can be used with JRuby[http://www.jruby.org/]. It allows use of virtually any JDBC-compliant database with your JRuby on Rails application.
16
+ description: activerecord-jdbc-adapter is a database adapter for Rails' ActiveRecord component that can be used with JRuby[http://www.jruby.org/]. It allows use of virtually any JDBC-compliant database with your JRuby on Rails application.
17
17
  email: nick@nicksieger.com, ola.bini@gmail.com
18
18
  executables: []
19
19
 
@@ -34,6 +34,7 @@ files:
34
34
  - lib/active_record/connection_adapters/derby_adapter.rb
35
35
  - lib/active_record/connection_adapters/h2_adapter.rb
36
36
  - lib/active_record/connection_adapters/hsqldb_adapter.rb
37
+ - lib/active_record/connection_adapters/informix_adapter.rb
37
38
  - lib/active_record/connection_adapters/jdbc_adapter.rb
38
39
  - lib/active_record/connection_adapters/jdbc_adapter_spec.rb
39
40
  - lib/active_record/connection_adapters/jndi_adapter.rb
@@ -46,6 +47,7 @@ files:
46
47
  - lib/jdbc_adapter/jdbc_derby.rb
47
48
  - lib/jdbc_adapter/jdbc_firebird.rb
48
49
  - lib/jdbc_adapter/jdbc_hsqldb.rb
50
+ - lib/jdbc_adapter/jdbc_informix.rb
49
51
  - lib/jdbc_adapter/jdbc_mimer.rb
50
52
  - lib/jdbc_adapter/jdbc_mssql.rb
51
53
  - lib/jdbc_adapter/jdbc_mysql.rb
@@ -67,6 +69,7 @@ files:
67
69
  - test/db/derby.rb
68
70
  - test/db/h2.rb
69
71
  - test/db/hsqldb.rb
72
+ - test/db/informix.rb
70
73
  - test/db/jdbc.rb
71
74
  - test/db/jndi_config.rb
72
75
  - test/db/logger.rb
@@ -82,9 +85,11 @@ files:
82
85
  - test/h2_simple_test.rb
83
86
  - test/has_many_through.rb
84
87
  - test/hsqldb_simple_test.rb
88
+ - test/informix_simple_test.rb
85
89
  - test/jdbc_adapter/jdbc_db2_test.rb
86
90
  - test/jdbc_adapter/jdbc_sybase_test.rb
87
91
  - test/jdbc_common.rb
92
+ - test/jndi_callbacks_test.rb
88
93
  - test/jndi_test.rb
89
94
  - test/manualTestDatabase.rb
90
95
  - test/minirunit/testConnect.rb
@@ -136,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
136
141
  requirements: []
137
142
 
138
143
  rubyforge_project: jruby-extras
139
- rubygems_version: 1.0.1
144
+ rubygems_version: 1.3.1
140
145
  signing_key:
141
146
  specification_version: 2
142
147
  summary: JDBC adapter for ActiveRecord, for use within JRuby on Rails.