use super::error::DbResult;
use super::ffi::{self, RawStmt};
use super::value::Value;
pub enum StepResult<'stmt, 'conn> {
Row(Row<'stmt, 'conn>),
Done,
}
pub struct Row<'stmt, 'conn> {
stmt: &'stmt Statement<'conn>,
}
impl Row<'_, '_> {
#[must_use]
pub fn column_i64(&self, idx: usize) -> i64 {
self.stmt
.raw
.column_i64(i32::try_from(idx).expect("column index overflow"))
}
#[must_use]
pub fn column_blob(&self, idx: usize) -> Vec<u8> {
self.stmt
.raw
.column_blob(i32::try_from(idx).expect("column index overflow"))
}
#[must_use]
pub fn column_text(&self, idx: usize) -> String {
self.stmt
.raw
.column_text(i32::try_from(idx).expect("column index overflow"))
}
#[allow(dead_code)]
#[must_use]
pub fn is_column_null(&self, idx: usize) -> bool {
self.stmt
.raw
.column_type(i32::try_from(idx).expect("column index overflow"))
== ffi::SQLITE_NULL
}
}
pub struct Statement<'conn> {
raw: RawStmt<'conn>,
}
impl<'conn> Statement<'conn> {
pub(super) const fn new(raw: RawStmt<'conn>) -> Self {
Self { raw }
}
pub fn bind_values(&mut self, values: &[Value]) -> DbResult<()> {
for (i, val) in values.iter().enumerate() {
let idx = i32::try_from(i + 1).expect("parameter index overflow");
match val {
Value::Integer(v) => self.raw.bind_i64(idx, *v)?,
Value::Blob(v) => self.raw.bind_blob(idx, v)?,
Value::Text(v) => self.raw.bind_text(idx, v)?,
Value::Null => self.raw.bind_null(idx)?,
}
}
Ok(())
}
pub fn step<'stmt>(&'stmt mut self) -> DbResult<StepResult<'stmt, 'conn>> {
let rc = self.raw.step()?;
if rc == ffi::SQLITE_ROW {
Ok(StepResult::Row(Row { stmt: self }))
} else {
Ok(StepResult::Done)
}
}
}