news 2026/9/14 4:31:55

Effect Model.BooleanSqlite:为 SQLite 布尔列提供 0|1 与 boolean 双边界编码的模型字段

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Effect Model.BooleanSqlite:为 SQLite 布尔列提供 0|1 与 boolean 双边界编码的模型字段

Effect Model.BooleanSqlite:为 SQLite 布尔列提供 0|1 与 boolean 双边界编码的模型字段

【免费下载链接】effectBuild production-ready applications in TypeScript项目地址: https://gitcode.com/GitHub_Trending/ef/effect

本文围绕 Effect 仓库中的变更记录 bright-dogs-fail.md 展开:该 changeset 声明为effect包新增了一个 patch 级 API——Model.BooleanSqlite,一个数据库变体使用0 | 1编码、JSON 变体使用原生boolean编码的模型字段模式。读完本文,你将理解它在 Effect 4.0 的Model变体模型体系中的定位、底层BooleanFromBit编解码的实现细节,以及如何在你自己的模型中正确使用它并通过测试验证。

变更记录本身说了什么

该 changeset 文件位于 .changeset/pre/bright-dogs-fail.md,正文只有一句话:

AddModel.BooleanSqlite, a model field schema that uses0 | 1encoding for database variants and plainbooleanencoding for JSON variants.

即:新增Model.BooleanSqlite——一个模型字段模式(model field schema),其中:

  • 数据库变体select/insert/update)使用0 | 1的位编码;
  • JSON 变体json/jsonCreate/jsonUpdate)使用普通boolean编码。

