Skip to content

Commit

Permalink
support for queries in Root band
Browse files Browse the repository at this point in the history
Introduce datasource holder for console applications
bookstore2 test
  • Loading branch information
tinhol committed Aug 7, 2015
1 parent a87298e commit 026a9fd
Show file tree
Hide file tree
Showing 9 changed files with 271 additions and 17 deletions.
13 changes: 10 additions & 3 deletions core/modules/core/src/com/haulmont/yarg/console/ConsoleRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import com.haulmont.yarg.loaders.factory.PropertiesSqlLoaderFactory;
import com.haulmont.yarg.loaders.impl.GroovyDataLoader;
import com.haulmont.yarg.loaders.impl.JsonDataLoader;
import com.haulmont.yarg.loaders.impl.SqlDataLoader;
import com.haulmont.yarg.reporting.Reporting;
import com.haulmont.yarg.reporting.RunParams;
import com.haulmont.yarg.structure.Report;
Expand Down Expand Up @@ -149,11 +150,17 @@ private static Reporting createReportingEngine(PropertiesLoader propertiesLoader
}

reporting.setFormatterFactory(formatterFactory);
SqlDataLoader sqlDataLoader = new PropertiesSqlLoaderFactory(propertiesLoader).create();
GroovyDataLoader groovyDataLoader = new GroovyDataLoader(new DefaultScriptingImpl());
JsonDataLoader jsonDataLoader = new JsonDataLoader();

reporting.setLoaderFactory(
new DefaultLoaderFactory()
.setSqlDataLoader(new PropertiesSqlLoaderFactory(propertiesLoader).create())
.setGroovyDataLoader(new GroovyDataLoader(new DefaultScriptingImpl()))
.setJsonDataLoader(new JsonDataLoader()));
.setSqlDataLoader(sqlDataLoader)
.setGroovyDataLoader(groovyDataLoader)
.setJsonDataLoader(jsonDataLoader));

DatasourceHolder.dataSource = sqlDataLoader.getDataSource();
return reporting;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.haulmont.yarg.console;

import javax.sql.DataSource;

/**
* @author degtyarjov
* @version $Id$
*/
public final class DatasourceHolder {
private DatasourceHolder() {
}

public static volatile DataSource dataSource;
}
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,8 @@ private void setCaseSensitiveSynonym(String columnName, OutputValue outputValue)

return fillOutputData(resList, outputValues);
}

