All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jooq.meta.extensions.liquibase.LiquibaseDatabase Maven / Gradle / Ivy

The newest version!
/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Other licenses:
 * -----------------------------------------------------------------------------
 * Commercial licenses for this work are available. These replace the above
 * Apache-2.0 license and offer limited warranties, support, maintenance, and
 * commercial database integrations.
 *
 * For more information, please visit: https://www.jooq.org/legal/licensing
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */
package org.jooq.meta.extensions.liquibase;

import static org.jooq.impl.DSL.unquotedName;
import static org.jooq.tools.StringUtils.isBlank;

import java.io.File;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.jooq.meta.TableDefinition;
import org.jooq.meta.extensions.AbstractInterpretingDatabase;
import org.jooq.tools.Convert;
import org.jooq.tools.JooqLogger;
import org.jooq.tools.StringUtils;

import liquibase.Liquibase;
import liquibase.database.Database;
import liquibase.database.DatabaseFactory;
import liquibase.database.jvm.JdbcConnection;
import liquibase.resource.ClassLoaderResourceAccessor;
import liquibase.resource.CompositeResourceAccessor;
import liquibase.resource.DirectoryResourceAccessor;
import liquibase.resource.ResourceAccessor;

/**
 * The Liquibase database.
 * 

* This meta data source parses a set of XML files that follow the Liquibase * migration DSL, runs them on an in-memory H2 database before reverse * engineering the outcome. *

* The XML scripts are located in the scripts scripts property * available from {@link #getProperties()}. * * @author Lukas Eder */ public class LiquibaseDatabase extends AbstractInterpretingDatabase { private static final JooqLogger log = JooqLogger.getLogger(LiquibaseDatabase.class); private static final Map SETTERS; private boolean includeLiquibaseTables; private String databaseChangeLogTableName; private String databaseChangeLogLockTableName; private String databaseLiquibaseSchemaName; static { SETTERS = new HashMap<>(); try { for (Method method : Database.class.getMethods()) { String name = method.getName(); if (name.startsWith("set") && method.getParameterTypes().length == 1) SETTERS.put(name, method); } } catch (Exception e) { throw new RuntimeException(e); } } @Override protected void export() throws Exception { String rootPath = getProperties().getProperty("rootPath"); String scripts = getProperties().getProperty("scripts"); includeLiquibaseTables = Boolean.parseBoolean(getProperties().getProperty("includeLiquibaseTables", "false")); if (isBlank(scripts)) { scripts = ""; log.warn("No scripts defined", "It is recommended that you provide an explicit script directory to scan"); } Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(connection())); String contexts = ""; // [#9514] Forward all database.xyz properties to matching Liquibase // Database.setXyz() configuration setter calls for (Entry entry : getProperties().entrySet()) { String key = "" + entry.getKey(); if (key.startsWith("database.")) { String property = key.substring("database.".length()); Method setter = SETTERS.get("set" + Character.toUpperCase(property.charAt(0)) + property.substring(1)); try { if (setter != null) setter.invoke(database, Convert.convert(entry.getValue(), setter.getParameterTypes()[0])); } catch (Exception e) { log.warn("Configuration error", e.getMessage(), e); } } // [#9872] Some changeLogParameters can also be passed along else if (key.startsWith("changeLogParameters.")) { String property = key.substring("changeLogParameters.".length()); if ("contexts".equals(property)) contexts = "" + entry.getValue(); } } // Retrieve changeLog table names as they might be overridden by configuration setters databaseChangeLogTableName = database.getDatabaseChangeLogTableName(); databaseChangeLogLockTableName = database.getDatabaseChangeLogLockTableName(); databaseLiquibaseSchemaName = database.getLiquibaseSchemaName(); if (!StringUtils.isBlank(databaseLiquibaseSchemaName)) create().createSchemaIfNotExists(unquotedName(databaseLiquibaseSchemaName)).execute(); // [#9866] Allow for loading included files from the classpath or using absolute paths. // [#12872] [#13021] The decision is made based on the presence of the rootPath property ResourceAccessor ra = StringUtils.isBlank(rootPath) ? new CompositeResourceAccessor( new ClassLoaderResourceAccessor(), new ClassLoaderResourceAccessor(Thread.currentThread().getContextClassLoader()) ) : new DirectoryResourceAccessor(new File(rootPath)); Liquibase liquibase = new Liquibase(scripts, ra, database); liquibase.update(contexts); } @Override protected List getTables0() throws SQLException { List result = new ArrayList<>(super.getTables0()); if (!includeLiquibaseTables) { List liquibaseTables = Arrays.asList(databaseChangeLogTableName, databaseChangeLogLockTableName); result.removeIf(t -> liquibaseTables.contains(t.getName())); } return result; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy