You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
docuseal/vendor/bundle/ruby/4.0.0/gems/trilogy-2.12.2/lib/trilogy.rb

132 lines
3.6 KiB

# frozen_string_literal: true
require "socket"
require "trilogy/version"
require "trilogy/error"
require "trilogy/result"
require "trilogy/cext"
require "trilogy/encoding"
class Trilogy
IO_TIMEOUT_ERROR =
if defined?(IO::TimeoutError)
IO::TimeoutError
else
Class.new(StandardError)
end
private_constant :IO_TIMEOUT_ERROR
module Synchronization
def initialize(...)
@mutex = Mutex.new
super
end
synchronized_methods = Trilogy.public_instance_methods(false) - %i(closed?)
source = synchronized_methods.flat_map do |method|
[
"def #{method}(...)",
"raise SynchronizationError unless @mutex.try_lock",
"begin",
"super",
"ensure",
"@mutex.unlock",
"end",
"end",
]
end
class_eval(source.join(";"), __FILE__, __LINE__)
end
prepend(Synchronization)
def initialize(options = {})
options[:port] = options[:port].to_i if options[:port]
mysql_encoding = options[:encoding] || "utf8mb4"
encoding = Trilogy::Encoding.find(mysql_encoding)
charset = Trilogy::Encoding.charset(mysql_encoding)
@connection_options = options
@connected_host = nil
socket = nil
begin
if host = options[:host]
port = options[:port] || 3306
connect_timeout = options[:connect_timeout] || options[:write_timeout]
socket = TCPSocket.new(host, port, connect_timeout: connect_timeout)
socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
if keepalive_enabled = options[:keepalive_enabled]
keepalive_idle = options[:keepalive_idle]
keepalive_interval = options[:keepalive_interval]
keepalive_count = options[:keepalive_count]
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
if keepalive_idle > 0 && defined?(Socket::TCP_KEEPIDLE)
socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPIDLE, keepalive_idle)
end
if keepalive_interval > 0 && defined?(Socket::TCP_KEEPINTVL)
socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPINTVL, keepalive_interval)
end
if keepalive_count > 0 && defined?(Socket::TCP_KEEPCNT)
socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPCNT, keepalive_count)
end
end
else
path = options[:socket] ||= "/tmp/mysql.sock"
socket = UNIXSocket.new(path)
end
rescue Errno::ETIMEDOUT, IO_TIMEOUT_ERROR => e
raise Trilogy::TimeoutError, e.message
rescue SocketError => e
connection_str = host ? "#{host}:#{port}" : path
raise Trilogy::BaseConnectionError, "unable to connect to \"#{connection_str}\": #{e.message}"
rescue => e
if e.respond_to?(:errno)
raise Trilogy::SyscallError.from_errno(e.errno, e.message)
else
raise
end
end
_connect(socket, encoding, charset, options)
ensure
# Socket's fd will be dup'd in C
socket&.close
end
def connection_options
@connection_options.dup.freeze
end
def in_transaction?
(server_status & SERVER_STATUS_IN_TRANS) != 0
end
def server_info
version_str = server_version
if /\A(\d+)\.(\d+)\.(\d+)/ =~ version_str
version_num = ($1.to_i * 10000) + ($2.to_i * 100) + $3.to_i
end
{ :version => version_str, :id => version_num }
end
def connected_host
@connected_host ||= query_with_flags("select @@hostname", query_flags | QUERY_FLAGS_FLATTEN_ROWS).rows.first
end
def query_with_flags(sql, flags)
old_flags = query_flags
self.query_flags = flags
query(sql)
ensure
self.query_flags = old_flags
end
end