Estoy jugando con una abstracción de consulta sobre la API de base de datos WebSQL / Phonegap, y me siento atraído y dudoso por definir una API fluida que imite el uso de la gramática del idioma inglés natural.
Puede ser más fácil explicar esto a través de ejemplos. Las siguientes son todas las consultas válidas en mi gramática, y los comentarios explican la semántica prevista:
//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);
Edición basada en los comentarios de Quentin Pradet : Además, parece que la API debería admitir formas verbales tanto en plural como en singular, por lo que:
//a equals b
find("post").where("foo").equals(1);
//a and b (both) equal c
find("post").where("foo").and("bar").equal(2);
En aras de la pregunta, supongamos que no he agotado todas las construcciones posibles aquí. Supongamos también que puedo cubrir la mayoría de las oraciones correctas en inglés; después de todo, la gramática en sí misma se limita a los verbos y conjunciones definidos por SQL.
Editar con respecto a la agrupación : una "oración" es un grupo, y la precedencia es como se define en SQL: de izquierda a derecha. Se pueden expresar múltiples agrupaciones con múltiples where
declaraciones:
//the conjunctive "and()" between where statements is optional
find("post")
.where("foo").and("bar").equal(2).and()
.where("baz").isLessThan(5);
Como puede ver, la definición de cada método depende del contexto gramatical en el que se encuentre. Por ejemplo, el argumento de "métodos de conjunción" or()
y and()
puede omitirse o referirse a un nombre de campo o valor esperado.
Para mí, esto se siente muy intuitivo, pero me gustaría que escuche sus comentarios: ¿es esta una API buena y útil, o debería retroceder para una implementación más sencilla?
Para el registro: esta biblioteca también proporcionará una API más convencional y no fluida basada en objetos de configuración.
fuente
... where foo = 1 or (bar = 2 and qux = 3)
:?where("name").equals("foo").or("bar")
como(name=="foo")or bar
. Entonces no está claro cuándo una cadena representa un literal, y cuando presenta un nombre de columna, ...