activerecord-jdbc-adapter 1.0.0.beta1-java → 1.0.0.beta2-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. data/History.txt +37 -0
  2. data/Manifest.txt +8 -0
  3. data/README.txt +41 -88
  4. data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -0
  5. data/lib/arel/engines/sql/compilers/hsqldb_compiler.rb +9 -0
  6. data/lib/arel/engines/sql/compilers/mssql_compiler.rb +34 -0
  7. data/lib/arjdbc/db2/adapter.rb +232 -52
  8. data/lib/arjdbc/derby/adapter.rb +28 -1
  9. data/lib/arjdbc/derby/connection_methods.rb +1 -1
  10. data/lib/arjdbc/discover.rb +1 -1
  11. data/lib/arjdbc/firebird/adapter.rb +26 -0
  12. data/lib/arjdbc/h2/adapter.rb +13 -0
  13. data/lib/arjdbc/hsqldb/adapter.rb +8 -6
  14. data/lib/arjdbc/informix/adapter.rb +4 -0
  15. data/lib/arjdbc/jdbc/adapter.rb +27 -5
  16. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  17. data/lib/arjdbc/jdbc/connection.rb +76 -45
  18. data/lib/arjdbc/jdbc/jdbc.rake +22 -20
  19. data/lib/arjdbc/jdbc/type_converter.rb +9 -2
  20. data/lib/arjdbc/mssql/adapter.rb +102 -24
  21. data/lib/arjdbc/mssql/connection_methods.rb +19 -2
  22. data/lib/arjdbc/mssql/tsql_helper.rb +1 -0
  23. data/lib/arjdbc/mysql/adapter.rb +6 -0
  24. data/lib/arjdbc/mysql/connection_methods.rb +8 -7
  25. data/lib/arjdbc/oracle/adapter.rb +8 -6
  26. data/lib/arjdbc/postgresql/adapter.rb +51 -19
  27. data/lib/arjdbc/version.rb +1 -1
  28. data/lib/jdbc_adapter/rake_tasks.rb +3 -0
  29. data/rails_generators/templates/lib/tasks/jdbc.rake +2 -2
  30. data/rakelib/package.rake +2 -0
  31. data/rakelib/test.rake +6 -3
  32. data/src/java/arjdbc/derby/DerbyModule.java +30 -1
  33. data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +74 -0
  34. data/src/java/arjdbc/jdbc/AdapterJavaService.java +7 -3
  35. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +45 -30
  36. data/src/java/arjdbc/mssql/MssqlRubyJdbcConnection.java +54 -1
  37. data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +85 -0
  38. data/test/abstract_db_create.rb +6 -1
  39. data/test/db/jndi_config.rb +20 -10
  40. data/test/db2_simple_test.rb +34 -1
  41. data/test/derby_simple_test.rb +78 -0
  42. data/test/generic_jdbc_connection_test.rb +21 -1
  43. data/test/jndi_callbacks_test.rb +2 -1
  44. data/test/jndi_test.rb +1 -11
  45. data/test/models/entry.rb +20 -0
  46. data/test/mssql_limit_offset_test.rb +28 -0
  47. data/test/mssql_simple_test.rb +7 -1
  48. data/test/mysql_info_test.rb +49 -6
  49. data/test/mysql_simple_test.rb +4 -0
  50. data/test/oracle_simple_test.rb +3 -47
  51. data/test/oracle_specific_test.rb +83 -0
  52. data/test/postgres_db_create_test.rb +6 -0
  53. data/test/postgres_drop_db_test.rb +16 -0
  54. data/test/postgres_simple_test.rb +17 -0
  55. data/test/postgres_table_alias_length_test.rb +15 -0
  56. data/test/simple.rb +17 -4
  57. metadata +33 -7
