jdbc-helper 0.2.1 → 0.3.0

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.
data/README.rdoc CHANGED
@@ -6,14 +6,14 @@ crucial database operations from primitive selects and updates to more complex o
6
6
  batch updates, prepared statements and transactions.
7
7
  As the name implies, this gem only works on JRuby.
8
8
 
9
- = Examples
9
+ == Examples
10
10
 
11
- == Prerequisites
11
+ === Prerequisites
12
12
  Add JDBC driver of the DBMS you're willing to use to your CLASSPATH
13
13
  export CLASSPATH=$CLASSPATH:~/lib/mysql-connector-java.jar
14
14
 
15
15
 
16
- == Connecting to a database
16
+ === Connecting to a database
17
17
 
18
18
  # :driver and :url must be given
19
19
  conn = JDBCHelper::Connection.new(
@@ -35,7 +35,7 @@ Add JDBC driver of the DBMS you're willing to use to your CLASSPATH
35
35
  conn = JDBCHelper::MySQLConnector.connect('localhost', 'mysql', '', 'test')
36
36
  conn.close
37
37
 
38
- == Querying database table
38
+ === Querying database table
39
39
 
40
40
  conn.query("SELECT a, b, c FROM T") do | row |
41
41
  row.labels
@@ -71,10 +71,10 @@ Add JDBC driver of the DBMS you're willing to use to your CLASSPATH
71
71
  end
72
72
  end
73
73
 
74
- == Updating database table
74
+ === Updating database table
75
75
  del_count = conn.update("DELETE FROM T")
76
76
 
77
- == Transaction
77
+ === Transaction
78
78
  committed = conn.transaction do | tx |
79
79
  # ...
80
80
  # Transaction logic here
@@ -87,13 +87,13 @@ Add JDBC driver of the DBMS you're willing to use to your CLASSPATH
87
87
  end
88
88
  end
89
89
 
90
- == Using batch interface
90
+ === Using batch interface
91
91
  conn.add_batch("DELETE FROM T");
92
92
  conn.execute_batch
93
93
  conn.add_batch("DELETE FROM T");
94
94
  conn.clear_batch
95
95
 
96
- == Using prepared statements
96
+ === Using prepared statements
97
97
  p_sel = conn.prepare("SELECT * FROM T WHERE b = ? and c = ?")
98
98
  p_sel.query(100, 200) do | row |
99
99
  p row
@@ -112,21 +112,82 @@ Add JDBC driver of the DBMS you're willing to use to your CLASSPATH
112
112
  p_upd.execute_batch
113
113
  p_upd.close
114
114
 
115
- == Using table wrappers (since 0.2.0)
115
+ === Using table wrappers (since 0.2.0)
116
116
  # For more complex examples, refer to test/test_object_wrapper.rb
117
117
 
118
- conn.table('test.data').count
119
- conn.table('test.data').empty?
120
- conn.table('test.data').select(:c => 3) do |row|
118
+ table = conn.table('test.data')
119
+ table.count
120
+ table.empty?
121
+ table.select(:c => 3) do |row|
121
122
  puts row.a
122
123
  end
123
- conn.table('test.data').update(:a => 1, :b => 2, :where => { :c => 3 })
124
- conn.table('test.data').insert(:a => 10, :b => 20, :c => 30)
125
- conn.table('test.data').insert_ignore(:a => 10, :b => 20, :c => 30)
126
- conn.table('test.data').replace(:a => 10, :b => 20, :c => 30)
127
- conn.table('test.data').delete(:c => 3)
128
- conn.table('test.data').truncate_table!
129
- conn.table('test.data').drop_table!
124
+ table.update(:a => 1, :b => 2, :where => { :c => 3 })
125
+ table.insert(:a => 10, :b => 20, :c => 30)
126
+ table.insert_ignore(:a => 10, :b => 20, :c => 30)
127
+ table.replace(:a => 10, :b => 20, :c => 30)
128
+ table.delete(:c => 3)
129
+ table.truncate_table!
130
+ table.drop_table!
131
+
132
+ === Using function wrappers (since 0.2.2)
133
+ conn.function(:mod).call 5, 3
134
+ conn.function(:coalesce).call(nil, nil, 'king')
135
+
136
+ === Using procedure wrappers (since 0.3.0)
137
+ # Working with IN/INOUT/OUT parameteres
138
+ # Bind by ordinal number
139
+ conn.procedure(:update_and_fetch_something).call(
140
+ 100, ["value", String], Fixnum)
141
+
142
+ # Bind by parameter name
143
+ conn.procedure(:update_and_fetch_something).call(
144
+ :a => 100, :b => ["value", String], :c => Fixnum)
145
+
146
+ == Notes on vendor-independence
147
+
148
+ jdbc-helper tries to be a vendor-independent library, so that it behaves the same on any RDBMS,
149
+ and that is why it's built on JDBC in the first place which can be used to minimize the amount of vendor-specific code.
150
+ (Ideally, one codebase for all RDBMSs.)
151
+ So far so good, but not great. It has small amount of code that is vendor-specific, non-standard JDBC.
152
+ And it has been confirmed to work the same for both MySQL and Oracle, except for stored procedures.
153
+ MySQL and Oracle implement parameter binding of CallableStatement differently.
154
+ See the following example.
155
+ # Let's say we have a stored procedure named my_procedure
156
+ # which takes 3 parameters, param1, param2, and param3.
157
+
158
+ # Creates a CallableStatemet
159
+ cstmt = conn.prepare_call("{call my_procedure(?, ?, ?)}")
160
+
161
+ cstmt.call(10, "ten", Fixnum)
162
+ # OK for both MySQL and Oracle. Filling paramters sequentially.
163
+
164
+ cstmt.call(:param1 => 10, :param2 => "ten", :param3 => Fixnum)
165
+ # MySQL automatically binds values by the parameter names in the original procedure definition.
166
+ # Oracle fails to do so.
167
+ cstmt.close
168
+
169
+ # For Oracle, if you prepare as follows,
170
+ cstmt = conn.prepare_call("{call my_procedure(:p1, :p2, :p3)}")
171
+
172
+ # Then you can do this.
173
+ cstmt.call(:p1 => 10, :p2 => "ten", :p3 => Fixnum)
174
+ # However, p1, p2, p3 have nothing to do with the original
175
+ # parameter names (param1, param2, param3) in the procedure definition.
176
+ # They're just aliases for ordinal positions.
177
+ # So, it's semantically different from the first example.
178
+
179
+ cstmt.close
180
+
181
+ There's no way to find out the original parameter names and their ordinal positions without looking up the metadata of the database,
182
+ which requires having to write vendor-specific code branches, and that is definitely not desirable.
183
+ ProcedureWrapper prepares call with '?'s as the first example.
184
+ So it would work fine for MySQL, but you can't use it with parameter names on Oracle.
185
+
186
+ # Good for both
187
+ conn.procedure(:my_procedure).call(10, "ten", Fixnum)
188
+
189
+ # Only for MySQL
190
+ conn.procedure(:my_procedure).call(:param1 => 10, :param2 => "ten", :param3 => Fixnum)
130
191
 
131
192
  == Contributing to jdbc-helper
132
193
 
@@ -0,0 +1,75 @@
1
+ # encoding: UTF-8
2
+ # Junegunn Choi (junegunn.c@gmail.com)
3
+
4
+ module JDBCHelper
5
+ class Connection
6
+ # Interface to Java CallableStatment
7
+ class CallableStatement < ParameterizedStatement
8
+ # Array or Hash (for named parameters)
9
+ # - IN parameter: value
10
+ # - OUT parameter: class
11
+ # - INOUT parameter: [value, class]
12
+ # (Although class can be inferred from the value,
13
+ # we still need a way to figure out if it's INOUT parameter)
14
+ def call *params
15
+ check_closed
16
+
17
+ out_params = set_params(params)
18
+ measure_exec(:call) { @java_obj.execute }
19
+
20
+ result = {}
21
+ out_params.each do |idx, jtype|
22
+ getter = JDBCHelper::Connection::GETTER_MAP.fetch(jtype, :get_string)
23
+ value = @java_obj.send(getter, idx.is_a?(Symbol) ? idx.to_s : idx)
24
+ result[idx] = @java_obj.was_null ? nil : value
25
+ end
26
+ result
27
+ end
28
+
29
+ private
30
+ def set_params(params) # :nodoc:
31
+ hash_params =
32
+ if params.first.kind_of? Hash
33
+ raise ArgumentError.new("More than one Hash given") if params.length > 1
34
+ params.first
35
+ else
36
+ params.each_with_index.inject({}) { |hash, pair|
37
+ hash[pair.last + 1] = pair.first
38
+ hash
39
+ }
40
+ end
41
+
42
+ out_params = {}
43
+ hash_params.each do | idx, value |
44
+ # Symbol need to be transformed into string
45
+
46
+ idx_ = idx.is_a?(Symbol) ? idx.to_s : idx
47
+ case value
48
+ # OUT parameter
49
+ when Class
50
+ jtype = JDBCHelper::Connection::RUBY_SQL_TYPE_MAP[value] || java.sql.Types::VARCHAR
51
+ @java_obj.registerOutParameter(idx_, jtype)
52
+ out_params[idx] = jtype
53
+
54
+ # INOUT parameter
55
+ when Array
56
+ set_param(idx_, value.first)
57
+ jtype = JDBCHelper::Connection::RUBY_SQL_TYPE_MAP[value.last] || java.sql.Types::VARCHAR
58
+ @java_obj.registerOutParameter(idx_, jtype)
59
+ out_params[idx] = jtype
60
+
61
+ # IN parameter
62
+ else
63
+ set_param(idx_, value)
64
+ end
65
+ end
66
+ out_params
67
+ end
68
+
69
+ def initialize(*args)
70
+ super(*args)
71
+ end
72
+ end#CallableStatment
73
+ end#Connection
74
+ end#JDBCHelper
75
+
@@ -0,0 +1,64 @@
1
+ # encoding: UTF-8
2
+ # Junegunn Choi (junegunn.c@gmail.com)
3
+
4
+ module JDBCHelper
5
+ class Connection
6
+ # Base class for CallableStatement and PreparedStatment
7
+ # @abstract
8
+ class ParameterizedStatement
9
+ # SQL string
10
+ # @return [String]
11
+ attr_reader :sql
12
+
13
+ # Underlying Java object
14
+ attr_reader :java_obj
15
+
16
+ # @param [JDBCHelper::Connection] conn
17
+ # @param [String] cstmt_str
18
+ def initialize(conn, sql, obj)
19
+ @conn = conn
20
+ @sql = sql
21
+ @java_obj = obj
22
+ end
23
+
24
+ def set_param(idx, param)
25
+ if param.nil?
26
+ @java_obj.set_null idx, java.sql.Types::NULL
27
+ elsif setter = JDBCHelper::Connection::SETTER_MAP[param.class.to_s]
28
+ if setter == :setBinaryStream
29
+ @java_obj.send setter, idx, param.getBinaryStream, param.length
30
+ elsif setter == :setTimestamp && param.is_a?(Time)
31
+ @java_obj.send setter, idx, java.sql.Timestamp.new(param.to_i * 1000)
32
+ else
33
+ @java_obj.send setter, idx, param
34
+ end
35
+ else
36
+ @java_obj.set_string idx, param.to_s
37
+ end
38
+ end
39
+
40
+ # @return [NilClass]
41
+ def close
42
+ @java_obj.close
43
+ @java_obj = nil
44
+ end
45
+
46
+ # @return [Boolean]
47
+ def closed?
48
+ @java_obj.nil?
49
+ end
50
+
51
+ private
52
+ def measure_exec(type, &blk) # :nodoc:
53
+ @conn.send(:measure_exec, type, &blk)
54
+ end
55
+
56
+ def check_closed
57
+ raise RuntimeError.new("Object already closed") if closed?
58
+ end
59
+
60
+ end#ParameterizedStatement
61
+ end#Connection
62
+ end#JDBCHelper
63
+
64
+
@@ -11,20 +11,11 @@ class Connection
11
11
  # pstmt = conn.prepare("SELECT * FROM T WHERE a = ? and b = ?")
12
12
  # rows = pstmt.query(10, 20)
13
13
  # enum = pstmt.enumerate(10, 20)
14
- class PreparedStatement
15
- # SQL string
16
- # @return [String]
17
- attr_reader :sql
18
-
19
- # Returns the encapsulated JDBC PreparedStatement object.
20
- def java_obj
21
- @pstmt
22
- end
23
-
14
+ class PreparedStatement < ParameterizedStatement
24
15
  # Returns the number of parameters required
25
16
  # @return [Fixnum]
26
17
  def parameter_count
27
- @pmd ||= @pstmt.get_parameter_meta_data
18
+ @pmd ||= @java_obj.get_parameter_meta_data
28
19
  @pmd.get_parameter_count
29
20
  end
30
21
 
@@ -33,7 +24,7 @@ class PreparedStatement
33
24
  check_closed
34
25
 
35
26
  set_params(params)
36
- measure_exec(:p_update) { @pstmt.execute_update }
27
+ measure_exec(:p_update) { @java_obj.execute_update }
37
28
  end
38
29
 
39
30
  # @return [Array] Returns an Array if block is not given
@@ -43,7 +34,7 @@ class PreparedStatement
43
34
  set_params(params)
44
35
  # sorry, ignoring privacy
45
36
  @conn.send(:process_and_close_rset,
46
- measure_exec(:p_query) { @pstmt.execute_query }, &blk)
37
+ measure_exec(:p_query) { @java_obj.execute_query }, &blk)
47
38
  end
48
39
 
49
40
  # @return [JDBCHelper::Connection::ResultSetEnumerator]
@@ -53,7 +44,7 @@ class PreparedStatement
53
44
  return query(*params, &blk) if block_given?
54
45
 
55
46
  set_params(params)
56
- ResultSetEnumerator.new(measure_exec(:p_query) { @pstmt.execute_query })
47
+ ResultSetEnumerator.new(measure_exec(:p_query) { @java_obj.execute_query })
57
48
  end
58
49
 
59
50
  # Adds to the batch
@@ -62,14 +53,14 @@ class PreparedStatement
62
53
  check_closed
63
54
 
64
55
  set_params(params)
65
- @pstmt.add_batch
56
+ @java_obj.add_batch
66
57
  end
67
58
  # Executes the batch
68
59
  def execute_batch
69
60
  check_closed
70
61
 
71
62
  measure_exec(:p_execute_batch) {
72
- @pstmt.executeBatch
63
+ @java_obj.executeBatch
73
64
  }
74
65
  end
75
66
  # Clears the batch
@@ -77,7 +68,7 @@ class PreparedStatement
77
68
  def clear_batch
78
69
  check_closed
79
70
 
80
- @pstmt.clear_batch
71
+ @java_obj.clear_batch
81
72
  end
