Permalink
Browse files

Enable almost full support for MySQL using JDBC

As much as it pained me, I did the necessary work splitting the MySQL
adapter into shared and native parts, and adding the necessary JDBC
support.  There are still three spec failures, one in the integration
specs and two in the MySQL specific specs.  One notable feature not
working is that MySQL via JDBC does not support the
convert_tinyint_to_boolean option.  I don't plan to improve the
MySQL JDBC situation further, but I'll accept patches to do so.

Now that the PostgreSQL, SQLite, and MySQL adapters have been split,
I don't plan to add support for other JDBC adapters.  It should be
fairly easy to add support for the remaining adapters using JDBC,
since all of the remaining adapters are fairly small.  If you get
another adapter working with JDBC, be sure to send a patch/pull
request.

There were a few related changes made to enable this that are worth
mentioning.  First is that JDBC::Database got a default transaction
method, which hopefully should work on most databases (it appears
to work with both SQLite and MySQL).  Second is that
Dataset#multi_insert now uses execute_dui instead of execute.
  • Loading branch information...
1 parent abd1251 commit 33d3cf1e9fd16b3710a08e9c6072d72ce61fa465 @jeremyevans committed Jul 25, 2008
View
@@ -1,5 +1,7 @@
=== HEAD
+* Enable almost full support for MySQL using JDBC (jeremyevans)
+
* Fix ODBC adapter's conversion of ::ODBC::Time values (Michael Xavier)
* Enable full support for SQLite-JDBC using the JDBC adapter (jeremyevans)
@@ -11,6 +11,8 @@ module JavaSQL; include_package 'java.sql'; end
org.postgresql.Driver
end,
:mysql=>proc do |db|
+ require 'sequel_core/adapters/jdbc/mysql'
+ db.extend(Sequel::JDBC::MySQL::DatabaseMethods)
JDBC.load_gem('mysql')
com.mysql.jdbc.Driver
end,
@@ -104,6 +106,31 @@ def setup_connection(conn)
conn
end
+ def transaction
+ @pool.hold do |conn|
+ @transactions ||= []
+ return yield(conn) if @transactions.include?(Thread.current)
+ stmt = conn.createStatement
+ begin
+ log_info(Sequel::Database::SQL_BEGIN)
+ stmt.execute(Sequel::Database::SQL_BEGIN)
+ @transactions << Thread.current
+ yield(conn)
+ rescue Exception => e
+ log_info(Sequel::Database::SQL_ROLLBACK)
+ stmt.execute(Sequel::Database::SQL_ROLLBACK)
+ raise e unless Error::Rollback === e
+ ensure
+ unless e
+ log_info(Sequel::Database::SQL_COMMIT)
+ stmt.execute(Sequel::Database::SQL_COMMIT)
+ end
+ stmt.close
+ @transactions.delete(Thread.current)
+ end
+ end
+ end
+
def uri
ur = @opts[:uri] || @opts[:url] || @opts[:database]
ur =~ /^\Ajdbc:/ ? ur : "jdbc:#{ur}"
@@ -0,0 +1,55 @@
+require 'sequel_core/adapters/shared/mysql'
+
+module Sequel
+ module JDBC
+ module MySQL
+ module DatabaseMethods
+ include Sequel::MySQL::DatabaseMethods
+
+ def dataset(opts=nil)
+ Sequel::JDBC::MySQL::Dataset.new(self, opts)
+ end
+
+ def execute_insert(sql)
+ begin
+ log_info(sql)
+ @pool.hold do |conn|
+ stmt = conn.createStatement
+ begin
+ stmt.executeUpdate(sql)
+ rs = stmt.executeQuery('SELECT LAST_INSERT_ID()')
+ rs.next
+ rs.getInt(1)
+ rescue NativeException, JavaSQL::SQLException => e
+ raise Error, e.message
+ ensure
+ stmt.close
+ end
+ end
+ rescue NativeException, JavaSQL::SQLException => e
+ raise Error, "#{sql}\r\n#{e.message}"
+ end
+ end
+
+ private
+
+ def database_name
+ u = URI.parse(uri.sub(/\Ajdbc:/, ''))
+ (m = /\/(.*)/.match(u.path)) && m[1]
+ end
+ end
+
+ class Dataset < JDBC::Dataset
+ include Sequel::MySQL::DatasetMethods
+
+ def insert(*values)
+ @db.execute_insert(insert_sql(*values))
+ end
+
+ def replace(*args)
+ @db.execute_insert(replace_sql(*args))
+ end
+ end
+ end
+ end
+end
@@ -31,31 +31,6 @@ def execute_insert(sql)
end
end
- def transaction
- @pool.hold do |conn|
- @transactions ||= []
- return yield(conn) if @transactions.include?(Thread.current)
- stmt = conn.createStatement
- begin
- log_info(Sequel::Database::SQL_BEGIN)
- stmt.execute(Sequel::Database::SQL_BEGIN)
- @transactions << Thread.current
- yield(conn)
- rescue Exception => e
- log_info(Sequel::Database::SQL_ROLLBACK)
- stmt.execute(Sequel::Database::SQL_ROLLBACK)
- raise e unless Error::Rollback === e
- ensure
- unless e
- log_info(Sequel::Database::SQL_COMMIT)
- stmt.execute(Sequel::Database::SQL_COMMIT)
- end
- stmt.close
- @transactions.delete(Thread.current)
- end
- end
- end
-
private
def connection_pool_default_options
Oops, something went wrong. Retry.

0 comments on commit 33d3cf1

Please sign in to comment.