@@ -0,0 +1,85 @@
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.oracle;
27
+
28
+ import java.sql.ResultSet;
29
+ import java.sql.SQLException;
30
+
31
+ import arjdbc.jdbc.RubyJdbcConnection;
32
+
33
+ import org.jruby.Ruby;
34
+ import org.jruby.RubyClass;
35
+ import org.jruby.runtime.ObjectAllocator;
36
+ import org.jruby.runtime.builtin.IRubyObject;
37
+
38
+ /**
39
+ *
40
+ * @author nicksieger
41
+ */
42
+ public class OracleRubyJdbcConnection extends RubyJdbcConnection {
43
+ protected OracleRubyJdbcConnection(Ruby runtime, RubyClass metaClass) {
44
+ super(runtime, metaClass);
45
+ }
46
+
47
+ public static RubyClass createOracleJdbcConnectionClass(Ruby runtime, RubyClass jdbcConnection) {
48
+ RubyClass clazz = RubyJdbcConnection.getConnectionAdapters(runtime).defineClassUnder("OracleJdbcConnection",
49
+ jdbcConnection, ORACLE_JDBCCONNECTION_ALLOCATOR);
50
+ clazz.defineAnnotatedMethods(OracleRubyJdbcConnection.class);
51
+
52
+ return clazz;
53
+ }
54
+
55
+ private static ObjectAllocator ORACLE_JDBCCONNECTION_ALLOCATOR = new ObjectAllocator() {
56
+ public IRubyObject allocate(Ruby runtime, RubyClass klass) {
57
+ return new OracleRubyJdbcConnection(runtime, klass);
58
+ }
59
+ };
60
+
61
+ /**
62
+ * Oracle needs this override to reconstruct NUMBER which is different
63
+ * from NUMBER(x) or NUMBER(x,y).
64
+ */
65
+ @Override
66
+ protected String typeFromResultSet(ResultSet resultSet) throws SQLException {
67
+ int precision = intFromResultSet(resultSet, COLUMN_SIZE);
68
+ int scale = intFromResultSet(resultSet, DECIMAL_DIGITS);
69
+
70
+ // According to http://forums.oracle.com/forums/thread.jspa?threadID=658646
71
+ // Unadorned NUMBER reports scale == null, so we look for that here.
72
+ if (scale < 0 && resultSet.getInt(DATA_TYPE) == java.sql.Types.DECIMAL) {
73
+ precision = -1;
74
+ }
75
+
76
+ String type = resultSet.getString(TYPE_NAME);
77
+ if (precision > 0) {
78
+ type += "(" + precision;
79
+ if(scale > 0) type += "," + scale;
80
+ type += ")";
81
+ }
82
+
83
+ return type;
84
+ }
85
+ }
@@ -28,8 +28,11 @@ module AbstractDbCreate
28
28
  load File.dirname(__FILE__) + '/../lib/arjdbc/jdbc/jdbc.rake' if jruby?
29
29
  task :environment do
30
30
  ActiveRecord::Base.configurations = configurations
31
+ @full_env_loaded = true
32
+ end
33
+ task :rails_env do
34
+ @rails_env_set = true
31
35
  end
32
- task :rails_env
33
36
  end
34
37
 
35
38
  def teardown
@@ -38,6 +41,8 @@ module AbstractDbCreate
38
41
  restore_rails
39
42
  ActiveRecord::Base.configurations = @prevconfigs
40
43
  ActiveRecord::Base.establish_connection(db_config)
44
+ @rails_env_set = nil
45
+ @full_env_loaded = nil
41
46
  end
42
47
 
43
48
  def setup_rails
@@ -1,6 +1,18 @@
1
1
  require 'fileutils'
2
2
  require 'arjdbc'
3
3
 
4
+ JNDI_CONFIG = {
5
+ :adapter => "jdbc",
6
+ :jndi => 'jdbc/derbydb'
7
+ }
8
+
9
+ # To test JNDI, grab fscontext-1_2-beta3.zip from
10
+ # http://java.sun.com/products/jndi/downloads/index.html
11
+ # and put fscontext.jar and providerutil.jar in test/
12
+ require 'test/fscontext.jar'
13
+ require 'test/providerutil.jar'
14
+ require 'jdbc/derby'
15
+
4
16
  System = java.lang.System
5
17
  Context = javax.naming.Context
6
18
  InitialContext = javax.naming.InitialContext
@@ -15,16 +27,14 @@ jdbc_dir = jndi_dir + '/jdbc'
15
27
  FileUtils.mkdir_p jdbc_dir unless File.exist?(jdbc_dir)
16
28
 
17
29
  System.set_property(Context::PROVIDER_URL, "file://#{jndi_dir}")
