资讯详情

资讯详情

DBeaver 如何为 SQL 方言注册自定义 LSM 分析器

DBeaver 如何为 SQL 方言注册自定义 LSM 分析器【免费下载链接】dbeaverFree universal database tool and SQL client项目地址: https://gitcode.com/GitHub_Trending/db/dbeaver当你要为 DBeaver 支持的某个数据库扩展 SQL 解析能力——例如让方言支持特殊的标识符引用符号或者改用数据库专属的 parser 与 lexer——就需要通过扩展点org.jkiss.dbeaver.lsm.dialectSyntax为对应的 SQL 方言注册一个自定义的 LSM 分析器analyzer。整个机制基于 Eclipse OSGI 扩展点插件在自己的plugin.xml中声明方言与分析器工厂的对应关系运行时由LSMDialectRegistry加载并按方言类解析出工厂。本文基于 DBeaver 仓库中的 LSM 模块说明文档、扩展点定义、扩展点 schema 以及 LSMDialectRegistry 源码整理给出从实现分析器到完成注册的完整路径和验证方式。先理解注册链路注册流程的关键事实均来自上述文档与源码扩展点定义。扩展点org.jkiss.dbeaver.lsm.dialectSyntax名称 Dialect Syntax Analyzer Provider在 org.jkiss.dbeaver.model.lsm 的 plugin.xml 中声明其元素结构由 schema 文件 org.jkiss.dbeaver.lsm.dialectSyntax.exsd 约束lsmDialect元素必须提供analyzerFactoryClass属性必填字符串每个lsmDialect可包含多个appliesTo子元素每个appliesTo必须提供dialectClass属性必填schema 中标注基于SQLDialect类型。加载与解析。LSMDialectRegistry 是单例首次getInstance()时从 Eclipse 扩展注册表读取所有lsmDialect配置项通过createExecutableExtension(analyzerFactoryClass)实例化工厂再把每个appliesTo的dialectClass映射为「方言类 → 工厂」的条目。解析顺序。getAnalyzerFactoryForDialect从当前方言的具体类开始查找未命中就沿其父类逐级上溯只要方言类层级中任一节点有注册就能取到工厂。这意味着注册在具体方言类上的分析器优先于注册在父类上的通用分析器。内置兜底。org.jkiss.dbeaver.model.sql 的 plugin.xml 已经注册了一条通用映射SQLStandardAnalyzerFactory应用于org.jkiss.dbeaver.model.impl.sql.AbstractSQLDialect。SQLStandardAnalyzer使用通用 SQL 语法的 parser 与 lexer适用于大多数没有特殊设置的数据库。你的自定义注册就是在这条兜底之上做覆盖。第一步实现分析器根据需求不同分两种情况均来自 README 的说明分支 A复用通用语法只调整 parser 配置。继承SQLStandardAnalyzer重写prepareParser钩子该钩子定义在LSMAnalyzerImpl中签名为prepareParser(STMSource source, STMErrorListener errorListener)。README 给出的例子是让解析器支持方括号引用标识符public class SQLiteSQLAnalyzer extends SQLStandardAnalyzer { NotNull Override protected SQLStandardParser prepareParser(NotNull STMSource source, Nullable STMErrorListener errorListener) { SQLStandardParser parser super.prepareParser(source, errorListener); parser.setIsSupportSquareBracketQuotation(true); return parser; } }分支 B使用数据库专属的 parser 和 lexer。README 指出当「需要通用语法加特定 parser 配置或想使用数据库专属的 parser 与 lexer」时应通过扩展点描述相应的专属实现即自行实现LSMAnalyzer接口当前仓库中的接口签名为STMTreeRuleNode parseSqlQueryTree(STMSource source, STMErrorListener errorListener)在分析器中封装 parser 与 lexer 的创建和解析过程。错误处理行为由传入的STMErrorListener决定按 README 说明使用STMLoggingErrorListener记录解析错误使用STMSkippingErrorListener则跳过错误不做处理。第二步实现分析器工厂appliesTo绑定的是方言类而分析器实例需要一个带上下文的创建入口因此必须提供一个工厂类实现 LSMAnalyzerFactory 接口。当前仓库中该接口的方法签名为public interface LSMAnalyzerFactory { NotNull LSMAnalyzer createAnalyzer(NotNull LSMAnalyzerParameters parameters); }其中 LSMAnalyzerParameters 携带解析所需的方言上下文标识符引用对knownIdentifierQuotes、SQL 参数与匿名参数开关、匿名参数标记字符、命名参数前缀、变量开关等可用其静态方法forDialect(SQLDialect dialect, SQLSyntaxManager syntaxManager)从方言与语法管理器构建。工厂示例类名以你实现的为准public class SQLiteAnalyzerFactory implements LSMAnalyzerFactory { Override public LSMAnalyzer createAnalyzer(NotNull LSMAnalyzerParameters parameters) { return new SQLiteSQLAnalyzer(parameters); } }注意README 中给出的旧示例是createAnalyzer(SQLDialect dialect)单参数签名与仓库当前接口定义不一致。以仓库当前的LSMAnalyzerParameters签名为准SQLStandardAnalyzerFactory等现有实现均使用它。第三步在 plugin.xml 中注册在你自己的插件例如数据库驱动插件的plugin.xml中添加扩展analyzerFactoryClass填工厂类的全限定名dialectClass填目标方言类的全限定名extension pointorg.jkiss.dbeaver.lsm.dialectSyntax lsmDialect analyzerFactoryClasscom.example.ext.sqlite.model.SQLiteAnalyzerFactory appliesTo dialectClasscom.example.ext.sqlite.model.SQLiteSQLDialect/ /lsmDialect /extension上面两个类名是占位符需替换为你实际实现的工厂类和方言类全限定名方言类必须是org.jkiss.dbeaver.model.sql.SQLDialect的子类schema 的basedOn约束。README 中展示的通用语法注册写法与 model.sql/plugin.xml 中的实际注册基本一致区别仅在appliesTo的目标类README 示例写作BasicSQLDialect实际代码注册在AbstractSQLDialect上后者覆盖范围更大以实际代码为准。如果你希望某个方言走通用分析器不做任何自定义直接注册SQLStandardAnalyzerFactory即可无需自己写分析器extension pointorg.jkiss.dbeaver.lsm.dialectSyntax lsmDialect analyzerFactoryClassorg.jkiss.dbeaver.model.lsm.sql.dialect.SQLStandardAnalyzerFactory appliesTo dialectClassorg.jkiss.dbeaver.model.impl.sql.BasicSQLDialect/ /lsmDialect /extension验证注册是否生效文档没有给出独立的验证命令可依据LSMDialectRegistry源码中的行为做判断解析失败最常见的错误现象。当某方言的整个类层级都找不到任何lsmDialect注册时getAnalyzerFactoryForDialect抛出IllegalStateException消息为Failed to resolve LSMAnalyzer for 方言名 dialect. Illegal database driver configuration.。看到这条错误说明你的插件没有把appliesTo指向该方言类或其父类检查dialectClass拼写即可。注册失败。registerLsmDialect中如果createExecutableExtension抛CoreException工厂类无法实例化等会记录错误日志Failed to register LSM dialect analyzerFactoryClass 属性值。看到这条日志时核对工厂类是否为公有的可实例化类、全限定名是否正确。正向判断。两条负向日志都不出现、且上述IllegalStateException不再抛出即说明方言已能解析到工厂调用分析器的parseSqlQueryTree传入STMSource与STMErrorListener应得到解析树节点README 描述为STMTreeNode类型当前接口返回的是其子类型STMTreeRuleNode。限制与注意事项一个lsmDialect可以写多个appliesTo把同一个工厂应用到多个方言类但每个方言类到工厂的映射在注册表中只保留最后写入的条目重复注册同一方言类时以注册顺序为准建议一个方言类只注册一次。解析按「具体方言类 → 父类」的顺序取第一个命中项因此把自定义分析器注册在具体方言类上即可覆盖内置的AbstractSQLDialect兜底无需改动 model.sql 的 plugin.xml。本文所有类名、包名均取自当前仓库README 中的个别示例工厂旧签名、BasicSQLDialect目标类与当前代码存在出入已在正文中标注以源码为准。【免费下载链接】dbeaverFree universal database tool and SQL client项目地址: https://gitcode.com/GitHub_Trending/db/dbeaver创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →