- Содержание
- Описание и назначение
- Формат запроса
- Структура запроса
- Типы математических операторов
- Типы логических операторов
- Блок fields
- Блок conditions
- Блок conditions (с аргументами)
- Блок restrictions
- TO-DO
Пакет компилятора SQaLice предназначен для гибкой обработки запросов к БД на PostgreSQL в проектах с применением go-swagger. SQaLice позволяет запрашивать конкретный набор полей из установленного target, фильтровать, сортировать и ограничивать получаемый набор строк.
В функцию-компилятор Compile в качестве аргумента передается modelsMap, содержащая информацию о полях моделей проекта, используемых для обработки целевого SQL кода. Рекомендуется формировать данную map динамически, например в init модуля при запуске проекта, что обеспечит консистентность сгенерированных посредством go-swagger моделей и данных, передаваемых в компилятор через map. Для этого можно использовать функцию FormDinamicModel. Также в этом случае в swagger-модели не должно быть вложенных моделей, иначе произойдут некорректное считывание тегов полей и ошибки формирования полей.
UPDATE 0.4 Начиная с данной версии считывание полей модели, используемых при компиляции запроса, а также при изменении исходной строки-аргумента params внесено внутрь целевых функций и не нуждается в отдельном формировании. В качестве аргумента model в Compile следует передавать структуру-модель, на которую планируется считывание данных из БД.
UPDATE 0.4.1 Начиная с данной версии компилятор поддерживает считывание тегов полей из вложенных структур
UPDATE 0.5.0 Запрос компиляции Compile разделен на основной запрос Get и поисковый Search. Примеры вызовов запроса Search описаны в отдельном блоке
UPDATE 0.7.1 Добавлена возможность раздельного формирования запроса и параметров блока условий для постобработки и безопасной передачи в стандартный пакет GO - database/sql. Данная опция активируется при вызове Get или Search и передаче withArgs = true. Примеры запросов сформированных запросов и аргументов приведены в отдельном блоке этого документа.
В случае обращения к компилятору SQaLice для генерации основного Get запроса все параметры целевого запроса должны содержаться в аргументе params. В target передается целевая таблица или view, к которой осуществляется запрос и которая используется при указании динамической модели.
Аргумент params при парсинге запроса внутри Get разделяется на 3 блока - fields, conditions, restrictions.
http://url/.../query=ID,title,updatedAt?ID==10||ID==8?ID,desc,2,0
В случае отсутствия необходимости в указании одного из этих блоков, приведенное форматирование должно сохраняться.
http://url/.../query=ID,title,updatedAt??ID,desc,2,0
Запрос без указания условий в 3 блоках одновременно не рекомендуется, так как может привести к неожиданным ошибкам.
SQaLice поддерживает следующие математические операторы:
Оператор | SQaLice | PG |
---|---|---|
РАВНО | == | = |
НЕ РАВНО | != | != |
МЕНЬШЕ | < | < |
МЕНЬШЕ ИЛИ РАВНО | <= | <= |
БОЛЬШЕ | > | > |
БОЛЬШЕ ИЛИ РАВНО | >= | >= |
СОДЕРЖИТ | >> | && |
ВКЛЮЧАЕТ | ->> | ->> |
http://url/.../query=ID,name?ID!=10?,,2,0
SQaLice поддерживает следующие логические операторы:
Оператор | SQaLice | PG |
---|---|---|
И | * | AND |
ИЛИ | Двойная прямая черта | OR |
http://url/.../query=?(ID==8*title==Тест)||ID==10?
Для получения всех полей из целевой SQL, содержащиеся в структуре модели modelsMap, нужно передавать данный блок пустым.
http://url/.../query=?ID==10||ID==8?ID,desc,2,0
Для получения конкретных полей, в поле fields необходимо передавать название поля в формате json с запятыми в качестве разделителя и без пробелов.
ID,title,createdAt?
http://url/.../query=ID?ID>=1?ID,desc,10,0
При передаче некорректного названия поля, SQaLice вернет ошибку:
"[SQaLice] Passed unexpected field name in select"
В данном блоке возможно указание условий получения записей. Допускается передача пустого блока conditions, в таком случае происходит выборка без дополнительных условий.
http://url/.../query=ID,title,createdAt??ID,asc,10,0
Условия должны разделяться допустимыми математическими операторами и не содержать пробелов.
?title==Тест?
Разделение нескольких условий осуществляется с помощью допустимых логических операторов, так же без пробелов. Кроме того могут быть использованы условные блоки в круглых скобках. Количество таких блоков не ограничено.
(ID>8*ID<10)||title==Тест
ВАЖНО! При использовании сочетания условных блоков в скобках и без, блок без скобок должен указываться последним, как на приведенном выше примере. В противном случае запрос будет некорректным.
http://url/.../query=title?ID==7,8,9?
select q.title from v_test q where q.id = any(array[7,8,9])
http://url/.../query=title?ID!=7,8,9?
select q.title from v_test q where not q.id = any(array[7,8,9])
При передаче условной конструкции с неверным логическим оператором, SQaLice вернет ошибку:
"[SQaLice] Unsupported operator in condition"
При передаче условной конструкции с неверным названием поля, SQaLice вернет ошибку:
"[SQaLice] Passed unexpected field name in condition"
При передаче условной конструкции с массивом и неверным оператором, SQaLice вернет ошибку:
"[SQaLice] Passed unexpected operator in array condition - <="
UPDATE 0.5.8
Для операторов == и != возможно указание нескольких значений через запятую, без пробелов. В таком случае происходит отбор строк по переданному массиву.
UPDATE 0.6.3
Для запроса нулевых значений необходимо передавать значение null или NULL c оператором РАВНО или НЕ РАВНО
http://url/.../query=ID?ID!=null*title==NULL?
select q.id from v_test q where q.id is not null and q.title is null
При передаче некорректного для NULL условия оператора, SQaLice вернет ошибку:
"[SQaLice] Passed unexpected operator in NULL condition - <"
UPDATE 0.7.1
Добавлен блок раздельного получения параметров и тела запроса к БД. В блоке условий запроса значения величин заменяются аргументами-плейсхолдерами ($1, $2 и т.д). Сами аргументы выдаются в ответе компилятора массивом, по последовательному порядку плейсхолдеров запроса.
http://url/.../query=?ID==1?
select q.id, q.content, q.count, q.extra_field, q.is_bool, q.one_more_field from v_test q where q.id = $1
[1]
http://url/.../query=ID?(ID==1,2,3||content!=new)*isBool==true?ID,desc,10,0
select q.id from v_test q where (q.id = any(array[$1]) or q.content != $2) and q.is_bool = $3 order by q.id desc limit 10 offset 0
["1,2,3", "'new'", true]
http://url/.../query=isBool?(ID==null||content!=new)*(isBool==true)?ID,desc,10,0
select q.is_bool from v_test q where (q.id is null or q.content != $1) and (q.is_bool = $2) order by q.id desc limit 10 offset 0
[nil, "'new'", true]
http://url/.../query=ID?content==content^^smth?
select q.id from v_test q where q.content->>'content' = $1
["'smth'"]
В данном блоке возможно указание ограничений конечной выборки. Допускается передача пустого блока ограничений, в таком случае SQaLice не накладывает дополнительных условий на выборку.
http://url/.../query=ID,title,createdAt?ID>1?
При заполнении ограничений в блоке restrictions необходимо соблюдать порядок параметров блока, разделять их запятыми и не использовать пробелы
Порядок указания ограничений
Параметр | Допустимые значения |
---|---|
Поля сортировки | Поля, переданные в fieldsMap |
Порядок сортировки | asc, desc |
Лимит | Целое число >= 0 |
Оффсет | Целое число >= 0 |
http://url/.../query=ID,title,createdAt?ID>1?ID,asc,10,0
http://url/.../query=ID,title,createdAt?ID>1?ID|isBool,asc,10,0
http://url/.../query=ID,title,createdAt?ID>1?,,10,0
При передаче некорректного названия поля сортировки, SQaLice вернет ошибку:
"[SQaLice] Unexpected selection order field"
При передаче некорректного порядка сортировки, SQaLice вернет ошибку:
"[SQaLice] Unexpected selection order"
При передаче некорректного лимита, SQaLice вернет ошибку:
"[SQaLice] Unexpected selection limit"
При передаче некорректного оффсета, SQaLice вернет ошибку:
"[SQaLice] Unexpected selection offset"
TO-DO | Статус |
---|---|
Покрытие тестами | Выполнено |
Обработка сложных условий (вложенность, дополнительные операторы) | Выполнено частично |
Снятие ограничений порядка условий | Не выполнено |
Функция Search обеспечивает компиляцию запроса с LIKE-поиском по переданной строке и параметру. Параметры компиляции запроса (выборка полей, условия, ограничения) работают аналогично основному запросу Get. Функция поиска дополнительно принимает строковый параметр - searchParams, содержащий условные выражения, аналогичные блоку условий основного запроса. Использование логических операторов также аналогично основному запросу Поле и значение внутри условной конструкции требуется разделять оператором ~~. В случае использования иных операторов, выражение будет разделено некорректно. При формировании итогового запроса, поисковая часть отделяется от основной скобками. Поиск протестирован для работы с полями строкового и цифрового формата (varchar, text, integer, numeric). Корректность работы поиска по другим полям не гарантирована.
UPDATE 0.5.5 Добавлена обработка скобочных выражений аналогично основному блоку условий. Примеры реализации приведены ниже.
Запрос с пустыми основными параметрами и поиском по одному полю:
http://url/.../query=??&searchQuery=title~~some
select q.id, q.title, q.updatedAt from v_test q where (q.title::text like '%%some%%')
Запрос со сложными основными параметрами и поиску по нескольким полям:
http://url/.../query=title?ID!=1?ID,desc,10,0&searchQuery=ID~~1||ID~~2
select q.title from v_test q where (q.id::text like '%%1%%' or q.id::text like '%%2%%') and q.id != 1 order by q.id desc limit 10 offset 0
Запрос с одним скобочным выражением (должен быть на первом месте):
http://url/.../query=ID??&searchQuery=(content~~1||content~~2)*extraField~~ok
select q.id from v_test q where ((lower(q.content::text) like '%1%' or lower(q.content::text) like '%2%') and lower(q.extra_field::text) like '%ok%')
Запрос с несколькими скобочными выражениями (порядок произволен):
http://url/.../query=ID,content,extraField??ID,desc,,&searchQuery=(content~~1||content~~2)*(extraField~~some||extraField~~any)
select q.id, q.content, q.extra_field from v_test q where ((lower(q.content::text) like '%1%' or lower(q.content::text) like '%2%') and (lower(q.extra_field::text) like '%some%' or lower(q.extra_field::text) like '%any%')) order by q.id desc
Запрос со вложенным объектом:
http://url/.../query=ID,content,extraField??ID,desc,,&searchQuery=content~~extraField^^something
select q.id, q.content, q.extra_field from v_test q where (q.content->>'extraField'::text like '%something%')
При передаче значения searchField, отсутствующего в параметре модели, SQaLice вернет ошибку:
"[SQaLice] Passed unexpected field name in search condition - extra_Field"
http://url/.../query=content?ID!=1?ID,asc,,&searchQuery=ID~~1
select q.content from v_test q where (lower(q.id::text) like $1) and q.id != $2 order by q.id asc
["'%1%'", 1]
http://url/.../query=ID?(ID==1,2,13||isBool==true)*content!=anth?&searchQuery=ID~~1||content~~smth
select q.id from v_test q where (lower(q.id::text) like $1 or lower(q.content::text) like $2) and (q.id = any(array[$3]) or q.is_bool = $4) and q.content != $5
["'%1%'", "'%smth%'", "1,2,13", true, "'anth'"]
Функция GetFieldsList позволяет получать список полей, приведенных к формату запроса в базу.
Пример строки запроса:
http://url/.../query=ID,title,updatedAt?ID==10||ID==8?ID,desc,2,0
Получаемый массив полей:
["id", "title", "updated_at"]
При обработке строки запроса, не содержащей список полей, будет возвращен пустой массив:
http://url/.../query=??
[]
При запросе поля, не входящего в модель, компилятор вернет ошибку:
"[SQaLice] Passed unexpected field name in select - field"
Функция GetConditionsList позволяет получить список условий, содержащихся в запросе. При этом элементы условий приводятся к формату запроса к БД.
Формат условной структуры:
Имя | Тип | Описание |
---|---|---|
fieldName | string | Название поля |
operator | string | Оператор |
value | interface | Значение |
isBracket | string | Признак "Условие в скобках" |
Пример строки запроса:
http://url/.../query=ID,title,updatedAt?(title==testText)*ID!=8?ID,desc,2,0
Получаемый массив условий:
[
{
"fieldName": "title",
"operator": "=",
"value": {"testText"},
"isBracket": true
},
{
"fieldName": "id",
"operator": "!=",
"value": {"8"},
"isBracket": false
},
]
При обработке строки запроса, не содержащей условий, будет возвращен пустой массив:
http://url/.../query=??
[]
Пример ошибки:
"[SQaLice] Unsupported operator in condition - <<"
Функция GetConditionByName позволяет получить первое по порядку условие по с переданным названием поля, содержащегося в запросе. При этом элементы условия приводятся к формату запроса к БД.
Формат условной структуры:
Имя | Тип | Описание |
---|---|---|
fieldName | string | Название поля |
operator | string | Оператор |
value | interface | Значение |
isBracket | string | Признак "Условие в скобках" |
Пример строки запроса:
http://url/.../query=ID,title,updatedAt?(ID==3)*ID!=8?ID,desc,2,0
Получаемый массив условий:
{
"fieldName": "id",
"operator": "=",
"value": {"3"},
"isBracket": true
}
При обработке строки запроса, не содержащей условий, будет возвращен пустой массив:
http://url/.../query=??
[]
Пример ошибки:
"[SQaLice] Unsupported operator in condition - <<"
Функция GetSortField позволяет получить массив полей сортировки, содержащихся в запросе. При этом названия полей приводятся к формату запроса в БД.
Пример строки запроса:
http://url/.../query=ID,title,updatedAt?(ID==3)*ID!=8?ID,desc,2,0
Получаемое название поля:
{
["id"]
}
Пример строки запроса с несколькими полями:
http://url/.../query=ID,title,updatedAt?(ID==3)*ID!=8?ID,isBool,desc,2,0
Получаемое название поля:
{
["id", "is_bool"]
}
При обработке строки запроса, не содержащей ограничений, будет возвращена пустая строка:
http://url/.../query=??
""
Пример ошибки:
"[SQaLice] Unsupported field in restrictions - field"
Функция GetSortOrder позволяет получить порядок сортировки, содержащийся в запросе.
Пример строки запроса:
http://url/.../query=ID,title,updatedAt?(ID==3)*ID!=8?ID,desc,2,0
Получаемый порядок сортировки:
{"desc"}
При обработке строки запроса, не содержащей ограничений, будет возвращена пустая строка:
http://url/.../query=??
""
Пример ошибки:
"[SQaLice] Unsupported field in restrictions - field"
Функция GetLimit позволяет получить лимит, содержащийся в запросе.
Пример строки запроса:
http://url/.../query=ID,title,updatedAt?(ID==3)*ID!=8?ID,desc,2,0
Получаемый порядок сортировки:
2
При обработке строки запроса, не содержащего ограничений, будет возвращен nil:
http://url/.../query=??
nil
Пример ошибки:
"[SQaLice] Invalid negative selection limit - -1"
Функция GetOffset позволяет получить отступ, содержащийся в запросе.
Пример строки запроса:
http://url/.../query=ID,title,updatedAt?(ID==3)*ID!=8?ID,desc,2,0
Получаемый порядок сортировки:
0
При обработке строки запроса, не содержащей ограничений, будет возвращен nil:
http://url/.../query=??
nil
Пример ошибки:
"[SQaLice] Invalid negative selection offset - -1"
TO-DO | Статус |
---|---|
Покрытие тестами | Выполнено |
Расширение получения условий запроса | Не выполнено |
Функция AddQueryFieldsToSelect позволяет добавлять дополнительные поля в SELECT блок запроса, либо полностью заменить его. Это регулируется флагом isDeleteCurrent. Передаваемые поля проверяются по аргументу fieldsMap на наличие в модели, если он передан. В случае передачи неверного поля, компилятор пропустит данное поле. Если fieldsMap не передан, все поля добавляются в запрос без проверки
UPDATE 0.4 Начиная с данной версии считывание полей модели, используемых при компиляции запроса, а также при изменении исходной строки-аргумента params внесено внутрь целевых функций и не нуждается в отдельном формировании. В качестве аргумента model при получении/изменении условий запроса необходимо передавать модель, на которую планируется считывание данных
Функция AddQueryConditions позволяет добавлять дополнительные условия в запрос, либо полностью заменить их. Это регулируется флагом isDeleteCurrent. Если в условии передан некорректный оператор, компилятор вернет ошибку:
"[SQaLice] Passed incorrect operator in query condition"
Добавляемые поля разделяются логическим оператором AND между собой, а также с текущими условиями запроса.
Функция ReplaceQueryCondition позволяет заменить текущее условие в запросе по названию поля. Если условия с переданным именем нет в запросе, компилятор вернет ошибку:
"[SQaLice] Condition with passed name not found"
Функция DeleteQueryCondition позволяет удалить текущее условие в запросе по названию поля. Если условия с переданным именем нет в запросе, компилятор вернет исходную строку запроса
Функция AddQueryRestrictions позволяет заменить поля и порядок сортировки, лимит и оффсет в запросе.