public DataSource getDataSource() {
return dataSource;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
package com.haulmont.yarg.reporting;

import com.google.common.base.Preconditions;
import com.google.common.collect.Multimap;
import com.haulmont.yarg.exception.DataLoadingException;
import com.haulmont.yarg.exception.ValidationException;
import com.haulmont.yarg.loaders.ReportDataLoader;
Expand Down Expand Up @@ -105,8 +106,15 @@ protected List<Map<String, Object>> getBandData(ReportBand band, BandData parent

if (result != null) {
//add input params to band
//todo eude - probably we need to get rid of the following logic, because leads to errors while logging report
for (Map<String, Object> map : result) {
map.putAll(params);
for (Map.Entry<String, Object> paramEntry : params.entrySet()) {
if ( !(paramEntry.getValue() instanceof Collection)
&& !(paramEntry.getValue() instanceof Map)
&& !(paramEntry.getValue() instanceof Multimap)) {
map.put(paramEntry.getKey(), paramEntry.getValue());
}
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ public Report parseXml(String xml) throws IOException {
List<ReportParameter> reportParameters = parseInputParameters(rootElement);
List<ReportFieldFormat> reportFieldFormats = parseValueFormats(rootElement);
BandBuilder rootBandDefinitionBuilder = new BandBuilder().name(BandData.ROOT_BAND_NAME);
parseQueries(rootElement.element("rootBand"), rootBandDefinitionBuilder);
parseChildBandDefinitions(rootElement.element("rootBand"), rootBandDefinitionBuilder);
ReportBand rootBandDefinition = rootBandDefinitionBuilder.build();
String reportName = rootElement.attribute("name").getText();
Expand Down Expand Up @@ -181,23 +182,26 @@ protected void parseChildBandDefinitions(Element bandDefinitionElement, BandBuil
.name(childBandName)
.orientation(orientation);

Element reportQueriesElement = childBandElement.element("queries");

if (reportQueriesElement != null) {
List<Element> reportQueryElements = reportQueriesElement.elements("query");
for (Element queryElement : reportQueryElements) {
String script = queryElement.element("script").getText();
String type = queryElement.attribute("type").getText();
String queryName = queryElement.attribute("name").getText();

childBandDefinitionBuilder.query(queryName, script, type);
}
}

parseQueries(childBandElement, childBandDefinitionBuilder);
parseChildBandDefinitions(childBandElement, childBandDefinitionBuilder);
ReportBand childBandDefinition = childBandDefinitionBuilder.build();
parentBandDefinitionBuilder.child(childBandDefinition);
}
}
}

private void parseQueries(Element bandElement, BandBuilder bandDefinitionBuilder) {
Element reportQueriesElement = bandElement.element("queries");

if (reportQueriesElement != null) {
List<Element> reportQueryElements = reportQueriesElement.elements("query");
for (Element queryElement : reportQueryElements) {
String script = queryElement.element("script").getText();
String type = queryElement.attribute("type").getText();
String queryName = queryElement.attribute("name").getText();

bandDefinitionBuilder.query(queryName, script, type);
}
}
}
}
83 changes: 83 additions & 0 deletions core/modules/core/test/sample/bookstore2/BookStore2Test.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package sample.bookstore2;

import com.haulmont.yarg.console.ConsoleRunner;
import com.haulmont.yarg.console.DatasourceHolder;
import com.haulmont.yarg.formatters.factory.DefaultFormatterFactory;
import com.haulmont.yarg.loaders.factory.DefaultLoaderFactory;
import com.haulmont.yarg.loaders.impl.GroovyDataLoader;
import com.haulmont.yarg.loaders.impl.SqlDataLoader;
import com.haulmont.yarg.reporting.ReportOutputDocument;
import com.haulmont.yarg.reporting.Reporting;
import com.haulmont.yarg.reporting.RunParams;
import com.haulmont.yarg.structure.Report;
import com.haulmont.yarg.structure.xml.impl.DefaultXmlReader;
import com.haulmont.yarg.util.groovy.DefaultScriptingImpl;
import org.apache.commons.io.FileUtils;
import org.junit.Test;
import utils.TestDatabase;

import java.io.File;
import java.io.FileOutputStream;
import java.sql.Connection;
import java.sql.SQLException;

/**
* @author degtyarjov
* @version $Id$
*/

public class BookStore2Test {
@Test
public void testBookStoreReport() throws Exception {
TestDatabase testDatabase = new TestDatabase();
testDatabase.setUpDatabase();

Connection connection = testDatabase.getDs().getConnection();
DatasourceHolder.dataSource = testDatabase.getDs();
try {
connection.createStatement().executeUpdate("drop table store;");
} catch (SQLException e) {
//ignore
}
try {
connection.createStatement().executeUpdate("drop table book;");
} catch (SQLException e) {
//ignore
}

connection.createStatement().executeUpdate("create table store (id integer, name varchar, address varchar);");
connection.createStatement().executeUpdate("create table book(id integer, name varchar, author varchar, price decimal, store_id integer);");

connection.createStatement().executeUpdate("insert into store values(1, 'Main store', 'Some street');");
connection.createStatement().executeUpdate("insert into store values(2, 'Secondary store', 'Another street');");

connection.createStatement().executeUpdate("insert into book values(1, 'Concurrency in practice', 'Brian Goetz', 10.0, 1);");
connection.createStatement().executeUpdate("insert into book values(2, 'Concurrency in practice', 'Brian Goetz', 10.0, 1);");
connection.createStatement().executeUpdate("insert into book values(2, 'Concurrency in practice', 'Brian Goetz', 10.0, 1);");
connection.createStatement().executeUpdate("insert into book values(3, 'Effective Java', 'Josh Bloch', 20.0, 2);");
connection.createStatement().executeUpdate("insert into book values(4, 'Effective Java', 'Josh Bloch', 20.0, 2);");
connection.createStatement().executeUpdate("insert into book values(4, 'Effective Java', 'Josh Bloch', 20.0, 2);");
connection.createStatement().executeUpdate("insert into book values(5, 'Effective Java', 'Josh Bloch', 20.0, 1);");
connection.createStatement().executeUpdate("insert into book values(5, 'Effective Java', 'Josh Bloch', 20.0, 1);");
connection.createStatement().executeUpdate("insert into book values(6, 'Concurrency in practice', 'Brian Goetz', 10.0, 2);");
connection.createStatement().executeUpdate("insert into book values(7, 'Refactoring', 'Martin Fowler', 15.0, 2);");
connection.createStatement().executeUpdate("insert into book values(8, 'Refactoring', 'Martin Fowler', 15.0, 2);");
connection.createStatement().executeUpdate("insert into book values(8, 'Refactoring', 'Martin Fowler', 15.0, 2);");
connection.createStatement().executeUpdate("insert into book values(9, 'Refactoring', 'Martin Fowler', 15.0, 1);");

connection.commit();

Report report = new DefaultXmlReader().parseXml(FileUtils.readFileToString(new File("./modules/core/test/sample/bookstore2/bookstore2.xml")));
System.out.println();

Reporting reporting = new Reporting();
reporting.setFormatterFactory(new DefaultFormatterFactory());
reporting.setLoaderFactory(new DefaultLoaderFactory()
.setGroovyDataLoader(new GroovyDataLoader(new DefaultScriptingImpl()))
.setSqlDataLoader(new SqlDataLoader(testDatabase.getDs())));

ReportOutputDocument reportOutputDocument = reporting.runReport(new RunParams(report), new FileOutputStream("./result/sample/bookstore2.xls"));

testDatabase.stop();
}
}
Binary file not shown.
87 changes: 87 additions & 0 deletions core/modules/core/test/sample/bookstore2/bookstore2.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>

<report name="report">
<templates>
<template code="DEFAULT" documentName="bookstore.xls"
documentPath="./modules/core/test/sample/bookstore2/bookstore2.xls" outputType="xls"
outputNamePattern="bookstore.xls"/>
</templates>
<rootBand name="Root" orientation="H">
<bands>
<band name="Header" orientation="H"/>
<band name="Shop" orientation="H">
<bands>
<band name="Book" orientation="H">
<queries>
<query name="Book" type="groovy">
<script>
return params['Books'].asMap().get(parentBand.getParameterValue('id'))
</script>
</query>
</queries>
</band>
</bands>
<queries>
<query name="Shop" type="groovy">
<script>
return params['Shops']
</script>
</query>
</queries>
</band>
</bands>
<queries>
<query name="Root" type="groovy">
<script>
package sample.bookstore2.bookstore

import com.google.common.collect.ArrayListMultimap
import com.google.common.collect.Multimap
import com.haulmont.yarg.console.DatasourceHolder
import com.haulmont.yarg.util.db.QueryRunner
import com.haulmont.yarg.util.db.ResultSetHandler

import java.sql.ResultSet
import java.sql.SQLException

QueryRunner runner = new QueryRunner(DatasourceHolder.dataSource);
def query =
'select shop.id as "id", shop.name as "name", shop.address as "address", ' +
' book.author as "author", book.name as "name", book.price as "price", count(*) as "count" ' +
'from store shop, book ' +
'where book.store_id = shop.id ' +
'group by shop.id, shop.name, shop.address, book.author, book.name, book.price';
def shops = new HashSet()
def booksByShopId = ArrayListMultimap.create()

runner.query(query, new ResultSetHandler() {
@Override
Object handle(ResultSet rs) throws SQLException {
while (rs.next()) {
def shop = [:]
shop['id'] = rs.getInt(1)
shop['name'] = rs.getString(2)
shop['address'] = rs.getString(3)

shops.add(shop)
def book = [:]
book['author'] = rs.getString(4)
book['name'] = rs.getString(5)
book['price'] = rs.getBigDecimal(6)
book['count'] = rs.getLong(7)

booksByShopId.put(rs.getInt(1), book)
}
return null
}
})

params['Shops'] = new ArrayList(shops)
params['Books'] = booksByShopId

return [[:]]
</script>
</query>
</queries>
</rootBand>
</report>
47 changes: 47 additions & 0 deletions core/modules/core/test/sample/bookstore2/script.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package sample.bookstore2.bookstore

import com.google.common.collect.ArrayListMultimap
import com.google.common.collect.Multimap
import com.haulmont.yarg.console.ConsoleRunner
import com.haulmont.yarg.util.db.QueryRunner
import com.haulmont.yarg.util.db.ResultSetHandler

import java.sql.ResultSet
import java.sql.SQLException

QueryRunner runner = new QueryRunner(ConsoleRunner.dataSource);
def query =
'select shop.id as "id", shop.name as "name", shop.address as "address", ' +
' book.author as "author", book.name as "name", book.price as "price", count(*) as "count" ' +
'from shop, book book ' +
'where book.store_id = shop.id ' +
'group by shop.id, shop.name, shop.address book.author, book.name, book.price';
def shops = new HashSet()
def booksByShopId = ArrayListMultimap.create()

runner.query(query, new ResultSetHandler() {
@Override
Object handle(ResultSet rs) throws SQLException {
while (rs.next()) {
def shop = [:]
shop['id'] = rs.getInt(1)
shop['name'] = rs.getString(2)
shop['address'] = rs.getString(3)

shops.add(shop)
def book = [:]
book['author'] = rs.getString(4)
book['name'] = rs.getString(5)
book['price'] = rs.getBigDecimal(6)
book['count'] = rs.getLong(7)

booksByShopId.put(rs.getInt(1), book)
}
return null
}
})

params['Shops'] = shops
params['Books'] = booksByShopId

return [[:]]

0 comments on commit 026a9fd

Please sign in to comment.