Support

Lorem ipsum dolor sit amet:

24h / 365days

We offer support for our customers

Mon - Fri 8:00am - 5:00pm (GMT +1)

Get in touch

Cybersteel Inc.
376-293 City Road, Suite 600
San Francisco, CA 94102

Have any questions?
+44 1234 567 890

Drop us a line
info@yourdomain.com

About us

Lorem ipsum dolor sit amet, consectetuer adipiscing elit.

Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec.

Chapter 11. Adding Additional Datasources

11. Adding Additional Datasources

By default ReportServer is shipped with support only for the most common database systems, although it can interact with virtually every database that offers a JDBC compliant driver. In this chapter we will show how to develop a groovy script that adds support for the Firebird database (www.firebirdsql.org) to ReportServer.

Although SQL is well standardized and the JDBC specification defines a vendor independent interface to the actual database driver, simply adding the database driver to the classpath does not suffice. ReportServer tries to use mostly ANSI-SQL whenever possible, but in some situations not using a vendor-specific extension bears a high performance penalty. One of these situations is the limit/offset-mechanism, that allows the application to request only a certain chunk of the resultset. Most databases offer some solution to this problem, but there is no standard approach. To manage these differences in different SQL dialects ReportServer uses a DatabaseHelper class for each supported SQL dialect.

To add support for a new datatabase, what we need to do, is to implement a DatabaseHelper for the database and register it with ReportServer.

  • Please note that Firebird is already integrated in ReportServer out-of-the-box. In order to use Firebird with ReportServer, you just have to add the Firebird drivers to your lib directory. The example below is meant for understanding the principle.

Lets start by looking at the DatabaseHelper for the H2 database engine:

public class H2 extends DatabaseHelper {

 public static final String DB_NAME = "H2";
 public static final String DB_DRIVER = "org.h2.Driver";
 public static final String DB_DESCRIPTOR = "DBHelper_H2";

 @Override
 public String getDescriptor() {
  return DB_DESCRIPTOR;
 }

 @Override
 public String getDriver() {
  return DB_DRIVER;
 }

 @Override
 public String getName() {
  return DB_NAME;
 }
}

The three methods getDescriptor, getName and getDriver are the minimum each DatabaseHelper has to implement.

getName() The text the user is shown on the front-end when selecting the database type.
getDriver() The name of the JDBC driver class.
getDescriptor() The key used internally to map datasources to DatabaseHelpers

To adapt this to the Firebird database, we simply change the values of the three constants

class Firebird extends DatabaseHelper {

 public static final String DB_NAME = "Firebird";
 public static final String DB_DRIVER = "org.firebirdsql.jdbc.FBDriver";
 public static final String DB_DESCRIPTOR = "DBHelper_Firebird";

 @Override
 public String getDescriptor() {
  return DB_DESCRIPTOR;
 }

 @Override
 public String getDriver() {
  return DB_DRIVER;
 }

 @Override
 public String getName() {
  return DB_NAME;
 }
}

If we added this class to ReportServer, we would already be able to execute Birt and Jasper Reports where the query is simply passed through, but using a dynamic list with a Firebird datasource would still fail.

There are basically three more changes to be made to fully support Firebird from within ReportServer.

  • As of ReportServer 4.2.0, the old createDummyQuery() method is not further used, as it now uses JDBC 4 connection.isValid() for this purpose. You should remove this method from your scripts if you use it.

The other two enhancements concern the earlier mentioned matter of limit and offset. ReportServers default implementation creates queries with LIMIT and OFFSET keywords at the end, so we need to provide a different implementation for Firebird.

@Override
 public LimitQuery getNewLimitQuery(Query nestedQuery, QueryBuilder queryBuilder) {
  return new LimitQuery(nestedQuery, queryBuilder){
   @Override
   public void appendToBuffer(StringBuffer buf) {
    buf.append("SELECT FIRST ");
    buf.append(queryBuilder.getLimit());
    buf.append(" * FROM (");
    nestedQuery.appendToBuffer(buf);
    buf.append(") limitQry");
   }
  }
 }

 @Override
 public OffsetQuery getNewOffsetQuery(Query nestedQuery, QueryBuilder queryBuilder, ColumnNamingService columnNamingService) {
  return new OffsetQuery(nestedQuery, queryBuilder, columnNamingService){
   @Override
   public void appendToBuffer(StringBuffer buf) {
    buf.append("SELECT FIRST ");
    buf.append(queryBuilder.getLimit());
    buf.append(" SKIP ");
    buf.append(queryBuilder.getOffset());
    buf.append(" * FROM (");
    nestedQuery.appendToBuffer(buf);
    buf.append(") limitQry");
   }
  }
 }

The way ReportServer constructs dynamic queries is by basically wrapping multiple layers of SQL around each other. The LimitQuery follows the same approach. It has access to a nestedQuery and is asked to write itself into the supplied buffer, wrapping this nested query.

The final step is to register the newly created DatabaseHelper with ReportServer. This is done by implementing the net.datenwerke.rs.base.service.dbhelper.hooks.DatabaseHelperProviderHook. Following is the implementation needed to attach our custom Firebird database helper class

def HOOK_NAME = "DATASOURCE_HELPER_FIREBIRD"
def callback =  [
   provideDatabaseHelpers : {
    return Collections.singletonList(new Firebird());
   }
  ] as DatabaseHelperProviderHook;
GLOBALS.services.callbackRegistry.attachHook(HOOK_NAME, DatabaseHelperProviderHook.class, callback)

You will find the complete script (AddFirebirdSupport.groovy) in the appendix as well as in the support portal for download.

Note that, in order for this to work you of course need to place the Firebird JDBC driver into your classpath. Download Jaybird from http://www.firebirdsql.org/en/jdbc-driver/ and put the files jaybird-2.2.3.jar and lib/connector-api-1.5.jar into the WEB-INF/lib subdirectory of your ReportServer installation. You might have to restart ReportServer afterwards.

Beware, that after restarting ReportServer hooks attached from the terminal will no longer be present. To automatically attach a hook on start-up put the script in the bin/onstartup.d directory in the fileserver.

InfoFabrik GmbH

Wir wollen, dass alle Unternehmen, Institutionen und Organisationen, die Daten auswerten, selbständig und zeitnah genau die Informationen erhalten, die sie für ein erfolgreiches Arbeiten benötigen.

InfoFabrik GmbH
Klingholzstr. 7
65189 Wiesbaden
Germany

+49 (0) 611 580 66 25

Kontaktieren Sie uns

Was ist die Summe aus 2 und 6?
Copyright 2007 - 2024 InfoFabrik GmbH. All Rights Reserved.

Auf unserer Website setzen wir Cookies und andere Technologien ein. Während einige davon essenziell sind, dienen andere dazu, die Website zu verbessern und den Erfolg unserer Kampagnen zu bewerten. Bei der Nutzung unserer Website werden Daten verarbeitet, um Anzeigen und Inhalte zu messen. Weitere Informationen dazu finden Sie in unserer Datenschutzerklärung. Sie haben jederzeit die Möglichkeit, Ihre Einstellungen anzupassen oder zu widerrufen.

Datenschutzerklärung Impressum
You are using an outdated browser. The website may not be displayed correctly. Close