class Connection
A native FFI connection to the MariaDB/MySQL client library.
Definitions
def self.connect(host: "localhost", username: nil, password: nil, database: nil, port: 0, unix_socket: nil, client_flags: 0, compression: false, types: DEFAULT_TYPES, **options)
Establish a connection to the MariaDB/MySQL server.
Signature
-
parameter
hostString The hostname or IP address to connect to.
-
parameter
usernameString | Nil The username for authentication.
-
parameter
passwordString | Nil The password for authentication.
-
parameter
databaseString | Nil The database name to connect to.
-
parameter
portInteger The port number to connect to.
-
parameter
unix_socketString | Nil The Unix socket path for local connections.
-
parameter
client_flagsInteger Client connection flags.
-
parameter
compressionBoolean Whether to enable connection compression.
-
parameter
typesHash Type mapping configuration.
-
parameter
optionsHash Additional connection options.
-
returns
Connection A new connected instance.
-
raises
Error If the connection fails.
Implementation
def self.connect(host: "localhost", username: nil, password: nil, database: nil, port: 0, unix_socket: nil, client_flags: 0, compression: false, types: DEFAULT_TYPES, **options)
pointer = Native.mysql_init(nil)
Native.mysql_options(pointer, MYSQL_OPT_NONBLOCK, nil)
# if protocol
# Native.mysql_options(pointer, MYSQL_OPT_PROTOCOL, FFI::MemoryPointer.new(:uint, protocol))
# end
client_flags |= CLIENT_MULTI_STATEMENT | CLIENT_MULTI_RESULTS
if compression
client_flags |= CLIENT_COMPRESSION
end
result = FFI::MemoryPointer.new(:pointer)
status = Native.mysql_real_connect_start(result, pointer, host, username, password, database, port, unix_socket, client_flags);
io = ::IO.new(Native.mysql_get_socket(pointer), "r+", autoclose: false)
if status > 0
while status > 0
if status & MYSQL_WAIT_READ
io.wait_readable
elsif status & MYSQL_WAIT_WRITE
io.wait_writable
else
io.wait_any
end
status = Native.mysql_real_connect_cont(result, pointer, status)
end
end
if result.read_pointer.null?
raise Error, "Could not connect: #{Native.mysql_error(pointer)}!"
end
return self.new(pointer, io, types, **options)
end
def initialize(address, io, types, **options)
Initialize a native connection wrapper.
Signature
-
parameter
addressFFI::Pointer The pointer to the native connection.
-
parameter
ioIO The IO object for the socket.
-
parameter
typesHash Type mapping configuration.
-
parameter
optionsHash Additional options.
Implementation
def initialize(address, io, types, **options)
super(address)
@io = io
@result = nil
@types = types
end
attr :types
Signature
-
attribute
Hash The type mapping configuration.
def wait_for(status)
Wait for the specified IO condition.
Signature
-
parameter
statusInteger The status flags indicating which IO condition to wait for.
Implementation
def wait_for(status)
if status & MYSQL_WAIT_READ
@io.wait_readable
elsif status & MYSQL_WAIT_WRITE
@io.wait_writable
end
end
def check_error!(message)
Check for errors and raise an exception if one occurred.
Signature
-
parameter
messageString The error message prefix.
-
raises
Error If an error occurred.
Implementation
def check_error!(message)
if Native.mysql_errno(self) != 0
raise Error, "#{message}: #{Native.mysql_error(self)}!"
end
end
def status
Get the current connection status.
Signature
-
returns
String The status string from the server.
Implementation
def status
Native.mysql_stat(self)
end
def free_result
Free the current result set.
Implementation
def free_result
if @result
Native.mysql_free_result(@result)
@result = nil
end
end
def close
Close the connection and release all resources.
Implementation
def close
self.free_result
Native.mysql_close(self)
@io.close
end
def escape(value)
Escape a string value for safe inclusion in SQL queries.
Signature
-
parameter
valueString The value to escape.
-
returns
String The escaped string.
Implementation
def escape(value)
value = value.to_s
maximum_length = value.bytesize * 2 + 1
out = FFI::MemoryPointer.new(:char, maximum_length)
Native.mysql_real_escape_string(self, out, value, value.bytesize)
return out.read_string
end
def send_query(statement)
Send a query to the server for execution.
Signature
-
parameter
statementString The SQL statement to execute.
-
raises
Error If the query fails.
Implementation
def send_query(statement)
self.free_result
error = FFI::MemoryPointer.new(:int)
status = Native.mysql_real_query_start(error, self, statement, statement.bytesize)
while status != 0
self.wait_for(status)
status = Native.mysql_real_query_cont(error, self, status)
end
if error.read_int != 0
raise Error, "Could not send query: #{Native.mysql_error(self)}!"
end
end
def more_results?
Check if there are more result sets available.
Signature
-
returns
Boolean True if there are more results.
Implementation
def more_results?
Native.mysql_more_results(self) == 1
end
def next_result(types: @types)
Get the next result set from a multi-result query.
Signature
-
parameter
typesHash Type mapping to use for this result.
-
returns
Result | Nil The next result set, or
nilif no more results.
Implementation
def next_result(types: @types)
if result = self.get_result
return Result.new(self, types, result)
end
end
def discard_results
Silently discard any results that the application did not read.
Signature
-
returns
Nil
Implementation
def discard_results
while result = self.get_result
end
return nil
end
def affected_rows
Get the number of rows affected by the last query.
Signature
-
returns
Integer The number of affected rows.
Implementation
def affected_rows
Native.mysql_affected_rows(self)
end
def insert_id
Get the last auto-generated ID from an INSERT query.
Signature
-
returns
Integer The last insert ID.
Implementation
def insert_id
Native.mysql_insert_id(self)
end
def info
Get information about the last query execution.
Signature
-
returns
String | Nil Information string about the query.
Implementation
def info
Native.mysql_info(self)
end