dbd-jdbc 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/README.txt CHANGED
@@ -1,33 +1,85 @@
1
1
  RECENT CHANGES
2
2
  ==============
3
- The dbd-jdbc project has recently moved to Kenai and can be found at the following url (http://kenai.com/projects/dbd-jdbc). Please report any bugs found to the issue tracker listed on the Kenai project page.
3
+ The dbd-jdbc project has recently moved to Kenai and can be found at the following url
4
+ (http://kenai.com/projects/dbd-jdbc). Please report any bugs found to the issue
5
+ tracker listed on the Kenai project page.
4
6
 
5
7
  OVERVIEW
6
8
  ========
7
- The Jdbc driver for DBI runs only under JRuby, using JRuby's Java integration to act as a thin wrapper around JDBC Connections obtained through DriverManager. Theoretically this driver can support any database that has JDBC support, although the behavior of certain aspects of the DBI API will differ slightly based on the implementation of the JDBC driver and the underlying database (see LIMITATIONS)
9
+ The Jdbc driver for DBI runs only under JRuby, using JRuby's Java integration to act
10
+ as a thin wrapper around JDBC Connections obtained through DriverManager.
11
+ Theoretically this driver can support any database that has JDBC support, although the
12
+ behavior of certain aspects of the DBI API will differ slightly based on the
13
+ implementation of the JDBC driver and the underlying database (see LIMITATIONS)
8
14
 
9
15
  INSTALLATION
10
16
  ============
11
- Besides the ruby files being installed with DBI (in DBD/Jdbc), the JDBC driver classes must be added to the JRuby classpath. One way to do this on UNIX machines is to place a JDBC driver jarfile in JRUBY_HOME/lib. Another way is to set the CLASSPATH environment variable. The jruby (or jruby.bat) script can also be modified to add to the classpath. In the future there may be more dynamic ways to add jarfiles to the classpath as well; check with the JRuby documentation.
17
+ Besides the ruby files being installed with DBI (in DBD/Jdbc), the JDBC driver classes
18
+ must be added to the JRuby classpath. One way to do this on UNIX machines is to
19
+ place a JDBC driver jarfile in JRUBY_HOME/lib. Another way is to set the CLASSPATH
20
+ environment variable. The jruby (or jruby.bat) script can also be modified to add to
21
+ the classpath. In the future there may be more dynamic ways to add jarfiles to the
22
+ classpath as well; check with the JRuby documentation.
12
23
 
13
24
  USAGE
14
25
  =====
15
- This driver is used like any standard DBI driver, by requiring 'dbi' and obtaining a connection through the DBI.connect method. The DSN for the database should be "dbi:" followed by the standard Java database URL (jdbc:<subprotocol>:<subname>). In addition, the attributes hash passed to the connect method must contain the key/value pair "driver" => <jdbc driver class name>. For example (MySQL):
26
+ This driver is used like any standard DBI driver, by requiring 'dbi' and obtaining a
27
+ connection through the DBI.connect method. The DSN for the database should be "dbi:"
28
+ followed by the standard Java database URL (jdbc:<subprotocol>:<subname>). In
29
+ addition, the attributes hash passed to the connect method must contain the key/value
30
+ pair "driver" => <jdbc driver class name>. For example (MySQL):
16
31
 
17
- dbh = DBI.connect('dbi:jdbc:mysql://localhost:3306/test', 'anonymous', '', { "driver" => "com.mysql.jdbc.Driver" } )
32
+ dbh = DBI.connect('dbi:jdbc:mysql://localhost:3306/test', 'anonymous', '',
33
+ { "driver" => "com.mysql.jdbc.Driver" } )
18
34
 
19
35
  SUPPORTED ATTRIBUTES
20
36
  ====================
21
- Besides the mandatory "driver" attribute that must be passed in the DBI connect method, there are additional attributes that can be passed to modify the behavior of the driver. In addition to setting these attributes during the connect call, they can be set on a driver handle using []= (e.g. dbh["autocommit"] = true). The currently supported attributes are:
22
- 1) autocommit: sets the autoCommit status of the underlying JDBC Connection (there is a 1-1 relationship between a DBI Database instance and a JDBC Connection)
23
- 2) nulltype: sets the java.sql.Types constant to use when binding nil to a Statement. See LIMITATIONS
37
+ Besides the mandatory "driver" attribute that must be passed in the DBI connect method,
38
+ there are additional attributes that can be passed to modify the behavior of the
39
+ driver. In addition to setting these attributes during the connect call, they can be
40
+ set on a driver handle using []= (e.g. dbh["autocommit"] = true). The currently
41
+ supported attributes are:
42
+
43
+ 1) autocommit: sets the autoCommit status of the underlying JDBC Connection
44
+ (there is a 1-1 relationship between a DBI Database instance and a JDBC Connection)
45
+ 2) nulltype: sets the java.sql.Types constant to use when binding nil to a Statement.
46
+ See LIMITATIONS
24
47
 
25
48
  LIMITATIONS
26
49
  ===========
27
- There are limitations to the JDBC driver that are largely based on incompatibilities between the DBI and JDBC APIs, and the differences in underlying JDBC driver implementations.
50
+ There are limitations to the JDBC driver that are largely based on incompatibilities
51
+ between the DBI and JDBC APIs, and the differences in underlying JDBC driver
52
+ implementations.
28
53
 
