Ich arbeite an einer Abfrageabstraktion über die WebSQL / Phonegap-Datenbank-API, und ich bin sowohl davon überzeugt als auch bezweifelt, eine fließende API zu definieren, die die Verwendung der Grammatik in natürlicher englischer Sprache imitiert.
Dies lässt sich am einfachsten anhand von Beispielen erklären. Das Folgende sind alle gültigen Abfragen in meiner Grammatik und Kommentare erklären die beabsichtigte Semantik:
//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 basierend auf dem Feedback von Quentin Pradet : Außerdem müsste die API anscheinend sowohl Plural- als auch Singular-Verbformen unterstützen.
//a equals b
find("post").where("foo").equals(1);
//a and b (both) equal c
find("post").where("foo").and("bar").equal(2);
Um der Frage willen nehmen wir an, dass ich hier nicht alle möglichen Konstrukte ausgeschöpft habe. Nehmen wir auch an, dass ich die meisten korrekten englischen Sätze abdecken kann - schließlich ist die Grammatik selbst auf die von SQL definierten Verben und Konjunktionen beschränkt.
Bearbeiten hinsichtlich der Gruppierung : Ein "Satz" ist eine Gruppe, und die Rangfolge ist wie in SQL definiert: von links nach rechts. Mehrere Gruppierungen können mit mehreren where
Anweisungen ausgedrückt werden :
//the conjunctive "and()" between where statements is optional
find("post")
.where("foo").and("bar").equal(2).and()
.where("baz").isLessThan(5);
Wie Sie sehen, hängt die Definition jeder Methode vom grammatikalischen Kontext ab, in dem sie sich befindet. Zum Beispiel das Argument für "Konjunktionsmethoden" or()
und and()
kann entweder weggelassen werden oder auf einen Feldnamen oder einen erwarteten Wert verweisen .
Für mich fühlt sich das sehr intuitiv an, aber ich möchte, dass Sie Ihr Feedback hören: Ist dies eine gute, nützliche API, oder sollte ich zu einer geradlinigeren Implementierung zurückkehren?
Um es festzuhalten: Diese Bibliothek bietet auch eine konventionellere, nicht fließende API, die auf Konfigurationsobjekten basiert.
... where foo = 1 or (bar = 2 and qux = 3)
:?
where("name").equals("foo").or("bar")
als (name=="foo")or bar
. Dann ist es nicht klar, wann ein String ein Literal repräsentiert und wann er einen Spaltennamen präsentiert, ...