I am using Rust's rusqlite crate to insert and recall data from a sqlite database.
I am using the get() method for its Row that returns a Result<T>. I have this current code snippet:
while let Some(row) = rows.next()? {
let value = match row.get(0).expect("Could not get value from database cell.") {
// Do something here to specify types and return them or add them to a separate collection
};
}
How could I specify the type? Currently the only way I can properly unwrap the get function is by assigning it to a variable with a specific type already, like let value: i64 = row.get(0).unwrap(), but I don't know how to differentiate if the get(0) was actually a string or a boolean or any other acceptable SQL type.
I've searched through other examples of match with Result, but their match enums are based off values, not types.
How could I specify the type? Currently the only way I can properly unwrap the get function is by assigning it to a variable with a specific type already, like
let value: i64 = row.get(0).unwrap()
If I understand what you want correctly, you're looking for get_raw and get_raw_checked which return a ValueRef enum this way you can check at runtime what type the retrieved value was:
while let Some(row) = rows.next()? {
let value = match row.get_raw(0) {
ValueRef::Null => ...
ValueRef::Integer(i) => ...
ValueRef::Real(f) => ...
ValueRef::Text(t) => ...
ValueRef::Blob(b) => ...
}
}
get indicates an expectation and returns an Err if the expectation is betrayed, because usually you know what the type of the value stored in the column should be, and if someone went under you and replaced the column or value's type, then everything is broken. It also conveniently handles various conversions so you don't have to handle them by hand.
Incidentally if you don't want to handle the possible error from get you can just use its sibling get_unwrap.
The T on your Result<T> is coming from the table scheme, so T's type will be already determined by the database, not by Rust.
Usually a good practice is to create a struct that maps your SQL table like in the example on the documentation.
SQLite side
CREATE TABLE person (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
time_created TEXT NOT NULL,
data BLOB
)
Rust side
#[derive(Debug)]
struct Person {
id: i32,
name: String,
time_created: Timespec,
data: Option<Vec<u8>>,
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With