Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
de.tsl2.nano.persistence.DatabaseTool Maven / Gradle / Ivy
package de.tsl2.nano.persistence;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.apache.commons.logging.Log;
import de.tsl2.nano.bean.BeanContainer;
import de.tsl2.nano.core.ENV;
import de.tsl2.nano.core.ManagedException;
import de.tsl2.nano.core.cls.BeanClass;
import de.tsl2.nano.core.log.LogFactory;
import de.tsl2.nano.core.messaging.EMessage;
import de.tsl2.nano.core.util.FileUtil;
import de.tsl2.nano.core.util.NetUtil;
import de.tsl2.nano.core.util.StringUtil;
import de.tsl2.nano.core.util.Util;
import de.tsl2.nano.util.SchedulerUtil;
/**
* Use the jdbc connection to run/evaluate some database specific actions/properties
*
* @author Tom, Thomas Schneider
* @version $Revision$
*/
public class DatabaseTool {
private static final Log LOG = LogFactory.getLog(DatabaseTool.class);
Persistence persistence;
public DatabaseTool(Persistence persistence) {
this.persistence = persistence;
}
public Persistence getPersistence() {
return persistence;
}
public boolean isLocalDatabase(Persistence persistence) {
String url = persistence.getConnectionUrl();
if (!Util.isEmpty(persistence.getPort()) || isH2(url)) {
return Arrays.asList(persistence.STD_LOCAL_DATABASE_DRIVERS).contains(
persistence.getConnectionDriverClass())
&& (url.contains("localhost") || url.contains("127.0.0.1") || isH2(url));
}
return false;
}
public boolean canConnectToLocalDatabase(Persistence persistence) {
if (!Util.isEmpty(persistence.getPort())) {
int p = Integer.valueOf(persistence.getPort());
return NetUtil.isOpen(p);
}
return false;
}
public void addShutdownHook() {
Runtime.getRuntime().addShutdownHook(Executors.defaultThreadFactory().newThread(new Runnable() {
@Override
public void run() {
if (BeanContainer.isInitialized()) {
Persistence persistence = Persistence.current();
EMessage.broadcast(this, "APPLICATION SHUTDOWN INITIALIZED...", "*");
shutdownDBServer();
shutdownDatabase(); //doppelt gemoppelt hält besser ;-)
String hsqldbScript = isH2(persistence.getConnectionUrl())
? persistence.getDefaultSchema() + ".mv.db" : persistence.getDatabase() + ".script";
String backupFile =
ENV.getTempPath() + FileUtil.getUniqueFileName(ENV.get("app.database.backup.file",
persistence.getDatabase()) + ".zip");
LOG.info("creating database backup to file " + backupFile);
FileUtil.writeToZip(backupFile, hsqldbScript, FileUtil.getFileBytes(ENV.getConfigPath() + hsqldbScript, null));
}
}
}));
}
public static void shutdownDatabaseDefault() {
shutdownDatabase(Persistence.H2_DATABASE_URL);
}
public void shutdownDatabase() {
shutdownDatabase(persistence.getConnectionUrl());
}
public static void shutdownDatabase(String url) {
if (BeanContainer.isInitialized()) {
LOG.info("preparing shutdown of local database " + url);
try {
BeanContainer.instance().executeStmt(ENV.get("app.shutdown.statement", "SHUTDOWN"), true, null);
Thread.sleep(2000);
} catch (Exception e) {
LOG.error(e.toString());
}
}
}
public void doPeriodicalBackup() {
//do a periodical backup
SchedulerUtil.runAt(0, -1, TimeUnit.DAYS, new Runnable() {
@Override
public void run() {
LOG.info("preparing backup of local database " + persistence.getConnectionUrl());
try {
BeanContainer.instance().executeStmt(
ENV.get("app.backup.statement", "backup to temp/database-daily-backup.zip"), true, null);
} catch (Exception e) {
LOG.error(e.toString());
}
}
});
}
public Connection getConnection() {
Connection con = null;
try {
Class.forName(persistence.getConnectionDriverClass());
con = DriverManager.getConnection(persistence.getConnectionUrl(), persistence.getConnectionUserName(), persistence.getConnectionPassword());
} catch (Exception e) {
ManagedException.forward(e);
}
return con;
}
public boolean checkJDBCConnection(boolean throwExceptionOnEmpty) {
Connection con = null;
try {
con = getConnection();
ResultSet tables = getTableNames(con);
if (!tables.next()) {
LOG.info("Available tables are:\n" + getTablesAsString(con.getMetaData().getTables(null, null, null, null)));
if (throwExceptionOnEmpty)
throw new ManagedException("The desired jdbc connection provides no tables to work on!");
return false;
}
return true;
} catch (Exception e) {
ManagedException.forward(e);
return false;
} finally {
close(con);
}
}
private static void close(Connection con) {
if (con != null) {
try {
con.close();
} catch (SQLException e) {
ManagedException.forward(e);
}
}
}
private ResultSet getTableNames(Connection con) throws SQLException {
String schema = !Util.isEmpty(persistence.getDefaultSchema()) ? persistence.getDefaultSchema() : null;
ResultSet tables = con.getMetaData().getTables(null, schema, null, null);
return tables;
}
public String[] getTableNames() {
Connection con = null;
try {
con = getConnection();
ResultSet tables = getTableNames(con);
int cc = tables.getMetaData().getColumnCount();
String[] result = new String[cc];
int i = 0;
while(tables.next()) {
result[i++] = tables.getObject("TABLE_NAME").toString();
}
return result;
} catch (Exception e) {
ManagedException.forward(e);
return null;
} finally {
close(con);
}
}
private String getTablesAsString(ResultSet tables) throws SQLException {
StringBuilder str = new StringBuilder();
int cc = tables.getMetaData().getColumnCount();
ArrayList row = new ArrayList<>(cc);
while(tables.next()) {
for (int i = 1; i < cc; i++) {
row.add(tables.getObject(i));
}
str.append(StringUtil.toString(row, -1) + "\n");
row.clear();
}
return str.toString();
}
public void copyJavaDBDriverFiles(Persistence persistence) {
String dest = ENV.getConfigPath();
if (persistence.getConnectionUrl().contains("derby") && ! new File(dest + "derby.jar").exists()) {
String path = System.getProperty("java.home") + "/../db/lib/";
if (new File(path + "derby.jar").canRead()) {
LOG.info("copying derby/javadb database driver files to environment");
FileUtil.copy(path + "derby.jar", dest + "derby.jar");
FileUtil.copy(path + "derbynet.jar", dest + "derbynet.jar");
FileUtil.copy(path + "derbytools.jar", dest + "derbytools.jar");
FileUtil.copy(path + "derbyclient.jar", dest + "derbyclient.jar");
try {
FileUtil.writeBytes("java -cp * org.apache.derby.drda.NetworkServerControl start %*".getBytes(), dest + "runServer.cmd", false);
FileUtil.writeBytes("java -cp derby*.jar org.apache.derby.drda.NetworkServerControl start %*".getBytes(), dest + "runServer.sh", false);
} catch (Exception e) {
LOG.warn(e.toString());
}
} else {
LOG.warn("cannot copy derby driver files from jdk path: " + path);
}
}
}
/**
* extracts the port of the given database url
* @param url database url
* @return port or null
*/
public static String getPort(String url) {
return StringUtil.extract(url, "[:](\\d+)([:/;]\\w+)?", 1);
}
/**
* see {@link #isEmbeddedDatabase(String)}
*/
public boolean isEmbeddedDatabase() {
return isEmbeddedDatabase(persistence.getConnectionUrl());
}
/**
* isEmbeddedDatabase
* @param urlOrDriver
* @return true, if it contains hsqldb or h2
*/
public static boolean isEmbeddedDatabase(String urlOrDriver) {
return (urlOrDriver.contains("hsqldb")
|| urlOrDriver.contains("h2"));
}
public static boolean isH2(String url) {
return url.matches("jdbc[:]h2[:].*");
}
/**
* url to an sql tool, if it is an embedded database.
* @return optional SQL Tool like the one of H2 on port 8082
*/
public String getSQLToolURL() {
return isEmbeddedDatabase() && isH2(persistence.getConnectionUrl())
? ENV.get("app.database.sqltool.url", "http://localhost:8082") : null;
}
public void replaceKeyWords() {
if (isH2(persistence.getConnectionUrl()))
H2DatabaseTool.replaceKeyWords(persistence);
}
public static Boolean isDBRunInternally() {
return ENV.get("app.database.internal.server.run", false);
}
/* mostly H2 functions - generalized and without linking to dependencies */
public void runDBServer() {
runDBServer(ENV.getConfigPath(), persistence.getPort());
}
public static void runDBServerDefault() {
runDBServer(ENV.getConfigPath(), Persistence.current().getPort());
}
public static void runDBServer(String... args) {
String cmd = ENV.get("app.database.internal.server.run.cmd", "org.h2.tools.Server.main(-baseDir, {0}, -tcp, -tcpPort, {1}, -trace, -ifNotExists)");
LOG.info("running database internally: " + cmd + "[" + Arrays.toString(args) + "]");
BeanClass.call(cmd, args);
}
public static void shutdownDBServerDefault() {
shutdownDBServer(Persistence.current().getConnectionUrl(), "");
}
public void shutdownDBServer() {
shutdownDBServer(persistence.getConnectionUrl(), persistence.getConnectionPassword());
}
public static void shutdownDBServer(String... args) {
String cmd = ENV.get("app.database.internal.server.shutdown.cmd", "org.h2.tools.Server.shutdownTcpServer({0}, {1}, true, true)");
LOG.info("shutdown database server: " + cmd + "[" + args[0] + ", ***]");
try {
BeanClass.call(cmd, args);
} catch (Exception e) {
LOG.error(e.toString());
}
}
public static void dbDump(String... args) {//unused yet!
FileUtil.writeBytes("SCRIPT TO 'db-dump.sql'".getBytes(), "dump.sql", false);
String cmd = ENV.get("app.database.internal.server.dump.cmd", "org.h2.tools.RunScript -url \"{0}\" -user {1} -password {2} -script dump.sql -showResults");
LOG.info("dump database : " + cmd + "[" + args[0] + ", ***]");
try {
BeanClass.call(cmd, args);
} catch (Exception e) {
LOG.error(e.toString());
}
}
}