compiler

package module
v1.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 24, 2024 License: MIT Imports: 8 Imported by: 0

README

SQaLice-compiler

SQa-Lice-logo

Описание компиляции основного запроса

Описание компиляции поискового запроса

Описание методов парсинга запроса

Описание методов изменения запроса

Описание и назначение

Пакет компилятора 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.

Пример адресной строки запроса, содержащей все 3 блока
http://url/.../query=ID,title,updatedAt?ID==10||ID==8?ID,desc,2,0

В случае отсутствия необходимости в указании одного из этих блоков, приведенное форматирование должно сохраняться.

Пример адресной строки запроса без блока conditions
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?

Блок fields

Для получения всех полей из целевой SQL, содержащиеся в структуре модели modelsMap, нужно передавать данный блок пустым.

Пример адресной строки запроса с пустым блоком fields
http://url/.../query=?ID==10||ID==8?ID,desc,2,0

Для получения конкретных полей, в поле fields необходимо передавать название поля в формате json с запятыми в качестве разделителя и без пробелов.

ID,title,createdAt?
Пример адресной строки запроса для получения ID
http://url/.../query=ID?ID>=1?ID,desc,10,0

При передаче некорректного названия поля, SQaLice вернет ошибку:

"[SQaLice] Passed unexpected field name in select"

Блок conditions

В данном блоке возможно указание условий получения записей. Допускается передача пустого блока conditions, в таком случае происходит выборка без дополнительных условий.

Пример запроса без блока 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 - <"

Блок conditions (аргументы)

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]
Запрос с несколькими условиями 2
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'"]

Блок restrictions

В данном блоке возможно указание ограничений конечной выборки. Допускается передача пустого блока ограничений, в таком случае 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

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"
Примеры сборки запроса с массивом аргументов
Запрос 1 + 1
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. Также возможна запись перед текущими выражениями, или после них (isLeading) Если в условии передан некорректный оператор, компилятор вернет ошибку:

"[SQaLice] Passed incorrect operator in query condition"

Добавляемые поля разделяются логическим оператором AND между собой, а также с текущими условиями запроса.

Замена условия

Функция ReplaceQueryCondition позволяет заменить текущее условие в запросе по названию поля. Если условия с переданным именем нет в запросе, компилятор вернет ошибку:

"[SQaLice] Condition with passed name not found"

Удаление условия

Функция DeleteQueryCondition позволяет удалить текущее условие в запросе по названию поля. Если условия с переданным именем нет в запросе, компилятор вернет исходную строку запроса

Добавление ограничений

Функция AddQueryRestrictions позволяет заменить поля и порядок сортировки, лимит и оффсет в запросе

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AddQueryConditions added in v0.3.0

func AddQueryConditions(query string, conds []CondExpr, isDeleteCurrent, isLeading bool) (string, error)

AddQueryConditions adds conditions to query conditions list with AND separators If isDeleteCurrent argument passed, conds list peplacing current query conditions If correct sepOperator passed in condition, compiler use it instead of AND separator

func AddQueryFieldsToSelect added in v0.3.0

func AddQueryFieldsToSelect(model interface{}, query string, fieldsArray []string, isDeleteCurrent bool) (string, error)

AddQueryFieldsToSelect adds fieldsMap JSON or fieldsArray fields in SELECT block, replacing current fields in query if isDeleteCurrent passed as true

func AddQueryRestrictions added in v0.3.0

func AddQueryRestrictions(query string, sortFields string, sortOrder string, limit string, offset string) (string, error)

AddQueryRestrictions adds restrictions to query restrictions block instead of current If argument is not passed, query saves current parameter

func DeleteQueryCondition added in v0.6.9

func DeleteQueryCondition(model interface{}, query, condName string) (string, error)

DeleteQueryCondition prunes condition from query by fieldname

func Get added in v0.5.0

func Get(model interface{}, target, params string, withCount, withArgs bool) (mainQ, countQ string, args []interface{}, er error)

Get builds a GET query with parameters

func GetFieldsList added in v0.2.1

func GetFieldsList(model interface{}, q string) (fieldsList []string, err error)

GetFieldsList returns a list of query fields in SQL format

func GetLimit added in v0.2.1

func GetLimit(q string) (limit *int, err error)

GetLimit returns selection limit from query

func GetOffset added in v0.2.1

func GetOffset(q string) (limit *int, err error)

GetOffset returns selection offset from query

func GetSortField added in v0.2.1

func GetSortField(model interface{}, q string) (fields []string, err error)

GetSortField returns selection sort field from query

func GetSortOrder added in v0.2.1

func GetSortOrder(q string) (order string, err error)

GetSortOrder returns selection order from query

func ReplaceQueryCondition added in v0.3.0

func ReplaceQueryCondition(model interface{}, query string, newCond CondExpr) (string, error)

ReplaceQueryCondition replaces query condition by fieldName

func Search(model interface{}, target, params string, withCount, withArgs bool, searchParams string) (mainQ, countQ string, args []interface{}, er error)

Search builds a GET query with LIKE filter on searchField

Types

type CondExpr added in v0.2.1

type CondExpr struct {
	FieldName   string
	Operator    string
	Value       interface{}
	IsBracket   bool
	SepOperator string
}

CondExpr describes structure of query condition

func GetConditionByName added in v0.2.1

func GetConditionByName(model interface{}, q string, fieldName string, toDBFormat bool) (condExpr *CondExpr, err error)

GetConditionByName returns first condition with passed name and operator

func GetConditionsList added in v0.2.1

func GetConditionsList(model interface{}, q string, toDBFormat bool, isSearch bool) (condExprsList []*CondExpr, err error)

GetConditionsList returns a list of all query conditions in SQL format

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL