跳到主要内容

assertQueryCacheRowContract()

function assertQueryCacheRowContract(
entityName,
rows,
metadata
): void;

Defined in: packages/rxdb-adapter-pglite/src/query-cache/query_cache_row_contract.ts:374

落地前校验远端行的列集,不合契约就 fail-fast。

Parameters​

ParameterTypeDescription
entityNamestringQueryCacheEngine 传入的逻辑实体名,原样进错误消息
rowsreadonly object[]待落地的远端行
metadataEntityMetadata实体元数据(resolveQueryCacheTarget 已 fail-fast,这里必然拿得到)

Returns​

void

Remarks​

只判一条:本地表上 NOT NULL 且无 SQL 默认值的列,这一行送不进一个非空值 —— 要么三种写法一个都没带,要么带了键而值是 null / undefined。两种都写下去必被 PostgreSQL 拒,今天的表现是同一条 null value in column "created_at" of relation "qc_recipes" violates not-null constraint:表名是加了 schema 的本地表名、列名在 远端的 schema 里根本不存在、调用栈落在适配器内部而不是那次 find() —— 三重误导,读者第一反应是「本地表建错了」。

「带了键但值是空」不是理论形态:远端那一列可空、或 select 带了没命中的 join 时, select('*') 返回的就是 { createdAt: null }。只判键在不在会把它整批放行。

不判批内异构。sqlite-core 侧那条判据的成因是它的列清单取自 data[0],后续行按同一批 键取值、缺哪个就绑 undefined 写成 NULL(可空列被静默清空)。PGlite 走 groupByColumnSet 按列集分组、每组一条 INSERT,缺的键根本不出现在列清单里 —— 结构上没有这个病,跟着判只会把一个已交付的能力改成报错。

判在落地前,而不是捕获 PostgreSQL 错误再翻译:翻译要匹配驱动的字符串,而各驱动措辞 各不相同,那是一张要跟着驱动版本一起维护的正则表。按元数据算出「必须有哪些列」 再比对,与驱动无关。

也不给缺列补本地默认值(铁律「无 fallback 兜底」):补出来的 createdAt 是本机拉取 的时刻而非记录创建的时刻,不同设备拉同一行会得到不同的值,且这个污染要到跨设备对比时 才暴露。

Throws​

存在不满足契约的行