33 个版本 (破坏性更新)

新版本 0.36.0 2024 年 8 月 22 日
0.35.0 2024 年 2 月 19 日
0.34.0 2023 年 11 月 14 日
0.33.1 2023 年 5 月 18 日
0.11.0 2017 年 6 月 2 日

#154编码

Download history 3427/week @ 2024-05-02 2974/week @ 2024-05-09 3015/week @ 2024-05-16 4561/week @ 2024-05-23 3853/week @ 2024-05-30 5882/week @ 2024-06-06 3647/week @ 2024-06-13 2744/week @ 2024-06-20 3699/week @ 2024-06-27 3463/week @ 2024-07-04 2445/week @ 2024-07-11 2534/week @ 2024-07-18 2739/week @ 2024-07-25 4255/week @ 2024-08-01 3166/week @ 2024-08-08 2172/week @ 2024-08-15

12,738 每月下载量
15 crate 中使用 15 (12 直接使用)

MIT/Apache

68KB
1.5K SLoC

serde_rusqlite

文档

查看 完整文档

使用方法

将以下内容添加到您的 Cargo.toml

[dependencies]
serde_rusqlite = "0.36.0"

Maintenance Build Status Documentation

Serde Rusqlite

此 crate 提供了连接 serde 和 rusqlite 的便利函数。有了这些函数,您可以将 rusqlite 的 Row 反序列化为 serde 的 Deserialize 类型,并将实现 Serialize 的类型序列化为 rusqlite 期望的位置参数或命名参数。

仅支持从结构体和映射中序列化命名绑定参数,因为其他 serde 类型缺少列名信息。同样,仅支持从元组、序列和原始非迭代类型中序列化位置绑定参数。在后一种情况下,结果将是单元素向量。每个序列化的字段或元素都必须实现 rusqlite::types::ToSql

对于反序列化,您可以使用两个函数家族:from_*()from_*_with_columns()。最常用的是前者。后者允许您为需要但未提供列名的类型指定列名,这包括不同的 Map 类型,如 HashMap。将列指定为反序列化到例如结构体不会产生任何效果,因为结构体的字段列表在任何情况下都会被使用。

SQLite只支持5种类型:NULLNone)、INTEGERi64)、REALf64)、TEXTString)和BLOBVec<u8>)。对应的Rust类型放在括号内。

某些类型需要复杂处理,下面将进行描述。

  • 由于SQLite的限制,当无法用i64表示时,u64的序列化将失败。

  • 简单的enum将被序列化为字符串,因此

    enum Gender {
       M,
       F,
    }
    

    数据库中将有两个可能的TEXT选项:"M"和"F"。也支持从TEXT反序列化为enum

  • bool被序列化为整数0或1,可以从INTEGERREAL反序列化,其中0和0.0是false,其他任何内容都是true

  • f64f32NaN值被序列化为NULL。当反序列化此类值时,Option<f64>将具有值None,而f64将具有值NaN。同样适用于f32

  • BytesByteBufserde_bytes支持作为处理BLOB的优化方式。

  • unit序列化为NULL

  • 只有sequenceu8被序列化和反序列化,使用数据库中的BLOB类型。尽管如此,对于此类字段,使用来自serde_bytesBytesByteBuf会更优化。

  • unit_struct序列化为struct名称作为TEXT,在反序列化时将检查struct名称是否与数据库中的字符串相匹配。

示例

use serde_derive::{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 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() });

许可:MIT OR Apache-2.0

依赖项

~22MB
~425K SLoC