29
- 1) Binding nil to statements is somewhat unreliable due to the fact that JDBC requires type information in PreparedStatement.setNull(int), but there is no type information associated with nil in ruby. E.g., statements like DBI.select_all("select * from a, b, c where col1=? and col2=?", "a", nil) might run into problems. One workaround is to hardcode NULL in the sql statement. If executing multiple inserts and some values might be nil, the driver will call setNull with the type specified in the driver attribute "nulltype". If the default fails with a given driver, try specifying different nulltypes such as "dbh['nulltype'] = java.sql.Types::NULL" or "dbh['nulltype'] = java.sql.Types::OTHER" to see if it will work.
54
+ 1) Binding nil to statements is somewhat unreliable due to the fact that JDBC requires
55
+ type information in PreparedStatement.setNull(int), but there is no type information
56
+ associated with nil in ruby. E.g., statements like DBI.select_all("select * from a, b,
57
+ c where col1=? and col2=?", "a", nil) might run into problems. One workaround is to
58
+ hardcode NULL in the sql statement. If executing multiple inserts and some values
59
+ might be nil, the driver will call setNull with the type specified in the driver
60
+ attribute "nulltype". If the default fails with a given driver, try specifying
61
+ different nulltypes such as "dbh['nulltype'] = java.sql.Types::NULL" or
62
+ "dbh['nulltype'] = java.sql.Types::OTHER" to see if it will work.
30
63
 
31
- 2) Type conversion in result sets: Java to Ruby type conversion in results of queries is more limited than in JDBC, since DBI returns an entire row at a time, without type information specified (unlike JDBC ResultSet where getInt, getString, etc allow each column to be typed appropriately). The driver attempts to convert each data type, relying mostly on getObject() and the JRuby type conversion system. Due to the fact that JDBC drivers are not constrained to the exact Java types returned for each SQL type, it is possible for some conversion oddities to arise (e.g. returning Java BigDecimal which isn't converted by JRuby, leading to a Java BigDecimal rather than Ruby Fixnum/BigDecimal).
64
+ 2) Type conversion in result sets: Java to Ruby type conversion in results of queries
65
+ is more limited than in JDBC, since DBI returns an entire row at a time, without type
66
+ information specified (unlike JDBC ResultSet where getInt, getString, etc allow each
67
+ column to be typed appropriately). The driver attempts to convert each data type,
68
+ relying mostly on getObject() and the JRuby type conversion system. Due to the fact
69
+ that JDBC drivers are not constrained to the exact Java types returned for each SQL
70
+ type, it is possible for some conversion oddities to arise (e.g. returning Java
71
+ BigDecimal which isn't converted by JRuby, leading to a Java BigDecimal rather than
72
+ Ruby Fixnum/BigDecimal).
32
73
 
33
- 3) Type conversion in prepared statements: In addition to not being able to use type data when returning data, it isn't possible to specify type data directly when binding parameters either (when binding multiple parameters, DBI has ability to set type data, and when calling bind_param, this driver does not currently support type data in the attributes). Most conversions should work without problem, but there is ambiguity in the Ruby Float type since it can be treated as float or double (or BigDecimal) in Java (and FLOAT, DOUBLE, REAL, NUMERIC, DECIMAL, etc in java.sql.Types). setDouble() is used to try to retain the highest precision, but some problems have been seen (e.g. Sybase REAL works better with setFloat()). When doing inserts or retrieval, be sure that the driver keeps the desired precision (the only workaround is to change the database column type to something that works better for doubles with the given JDBC driver and database)
74
+ 3) Type conversion in prepared statements: In addition to not being able to use type
75
+ data when returning data, it isn't possible to specify type data directly when binding
76
+ parameters either (when binding multiple parameters, DBI has ability to set type data,
77
+ and when calling bind_param, this driver does not currently support type data in the
78
+ attributes). Most conversions should work without problem, but there is ambiguity in
79
+ the Ruby Float type since it can be treated as float or double (or BigDecimal) in Java
80
+ (and FLOAT, DOUBLE, REAL, NUMERIC, DECIMAL, etc in java.sql.Types). setDouble() is
81
+ used to try to retain the highest precision, but some problems have been seen (e.g.
82
+ Sybase REAL works better with setFloat()). When doing inserts or retrieval, be sure
83
+ that the driver keeps the desired precision (the only workaround is to change the
84
+ database column type to something that works better for doubles with the given JDBC
85
+ driver and database)
data/Rakefile CHANGED
@@ -28,11 +28,12 @@ Rake::Task['manifest'].invoke # Always regen manifest, so Hoe has up-to-date lis
28
28
 
29
29
  begin
30
30
  require 'hoe'
31
- Hoe.new("dbd-jdbc", "0.0.4") do |p|
31
+ Hoe.new("dbd-jdbc", "0.0.5") do |p|
32
32
  p.rubyforge_name = "jruby-extras"
33
33
  p.url = "http://kenai.com/projects/dbd-jdbc"
34
34
  p.author = "Chad Johnson"
35
35
  p.email = "chad.j.johnson@gmail.com"
36
+ p.description = "A JDBC DBD driver for Ruby DBI"
36
37
  p.summary = "JDBC driver for DBI, originally by Kristopher Schmidt and Ola Bini"
37
38
  end.spec.dependencies.delete_if { |dep| dep.name == "hoe" }
38
39
  rescue LoadError
@@ -27,16 +27,54 @@
27
27
  # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
28
 
29
29
  require 'java'
30
- require File.dirname(__FILE__) + '/JdbcTypeConversions'
30
+
31
+ begin
32
+ require 'rubygems'
33
+ gem 'dbi'
34
+ rescue LoadError => e
35
+ end
36
+
37
+ require 'dbi'
31
38
 
32
39
  module DBI
33
40
  module DBD
41
+ #
42
+ # DBD::Jdbc - Database Driver for Java / JDBC
43
+ #
44
+ # Requires DBI and JRuby
45
+ #
34
46
  module Jdbc
35
-
36
47
  include_class 'java.sql.Connection'
37
48
  include_class 'java.sql.ResultSet'
49
+ include_class 'java.util.HashMap'
50
+ include_class 'java.util.Collections'
51
+
52
+ VERSION = "0.0.5"
53
+ DESCRIPTION = "JDBC DBD driver for JRuby"
38
54
 
39
- VERSION = "0.0.4"
55
+ #
56
+ # Transaction isolation levels copied from JDBC
57
+ #
58
+ TRANSACTION_NONE = Connection::TRANSACTION_NONE
59
+ TRANSACTION_READ_COMMITTED = Connection::TRANSACTION_READ_COMMITTED
60
+ TRANSACTION_READ_UNCOMMITTED = Connection::TRANSACTION_READ_UNCOMMITTED
61
+ TRANSACTION_REPEATABLE_READ = Connection::TRANSACTION_REPEATABLE_READ
62
+ TRANSACTION_SERIALIZABLE = Connection::TRANSACTION_SERIALIZABLE
63
+ # Convience isolation levels
64
+ NONE = Connection::TRANSACTION_NONE
65
+ READ_COMMITTED = Connection::TRANSACTION_READ_COMMITTED
66
+ READ_UNCOMMITTED = Connection::TRANSACTION_READ_UNCOMMITTED
67
+ REPEATABLE_READ = Connection::TRANSACTION_REPEATABLE_READ
68
+ SERIALIZABLE = Connection::TRANSACTION_SERIALIZABLE
69
+
70
+ #
71
+ # returns 'Jdbc'
72
+ #
73
+ # See DBI::TypeUtil#convert for more information.
74
+ #
75
+ def self.driver_name
76
+ "Jdbc"
77
+ end
40
78
 
