Expand description
§Serde Rusqlite
This crate provides convenience functions to bridge serde and rusqlite. With their help
you can “deserialize” rusqlite::Row’s into [serde::Deserialize] types and “serialize” types
implementing [serde::Serialize] into bound query arguments (positional or named) that rusqlite
expects.
Serialization of named bound arguments is only supported from structs and maps because other
serde types lack column name information. Likewise, serialization of positional bound arguments
is only supported from tuples, sequences and primitive non-iterable types. In the latter case
the result will be a single-element vector. Each serialized field or element must implement
rusqlite::types::ToSql.
For deserialization, you can use two families of functions: from_*() and from_*_with_columns().
The most used one is the former. The latter allows you to specify column names for types that need
them but don’t supply them. This includes different Map types like std::collections::HashMap.
Specifying columns for deserialization into e.g. struct doesn’t have any effect as the field list
of the struct itself will be used in any case.
SQLite only supports 5 types: NULL (None), INTEGER (i64), REAL (f64), TEXT (String)
and BLOB (Vec
Some types employ non-trivial handling, these are described below:
-
Serialization of
u64will fail if it can’t be represented byi64due to the SQLite limitations. -
Simple
enums will be serialized as strings so:enum Gender { M, F, }will have two possible
TEXToptions in the database “M” and “F”. Deserialization intoenumfromTEXTis also supported. -
bools are serialized as
INTEGERs 0 or 1, can be deserialized fromINTEGERandREALwhere 0 and 0.0 arefalse, anything else istrue. -
f64 and f32 values of
NaNare serialized asNULLs. When deserializing such a value, Optionwill have the value of None and f64 will have the value of NaN. The same applies to f32. -
[serde_bytes::Bytes], [serde_bytes::ByteBuf] are supported as optimized way of handling
BLOBs. -
unitserializes toNULL. -
Only
sequences of u8 are serialized and deserialized,BLOBdatabase type is used. It’s more optimal, though, to use [serde_bytes::Bytes] and [serde_bytes::ByteBuf] for such fields. -
unit_structserializes tostructname asTEXT. When deserializing, the check is made to ensure that thestructname coincides with the string in the database.
§Examples
use serde::{Deserialize, Serialize};
use serde_rusqlite::*;
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct Example {
id: i64,
name: String,
}
let connection = rusqlite::Connection::open_in_memory().unwrap();
connection.execute("CREATE TABLE example (id INT, name TEXT)", []).unwrap();
// using structure to generate named bound query arguments
let row1 = Example { id: 1, name: "first name".into() };
connection.execute("INSERT INTO example (id, name) VALUES (:id, :name)", to_params_named(&row1).unwrap().to_slice().as_slice()).unwrap();
// and limiting the set of fields that are to be serialized
let row2 = Example { id: 10, name: "second name".into() };
connection.execute("INSERT INTO example (id, name) VALUES (2, :name)", to_params_named_with_fields(&row2, &["name"]).unwrap().to_slice().as_slice()).unwrap();
// using tuple to generate positional bound query arguments
let row2 = (3, "third name");
connection.execute("INSERT INTO example (id, name) VALUES (?, ?)", to_params(&row2).unwrap()).unwrap();
// deserializing using query() and from_rows(), the most efficient way
let mut statement = connection.prepare("SELECT * FROM example").unwrap();
let mut res = from_rows::<Example>(statement.query([]).unwrap());
assert_eq!(res.next().unwrap().unwrap(), row1);
assert_eq!(res.next().unwrap().unwrap(), Example { id: 2, name: "second name".into() });
// deserializing using query_and_then() and from_row(), incurs extra overhead in from_row() call
let mut statement = connection.prepare("SELECT * FROM example").unwrap();
let mut rows = statement.query_and_then([], from_row::<Example>).unwrap();
assert_eq!(rows.next().unwrap().unwrap(), row1);
assert_eq!(rows.next().unwrap().unwrap(), Example { id: 2, name: "second name".into() });
// deserializing using query_and_then() and from_row_with_columns(), better performance than from_row()
let mut statement = connection.prepare("SELECT * FROM example").unwrap();
let columns = columns_from_statement(&statement);
let mut rows = statement.query_and_then([], |row| from_row_with_columns::<Example>(row, &columns)).unwrap();
assert_eq!(rows.next().unwrap().unwrap(), row1);
assert_eq!(rows.next().unwrap().unwrap(), Example { id: 2, name: "second name".into() });
// deserializing using query() and from_rows_ref()
let mut statement = connection.prepare("SELECT * FROM example").unwrap();
let mut rows = statement.query([]).unwrap();
{
// only the first record is deserialized here
let mut res = from_rows_ref::<Example>(&mut rows);
assert_eq!(res.next().unwrap().unwrap(), row1);
}
// the second record is deserialized using the original Rows iterator
assert_eq!(from_row::<Example>(&rows.next().unwrap().unwrap()).unwrap(), Example { id: 2, name: "second name".into() });Re-exports§
pub use de::DeserRows;pub use de::DeserRowsRef;pub use de::RowDeserializer;pub use error::Error;pub use error::Result;pub use ser::NamedParamSlice;pub use ser::NamedSliceSerializer;pub use ser::PositionalParams;pub use ser::PositionalSliceSerializer;pub use rusqlite;
Modules§
Functions§
- columns_
from_ statement - Returns column names of the rusqlite::Statement the way from_row_with_columns() function expects them
- from_
row - Deserializes an instance of
D:[serde::Deserialize] from rusqlite::Row - from_
row_ with_ columns - Deserializes any instance of
D:[serde::Deserialize] from rusqlite::Row with specified columns - from_
rows - Returns an iterator that owns rusqlite::Rows and deserializes all records from it into instances of
D:[serde::Deserialize] - from_
rows_ ref - Returns an iterator that borrows rusqlite::Rows and deserializes records from it into instances of
D:[serde::Deserialize] - to_
params - Serializes an instance of
S:[serde::Serialize] into structure for positional bound query arguments - to_
params_ named - Serializes an instance of
S:[serde::Serialize] into structure for named bound query arguments - to_
params_ named_ with_ fields - Serializes only the specified
fieldsof an instance ofS:[serde::Serialize] into structure for named bound query arguments