tank-sqlite 0.36.0

SQLite driver implementation for Tank: the Rust data layer
Documentation
use libsqlite3_sys::*;
use std::ffi::{CStr, c_int};
use tank_core::{AsValue, Error, Result, Value};

pub(crate) fn extract_value(statement: *mut sqlite3_stmt, index: c_int) -> Result<Value> {
    unsafe {
        let column_type = sqlite3_column_type(statement, index);
        Ok(match column_type {
            SQLITE_NULL => Value::Null,
            SQLITE_INTEGER => sqlite3_column_int64(statement, index).as_value(),
            SQLITE_FLOAT => sqlite3_column_double(statement, index).as_value(),
            SQLITE_BLOB => {
                let ptr = sqlite3_column_blob(statement, index) as *const u8;
                let len = sqlite3_column_bytes(statement, index) as usize;
                Value::Blob(Some((0..len).map(|i| *ptr.add(i)).collect()))
            }
            SQLITE_TEXT => {
                let ptr = sqlite3_column_text(statement, index);
                let len = sqlite3_column_bytes(statement, index) as usize;
                String::from_utf8_unchecked((0..len).map(|i| *ptr.add(i)).collect()).as_value()
            }
            _ => {
                return Err(Error::msg(format!("Unexpected column type {column_type}",)));
            }
        })
    }
}

pub(crate) fn extract_name(statement: *mut sqlite3_stmt, index: c_int) -> Result<String> {
    unsafe {
        Ok(CStr::from_ptr(sqlite3_column_name(statement, index))
            .to_str()?
            .into())
    }
}