diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultRenderContext.java b/jOOQ/src/main/java/org/jooq/impl/DefaultRenderContext.java index 3bbdd730f6..c7dbbb1f75 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultRenderContext.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultRenderContext.java @@ -288,7 +288,7 @@ class DefaultRenderContext extends AbstractContext implements Ren // MySQL supports backticks and double quotes case MYSQL: - sql("`").sql(literal.replace("`", "``")).sql("`"); + sql("`").sql(StringUtils.replace(literal, "`", "``")).sql("`"); break; // SQLite is supposed to support all sorts of delimiters, but it @@ -301,7 +301,7 @@ class DefaultRenderContext extends AbstractContext implements Ren case ASE: case SQLSERVER: case SYBASE: - sql("[").sql(literal.replace("]", "]]")).sql("]"); + sql("[").sql(StringUtils.replace(literal, "]", "]]")).sql("]"); break; // Most dialects implement the SQL standard, using double quotes @@ -315,7 +315,7 @@ class DefaultRenderContext extends AbstractContext implements Ren case ORACLE: case POSTGRES: default: - sql('"').sql(literal.replace("\"", "\"\"")).sql('"'); + sql('"').sql(StringUtils.replace(literal, "\"", "\"\"")).sql('"'); break; } } diff --git a/jOOQ/src/main/java/org/jooq/tools/StringUtils.java b/jOOQ/src/main/java/org/jooq/tools/StringUtils.java index 9113e41bdf..0f6f1ac067 100644 --- a/jOOQ/src/main/java/org/jooq/tools/StringUtils.java +++ b/jOOQ/src/main/java/org/jooq/tools/StringUtils.java @@ -120,6 +120,12 @@ public final class StringUtils { */ public static final String EMPTY = ""; + /** + * Represents a failed index search. + * @since 2.1 + */ + public static final int INDEX_NOT_FOUND = -1; + /** *

The maximum size to which the padding constant(s) can expand.

*/ @@ -683,6 +689,87 @@ public final class StringUtils { return false; } + /** + *

Replaces all occurrences of a String within another String.

+ * + *

A {@code null} reference passed to this method is a no-op.

+ * + *
+     * StringUtils.replace(null, *, *)        = null
+     * StringUtils.replace("", *, *)          = ""
+     * StringUtils.replace("any", null, *)    = "any"
+     * StringUtils.replace("any", *, null)    = "any"
+     * StringUtils.replace("any", "", *)      = "any"
+     * StringUtils.replace("aba", "a", null)  = "aba"
+     * StringUtils.replace("aba", "a", "")    = "b"
+     * StringUtils.replace("aba", "a", "z")   = "zbz"
+     * 
+ * + * @see #replace(String text, String searchString, String replacement, int max) + * @param text text to search and replace in, may be null + * @param searchString the String to search for, may be null + * @param replacement the String to replace it with, may be null + * @return the text with any replacements processed, + * {@code null} if null String input + */ + public static String replace(String text, String searchString, String replacement) { + return replace(text, searchString, replacement, -1); + } + + /** + *

Replaces a String with another String inside a larger String, + * for the first {@code max} values of the search String.

+ * + *

A {@code null} reference passed to this method is a no-op.

+ * + *
+     * StringUtils.replace(null, *, *, *)         = null
+     * StringUtils.replace("", *, *, *)           = ""
+     * StringUtils.replace("any", null, *, *)     = "any"
+     * StringUtils.replace("any", *, null, *)     = "any"
+     * StringUtils.replace("any", "", *, *)       = "any"
+     * StringUtils.replace("any", *, *, 0)        = "any"
+     * StringUtils.replace("abaa", "a", null, -1) = "abaa"
+     * StringUtils.replace("abaa", "a", "", -1)   = "b"
+     * StringUtils.replace("abaa", "a", "z", 0)   = "abaa"
+     * StringUtils.replace("abaa", "a", "z", 1)   = "zbaa"
+     * StringUtils.replace("abaa", "a", "z", 2)   = "zbza"
+     * StringUtils.replace("abaa", "a", "z", -1)  = "zbzz"
+     * 
+ * + * @param text text to search and replace in, may be null + * @param searchString the String to search for, may be null + * @param replacement the String to replace it with, may be null + * @param max maximum number of values to replace, or {@code -1} if no maximum + * @return the text with any replacements processed, + * {@code null} if null String input + */ + public static String replace(String text, String searchString, String replacement, int max) { + if (isEmpty(text) || isEmpty(searchString) || replacement == null || max == 0) { + return text; + } + int start = 0; + int end = text.indexOf(searchString, start); + if (end == INDEX_NOT_FOUND) { + return text; + } + int replLength = searchString.length(); + int increase = replacement.length() - replLength; + increase = (increase < 0 ? 0 : increase); + increase *= (max < 0 ? 16 : (max > 64 ? 64 : max)); + StringBuilder buf = new StringBuilder(text.length() + increase); + while (end != INDEX_NOT_FOUND) { + buf.append(text.substring(start, end)).append(replacement); + start = end + replLength; + if (--max == 0) { + break; + } + end = text.indexOf(searchString, start); + } + buf.append(text.substring(start)); + return buf.toString(); + } + /** *

* Replaces all occurrences of Strings within another String.