3

我正在开发和维护一个名为jOOQ的数据库抽象库,它旨在将 SQL 作为外部 DSL “内部化”到 Java 中。这项工作的目标是允许类型安全地构造和执行最流行的 RDBMS 的所有可能的 SQL 语法元素。jOOQ 的内部 DSL 变得越来越复杂,我想正式掌握它。这个想法是我希望能够将某种形式的 SQL 定义作为输入,例如

select ::= subquery [ for-update-clause ]
subquery ::= SELECT [ { ALL | DISTINCT | UNIQUE } ] select-list 
           [ FROM table-reference ] ..
select-list ::= expression [ [ AS ] alias ] [, expression ... ]
expression ::= ...
alias ::= ...
table-reference ::= ...

输入也可以用 XML 或任何其他描述性元语言定义。一旦我有了那个输入,我想从那个输入生成一组 Java 接口,这些接口对 Java 中定义的语法进行建模。示例接口是:

// The first "step" of query creation is modelled with this interface
interface Select0 {

    // The various SELECT keywords are modelled with methods
    // returning the subsequent generated syntax-element
    Select1 select(Expression...);
    Select1 selectAll(Expression...);
    Select1 selectDistinct(Expression...);
    Select1 selectUnique(Expression...);
}

// The second "step" of query creation is optional, hence it
// inherits from the third "step"
interface Select1 extends Select2 {

    // Here a FROM clause may be added optionally
    Select2 from(TableReference...);
}

// To keep it simple, the third "step" is the last for this example
interface Select2 extends SelectEnd {
    // WHERE, CONNECT BY, PIVOT, UNPIVOT, GROUP BY, HAVING, ORDER BY, etc...
}

有了上面的接口,就可以在 Java 中构造 SQL 查询,就像今天 jOOQ 已经允许做的那样:

create.select(ONE, TWO).from(TABLE)...
create.selectDistinct(ONE, TWO).from(TABLE)...
// etc...

另外,我想排除某些特定构建的一些语法元素。例如,当我为 MySQL 专门构建 jOOQ 时,不需要支持 SQL MERGE 语句。

是否有任何现有的库实现了这种通用方法,以便将 DSL 正式内部化和外部化到 Java?还是我应该自己滚动?

4

1 回答 1

1

您真正想做的是将通用 SQL 转换为对内部 API 的调用。似乎有道理。

为此,您需要一个“通用 SQL”解析器,以及从该解析器生成代码的方法。通常你需要解析器来构建一个抽象语法树,你几乎需要一个符号表(这样你就知道什么是表名,什么是列名,以及这些列名是来自表 A 还是表 B,所以在某个地方您需要访问定义数据模型的 SQL DDL.... 这需要您再次解析 SQL :)。

使用 AST 和符号表,您可以通过多种方式生成代码,但一个简单的方法是在遇到它们时遍历 AST 和 translate 构造。这将不允许构建优化查询;这需要更复杂的代码生成,但如果您提供的适当 API 函数支持,我希望它就足够了。

实际的代码生成可以通过打印 Java 文本来完成;如果你走 ANTLR 路线,你将不得不做这样的事情。另一种方法是将 SQL 代码片段(作为 AST)从字面上转换为 Java 代码片段(作为 AST)。后一种方案为您提供了更多控制权(如果它们是 AST,您实际上可以对 Java 代码片段进行转换),如果操作正确,可以通过代码生成工具进行检查。

我们的DMS Software Reengineering Toolkit将为此奠定良好的基础。DMS 为构建翻译工具提供了一个生态系统,包括强大的解析器机制、符号表支持、表面语法模式导向的翻译规则,并具有通用 SQL(SQL 2011,标准)作为可用的、经过测试的解析器,以及 Java,用于代码生成端。

于 2011-12-02T16:31:53.697 回答