41
79
  module Type
42
80
  class Timestamp < DBI::Type::Null
@@ -56,369 +94,20 @@ module DBI
56
94
  end
57
95
  end
58
96
  end
59
-
60
- def self.driver_name
61
- "Jdbc"
62
- end
63
-
97
+
64
98
  #
65
99
  # Bound values pass through this function before being handed to Statement.bind_param
66
- #
100
+ #
67
101
  # The false value prevents the default type conversion from occurring
68
102
  #
69
103
  DBI::TypeUtil.register_conversion(driver_name) do |obj|
70
104
  [obj, false]
71
105
  end
72
-
73
- class Driver < DBI::BaseDriver
74
-
75
- def initialize
76
- super("0.4.0")
77
- #attributes specific to this class. All attributes in the
78
- #connect attributes that aren't in this list will be
79
- #applied to the database handle
80
- @driverAttributes = [ "driver" ]
81
- end
82
-
83
- # Stolen from AR-JDBC
84
- def driver_class(name)
85
- return @driver_class if @driver_class
86
-
87
- driver_class_const = (name[0...1].capitalize + name[1..name.length]).gsub(/\./, '_')
88
- driver_class_name = name
89
- Driver.module_eval do
90
- include_class(driver_class_name) { driver_class_const }
91
- end
92
- driver_class = Driver.const_get(driver_class_const)
93
- raise "You specify a driver for your JDBC connection" unless driver_class
94
- @driver_class = driver_class
95
- end
96
-
97
- def load(name)
98
- java.sql.DriverManager.registerDriver(driver_class(name).new)
99
- end
100
-
101
- def connect(dbname, user, auth, attr)
102
- driverClass = attr["driver"]
103
- raise InterfaceError.new('driver class name must be specified as "driver" in connection attributes') unless driverClass
104
- load(driverClass)
105
- connection = java.sql.DriverManager.getConnection("jdbc:"+dbname, user, auth)
106
- dbh = Database.new(connection)
107
- (attr.keys - @driverAttributes).each { |key| dbh[key] = attr[key] }
108
- return dbh
109
- rescue NativeException => error
110
- raise DBI::DatabaseError.new(error.message)
111
- end
112
-
113
- end #Driver
114
-
115
- class Database < DBI::BaseDatabase
116
-
117
- include JdbcTypeConversions
118
-
119
- def initialize(connection)
120
- @connection = connection
121
- @attributes = {
122
- #works with Sybase and Mysql.
123
- "nulltype" => java.sql.Types::VARCHAR,
124
- "allow_scroll" => false
125
- }
126
- end
127
-
128
- def disconnect
129
- @connection.rollback unless self["autocommit"]
130
- @connection.close
131
- rescue NativeException => error
132
- raise DBI::DatabaseError.new(error.message)
133
- end
134
-
135
- def prepare(sql)
136
- if self["allow_scroll"]
137
- return Statement.new(@connection.prepareStatement(sql,ResultSet::TYPE_SCROLL_INSENSITIVE, ResultSet::CONCUR_READ_ONLY), self["nulltype"], self["allow_scroll"])
138
- else
139
- return Statement.new(@connection.prepareStatement(sql), self["nulltype"], self["allow_scroll"])
140
- end
141
- rescue NativeException => error
142
- raise DBI::DatabaseError.new(error.message)
143
- end
144
-
145
- def do(statement, *bindvars)
146
- res = nil
147
- if bindvars.nil? || bindvars.empty?
148
- stmt = @connection.createStatement()
149
- begin
150
- stmt.execute(statement)
151
- ensure
152
- stmt.close rescue NativeException
153
- end
154
- else
155
- stmt = execute(statement, *bindvars)
156
- res = stmt.rows
157
- stmt.finish
158
- end
159
- return res
160
- rescue NativeException => error
161
- raise DBI::DatabaseError.new(error.message)
162
- end
163
-
164
- def ping
165
- return !@connection.isClosed
166
- rescue NativeException => error
167
- raise DBI::DatabaseError.new(error.message)
168
- end
169
-
170
- def commit
171
- @connection.commit()
172
- rescue NativeException => error
173
- raise DBI::DatabaseError.new(error.message)
174
- end
175
-
176
- def rollback
177
- @connection.rollback()
178
- rescue NativeException => error
179
- raise DBI::DatabaseError.new(error.message)
180
- end
181
-
182
- def tables
183
- rs = @connection.getMetaData.getTables(nil, nil, nil, nil)
184
- tables = []
185
- while(rs.next())
186
- tables << rs.getString(3)
187
- end
188
- return tables
189
- rescue NativeException => error
190
- raise DBI::DatabaseError.new(error.message)
191
- end
192
-
193
- def columns(table)
194
- metaData = @connection.getMetaData()
195
- rs = metaData.getColumns(nil, nil, table, nil)
196
- columns = []
197
- while(rs.next())
198
- type_name, dbi_type = jdbc_to_dbi_sqltype(rs.getShort(5))
199
- columns << {
200
- "name" => rs.getString(4),
201
- "sql_type" => type_name,
202
- "type_name" => rs.getString(6),
203
- "precision" => rs.getInt(7),
204
- "scale" => rs.getInt(9),
205
- "default" => rs.getString(13),
206
- "nullable" => (rs.getInt(11) == 1)
207
- }
208
- columns[-1]["dbi_type"] = dbi_type if dbi_type
209
- end
210
- return columns
211
- rescue NativeException => error
212
- raise DBI::DatabaseError.new(error.message)
213
- end
214
-
215
- def [](attribute)
216
- attribute = attribute.downcase
217
- check_attribute(attribute)
218
- case attribute
219
- when "autocommit" then @connection.getAutoCommit()
220
- else
221
- @attributes[attribute]
222
- end
223
- rescue NativeException => error
224
- raise DBI::DatabaseError.new(error.message)
225
- end
226
-
227
- def []=(attribute, value)
228
- attribute = attribute.downcase
229
- check_attribute(attribute)
230
- case attribute
231
- when "autocommit" then @connection.setAutoCommit(value)
232
- else
233
- @attributes[attribute] = value
234
- end
235
- rescue NativeException => error
236
- raise DBI::DatabaseError.new(error.message)
237
- end
238
-
239
- def __get_java_connection
240
- return @connection
241
- end
242
-
243
- def self.from_java_connection(java_connection, type_coercion = false)
244
- DBI::DatabaseHandle.new(Database.new(java_connection), type_coercion)
245
- end
246
-
247
- private
248
-
249
- def check_attribute(attribute)
250
- raise DBI::NotSupportedError.new("Database attribute #{attribute} is not supported") unless (attribute == "autocommit" || @attributes.has_key?(attribute))
251
- end
252
-
253
- end
254
-
255
- class Statement < DBI::BaseStatement
256
-
257
- include JdbcTypeConversions
258
-
259
- def initialize(statement, nulltype, allow_scroll = false)
260
- @statement = statement
261
- @nulltype = nulltype
262
- @allow_scroll = allow_scroll
263
- @rows = nil
264
- @data = []
265
- end
266
-
267
- def bind_param(param, value, attribs)
268
- raise InterfaceError.new("Statement.bind_param only supports numeric placeholder numbers") unless param.is_a?(Fixnum)
269
- if value.nil?
270
- @statement.setNull(param, @nulltype)
271
- elsif value.is_a?(String)
272
- @statement.setString(param, value)
273
- elsif value.is_a?(Fixnum)
274
- #no reason not to coerce it to a long?
275
- @statement.setLong(param, value)
276
- elsif value.is_a?(Float)
277
- #despite DBD spec saying Float->SQL Float, using Double gives
278
- #better precision and passes tests that setFloat does not.
279
- @statement.setDouble(param, value)
280
- elsif value.is_a?(::DateTime) || value.is_a?(DBI::Timestamp)
281
- @statement.setTimestamp(param, timestamp_to_jdbctimestamp(value))
282
- elsif value.is_a?(::Date) || value.is_a?(DBI::Date)
283
- @statement.setDate(param, date_to_jdbcdate(value))
284
- elsif value.is_a?(::Time) || value.is_a?(DBI::Time)
285
- @statement.setTime(param, time_to_jdbctime(value))
286
- else
287
- @statement.setObject(param, value)
288
- end
289
- rescue NativeException => error
290
- raise DBI::DatabaseError.new(error.message)
291
- end
292
-
293
- def execute
294
- if @statement.execute()
295
- @rs = @statement.getResultSet
296
- @rows = nil
297
- @data.clear
298
- else
299
- @rs = nil
300
- @rows = @statement.getUpdateCount
301
- end
302
- rescue NativeException => error
303
- raise DBI::DatabaseError.new(error.message)
304
- end
305
-
306
- def finish
307
- @statement.close()
308
- @rs = nil
309
- @rows = nil
310
- rescue NativeException => error
311
- raise DBI::DatabaseError.new(error.message)
312
- end
313
-
314
- def fetch
315
- if (@rs && @rs.next())
316
- return fill_data
317
- else
318
- return nil
319
- end
320
- rescue NativeException => error
321
- raise DBI::DatabaseError.new(error.message)
322
- end
323
-
324
- def fill_data
325
- @data.clear
326
- metaData = @rs.getMetaData()
327
- (1..metaData.getColumnCount()).each do |columnNumber|
328
- @data << get_value(columnNumber, @rs, metaData)
329
- end
330
- return @data
331
- end
332
-
333
- #
334
- # Unless "allow_scroll" was set on this connection this will default to the
335
- # DBI::BaseStatement#fetch_scroll implementation.
336
- #
337
- # See DBI::BaseStatement#fetch_scroll. These additional constants are supported
338
- # when "allow_scroll" is set on the connection.
339
- #
340
- # * DBI::SQL_FETCH_PRIOR: Fetch the row previous to the current one.
341
- # * DBI::SQL_FETCH_FIRST: Fetch the first row.
342
- # * DBI::SQL_FETCH_ABSOLUTE: Fetch the row at the offset provided.
343
- # * DBI::SQL_FETCH_RELATIVE: Fetch the row at the current point + offset.
344
- #
345
- def fetch_scroll(direction, offset)
346
- return super(direction, offset) unless @allow_scroll
347
-
348
- case direction
349
- when DBI::SQL_FETCH_NEXT
350
- fill_data if @rs && @rs.next()
351
- when DBI::SQL_FETCH_PRIOR
352
- fill_data if @rs && @rs.previous()
353
- when DBI::SQL_FETCH_FIRST
354
- fill_data if @rs && @rs.first()
355
- when DBI::SQL_FETCH_LAST
356
- fill_data if @rs && @rs.last()
357
- when DBI::SQL_FETCH_ABSOLUTE
358
- fill_data if @rs && @rs.absolute(offset)
359
- when DBI::SQL_FETCH_RELATIVE
360
- fill_data if @rs && @rs.relative(offset)
361
- else
362
- raise DBI::NotSupportedError
363
- end
364
- rescue NativeException => error
365
- raise DBI::NotSupportedError.new(error.message)
366
- end
367
-
368
- def column_info
369
- info = Array.new
370
- return info unless @rs
371
- metaData = @rs.getMetaData()
372
- (1..metaData.getColumnCount()).each do |columnNumber|
373
- type_name, dbi_type = jdbc_to_dbi_sqltype(metaData.getColumnType(columnNumber))
374
- info << {
375
- "name" => metaData.getColumnName(columnNumber),
376
- "sql_type" => type_name,
377
- "type_name" => metaData.getColumnTypeName(columnNumber),
378
- "precision" => metaData.getPrecision(columnNumber),
379
- "scale" => metaData.getScale(columnNumber),
380
- "nullable" => (metaData.isNullable(columnNumber) == 1)
381
- }
382
- info[-1]["dbi_type"] = dbi_type if dbi_type
383
- end
384
- return info
385
- rescue NativeException => error
386
- raise DBI::DatabaseError.new(error.message)
387
- end
388
-
389
- def rows
390
- return @rows
391
- end
392
-
393
- def self.from_java_statement(java_statement, type_coercion = false, null_type = java.sql.Types::VARCHAR)
394
- raise DBI::DatabaseError.new("Only java.sql.PreparedStatement instances accepted") unless java_statement.kind_of?(java.sql.PreparedStatement)
395
-
396
- DBI::StatementHandle.new(Statement.new(java_statement, null_type), true, true, type_coercion)
397
- end
398
-
399
- private
400
-
401
- def get_value(columnNumber, rs, metaData)
402
- #note only map things that seem unlikely to coerce properly to jruby,
403
- #since anything mapped as primitive type cannot be returned as null
404
- return case metaData.getColumnType(columnNumber)
405
- when java.sql.Types::BIT
406
- rs.getBoolean(columnNumber)
407
- when java.sql.Types::NUMERIC, java.sql.Types::DECIMAL
408
- metaData.getScale(columnNumber) == 0 ? rs.getLong(columnNumber) : rs.getDouble(columnNumber)
409
- when java.sql.Types::DATE
410
- jdbcdate_to_date(rs.getDate(columnNumber))
411
- when java.sql.Types::TIME
412
- jdbctime_to_time(rs.getTime(columnNumber))
413
- when java.sql.Types::TIMESTAMP
414
- jdbctimestamp_to_timestamp(rs.getTimestamp(columnNumber))
415
- else
416
- rs.getObject(columnNumber)
417
- end
418
- end
419
-
420
- end # class Statement
421
-
422
- end # module Jdbc
423
- end # module DBD
424
- end # module DBI
106
+ end
107
+ end
108
+ end
109
+
110
+ require 'dbd/jdbc/type_conversion'
111
+ require 'dbd/jdbc/driver'
112
+ require 'dbd/jdbc/database'
113
+ require 'dbd/jdbc/statement'
@@ -0,0 +1,178 @@
1
+ # (C) 2009 Chad Johnson <chad.j.johnson@gmail.com>.
2
+ # (C) 2008 Ola Bini <ola.bini@gmail.com>.
3
+ # (C) 2006 Kristopher Schmidt <krisschmidt@optonline.net>.
4
+ #
5
+ # All rights reserved.
6
+ #
7
+ # Redistribution and use in source and binary forms, with or without
8
+ # modification, are permitted provided that the following conditions
9
+ # are met:
10
+ # 1. Redistributions of source code must retain the above copyright
11
+ # notice, this list of conditions and the following disclaimer.
12
+ # 2. Redistributions in binary form must reproduce the above copyright
13
+ # notice, this list of conditions and the following disclaimer in the
14
+ # documentation and/or other materials provided with the distribution.
15
+ # 3. The name of the author may not be used to endorse or promote products
16
+ # derived from this software without specific prior written permission.
17
+ #
18
+ # THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
19
+ # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20
+ # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21
+ # THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
+ # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24
+ # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
+ # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26
+ # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27
+ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+
29
+ module DBI::DBD::Jdbc
30
+ #
31
+ # Models the DBI::BaseDatabase API to create DBI::DatabaseHandle objects.
32
+ #
33
+ class Database < DBI::BaseDatabase
34
+ include TypeConversions
35
+
36
+ def initialize(connection)
37
+ @connection = connection
38
+ @attributes = {
39
+ #works with Sybase and Mysql.
40
+ "nulltype" => java.sql.Types::VARCHAR,
41
+ "allow_scroll" => false
42
+ }
43
+ end
44
+
45
+ def disconnect
46
+ @connection.rollback unless self["autocommit"]
47
+ @connection.close
48
+ rescue NativeException => error
49
+ raise DBI::DatabaseError.new(error.message)
50
+ end
51
+
52
+ def prepare(sql)
53
+ if self["allow_scroll"]
54
+ return Statement.new(@connection.prepareStatement(sql,ResultSet::TYPE_SCROLL_INSENSITIVE, ResultSet::CONCUR_READ_ONLY), self["nulltype"], self["allow_scroll"])
55
+ else
56
+ return Statement.new(@connection.prepareStatement(sql), self["nulltype"], self["allow_scroll"])
57
+ end
58
+ rescue NativeException => error
59
+ raise DBI::DatabaseError.new(error.message)
60
+ end
61
+
62
+ def do(statement, *bindvars)
63
+ res = nil
64
+ if bindvars.nil? || bindvars.empty?
65
+ stmt = @connection.createStatement()
66
+ begin
67
+ stmt.execute(statement)
68
+ ensure
69
+ stmt.close rescue NativeException
70
+ end
71
+ else
72
+ stmt = execute(statement, *bindvars)
73
+ res = stmt.rows
74
+ stmt.finish
75
+ end
76
+ return res
77
+ rescue NativeException => error
78
+ raise DBI::DatabaseError.new(error.message)
79
+ end
80
+
81
+ def ping
82
+ return !@connection.isClosed
83
+ rescue NativeException => error
84
+ raise DBI::DatabaseError.new(error.message)
85
+ end
86
+
87
+ def commit
88
+ @connection.commit()
89
+ rescue NativeException => error
90
+ raise DBI::DatabaseError.new(error.message)
91
+ end
92
+
93
+ def rollback
94
+ @connection.rollback()
95
+ rescue NativeException => error
96
+ raise DBI::DatabaseError.new(error.message)
97
+ end
98
+
99
+ def tables
100
+ rs = @connection.getMetaData.getTables(nil, nil, nil, nil)
101
+ tables = []
102
+ while(rs.next())
103
+ tables << rs.getString(3)
104
+ end
105
+ return tables
106
+ rescue NativeException => error
107
+ raise DBI::DatabaseError.new(error.message)
108
+ end
109
+
110
+ def columns(table)
111
+ (table,schema,db) = table.split(".").reverse
112
+
113
+ metaData = @connection.getMetaData()
114
+ rs = metaData.getColumns(db, schema, table, nil)
115
+ columns = []
116
+ while(rs.next())
117
+ type_name, dbi_type = jdbc_to_dbi_sqltype(rs.getShort(5))
118
+ columns << {
119
+ "name" => rs.getString(4),
120
+ "sql_type" => type_name,
121
+ "type_name" => rs.getString(6),
122
+ "precision" => rs.getInt(7),
123
+ "scale" => rs.getInt(9),
124
+ "default" => rs.getString(13),
125
+ "nullable" => (rs.getInt(11) == 1)
126
+ }
127
+ columns[-1]["dbi_type"] = dbi_type if dbi_type
128
+ end
129
+ return columns
130
+ rescue NativeException => error
131
+ raise DBI::DatabaseError.new(error.message)
132
+ end
133
+
134
+ def [](attribute)
135
+ attribute = attribute.downcase
136
+ check_attribute(attribute)
137
+ case attribute
138
+ when "autocommit" then @connection.getAutoCommit()
139
+ when "isolation" || "isolation_level" then @connection.getTransactionIsolation()
140
+ else
141
+ @attributes[attribute]
142
+ end
143
+ rescue NativeException => error
144
+ raise DBI::DatabaseError.new(error.message)
145
+ end
146
+
147
+ def []=(attribute, value)
148
+ attribute = attribute.downcase
149
+ check_attribute(attribute)
150
+ case attribute
151
+ when "autocommit" then @connection.setAutoCommit(value)
152
+ when "isolation" || "isolation_level" then @connection.setTransactionIsolation(value)
153
+ else
154
+ @attributes[attribute] = value
155
+ end
156
+ rescue NativeException => error
157
+ raise DBI::DatabaseError.new(error.message)
158
+ end
159
+
160
+ def java_connection
161
+ return @connection
162
+ end
163
+
164
+ def self.from_java_connection(java_connection, type_coercion = false)
165
+ DBI::DatabaseHandle.new(Database.new(java_connection), type_coercion)
166
+ end
167
+
168
+ private
169
+
170
+ def check_attribute(attribute)
171
+ raise DBI::NotSupportedError.new("Database attribute #{attribute} is not supported") unless (attribute == "autocommit" ||
172
+ attribute == "isolation" ||
173
+ attribute == "isolation_level" ||
174
+ @attributes.has_key?(attribute))
175
+ end
176
+
177
+ end
178
+ end # module DBI
@@ -0,0 +1,70 @@
1
+ # (C) 2009 Chad Johnson <chad.j.johnson@gmail.com>.
2
+ # (C) 2008 Ola Bini <ola.bini@gmail.com>.
3
+ # (C) 2006 Kristopher Schmidt <krisschmidt@optonline.net>.
4
+ #
5
+ # All rights reserved.
6
+ #
7
+ # Redistribution and use in source and binary forms, with or without
8
+ # modification, are permitted provided that the following conditions
9
+ # are met:
10
+ # 1. Redistributions of source code must retain the above copyright
11
+ # notice, this list of conditions and the following disclaimer.
12
+ # 2. Redistributions in binary form must reproduce the above copyright
13
+ # notice, this list of conditions and the following disclaimer in the
14
+ # documentation and/or other materials provided with the distribution.
15
+ # 3. The name of the author may not be used to endorse or promote products
16
+ # derived from this software without specific prior written permission.
17
+ #
18
+ # THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
19
+ # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20
+ # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21
+ # THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
+ # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24
+ # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
+ # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26
+ # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27
+ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+
29
+ module DBI::DBD::Jdbc
30
+ #
31
+ # Models the DBI::BaseDriver API to create DBI::DriverHandle objects.
32
+ #
33
+ class Driver < DBI::BaseDriver
34
+
35
+ def initialize
36
+ super("0.4.0")
37
+ #attributes specific to this class. All attributes in the
38
+ #connect attributes that aren't in this list will be
39
+ #applied to the database handle
40
+ @driverAttributes = [ "driver" ]
41
+ @loaded_drivers = Collections.synchronizedMap(HashMap.new)
42
+ end
43
+
44
+ def load(name)
45
+ unless @loaded_drivers.containsKey(name)
46
+ clazz = java.lang.Class.forName(name,true,JRuby.runtime.jruby_class_loader)
47
+ java.sql.DriverManager.registerDriver(clazz.newInstance)
48
+
49
+ @loaded_drivers.put(name,true)
50
+ end
51
+ end
52
+
53
+ def connect(dbname, user, auth, attr)
54
+ driverClass = attr["driver"]
55
+ raise InterfaceError.new('driver class name must be specified as "driver" in connection attributes') unless driverClass
56
+
57
+ load(driverClass)
58
+
59
+ connection = java.sql.DriverManager.getConnection("jdbc:"+dbname, user, auth)
60
+ dbh = Database.new(connection)
61
+
62
+ (attr.keys - @driverAttributes).each { |key| dbh[key] = attr[key] }
63
+
64
+ return dbh
65
+ rescue NativeException => error
66
+ raise DBI::DatabaseError.new(error.message)
67
+ end
68
+
69
+ end #Driver
70
+ end
@@ -0,0 +1,199 @@
1
+ # (C) 2009 Chad Johnson <chad.j.johnson@gmail.com>.
2
+ # (C) 2008 Ola Bini <ola.bini@gmail.com>.
3
+ # (C) 2006 Kristopher Schmidt <krisschmidt@optonline.net>.
4
+ #
5
+ # All rights reserved.
6
+ #
7
+ # Redistribution and use in source and binary forms, with or without
8
+ # modification, are permitted provided that the following conditions
9
+ # are met:
10
+ # 1. Redistributions of source code must retain the above copyright
11
+ # notice, this list of conditions and the following disclaimer.
12
+ # 2. Redistributions in binary form must reproduce the above copyright
13
+ # notice, this list of conditions and the following disclaimer in the
14
+ # documentation and/or other materials provided with the distribution.
15
+ # 3. The name of the author may not be used to endorse or promote products
16
+ # derived from this software without specific prior written permission.
17
+ #
18
+ # THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
19
+ # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20
+ # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21
+ # THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
+ # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24
+ # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
+ # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26
+ # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27
+ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+
29
+ module DBI::DBD::Jdbc
30
+ #
31
+ # Models the DBI::BaseStatement API to create DBI::StatementHandle objects.
32
+ #
33
+ class Statement < DBI::BaseStatement
34
+ include TypeConversions
35
+
36
+ def initialize(statement, nulltype, allow_scroll = false)
37
+ @statement = statement
38
+ @nulltype = nulltype
39
+ @allow_scroll = allow_scroll
40
+ @rows = nil
41
+ @data = []
42
+ end
43
+
44
+ def bind_param(param, value, attribs)
45
+ raise InterfaceError.new("Statement.bind_param only supports numeric placeholder numbers") unless param.is_a?(Fixnum)
46
+ if value.nil?
47
+ @statement.setNull(param, @nulltype)
48
+ elsif value.is_a?(String)
49
+ @statement.setString(param, value)
50
+ elsif value.is_a?(Fixnum)
51
+ #no reason not to coerce it to a long?
52
+ @statement.setLong(param, value)
53
+ elsif value.is_a?(Float)
54
+ #despite DBD spec saying Float->SQL Float, using Double gives
55
+ #better precision and passes tests that setFloat does not.
56
+ @statement.setDouble(param, value)
57
+ elsif value.is_a?(::DateTime) || value.is_a?(DBI::Timestamp)
58
+ @statement.setTimestamp(param, timestamp_to_jdbctimestamp(value))
59
+ elsif value.is_a?(::Date) || value.is_a?(DBI::Date)
60
+ @statement.setDate(param, date_to_jdbcdate(value))
61
+ elsif value.is_a?(::Time) || value.is_a?(DBI::Time)
62
+ @statement.setTime(param, time_to_jdbctime(value))
63
+ else
64
+ @statement.setObject(param, value)
65
+ end
66
+ rescue NativeException => error
67
+ raise DBI::DatabaseError.new(error.message)
68
+ end
69
+
70
+ def execute
71
+ if @statement.execute()
72
+ @rs = @statement.getResultSet
73
+ @rows = nil
74
+ @data.clear
75
+ else
76
+ @rs = nil
77
+ @rows = @statement.getUpdateCount
78
+ end
79
+ rescue NativeException => error
80
+ raise DBI::DatabaseError.new(error.message)
81
+ end
82
+
83
+ def finish
84
+ @statement.close()
85
+ @rs = nil
86
+ @rows = nil
87
+ rescue NativeException => error
88
+ raise DBI::DatabaseError.new(error.message)
89
+ end
90
+
91
+ def fetch
92
+ if (@rs && @rs.next())
93
+ return fill_data
94
+ else
95
+ return nil
96
+ end
97
+ rescue NativeException => error
98
+ raise DBI::DatabaseError.new(error.message)
99
+ end
100
+
101
+ def fill_data
102
+ @data.clear
103
+ metaData = @rs.getMetaData()
104
+ (1..metaData.getColumnCount()).each do |columnNumber|
105
+ @data << get_value(columnNumber, @rs, metaData)
106
+ end
107
+ return @data
108
+ end
109
+
110
+ #
111
+ # Unless "allow_scroll" was set on this connection this will default to the
112
+ # DBI::BaseStatement#fetch_scroll implementation.
113
+ #
114
+ # See DBI::BaseStatement#fetch_scroll. These additional constants are supported
115
+ # when "allow_scroll" is set on the connection.
116
+ #
117
+ # * DBI::SQL_FETCH_PRIOR: Fetch the row previous to the current one.
118
+ # * DBI::SQL_FETCH_FIRST: Fetch the first row.
119
+ # * DBI::SQL_FETCH_ABSOLUTE: Fetch the row at the offset provided.
120
+ # * DBI::SQL_FETCH_RELATIVE: Fetch the row at the current point + offset.
121
+ #
122
+ def fetch_scroll(direction, offset)
123
+ return super(direction, offset) unless @allow_scroll
124
+
125
+ case direction
126
+ when DBI::SQL_FETCH_NEXT
127
+ fill_data if @rs && @rs.next()
128
+ when DBI::SQL_FETCH_PRIOR
129
+ fill_data if @rs && @rs.previous()
130
+ when DBI::SQL_FETCH_FIRST
131
+ fill_data if @rs && @rs.first()
132
+ when DBI::SQL_FETCH_LAST
133
+ fill_data if @rs && @rs.last()
134
+ when DBI::SQL_FETCH_ABSOLUTE
135
+ fill_data if @rs && @rs.absolute(offset)
136
+ when DBI::SQL_FETCH_RELATIVE
137
+ fill_data if @rs && @rs.relative(offset)
138
+ else
139
+ raise DBI::NotSupportedError
140
+ end
141
+ rescue NativeException => error
142
+ raise DBI::NotSupportedError.new(error.message)
143
+ end
144
+
145
+ def column_info
146
+ info = Array.new
147
+ return info unless @rs
148
+ metaData = @rs.getMetaData()
149
+ (1..metaData.getColumnCount()).each do |columnNumber|
150
+ type_name, dbi_type = jdbc_to_dbi_sqltype(metaData.getColumnType(columnNumber))
151
+ info << {
152
+ "name" => metaData.getColumnName(columnNumber),
153
+ "sql_type" => type_name,
154
+ "type_name" => metaData.getColumnTypeName(columnNumber),
155
+ "precision" => metaData.getPrecision(columnNumber),
156
+ "scale" => metaData.getScale(columnNumber),
157
+ "nullable" => (metaData.isNullable(columnNumber) == 1)
158
+ }
159
+ info[-1]["dbi_type"] = dbi_type if dbi_type
160
+ end
161
+ return info
162
+ rescue NativeException => error
163
+ raise DBI::DatabaseError.new(error.message)
164
+ end
165
+
166
+ def rows
167
+ return @rows
168
+ end
169
+
170
+ def self.from_java_statement(java_statement, type_coercion = false, null_type = java.sql.Types::VARCHAR)
171
+ raise DBI::DatabaseError.new("Only java.sql.PreparedStatement instances accepted") unless java_statement.kind_of?(java.sql.PreparedStatement)
172
+
173
+ DBI::StatementHandle.new(Statement.new(java_statement, null_type), true, true, type_coercion)
174
+ end
175
+
176
+ private
177
+
178
+ def get_value(columnNumber, rs, metaData)
179
+ #note only map things that seem unlikely to coerce properly to jruby,
180
+ #since anything mapped as primitive type cannot be returned as null
181
+ return case metaData.getColumnType(columnNumber)
182
+ when java.sql.Types::BIT
183
+ rs.getBoolean(columnNumber)
184
+ when java.sql.Types::NUMERIC, java.sql.Types::DECIMAL
185
+ metaData.getScale(columnNumber) == 0 ? rs.getLong(columnNumber) : rs.getDouble(columnNumber)
186
+ when java.sql.Types::DATE
187
+ jdbcdate_to_date(rs.getDate(columnNumber))
188
+ when java.sql.Types::TIME
189
+ jdbctime_to_time(rs.getTime(columnNumber))
190
+ when java.sql.Types::TIMESTAMP
191
+ jdbctimestamp_to_timestamp(rs.getTimestamp(columnNumber))
192
+ else
193
+ rs.getObject(columnNumber)
194
+ end
195
+ end
196
+
197
+ end # class Statement
198
+
199
+ end # module Jdbc
@@ -26,32 +26,31 @@
26
26
  # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27
