View | Details | Raw Unified | Return to bug 28681
Collapse All | Expand All

(-)SQLExec.java (-18 / +170 lines)
Lines 22-27 Link Here
22
import org.apache.tools.ant.Project;
22
import org.apache.tools.ant.Project;
23
import org.apache.tools.ant.types.EnumeratedAttribute;
23
import org.apache.tools.ant.types.EnumeratedAttribute;
24
import org.apache.tools.ant.types.FileSet;
24
import org.apache.tools.ant.types.FileSet;
25
import org.apache.tools.ant.util.StringUtils;
25
26
26
import java.io.File;
27
import java.io.File;
27
import java.io.PrintStream;
28
import java.io.PrintStream;
Lines 147-153 Link Here
147
     */
148
     */
148
    private File output = null;
149
    private File output = null;
149
150
150
151
    /**
151
    /**
152
     * Action to perform if an error is found
152
     * Action to perform if an error is found
153
     **/
153
     **/
Lines 176-181 Link Here
176
    private boolean escapeProcessing = true;
176
    private boolean escapeProcessing = true;
177
177
178
    /**
178
    /**
179
     * The output format, can be csv or xml
180
     *
181
     * @since Ant 1.6
182
     */
183
    private String outputFormat = "csv";
184
        
185
    /**
186
     * The depth of nesting for the xml output
187
     *
188
     * @since Ant 1.6
189
     */
190
    private int nestLevel = 0;
191
    
192
    /**
179
     * Set the name of the SQL file to be run.
193
     * Set the name of the SQL file to be run.
180
     * Required unless statements are enclosed in the build file
194
     * Required unless statements are enclosed in the build file
181
     * @param srcFile the file containing the SQL command.
195
     * @param srcFile the file containing the SQL command.
Lines 313-320 Link Here
313
    public void setEscapeProcessing(boolean enable) {
327
    public void setEscapeProcessing(boolean enable) {
314
        escapeProcessing = enable;
328
        escapeProcessing = enable;
315
    }
329
    }
330
    
331
    /**
332
     * Set the output format.
333
     * @param type the format type of the output, currently supports csv and xml.
334
     * @since Ant 1.6
335
     */
336
    public void setOutputFormat(String type) {
337
        if(type.equals("xml") || type.equals("csv")){
338
            outputFormat = type;
339
        }
340
        else{
341
            log("outputType "+type+" not supported, defaulting to csv format.", Project.MSG_WARN);
342
            outputFormat = "csv";
343
        }
344
    }
316
345
317
    /**
346
    /**
347
     * Abilitate the nesting option for the xml output.
348
     * @param nestLevel the depth of the nesting.
349
     * @since Ant 1.6
350
     */
351
    public void setNestLevel(int nestLevel) {
352
        this.nestLevel = nestLevel;
353
    }
354
        
355
    /**
318
     * Load the sql file and then execute it
356
     * Load the sql file and then execute it
319
     * @throws BuildException on error.
357
     * @throws BuildException on error.
320
     */
358
     */
Lines 542-548 Link Here
542
580
543
            if (print) {
581
            if (print) {
544
                StringBuffer line = new StringBuffer();
582
                StringBuffer line = new StringBuffer();
583
                if(outputFormat.equals("xml")) line.append("<!--");
545
                line.append(updateCountTotal + " rows affected");
584
                line.append(updateCountTotal + " rows affected");
585
                if(outputFormat.equals("xml")) line.append("-->");
546
                out.println(line);
586
                out.println(line);
547
            }
587
            }
548
588
Lines 572-611 Link Here
572
        rs = statement.getResultSet();
612
        rs = statement.getResultSet();
