06. Pentaho Metadata Dialect SPI
What's a Pentaho Metadata Dialect?
A dialect defines how Pentaho Metadata should generate SQL for a given database type.
Pentaho Metadata's Dialect Plugin System
Introduced in BI Suite Release 3.7, Pentaho Metadata supports additional dialects through it's Service Provider Interface (SPI): SQLDialectInterface
. A Pentaho Metadata Dialect Plugin is a jar file that consists of a dialect implementation and some configuration. The SPI enables developers to develop new database dialects which Pentaho Metadata will automatically detect and register.
Implementing SQLDialectInterface
Database types are defined in Kettle with a unique database id, e.g. SampleDB. Dialects relate one-to-one with database type ids defined in Kettle DB Core or a Kettle Database Plugin. A dialect is an implementation of the SPI:
public interface SQLDialectInterface { public String getDatabaseType(); public String quoteStringLiteral(Object str); public boolean isSupportedFunction(String functionName); public boolean isAggregateFunction(String functionName); public boolean isSupportedInfixOperator(String operator); public SQLFunctionGeneratorInterface getFunctionSQLGenerator(String functionName); public SQLOperatorGeneratorInterface getInfixOperatorSQLGenerator(String operatorName); public String getDateSQL(int year, int month, int day); public String generateSelectStatement(SQLQueryModel model); public int getMaxTableNameLength(); }
A base implementation exists and can be used as a simple starting point for most new dialects. In addition to the SPI, DefaultSQLDialect
defines additional extension points to facilitate building new dialects quickly. Below is a dialect that defines the maximum table name length and a trivial method for quoting a String literal for our Sample Database:
public class SampleDialect extends DefaultSQLDialect { public SampleDialect() { super("SampleDB"); } @Override public int getMaxTableNameLength() { return 128; } @Override public String quoteStringLiteral(Object str) { return "'" + str + "'"; } }
Declaring your Dialect as a Service Provider
A jar file containing your new dialect should be created with an additional META-INF entry. Pentaho Metadata utilizes the Java Service Loader API to dynamically look up dialect implementations. The ServiceLoader API requires you list all Service Provider implementations in a file named after the interface of the service they provide in the META-INF/services
directory of the jar file:
META-INF/services/org.pentaho.pms.mql.dialect.SQLDialectInterface: org.pentaho.pms.mql.dialect.SampleDBDialect
Where org.pentaho.pms.mql.dialect.SampleDialect
is the implementation of SQLDialectInterface
for our fictitious database type: SampleDB.
For more information see Jar Service Provider Packaging Notes from Oracle.
Using your dialect
All that is required is the jar file to be in the classpath. In most applications this is a /lib
directory within the application's installation directory.
- Note: In order to use a dialect the database type must be defined in Kettle. See the sample project for how to create a Kettle Database Plugin, and the Unit Test for how to register it programmatically.
Sample Source Code
Attached is a sample project with the aforementioned SampleDB Dialect Plugin and a SampleDB Kettle Database Plugin. The attachment is an Eclipse project with independent Ant build scripts based on Subfloor. All dependencies are managed by Ivy. Subfloor will take care of downloading Ivy and resolving all dependencies by running the default target:
../sampledb-plugin> ant
http://wiki.pentaho.com/download/attachments/19235857/sampledb-plugin.tar.gz
Additional Notes
Existing database dialects that ship with Pentaho Metadata can be overridden by supplying a dialect for the same database type id.
Further Reading
For more information on how to test a Kettle Plugin click here: http://wiki.pentaho.com/display/EAI/How+to+debug+a+Kettle+4+plugin
For more general information about Java's ServiceLoader API see these links:
http://download.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html
http://java.sun.com/developer/technicalArticles/javase/extensible/index.html