#!/usr/bin/env ruby # # Copyright (c) 2001, 2002 Michael Neumann # # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. The name of the author may not be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL # THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # $Id: proxyserver.rb,v 1.1.1.1 2006/01/04 02:03:08 francis Exp $ # require "drb" require "dbi" module DBI module ProxyServer USED_DBD_API = "0.2" module HelperMixin def catch_exception begin yield rescue Exception => err if err.kind_of? DBI::Error or err.kind_of? DBI::Warning err else DBI::InterfaceError.new("Unexpected Exception was raised in " + "ProxyServer (#{err.inspect})") end end end def define_methods(meths) meths.each {|d| eval %{ def #{d}(*a) catch_exception do @handle.#{d}(*a) end end } } end end # module HelperMixin class ProxyServer include HelperMixin attr_reader :databases def initialize @databases = [] end def get_used_DBD_version USED_DBD_API end def DBD_connect(driver_url, user, auth, attr) catch_exception do ret = DBI._get_full_driver(driver_url) drh = ret[0][1] db_args = ret[1] dbh = drh.connect(db_args, user, auth, attr) DatabaseProxy.new(self, dbh) end end end # class ProxyServer class DatabaseProxy include HelperMixin METHODS = %w(ping commit rollback tables execute do quote [] []= columns) attr_reader :statements def initialize(parent, dbh) @parent = parent @handle = dbh define_methods METHODS @statements = [] # store it otherwise, it'll get recycled @parent.databases << self end def disconnect begin catch_exception do @handle.disconnect @handle = nil end ensure @parent.databases.delete(self) end end def prepare(stmt) catch_exception do sth = @handle.prepare(stmt) StatementProxy.new(self, sth) end end end # class DatabaseProxy class StatementProxy include HelperMixin METHODS = %w(bind_param execute fetch column_info bind_params cancel fetch_scroll fetch_many fetch_all rows) def initialize(parent, sth) @parent = parent @handle = sth define_methods(METHODS) # store it otherwise, it'll get recycled @parent.statements << self end def finish begin catch_exception do @handle.finish @handle = nil end ensure @parent.statements.delete(self) end end end # class StatementProxy end # module ProxyServer end # module DBI if __FILE__ == $0 if DBI::DBD::API_VERSION.split(".")[0].to_i != DBI::DBD::DBI::ProxyServer::USED_DBD_API.split(".")[0].to_i raise "Wrong DBD Version" end HOST = ARGV.shift || 'localhost' PORT = (ARGV.shift || 9001).to_i URL = "druby://#{HOST}:#{PORT}" proxyServer = DBI::ProxyServer::ProxyServer.new DRb.start_service(URL, proxyServer) puts "DBI::ProxyServer started as #{URL} at #{Time.now.to_s}" DRb.thread.join end