Skip to content

Commit

Permalink
Enable almost full support for MySQL using JDBC
Browse files Browse the repository at this point in the history
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
jeremyevans committed Jul 25, 2008
1 parent abd1251 commit 33d3cf1
Show file tree
Hide file tree
Showing 9 changed files with 402 additions and 312 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG
Original file line number Original file line Diff line number Diff line change
@@ -1,5 +1,7 @@
=== HEAD === HEAD


* Enable almost full support for MySQL using JDBC (jeremyevans)

* Fix ODBC adapter's conversion of ::ODBC::Time values (Michael Xavier) * Fix ODBC adapter's conversion of ::ODBC::Time values (Michael Xavier)


* Enable full support for SQLite-JDBC using the JDBC adapter (jeremyevans) * Enable full support for SQLite-JDBC using the JDBC adapter (jeremyevans)
Expand Down
27 changes: 27 additions & 0 deletions lib/sequel_core/adapters/jdbc.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ module JavaSQL; include_package 'java.sql'; end
org.postgresql.Driver org.postgresql.Driver
end, end,
:mysql=>proc do |db| :mysql=>proc do |db|
require 'sequel_core/adapters/jdbc/mysql'
db.extend(Sequel::JDBC::MySQL::DatabaseMethods)
JDBC.load_gem('mysql') JDBC.load_gem('mysql')
com.mysql.jdbc.Driver com.mysql.jdbc.Driver
end, end,
Expand Down Expand Up @@ -104,6 +106,31 @@ def setup_connection(conn)
conn conn
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

def uri def uri
ur = @opts[:uri] || @opts[:url] || @opts[:database] ur = @opts[:uri] || @opts[:url] || @opts[:database]
ur =~ /^\Ajdbc:/ ? ur : "jdbc:#{ur}" ur =~ /^\Ajdbc:/ ? ur : "jdbc:#{ur}"
Expand Down
55 changes: 55 additions & 0 deletions lib/sequel_core/adapters/jdbc/mysql.rb
Original file line number Original file line Diff line number Diff line change
@@ -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
25 changes: 0 additions & 25 deletions lib/sequel_core/adapters/jdbc/sqlite.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -31,31 +31,6 @@ def execute_insert(sql)
end end
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 private


def connection_pool_default_options def connection_pool_default_options
Expand Down
Loading

0 comments on commit 33d3cf1

Please sign in to comment.