Estou mexendo com uma abstração de consulta na API WebSQL / Phonegap Database, e me sinto atraído e duvidoso por definir uma API fluente que imita o uso da gramática natural da língua inglesa.
Pode ser mais fácil explicar isso por meio de exemplos. A seguir, todas as consultas válidas na minha gramática e os comentários explicam a semântica pretendida:
//find user where name equals "foo" or email starts with "foo@"
find("user").where("name").equals("foo").and("email").startsWith("foo@")
//find user where name equals "foo" or "bar"
find("user").where("name").equals("foo").or("bar");
//find user where name equals "foo" or ends with "bar"
find("user").where("name").equals("foo").or().endsWith("bar");
//find user where name equals or ends with "foo"
find("user").where("name").equals().or().endsWith("foo");
//find user where name equals "foo" and email is not like "%contoso.com"
find("user").where("name").equals("foo").and("email").is().not().like("%contoso.com");
//where name is not null
find("user").where("name").is().not().null();
//find post where author is "foo" and id is in (1,2,3)
find("post").where("author").is("foo").and("id").is().in(1, 2, 3);
//find post where id is between 1 and 100
find("post").where("id").is().between(1).and(100);
Edite com base no feedback de Quentin Pradet : Além disso, a API teria que suportar formas verbais no plural e no singular, portanto:
//a equals b
find("post").where("foo").equals(1);
//a and b (both) equal c
find("post").where("foo").and("bar").equal(2);
Por uma questão de dúvida, vamos supor que eu não tenha esgotado todas as construções possíveis aqui. Suponhamos também que eu possa cobrir as frases em inglês mais corretas - afinal, a gramática em si é limitada aos verbos e conjurações definidos pelo SQL.
Editar em relação ao agrupamento : uma "sentença" é um grupo e a precedência é como definida em SQL: da esquerda para a direita. Vários agrupamentos podem ser expressos com várias where
instruções:
//the conjunctive "and()" between where statements is optional
find("post")
.where("foo").and("bar").equal(2).and()
.where("baz").isLessThan(5);
Como você pode ver, a definição de cada método depende do contexto gramatical em que está. Por exemplo, o argumento para "métodos de conjunção" or()
e and()
pode ser deixado de fora, ou referir-se a um nome de campo ou valor esperado.
Para mim, isso parece muito intuitivo, mas gostaria que você ouvisse seus comentários: essa é uma API boa e útil ou devo recuar para uma implementação mais direta?
Para o registro: essa biblioteca também fornecerá uma API mais convencional e não fluente, com base em objetos de configuração.
where("name").equals("foo").or("bar")
como (name=="foo")or bar
. Então não é claro quando uma string representa um literal, e quando apresenta um nome de coluna, ...