comparison artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/CompiledStatement.java @ 5838:5aa05a7a34b7

Rename modules to more fitting names.
author Sascha L. Teichmann <teichmann@intevation.de>
date Thu, 25 Apr 2013 15:23:37 +0200
parents flys-artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/CompiledStatement.java@bd047b71ab37
children 4897a58c8746
comparison
equal deleted inserted replaced
5837:d9901a08d0a6 5838:5aa05a7a34b7
1 package org.dive4elements.river.artifacts.datacage.templating;
2
3 import java.util.regex.Pattern;
4 import java.util.regex.Matcher;
5
6 import java.util.List;
7 import java.util.Map;
8 import java.util.TreeMap;
9 import java.util.ArrayList;
10
11 import java.sql.PreparedStatement;
12 import java.sql.SQLException;
13 import java.sql.Connection;
14 import java.sql.ResultSet;
15
16 import net.sf.ehcache.Cache;
17 import net.sf.ehcache.Element;
18
19 import org.dive4elements.river.artifacts.cache.CacheFactory;
20
21 import org.apache.log4j.Logger;
22
23 /** SQL Statement, create PreparedStatement. */
24 public class CompiledStatement
25 {
26 private static Logger log = Logger.getLogger(CompiledStatement.class);
27
28 public static final String DATACAGE_DB_CACHE =
29 "datacage.db";
30
31 public static final Pattern VAR =
32 Pattern.compile("\\$\\{([a-zA-Z0-9_-]+)\\}");
33
34 protected String original;
35 protected String statement;
36
37 protected Map<String, List<Integer>> positions;
38
39 protected int numVars;
40
41 public class Instance {
42
43 protected PreparedStatement preparedStatement;
44
45 public Instance() {
46 }
47
48 /** Executes a Statement. */
49 protected ResultData executeCached(
50 Cache cache,
51 Connection connection,
52 StackFrames frames
53 )
54 throws SQLException
55 {
56 log.debug("executeCached");
57 Object [] values = new Object[numVars];
58
59 StringBuilder sb = new StringBuilder(original);
60
61 for (Map.Entry<String, List<Integer>> entry: positions.entrySet()) {
62 String key = entry.getKey();
63 Object value = frames.get(key);
64 sb.append(';').append(key).append(':').append(value);
65 for (Integer index: entry.getValue()) {
66 values[index] = value;
67 }
68 }
69
70 // XXX: Maybe too many collisions?
71 // String key = original + Arrays.hashCode(values);
72 String key = sb.toString();
73
74 Element element = cache.get(key);
75
76 if (element != null) {
77 return (ResultData)element.getValue();
78 }
79
80 if (preparedStatement == null) {
81 preparedStatement = connection.prepareStatement(statement);
82 }
83
84 for (int i = 0; i < values.length; ++i) {
85 preparedStatement.setObject(i+1, values[i]);
86 }
87
88 ResultData data;
89
90 if (log.isDebugEnabled()) {
91 log.debug("executing: " + statement);
92 }
93
94 ResultSet result = preparedStatement.executeQuery();
95 try {
96 data = new ResultData(preparedStatement.getMetaData())
97 .addAll(result);
98 }
99 finally {
100 result.close();
101 }
102
103 element = new Element(key, data);
104 cache.put(element);
105
106 return data;
107 }
108
109 protected ResultData executeUncached(
110 Connection connection,
111 StackFrames frames
112 )
113 throws SQLException
114 {
115 log.debug("executeUncached");
116 if (preparedStatement == null) {
117 if (log.isDebugEnabled()) {
118 log.debug("preparing statement: " + statement);
119 }
120 preparedStatement = connection.prepareStatement(statement);
121 }
122
123 for (Map.Entry<String, List<Integer>> entry: positions.entrySet()) {
124 Object value = frames.get(entry.getKey());
125 for (Integer index: entry.getValue()) {
126 preparedStatement.setObject(index+1, value);
127 }
128 }
129
130 if (log.isDebugEnabled()) {
131 log.debug("executing: " + statement);
132 }
133
134 ResultSet result = preparedStatement.executeQuery();
135 try {
136 return new ResultData(preparedStatement.getMetaData())
137 .addAll(result);
138 }
139 finally {
140 result.close();
141 }
142 }
143
144 public ResultData execute(
145 Connection connection,
146 StackFrames frames,
147 boolean cached
148 )
149 throws SQLException
150 {
151 if (!cached) {
152 return executeUncached(connection, frames);
153 }
154
155 Cache cache = CacheFactory.getCache(DATACAGE_DB_CACHE);
156
157 return cache != null
158 ? executeCached(cache, connection, frames)
159 : executeUncached(connection, frames);
160 }
161
162 public void close() {
163 if (preparedStatement != null) {
164 try {
165 preparedStatement.close();
166 }
167 catch (SQLException sqle) {
168 }
169 preparedStatement = null;
170 }
171 }
172 } // class Instance
173
174 public CompiledStatement() {
175 }
176
177 public CompiledStatement(String original) {
178 this.original = original;
179 // TreeMap to ensure order
180 positions = new TreeMap<String, List<Integer>>();
181 compile();
182 }
183
184 protected void compile() {
185
186 StringBuffer sb = new StringBuffer();
187
188 Matcher m = VAR.matcher(original);
189
190 int index = 0;
191
192 // Find variables like ${varname}.
193 while (m.find()) {
194 String key = m.group(1).toUpperCase();
195 List<Integer> indices = positions.get(key);
196 if (indices == null) {
197 indices = new ArrayList<Integer>();
198 positions.put(key, indices);
199 }
200 indices.add(index);
201 m.appendReplacement(sb, "?");
202 ++index;
203 }
204
205 m.appendTail(sb);
206
207 numVars = index;
208
209 statement = sb.toString();
210 }
211
212 public String getStatement() {
213 return statement;
214 }
215 }
216 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org