activerecord-jdbc-adapter 0.9.5-java → 0.9.6-java
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +14 -0
- data/lib/active_record/connection_adapters/jdbc_adapter.rb +25 -10
- data/lib/jdbc_adapter/jdbc_adapter_internal.jar +0 -0
- data/lib/jdbc_adapter/jdbc_mimer.rb +4 -0
- data/lib/jdbc_adapter/jdbc_oracle.rb +30 -10
- data/lib/jdbc_adapter/version.rb +1 -1
- data/src/java/jdbc_adapter/RubyJdbcConnection.java +18 -7
- data/test/oracle_simple_test.rb +32 -7
- data/test/simple.rb +20 -1
- metadata +3 -3
data/History.txt
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
== 0.9.6
|
2
|
+
|
3
|
+
- The Oracle release!
|
4
|
+
- Oracle should be working much better with this release. Also updated
|
5
|
+
to work with Rails 3.
|
6
|
+
- Get all unit tests running cleanly on Oracle, fixing previous
|
7
|
+
datetime/timezone issues.
|
8
|
+
- ACTIVERECORD_JDBC-83: Add :sequence_start_value option to
|
9
|
+
create_table, following oracle_enhanced adapter
|
10
|
+
- ACTIVERECORD_JDBC-33: Don't double-quote table names in oracle
|
11
|
+
- ACTIVERECORD_JDBC-17: Fix Oracle primary keys so that /^NUMBER$/ => :integer
|
12
|
+
- Fix remaining blockers ACTIVERECORD_JDBC-82, JRUBY-3675,
|
13
|
+
ACTIVERECORD_JDBC-22, ACTIVERECORD_JDBC-27, JRUBY-4759
|
14
|
+
|
1
15
|
== 0.9.5
|
2
16
|
|
3
17
|
- The MSSQL release, courtesy of Mike Williams and Lonely
|
@@ -56,21 +56,36 @@ module JdbcSpec
|
|
56
56
|
jdbc_connection(config)
|
57
57
|
end
|
58
58
|
end
|
59
|
+
|
60
|
+
module QuotedPrimaryKeyExtension
|
61
|
+
def self.extended(base)
|
62
|
+
# Rails 3 method Rails 2 method
|
63
|
+
meth = [:arel_attributes_values, :attributes_with_quotes].detect do |m|
|
64
|
+
base.private_instance_methods.include?(m.to_s)
|
65
|
+
end
|
66
|
+
pk_hash_key = "self.class.primary_key"
|
67
|
+
pk_hash_value = '"?"'
|
68
|
+
if meth == :arel_attributes_values
|
69
|
+
pk_hash_key = "self.class.arel_table[#{pk_hash_key}]"
|
70
|
+
pk_hash_value = "Arel::SqlLiteral.new(#{pk_hash_value})"
|
71
|
+
end
|
72
|
+
if meth
|
73
|
+
base.module_eval %{
|
74
|
+
alias :#{meth}_pre_pk :#{meth}
|
75
|
+
def #{meth}(include_primary_key = true, *args) #:nodoc:
|
76
|
+
aq = #{meth}_pre_pk(include_primary_key, *args)
|
77
|
+
aq[#{pk_hash_key}] = #{pk_hash_value} if include_primary_key && aq[#{pk_hash_key}].nil?
|
78
|
+
aq
|
79
|
+
end
|
80
|
+
}
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
59
84
|
end
|
60
85
|
|
61
86
|
module ActiveRecord
|
62
87
|
class Base
|
63
88
|
extend JdbcSpec::ActiveRecordExtensions
|
64
|
-
if respond_to?(:attributes_with_quotes)
|
65
|
-
alias :attributes_with_quotes_pre_oracle :attributes_with_quotes
|
66
|
-
def attributes_with_quotes(include_primary_key = true, *args) #:nodoc:
|
67
|
-
aq = attributes_with_quotes_pre_oracle(include_primary_key, *args)
|
68
|
-
if connection.class == ConnectionAdapters::JdbcAdapter && (connection.is_a?(JdbcSpec::Oracle) || connection.is_a?(JdbcSpec::Mimer))
|
69
|
-
aq[self.class.primary_key] = "?" if include_primary_key && aq[self.class.primary_key].nil?
|
70
|
-
end
|
71
|
-
aq
|
72
|
-
end
|
73
|
-
end
|
74
89
|
end
|
75
90
|
|
76
91
|
module ConnectionAdapters
|
Binary file
|
@@ -26,8 +26,10 @@ module ::JdbcSpec
|
|
26
26
|
ActiveRecord::Base.after_save :after_save_with_oracle_lob
|
27
27
|
@lob_callback_added = true
|
28
28
|
end
|
29
|
+
ActiveRecord::Base.extend JdbcSpec::QuotedPrimaryKeyExtension
|
29
30
|
mod.class.class_eval do
|
30
|
-
alias_chained_method :insert, :query_dirty, :
|
31
|
+
alias_chained_method :insert, :query_dirty, :insert
|
32
|
+
alias_chained_method :columns, :query_cache, :columns
|
31
33
|
end
|
32
34
|
end
|
33
35
|
|
@@ -40,6 +42,13 @@ module ::JdbcSpec
|
|
40
42
|
end
|
41
43
|
|
42
44
|
module Column
|
45
|
+
def primary=(val)
|
46
|
+
super
|
47
|
+
if val && @sql_type =~ /^NUMBER$/i
|
48
|
+
@type = :integer
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
43
52
|
def type_cast(value)
|
44
53
|
return nil if value.nil?
|
45
54
|
case type
|
@@ -63,8 +72,8 @@ module ::JdbcSpec
|
|
63
72
|
end
|
64
73
|
|
65
74
|
def self.guess_date_or_time(value)
|
66
|
-
(value.hour == 0 && value.min == 0 && value.sec == 0) ?
|
67
|
-
|
75
|
+
(value && value.hour == 0 && value.min == 0 && value.sec == 0) ?
|
76
|
+
Date.new(value.year, value.month, value.day) : value
|
68
77
|
end
|
69
78
|
|
70
79
|
private
|
@@ -74,7 +83,7 @@ module ::JdbcSpec
|
|
74
83
|
when /char/i then :string
|
75
84
|
when /float|double/i then :float
|
76
85
|
when /int/i then :integer
|
77
|
-
when /num|dec|real/i then
|
86
|
+
when /num|dec|real/i then extract_scale(field_type) == 0 ? :integer : :decimal
|
78
87
|
when /date|time/i then :datetime
|
79
88
|
when /clob/i then :text
|
80
89
|
when /blob/i then :binary
|
@@ -115,8 +124,9 @@ module ::JdbcSpec
|
|
115
124
|
def create_table(name, options = {}) #:nodoc:
|
116
125
|
super(name, options)
|
117
126
|
seq_name = options[:sequence_name] || "#{name}_seq"
|
127
|
+
start_value = options[:sequence_start_value] || 10000
|
118
128
|
raise ActiveRecord::StatementInvalid.new("name #{seq_name} too long") if seq_name.length > table_alias_length
|
119
|
-
execute "CREATE SEQUENCE #{seq_name} START WITH
|
129
|
+
execute "CREATE SEQUENCE #{seq_name} START WITH #{start_value}" unless options[:id] == false
|
120
130
|
end
|
121
131
|
|
122
132
|
def rename_table(name, new_name) #:nodoc:
|
@@ -138,10 +148,14 @@ module ::JdbcSpec
|
|
138
148
|
recreate_database(name)
|
139
149
|
end
|
140
150
|
|
141
|
-
def
|
142
|
-
if id_value || pk.nil?
|
151
|
+
def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
|
152
|
+
if (id_value && !id_value.respond_to?(:to_sql)) || pk.nil?
|
153
|
+
# Pre-assigned id or table without a primary key
|
154
|
+
# Presence of #to_sql means an Arel literal bind variable
|
155
|
+
# that should use #execute_id_insert below
|
143
156
|
execute sql, name
|
144
|
-
else
|
157
|
+
else
|
158
|
+
# Assume the sql contains a bind-variable for the id
|
145
159
|
# Extract the table from the insert sql. Yuck.
|
146
160
|
table = sql.split(" ", 4)[2].gsub('"', '')
|
147
161
|
sequence_name ||= default_sequence_name(table)
|
@@ -313,6 +327,12 @@ module ::JdbcSpec
|
|
313
327
|
#
|
314
328
|
# see: abstract/quoting.rb
|
315
329
|
|
330
|
+
# See ACTIVERECORD_JDBC-33 for details -- better to not quote
|
331
|
+
# table names, esp. if they have schemas.
|
332
|
+
def quote_table_name(name) #:nodoc:
|
333
|
+
name.to_s
|
334
|
+
end
|
335
|
+
|
316
336
|
# Camelcase column names need to be quoted.
|
317
337
|
# Nonquoted identifiers can contain only alphanumeric characters from your
|
318
338
|
# database character set and the underscore (_), dollar sign ($), and pound sign (#).
|
@@ -335,7 +355,7 @@ module ::JdbcSpec
|
|
335
355
|
%Q{empty_#{ column.sql_type.downcase rescue 'blob' }()}
|
336
356
|
end
|
337
357
|
else
|
338
|
-
if column.respond_to?(:primary) && column.primary
|
358
|
+
if column.respond_to?(:primary) && column.primary && column.klass != String
|
339
359
|
return value.to_i.to_s
|
340
360
|
end
|
341
361
|
quoted = super
|
@@ -347,7 +367,7 @@ module ::JdbcSpec
|
|
347
367
|
end
|
348
368
|
|
349
369
|
def quoted_date(value)
|
350
|
-
%Q{TIMESTAMP'#{
|
370
|
+
%Q{TIMESTAMP'#{super}'}
|
351
371
|
end
|
352
372
|
|
353
373
|
def quoted_true #:nodoc:
|
data/lib/jdbc_adapter/version.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
**** BEGIN LICENSE BLOCK *****
|
3
|
-
* Copyright (c) 2006-
|
3
|
+
* Copyright (c) 2006-2010 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
|
*
|
@@ -117,7 +117,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
117
117
|
throws SQLException, IOException {
|
118
118
|
return (IRubyObject) withConnectionAndRetry(context, new SQLBlock() {
|
119
119
|
public Object call(Connection c) throws SQLException {
|
120
|
-
ResultSet results = null;
|
120
|
+
ResultSet results = null, pkeys = null;
|
121
121
|
try {
|
122
122
|
String table_name = rubyApi.convertToRubyString(args[0]).getUnicodeValue();
|
123
123
|
String schemaName = null;
|
@@ -143,9 +143,11 @@ public class RubyJdbcConnection extends RubyObject {
|
|
143
143
|
}
|
144
144
|
|
145
145
|
results = metadata.getColumns(c.getCatalog(),schemaName,table_name,null);
|
146
|
-
|
146
|
+
pkeys = metadata.getPrimaryKeys(c.getCatalog(),schemaName,table_name);
|
147
|
+
return unmarshal_columns(context, metadata, results, pkeys);
|
147
148
|
} finally {
|
148
149
|
close(results);
|
150
|
+
close(pkeys);
|
149
151
|
}
|
150
152
|
}
|
151
153
|
});
|
@@ -991,22 +993,28 @@ public class RubyJdbcConnection extends RubyObject {
|
|
991
993
|
}
|
992
994
|
|
993
995
|
private IRubyObject unmarshal_columns(ThreadContext context, DatabaseMetaData metadata,
|
994
|
-
|
996
|
+
ResultSet rs, ResultSet pkeys) throws SQLException {
|
995
997
|
try {
|
996
998
|
Ruby runtime = context.getRuntime();
|
997
999
|
List columns = new ArrayList();
|
1000
|
+
List pkeyNames = new ArrayList();
|
998
1001
|
String clzName = metadata.getClass().getName().toLowerCase();
|
999
1002
|
boolean isOracle = clzName.indexOf("oracle") != -1 || clzName.indexOf("oci") != -1;
|
1000
1003
|
|
1001
1004
|
RubyHash types = (RubyHash) native_database_types();
|
1002
1005
|
IRubyObject jdbcCol = getConnectionAdapters(runtime).getConstant("JdbcColumn");
|
1003
1006
|
|
1004
|
-
while(
|
1007
|
+
while (pkeys.next()) {
|
1008
|
+
pkeyNames.add(pkeys.getString(COLUMN_NAME));
|
1009
|
+
}
|
1010
|
+
|
1011
|
+
while (rs.next()) {
|
1012
|
+
String colName = rs.getString(COLUMN_NAME);
|
1005
1013
|
IRubyObject column = jdbcCol.callMethod(context, "new",
|
1006
1014
|
new IRubyObject[] {
|
1007
1015
|
getInstanceVariable("@config"),
|
1008
1016
|
RubyString.newUnicodeString(runtime,
|
1009
|
-
caseConvertIdentifierForRails(metadata,
|
1017
|
+
caseConvertIdentifierForRails(metadata, colName)),
|
1010
1018
|
defaultValueFromResultSet(runtime, rs),
|
1011
1019
|
RubyString.newUnicodeString(runtime, typeFromResultSet(rs, isOracle)),
|
1012
1020
|
runtime.newBoolean(!rs.getString(IS_NULLABLE).trim().equals("NO"))
|
@@ -1014,12 +1022,15 @@ public class RubyJdbcConnection extends RubyObject {
|
|
1014
1022
|
columns.add(column);
|
1015
1023
|
|
1016
1024
|
IRubyObject tp = (IRubyObject)types.fastARef(column.callMethod(context,"type"));
|
1017
|
-
if(tp != null && !tp.isNil() && tp.callMethod(context, "[]", runtime.newSymbol("limit")).isNil()) {
|
1025
|
+
if (tp != null && !tp.isNil() && tp.callMethod(context, "[]", runtime.newSymbol("limit")).isNil()) {
|
1018
1026
|
column.callMethod(context, "limit=", runtime.getNil());
|
1019
1027
|
if(!column.callMethod(context, "type").equals(runtime.newSymbol("decimal"))) {
|
1020
1028
|
column.callMethod(context, "precision=", runtime.getNil());
|
1021
1029
|
}
|
1022
1030
|
}
|
1031
|
+
if (pkeyNames.contains(colName)) {
|
1032
|
+
column.callMethod(context, "primary=", runtime.getTrue());
|
1033
|
+
}
|
1023
1034
|
}
|
1024
1035
|
return runtime.newArray(columns);
|
1025
1036
|
} finally {
|
data/test/oracle_simple_test.rb
CHANGED
@@ -6,24 +6,49 @@ class OracleSimpleTest < Test::Unit::TestCase
|
|
6
6
|
end
|
7
7
|
|
8
8
|
class OracleSpecificTest < Test::Unit::TestCase
|
9
|
-
include MultibyteTestMethods
|
9
|
+
include MultibyteTestMethods # so we can get @java_con
|
10
10
|
|
11
11
|
def setup
|
12
12
|
super
|
13
|
-
@java_con.createStatement.execute "CREATE TABLE DEFAULT_NUMBER (VALUE NUMBER)"
|
14
|
-
@java_con.createStatement.execute "INSERT INTO DEFAULT_NUMBER (VALUE) VALUES (0.076)"
|
13
|
+
@java_con.createStatement.execute "CREATE TABLE DEFAULT_NUMBER (VALUE NUMBER, DATUM DATE)"
|
14
|
+
@java_con.createStatement.execute "INSERT INTO DEFAULT_NUMBER (VALUE, DATUM) VALUES (0.076, TIMESTAMP'2009-11-05 00:00:00')"
|
15
|
+
@java_con.createStatement.execute "CREATE SYNONYM POSTS FOR ENTRIES"
|
16
|
+
@klass = Class.new(ActiveRecord::Base)
|
17
|
+
@klass.set_table_name "DEFAULT_NUMBER"
|
15
18
|
end
|
16
19
|
|
17
20
|
def teardown
|
18
21
|
@java_con.createStatement.execute "DROP TABLE DEFAULT_NUMBER"
|
22
|
+
@java_con.createStatement.execute "DROP SYNONYM POSTS"
|
19
23
|
super
|
20
24
|
end
|
21
25
|
|
22
|
-
|
23
26
|
def test_default_number_precision
|
24
|
-
|
25
|
-
klass.set_table_name "DEFAULT_NUMBER"
|
26
|
-
obj = klass.find(:first)
|
27
|
+
obj = @klass.find(:first)
|
27
28
|
assert_equal 0.076, obj.value
|
28
29
|
end
|
30
|
+
|
31
|
+
# JRUBY-3675, ACTIVERECORD_JDBC-22
|
32
|
+
def test_load_date
|
33
|
+
obj = @klass.find(:first)
|
34
|
+
assert_not_nil obj.datum, "no date"
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_load_null_date
|
38
|
+
@java_con.createStatement.execute "UPDATE DEFAULT_NUMBER SET DATUM = NULL"
|
39
|
+
obj = @klass.find(:first)
|
40
|
+
assert obj.datum.nil?
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_model_access_by_synonym
|
44
|
+
@klass.set_table_name "POSTS"
|
45
|
+
entry_columns = Entry.columns_hash
|
46
|
+
@klass.columns.each do |c|
|
47
|
+
ec = entry_columns[c.name]
|
48
|
+
assert ec
|
49
|
+
assert_equal ec.sql_type, c.sql_type
|
50
|
+
assert_equal ec.type, c.type
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
29
54
|
end if defined?(JRUBY_VERSION)
|
data/test/simple.rb
CHANGED
@@ -105,6 +105,20 @@ module SimpleTestMethods
|
|
105
105
|
end
|
106
106
|
|
107
107
|
if Time.respond_to?(:zone)
|
108
|
+
def test_save_time_with_utc
|
109
|
+
current_zone = Time.zone
|
110
|
+
default_zone = ActiveRecord::Base.default_timezone
|
111
|
+
ActiveRecord::Base.default_timezone = Time.zone = :utc
|
112
|
+
now = Time.now
|
113
|
+
my_time = Time.local now.year, now.month, now.day, now.hour, now.min, now.sec
|
114
|
+
m = DbType.create! :sample_datetime => my_time
|
115
|
+
m.reload
|
116
|
+
assert_equal my_time, m.sample_datetime
|
117
|
+
rescue
|
118
|
+
Time.zone = current_zone
|
119
|
+
ActiveRecord::Base.default_timezone = default_zone
|
120
|
+
end
|
121
|
+
|
108
122
|
def test_save_time
|
109
123
|
t = Time.now
|
110
124
|
#precision will only be expected to the second.
|
@@ -156,7 +170,12 @@ module SimpleTestMethods
|
|
156
170
|
e.sample_date = date
|
157
171
|
e.save!
|
158
172
|
e = DbType.find(:first)
|
159
|
-
|
173
|
+
if DbType.columns_hash["sample_date"].type == :datetime
|
174
|
+
# Oracle doesn't distinguish btw date/datetime
|
175
|
+
assert_equal date, e.sample_date.to_date
|
176
|
+
else
|
177
|
+
assert_equal date, e.sample_date
|
178
|
+
end
|
160
179
|
end
|
161
180
|
|
162
181
|
def test_boolean
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 9
|
8
|
-
-
|
9
|
-
version: 0.9.
|
8
|
+
- 6
|
9
|
+
version: 0.9.6
|
10
10
|
platform: java
|
11
11
|
authors:
|
12
12
|
- Nick Sieger, Ola Bini and JRuby contributors
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-05-05 00:00:00 -05:00
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|