Mercurial > dive4elements > river
diff flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/meta/CompiledStatement.java @ 972:0c8aca463bd4
Added caching support for the static part of the datacage.
flys-artifacts/trunk@2398 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Fri, 22 Jul 2011 16:55:36 +0000 |
parents | 2c8fc60125b9 |
children | c30ada285d45 |
line wrap: on
line diff
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/meta/CompiledStatement.java Fri Jul 22 11:18:00 2011 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/meta/CompiledStatement.java Fri Jul 22 16:55:36 2011 +0000 @@ -5,7 +5,7 @@ import java.util.List; import java.util.Map; -import java.util.HashMap; +import java.util.TreeMap; import java.util.ArrayList; import java.sql.PreparedStatement; @@ -13,8 +13,16 @@ import java.sql.Connection; import java.sql.ResultSet; +import net.sf.ehcache.Cache; +import net.sf.ehcache.Element; + +import de.intevation.flys.artifacts.cache.CacheFactory; + public class CompiledStatement { + public static final String DATACAGE_DB_CACHE = + "datacage.db"; + public static final Pattern VAR = Pattern.compile("\\$\\{([a-zA-Z0-9_-]+)\\}"); @@ -25,12 +33,15 @@ protected PreparedStatement preparedStatement; + protected int numVars; + public CompiledStatement() { } public CompiledStatement(String original) { this.original = original; - positions = new HashMap<String, List<Integer>>(); + // TreeMap to ensure order + positions = new TreeMap<String, List<Integer>>(); compile(); } @@ -40,7 +51,7 @@ Matcher m = VAR.matcher(original); - int index = 1; + int index = 0; while (m.find()) { String key = m.group(1); @@ -56,6 +67,8 @@ m.appendTail(sb); + numVars = index; + statement = sb.toString(); } @@ -63,7 +76,65 @@ return statement; } - public ResultData execute(Connection connection, StackFrames frames) + protected ResultData executeCached( + Cache cache, + Connection connection, + StackFrames frames + ) + throws SQLException + { + Object [] values = new Object[numVars]; + + StringBuilder sb = new StringBuilder(original); + + for (Map.Entry<String, List<Integer>> entry: positions.entrySet()) { + String key = entry.getKey(); + Object value = frames.get(key); + sb.append(';').append(key).append(':').append(value); + for (Integer index: entry.getValue()) { + values[index] = value; + } + } + + // XXX: Maybe too many collisions? + // String key = original + Arrays.hashCode(values); + String key = sb.toString(); + + Element element = cache.get(key); + + if (element != null) { + return (ResultData)element.getValue(); + } + + if (preparedStatement == null) { + preparedStatement = connection.prepareStatement(statement); + } + + for (int i = 0; i < values.length; ++i) { + preparedStatement.setObject(i+1, values[i]); + } + + ResultData data; + + ResultSet result = preparedStatement.executeQuery(); + try { + data = new ResultData(preparedStatement.getMetaData()) + .addAll(result); + } + finally { + result.close(); + } + + element = new Element(key, data); + cache.put(element); + + return data; + } + + protected ResultData executeUncached( + Connection connection, + StackFrames frames + ) throws SQLException { if (preparedStatement == null) { @@ -73,7 +144,7 @@ for (Map.Entry<String, List<Integer>> entry: positions.entrySet()) { Object value = frames.get(entry.getKey()); for (Integer index: entry.getValue()) { - preparedStatement.setObject(index, value); + preparedStatement.setObject(index+1, value); } } @@ -87,6 +158,16 @@ } } + public ResultData execute(Connection connection, StackFrames frames) + throws SQLException + { + Cache cache = CacheFactory.getCache(DATACAGE_DB_CACHE); + + return cache != null + ? executeCached(cache, connection, frames) + : executeUncached(connection, frames); + } + public void close() { if (preparedStatement != null) { try {