1 3 package jodd.db; 4 5 import jodd.util.StringUtil; 6 import jodd.util.collection.IntArrayList; 7 8 import java.util.Map ; 9 import java.util.HashMap ; 10 import java.util.Iterator ; 11 12 15 class DbQueryParser { 16 17 public static final String SQL_SEPARATORS = " \n\r\f\t,()=<>&|+-=/*'^![]#~\\"; 18 19 boolean prepared = false; 20 21 String sql; 22 23 25 DbQueryParser() { 26 } 27 28 DbQueryParser(String sql) { 29 parseSql(sql); 30 } 31 32 33 35 private Map namedParameterLocationMap; 36 37 private void storeNamedParameter(String 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 name) { 47 return (IntArrayList) namedParameterLocationMap.get(name); 48 } 49 50 IntArrayList getExistingNamedParameterPositions(String 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 iterateNamedParameters() { 59 return namedParameterLocationMap.keySet().iterator(); 60 } 61 62 64 void parseSql(String sqlString) { 65 namedParameterLocationMap = new HashMap (); 66 int stringLength = sqlString.length(); 67 StringBuffer pureSql = new StringBuffer (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 param = sqlString.substring(index + 1, right); 85 paramCount++; 86 storeNamedParameter(param, paramCount); 87 pureSql.append('?'); 88 index = right; 89 continue; 90 } else if (c == '?') { if ((index < stringLength - 1) && (Character.isDigit(sqlString.charAt(index + 1)))) { int right = StringUtil.indexOfChars(sqlString, SQL_SEPARATORS, index + 1); 93 if (right < 0) { 94 right = stringLength; 95 } 96 String param = sqlString.substring(index + 1, right); 97 try { 98 Integer.parseInt(param); 99 } catch (NumberFormatException 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++; } 110 pureSql.append(c); 111 index++; 112 } 113 this.prepared = (paramCount != 0); 114 this.sql = pureSql.toString(); 115 } 116 } 117 | Popular Tags |