use std::ffi::NulError;
use std::fmt::{Display, Formatter};
use quex_mariadb_sys as ffi;
use super::runtime::{c_error_string, c_opt_string};
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, Clone, Copy, Default)]
pub struct ExecuteResult {
pub rows_affected: u64,
pub last_insert_id: u64,
}
#[derive(Debug, Clone)]
pub struct Error {
code: Option<u32>,
sql_state: Option<String>,
message: String,
}
impl Error {
#[inline]
pub(crate) fn new(message: impl Into<String>) -> Self {
Self {
code: None,
sql_state: None,
message: message.into(),
}
}
pub(super) unsafe fn from_mysql(mysql: *mut ffi::MYSQL, fallback: impl Into<String>) -> Self {
if mysql.is_null() {
return Self::new(fallback);
}
let code = unsafe { ffi::mysql_errno(mysql) };
let message = c_error_string(unsafe { ffi::mysql_error(mysql) }, fallback.into());
let sql_state = c_opt_string(unsafe { ffi::mysql_sqlstate(mysql) });
Self {
code: Some(code),
sql_state,
message,
}
}
pub(super) unsafe fn from_stmt(
stmt: *mut ffi::MYSQL_STMT,
fallback: impl Into<String>,
) -> Self {
if stmt.is_null() {
return Self::new(fallback);
}
let code = unsafe { ffi::mysql_stmt_errno(stmt) };
let message = c_error_string(unsafe { ffi::mysql_stmt_error(stmt) }, fallback.into());
let sql_state = c_opt_string(unsafe { ffi::mysql_stmt_sqlstate(stmt) });
Self {
code: Some(code),
sql_state,
message,
}
}
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match (self.code, &self.sql_state) {
(Some(code), Some(state)) => {
write!(f, "{} (code {}, sqlstate {})", self.message, code, state)
}
_ => f.write_str(&self.message),
}
}
}
impl std::error::Error for Error {}
impl From<std::io::Error> for Error {
fn from(value: std::io::Error) -> Self {
Self::new(value.to_string())
}
}
impl From<NulError> for Error {
fn from(value: NulError) -> Self {
Self::new(value.to_string())
}
}