82
73
 
83
74
  # Gives the JDBC driver a hint of the number of rows to fetch from the database by a single interaction.
@@ -86,72 +77,19 @@ class PreparedStatement
86
77
  def set_fetch_size(fsz)
87
78
  check_closed
88
79
 
89
- @pstmt.set_fetch_size fsz
80
+ @java_obj.set_fetch_size fsz
90
81
  end
91
82
 
92
- # Closes the prepared statement
93
- # @return [NilClass]
94
- def close
95
- return if closed?
96
- @pstmt.close
97
- @pstmts.delete @sql
98
- @pstmt = @pstmts = nil
99
- end
100
-
101
- # @return [Boolean]
102
- def closed?
103
- @pstmt.nil?
104
- end
105
83
  private
106
- def initialize(conn, pstmts, sql, pstmt) # :nodoc:
107
- @conn = conn
108
- @pstmts = pstmts
109
- @sql = sql
110
- @pstmt = pstmt
111
- end
112
-
113
84
  def set_params(params) # :nodoc:
114
- idx = 0
115
- params.each do | param |
116
- if param.nil?
117
- @pstmt.set_null(idx += 1, java.sql.Types::NULL)
118
- elsif setter = SETTER_MAP[param.class.to_s]
119
- if setter == :setBinaryStream
120
- @pstmt.send(setter, idx += 1, param.getBinaryStream, param.length)
121
- elsif setter == :setTimestamp && param.is_a?(Time)
122
- @pstmt.send(setter, idx += 1, java.sql.Timestamp.new(param.to_i * 1000))
123
- else
124
- @pstmt.send(setter, idx += 1, param)
125
- end
126
- else
127
- @pstmt.set_string(idx += 1, param.to_s)
128
- end
85
+ params.each_with_index do | param, idx |
86
+ set_param(idx + 1, param)
129
87
  end