18
- derby_ref = Reference.new('javax.sql.DataSource',
19
- 'org.apache.commons.dbcp.BasicDataSourceFactory',
20
- nil)
21
- derby_ref.add StringRefAddr.new('driverClassName',
22
- 'org.apache.derby.jdbc.EmbeddedDriver')
23
- derby_ref.add StringRefAddr.new('url',
24
- 'jdbc:derby:derby-testdb;create=true')
25
- derby_ref.add StringRefAddr.new('username', 'sa')
26
- derby_ref.add StringRefAddr.new('password', '')
27
30
 
28
31
  ic = InitialContext.new
29
- ic.rebind("jdbc/derbydb", derby_ref)
32
+ ic.rebind(JNDI_CONFIG[:jndi],
33
+ org.apache.derby.jdbc.EmbeddedDataSource.new.tap {|ds|
34
+ ds.database_name = "derby-testdb"
35
+ ds.create_database = "create"
36
+ ds.user = "sa"
37
+ ds.password = ""})
38
+
30
39
 
40
+ ActiveRecord::Base.establish_connection(JNDI_CONFIG)
@@ -3,6 +3,40 @@ require 'db/db2'
3
3
 
4
4
  class DB2SimpleTest < Test::Unit::TestCase
5
5
  include SimpleTestMethods
6
+
7
+ # For backwards compatibility with how the DB2 code in
8
+ # jdbc_adapter 0.9.x handled booleans.
9
+ #
10
+ # The old DB2 jdbc_db2.rb driver was broken enough that
11
+ # applications were exposed to the underlying type (was DECIMAL)
12
+ # and used 0 and 1 as false and true, respectively.
13
+ #
14
+ # This driver now uses SMALLINT as a boolean, and properly
15
+ # type cast's it to a Ruby boolean. Need to make sure we don't
16
+ # break existing apps!
17
+ def test_boolean_as_integer
18
+ e = DbType.find(:first)
19
+
20
+ # true
21
+ e.sample_boolean = 1
22
+ assert_equal true, e.sample_boolean
23
+ assert_equal true, e.sample_boolean?
24
+ e.save!
25
+
26
+ e = DbType.find(:first)
27
+ assert_equal true, e.sample_boolean
28
+ assert_equal true, e.sample_boolean?
29
+
30
+ # false
31
+ e.sample_boolean = 0
32
+ assert_equal false, e.sample_boolean
33
+ assert_equal false, e.sample_boolean?
34
+ e.save!
35
+
36
+ e = DbType.find(:first)
37
+ assert_equal false, e.sample_boolean
38
+ assert_equal false, e.sample_boolean?
39
+ end
6
40
  end
7
41
 
8
42
  class DB2HasManyThroughTest < Test::Unit::TestCase
@@ -29,5 +63,4 @@ class DB2Test < Test::Unit::TestCase
29
63
  @column.type = :primary_key
30
64
  assert_equal 'int not null generated by default as identity (start with 1) primary key', @inst.modify_types({:string => {}, :integer => {}, :boolean => {}})[:primary_key]
31
65
  end
32
-
33
66
  end
@@ -18,4 +18,82 @@ class DerbySimpleTest < Test::Unit::TestCase
18
18
  end
19
19
  assert_equal [['ur', 'doin', 'it', 'right']], value
20
20
  end
