Я занимаюсь разработкой и обслуживанием библиотеки абстракции базы данных под названием jOOQ , которая направлена на "интернализацию" SQL как внешнего DSL в Java. Целью этого усилия является обеспечение безопасного создания типов и выполнения всех возможных элементов синтаксиса SQL наиболее популярных СУБД. Внутренний DSL в jOOQ становится все более и более сложным, и я хотел бы получить его официально. Идея заключается в том, что я хотел бы иметь какое-то формальное определение 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...
}
С помощью вышеупомянутых интерфейсов можно будет создавать запросы SQL в Java, как jOOQ уже позволяет делать сегодня:
create.select(ONE, TWO).from(TABLE)...
create.selectDistinct(ONE, TWO).from(TABLE)...
// etc...
Кроме того, я бы хотел исключить некоторые элементы синтаксиса для некоторых конкретных сборок. Например. когда я собираю jOOQ для эксклюзивного использования с MySQL, нет необходимости поддерживать оператор SQL MERGE.
Существует ли какая-либо существующая библиотека, реализующая такой общий подход для формальной интернализации и внешнего DSL в Java? Или я должен свернуть свой собственный?