尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

解码机制揭秘:deno-postgres 如何将 200+ PostgreSQL 类型自动转为 JS 对象

解码机制揭秘:deno-postgres 如何将 200+ PostgreSQL 类型自动转为 JS 对象 解码机制揭秘deno-postgres 如何将 200 PostgreSQL 类型自动转为 JS 对象【免费下载链接】postgresPostgreSQL driver for Deno项目地址: https://gitcode.com/gh_mirrors/postgr/postgres当你用 deno-postgres 执行SELECT查询并拿到rows时数据库返回的其实是一堆字符串而你看到的却是number、Date、boolean、嵌套数组甚至几何对象——这种PostgreSQL 类型自动转为 JS 对象的魔法正是 deno-postgresPostgreSQL driver for Deno解码机制的核心能力。本文带你拆解这条解码流水线看懂 200 数据库类型是如何被识别、分发并转换为原生 JavaScript 对象的即使你是新手也能轻松理解。为什么需要自动类型转换先认识 PostgreSQL 的文本协议PostgreSQL 服务端在返回查询结果时默认使用文本格式Text Format传输数据。也就是说123是字符串123true是字符串t时间戳是2024-01-01 08:00:0008这样的文本。如果驱动不做任何处理你的应用拿到的将全是字符串后续还得手动parseInt、new Date()…… 而 deno-postgres 的目标就是让开发者开箱即用直接拿到最接近原生 JS 的类型。这就催生了整套解码Decode机制。deno-postgres 的解码相关代码集中在query/目录下核心文件包括query/decode.ts解码入口与类型分发query/oid.ts类型标识OID映射表query/decoders.ts各类型的具体解码函数query/array_parser.ts数组字符串解析器query/types.ts几何类型等对象的 TypeScript 定义OIDPostgreSQL 类型的身份证PostgreSQL 为每一种内置类型分配了一个唯一编号称为OIDObject Identifier。例如int4是 23text是 25jsonb是 3802uuid是 2950。当查询结果返回时服务端会附带一份Row Description行描述其中包含每一列的typeOid。deno-postgres 就在 query/oid.ts 中维护了一张完整的OID 映射表把数字编号与类型名称一一对应覆盖了 200 种 PostgreSQL 类型包括类型OIDJS 目标类型bool16booleanint2 / int421 / 23numberint820bigintfloat4 / float8700 / 701numbernumeric1700string保留精度text / varchar25 / 1043stringdate / timestamp1082 / 1114Datejson / jsonb114 / 3802objectpoint / box / circle600 / 603 / 718几何对象通过这张表驱动不需要猜数据类型而是根据 OID 精准匹配这也是它能做到类型自动转换的前提。解码流水线从字节流到 JS 对象的三步走整个解码过程可以概括为三步入口函数在 query/decode.ts 中收数据服务端返回的每一列原始值是一个Uint8Array字节流先用TextDecoder转成字符串查身份拿到该列的typeOid在 OID 映射表中确认它是什么类型调解码器根据类型调用 query/decoders.ts 中对应的解码函数得到 JS 对象。实际代码中decode()函数内部是一个巨大的switch (typeOid)分支每个 case 对应一种类型例如Oid.bool→decodeBoolean把t / true / 1统一转成trueOid.int4→decodeInt直接parseIntOid.json / jsonb→decodeJson直接JSON.parseOid.timestamp→decodeDatetime解析成Date对象如果某个类型没有对应解码器驱动会原样返回字符串把解析的主动权交给你绝不会擅自丢弃数据。内置解码器一览200 类型的分类处理query/decoders.ts 是解码机制的武器库内置解码器可以按类别划分数值类decodeInt、decodeFloat、decodeBigint其中int8会转成bigint避免大数精度丢失布尔类decodeBoolean兼容t/true/y/yes/on/1等多种写法时间类decodeDate、decodeDatetime连infinity这种特殊日期值也能处理并正确解析时区偏移JSON 类decodeJson与decodeJsonb统一走JSON.parse二进制类decodeBytea同时支持十六进制\x...和转义两种格式返回Uint8Array几何类decodePoint、decodeBox、decodeCircle、decodeLine、decodePath、decodePolygon它们被解析成 query/types.ts 中定义的结构化对象元组类decodeTid返回[bigint, bigint]元组这套设计让 deno-postgres 能在原样字符串和类型化对象之间自由选择兼顾了便利性与灵活性。数组类型递归解析的进阶玩法数组是 PostgreSQL 类型转换中最考验功力的一环。比如int4[]类型的值在文本协议下是{1,2,3}而嵌套数组则是{{1,2},{3,4}}还可能出现带引号的字符串元素和NULL。deno-postgres 在 query/array_parser.ts 中实现了一个专门的数组解析器parseArray它按字符逐个扫描遇到{进入更深一层递归创建子解析器处理嵌套数组遇到进入引号模式字符串中的逗号不会被误拆遇到\处理转义字符遇到NULL转换为null最妙的是数组解析器与元素解码器是解耦的你给int4[]传decodeInt它就能把{1,2,3}解析成[1, 2, 3]给jsonb[]传JSON.parse它就能解析出对象数组。任何内置或自定义解码器都能复用到数组场景。两种解码策略auto 与 string如何选择在 connection/connection_params.ts 中deno-postgres 提供了decodeStrategy配置默认是autoauto默认自动解析为 JS 对象未实现的类型返回字符串适合绝大多数场景string所有值一律以字符串返回解析工作完全交给你适合需要原始数据做自定义处理的场景const client new Client({ database: some_db, user: some_user, controls: { decodeStrategy: auto, // 默认值也可显式声明 }, });选择很简单追求开箱即用选auto追求完全可控选string。自定义解码器按需定制你的类型转换内置解码器覆盖了绝大多数场景但如果你有特殊需求——比如希望日期返回成 dayjs 对象、布尔值返回成数字——deno-postgres 允许你通过controls.decoders传入自定义解码函数。自定义解码器有两个特点优先级最高它会覆盖内置解码器和解码策略键名灵活既可以用 OID 数字如23也可以用类型名如int4作为 key。const client new Client({ controls: { decoders: { bool: (value: string) (value t ? 1 : 0), // 布尔转数字 1082: (value: string) dayjs(value), // date 类型转 dayjs }, }, });更贴心的是如果你只给基础类型如int4定义了自定义解码器驱动会自动把它套用到int4[]数组的每个元素上无需重复定义。解码失败怎么办容错机制兜底解码过程中难免遇到异常数据比如格式非法的日期。deno-postgres 的处理策略很务实捕获异常、在控制台打印警告信息然后将该字段值默认为null而不是让整个查询崩溃。这种宁可给 null不让应用挂掉的容错设计保证了线上服务的稳定性。写在最后deno-postgres 的解码机制并不神秘OID 识别类型 → 分发解码器 → 输出 JS 对象配合数组递归解析、双解码策略与自定义解码器让 200 PostgreSQL 类型得以自动转换为 JS 对象。理解这条流水线后你再遇到为什么这个字段返回了字符串或如何定制类型解析这类问题就能直接去 query/decode.ts 和 query/oid.ts 里找到答案甚至为项目贡献自己的解码器。【免费下载链接】postgresPostgreSQL driver for Deno项目地址: https://gitcode.com/gh_mirrors/postgr/postgres创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表