21
+
22
+ def test_find_with_include_and_order
23
+ users = User.find(:all, :include=>[:entries], :order=>"entries.rating DESC", :limit=>2)
24
+
25
+ assert users.include?(@user)
26
+ end
27
+
28
+ def test_text_and_string_conversions
29
+ e = DbType.find(:first)
30
+
31
+ # Derby will normally reject any non text value.
32
+ # The adapter has been patched to convert non text values to strings
33
+ ['string', 45, 4.3, 18488425889503641645].each do |value|
34
+ assert_nothing_raised do
35
+ e.sample_string = value
36
+ e.sample_text = value
37
+ e.save!
38
+ e.reload
39
+ assert_equal [value.to_s]*2, [e.sample_string, e.sample_text]
40
+ end
41
+ end
42
+ [true, false].each do |value|
43
+ assert_nothing_raised do
44
+ e.sample_string = value
45
+ e.sample_text = value
46
+ e.save!
47
+ e.reload
48
+ assert_equal [value ? "1" : "0"]*2, [e.sample_string, e.sample_text]
49
+ end
50
+ end
51
+ assert_nothing_raised do
52
+ value = Time.now
53
+ if ActiveRecord::VERSION::MAJOR >= 3
54
+ str = value.utc.to_s(:db)
55
+ else # AR 2 #quoted_date did not do TZ conversions
56
+ str = value.to_s(:db)
57
+ end
58
+ e.sample_string = value
59
+ e.sample_text = value
60
+ e.save!
61
+ e.reload
62
+ assert_equal [str]*2, [e.sample_string, e.sample_text]
63
+ end
64
+ assert_nothing_raised do
65
+ value = Date.today
66
+ e.sample_string = value
67
+ e.sample_text = value
68
+ e.save!
69
+ e.reload
70
+ assert_equal [value.to_s(:db)]*2, [e.sample_string, e.sample_text]
71
+ end
72
+ value = {'a' => 7}
73
+ assert_nothing_raised do
74
+ e.sample_string = value
75
+ e.sample_text = value
76
+ e.save!
77
+ e.reload
78
+ assert_equal [value.to_yaml]*2, [e.sample_string, e.sample_text]
79
+ end
80
+ value = BigDecimal.new("0")
81
+ assert_nothing_raised do
82
+ e.sample_string = value
83
+ e.sample_text = value
84
+ e.save!
85
+ e.reload
86
+ assert_equal ['0.0']*2, [e.sample_string, e.sample_text]
87
+ end
88
+ # An empty string is treated as a null value in Oracle: http://www.techonthenet.com/oracle/questions/empty_null.php
89
+ unless ActiveRecord::Base.connection.adapter_name =~ /oracle/i
90
+ assert_nothing_raised do
91
+ e.sample_string = nil
92
+ e.sample_text = nil
93
+ e.save!
94
+ e.reload
95
+ assert_equal [nil]*2, [e.sample_string, e.sample_text]
96
+ end
97
+ end
98
+ end
21
99
  end
@@ -6,4 +6,24 @@ class GenericJdbcConnectionTest < Test::Unit::TestCase
6
6
  ActiveRecord::Base.connection.execute("show databases");
7
7
  assert ActiveRecord::Base.connected?
8
8
  end
9
- end
9
+
10
+ def test_configure_connection_url
11
+ connection = Object.new
12
+ connection.extend ActiveRecord::ConnectionAdapters::JdbcConnection::ConfigHelper
13
+ connection.config = { :url => "jdbc://somehost", :options => { :hoge => "true", :fuya => "false"} }
14
+ assert_equal "jdbc://somehost?hoge=true&fuya=false", connection.configure_url
15
+
16
+ connection.config = { :url => "jdbc://somehost?param=0", :options => { :hoge => "true", :fuya => "false"} }
17
+ assert_equal "jdbc://somehost?param=0&hoge=true&fuya=false", connection.configure_url
18
+ end
19
+
20
+ def test_connection_fails_without_driver_and_url
21
+ conn = ActiveRecord::Base.remove_connection
22
+ assert_raises(ActiveRecord::ConnectionNotEstablished) do
23
+ ActiveRecord::Base.establish_connection :adapter => 'jdbc'
24
+ ActiveRecord::Base.connection
25
+ end
26
+ ensure
27
+ ActiveRecord::Base.establish_connection conn
28
+ end
29
+ end
@@ -1,4 +1,5 @@
1
1
  require 'jdbc_common'
2
+ require 'db/jndi_config'
2
3
 
3
4
  begin
4
5
  require 'mocha'
@@ -9,7 +10,7 @@ class JndiConnectionPoolCallbacksTest < Test::Unit::TestCase
9
10
  @connection.stubs(:jndi_connection?).returns(true)
10
11
  @connection.stubs(:adapter=)
11
12
  @logger = mock "logger"
12
- @config = { :jndi => "jdbc/some_pool", :adapter => "mysql" }
13
+ @config = JNDI_CONFIG
13
14
  Entry.connection_pool.disconnect!
14
15
  assert !Entry.connection_pool.connected?
15
16
  class << Entry.connection_pool; public :instance_variable_set; end
data/test/jndi_test.rb CHANGED
@@ -17,19 +17,9 @@ require 'db/jndi_config'
17
17
 
18
18
  class DerbyJndiTest < Test::Unit::TestCase
19
19
  include SimpleTestMethods
