Database Plugins and Dialects
A database plugin teaches Apache Hop how to interact with a specific relational database dialect: assembling JDBC URLs, formatting DDL statements, mapping SQL data types to Hop’s IValueMeta types, and identifying reserved keywords.
The Plugin Class
Annotate the class with @DatabaseMetaPlugin and extend BaseDatabaseMeta:
import org.apache.hop.core.database.BaseDatabaseMeta;
import org.apache.hop.core.database.DatabaseMetaPlugin;
import org.apache.hop.core.database.IDatabase;
import org.apache.hop.core.gui.plugin.GuiPlugin;
@DatabaseMetaPlugin(
type = "CUSTOMDB",
typeDescription = "Custom Database Engine"
)
@GuiPlugin
public class CustomDatabaseMeta extends BaseDatabaseMeta implements IDatabase {
@Override
public String getDriverClass() {
return "com.customdb.jdbc.CustomDriver";
}
@Override
public String getURL(String hostname, String port, String databaseName) {
if (Utils.isEmpty(port)) {
return "jdbc:customdb://" + hostname + "/" + databaseName;
}
return "jdbc:customdb://" + hostname + ":" + port + "/" + databaseName;
}
@Override
public int getDefaultDatabasePort() {
return 5432;
}
@Override
public String[] getAccessTypeList() {
return new String[] {"Native (JDBC)"};
}
@Override
public String getFieldDefinition(IValueMeta v, String tk, String pk,
boolean useAutoIncrement, boolean addFieldName,
boolean addCr) {
// Translate Hop value types into SQL DDL column specifications
StringBuilder retval = new StringBuilder();
String fieldname = v.getName();
int length = v.getLength();
int precision = v.getPrecision();
if (addFieldName) {
retval.append(fieldname).append(" ");
}
switch (v.getType()) {
case IValueMeta.TYPE_INTEGER:
retval.append("BIGINT");
break;
case IValueMeta.TYPE_STRING:
if (length > 0 && length < 4000) {
retval.append("VARCHAR(").append(length).append(")");
} else {
retval.append("TEXT");
}
break;
default:
retval.append("TEXT");
break;
}
return retval.toString();
}
@Override
public String[] getReservedWords() {
return new String[] {"SELECT", "FROM", "WHERE", "ORDER", "GROUP", "BY", "USER"};
}
}
JDBC Drivers and Classloading
-
Driver Placement: For licensing reasons, JDBC drivers should not be bundled directly inside the plugin zip. Drivers are placed in
lib/jdbcof the Hop installation (or custom directories defined byHOP_SHARED_JDBC_FOLDERS). -
Bulk Loaders: If your dialect plugin ships with dedicated bulk-loader transforms (e.g., PostgreSQL COPY or MySQL Bulk Loader), declare the same
classLoaderGroupon both plugins so the transform sees the dialect’s loaded driver classes.
Concrete Codebase Examples
-
plugins/databases/postgresql/src/main/java/org/apache/hop/databases/postgresql/PostgreSqlDatabaseMeta.java: Comprehensive relational dialect implementation. -
plugins/databases/duckdb/src/main/java/org/apache/hop/databases/duckdb/DuckDBDatabaseMeta.java: Embedded file-based database dialect.