KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jodd > db > DbQueryParser


1 // Copyright (c) 2003-2007, Jodd Team (jodd.sf.net). All Rights Reserved.
2

3 package jodd.db;
4
5 import jodd.util.StringUtil;
6 import jodd.util.collection.IntArrayList;
7
8 import java.util.Map JavaDoc;
9 import java.util.HashMap JavaDoc;
10 import java.util.Iterator JavaDoc;
11
12 /**
13  * SQL parameters parser that recognizes named and ordinal parameters.
14  */

15 class DbQueryParser {
16
17     public static final String JavaDoc SQL_SEPARATORS = " \n\r\f\t,()=<>&|+-=/*'^![]#~\\";
18
19     boolean prepared = false;
20
21     String JavaDoc sql;
22
23     // ---------------------------------------------------------------- ctors
24

25     DbQueryParser() {
26     }
27
28     DbQueryParser(String JavaDoc sql) {
29         parseSql(sql);
30     }
31
32
33     // ---------------------------------------------------------------- parameters
34

35     private Map JavaDoc namedParameterLocationMap;
36
37     private void storeNamedParameter(String JavaDoc name, int position) {
38         IntArrayList locations = (IntArrayList) namedParameterLocationMap.get(name);
39         if (locations == null) {
40             locations = new IntArrayList();
41             namedParameterLocationMap.put(name, locations);
42         }
43         locations.add(position);
44     }
45
46     IntArrayList getNamedParameterPositions(String JavaDoc name) {
47         return (IntArrayList) namedParameterLocationMap.get(name);
48     }
49
50     IntArrayList getExistingNamedParameterPositions(String JavaDoc name) {
51         IntArrayList positions = (IntArrayList) namedParameterLocationMap.get(name);
52         if (positions == null) {
53             throw new DbSqlException("Named parameter '" + name + "' not found.");
54         }
55         return positions;
56     }
57
58     Iterator JavaDoc iterateNamedParameters() {
59         return namedParameterLocationMap.keySet().iterator();
60     }
61
62     // ---------------------------------------------------------------- parser
63

64     void parseSql(String JavaDoc sqlString) {
65         namedParameterLocationMap = new HashMap JavaDoc();
66         int stringLength = sqlString.length();
67         StringBuffer JavaDoc pureSql = new StringBuffer JavaDoc(stringLength);
68         boolean inQuote = false;
69         int index = 0;
70         int paramCount = 0;
71         while (index < stringLength) {
72             char c = sqlString.charAt(index);
73             if (inQuote == true) {
74                 if (c == '\'') {
75                     inQuote = false;
76                 }
77             } else if (c == '\'') {
78                 inQuote = true;
79             } else if (c == ':') {
80                 int right = StringUtil.indexOfChars(sqlString, SQL_SEPARATORS, index + 1);
81                 if (right < 0) {
82                     right = stringLength;
83                 }
84                 String JavaDoc param = sqlString.substring(index + 1, right);
85                 paramCount++;
86                 storeNamedParameter(param, paramCount);
87                 pureSql.append('?');
88                 index = right;
89                 continue;
90             } else if (c == '?') { // either an ordinal or positional parameter
91
if ((index < stringLength - 1) && (Character.isDigit(sqlString.charAt(index + 1)))) { // positional parameter
92
int right = StringUtil.indexOfChars(sqlString, SQL_SEPARATORS, index + 1);
93                     if (right < 0) {
94                         right = stringLength;
95                     }
96                     String JavaDoc param = sqlString.substring(index + 1, right);
97                     try {
98                         Integer.parseInt(param);
99                     } catch (NumberFormatException JavaDoc nfex) {
100                         throw new DbSqlException("Positional parameter '" + nfex + "' is not an integral ordinal.", nfex);
101                     }
102                     paramCount++;
103                     storeNamedParameter(param, paramCount);
104                     pureSql.append('?');
105                     index = right;
106                     continue;
107                 }
108                 paramCount++; // ordinal param
109
}
110             pureSql.append(c);
111             index++;
112         }
113         this.prepared = (paramCount != 0);
114         this.sql = pureSql.toString();
115     }
116 }
117
Popular Tags