这一变更对应 packages/effect/CHANGELOG.md 中记录的条目(PR #1622),并属于 Effect v4 中Model模块(@since 4.0.0)的一部分。迁移文档 migration/v3-to-v4.md 还给出了相关的版本对照说明:v3 时代的Model.BooleanFromNumber对应 v4 的核心 schemaBooleanFromBit,而Model.BooleanSqlite则是「开箱即用的模型字段」形态。

为什么需要它:变体模型的基本问题

SQLite 没有原生布尔类型,布尔值通常以整数列0 | 1存储;而面向 HTTP API 的 JSON 表示则应当是true | false。在 Effect 4 的模型体系中,一个字段在不同操作边界(读取数据库、写入数据库、对外输出 JSON)可能需要不同的编码形态

Model模块正是为此设计的。从 packages/effect/src/unstable/schema/Model.ts 可以看到,模型模式基于VariantSchema工厂生成,固定提供六个变体:

const { Class, Field, FieldExcept, FieldOnly, Struct, Union, extract, fieldEvolve } = VariantSchema.make({ variants: ["select", "insert", "update", "json", "jsonCreate", "jsonUpdate"], defaultVariant: "select" })

每个字段通过Field({ ... })按变体名声明各自的 schema;未声明的变体中该字段被整体省略。这样Group.insert就只包含需要用户提供的字段,Group.json就只暴露应当对外可见的字段,且每个变体都是独立可校验、可编解码的 schema。

BooleanSqlite 的源码实现

BooleanSqlite定义在 packages/effect/src/unstable/schema/Model.ts,其类型与构造实现为:

export interface BooleanSqlite extends VariantSchema.Field<{ readonly select: Schema.BooleanFromBit readonly insert: Schema.BooleanFromBit readonly update: Schema.BooleanFromBit readonly json: Schema.Boolean readonly jsonCreate: Schema.Boolean readonly jsonUpdate: Schema.Boolean }> {} export const BooleanSqlite: BooleanSqlite = Field({ select: Schema.BooleanFromBit, insert: Schema.BooleanFromBit, update: Schema.BooleanFromBit, json: Schema.Boolean, jsonCreate: Schema.Boolean, jsonUpdate: Schema.Boolean })

可以清晰地看出它对六个变体的完整覆盖:

变体schema编码形态
selectSchema.BooleanFromBit0 \| 1
insertSchema.BooleanFromBit0 \| 1
updateSchema.BooleanFromBit0 \| 1
jsonSchema.Booleantrue \| false
jsonCreateSchema.Booleantrue \| false
jsonUpdateSchema.Booleantrue \| false

也就是说:解码数据库行时接受0 | 1并映射为boolean,编码回数据库时把boolean映射回0 | 1;而在 JSON API 边界上完全使用原生布尔,不做任何位转换。

底层编解码:BooleanFromBit

数据库侧的Schema.BooleanFromBit定义在 packages/effect/src/Schema.ts:

export const BooleanFromBit: BooleanFromBit = Literals([0, 1]).pipe( decodeTo( Boolean, SchemaTransformation.transform({ decode: (bit) => bit === 1, encode: (bool) => bool ? 1 : 0 }) ) )

其文档注释明确了语义边界:解码只接受字面量011映射为true0映射为false;编码时true映射为1false映射为0。注意这是严格校验——传入2"1"等值会触发解码失败,而不是宽松地把「任意真值」当作布尔。这与 SQLite 中「整数列存布尔」的常见约定一致:列里应当只出现01

实际使用:在模型中声明与验证

Model.BooleanSqliteModel.Struct/Model.Class组合使用。官方测试 packages/effect/test/unstable/schema/VariantSchema.test.ts 提供了可直接复制的完整示例,验证了数据库与 JSON 两侧的编解码行为:

import { Schema } from "effect" import { Model } from "effect/unstable/schema" const User = Model.Struct({ active: Model.BooleanSqlite }) const select = Model.extract(User, "select") // 数据库变体 const json = Model.extract(User, "json") // JSON 变体 Schema.encodeSync(select)({ active: true }) // => { active: 1 } Schema.decodeSync(select)({ active: 0 }) // => { active: false } Schema.encodeSync(json)({ active: true }) // => { active: true } Schema.decodeSync(json)({ active: false }) // => { active: false }

这四行断言恰好对应 changeset 描述的两种编码:select 变体编出1、解入0得到false;json 变体则原样保持布尔。

如果你使用Model.Class定义领域模型,字段声明方式完全一致,例如:

import { Model } from "effect/unstable/schema" class Post extends Model.Class<Post>("Post")({ title: Schema.String, published: Model.BooleanSqlite, // DB 列为 0 | 1,JSON 输出为 boolean createdAt: Model.DateTimeInsertFromDate }) {}

此时Post(即select变体)用于读取数据库行,Post.insert/Post.update用于写库载荷,Post.json/Post.jsonCreate/Post.jsonUpdate用于 API 输入输出;各变体中published的 TS 类型都是boolean,只有落到数据库边界时才表现为0 | 1

与同类字段模式的对照

Model模块中还有一批同样按「变体 × schema」声明的现成字段,可帮助判断何时选用BooleanSqlite(见 Model.ts):

  • GeneratedByDb(schema):字段仅出现在select/json(数据库自增列,插入时不可提供);
  • GeneratedByApp(schema):出现在数据库三变体与json,但不出现在 JSON 创建/更新载荷;
  • Sensitive(schema):仅数据库变体可见,所有 JSON 变体中整体省略(如密码);
  • FieldOption(schema):所有变体可选,数据库变体接受null,JSON 变体接受缺失键且解码为Option
  • BooleanSqlite:所有变体都可见,仅编码形态按边界区分。

如果字段在数据库与 JSON 中的编码形态相同(比如都是字符串),直接写Schema.String即可;BooleanSqlite专治「同一逻辑值、两种编码形态」的场景。

小结

这条 patch 变更记录对应的Model.BooleanSqlite是 Effect v4 变体模型体系中的一个小而完整的构件:它以六个变体为粒度声明「SQLite 侧用0 | 1、JSON 侧用boolean」的编解码契约,底层复用核心Schema.BooleanFromBit的严格字面量转换,并配套了覆盖两侧编解码的测试用例。对于使用 SQLite 并通过 Effect 构建 API 的项目,把它声明为模型字段后,数据库行与对外 JSON 之间的布尔转换即由类型系统接管,无需在每个读写点手写? 1 : 0

【免费下载链接】effectBuild production-ready applications in TypeScript项目地址: https://gitcode.com/GitHub_Trending/ef/effect

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 4:29:45

GoogleTest深入解析:断言宏、参数化测试与Bazel工程实践

简介&#xff1a;GoogleTest谷歌C测试框架是一套面向C开发者的开源单元测试解决方案&#xff0c;基于成熟的xUnit架构&#xff0c;能够自动发现并运行测试&#xff0c;省去手动注册的繁琐流程。除了一般的相等性、异常等断言外&#xff0c;还可以自定义断言&#xff0c;并借助致…

作者头像 李华
网站建设 2026/9/14 4:29:37

无人机通信安全:MAVLink AES-128-GCM加密实战指南

刚开始接触无人机组装和飞控开发的朋友&#xff0c;多半会碰上这么一件事&#xff1a;地面站和飞控之间用MAVLink协议通信&#xff0c;参数、航点、遥控指令全都明文在空中飞来飞去。懂点通信安全的人看一眼就会后背发凉——这意味着附近任何人拿一台接收机&#xff0c;就能把你…

作者头像 李华
网站建设 2026/9/14 4:26:45

YOLO+MobileFaceNet人脸识别签到系统实战:选型、训练与部署

我这两年陆续帮几个学生和同行看过类似的毕业设计项目&#xff0c;人脸识别签到这个方向确实被选得很多。但大部分作品还停留在"跑通Demo"阶段——拿着开源模型套个界面&#xff0c;能认出几个人就算完事。真正把会议签到场景的痛点想清楚、把YOLO MobileFaceNet这套…

作者头像 李华
网站建设 2026/9/14 4:25:52

动力总成集成化:四流协同重构与系统级验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华