Skip to content

Defining a New Database

Overview

When adding support for a new database, the first class to create is a new liquibase.database.Database implementation. Your Database implementation acts as the "dialect" definition and the facade to your database.

The Database interface defines methods for:

  • Reading metadata about the database (getDatabaseMajorVersion(), getDefaultPort(), getDefaultSchema(), etc.)
  • Checking capabilities of the database (isCaseSensitive(), supportsInitiallyDeferrableColumns, supportsSchemas(), etc.)
  • Performing common logic (escapeObjectName(), commit(), rollback(), etc.)

If your database generally attempts to be compatible with another database, your new Database implementation can extend the existing Database class. For example, if your database is PostgreSQL-compatible you can extend liquibase.database.core.PostgresDatabase and only override what is special about your database.

If your database is unique, you will likely want to extend from liquibase.database.AbstractJdbcDatabase which provides default logic that follows SQL standards.

Depending on your base class you will have more or less abstract methods which must be implemented.

API Documentation

A complete description of the API, including what methods must be implemented and how is available on the liquibase.database.Database API page.

Example Code

package com.example.database;

import liquibase.database.AbstractJdbcDatabase;
import liquibase.database.DatabaseConnection;
import liquibase.exception.DatabaseException;

public class ExampleDatabase extends AbstractJdbcDatabase {

    @Override
    public int getPriority() {
        return PRIORITY_DEFAULT;
    }

    @Override
    public boolean isCorrectDatabaseImplementation(DatabaseConnection databaseConnection) throws DatabaseException {
        return databaseConnection.getDatabaseProductName().equals("ExampleDB");
    }

    @Override
    public String getShortName() {
        return "example";
    }

    @Override
    protected String getDefaultDatabaseProductName() {
        return "Example Database";
    }

    @Override
    public String getDefaultDriver(String s) {
        return "com.example.db.Driver";
    }

    @Override
    public Integer getDefaultPort() {
        return 55555;
    }

    @Override
    public boolean supportsInitiallyDeferrableColumns() {
        return false;
    }

    @Override
    public boolean supportsTablespaces() {
        return true;
    }
}

If your database is compatible with an existing database, your class would look more like this:

package com.example.database;

import liquibase.database.DatabaseConnection;
import liquibase.database.core.PostgresDatabase;
import liquibase.exception.DatabaseException;

public class ExamplePostgresDatabase extends PostgresDatabase {

    @Override
    public int getPriority() {
        return PRIORITY_DATABASE;
    }

    @Override
    public boolean isCorrectDatabaseImplementation(DatabaseConnection databaseConnection) throws DatabaseException {
        return databaseConnection.getDatabaseProductName().equals("ExampleDB");
    }

    @Override
    public String getShortName() {
        return "example";
    }

    @Override
    protected String getDefaultDatabaseProductName() {
        return "Example Database";
    }
}

Next Step

After you have created your Database class, it's time to test it out


Last update: April 11, 2023
Created: January 5, 2023