1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package com.finalist.tools.database;
19
20 import java.util.*;
21
22 /***
23 * Class that models a Query.
24 *
25 * @author P.S.D.Reitsma, Finalist IT Group
26 * @version 1.0
27 */
28 public class Query {
29 String qName;
30 String qString;
31 String oriqString;
32
33 ArrayList BindIdentifiers;
34
35 int argCount;
36 boolean givesResultSet;
37 boolean performsOrderBy;
38 boolean isUpdate;
39 boolean isInsert;
40 boolean isDelete;
41 boolean isCallable;
42 boolean malformed = false;
43
44
45 private String replace(String text1, String text2, int pPosition) {
46 String repString = "<P" + pPosition + ">";
47
48 int pos = text1.indexOf(repString);
49 if (pos == -1) {
50 return text1;
51 }
52 StringBuffer labelBuf = new StringBuffer(text1);
53 labelBuf.replace(pos, pos + repString.length(), text2);
54 return replace(labelBuf.toString(), text2, pPosition);
55 }
56
57
58
59
60
61
62
63
64 public void fillInPlaceholder(Hashtable pReplacements) {
65 Enumeration E = pReplacements.keys();
66 String replacer;
67 Integer pos;
68
69
70 String qStr = oriqString;
71
72 String workString = oriqString;
73
74 while (E.hasMoreElements()) {
75 pos = (Integer) E.nextElement();
76 replacer = (String) pReplacements.get(pos);
77 qStr = replace(workString, replacer, pos.intValue());
78 workString = qStr;
79 }
80
81 parse(qStr);
82 }
83
84
85 /***
86 * Constructor.
87 * Initializes the Query object by parsing the Query definition qStr.
88 *
89 * @param qNm defines the name of the query
90 * @param qStr defines the query's definition
91 */
92 public Query(String qNm, String qStr) {
93
94 oriqString = qStr;
95
96 qName = qNm;
97
98 parse(qStr);
99
100 }
101
102
103 /***
104 * Constructor
105 * Initializes the Query object by parsing the Query definition
106 *
107 * @param definition the definition of the query in SQL
108 */
109 public Query(String definition) {
110 oriqString = definition;
111 parse(definition);
112 }
113
114
115 void parse(String qStr) {
116
117 BindIdentifiers = new ArrayList();
118
119 try {
120 String BindIdentifyer = null;
121 StringBuffer q = new StringBuffer(qStr);
122 int startBI = qStr.indexOf("{{");
123 int endBI = qStr.lastIndexOf("}}") + 2;
124 if ((startBI != -1) && (endBI != -1)) {
125 BindIdentifyer = q.substring(startBI, endBI);
126 qString = q.delete(startBI, endBI).toString();
127 qString.toUpperCase();
128 qString.trim();
129 BindIdentifyer = BindIdentifyer.replace('{', ' ');
130 BindIdentifyer = BindIdentifyer.replace('}', ' ');
131 BindIdentifyer = BindIdentifyer.trim();
132
133 StringTokenizer st = new StringTokenizer(BindIdentifyer, ",");
134 while (st.hasMoreTokens()) {
135 BindIdentifiers.add(st.nextToken().trim());
136 }
137
138 }
139 else {
140 qString = qStr.trim();
141
142 char[] querychars = qString.toCharArray();
143 Vector startpositions = new Vector();
144
145 for (int i = 1; i != querychars.length; i++) {
146
147 if ((querychars[i] == ':') &&
148 (
149 (querychars[i - 1] == ' ') ||
150 (querychars[i - 1] == ',') ||
151 (querychars[i - 1] == '=') ||
152 (querychars[i - 1] == '(') ||
153 (querychars[i - 1] == '-') ||
154 (querychars[i - 1] == '+') ||
155 (querychars[i - 1] == '{') ||
156 (querychars[i - 1] == '<') ||
157 (querychars[i - 1] == '>') ||
158 (querychars[i - 1] == '|') ||
159 (querychars[i - 1] == 13)
160 ) &&
161 (
162 (querychars[i + 1] != '=')
163 )
164 ) {
165
166
167 int j = i + 1;
168 StringBuffer bindelement = new StringBuffer();
169 while (
170 (j < querychars.length)
171 && (
172 (querychars[j] >= 48) && (querychars[j] <= 57)
173 || (querychars[j] >= 65) && (querychars[j] <= 90)
174 || (querychars[j] >= 97) && (querychars[j] <= 122)
175 || (querychars[j] == 95)
176 )
177 ) {
178
179 bindelement.append(querychars[j]);
180 startpositions.addElement(new Integer(i));
181 j++;
182 }
183
184 BindIdentifiers.add(bindelement.toString().trim());
185 }
186 }
187 StringBuffer sb;
188 Iterator E = BindIdentifiers.iterator();
189 while (E.hasNext()) {
190 String bindElement = ":" + (String) E.next();
191 sb = new StringBuffer(qString);
192 for (int i = 0; i < qString.length(); i++) {
193 if (qString.startsWith(bindElement, i)) {
194 sb.replace(i, i + bindElement.length(), "?");
195
196 break;
197 }
198 }
199 qString = sb.toString();
200 }
201 }
202 givesResultSet = qString.toUpperCase().startsWith("SELECT");
203 performsOrderBy = (qString.toUpperCase().indexOf("ORDER BY") != -1);
204 isUpdate = qString.toUpperCase().startsWith("UPDATE");
205 isInsert = qString.toUpperCase().startsWith("INSERT");
206 isDelete = qString.toUpperCase().startsWith("DELETE");
207 isCallable = (
208 qString.toUpperCase().startsWith("BEGIN")
209 || qString.toUpperCase().startsWith("{")
210 );
211 argCount = 0;
212 for (int i = 0; i < qStr.length(); i++) {
213 if (qStr.charAt(i) == '?') {
214 argCount++;
215 }
216 }
217 if (BindIdentifyer != null) {
218 if (BindIdentifiers.size() < argCount) {
219 System.out.println("Query(): " + qName + " has not enough bind identifiers.");
220 }
221 if (BindIdentifiers.size() > argCount) {
222 System.out.println("Query(): " + qName + " has too many bind identifiers.");
223 }
224 }
225 }
226 catch (Exception E) {
227 malformed = true;
228 System.out.println("Query(): Exception ocurred during initialisation of query " + qName);
229 E.printStackTrace();
230 }
231 }
232
233
234 /*** Getter for property BindIdentifiers.
235 *
236 * @return Value of property BindIdentifiers.
237 */
238 public ArrayList getBindIdentifiers() {
239 return BindIdentifiers;
240 }
241
242
243 /*** Setter for property BindIdentifiers.
244 * @param BindIdentifiers New value of property BindIdentifiers.
245 */
246 public void setBindIdentifiers(ArrayList BindIdentifiers) {
247 this.BindIdentifiers = BindIdentifiers;
248 }
249
250
251 /*** Getter for property oriqString.
252 * @return Value of property oriqString.
253 */
254 public java.lang.String getOriqString() {
255 return oriqString;
256 }
257
258
259 /*** Setter for property oriqString.
260 * @param oriqString New value of property oriqString.
261 */
262 public void setOriqString(java.lang.String oriqString) {
263 this.oriqString = oriqString;
264 }
265
266 }
267
268