核心抽象
这一部分是本卷的重点:和具体数据库无关的 trait 都在 sqlx-core/src/ 里,驱动 crate(这一卷只看 sqlx-postgres)负责实现它们,sqlx crate 原样重新导出。相关的文件不大:database.rs、connection.rs、executor.rs、acquire.rs 加起来约 800 行,query*.rs、sql_str.rs、raw_sql.rs、query_builder.rs 约 2.6k 行(其中 1.1k 多行是文档注释),类型、行和错误各几百行。
前三章沿着查询主线走一遍「执行之前」:一个数据库由哪些类型组成,查询交给谁执行,查询本身是什么。后三章是执行之后:值怎么编码解码,行怎么变成 Rust 类型,出错时是什么。
- Database 与关联类型:
Database没有方法,只是一张关联类型表,各组件 trait 用Database = Self指回来;0.9 起只剩ValueRef<'r>带生命周期;跨数据库的泛型函数要逐条写约束,运行时选库用Any驱动,它能处理的值只有十种。 - Executor 与 Acquire:
Executor十个方法里必须实现的是fetch_many、fetch_optional、prepare_with(开了macros还有describe);Execute::take_arguments返回None走简单查询;&Pool每次调用重新取连接,Transaction要写&mut *tx;要在一个函数里跑多条查询,收Acquire。 - Query、QueryAs 与 SqlSafeStr:三种查询类型一层包一层;
bind当场编码、错误留到执行时抛出;0.9 的SqlSafeStr让query(&format!(..))编译不过,SqlStr让查询可以是'static;raw_sql和QueryBuilder。 - 类型:Type、Encode、Decode:Rust 类型和 SQL 类型怎么对应、怎么编码成参数、怎么从列里解码,
Option<T>和 NULL,#[derive(sqlx::Type)]。 - Row 与 FromRow:按列名或下标取值,类型检查发生在哪里,元组和
#[derive(FromRow)]怎么把一行变成结构体。 - 错误:
Error的各个分支,Postgres 的错误码和约束名,怎么判断唯一约束冲突。
flowchart TB db["Database 类型表"] --> exec["Executor 拿什么跑"] db --> query["Query 跑什么"] query -->|Execute| exec query --> enc["Encode 参数"] exec --> row[Row] row --> dec["Decode / FromRow"] exec --> err[Error]
Postgres 驱动怎么实现这些 trait(协议消息、语句缓存、类型 OID)在 03 Postgres 驱动;&Pool 背后的 acquire 在 04 连接池。
💬 关联讨论
发起讨论加载中...