Index: org/apache/tools/ant/taskdefs/SQLExec.java =================================================================== RCS file: /home/cvspublic/ant/src/main/org/apache/tools/ant/taskdefs/SQLExec.java,v retrieving revision 1.67 diff -u -r1.67 SQLExec.java --- org/apache/tools/ant/taskdefs/SQLExec.java 23 Feb 2004 19:28:23 -0000 1.67 +++ org/apache/tools/ant/taskdefs/SQLExec.java 25 May 2004 15:05:23 -0000 @@ -22,6 +22,7 @@ import org.apache.tools.ant.Project; import org.apache.tools.ant.types.EnumeratedAttribute; import org.apache.tools.ant.types.FileSet; +import org.apache.tools.ant.types.Reference; import java.io.File; import java.io.PrintStream; @@ -176,6 +177,13 @@ private boolean escapeProcessing = true; /** + * The extractor to use + * + * @since Ant 1.6 + */ + private SQLExtractor extractor = null; + + /** * Set the name of the SQL file to be run. * Required unless statements are enclosed in the build file * @param srcFile the file containing the SQL command. @@ -313,6 +321,22 @@ public void setEscapeProcessing(boolean enable) { escapeProcessing = enable; } + + /** + * Set the extractor to use. + * @param id of the extractor to use. + * @since Ant 1.6 + */ + public void setExtractorRef(Reference ref) { + Object refObj = ref.getReferencedObject(project); + + if (refObj instanceof SQLExtractor) { + extractor = (SQLExtractor) refObj; + } else { + throw new BuildException("The reference '"+ref.getRefId()+"' supplied to the sql task does not reference an object of type SQLExtractor."); + } + + } /** * Load the sql file and then execute it @@ -377,6 +401,8 @@ append))); } + if(extractor!=null)extractor.startExtraction(sqlCommand, out); + // Process all transactions for (Enumeration e = transactions.elements(); e.hasMoreElements();) { @@ -388,8 +414,13 @@ } } } finally { - if (out != null && out != System.out) { - out.close(); + if (out != null) { + if(extractor!=null) { + extractor.endExtraction(out); + } + if (out != System.out) { + out.close(); + } } } } catch (IOException e) { @@ -540,17 +571,23 @@ log(updateCountTotal + " rows affected", Project.MSG_VERBOSE); - if (print) { - StringBuffer line = new StringBuffer(); - line.append(updateCountTotal + " rows affected"); - out.println(line); - } - SQLWarning warning = conn.getWarnings(); - while (warning != null) { - log(warning + " sql warning", Project.MSG_VERBOSE); - warning = warning.getNextWarning(); + + if(extractor!=null) { + extractor.endResultSet(updateCountTotal, warning, out); } + else { + if (print) { + StringBuffer line = new StringBuffer(); + line.append(updateCountTotal + " rows affected"); + out.println(line); + } + while (warning != null) { + log(warning + " sql warning", Project.MSG_VERBOSE); + warning = warning.getNextWarning(); + } + } + conn.clearWarnings(); goodSql++; } catch (SQLException e) { @@ -570,7 +607,10 @@ protected void printResults(PrintStream out) throws SQLException { ResultSet rs = null; rs = statement.getResultSet(); - if (rs != null) { + if(extractor!=null) { + extractor.startResultSet(rs, out, showheaders); + } + else if (rs != null) { log("Processing new result set.", Project.MSG_VERBOSE); ResultSetMetaData md = rs.getMetaData(); int columnCount = md.getColumnCount(); @@ -602,8 +642,11 @@ out.println(line); line = new StringBuffer(); } + out.println(); + } + else { + out.println(); } - out.println(); } /** Index: org/apache/tools/ant/util/StringUtils.java =================================================================== RCS file: /home/cvspublic/ant/src/main/org/apache/tools/ant/util/StringUtils.java,v retrieving revision 1.11 diff -u -r1.11 StringUtils.java --- org/apache/tools/ant/util/StringUtils.java 9 Mar 2004 16:48:52 -0000 1.11 +++ org/apache/tools/ant/util/StringUtils.java 25 May 2004 15:05:24 -0000 @@ -92,4 +92,41 @@ return sw.toString(); } + /** + * Escape characters in the string as required by xml. + * @param str the string to escape. + * @return the escaped string. + */ + public static String escapeXml(String str) { + if (str == null) { + return null; + } + + StringBuffer buf = new StringBuffer(str.length() * 2); + int i; + for (i = 0; i < str.length(); ++i) { + char ch = str.charAt(i); + int intValue = ch; + + if(intValue == 34){ + buf.append("""); + } else if(intValue == 38){ + buf.append("&"); + } else if(intValue == 60){ + buf.append("<"); + } else if(intValue == 62){ + buf.append(">"); + } else if(intValue == 39){ + buf.append("'"); + } else if (ch > 0x7F) { + buf.append("&#"); + buf.append(intValue); + buf.append(";"); + } else { + buf.append(ch); + } + } + return buf.toString(); + } + } Index: org/apache/tools/ant/taskdefs/SQLExtractor.java =================================================================== RCS file: org/apache/tools/ant/taskdefs/SQLExtractor.java diff -N org/apache/tools/ant/taskdefs/SQLExtractor.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ org/apache/tools/ant/taskdefs/SQLExtractor.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,28 @@ +/* + * Created on 24-mag-2004 + */ +package org.apache.tools.ant.taskdefs; + +import java.io.PrintStream; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.SQLWarning; + +/** + * @author barozzink 24-mag-2004 + **/ +public interface SQLExtractor +{ + + public void startExtraction(String request, PrintStream out); + + + public void startResultSet(ResultSet rs, PrintStream out, boolean showheaders) + throws SQLException; + + public void endResultSet(int updateCountTotal, SQLWarning warning, + PrintStream out) throws SQLException; + + public void endExtraction(PrintStream out); + +} Index: org/apache/tools/ant/taskdefs/SQLExtractorXML.java =================================================================== RCS file: org/apache/tools/ant/taskdefs/SQLExtractorXML.java diff -N org/apache/tools/ant/taskdefs/SQLExtractorXML.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ org/apache/tools/ant/taskdefs/SQLExtractorXML.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,221 @@ +/* + * Created on 24-mag-2004 + */ +package org.apache.tools.ant.taskdefs; + +import java.io.PrintStream; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.SQLWarning; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.util.StringUtils; + +/** + * @author barozzink 24-mag-2004 + **/ +public class SQLExtractorXML extends Task implements SQLExtractor +{ + + /** + * The depth of nesting for the xml output + * + * @since Ant 1.6 + */ + private int nestLevel = 0; + + /** + * Abilitate the nesting option for the xml output. + * @param nestLevel the depth of the nesting. + * @since Ant 1.6 + */ + public void setNestLevel(int nestLevel) { + this.nestLevel = nestLevel; + } + + + + public void startExtraction(String request, PrintStream out) { + out.println(""); +// out.println(""); +// out.println(" "); +// out.println(" "); +// out.println(" "); +// out.println(" "); +// out.println(" "); +// out.println(" "); +// out.println(" "); +// out.println("]>"); + out.println(""); + } + + public void endExtraction(PrintStream out) { + out.println(""); + } + + + /** + * print any results in the statement. + * @param out the place to print results + * @throws SQLException on SQL problems. + */ + public void startResultSet(ResultSet rs, PrintStream out, + boolean showheaders) throws SQLException { + out.println(""); + out.println(""); + if (rs != null) { + log("Processing new result set.", Project.MSG_VERBOSE); + + ResultSetMetaData md = rs.getMetaData(); + int columnCount = md.getColumnCount(); + String[] headers = new String[columnCount + 1]; + String[] nestedValues = new String[columnCount + 1]; + StringBuffer line = new StringBuffer(); + + //TODO nestLevel must not me > num columns + // do a * nestlevel + + for (int col = 1; col < columnCount + 1; col++) { + headers[col] = (escape(md.getColumnName(col))); + nestedValues[col] = null; + out.println(""); + } + + if (showheaders) { + out.println(""); + + for (int col = 1; col < columnCount; col++) { + line.append("
"); + line.append(headers[col]); + line.append("
"); + } + + line.append("
"); + line.append(escape(md.getColumnName(columnCount))); + line.append("
"); + out.println(line); + out.println("
"); + line = new StringBuffer(); + } + + int currentNestLevel = 0; + + while (rs.next()) { + boolean first = true; + + //nesting pertains only to xml + { + //stay or retract + if (currentNestLevel == nestLevel) { + boolean stayInTag = true; + do { + stayInTag = true; + if (currentNestLevel != 0) { + //I have to check that *all* remaining nested values still match + //see if it changes to false + for (int i = currentNestLevel; i > 0 + && stayInTag; i--) { + String currentValue = escape( + rs.getString(i)).trim(); + String lastValue = nestedValues[i + 1]; + stayInTag = currentValue.equals(lastValue); + + log(lastValue + "->" + currentValue + + " (level:" + + String.valueOf(i) + "of" + + String.valueOf(i) + ")" + + " (stayInTag:" + + String.valueOf(stayInTag) + + ")", Project.MSG_DEBUG); + } + } + + if (!stayInTag) { + nestedValues[currentNestLevel + 1] = null; + currentNestLevel--; + out.println(""); + } + } while (!stayInTag); + } + + //nest + if (currentNestLevel < nestLevel) { + for (int i = currentNestLevel; currentNestLevel < nestLevel; i++) { + currentNestLevel++; + nestedValues[currentNestLevel + 1] = escape( + rs.getString(currentNestLevel)) + .trim(); + out + .println(""); + } + } + } + + { + line.append(""); + //col = nestLevel+1 to skip the values of the items we group by + for (int col = nestLevel + 1; col <= columnCount; col++) { + line.append(""); + String columnValue = escape(rs.getString(col)).trim(); + line.append(columnValue); + line.append(""); + } + line.append(""); + out.println(line); + line = new StringBuffer(); + } + + } + + { + for (int i = 0; i < currentNestLevel; i++) { + out.println(""); + } + } + } + out.println("
"); + } + + public void endResultSet(int updateCountTotal, SQLWarning warning, + PrintStream out) throws SQLException { + + StringBuffer line = new StringBuffer(); + line.append(""); + line.append(updateCountTotal + " rows affected"); + line.append(""); + out.println(line); + + line.append(""); + while (warning != null) { + log(warning + " sql warning", Project.MSG_VERBOSE); + line.append(""); + line.append(warning); + line.append(""); + warning = warning.getNextWarning(); + } + + line.append(""); + out.println("
"); + + + } + + private String escape(String str) { + if (str == null) { + return ""; + } else { + return StringUtils.escapeXml(str); + } + } + +}