27
  # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
28
 
29
- module JdbcTypeConversions
30
-
29
+ module DBI::DBD::Jdbc::TypeConversions
31
30
  include_class 'java.util.Calendar'
32
31
  include_class 'java.sql.Types'
33
32
 
34
33
  def jdbc_to_dbi_sqltype(jdbctype)
35
34
  return case jdbctype
36
- when Types::BIGINT then [DBI::SQL_BIGINT, nil]
37
- when Types::BINARY then [DBI::SQL_BINARY, nil]
38
- when Types::BIT then [DBI::SQL_BIT, nil]
39
- when Types::CHAR then [DBI::SQL_CHAR, nil]
40
- when Types::DATE then [DBI::SQL_DATE, DBI::DBD::Jdbc::Type::Timestamp]
41
- when Types::DECIMAL then [DBI::SQL_DECIMAL, nil]
42
- when Types::DOUBLE then [DBI::SQL_DOUBLE, nil]
43
- when Types::FLOAT then [DBI::SQL_FLOAT, nil]
44
- when Types::INTEGER then [DBI::SQL_INTEGER, nil]
45
- when Types::LONGVARBINARY then [DBI::SQL_LONGVARBINARY, nil]
46
- when Types::LONGVARCHAR then [DBI::SQL_LONGVARCHAR, nil]
47
- when Types::NUMERIC then [DBI::SQL_NUMERIC, nil]
48
- when Types::REAL then [DBI::SQL_REAL, nil]
49
- when Types::SMALLINT then [DBI::SQL_SMALLINT, nil]
50
- when Types::TIME then [DBI::SQL_TIME, DBI::DBD::Jdbc::Type::Timestamp]
51
- when Types::TIMESTAMP then [DBI::SQL_TIMESTAMP, DBI::DBD::Jdbc::Type::Timestamp]
52
- when Types::TINYINT then [DBI::SQL_TINYINT, nil]
53
- when Types::VARBINARY then [DBI::SQL_VARBINARY, nil]
54
- when Types::VARCHAR then [DBI::SQL_VARCHAR, nil]
35
+ when Types::BIGINT then [DBI::SQL_BIGINT, nil]
36
+ when Types::BINARY then [DBI::SQL_BINARY, nil]
37
+ when Types::BIT then [DBI::SQL_BIT, nil]
38
+ when Types::CHAR then [DBI::SQL_CHAR, nil]
39
+ when Types::DATE then [DBI::SQL_DATE, DBI::DBD::Jdbc::Type::Timestamp]
40
+ when Types::DECIMAL then [DBI::SQL_DECIMAL, nil]
41
+ when Types::DOUBLE then [DBI::SQL_DOUBLE, nil]
42
+ when Types::FLOAT then [DBI::SQL_FLOAT, nil]
43
+ when Types::INTEGER then [DBI::SQL_INTEGER, nil]
44
+ when Types::LONGVARBINARY then [DBI::SQL_LONGVARBINARY, nil]
45
+ when Types::LONGVARCHAR then [DBI::SQL_LONGVARCHAR, nil]
46
+ when Types::NUMERIC then [DBI::SQL_NUMERIC, nil]
47
+ when Types::REAL then [DBI::SQL_REAL, nil]
48
+ when Types::SMALLINT then [DBI::SQL_SMALLINT, nil]
49
+ when Types::TIME then [DBI::SQL_TIME, DBI::DBD::Jdbc::Type::Timestamp]
50
+ when Types::TIMESTAMP then [DBI::SQL_TIMESTAMP, DBI::DBD::Jdbc::Type::Timestamp]
51
+ when Types::TINYINT then [DBI::SQL_TINYINT, nil]
52
+ when Types::VARBINARY then [DBI::SQL_VARBINARY, nil]
53
+ when Types::VARCHAR then [DBI::SQL_VARCHAR, nil]
55
54
  else
