package org.aksw.jena_sparql_api.cache.h2; import java.io.InputStream; import java.io.InputStreamReader; import java.sql.Connection; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import org.aksw.jena_sparql_api.cache.core.QueryExecutionFactoryCacheEx; import org.aksw.jena_sparql_api.cache.extra.CacheBackend; import org.aksw.jena_sparql_api.cache.extra.CacheFrontend; import org.aksw.jena_sparql_api.cache.extra.CacheFrontendImpl; import org.aksw.jena_sparql_api.cache.staging.CacheBackendDao; import org.aksw.jena_sparql_api.cache.staging.CacheBackendDaoPostgres; import org.aksw.jena_sparql_api.cache.staging.CacheBackendDataSource; import org.aksw.jena_sparql_api.core.QueryExecutionFactory; import org.apache.commons.lang3.StringUtils; import org.h2.jdbcx.JdbcDataSource; import org.h2.tools.RunScript; /** * Utils for generating a cache * * @author Dimitris Kontokostas * @since 7/1/14 4:59 PM */ public class CacheUtilsH2 { /** * Create a cache frontend based on H2 database * * @param dbName the name of the DB * @param dbInMemory true creates this database in memory, otherwise in a file * @param cacheTTL the Time-To-Live for the cache * @return an initialized CacheFrontend or throws an a RuntimeException in case of error * @throws RuntimeException in case of error */ public static CacheFrontend createCacheFrontend(String dbName, boolean dbInMemory, long cacheTTL) { CacheFrontend result = createCacheFrontend(null, dbName, dbInMemory, cacheTTL); return result; } public static CacheFrontend createCacheFrontend(String dbDir, String dbName, boolean dbInMemory, long cacheTTL) { String dbType = "file"; if (dbInMemory) { dbType = "mem:"; } String dbd = StringUtils.isEmpty(dbDir) ? "" : dbDir + "/"; List<String> options = new ArrayList<String>(); if(!dbInMemory) { options.add("AUTO_SERVER=TRUE"); } options.add("AUTO_RECONNECT=TRUE"); options.add("DB_CLOSE_DELAY=-1"); String optionsStr = options.stream().collect(Collectors.joining(";")); try { Class.forName("org.h2.Driver"); //jdbc:h2:" + dbDir + "/" JdbcDataSource dataSource = new JdbcDataSource(); dataSource.setURL("jdbc:h2:" + dbType + ":" + dbd + dbName + ";" + optionsStr); dataSource.setUser("sa"); dataSource.setPassword("sa"); String schemaResourceName = "/org/aksw/jena_sparql_api/cache/cache-schema-pgsql.sql"; InputStream in = CacheBackendDao.class.getResourceAsStream(schemaResourceName); if (in == null) { throw new RuntimeException("Failed to load resource: " + schemaResourceName); } InputStreamReader reader = new InputStreamReader(in); Connection conn = dataSource.getConnection(); try { RunScript.execute(conn, reader); } finally { conn.close(); } CacheBackendDao dao = new CacheBackendDaoPostgres(cacheTTL); CacheBackend cacheBackend = new CacheBackendDataSource(dataSource, dao); return new CacheFrontendImpl(cacheBackend); } catch (Exception e) { throw new RuntimeException("Cannot create H2 CacheFrontend", e); } } /** * Create a QueryExecutionFactory that uses an H2 database as a cache * * @param decoratee the QueryExecutionFactory we want to decorate * @param dbName the name of the DB * @param dbInMemory true creates this database in memory, otherwise in a file * @param cacheTTL the Time-To-Live for the cache * @return an initialized CacheFrontend or throws an a RuntimeException in case of error * @throws RuntimeException in case of error */ public static QueryExecutionFactory createQueryExecutionFactory(QueryExecutionFactory decoratee, String dbName, boolean dbInMemory, long cacheTTL) { CacheFrontend cacheFrontend = createCacheFrontend(dbName, dbInMemory, cacheTTL); return new QueryExecutionFactoryCacheEx(decoratee, cacheFrontend); } }