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

eu.unicore.persist.impl.H2Persist Maven / Gradle / Ivy

There is a newer version: 1.2.3
Show newest version
package eu.unicore.persist.impl;

import java.io.File;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.sql.ConnectionPoolDataSource;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.h2.engine.Constants;
import org.h2.jdbcx.JdbcDataSource;

import eu.unicore.persist.PersistenceException;
import eu.unicore.persist.PersistenceProperties;

/**
 * H2 database based persistence
 * 
 * @author schuller
 */
public class H2Persist extends PersistImpl{

	private static final Logger logger = LogManager.getLogger("unicore.persistence.H2Persist");

	protected Boolean serverMode=null;

	String connectionURL;

	// setup periodic cache cleanup due to h2 issue with increasing cache memory use
	private static final Set> instances = new HashSet<>();
	
	private static final Thread cleanupThread;
	
	private static long cacheCleanupPeriod = 10; // minutes
	
	static{
		cleanupThread = new Thread(()->
			{
				logger.debug("Will reset H2 caches every <{}> minutes.", cacheCleanupPeriod);
				while(true){
					try{
						Thread.sleep(cacheCleanupPeriod);
						logger.debug("Resetting H2 caches");
						for(H2Persist p : instances){
							p.resetCache();
							Thread.sleep(1000*60*cacheCleanupPeriod);
						}
					}catch(Exception ie){}
				}
			}, "H2-Cache-Cleanup");
		cleanupThread.setDaemon(true);
		cleanupThread.start();
	}
	
	public H2Persist(Class daoClass, String tableName) {
		super(daoClass, tableName);
	}

	@Override
	public void init()throws PersistenceException, SQLException {
		super.init();
		if(config==null)return;
		resetCache();
		instances.add(this);
	}

	@Override
	public void shutdown() throws PersistenceException, SQLException {
		instances.remove(this);
		super.shutdown();
	}
	
	protected void resetCache() throws PersistenceException, SQLException {
		try(Connection conn = getConnection()){
			synchronized (conn) {
				try(Statement s = conn.createStatement()){
					String cacheSize = config.getSubkeyValue(PersistenceProperties.H2_CACHESIZE, pd.getTableName());
					s.execute("SET CACHE_SIZE "+cacheSize);
					logger.debug("Set H2 cache size to {} kb.", cacheSize);
				}
			}
		}
	}
	
	@Override
	protected List getSQLCreateTable() throws PersistenceException, SQLException {
		Listcmds = new ArrayList<>();
		String stringType = getSQLStringType();
		cmds.add(String.format("CREATE TABLE IF NOT EXISTS %s (id %s PRIMARY KEY, data %s)",
				pd.getTableName(), stringType, stringType));
		boolean haveTable = tableExists();
		if(pd.getColumns().size()>0){
			for(ColumnDescriptor c: pd.getColumns()){
				if(!haveTable || !columnExists(c.getColumn())){
					cmds.add(String.format("ALTER TABLE %s ADD COLUMN %s %s",
							pd.getTableName(), c.getColumn(), stringType));
				}
			}
		}
		if(!haveTable || !columnExists("CREATED")){
			cmds.add(String.format("ALTER TABLE %s ADD COLUMN CREATED %s NOT NULL DEFAULT '%s'",
					pd.getTableName(), stringType, getTimeStamp()));
		}
		return cmds;
	}

	@Override
	protected String getSQLStringType(){
		return "VARCHAR";
	}

	@Override
	protected String getSQLShutdown(){
		return "SHUTDOWN SCRIPT";
	}

	public Boolean getServerMode() {
		return serverMode;
	}

	public void setServerMode(boolean serverMode) {
		this.serverMode = serverMode;
	}

	private String createConnString(){
		if(connectionURL!=null){
			return connectionURL;
		}

		String tableName=pd.getTableName();
		String dir=null;

		if(serverMode==null){
			serverMode=config==null?false:Boolean.parseBoolean(config.getSubkeyValue(PersistenceProperties.H2_SERVER_MODE, tableName));
		}

		if(config!=null){
			dir=config.getSubkeyValue(PersistenceProperties.DB_DIRECTORY,tableName);
		}

		if(!(new File(dir).isAbsolute())){
			dir="./"+dir;
		}

		String params="DB_CLOSE_ON_EXIT=FALSE";
		String additionalParams=config==null?null:config.getSubkeyValue(PersistenceProperties.H2_OPTIONS, tableName);
		if(additionalParams!=null){
			params+=";"+additionalParams;
		}
		String id=getDatabaseName();
		if(serverMode){
			String host=config==null?"localhost":config.getSubkeyValue(PersistenceProperties.DB_HOST, pd.getTableName());
			String port=config==null?"3306":config.getSubkeyValue(PersistenceProperties.DB_PORT, pd.getTableName());
			connectionURL="jdbc:h2:tcp://"+host+":"+port+"/"+dir+File.separator+id+";AUTO_RECONNECT=TRUE;"+params;
		}else{
			connectionURL= "jdbc:h2:file:"+dir+File.separator+id+";"+params;
		}

		logger.info("Connecting to: "+connectionURL);
		return connectionURL;
	}

	@Override
	protected int getDefaultPort() {
		return  Constants.DEFAULT_TCP_PORT;
	}

	@Override
	protected String getDefaultDriverName(){
		return "org.h2.Driver";
	}

	@Override
	protected ConnectionPoolDataSource getConnectionPoolDataSource(){
		JdbcDataSource ds=new JdbcDataSource();
		ds.setURL(createConnString());
		ds.setUser(getUserName());
		ds.setPassword(getPassword());
		return ds;
	}

	@Override
	protected String getUserName(){
		return "sa";
	}

	@Override
	protected String getPassword(){
		return "";
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy