/*
* Copyright (C) 2014 University of Dundee & Open Microscopy Environment.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package ome.services.util;
import ome.system.PreferenceContext;
import ome.util.SqlAction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;
/**
* Utility methods for checking if startup-time database adjustments have yet been performed.
* @author m.t.b.carroll@dundee.ac.uk
* @since 5.0.2
*/
abstract class BaseDBCheck {
private static final Logger log = LoggerFactory.getLogger(BaseDBCheck.class);
/** executor useful for performing database adjustments */
protected final Executor executor;
/* current database version */
private final String version;
private final int patch;
private final String configKey = "DB check " + getClass().getSimpleName();
private final String configValue = getCheckDone();
private final String configKeyValue = configKey + ": " + configValue;
/**
* @param executor executor to use for configuration map check
*/
protected BaseDBCheck(Executor executor, PreferenceContext preferences) {
this.executor = executor;
this.version = preferences.getProperty("omero.db.version");
this.patch = Integer.parseInt(preferences.getProperty("omero.db.patch"));
}
/**
* @return if the database adjustment is not yet performed
*/
private boolean isCheckRequired() {
return (Boolean) executor.executeSql(
new Executor.SimpleSqlWork(this, "BaseDBCheck") {
@Transactional(readOnly = true)
public Boolean doWork(SqlAction sql) {
return !configValue.equals(sql.configValue(configKey));
}
});
}
/**
* The database adjustment is to be performed.
*/
private void checkIsStarting() {
executor.executeSql(
new Executor.SimpleSqlWork(this, "BaseDBCheck") {
@Transactional(readOnly = false)
public Object doWork(SqlAction sql) {
sql.addMessageWithinDbPatchStart(version, patch, configKeyValue);
return null;
}
});
}
/**
* The database adjustment is now performed.
* Hereafter {@link #isCheckRequired()} should return {@code false}.
*/
private void checkIsDone() {
executor.executeSql(
new Executor.SimpleSqlWork(this, "BaseDBCheck") {
@Transactional(readOnly = false)
public Object doWork(SqlAction sql) {
sql.addMessageWithinDbPatchEnd(version, patch, configKeyValue);
sql.updateOrInsertConfigValue(configKey, configValue);
return null;
}
});
}
/**
* Do the database adjustment only if not already performed.
*/
public void start() {
if (isCheckRequired()) {
checkIsStarting();
doCheck();
checkIsDone();
log.info("performed " + configKeyValue);
} else if (log.isDebugEnabled()) {
log.debug("skipped " + configKey);
}
}
/**
* Do the database adjustment.
*/
protected abstract void doCheck();
/**
* @return a string identifying that the check is done, never {@code null}
*/
protected String getCheckDone() {
return "done";
}
}