Связь фильтров дашборда и запросов к данным

Для динамической передачи значений фильтров дашборда в SQL запросы и скрипты постпроцессов в Дизайнере дашбордов используется Apache Velocity (opens in a new tab) - инструмент, основанный на Java. Для этого используется Velocity Template Language (язык шаблонов Velocity).

Введение в Velocity Template Language (VTL)

VTL использует ссылки (references) для встраивания динамического контента, где переменная является одним из типов ссылок. В переменной можно ссылаться на данные из Java-кода, находящегося в редактируемом скрипте, или получать значение непосредственно с дашборда. Вот пример оператора VTL:

#set( $a = "Velocity" )

В этом примере символ # обозначает директиву (directive) set, которая присваивает значение переменной $a.

Для лучшего понимания синтаксиса Velocity, можно запомнить простое правило: ссылки начинаются с $ и используются для получения данных, а директивы начинаются с # и используются для выполнения действий.

Ссылки

В VTL существуют три типа ссылок: переменные (variable), свойства (property) и методы (method).

ТипПример
Переменная$customer
Свойство$customer.name
Метод$customer.getAddress()

Также для обращения к ссылке можно использовать вот такой синтаксис: ${customer}.

Директивы

О директивах, не разобранных ниже подробнее можно посмотреть здесь (opens in a new tab).

Set

Директива #set используется для установки значения ссылки. Значение может быть присвоено как ссылке на переменную, так и ссылке на свойство, например:

#set( $customer.name = "Name" )
#set( $address = "Address" )

Условный оператор (If / ElseIf / Else)

Директива #if в Velocity позволяет сделать так, чтобы часть скрипта, окружённая директивой, выполнялась только если выражение в if истинно. Например:

#if( $example )
    JOIN table2 ON table1.col1 = table2.col1
#end

Здесь происходит проверка истинности значения переменной $example:

  • если $example имеет логическое значение (true/false), равное true
  • если значение не является пустым (null).

Содержимое между директивами #if и #end будет включено в редактируемый запрос, если условие истинно. В приведенном выше примере, если $example истинно, то в результате будет выполнено присоединение новой таблицы. Если $example равно null или имеет логическое значение false, условие считается ложным, и запрос изменён не будет.

К директиве #if можно добавить директивы #elseif или #else. При этом движок шаблонов Velocity останавливается на первом выражении, которое оказывается истинным. В приведенном ниже примере предположим, что $example равно 15, а $test - 6.

#if( $example < 10 )
    WHERE table.col1 = 'A'
#elseif( $example == 10 )
    WHERE table.col1 = 'B'
#elseif( $test == 6 )
    WHERE table.col1 = 'C'
#else
    WHERE table.col1 = 'D'
#end

В этом примере $example больше 10, поэтому первые два сравнения не проходят. Затем $test сравнивается с 6, что истинно, поэтому в запрос будет добавлено WHERE table.col1 = 'C'.

Использование директив VTL для фильтрации данных

Предположим, что у нас дашборде добавлен фильтр множественного выбора со значением clients параметра field. Тогда, чтобы установить связь между SQL запросом и значениями фильтра, в запрос будет достаточно добавить следующий код:

where 1 = 1
#if(${clients})
    and (clients.name in (:clients))
#end

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

Условие 1 = 1 здесь нужно для корректной работы запроса в случае, если значения фильтра по клиентам выбраны не были, а с помощью блока if производится проверка существования фильтра перед добавлением условия фильтрации.

Если в качестве значений фильтра возвращается массив и нужно обратиться к какому-то конкретному его элементу можно следующим образом: ${clients.get(index)}.