Я возился с абстракцией запросов через 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
. Тогда неясно, когда строка представляет литерал, а когда она представляет имя столбца, ...