named parameters: prefix/suffix are now regular expressions v_0
authorFrantišek Kučera <franta-hg@frantovo.cz>
Tue, 24 Dec 2013 14:36:14 +0100
branchv_0
changeset 54 53020d0bd2e4
parent 53 eb30ad93ca8b
child 55 f5ed7c4efacc
named parameters: prefix/suffix are now regular expressions
java/sql-dk/src/info/globalcode/sql/dk/CLIOptions.java
java/sql-dk/src/info/globalcode/sql/dk/Functions.java
java/sql-dk/src/info/globalcode/sql/dk/SQLCommandNamed.java
--- a/java/sql-dk/src/info/globalcode/sql/dk/CLIOptions.java	Tue Dec 24 14:23:22 2013 +0100
+++ b/java/sql-dk/src/info/globalcode/sql/dk/CLIOptions.java	Tue Dec 24 14:36:14 2013 +0100
@@ -33,7 +33,7 @@
 public class CLIOptions {
 
 	public static final String DEFAULT_NAME_PREFIX = ":";
-	public static final String DEFAULT_NAME_SUFFIX = "";
+	public static final String DEFAULT_NAME_SUFFIX = "(?=([^\\w]|$))";
 	private String sql;
 	private String databaseName;
 	private String databaseNameToTest;
@@ -172,18 +172,30 @@
 		namedParameters.add(p);
 	}
 
+	/**
+	 * @return regular expression describing the name prefix
+	 */
 	public String getNamePrefix() {
 		return namePrefix;
 	}
 
+	/**
+	 * @see #getNamePrefix()
+	 */
 	public void setNamePrefix(String namePrefix) {
 		this.namePrefix = namePrefix;
 	}
 
+	/**
+	 * @return regular expression describing the name prefix
+	 */
 	public String getNameSuffix() {
 		return nameSuffix;
 	}
 
+	/**
+	 * @see #getNameSuffix()
+	 */
 	public void setNameSuffix(String nameSuffix) {
 		this.nameSuffix = nameSuffix;
 	}
--- a/java/sql-dk/src/info/globalcode/sql/dk/Functions.java	Tue Dec 24 14:23:22 2013 +0100
+++ b/java/sql-dk/src/info/globalcode/sql/dk/Functions.java	Tue Dec 24 14:36:14 2013 +0100
@@ -94,7 +94,7 @@
 
 	public static <T extends NameIdentified> T findByName(Collection<T> collection, String name) {
 		for (T element : collection) {
-			if (equalz(element.getName(), name)) {
+			if (element != null && equalz(element.getName(), name)) {
 				return element;
 			}
 		}
--- a/java/sql-dk/src/info/globalcode/sql/dk/SQLCommandNamed.java	Tue Dec 24 14:23:22 2013 +0100
+++ b/java/sql-dk/src/info/globalcode/sql/dk/SQLCommandNamed.java	Tue Dec 24 14:36:14 2013 +0100
@@ -74,8 +74,8 @@
 	private void buildPattern() {
 		StringBuilder patternString = new StringBuilder();
 
-		patternString.append(Pattern.quote(namePrefix));
-		patternString.append("(");
+		patternString.append(namePrefix);
+		patternString.append("(?<paramName>");
 		for (int i = 0; i < parameters.size(); i++) {
 			patternString.append(Pattern.quote(parameters.get(i).getName()));
 			if (i < parameters.size() - 1) {
@@ -83,7 +83,7 @@
 			}
 		}
 		patternString.append(")");
-		patternString.append(Pattern.quote(nameSuffix));
+		patternString.append(nameSuffix);
 
 		pattern = Pattern.compile(patternString.toString());
 	}
@@ -94,7 +94,7 @@
 
 		int lastPosition = 0;
 		while (m.find(lastPosition)) {
-			String name = m.group(1);
+			String name = m.group("paramName");
 
 			updatedQuery.append(originalQuery.substring(lastPosition, m.start()));
 			updatedQuery.append("?");
@@ -107,18 +107,25 @@
 
 		for (NamedParameter definedParameter : parameters) {
 			if (findByName(parametersUsed, definedParameter.getName()) == null) {
-				throw new SQLException("Parameter „" + definedParameter.getName() + "“ is defined but not used in the query: „" + originalQuery + "“");
+				/**
+				 * User can have predefined set of parameters and use them with different SQL
+				 * queries that use only subset of these parameters → just warning, not exception.
+				 */
+				log.log(Level.WARNING, "Parameter „{0}“ is defined but not used in the query: „{1}“", new Object[]{definedParameter.getName(), originalQuery});
 			}
 		}
 	}
 
 	private void logPossiblyMissingParameters() {
-		Pattern p = Pattern.compile(Pattern.quote(namePrefix) + ".*?" + Pattern.quote(nameSuffix));
+		Pattern p = Pattern.compile(namePrefix + "(?<paramName>.*?)" + nameSuffix);
 		Matcher m = p.matcher(updatedQuery);
 		int lastPosition = 0;
 		while (m.find(lastPosition)) {
-
-			log.log(Level.WARNING, "Possibly missing parameter: {0}", m.group());
+			/**
+			 * We have not parsed and understood the SQL query; the parameter-like looking string
+			 * could be inside a literal part of the query → just warning, not exception.
+			 */
+			log.log(Level.WARNING, "Possibly missing parameter „{0}“ in the query: „{1}“", new Object[]{m.group("paramName"), getQuery()});
 			lastPosition = m.end();
 		}
 	}