20
- alias_method :setup_simple, :setup
21
- def setup
22
- ActiveRecord::Base.establish_connection({
23
- :jndi => 'jdbc/derbydb',
24
- :adapter => 'jdbc'})
25
- logger = Logger.new('jndi_test.log')
26
- logger.level = Logger::DEBUG
27
- ActiveRecord::Base.logger = logger
28
- setup_simple
29
- end
30
20
  end
31
21
 
32
- at_exit {
22
+ at_exit {
33
23
  require 'fileutils'
34
24
  FileUtils.rm_rf 'derby-testdb'
35
25
  }
data/test/models/entry.rb CHANGED
@@ -8,6 +8,7 @@ class CreateEntries < ActiveRecord::Migration
8
8
  t.column :updated_on, :datetime
9
9
  t.column :content, :text
10
10
  t.column :rating, :decimal, :precision => 10, :scale => 2
11
+ t.column :user_id, :integer
11
12
  end
12
13
  end
13
14
 
@@ -17,7 +18,26 @@ class CreateEntries < ActiveRecord::Migration
17
18
  end
18
19
 
19
20
  class Entry < ActiveRecord::Base
21
+ belongs_to :user
22
+
20
23
  def to_param
21
24
  "#{id}-#{title.gsub(/[^a-zA-Z0-9]/, '-')}"
22
25
  end
23
26
  end
27
+
28
+ class CreateUsers < ActiveRecord::Migration
29
+ def self.up
30
+ create_table "users", :force => true do |t|
31
+ t.column :login, :string, :limit => 100
32
+ end
33
+ end
34
+
35
+ def self.down
36
+ drop_table "users"
37
+ end
38
+ end
39
+
40
+ class User < ActiveRecord::Base
41
+ has_many :entries
42
+ end
43
+
@@ -42,20 +42,48 @@ class Viking < ActiveRecord::Base
42
42
  belongs_to :long_ship
43
43
  end
44
44
 
45
+
46
+ class CreateNoIdVikings < ActiveRecord::Migration
47
+ def self.up
48
+ create_table "no_id_vikings", :force => true do |t|
49
+ t.string "name", :limit => 50, :default => "Sven"
50
+ end
51
+ remove_column "no_id_vikings", "id"
52
+ end
53
+
54
+ def self.down
55
+ drop_table "no_id_vikings"
56
+ end
57
+ end
58
+
59
+ class NoIdViking < ActiveRecord::Base
60
+ end
61
+
62
+
63
+
45
64
  class MsSQLLimitOffsetTest < Test::Unit::TestCase
46
65
 
47
66
  def setup
48
67
  CreateLongShips.up
49
68
  CreateVikings.up
69
+ CreateNoIdVikings.up
50
70
  @connection = ActiveRecord::Base.connection
51
71
  end
52
72
 
53
73
  def teardown
54
74
  CreateVikings.down
55
75
  CreateLongShips.down
76
+ CreateNoIdVikings.down
56
77
  ActiveRecord::Base.clear_active_connections!
57
78
  end
58
79
 
80
+ def test_limit_with_no_id_column_available
81
+ NoIdViking.create!(:name => 'Erik')
82
+ assert_nothing_raised(ActiveRecord::StatementInvalid) do
83
+ NoIdViking.find(:first)
84
+ end
85
+ end
86
+
59
87
  def test_limit_and_offset
60
88
  %w(one two three four five six seven eight).each do |name|
61
89
  LongShip.create!(:name => name)
@@ -12,7 +12,7 @@ class MsSQLSimpleTest < Test::Unit::TestCase
12
12
  undef_method :test_validates_uniqueness_of_strings_case_sensitive
13
13
 
14
14
  def test_does_not_munge_quoted_strings
15
- example_quoted_values = [%{'quoted'}, %{D'oh!}]
15
+ example_quoted_values = [%{'quoted'}, %{D\'oh!}]
16
16
  example_quoted_values.each do |value|
17
17
  entry = Entry.create!(:title => value)
18
18
  entry.reload
@@ -46,4 +46,10 @@ class MsSQLSimpleTest < Test::Unit::TestCase
46
46
 
47
47
  end
48
48
 
49
+ # ACTIVERECORD_JDBC-124
50
+ def test_model_does_not_have_row_num_column
51
+ entry = Entry.first
52
+ assert !entry.attributes.keys.include?("_row_num")
53
+ assert !entry.respond_to?(:_row_num)
54
+ end
49
55
  end