///|
/// A dynamically typed SQLite value.
///
/// Use `Value` when the SQLite storage class is not known statically or when
/// SQL `NULL` must be preserved. Concrete `bind` and `column` calls remain the
/// simpler choice when the expected MoonBit type is already known.
pub(all) enum Value {
Null
Integer(Int64)
Real(Double)
Text(String)
Blob(Bytes)
} derive(Debug, Eq)
///|
const SQLITE_INTEGER = 1
///|
const SQLITE_FLOAT = 2
///|
const SQLITE_TEXT = 3
///|
const SQLITE_BLOB = 4
///|
const SQLITE_NULL = 5
///|
pub impl Bind for Value with fn bind(stmt, param_index, value) {
let handle = stmt.get_handle()
let rescode = match value {
Null => @ffi.sqlite3_bind_null(handle, param_index)
Integer(value) => @ffi.sqlite3_bind_int64(handle, param_index, value)
Real(value) => @ffi.sqlite3_bind_double(handle, param_index, value)
Text(value) => @ffi.sqlite3_bind_text(handle, param_index, value[:])
Blob(value) => @ffi.sqlite3_bind_blob(handle, param_index, value[:])
}
if rescode != SQLITE_OK {
raise stmt.error(rescode)
}
}
///|
pub impl Column for Value with fn column(stmt, index) {
let (handle, storage_class) = stmt.column_info(index)
match storage_class {
SQLITE_INTEGER => Integer(@ffi.sqlite3_column_int64(handle, index))
SQLITE_FLOAT => Real(@ffi.sqlite3_column_double(handle, index))
SQLITE_TEXT => Text(stmt.column(index~))
SQLITE_BLOB => Blob(stmt.column(index~))
SQLITE_NULL => Null
_ => abort("sqlite3: SQLite returned an invalid column type")
}
}