Por coincidência eu estou desenvolvendo um framework SQL e precisarei fazer algo nesse sentido.
Ainda não tenho idéias muito concretas sobre a melhor forma de fazer, mas já tenho umas idéias para começar a testar e se tudo der certo, começarei com isso no final da semana q vem.
A idéia que tive é utilizar interfaces com repetição de métodos (o código vai ficar cheio de interface “inútil”, mas não consegui pensar em nada melhor p/ restringir opções). Ex:
Tabela: Usuario(id integer, nome varchar2(100))
Comando do meu framework (óbvio que o seu vai ser diferente, basta adaptar):
SelectStatement ss = select(usuario.name).from(usuario).where(usuario.id.equal(2));
Nesse caso, pensando na árvore de possibilidades ficaria o seguinte:
select ->from (obrigatório from após select)
from ->fim, where, orderBy, having, innerJoin, etc… (opcional, pode ter ou não uma dessas opções para retornar o statement)
Sendo assim, eu teria que criar uma interface para o select:
public interface SelectOptions {
SelectWhereOptions from(Table t);
}
E outra para o where:
public interface SelectWhereOptions{
SelectOrderBy orderBy(...);
SelectHaving having(...);
SelectInnerJoin innerJoin(...);
SelectStatement getStatement();
...
}
O principal problema que vejo nessa abordagem está quando o select deve retornar o statement após o where(), pois eu teria que adicionar algum método especial (getStatement()) só para obter o Statement. Não consegui melhorar a idéia a ponto de travar as opções e não ter que invocar essa função no final do select. mas claro, estou aberto para novas idéias!
No exemplo, o uso final ficaria assim:
SelectStatement ss = select(usuario.name).from(usuario).where(usuario.id.equal(2)).getStatement();
Espero ter ajudado