56
55
  [DBI::SQL_OTHER, nil]
57
56
  end
metadata CHANGED
@@ -18,16 +18,21 @@ name: dbd-jdbc
18
18
  rdoc_options:
19
19
  - --main
20
20
  - README.txt
21
- autorequire:
22
21
  rubyforge_project: jruby-extras
22
+ autorequire:
23
+ licenses: []
24
+
23
25
  executables: []
24
26
 
25
- description:
26
- specification_version: 2
27
+ description: A JDBC DBD driver for Ruby DBI
28
+ specification_version: 3
27
29
  default_executable:
28
30
  files:
29
- - lib/dbd/JdbcTypeConversions.rb
30
31
  - lib/dbd/Jdbc.rb
32
+ - lib/dbd/jdbc/database.rb
33
+ - lib/dbd/jdbc/driver.rb
34
+ - lib/dbd/jdbc/statement.rb
35
+ - lib/dbd/jdbc/type_conversion.rb
31
36
  - Rakefile
32
37
  - README.txt
33
38
  required_rubygems_version: !ruby/object:Gem::Requirement
@@ -38,17 +43,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
38
43
  version:
39
44
  extensions: []
40
45
 
41
- rubygems_version: 1.3.1
46
+ rubygems_version: 1.3.2
42
47
  requirements: []
43
48
 
44
49
  authors:
45
50
  - Chad Johnson
46
- date: 2009-03-11 00:00:00 Z
51
+ date: 2009-05-16 05:00:00 +00:00
47
52
  platform: ruby
48
53
  test_files: []
49
54
 
50
55
  version: !ruby/object:Gem::Version
51
- version: 0.0.4
56
+ version: 0.0.5
52
57
  require_paths:
53
58
  - lib
54
59
  dependencies: []