Je suis en train de bricoler une abstraction de requête sur l'API WebSQL / Phonegap Database, et je me trouve à la fois attiré et douteux de définir une API fluide qui imite l'utilisation de la grammaire naturelle de la langue anglaise.
Il pourrait être plus facile d'expliquer cela à l'aide d'exemples. Les requêtes suivantes sont toutes valides dans ma grammaire et les commentaires expliquent la sémantique voulue:
//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);
Edit basé sur les commentaires de Quentin Pradet : En outre, il semble que l'API devrait prendre en charge les formes verbales plurielles et singulières, donc:
//a equals b
find("post").where("foo").equals(1);
//a and b (both) equal c
find("post").where("foo").and("bar").equal(2);
Par souci de question, supposons que je n'ai pas épuisé toutes les constructions possibles ici. Supposons également que je puisse couvrir la plupart des phrases anglaises correctes - après tout, la grammaire elle-même est limitée aux verbes et aux conjonctions définis par SQL.
Modifier concernant le regroupement : une "phrase" est un groupe et la priorité est telle que définie dans SQL: de gauche à droite. Plusieurs regroupements peuvent être exprimés avec plusieurs where
déclarations:
//the conjunctive "and()" between where statements is optional
find("post")
.where("foo").and("bar").equal(2).and()
.where("baz").isLessThan(5);
Comme vous pouvez le voir, la définition de chaque méthode dépend du contexte grammatical il est. Par exemple l'argument « méthodes de conjonction » or()
et and()
peut soit être laissé de côté, ou se référer à un nom de champ ou valeur attendue.
Pour moi, cela semble très intuitif, mais j'aimerais que vous entendiez vos commentaires: est-ce une bonne API utile, ou devrais-je revenir sur une mise en œuvre plus directe?
Pour mémoire: cette bibliothèque fournira également une API plus conventionnelle et non fluide basée sur des objets de configuration.
... where foo = 1 or (bar = 2 and qux = 3)
:?
where("name").equals("foo").or("bar")
comme (name=="foo")or bar
. Ensuite, on ne sait pas quand une chaîne représente un littéral, et quand elle présente un nom de colonne, ...