H2SharedDB.java
/*
* Copyright 2018 Gregory Graham.
*
* Commercial licenses are available, please contact info@gregs.co.nz for details.
*
* This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
* To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/
* or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
*
* You are free to:
* Share - copy and redistribute the material in any medium or format
* Adapt - remix, transform, and build upon the material
*
* The licensor cannot revoke these freedoms as long as you follow the license terms.
* Under the following terms:
*
* Attribution -
* You must give appropriate credit, provide a link to the license, and indicate if changes were made.
* You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
* NonCommercial -
* You may not use the material for commercial purposes.
* ShareAlike -
* If you remix, transform, or build upon the material,
* you must distribute your contributions under the same license as the original.
* No additional restrictions -
* You may not apply legal terms or technological measures that legally restrict others from doing anything the
* license permits.
*
* Check the Creative Commons website for any details, legalese, and updates.
*/
package nz.co.gregs.dbvolution.databases;
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sql.DataSource;
import nz.co.gregs.dbvolution.databases.settingsbuilders.H2SharedSettingsBuilder;
import nz.co.gregs.dbvolution.exceptions.ExceptionDuringDatabaseFeatureSetup;
import org.h2.tools.Server;
public class H2SharedDB extends H2DB {
private final static long serialVersionUID = 1l;
Server server = null;
public H2SharedDB(File file, String username, String password) throws IOException, SQLException {
this(file.getAbsoluteFile().toString(), username, password);
}
public H2SharedDB(DataSource dataSource) throws SQLException {
super(dataSource);
}
private H2SharedDB(String jdbcURL, String username, String password, boolean dummy) throws SQLException {
super(jdbcURL, username, password);
}
public H2SharedDB(String databaseName, String username, String password) throws SQLException {
this("localhost", databaseName, username, password);
}
public H2SharedDB(String serverName, String databaseName, String username, String password) throws SQLException {
this("jdbc:h2:tcp://" + serverName + "/" + databaseName, username, password, false);
this.setDatabaseName(databaseName);
}
public H2SharedDB(DatabaseConnectionSettings settings) throws SQLException {
super(settings);
}
public H2SharedDB(H2SharedSettingsBuilder settingsBuilder) throws SQLException {
super(settingsBuilder);
}
@Override
public synchronized void addDatabaseSpecificFeatures(Statement stmt) throws ExceptionDuringDatabaseFeatureSetup {
super.addDatabaseSpecificFeatures(stmt);
}
@Override
protected void startServerIfRequired() {
if (isLocalhostServer()) {
if (internalServerIsNotRunning()) {
if (serverIsUnreachable()) {
try {
server = startInternalServer();
if (internalServerIsNotRunning()) {
//try a second time just in case
server = startInternalServer();
}
if (internalServerIsRunning()) {
// the server can be assigned a random port during startup so update our settings
getSettings().setPort("" + server.getPort());
}
} catch (SQLException ex) {
Logger.getLogger(H2SharedDB.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}
protected boolean internalServerIsRunning() {
return server != null && server.isRunning(false);
}
protected boolean internalServerIsNotRunning() {
return server == null || !server.isRunning(false);
}
protected Server startInternalServer() throws SQLException {
if (getPort().isEmpty()) {
return Server.createTcpServer("-tcpAllowOthers", "-ifNotExists", "-tcpDaemon").start();
} else {
return Server.createTcpServer("-tcpAllowOthers", "-ifNotExists", "-tcpDaemon", "-tcpPort", getPort()).start();
}
}
public boolean isLocalhostServer() {
return getHost() == null || getHost().equals("") || getHost().equalsIgnoreCase("localhost") || getHost().startsWith("127.0.0");
}
@Override
public synchronized void stop() {
super.stop();
if (internalServerIsRunning()) {
server.stop();
}
}
private boolean serverIsUnreachable() {
try {
tryToReachServer();
return false;
} catch (Exception ex) {
}
return true;
}
private void tryToReachServer() throws SQLException {
getConnectionFromDriverManager().close();
}
@Override
public H2SharedSettingsBuilder getURLInterpreter() {
return new H2SharedSettingsBuilder();
}
}