From: Juergen H. <jho...@us...> - 2006-04-20 09:50:25
|
Update of /cvsroot/springframework/spring/src/org/springframework/jdbc/core/namedparam In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17651/src/org/springframework/jdbc/core/namedparam Modified Files: NamedParameterUtils.java Log Message: use char array instead of byte array, throw exception if SQL to parse is null Index: NamedParameterUtils.java =================================================================== RCS file: /cvsroot/springframework/spring/src/org/springframework/jdbc/core/namedparam/NamedParameterUtils.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** NamedParameterUtils.java 18 Apr 2006 09:56:14 -0000 1.2 --- NamedParameterUtils.java 20 Apr 2006 09:50:15 -0000 1.3 *************** *** 24,27 **** --- 24,28 ---- import org.springframework.dao.InvalidDataAccessApiUsageException; + import org.springframework.util.Assert; /** *************** *** 35,49 **** public abstract class NamedParameterUtils { - /** * Count the occurrences of the character <code>placeholder</code> in an SQL string ! * <code>sql</code>. The character <code>placeholder</code> is not counted if it ! * appears within a literal -- surrounded by single or double quotes. This method will * count traditional placeholders in the form of a question mark ('?') as well as * named parameters indicated with a leading ':' or '&'. ! * @param sql string to search in. Returns 0 if this is <code>null</code> */ public static int countParameterPlaceholders(String sql) { ! byte[] statement = getBytesNullSafe(sql); boolean withinQuotes = false; Map namedParameters = new HashMap(); --- 36,53 ---- public abstract class NamedParameterUtils { /** * Count the occurrences of the character <code>placeholder</code> in an SQL string ! * <code>sql</code>. The character <code>placeholder</code> is not counted if it appears ! * within a literal, that is, surrounded by single or double quotes. This method will * count traditional placeholders in the form of a question mark ('?') as well as * named parameters indicated with a leading ':' or '&'. ! * @param sql String to search in. Returns 0 if the given String is <code>null</code>. */ public static int countParameterPlaceholders(String sql) { ! if (sql == null) { ! return 0; ! } ! ! char[] statement = sql.toCharArray(); boolean withinQuotes = false; Map namedParameters = new HashMap(); *************** *** 104,114 **** * Named parameters are substituted for a JDBC placeholder. * @param sql the SQL statement */ static ParsedSql parseSqlStatement(String sql) { List parameters = new ArrayList(); Map namedParameters = new HashMap(); ParsedSql parsedSql = new ParsedSql(sql); ! byte[] statement = getBytesNullSafe(sql); StringBuffer newSql = new StringBuffer(); boolean withinQuotes = false; --- 108,121 ---- * Named parameters are substituted for a JDBC placeholder. * @param sql the SQL statement + * @return the parsed statement, represented as ParsedSql instance */ static ParsedSql parseSqlStatement(String sql) { + Assert.notNull(sql, "SQL must not be null"); + List parameters = new ArrayList(); Map namedParameters = new HashMap(); ParsedSql parsedSql = new ParsedSql(sql); ! char[] statement = sql.toCharArray(); StringBuffer newSql = new StringBuffer(); boolean withinQuotes = false; *************** *** 170,243 **** } ! /** ! * Parse the SQL statement and locate any placeholders or named parameters. ! * Named parameters are substituted for a JDBC placeholder and any select list ! * is expanded to the required number of placeholders. ! * <p>The parameter values passed in are used to determine the number of ! * placeholder to be used for a select list. Select lists should be limited ! * to 100 or fewer elements. A larger number of elements is not guaramteed to ! * be supported by the database and is strictly vendor-dependent. ! * @param sql the SQL statement ! * @param paramSource the source for named parameters ! */ ! public static String substituteNamedParameters(String sql, SqlParameterSource paramSource) { ! byte[] statement = getBytesNullSafe(sql); ! StringBuffer newSql = new StringBuffer(); ! boolean withinQuotes = false; ! char currentQuote = '-'; ! int i = 0; ! while (i < statement.length) { ! if (withinQuotes) { ! if (statement[i] == currentQuote) { ! withinQuotes = false; ! currentQuote = '-'; ! } ! newSql.append((char) statement[i]); ! } ! else { ! if (statement[i] == '"' || statement[i] == '\'') { ! withinQuotes = true; ! currentQuote = (char) statement[i]; ! newSql.append((char) statement[i]); ! } ! else { ! if (statement[i] == ':' || statement[i] == '&') { ! int j = i + 1; ! while (j < statement.length && parameterNameContinues(statement, j)) { ! j++; ! } ! if (j - i > 1) { ! String paramName = sql.substring(i + 1, j); ! if (paramSource != null && paramSource.hasValue(paramName)) { ! Object value = paramSource.getValue(paramName); ! if (value instanceof Collection) { ! Collection entries = (Collection) value; ! for (int k = 0; k < entries.size(); k++) { ! if (k > 0) { ! newSql.append(", "); ! } ! newSql.append("?"); ! } ! } ! else { ! newSql.append("?"); ! } ! } ! else { ! newSql.append("?"); ! } ! } ! i = j - 1; ! } ! else { ! newSql.append((char) statement[i]); ! } ! } ! } ! i++; ! } ! return newSql.toString(); ! } /** --- 177,253 ---- } ! /** ! * Parse the SQL statement and locate any placeholders or named parameters. ! * Named parameters are substituted for a JDBC placeholder and any select list ! * is expanded to the required number of placeholders. ! * <p>The parameter values passed in are used to determine the number of ! * placeholder to be used for a select list. Select lists should be limited ! * to 100 or fewer elements. A larger number of elements is not guaramteed to ! * be supported by the database and is strictly vendor-dependent. ! * @param sql the SQL statement ! * @param paramSource the source for named parameters ! * @return the SQL statement with substituted parameters ! */ ! public static String substituteNamedParameters(String sql, SqlParameterSource paramSource) { ! Assert.notNull(sql, "SQL must not be null"); ! char[] statement = sql.toCharArray(); ! StringBuffer newSql = new StringBuffer(); ! boolean withinQuotes = false; ! char currentQuote = '-'; ! ! int i = 0; ! while (i < statement.length) { ! if (withinQuotes) { ! if (statement[i] == currentQuote) { ! withinQuotes = false; ! currentQuote = '-'; ! } ! newSql.append((char) statement[i]); ! } ! else { ! if (statement[i] == '"' || statement[i] == '\'') { ! withinQuotes = true; ! currentQuote = (char) statement[i]; ! newSql.append((char) statement[i]); ! } ! else { ! if (statement[i] == ':' || statement[i] == '&') { ! int j = i + 1; ! while (j < statement.length && parameterNameContinues(statement, j)) { ! j++; ! } ! if (j - i > 1) { ! String paramName = sql.substring(i + 1, j); ! if (paramSource != null && paramSource.hasValue(paramName)) { ! Object value = paramSource.getValue(paramName); ! if (value instanceof Collection) { ! Collection entries = (Collection) value; ! for (int k = 0; k < entries.size(); k++) { ! if (k > 0) { ! newSql.append(", "); ! } ! newSql.append("?"); ! } ! } ! else { ! newSql.append("?"); ! } ! } ! else { ! newSql.append("?"); ! } ! } ! i = j - 1; ! } ! else { ! newSql.append((char) statement[i]); ! } ! } ! } ! i++; ! } ! return newSql.toString(); ! } /** *************** *** 264,272 **** Object[] paramArray = new Object[parsedSql.getTotalParameterCount()]; if (parsedSql.getNamedParameterCount() > 0 && parsedSql.getUnnamedParameterCount() > 0) { ! throw new InvalidDataAccessApiUsageException( ! "You can't mix named and traditional ? placeholders. You have " + ! parsedSql.getNamedParameterCount() + " named parameter(s) and " + ! parsedSql.getUnnamedParameterCount() + " traditonal placeholder(s) in [" + ! parsedSql.getSql() + "]"); } String[] paramNames = parsedSql.getParameterNames(); --- 274,282 ---- Object[] paramArray = new Object[parsedSql.getTotalParameterCount()]; if (parsedSql.getNamedParameterCount() > 0 && parsedSql.getUnnamedParameterCount() > 0) { ! throw new InvalidDataAccessApiUsageException( ! "You can't mix named and traditional ? placeholders. You have " + ! parsedSql.getNamedParameterCount() + " named parameter(s) and " + ! parsedSql.getUnnamedParameterCount() + " traditonal placeholder(s) in [" + ! parsedSql.getSql() + "]"); } String[] paramNames = parsedSql.getParameterNames(); *************** *** 300,308 **** return sqlTypes; } - - - private static byte[] getBytesNullSafe(String sql) { - return (sql == null) ? new byte[0] : sql.getBytes(); - } /** --- 310,313 ---- *************** *** 310,319 **** * that is, does not end delimited by any whitespace character yet. * @param statement the SQL statement ! * @param j the position within the statement */ ! private static boolean parameterNameContinues(byte[] statement, int j) { ! return (statement[j] != ' ' && statement[j] != ',' && statement[j] != ')' && ! statement[j] != '"' && statement[j] != '\'' && statement[j] != '|' && ! statement[j] != ';' && statement[j] != '\n' && statement[j] != '\r'); } --- 315,324 ---- * that is, does not end delimited by any whitespace character yet. * @param statement the SQL statement ! * @param pos the position within the statement */ ! private static boolean parameterNameContinues(char[] statement, int pos) { ! return (statement[pos] != ' ' && statement[pos] != ',' && statement[pos] != ')' && ! statement[pos] != '"' && statement[pos] != '\'' && statement[pos] != '|' && ! statement[pos] != ';' && statement[pos] != '\n' && statement[pos] != '\r'); } |