comparison flys-aft/src/main/java/de/intevation/db/Statements.java @ 4069:a4e79e8e0aa0

Added support for symbolic SQL statements. flys-aft/trunk@3390 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 12 Dec 2011 17:52:58 +0000
parents 21e49e0a2307
children 2c70fae83d0c
comparison
equal deleted inserted replaced
4068:21e49e0a2307 4069:a4e79e8e0aa0
5 import java.io.IOException; 5 import java.io.IOException;
6 import java.io.InputStream; 6 import java.io.InputStream;
7 7
8 import org.apache.log4j.Logger; 8 import org.apache.log4j.Logger;
9 9
10 import java.util.List;
11 import java.util.ArrayList;
12 import java.util.Map;
13 import java.util.HashMap;
14 import java.util.Enumeration;
15
16 import java.sql.Connection;
17 import java.sql.SQLException;
18 import java.sql.PreparedStatement;
19 import java.sql.Timestamp;
20
21 import java.util.regex.Matcher;
22 import java.util.regex.Pattern;
23
10 public class Statements 24 public class Statements
11 { 25 {
26 public static final Pattern VAR = Pattern.compile(":([a-zA-Z0-9_]+)");
27
28 public static class SymbolicStatement {
29
30 protected String statement;
31 protected String compiled;
32 protected Map<String, List<Integer>> positions;
33
34 public class Instance {
35
36 /** TODO: Support more types. */
37
38 protected PreparedStatement stmnt;
39
40 public Instance(Connection connection) throws SQLException {
41 stmnt = connection.prepareStatement(compiled);
42 }
43
44 public void close() {
45 try {
46 stmnt.close();
47 }
48 catch (SQLException sqle) {
49 log.error("cannot close statement", sqle);
50 }
51 }
52
53 public void setInt(String key, int value)
54 throws SQLException
55 {
56 List<Integer> pos = positions.get(key.toLowerCase());
57 if (pos != null) {
58 for (Integer p: pos) {
59 stmnt.setInt(p, value);
60 }
61 }
62 }
63
64 public void setString(String key, String value)
65 throws SQLException
66 {
67 List<Integer> pos = positions.get(key.toLowerCase());
68 if (pos != null) {
69 for (Integer p: pos) {
70 stmnt.setString(p, value);
71 }
72 }
73 }
74
75 public void setObject(String key, Object value)
76 throws SQLException
77 {
78 List<Integer> pos = positions.get(key.toLowerCase());
79 if (pos != null) {
80 for (Integer p: pos) {
81 stmnt.setObject(p, value);
82 }
83 }
84 }
85
86 public void setTimestamp(String key, Timestamp value)
87 throws SQLException
88 {
89 List<Integer> pos = positions.get(key.toLowerCase());
90 if (pos != null) {
91 for (Integer p: pos) {
92 stmnt.setTimestamp(p, value);
93 }
94 }
95 }
96
97 public void setDouble(String key, int value)
98 throws SQLException
99 {
100 List<Integer> pos = positions.get(key.toLowerCase());
101 if (pos != null) {
102 for (Integer p: pos) {
103 stmnt.setDouble(p, value);
104 }
105 }
106 }
107
108 public void setNull(String key, int sqlType)
109 throws SQLException
110 {
111 List<Integer> pos = positions.get(key.toLowerCase());
112 if (pos != null) {
113 for (Integer p: pos) {
114 stmnt.setNull(p, sqlType);
115 }
116 }
117 }
118
119 public void set(Map<String, Object> map) throws SQLException {
120 for (Map.Entry<String, Object> entry: map.entrySet()) {
121 setObject(entry.getKey(), entry.getValue());
122 }
123 }
124
125 } // class Instance
126
127 public SymbolicStatement(String statement) {
128 this.statement = statement;
129 compile();
130 }
131
132 public String getStatement() {
133 return statement;
134 }
135
136 protected void compile() {
137 positions = new HashMap<String, List<Integer>>();
138
139 StringBuffer sb = new StringBuffer();
140 Matcher m = VAR.matcher(statement);
141 int index = 1;
142 while (m.find()) {
143 String key = m.group(1).toLowerCase();
144 List<Integer> list = positions.get(key);
145 if (list == null) {
146 list = new ArrayList<Integer>();
147 positions.put(key, list);
148 }
149 list.add(index++);
150 m.appendReplacement(sb, "?");
151 }
152 m.appendTail(sb);
153 compiled = sb.toString();
154 }
155 } // class SymbolicStatement
156
157
12 private static Logger log = Logger.getLogger(Statements.class); 158 private static Logger log = Logger.getLogger(Statements.class);
13 159
14 public static final String RESOURCE_PATH = "/sql/"; 160 public static final String RESOURCE_PATH = "/sql/";
15 public static final String COMMON_PROPERTIES = "-common.properties"; 161 public static final String COMMON_PROPERTIES = "-common.properties";
16 162
17 protected String type; 163 protected String type;
18 protected String driver; 164 protected String driver;
19 165
20 protected Properties properties; 166 protected Map<String, SymbolicStatement> statements;
21 167
22 public Statements(String type, String driver) { 168 public Statements(String type, String driver) {
23 this.type = type; 169 this.type = type;
24 this.driver = driver; 170 this.driver = driver;
171 }
172
173 public SymbolicStatement getStatement(String key) {
174 if (statements == null) {
175 statements = loadStatements();
176 }
177 return statements.get(key);
178 }
179
180 protected Map<String, SymbolicStatement> loadStatements() {
181 Map<String, SymbolicStatement> statements =
182 new HashMap<String, SymbolicStatement>();
183
184 Properties properties = loadProperties();
185
186 for (Enumeration e = properties.propertyNames(); e.hasMoreElements();) {
187 String key = (String)e.nextElement();
188 String value = properties.getProperty(key);
189 SymbolicStatement symbolic = new SymbolicStatement(value);
190 statements.put(key, symbolic);
191 }
192
193 return statements;
25 } 194 }
26 195
27 protected String driverToProperties() { 196 protected String driverToProperties() {
28 return 197 return
29 type + "-" + 198 type + "-" +
57 } 226 }
58 227
59 return common; 228 return common;
60 } 229 }
61 230
62 protected Properties getProperties() { 231 protected Properties loadProperties() {
63
64 if (properties != null) {
65 return properties;
66 }
67 232
68 Properties common = loadCommon(); 233 Properties common = loadCommon();
69 234
70 properties = new Properties(common); 235 Properties properties = new Properties(common);
71 236
72 String path = RESOURCE_PATH + driverToProperties(); 237 String path = RESOURCE_PATH + driverToProperties();
73 238
74 InputStream in = Statements.class.getResourceAsStream(path); 239 InputStream in = Statements.class.getResourceAsStream(path);
75 240

http://dive4elements.wald.intevation.org