573
        if (rs != null) {
613
        if (rs != null) {
574
            log("Processing new result set.", Project.MSG_VERBOSE);
614
            log("Processing new result set.", Project.MSG_VERBOSE);
615
            boolean xml = outputFormat.equals("xml")? true: false;
616
            boolean csv = outputFormat.equals("csv")? true: false;            
617
            
575
            ResultSetMetaData md = rs.getMetaData();
618
            ResultSetMetaData md = rs.getMetaData();
576
            int columnCount = md.getColumnCount();
619
            int columnCount = md.getColumnCount();
620
            String[] headers = new String[columnCount+1];
621
            String[] nestedValues = new String[columnCount+1];
577
            StringBuffer line = new StringBuffer();
622
            StringBuffer line = new StringBuffer();
578
            if (showheaders) {
623
            
624
            //TODO nestLevel must not me > num columns
625
            // do a * nestlevel
626
            
627
            if(xml) {
628
                out.println("<?xml version=\"1.0\" ?>");
629
                out.println("<!DOCTYPE sqlresults [");
630
                out.println("  <!ELEMENT sqlresults (headers?, (nest | row)* )>");
631
                out.println("  <!ELEMENT headers (header)*>");
632
                out.println("  <!ELEMENT header (#PCDATA)>");
633
                out.println("  <!ELEMENT nest (row)*>");
634
                out.println("  <!ATTLIST nest group-by CDATA #REQUIRED");
635
                out.println("                 value    CDATA #REQUIRED>");
636
                out.println("  <!ELEMENT row (cell)*>");
637
                out.println("  <!ELEMENT cell (#PCDATA)>");
638
                out.println("  <!ATTLIST cell header CDATA #REQUIRED>");
639
                out.println("]>");
640
                out.println("<sqlresults>");
641
            }
642
            
643
            for (int col = 1; col < columnCount+1; col++) {
644
                headers[col] = (escape(md.getColumnName(col),xml));
645
                nestedValues[col] = null;
646
                out.println("<!-- "+headers[col]+" -->");
647
            }
648
            
649
           if (showheaders) {
650
                if(xml) out.println("<headers>"); 
651
                                
579
                for (int col = 1; col < columnCount; col++) {
652
                for (int col = 1; col < columnCount; col++) {
580
                     line.append(md.getColumnName(col));
653
                    if(xml) line.append("<header>");
581
                     line.append(",");
654
                    line.append(headers[col]);
655
                    if(xml) 
656
                        line.append("</header>");
657
                    else 
658
                        line.append(",");
582
                }
659
                }
583
                line.append(md.getColumnName(columnCount));
660
                
661
                if(xml) line.append("<header>");
662
                line.append(escape(md.getColumnName(columnCount),xml));
663
                if(xml) line.append("</header>");
584
                out.println(line);
664
                out.println(line);
665
                if(xml) out.println("</headers>");
585
                line = new StringBuffer();
666
                line = new StringBuffer();
586
            }
667
            }
668
669
            int currentNestLevel = 0;
670
            
587
            while (rs.next()) {
671
            while (rs.next()) {
588
                boolean first = true;
672
                boolean first = true;
589
                for (int col = 1; col <= columnCount; col++) {
673
               
590
                    String columnValue = rs.getString(col);
674
                //nesting pertains only to xml
591
                    if (columnValue != null) {
675
                if(xml) {
592
                        columnValue = columnValue.trim();
676
                    //stay or retract
593
                    }
677
                    if(currentNestLevel==nestLevel){
594
678
                        boolean stayInTag = true;               
595
                    if (first) {
679
                        do{
596
                        first = false;
680
                            stayInTag = true;
597
                    } else {
681
                            if(currentNestLevel!=0){
598
                        line.append(",");
682
                                //I have to check that *all* remaining nested values still match
683
                                //see if it changes to false
684
                                for(int i=currentNestLevel; i>0&&stayInTag; i-- ){
685
                                    String currentValue = escape(rs.getString(i),xml).trim();
686
                                    String lastValue = nestedValues[i+1];
687
                                    stayInTag = currentValue.equals(lastValue);
688
                                    
689
                                    log(lastValue+"->"+currentValue+
690
                                        " (level:"+String.valueOf(i)+"of"+String.valueOf(i)+")"+
691
                                        " (stayInTag:"+String.valueOf(stayInTag)+")", Project.MSG_DEBUG);
692
                                }
693
                            }
694
                            
695
                            if(!stayInTag){
696
                                nestedValues[currentNestLevel+1]=null;
697
                                currentNestLevel--;
698
                                out.println("</nest>");
699
                            }
700
                        }
701
                        while(!stayInTag);
702
                    }  
703
    
704
                    //nest
705
                    if(currentNestLevel<nestLevel){
706
                        for(int i=currentNestLevel; currentNestLevel<nestLevel; i++ ){
707
                            currentNestLevel++;
708
                            nestedValues[currentNestLevel+1]=escape(rs.getString(currentNestLevel),xml).trim();
709
                            out.println("<nest group-by=\""+headers[currentNestLevel]+"\" value=\""+nestedValues[currentNestLevel+1]+"\">");
710
                        }
711
                    }    
712
                 }    
713
                
714
                {
715
                    if(xml) line.append("<row>");
716
                    //col = nestLevel+1 to skip the values of the items we group by    
717
                    for (int col = nestLevel+1; col <= columnCount; col++) {
718
                        if(xml) line.append("<cell header=\"");
719
                        if(xml) line.append(headers[col]);
720
                        if(xml) line.append("\">");
721
                        String columnValue = escape(rs.getString(col),xml).trim();
722
                        if(csv) {
723
                            if (first) {
724
                                first = false;
725
                            } else {
726
                                line.append(",");
727
                            }
728
                        }
729
                        line.append(columnValue);
730
                        if(xml) line.append("</cell>");
599
                    }
731
                    }
600
                    line.append(columnValue);
732
                    if(xml) line.append("</row>");
733
                    out.println(line);
734
                    line = new StringBuffer();
601
                }
735
                }
602
                out.println(line);
736
                
603
                line = new StringBuffer();
737
            }
738
            
739
            if(xml) {
740
                for(int i=0; i<currentNestLevel; i++){
741
                        out.println("</nest>");
742
                }
743
                out.println("</sqlresults>");
604
            }
744
            }
605
        }
745
        }
