Я возился с абстракцией запросов через API баз данных WebSQL / Phonegap, и я чувствую себя неуверенно и не в силах определить свободный API, который имитирует использование естественной грамматики английского языка.
Это может быть проще объяснить с помощью примеров. Следующее - все допустимые запросы в моей грамматике, и комментарии объясняют предполагаемую семантику:
//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);
Редактирование на основе отзывов Квентина Праде : Кроме того, похоже, что API должен был бы поддерживать как формы множественного числа, так и формы единственного числа, поэтому:
//a equals b
find("post").where("foo").equals(1);
//a and b (both) equal c
find("post").where("foo").and("bar").equal(2);
Ради вопроса, давайте предположим, что я не исчерпал все возможные конструкции здесь. Давайте также предположим, что я могу охватить большинство правильных английских предложений - в конце концов, сама грамматика ограничена глаголами и конъюнкциями, определенными в SQL.
Редактировать в отношении группировки : одно «предложение» - это одна группа, и приоритет такой, как определено в SQL: слева направо. Несколько группировок могут быть выражены несколькими whereоператорами:
//the conjunctive "and()" between where statements is optional
find("post")
.where("foo").and("bar").equal(2).and()
.where("baz").isLessThan(5);
Как вы можете видеть, определение каждого метода зависит от грамматического контекста он находится. Например, аргумент «метода сопряжения» or()и and()может быть либо опущено, либо ссылаться на имя поля или ожидаемое значение.
Для меня это кажется очень интуитивным, но я хотел бы, чтобы вы услышали ваши отзывы: это хороший, полезный API, или я должен вернуться к более простой реализации?
Для справки: эта библиотека также предоставит более обычный, не беглый API на основе объектов конфигурации.
where("name").equals("foo").or("bar")как (name=="foo")or bar. Тогда неясно, когда строка представляет литерал, а когда она представляет имя столбца, ...