130
88
  end
131
89
 
132
- def measure_exec(type, &blk) # :nodoc:
133
- @conn.send(:measure_exec, type, &blk)
134
- end
135
-
136
- def check_closed
137
- raise RuntimeError.new("Prepared statement already closed") if closed?
90
+ def initialize(*args)
91
+ super(*args)
138
92
  end
139
-
140
- SETTER_MAP =
141
- {
142
- 'Java::JavaSql::Date' => :setDate,
143
- 'Java::JavaSql::Time' => :setTime,
144
- 'Java::JavaSql::Timestamp' => :setTimestamp,
145
- 'Time' => :setTimestamp,
146
- 'Java::JavaSql::Blob' => :setBinaryStream,
147
-
148
- # Only available when MySQL JDBC driver is loaded.
149
- # So we use the string representation of the class.
150
- 'Java::ComMysqlJdbc::Blob' => :setBinaryStream
151
-
152
- # FIXME-MORE
153
- } # :nodoc:
154
-
155
93
  end#PreparedStatment
156
94
  end#Connection
157
95
  end#JDBCHelper
@@ -2,9 +2,9 @@
2
2
  # Junegunn Choi (junegunn.c@gmail.com)
3
3
 
4
4
  module JDBCHelper
5
- # Class for enumerating query results
6
- # Automatically closed after used. When not used, you must close it explicitly by calling "close".
7
5
  class Connection
