
postgres_lsp banDropDatabase 规则深度解析如何在 lint 层拦截危险的 DROP DATABASE 操作【免费下载链接】postgres_lspA Language Server for Postgres项目地址: https://gitcode.com/GitHub_Trending/po/postgres_lsp导读banDropDatabase是 postgres_lsp 项目中lint/safety安全组的一条静态检查规则用于在 SQL 语句被执行之前拦截DROP DATABASE这类高风险操作因为删除数据库会立刻断开所有现有客户端连接、并永久销毁数据。本文以 docs/reference/rules/ban-drop-database.md 为核心结合规则源码、配置注册表与测试用例讲解该规则的触发原理、默认行为、JSON 配置方式以及如何把它接入 CLI 与编辑器工作流帮助你建立危险语句在代码审查/CI 阶段即被拦截的防护习惯。规则概览它到底拦截什么banDropDatabase的诊断分类为lint/safety/banDropDatabase自vnext版本引入。它的设计动机在官方描述中说得非常直白Dropping a database may break existing clients (and everything else, really). Make sure that you really want to drop it.即删除数据库不仅会销毁其中全部表、索引、函数与数据还会使所有已建立的客户端连接立即失效——破坏现有客户端以及其它一切。规则本身不阻止你执行DROP DATABASE而是在代码检查阶段发出警告强制你确认我真的想删掉它。该规则的灵感来源于数据库迁移检查工具 Squawk 的squawk/ban-drop-database规则在源码中通过RuleSource::Squawk(ban-drop-database)声明postgres_lsp 将其移植为原生 lint 规则。源码实现如何识别 DROP DATABASE规则的完整实现位于 crates/pgls_analyser/src/lint/safety/ban_drop_database.rs整个文件核心逻辑只有几十行但清晰地展示了 postgres_lsp 规则的统一编写范式declare_lint_rule! { /// Dropping a database may break existing clients (and everything else, really). /// /// Make sure that you really want to drop it. pub BanDropDatabase { version: next, name: banDropDatabase, severity: Severity::Warning, recommended: false, sources: [RuleSource::Squawk(ban-drop-database)], } } impl LinterRule for BanDropDatabase { type Options (); fn run(ctx: LinterRuleContextSelf) - VecLinterDiagnostic { let mut diagnostics vec![]; if let pgls_query::NodeEnum::DropdbStmt(_) ctx.stmt() { diagnostics.push( LinterDiagnostic::new( rule_category!(), None, markup! { Dropping a database may break existing clients. }, ) .detail(None, You probably dont want to drop your database.), ); } diagnostics } }可以从源码结构中提取出以下几个关键事实匹配节点类型规则只针对解析树中的pgls_query::NodeEnum::DropdbStmt节点。也就是说只有当一条语句被解析器识别为 PostgreSQL 的DROP DATABASE语句对应 libpg_query 的DropdbStmt语法节点时才会触发DROP TABLE、DROP SCHEMA等其它删除语句不会命中本规则。规则的零配置特性type Options ()表示该规则不接受任何额外的选项参数开与关就是全部配置维度。默认行为severity: Severity::Warning且recommended: false。这意味着它默认不在推荐规则集内即单纯的recommended: true不会启用它需要显式在配置中打开同时它属于 Warning 级而非 Error 级即使启用默认也不会因它导致 CI 失败除非你显式提升为error或配合--error-on-warnings使用。诊断文案触发时输出主信息Dropping a database may break existing clients.并附带提示You probably dont want to drop your database.语气直接、目标明确。从语句到诊断的完整链路规则注册后会经过以下调用链生效crates/pgls_analyser/src/lint/safety.rs 通过declare_lint_group!把BanDropDatabase编入名为safety的规则组crates/pgls_analyser/src/registry.rs 将规则名banDropDatabase与规则实现建立映射供配置解析按名字查找crates/pgls_configuration/src/linter/rules.rs 中维护规则的合法名字列表第 351 行出现banDropDatabase并定义了banDropDatabase Severity::Warning的默认严重级别映射crates/pgls_diagnostics_categories/src/categories.rs 注册诊断分类lint/safety/banDropDatabase用于在编辑器、CLI 与文档中统一标识该诊断。当某条 SQL 语句经过解析产生DropdbStmt节点时规则即产生一条LinterDiagnostic最终由 CLI 或 LSP 通道以该分类名呈现给用户。触发行为验证测试用例与快照仓库为每条规则都配备了规范的测试用例位于 crates/pgls_analyser/tests/specs/safety/banDropDatabase/。输入文件 basic.sql 内容如下-- expect_lint/safety/banDropDatabase drop database all_users;注释中的expect_lint/safety/banDropDatabase声明了期望该语句应命中lint/safety/banDropDatabase诊断。对应的快照文件 basic.sql.snap 记录了实际输出lint/safety/banDropDatabase ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ × Dropping a database may break existing clients. i You probably dont want to drop your database.这段快照直接印证了源码中的诊断文案也说明了规则的触发边界任意形式的drop database name;无论目标库名是什么都会被标记。如果你希望在 CI 中引入该规则只需保证新增的迁移 SQL 中不出现DROP DATABASE语句规则检查即可通过。如何配置从关闭到强制 ErrorbanDropDatabase默认不在推荐规则集中recommended: false需要显式配置。官方文档给出的配置示例如下{ linter: { rules: { safety: { banDropDatabase: error } } } }在 postgres_lsp 中这份 JSON 配置可以直接写入项目根目录的postgres-language-server.jsonc参考仓库自带的 postgres-language-server.jsonc它支持//注释与$schema校验。其配置层级为linter.rules.safety.规则名其中safety即规则组名与源码中declare_lint_group!定义的组名一致。严重级别取值说明error把规则升级为 Error 级。在 CLI 场景下一旦命中DROP DATABASE语句检查将直接失败适用于生产迁移必须零风险的项目warning保持 Warning 级与源码默认值一致只提示不阻断适合希望提醒但允许人工确认后放行的团队off显式关闭该规则适合确有合法删库场景如自动化测试环境重建的仓库。需要特别注意的是由于规则默认recommended: false仅设置recommended: true不会启用它必须像上面的示例一样按规则名显式声明级别才会真正生效。规则接入实战CLI 与编辑器banDropDatabase属于静态 lint 能力不需要连接数据库即可触发因此非常适合放进日常开发与 CI 流程。postgres_lsp 的 CLI 提供了check命令位于 crates/pgls_cli/src/commands/check.rs例如pgls check path/to/migrations/check会递归遍历目录下的 SQL 文件遍历逻辑见 crates/pgls_cli/src/execute/walk.rs对每个文件执行解析与规则检查命中banDropDatabase时输出带分类名lint/safety/banDropDatabase的诊断。若你把它配置为error或使用--error-on-warnings包含删库语句的迁移就会被拒绝从而把风险拦截在合入主分支之前。与此同时由于该项目本质是一个 Language Server仓库描述为 A Language Server for Postgres规则同样会通过 LSP 通道在编辑器内实时呈现——你在编辑器中写下drop database xxx;的瞬间即可看到对应的警告提示无需等到 CI 阶段。与其它安全规则的协同在safety规则组中banDropDatabase与一系列禁止危险操作的兄弟规则构成完整的防护矩阵例如banDropTable禁止DROP TABLEbanDropColumn禁止DROP COLUMNbanDropSchema禁止DROP SCHEMAbanDropTrigger、banTruncate、banTruncateCascade分别针对触发器删除与TRUNCATE操作banDeleteWithoutWhere、banUpdateWithoutWhere拦截无 WHERE 条件的全表删除/更新banVacuumFull禁止VACUUM FULL这类高锁操作。这些规则的实现均位于 crates/pgls_analyser/src/lint/safety/模式高度一致。如果你的团队希望对破坏性迁移零容忍可以在配置文件中统一将上述规则批量设为error配合 CI 的check命令形成一道系统性的 SQL 安全门禁。小结banDropDatabase是一条实现极简但价值明确的防护性规则通过解析DropdbStmt节点精准识别删库语句以 Warning 级别提示删除数据库会破坏现有客户端并要求使用者显式确认。由于它默认不随推荐集启用正确接入的关键在于按本文给出的配置结构显式声明其级别再结合 CLIcheck命令或 LSP 实时诊断将其纳入团队工作流——让删库这种高危操作在代码审查阶段就被叫停而不是留到生产环境追悔莫及。【免费下载链接】postgres_lspA Language Server for Postgres项目地址: https://gitcode.com/GitHub_Trending/po/postgres_lsp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考