606
        out.println();
746
        out.println();
607
    }
747
    }
608
748
749
    private String escape(String str, boolean xml) {
750
        if (str == null) {
751
            return "";
752
        }
753
        else if(!xml) {
754
            return str;
755
        }
756
        else {
757
            return StringUtils.escapeXml(str);
758
        }
759
    }
760
    
609
    /**
761
    /**
610
     * The action a task should perform on an error,
762
     * The action a task should perform on an error,
611
     * one of "continue", "stop" and "abort"
763
     * one of "continue", "stop" and "abort"
(-)StringUtils.java (+37 lines)
Lines 92-95 Link Here
92
        return sw.toString();
92
        return sw.toString();
93
    }
93
    }
94
94
95
    /**
96
     * Escape characters in the string as required by xml.
97
     * @param str the string to escape.
98
     * @return the escaped string.
99
     */
100
    public static String escapeXml(String str) {
101
        if (str == null) {
102
            return null;
103
        }
104
         
105
        StringBuffer buf = new StringBuffer(str.length() * 2);
106
        int i;
107
        for (i = 0; i < str.length(); ++i) {
108
            char ch = str.charAt(i);
109
            int intValue = ch;
110
            
111
            if(intValue == 34){
112
                buf.append("&quot;");
113
            } else if(intValue == 38){
114
                buf.append("&amp;");
115
            } else if(intValue == 60){
116
                buf.append("&lt;");
117
            } else if(intValue == 62){
118
                buf.append("&gt;");
119
            } else if(intValue == 39){
120
                buf.append("&apos;");
121
            } else if (ch > 0x7F) {
122
                buf.append("&#");
123
                buf.append(intValue);
124
                buf.append(";");
125
            } else {
126
                buf.append(ch);
127
            }
128
        }
129
        return buf.toString();
130
    }
131
95
}
132
}

Return to bug 28681