6
+ # Class for enumerating query results.
7
+ # Automatically closed after used. When not used, you must close it explicitly by calling "close".
8
8
  class ResultSetEnumerator
9
9
  include Enumerable
10
10
 
@@ -14,10 +14,24 @@ class ResultSetEnumerator
14
14
  count = -1
15
15
  begin
16
16
  while @rset.next
17
+ idx = 0
18
+ # Oracle returns numbers in NUMERIC type, which can be of any precision.
19
+ # So, we retrieve the numbers in String type not to lose their precision.
20
+ # This can be quite annoying when you're just working with integers,
21
+ # so I tried the following code to automatically convert integer string into integer
22
+ # when it's obvious. However, the performance drop is untolerable.
23
+ # Thus, commented out.
24
+ #
25
+ # if v && @cols_meta[i-1] == java.sql.Types::NUMERIC && v !~ /[\.e]/i
26
+ # v.to_i
27
+ # else
28
+ # v
29
+ # end
17
30
  yield Connection::Row.new(
18
31
  @col_labels,
19
- (1..@num_col).map { | i |
20
- v = @rset.send(GETTER_MAP.fetch(@cols_meta[i-1], :get_string), i)
32
+ @col_labels_d,
33
+ @getters.map { |gt|
34
+ v = @rset.send gt, idx+=1
21
35
  @rset.was_null ? nil : v
22
36
  },
23
37
  count += 1)
@@ -52,48 +66,20 @@ private
52
66
  @rsmd = @rset.get_meta_data
53
67
  @num_col = @rsmd.get_column_count
54
68
  @cols_meta = []
69
+ @getters = []
55
70
  @col_labels = []
71
+ @col_labels_d = []
56
72
  (1..@num_col).each do | i |
57
73
  @cols_meta << @rsmd.get_column_type(i)
74
+ @getters << JDBCHelper::Connection::GETTER_MAP.fetch(@cols_meta.last, :get_string)
75
+
58
76
  @col_labels << @rsmd.get_column_label(i)
77
+ @col_labels_d << @col_labels.last.downcase
78
+
59
79
  end
60
80
 
61
81
  @closed = false
62
82
  end
63
-
64
- GETTER_MAP =
65
- {
66
- java.sql.Types::TINYINT => :get_int,
67
- java.sql.Types::SMALLINT => :get_int,
68
- java.sql.Types::INTEGER => :get_int,
69
- java.sql.Types::BIGINT => :get_long,
70
-
71
- java.sql.Types::CHAR => :get_string,
72
- java.sql.Types::VARCHAR => :get_string,
73
- java.sql.Types::LONGVARCHAR => :get_string,
74
- (java.sql.Types::NCHAR rescue nil) => :get_string,
75
- (java.sql.Types::NVARCHAR rescue nil) => :get_string,
76
- (java.sql.Types::LONGNVARCHAR rescue nil) => :get_blob, # FIXME: MySQL
77
- java.sql.Types::BINARY => :get_string,
78
- java.sql.Types::VARBINARY => :get_string,
79
- java.sql.Types::LONGVARBINARY => :get_blob, # FIXME: MySQL
80
-
81
- java.sql.Types::REAL => :get_double,
82
- java.sql.Types::FLOAT => :get_float,
83
- java.sql.Types::DOUBLE => :get_double,
84
- java.sql.Types::NUMERIC => :get_string, # FIXME
85
- java.sql.Types::DECIMAL => :get_string, # FIXME
86
-
87
- java.sql.Types::DATE => :get_date,
88
- java.sql.Types::TIME => :get_time,
89
- java.sql.Types::TIMESTAMP => :get_timestamp,
90
-
91
- java.sql.Types::BLOB => :get_blob,
92
- java.sql.Types::CLOB => :get_string,
93
- (java.sql.Types::NCLOB rescue nil) => :get_string,
94
-
95
- java.sql.Types::BOOLEAN => :get_boolean
96
- } # :nodoc:
97
83
  end#ResultSetEnumerator
98
84
  end#Connection
99
85
  end#JDBCHelper
@@ -105,9 +105,9 @@ class Row
105
105
  alias :== :eql?
106
106
 
107
107
  private
108
- def initialize(col_labels, values, rownum) # :nodoc:
108
+ def initialize(col_labels, col_labels_d, values, rownum) # :nodoc:
109
109
  @labels = col_labels
110
- @labels_d = col_labels.map { | l | l.downcase }
110
+ @labels_d = col_labels_d
111
111
  @values = values
112
112
  @rownum = rownum
113
113
 
@@ -0,0 +1,72 @@
1
+ # encoding: UTF-8
2
+ # Junegunn Choi (junegunn.c@gmail.com)
3
+
4
+ module JDBCHelper
5
+ class Connection
6
+ RUBY_SQL_TYPE_MAP = {
7
+ Fixnum => java.sql.Types::INTEGER,
8
+ Bignum => java.sql.Types::BIGINT,
9
+ String => java.sql.Types::VARCHAR,
10
+ Float => java.sql.Types::DOUBLE,
11
+ Time => java.sql.Types::TIMESTAMP
12
+ }
13
+
14
+ SETTER_MAP =
15
+ {
16
+ 'String' => :setString,
17
+ 'Fixnum' => :setInt,
18
+ 'Float' => :setDouble,
19
+ # See there's a caveat. Check out ParameterizedStatement#set_param
20
+ 'Time' => :setTimestamp,
21
+
22
+ 'Java::JavaSql::Date' => :setDate,
23
+ 'Java::JavaSql::Time' => :setTime,
24
+ 'Java::JavaSql::Timestamp' => :setTimestamp,
25
+ 'Java::JavaSql::Blob' => :setBinaryStream,
26
+
27
+ #########
28
+ # MySQL #
29
+ #########
30
+ # Only available when MySQL JDBC driver is loaded.
31
+ # So we use the string representation of the class.
32
+ 'Java::ComMysqlJdbc::Blob' => :setBinaryStream
33
+
34
+ # FIXME-MORE
35
+ } # :nodoc:
36
+
37
+ GETTER_MAP =
38
+ {
39
+ java.sql.Types::TINYINT => :getInt,
40
+ java.sql.Types::SMALLINT => :getInt,
41
+ java.sql.Types::INTEGER => :getInt,
42
+ java.sql.Types::BIGINT => :getLong,
43
+
44
+ java.sql.Types::CHAR => :getString,
45
+ java.sql.Types::VARCHAR => :getString,
46
+ java.sql.Types::LONGVARCHAR => :getString,
47
+ (java.sql.Types::NCHAR rescue nil) => :getString,
48
+ (java.sql.Types::NVARCHAR rescue nil) => :getString,
49
+ (java.sql.Types::LONGNVARCHAR rescue nil) => :getBlob, # FIXME: MySQL
50
+ java.sql.Types::BINARY => :getString,
51
+ java.sql.Types::VARBINARY => :getString,
52
+ java.sql.Types::LONGVARBINARY => :getBlob, # FIXME: MySQL
53
+
54
+ java.sql.Types::REAL => :getDouble,
55
+ java.sql.Types::FLOAT => :getFloat,
56
+ java.sql.Types::DOUBLE => :getDouble,
57
+ java.sql.Types::NUMERIC => :getString, # FIXME: get_big_decimal=no inherent jruby support
58
+ java.sql.Types::DECIMAL => :getString, # FIXME: get_big_decimal
59
+
60
+ java.sql.Types::DATE => :getDate,
61
+ java.sql.Types::TIME => :getTime,
62
+ java.sql.Types::TIMESTAMP => :getTimestamp,
63
+
64
+ java.sql.Types::BLOB => :getBlob,
65
+ java.sql.Types::CLOB => :getString,
66
+ (java.sql.Types::NCLOB rescue nil) => :getString,
67
+
68
+ java.sql.Types::BOOLEAN => :getBoolean
69
+ } # :nodoc:
70
+ end#Connection
71
+ end#JDBCHelper
72
+