assertQueryCacheRowContract()
function assertQueryCacheRowContract(
entityName,
rows,
metadata
): void;
Defined in: packages/rxdb-adapter-sqlite-core/src/query-cache-row-contract.ts:266
落地前校验远端行的列集,不合契约就 fail-fast。
Parameters
| Parameter | Type | Description |
|---|---|---|
entityName | string | QueryCacheEngine 传入的逻辑实体名,原样进错误消息 |
rows | readonly object[] | 待落地的远端行 |
metadata | | Readonly<EntityMetadataType> | undefined | 实体元数据;查不到时跳过前两条判据(本地表的非空列集无从算起),第 3 条照旧 |
Returns
void
Remarks
三条判据,成因不同、修法也不同,因此消息里分开写:
- 缺非空列 —— 本地表建成 NOT NULL 且无 SQL 默认值,写下去必被 SQLite 拒。
今天的表现是一条
NOT NULL constraint failed: public$recipes.createdAt:表名是加了 命名空间前缀的本地表名、列名在远端的 schema 里根本不存在、调用栈落在适配器内部 而不是那次find()—— 三重误导,读者第一反应是「本地表建错了」。 - 非空列带了键但值是空 ——
{ createdAt: null }会带着键通过第 1 条,再被数据库以 同一条 NOT NULL 报错拒掉。远端那一列可空、或select带了没命中的 join 时,select('*')返回的正是这个形状,不是理论形态。修法与第 1 条不同(要去查远端为什么 这一列是 null),因此单列一栏。 - 批内异构 ——
upsertMany的列清单取自data[0],后续行按同一批键取值。缺哪个键 就绑undefined,落到 SQLite 上是 NULL:可空列会被静默清空,连报错都没有。
判在落地前,而不是捕获 SQLite 错误再翻译:翻译要匹配驱动的字符串,而 wa-sqlite / sqlite-wasm / node:sqlite 的措辞各不相同,那是一张要跟着驱动版本一起维护的 正则表。按元数据算出「必须有哪些列」再比对,与驱动无关。
也不给缺列补本地默认值:补出来的 createdAt 是本机拉取的时刻而非记录创建的时刻,
不同设备拉同一行会得到不同的值,且这个污染要到跨设备对比时才暴露。
Throws
存在不满足契约的行