diff --git a/docs/manual/CoreTasks/sql.html b/docs/manual/CoreTasks/sql.html index db9b8ff05..6a78de5e4 100644 --- a/docs/manual/CoreTasks/sql.html +++ b/docs/manual/CoreTasks/sql.html @@ -204,6 +204,16 @@ and abort execution and transaction and fail task.
+Use nested <transaction>
diff --git a/src/main/org/apache/tools/ant/taskdefs/SQLExec.java b/src/main/org/apache/tools/ant/taskdefs/SQLExec.java
index cb0f0130f..73b09ad68 100644
--- a/src/main/org/apache/tools/ant/taskdefs/SQLExec.java
+++ b/src/main/org/apache/tools/ant/taskdefs/SQLExec.java
@@ -40,6 +40,7 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.Iterator;
+import java.util.Locale;
import java.util.StringTokenizer;
import java.util.Vector;
@@ -198,6 +199,12 @@ public class SQLExec extends JDBCTask {
*/
private boolean rawBlobs;
+ /**
+ * delimers must match in case and whitespace is significant.
+ * @since Ant 1.8.0
+ */
+ private boolean strictDelimiterMatching = true;
+
/**
* Set the name of the SQL file to be run.
* Required unless statements are enclosed in the build file
@@ -396,6 +403,16 @@ public class SQLExec extends JDBCTask {
this.rawBlobs = rawBlobs;
}
+ /**
+ * If false, delimiters will be searched for in a case-insesitive
+ * manner (i.e. delimer="go" matches "GO") and surrounding
+ * whitespace will be ignored (delimter="go" matches "GO ").
+ * @since Ant 1.8.0
+ */
+ public void setStrictDelimiterMatching(boolean b) {
+ strictDelimiterMatching = b;
+ }
+
/**
* Load the sql file and then execute it
* @throws BuildException on error.
@@ -542,9 +559,9 @@ public class SQLExec extends JDBCTask {
if (!keepformat && line.indexOf("--") >= 0) {
sql.append("\n");
}
- if ((delimiterType.equals(DelimiterType.NORMAL) && StringUtils.endsWith(sql, delimiter))
- || (delimiterType.equals(DelimiterType.ROW) && line.equals(delimiter))) {
- execSQL(sql.substring(0, sql.length() - delimiter.length()), out);
+ int lastDelimPos = lastDelimiterPosition(sql, line);
+ if (lastDelimPos > -1) {
+ execSQL(sql.substring(0, lastDelimPos), out);
sql.replace(0, sql.length(), "");
}
}
@@ -833,4 +850,45 @@ public class SQLExec extends JDBCTask {
}
}
}
+
+ public int lastDelimiterPosition(StringBuffer buf, String currentLine) {
+ if (strictDelimiterMatching) {
+ if (delimiterType.equals(DelimiterType.NORMAL)
+ && StringUtils.endsWith(buf, delimiter)) {
+ return buf.length() - delimiter.length();
+ } else if (delimiterType.equals(DelimiterType.ROW)
+ && currentLine.equals(delimiter)) {
+ return 0;
+ }
+ // no match
+ return -1;
+ } else {
+ String d = delimiter.trim().toLowerCase(Locale.US);
+ if (delimiterType.equals(DelimiterType.NORMAL)) {
+ // still trying to avoid wasteful copying, see
+ // StringUtils.endsWith
+ int endIndex = delimiter.length() - 1;
+ int bufferIndex = buf.length() - 1;
+ while (bufferIndex >= 0
+ && Character.isWhitespace(buf.charAt(bufferIndex))) {
+ --bufferIndex;
+ }
+ if (bufferIndex < endIndex) {
+ return -1;
+ }
+ while (endIndex >= 0) {
+ if (buf.substring(bufferIndex, 1).toLowerCase(Locale.US)
+ .charAt(0) != d.charAt(endIndex)) {
+ return -1;
+ }
+ bufferIndex--;
+ endIndex--;
+ }
+ return bufferIndex;
+ } else {
+ return currentLine.trim().toLowerCase(Locale.US).equals(d)
+ ? 0 : -1;
+ }
+ }
+ }
}
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/SQLExecTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/SQLExecTest.java
index 6854b8b31..91c440e51 100644
--- a/src/tests/junit/org/apache/tools/ant/taskdefs/SQLExecTest.java
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/SQLExecTest.java
@@ -234,4 +234,22 @@ public class SQLExecTest extends TestCase {
}
}
+ public void testLastDelimiterPositionNormalModeStrict() {
+ SQLExec s = new SQLExec();
+ assertEquals(-1,
+ s.lastDelimiterPosition(new StringBuffer(), null));
+ assertEquals(-1,
+ s.lastDelimiterPosition(new StringBuffer("GO"), null));
+ assertEquals(-1,
+ s.lastDelimiterPosition(new StringBuffer("; "), null));
+ assertEquals(2,
+ s.lastDelimiterPosition(new StringBuffer("ab;"), null));
+ s.setDelimiter("GO");
+ assertEquals(-1,
+ s.lastDelimiterPosition(new StringBuffer("GO "), null));
+ assertEquals(-1,
+ s.lastDelimiterPosition(new StringBuffer("go"), null));
+ assertEquals(0,
+ s.lastDelimiterPosition(new StringBuffer("GO"), null));
+ }
}