lib/baza/driver/mysql.rb
class Baza::Driver::Mysql < Baza::MysqlBaseDriver
AutoAutoloader.autoload_sub_classes(self, __FILE__)
attr_reader :conn
def self.from_object(args)
raise "Mysql does not support auth extraction" if args[:object].class.name == "Mysql"
end
def initialize(db)
super
@opts = @db.opts
require "monitor"
@mutex = Monitor.new
if db.opts[:conn]
@conn = db.opts[:conn]
else
if @opts[:encoding]
@encoding = @opts[:encoding]
else
@encoding = "utf8"
end
if @db.opts.key?(:port)
@port = @db.opts[:port].to_i
else
@port = 3306
end
reconnect
end
end
# Cleans the wref-map holding the tables.
def clean
tables.clean if tables
end
# Respawns the connection to the MySQL-database.
def reconnect
@mutex.synchronize do
require "mysql" unless ::Object.const_defined?(:Mysql)
@conn = ::Mysql.real_connect(@db.opts[:host], @db.opts[:user], @db.opts[:pass], @db.opts[:db], @port)
query("SET NAMES '#{esc(@encoding)}'") if @encoding
end
end
# Executes a query and returns the result.
def query(str)
str = str.to_s
str = str.force_encoding("UTF-8") if @encoding == "utf8" && str.respond_to?(:force_encoding)
tries = 0
begin
tries += 1
@mutex.synchronize do
return Baza::Driver::Mysql::Result.new(self, @conn.query(str))
end
rescue => e
if tries <= 3
if e.message == "MySQL server has gone away" || e.message == "closed MySQL connection" || e.message == "Can't connect to local MySQL server through socket"
sleep 0.5
reconnect
retry
elsif e.message.include?("No operations allowed after connection closed") || e.message == "This connection is still waiting for a result, try again once you have the result" || e.message == "Lock wait timeout exceeded; try restarting transaction"
reconnect
retry
end
end
raise e
end
end
# Executes an unbuffered query and returns the result that can be used to access the data.
def query_ubuf(str)
@mutex.synchronize do
@conn.query_with_result = false
return Baza::Driver::Mysql::UnbufferedResult.new(@conn, @opts, @conn.query(str))
end
end
# Escapes a string to be safe to use in a query.
def escape_alternative(string)
@conn.escape_string(string.to_s)
end
# Closes the connection threadsafe.
def close
@mutex.synchronize { @conn.close }
end
# Destroyes the connection.
def destroy
@conn = nil
@db = nil
@mutex = nil
@subtype = nil
@encoding = nil
@query_args = nil
@port = nil
end
def supports_multiple_databases?
true
end
end