Я замислююся над абстракцією запитів щодо API WebSQL / Phonegap Database, і мені здається, що я приваблюю та сумніваюсь, визначаючи вільний 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
. Тоді незрозуміло, коли рядок представляє буквальне значення, а коли в ньому представлено назву стовпця, ...