Предлагаю на суд общественности реализацию наглядного построителя текстовых запросов к внешним БД.
Преамбула
Наверняка многим приходилось сталкиваться с задачей формирования внешних SQL-запросов, и наверняка мало кто назовет такую задачу приятной. Особенно, если запрос длинный, "многоэтажный", а еще хуже - если приходится многократно дорабатывать такой хардкод. Разбираться во всех этих strfmt(...) (иногда вложенных) с десятками параметров - муторно. Того и гляди накосячишь.
Для пущей безопасности этого процесса в Аксапте есть семейство классов
SQLBuilder*. Но на мой взгляд, код, написанный с его помощью, тоже получается громоздким.
В итоге появилась идея, набросок которой я тут публикую.
Что умеет SimpleQueryBuilder (SQB)?
- Формировать строку SQL-запроса путем последовательного вызова методов, соответствующих ключевым словам SQL. Например,
X++:
selectStr = ...select(...).from(...).where(...)...toString();
insertStr = ...insert(...).into(...).values(...)...toString();
При этом никаких соединений с БД он не устанавливает, сформированный запрос не выполняет. Только конкатенация текста.
- Умеет "подсказывать" синтаксис запроса с помощью IntelliSense (см. скриншот), ограничивая текущий контекст через набор интерфейсов. Например, после метода select() обязательно должен быть вызван from() (без этого просто не получится "достать" финальную строку). Аналогично, where() не получится впихнуть после order_by(), и т.п.
- В текущей версии в общих чертах реализован только оператор SELECT (но далеко не все его нюансы). INSERT, UPDATE и DELETE - отсутствуют.
Основные плюсы- Для относительно простых запросов код выглядит кучеряво Для сложных - пока не пробовал.
- Легко начать пользоваться: пишем SimplyQueryBuilder::construct(), ставим точку, и дальше - все интуитивно понятно.
- Неожиданный бонус от редактора Х++ - подсветка "синтаксиса" (опять см. скриншот).
- Снижается риск ошибиться в "скелете" запроса (забыть "кусок", не туда скопипастить), так как он весь выписывается, по сути, в одну строку кода, которая либо скомпилируется, либо нет.
- За счет того, что практически все параметры - строковые, в конечном итоге можно получить любой синтаксис (не предусмотренный в наборе методов).
Минусы
- Строки, переданные в качестве параметров никак не проверяются. То есть нет никаких гарантий валидности итогового запроса.
- Вложенные выражения (условия, подзапросы) не поддаются красивому выстраиванию в цепочку методов, следовательно их придется конструировать отдельными частями.
- Предполагаю, что дорабатывать SQB под свои нужды будет неудобно из-за кучи переплетенных интерфейсов, которые в ряде случаев придется развязывать и связывать по-новому.
- Ваши замечания? (критика приветствуется)
Во вложении - проект с набором классов и интерфейсов (у интерфейсов префикс
SQB_*). Примеры использования - в классе
SQBTutorial. Делалось и проверялось на AX2009, в 2012 скорее всего тоже заработает.
PS. Еще точнее - изначально делалось даже на Java для других нужд, а потом любопытство заставило попробовать адаптировать под Аксапту)