ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

@effect/sql-mysql2 演进全解析:Effect 生态下 MySQL 适配器的配置面、错误分类与语句执行机制

@effect/sql-mysql2 演进全解析:Effect 生态下 MySQL 适配器的配置面、错误分类与语句执行机制 effect/sql-mysql2 演进全解析Effect 生态下 MySQL 适配器的配置面、错误分类与语句执行机制【免费下载链接】t3code项目地址: https://gitcode.com/GitHub_Trending/t3/t3codeeffect/sql-mysql2是 Effect 官方 SQL 生态中基于mysql2驱动的 MySQL 适配器本文以该包在仓库中的 CHANGELOG.md 为主轴结合其源码、配置与测试用例完整梳理 4.0 系列从 beta.0 到 rc.112 的能力演进。读完你将掌握SqlError的 reason 化错误分类体系与 errno 映射、disablePreparedStatements与valuesUnprepared背后的双执行通道设计、连接池与流式查询的底层实现以及迁移与命名转换等配套能力可直接用于基于 Effect 的 MySQL 服务开发与故障定位。一、模块定位与工程结构effect/sql-mysql2是一个独立的 npm 包其package.json见 .repos/effect-smol/packages/sql/mysql2/package.json声明了以下关键信息名称effect/sql-mysql2当前仓库版本4.0.0-rc.112type: moduleMIT 协议核心依赖mysql2^3.23.4effect作为 peerDependency开发依赖testcontainers/mysql用于集成测试中的真实 MySQL 容器导出入口.映射到./src/index.ts并显式将./index、./*/index设为null对应 CHANGELOG 中 beta.103 移除显式./indexentrypoints 的变更。包源码结构极为精简见 src/index.ts只导出两个模块MysqlClientsrc/MysqlClient.ts客户端构造器、Layer、编译器与配置类型MysqlMigratorsrc/MysqlMigrator.ts复用 Effect SQL 共享迁移运行器的 MySQL 适配入口。从源码结构看该包是“薄适配层”设计把 Effect 的类型化 SQL 抽象SqlClient、SqlConnection、Statement、SqlError对接到底层mysql2的Pool/PoolConnection之上绝大多数行为来自effect/unstable/sql/*共享模块mysql2 侧只负责连接管理、协议调用与原生错误翻译。二、4.0 系列版本时间线与演进主线CHANGELOG 记录了从4.0.0-beta.0到4.0.0-rc.112的完整发布序列。除大量Updated dependencies同步 effect 核心版本外本包自身的实质性变更集中在少数几个版本整理如下版本变更类型核心内容4.0.0-beta.0Majorv4 beta 发布PR #11834.0.0-beta.37PatchSqlError 全面 reason 化原生失败分类为结构化 reason无法识别的回退为Unknown4.0.0-beta.44PatchSqlModel.makeResolvers直接返回 resolversServiceMap模块更名为Context4.0.0-beta.65Patch新增UniqueViolation错误 reason约束标识提取失败时回退为unknown4.0.0-beta.86Patch新增Statement.valuesUnprepared返回未预编译语句的数组形式行4.0.0-beta.101PatchMysqlClientConfig新增disablePreparedStatements可完全禁用预编译语句4.0.0-beta.103Patch移除显式./indexentrypointsPR #67014.0.0-rc.112Patch将生产依赖更新到最新发布版PR #7421可以清晰地看出演进主线先奠定 reason 化错误模型再围绕“预编译 vs 文本协议”补全执行通道能力最后收敛导出与依赖。接下来逐个深入。三、SqlError 的 reason 化错误分类体系beta.37 → beta.65CHANGELOG 在4.0.0-beta.37中说明将SqlError的变更整合为新的reason-based 形状把各 SQL 驱动的原生失败分类成结构化 reason原生错误码不可用时以Unknown兜底4.0.0-beta.65进一步把“受支持的唯一约束冲突”从宽泛的ConstraintError中拆出为独立的UniqueViolationreason并覆盖 PostgreSQL、PGlite、MySQL、MSSQL 以及 SQLite 家族的共享分类。在 MySQL 适配器中这套机制的实现位于 MysqlClient.ts 的 classifyError其核心是根据 mysql2 异常对象的errno数值进行映射errnoreason 类型含义1040 / 1042 / 1043 / 1129 / 1130 / 1203ConnectionError连接类错误连接数超限、主机不可达等1045AuthenticationError访问被拒绝、认证失败1044 / 1142 / 1143 / 1227AuthorizationError权限不足1054 / 1064 / 1146SqlSyntaxError语法/未知列/表不存在1062UniqueViolation唯一约束冲突含约束标识提取1022 / 1048 / 1169 / 1216 / 1217 / 1451 / 1452 / 1557ConstraintError其他约束冲突含外键 1451/14521213DeadlockError死锁1205LockTimeoutError锁等待超时3024StatementTimeoutError语句超时其他 / 无 errnoUnknownError无法识别时兜底这些映射同时支撑四个使用场景连接校验失败operation: connect、获取连接失败acquireConnection、语句执行失败execute/executeUnprepared以及流式查询失败stream错误消息分别对应 Failed to connect、Failed to acquire connection、Failed to execute statement、Failed to stream statement。UniqueViolation 的约束标识提取对于 errno 1062适配器不会只给出一个宽泛的类型而是尽力提取冲突的约束/索引/键名。提取优先级见 MysqlClient.ts#L86-L96优先读取 cause 上的结构化constraint字段做 trim 规范化其次从sqlMessage中用正则for key ...、for key ...或裸标识符三种形式解析再退到message字段做同样解析全部失败时严格回退为字符串unknown常量UNKNOWN_CONSTRAINT。测试文件 SqlErrorClassification.test.ts 完整验证了这一行为链单引号、反引号、无引号三种约束写法都能提取如users_email_key、PRIMARY而对空白字符串、缺少匹配、非字符串字段则一律回退unknown同时确认非唯一约束类 errno如 1452 外键失败仍归类为ConstraintError未映射的 errno如 9999回退为UnknownError。这套测试通过vi.mock(mysql2)伪造连接失败 cause无需真实数据库即可运行。四、disablePreparedStatements双执行通道设计beta.1014.0.0-beta.101为MysqlClientConfig新增disablePreparedStatements选项用于完全禁用预编译语句。该选项的源码注释给出了典型场景某些代理如 Cloudflare Hyperdrive不支持COM_STMT_PREPARE协议此时必须退回到 MySQL 文本协议。其实现机制非常直观见 MysqlClient.ts#L227const defaultMethod: execute | query options.disablePreparedStatements true ? query : execute默认disablePreparedStatements: false或未设置所有语句走 mysql2 的execute即COM_STMT_PREPARE预编译通道开启后默认走query文本协议通道。ConnectionImpl暴露的六个执行入口分别对应两种协议见 MysqlClient.ts#L270-L306入口协议说明execute预编译execute标准查询支持行转换executeRaw预编译原始结果透传executeValues预编译行以数组形式返回rowsAsArray: trueexecuteValuesUnprepared文本query行以数组形式返回但走文本协议executeUnprepared文本强制文本协议查询executeStream文本流式查询集成测试 MysqlClient.integration.test.ts 专门验证了该行为在disablePreparedStatements: true下执行sql\SELECT ${1}、.values与sql.unsafe(SELECT ?, [1]).raw三种调用断言底层全部落在query通道[query, query, query]。与 valuesUnprepared 的呼应beta.864.0.0-beta.86引入的Statement.valuesUnprepared与上述设计一脉相承它让调用方在不预编译的前提下以数组形式获取行数据对应Connection上的executeValuesUnprepared实现。结合上一节的通道表可以看出Effect SQL 的语句抽象对“是否预编译”与“行形态对象/数组”做了正交组合disablePreparedStatements解决的是全局默认valuesUnprepared/executeUnprepared解决的是单条语句的显式控制。五、连接管理、健康检查与流式查询连接池的构建与校验make构造器MysqlClient.ts#L217-L417是适配器的核心工厂其行为要点两种配置形态提供urlRedacted包裹的 Redacted 类型时直接以 URI 创建池且url会覆盖其他连接字段否则使用host/port/database/username/password等离散字段默认池参数multipleStatements: true、supportBigNumbers: true连接数由maxConnections或poolConfig.connectionLimit决定空闲超时由connectionTTLDuration类型换算为毫秒传入idleTimeout启动健康检查池创建后立即执行SELECT 1失败则映射为SqlError并终止整体套了 5 秒超时Duration.seconds(5)超时抛ConnectionErrorMysqlClient: Connection timeout资源生命周期通过Effect.acquireRelease管理池的end()与连接的release()保证 Scope 作用域内安全关闭span 属性自动注入db.system.name mysql、server.address默认localhost、server.port默认 3306并可选注入db.namespace即 database可与 OpenTelemetry 观测体系打通。流式查询executeStream通过queryStream实现MysqlClient.ts#L482-L527基于 mysql2 的.query(...).stream()配合asyncPauseResume实现背压onPause/onResume对应流控用queueMicrotask批量缓冲发射数据并通过Effect.addFinalizer在作用域退出时销毁查询流。集成测试用 100 行数据对比“流式收集”与“直接执行”的结果数量验证二者一致见 MysqlClient.integration.test.ts#L12-L38。配置类型速查MysqlClientConfigMysqlClient.ts#L182-L209完整字段如下字段类型说明urlRedacted.Redacted连接 URI设置后覆盖其他连接选项host/port/database/username/password基础类型离散连接参数password 同样要求RedactedmaxConnectionsnumber池最大连接数connectionTTLDuration.Input连接空闲超时poolConfigMysql.PoolOptions透传 mysql2 池选项disablePreparedStatementsboolean使用文本协议替代预编译语句spanAttributesRecordstring, unknown附加追踪属性transformResultNames/transformQueryNames(str: string) string结果/查询命名转换其中命名转换在makeCompilerMysqlClient.ts#L461-L478中落地MySQL 编译器使用?占位符、反引号转义标识符Statement.defaultEscape()当配置了transformQueryNames时标识符在转义前先经转换函数处理。集成测试的工具层[test/utils.ts#L46-L55](https://link.gitcode.com/i/ffbea92e7318262a3ef54caaae54a1d8)就演示了camelToSnake/snakeToCamel 的典型用法查询名转 snake_case结果行转 camelCase实现跨命名风格映射。六、迁移、服务提供与其余 API 变更MigratorMysqlMigratorsrc/MysqlMigrator.ts基于共享的effect/unstable/sql/Migrator构建run({ loader, schemaDirectory, table })通过当前SqlClient按顺序应用迁移返回已应用迁移的[id, name]数组layer(options)在 Layer 构建期间执行迁移成功后不提供任何服务Layer.effectDiscard源码中保留了dumpSchema的注释实现基于mysqldump命令但因Command模块暂不可用而处于 TODO 状态——这说明当前版本暂不支持模式导出能力迁移聚焦于正向应用。服务注册方式MysqlClient提供了三种创建方式见 MysqlClient.ts#L217-L453make(config)返回 scopedEffectMysqlClient, SqlError, Scope | Reactivity.Reactivity适合在 Effect 内部手动管理layer(config)由具体配置直接构造 Layer同时提供MysqlClient与通用Client.SqlClient两个服务layerConfig(config)接受Config.WrapMysqlClientConfig支持从环境/配置文件惰性解析配置。三者都依赖Reactivity.layer提供响应式运行时支持。其他变更点beta.44 / beta.103 / rc.112beta.44SqlModel.makeResolvers改为直接返回 resolversServiceMap模块更名为Context——属于 API 表面收敛影响模型层调用方beta.103移除显式./indexentrypoints改用现代条件导出这也解释了package.json中./index: null的写法rc.112 及之前所有 Patch 版本绝大多数条目为同步effect核心依赖的Updated dependencies反映该包与 effect 主版本强绑定、跟随发布节奏的维护策略——升级本包时务必同步升级effect到对应版本。七、如何在本仓库中验证与深入学习无需额外安装即可在本仓库验证上述结论阅读 CHANGELOG.repos/effect-smol/packages/sql/mysql2/CHANGELOG.md按版本倒序查看每条 Patch 对应的 PR 与提交哈希阅读核心实现src/MysqlClient.ts 中的classifyError、make、queryStream、makeCompiler阅读单元测试test/SqlErrorClassification.test.ts 可在无数据库环境下验证 errno→reason 映射与约束提取阅读集成测试test/MysqlClient.integration.test.ts 与 test/utils.ts 展示了基于testcontainers/mysql的mysql:lts容器启动、健康检查与命名转换配置模式可作为本地联调 MySQL 适配器的参考脚手架。总体而言effect/sql-mysql2的 4.0 演进展示了典型的“协议适配 错误语义化”设计把 mysql2 原生 errno 翻译成语义明确的 Effect 类型化错误把预编译/文本协议差异封装为可配置且可精细控制的执行通道再以Config/Layer无缝接入 Effect 依赖注入体系。掌握这套映射与配置面即可在 Effect 项目中高效、可诊断地使用 MySQL。【免费下载链接】t3code项目地址: https://gitcode.com/GitHub_Trending/t3/t3code创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表