Je développe et maintient une bibliothèque d'abstraction de base de données appelée jOOQ, qui vise à "internaliser" SQL en tant que DSL externe en Java. Le but de cette entreprise est de permettre la construction et l'exécution en toute sécurité de tous les éléments de syntaxe SQL possibles du SGBDR le plus populaire. Le DSL interne de jOOQ devient de plus en plus complexe, et j'aimerais l'avoir officiellement. L'idée est que je voudrais être en mesure d'avoir une sorte de définition formelle de SQL en entrée, par exemple. L'entrée peut également être définie en XML ou tout autre méta-langage descriptif.Outil pour "internalisation" d'un DSL externe en Java
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 ::= ...
Une fois que j'ai cette entrée, je voudrais générer à partir de cette entrée un ensemble d'interfaces Java, qui modélisent la syntaxe définie en Java. interfaces exemple serait:
// 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...
}
Avec les interfaces ci-dessus, il sera possible de construire des requêtes SQL en Java, comme jOOQ permet déjà de faire aujourd'hui:
create.select(ONE, TWO).from(TABLE)...
create.selectDistinct(ONE, TWO).from(TABLE)...
// etc...
Aussi, je voudrais excluez certains éléments de syntaxe pour certaines versions spécifiques. Par exemple. Lorsque je crée jOOQ pour une utilisation exclusive avec MySQL, il n'est pas nécessaire de prendre en charge l'instruction SQL MERGE.
Existe-t-il une bibliothèque existante implémentant une telle approche générale afin d'internaliser formellement et DSL externe à Java? Ou devrais-je rouler le mien?
Je regarderais [ANTLR] (http://www.antlr.org/), il a plusieurs grammaires SQL, et [cette version de PLSQL] (http://www.antlr.org/grammar/1279318813752 /PLSQL.g) semble prometteur –
@Sean, je ne suis pas sûr si j'ai bien compris ANTLR, mais c'est pour l'analyse et la vérification syntaxique des chaînes, non? Mais ce que je veux, c'est "l'internalisation DSL".La sortie devrait être un ensemble d'interfaces, qui donnent l'impression que SQL pourrait être écrit nativement en Java (ce que jOOQ fait déjà aujourd'hui). Je vais mettre à jour la question. –
oui, mais vous pouvez utiliser la grammaire SQL pour créer des classes Java aussi –