-
Notifications
You must be signed in to change notification settings - Fork 74
Data loaders
Data loaders are objects of class implementing interface com.haulmont.yarg.loaders.ReportDataLoader
.
You can implement any logic in your own data loaders. In order to register custom data loader you should register it using com.haulmont.yarg.loaders.factory.DefaultLoaderFactory#registerDataLoader
instance, or create your own implementation of com.haulmont.yarg.loaders.factory.ReportLoaderFactory
.
Yarg provides 3 types of loaders by default : Groovy loader, SQL loader and JSON loader.
The default implementation is com.haulmont.yarg.loaders.impl.SqlDataLoader
.
This loader uses sql to extract data for reports. To use it you should set ReportQuery#type to sql in xml file or using report builder.
Let's consider the following example.
<?xml version="1.0" encoding="UTF-8"?>
<report name="report">
<templates>
<template code="DEFAULT" documentName="breakdown.xls" documentPath="./test/sample/financedetails/breakdown.xls" outputType="xls" outputNamePattern="breakdown.xls"/>
</templates>
<rootBand name="Root" orientation="H">
<bands>
<band name="Header" orientation="H"/>
<band name="Month" orientation="H">
<bands>
<band name="Item" orientation="H">
<queries>
<query name="Item" type="sql">
<script>
select i.name as "item", i.price as "price"
from sold_item i
where i.month = ${Month.month}
</script>
</query>
</queries>
</band>
</bands>
<queries>
<query name="Month" type="sql">
<script>
select i.month as "month", count(name) as "number", sum(price) as "summary"
from month_batch b, sold_item i
where i.month = b.month group by i.month
</script>
</query>
</queries>
</band>
</bands>
<queries/>
</rootBand>
</report>
This report contains two report queries which use sql data loader (you can see it in query element's attribute type).
These queries contain plain sql script, which can as well contain placeholders for external params: ${paramName}. In addition, query of a nested band can use data of parent band. You can see it in "Item" query which uses month field from parent band Month (${Month.month}).
You can note that all output fields of query are marked with aliases (using as "aliasName"). It is not mandatory, but is very useful and recommended to consider, because some databases (like postgres and hsql) can change case of output fields (in the considered case you would get MONTH instead of month field).
Groovy data loader allows to return data by a groovy script. The only restriction for the groovy script is that it must return List<Map<String, Object>>
.
All report parameters are accessible in script through params input parameter.
return [['field1':1, 'field2': 1 + params['someParameter']]]
Parent band is also accessible in the script as parentBand input parameter. It's an object ofcom.haulmont.yarg.structure.BandData
class.
Current report query is also passed to script as reportQuery input parameter. Its interface is com.haulmont.yarg.structure.ReportQuery
.
Sometimes you already have JSON structure with all necessary data. In this case you can use the JSON data loader to make queries to the structure. The data loader uses JsonPath syntax to query data from JSON tree.
Let's consider the following example:
We have the following JSON structure, describing the store with 2 books and 1 bicycle.
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99,
"isbn": "0-553-21311-3"
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
}
}
If we want to select all books we should write the following code in report query:
parameter=param1 $.store.book[*]
"parameter=param1" means that the loader will search for JSON string in param1 parameter.
There are 2 only steps to implement custom data loader:
- implement
com.haulmont.yarg.loaders.ReportDataLoader
interface - register your data loader in your
com.haulmont.yarg.loaders.factory.ReportLoaderFactory
(by default it'scom.haulmont.yarg.loaders.factory.DefaultLoaderFactory
)
We suggest to implement data loaders as stateless objects, so you would not have any issues with thread safety.