#![allow(unsafe_code)]
use core::ffi::c_void;
use super::report::report_u64;
use crate::engine::EngineResult;
use crate::panic_guard::FfiBoundary;
use crate::runtime::EngineContext;
fn report_records(num_rows: *mut u64, handled: *mut bool, value: Option<EngineResult<u64>>) -> i32 {
let (code, did_handle) = match value {
None => (0, false),
Some(Ok(rows)) => {
if !num_rows.is_null() {
unsafe { *num_rows = rows };
}
(0, true)
}
Some(Err(e)) => (e.to_mysql_errno(), true),
};
if !handled.is_null() {
unsafe { *handled = did_handle };
}
code
}
#[doc(hidden)]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust__handler__records(
ctx: *mut EngineContext,
num_rows: *mut u64,
handled: *mut bool,
) -> i32 {
FfiBoundary::run_default(0, || {
report_records(
num_rows,
handled,
unsafe { &mut *ctx }.engine_mut().records(),
)
})
}
#[doc(hidden)]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust__handler__records_from_index(
ctx: *mut EngineContext,
index: u32,
num_rows: *mut u64,
handled: *mut bool,
) -> i32 {
FfiBoundary::run_default(0, || {
let value = unsafe { &mut *ctx }.engine_mut().records_from_index(index);
report_records(num_rows, handled, value)
})
}
#[doc(hidden)]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust__handler__estimate_rows_upper_bound(
ctx: *mut EngineContext,
out: *mut u64,
) -> bool {
FfiBoundary::run_default(false, || {
report_u64(
out,
unsafe { &mut *ctx }
.engine_mut()
.estimate_rows_upper_bound(),
)
})
}
#[doc(hidden)]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust__handler__calculate_key_hash_value(
ctx: *mut EngineContext,
field_array: *const c_void,
out: *mut u32,
) -> bool {
FfiBoundary::run_default(false, || {
match unsafe { &mut *ctx }
.engine_mut()
.calculate_key_hash_value(field_array)
{
Some(v) => {
if !out.is_null() {
unsafe { *out = v };
}
true
}
None => false,
}
})
}
#[cfg(test)]
mod tests {
use super::report_records;
use crate::engine::EngineError;
use crate::sys;
#[test]
fn report_records_none_signals_unhandled_with_code_zero() {
let mut num_rows = 7;
let mut handled = true;
let code = report_records(&raw mut num_rows, &raw mut handled, None);
assert_eq!(code, 0);
assert!(!handled);
assert_eq!(num_rows, 7);
}
#[test]
fn report_records_ok_writes_count_and_signals_handled() {
let mut num_rows = 0;
let mut handled = false;
let code = report_records(&raw mut num_rows, &raw mut handled, Some(Ok(42)));
assert_eq!(code, 0);
assert!(handled);
assert_eq!(num_rows, 42);
}
#[test]
fn report_records_err_signals_handled_with_errno() {
let mut num_rows = 5;
let mut handled = false;
let code = report_records(
&raw mut num_rows,
&raw mut handled,
Some(Err(EngineError::Internal)),
);
assert_eq!(code, sys::HA_ERR_INTERNAL_ERROR);
assert!(handled);
assert_eq!(num_rows, 5);
}
#[test]
fn report_records_tolerates_null_out_pointers() {
let code = report_records(core::ptr::null_mut(), core::ptr::null_mut(), Some(Ok(1)));
assert_eq!(code, 0);
}
}