Majstruję przy abstrakcji zapytań dotyczących interfejsu API bazy danych WebSQL / Phonegap, i jestem przekonany, że mam wątpliwości co do zdefiniowania płynnego interfejsu API, który naśladuje użycie naturalnej gramatyki języka angielskiego.
Najłatwiej to wyjaśnić za pomocą przykładów. Poniżej znajdują się wszystkie poprawne zapytania w mojej gramatyce, a komentarze wyjaśniają zamierzony semantyczny:
//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);
Edycja na podstawie opinii Quentin Pradet : Ponadto wydaje się, że interfejs API musiałby obsługiwać zarówno formy liczby mnogiej, jak i liczby pojedynczej, więc:
//a equals b
find("post").where("foo").equals(1);
//a and b (both) equal c
find("post").where("foo").and("bar").equal(2);
Dla celów pytania załóżmy, że nie wyczerpałem tutaj wszystkich możliwych konstrukcji. Załóżmy również, że potrafię objąć najbardziej poprawne zdania angielskie - w końcu sama gramatyka jest ograniczona do czasowników i koniugatów zdefiniowanych przez SQL.
Edycja dotycząca grupowania : jedno „zdanie” to jedna grupa, a pierwszeństwo jest zdefiniowane w SQL: od lewej do prawej. Wiele grupowań można wyrazić za pomocą wielu whereinstrukcji:
//the conjunctive "and()" between where statements is optional
find("post")
.where("foo").and("bar").equal(2).and()
.where("baz").isLessThan(5);
Jak widać, definicja każdej metody zależy od kontekstu gramatycznego, w którym się znajduje. Na przykład argument „metody koniunkcji” or()i and()można go pominąć lub odwołać się do nazwy pola lub oczekiwanej wartości.
Moim zdaniem wydaje się to bardzo intuicyjne, ale chciałbym usłyszeć Twoją opinię: czy jest to dobry, przydatny interfejs API, czy powinienem cofnąć się do prostszej implementacji?
Dla przypomnienia: ta biblioteka zapewni również bardziej konwencjonalny, nie płynny interfejs API oparty na obiektach konfiguracyjnych.
where("name").equals("foo").or("bar")jak (name=="foo")or bar. Wtedy nie jest jasne, kiedy ciąg reprezentuje literał, a kiedy przedstawia nazwę kolumny, ...