Mercurial > dive4elements > river
comparison 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 |
comparison
equal
deleted
inserted
replaced
971:d0c9a5f32c30 | 972:0c8aca463bd4 |
---|---|
3 import java.util.regex.Pattern; | 3 import java.util.regex.Pattern; |
4 import java.util.regex.Matcher; | 4 import java.util.regex.Matcher; |
5 | 5 |
6 import java.util.List; | 6 import java.util.List; |
7 import java.util.Map; | 7 import java.util.Map; |
8 import java.util.HashMap; | 8 import java.util.TreeMap; |
9 import java.util.ArrayList; | 9 import java.util.ArrayList; |
10 | 10 |
11 import java.sql.PreparedStatement; | 11 import java.sql.PreparedStatement; |
12 import java.sql.SQLException; | 12 import java.sql.SQLException; |
13 import java.sql.Connection; | 13 import java.sql.Connection; |
14 import java.sql.ResultSet; | 14 import java.sql.ResultSet; |
15 | 15 |
16 import net.sf.ehcache.Cache; | |
17 import net.sf.ehcache.Element; | |
18 | |
19 import de.intevation.flys.artifacts.cache.CacheFactory; | |
20 | |
16 public class CompiledStatement | 21 public class CompiledStatement |
17 { | 22 { |
23 public static final String DATACAGE_DB_CACHE = | |
24 "datacage.db"; | |
25 | |
18 public static final Pattern VAR = | 26 public static final Pattern VAR = |
19 Pattern.compile("\\$\\{([a-zA-Z0-9_-]+)\\}"); | 27 Pattern.compile("\\$\\{([a-zA-Z0-9_-]+)\\}"); |
20 | 28 |
21 protected String original; | 29 protected String original; |
22 protected String statement; | 30 protected String statement; |
23 | 31 |
24 protected Map<String, List<Integer>> positions; | 32 protected Map<String, List<Integer>> positions; |
25 | 33 |
26 protected PreparedStatement preparedStatement; | 34 protected PreparedStatement preparedStatement; |
27 | 35 |
36 protected int numVars; | |
37 | |
28 public CompiledStatement() { | 38 public CompiledStatement() { |
29 } | 39 } |
30 | 40 |
31 public CompiledStatement(String original) { | 41 public CompiledStatement(String original) { |
32 this.original = original; | 42 this.original = original; |
33 positions = new HashMap<String, List<Integer>>(); | 43 // TreeMap to ensure order |
44 positions = new TreeMap<String, List<Integer>>(); | |
34 compile(); | 45 compile(); |
35 } | 46 } |
36 | 47 |
37 protected void compile() { | 48 protected void compile() { |
38 | 49 |
39 StringBuffer sb = new StringBuffer(); | 50 StringBuffer sb = new StringBuffer(); |
40 | 51 |
41 Matcher m = VAR.matcher(original); | 52 Matcher m = VAR.matcher(original); |
42 | 53 |
43 int index = 1; | 54 int index = 0; |
44 | 55 |
45 while (m.find()) { | 56 while (m.find()) { |
46 String key = m.group(1); | 57 String key = m.group(1); |
47 List<Integer> indices = positions.get(key); | 58 List<Integer> indices = positions.get(key); |
48 if (indices == null) { | 59 if (indices == null) { |
54 ++index; | 65 ++index; |
55 } | 66 } |
56 | 67 |
57 m.appendTail(sb); | 68 m.appendTail(sb); |
58 | 69 |
70 numVars = index; | |
71 | |
59 statement = sb.toString(); | 72 statement = sb.toString(); |
60 } | 73 } |
61 | 74 |
62 public String getStatement() { | 75 public String getStatement() { |
63 return statement; | 76 return statement; |
64 } | 77 } |
65 | 78 |
66 public ResultData execute(Connection connection, StackFrames frames) | 79 protected ResultData executeCached( |
80 Cache cache, | |
81 Connection connection, | |
82 StackFrames frames | |
83 ) | |
84 throws SQLException | |
85 { | |
86 Object [] values = new Object[numVars]; | |
87 | |
88 StringBuilder sb = new StringBuilder(original); | |
89 | |
90 for (Map.Entry<String, List<Integer>> entry: positions.entrySet()) { | |
91 String key = entry.getKey(); | |
92 Object value = frames.get(key); | |
93 sb.append(';').append(key).append(':').append(value); | |
94 for (Integer index: entry.getValue()) { | |
95 values[index] = value; | |
96 } | |
97 } | |
98 | |
99 // XXX: Maybe too many collisions? | |
100 // String key = original + Arrays.hashCode(values); | |
101 String key = sb.toString(); | |
102 | |
103 Element element = cache.get(key); | |
104 | |
105 if (element != null) { | |
106 return (ResultData)element.getValue(); | |
107 } | |
108 | |
109 if (preparedStatement == null) { | |
110 preparedStatement = connection.prepareStatement(statement); | |
111 } | |
112 | |
113 for (int i = 0; i < values.length; ++i) { | |
114 preparedStatement.setObject(i+1, values[i]); | |
115 } | |
116 | |
117 ResultData data; | |
118 | |
119 ResultSet result = preparedStatement.executeQuery(); | |
120 try { | |
121 data = new ResultData(preparedStatement.getMetaData()) | |
122 .addAll(result); | |
123 } | |
124 finally { | |
125 result.close(); | |
126 } | |
127 | |
128 element = new Element(key, data); | |
129 cache.put(element); | |
130 | |
131 return data; | |
132 } | |
133 | |
134 protected ResultData executeUncached( | |
135 Connection connection, | |
136 StackFrames frames | |
137 ) | |
67 throws SQLException | 138 throws SQLException |
68 { | 139 { |
69 if (preparedStatement == null) { | 140 if (preparedStatement == null) { |
70 preparedStatement = connection.prepareStatement(statement); | 141 preparedStatement = connection.prepareStatement(statement); |
71 } | 142 } |
72 | 143 |
73 for (Map.Entry<String, List<Integer>> entry: positions.entrySet()) { | 144 for (Map.Entry<String, List<Integer>> entry: positions.entrySet()) { |
74 Object value = frames.get(entry.getKey()); | 145 Object value = frames.get(entry.getKey()); |
75 for (Integer index: entry.getValue()) { | 146 for (Integer index: entry.getValue()) { |
76 preparedStatement.setObject(index, value); | 147 preparedStatement.setObject(index+1, value); |
77 } | 148 } |
78 } | 149 } |
79 | 150 |
80 ResultSet result = preparedStatement.executeQuery(); | 151 ResultSet result = preparedStatement.executeQuery(); |
81 try { | 152 try { |
83 .addAll(result); | 154 .addAll(result); |
84 } | 155 } |
85 finally { | 156 finally { |
86 result.close(); | 157 result.close(); |
87 } | 158 } |
159 } | |
160 | |
161 public ResultData execute(Connection connection, StackFrames frames) | |
162 throws SQLException | |
163 { | |
164 Cache cache = CacheFactory.getCache(DATACAGE_DB_CACHE); | |
165 | |
166 return cache != null | |
167 ? executeCached(cache, connection, frames) | |
168 : executeUncached(connection, frames); | |
88 } | 169 } |
89 | 170 |
90 public void close() { | 171 public void close() { |
91 if (preparedStatement != null) { | 172 if (preparedStatement != null) { |
92 try { | 173 try { |