1 18 19 package org.apache.tools.ant.taskdefs; 20 21 import org.apache.tools.ant.BuildException; 22 import org.apache.tools.ant.Project; 23 import org.apache.tools.ant.util.FileUtils; 24 import org.apache.tools.ant.util.StringUtils; 25 import org.apache.tools.ant.types.EnumeratedAttribute; 26 import org.apache.tools.ant.types.FileSet; 27 import org.apache.tools.ant.types.Resource; 28 import org.apache.tools.ant.types.ResourceCollection; 29 import org.apache.tools.ant.types.resources.FileResource; 30 import org.apache.tools.ant.types.resources.Union; 31 32 import java.io.File ; 33 import java.io.PrintStream ; 34 import java.io.BufferedOutputStream ; 35 import java.io.FileOutputStream ; 36 import java.io.IOException ; 37 import java.io.Reader ; 38 import java.io.BufferedReader ; 39 import java.io.StringReader ; 40 import java.io.InputStream ; 41 import java.io.InputStreamReader ; 42 import java.util.Enumeration ; 43 import java.util.Iterator ; 44 import java.util.StringTokenizer ; 45 import java.util.Vector ; 46 47 import java.sql.Connection ; 48 import java.sql.Statement ; 49 import java.sql.SQLException ; 50 import java.sql.SQLWarning ; 51 import java.sql.ResultSet ; 52 import java.sql.ResultSetMetaData ; 53 54 80 public class SQLExec extends JDBCTask { 81 82 85 public static class DelimiterType extends EnumeratedAttribute { 86 87 public static final String NORMAL = "normal", ROW = "row"; 88 89 public String [] getValues() { 90 return new String [] {NORMAL, ROW}; 91 } 92 } 93 94 private int goodSql = 0; 95 96 private int totalSql = 0; 97 98 101 private Connection conn = null; 102 103 106 private Union resources = new Union(); 107 108 111 private Statement statement = null; 112 113 116 private File srcFile = null; 117 118 121 private String sqlCommand = ""; 122 123 126 private Vector transactions = new Vector (); 127 128 131 private String delimiter = ";"; 132 133 137 private String delimiterType = DelimiterType.NORMAL; 138 139 142 private boolean print = false; 143 144 147 private boolean showheaders = true; 148 149 152 private boolean showtrailers = true; 153 154 157 private File output = null; 158 159 160 163 private String onError = "abort"; 164 165 168 private String encoding = null; 169 170 173 private boolean append = false; 174 175 178 private boolean keepformat = false; 179 180 185 private boolean escapeProcessing = true; 186 187 193 private boolean expandProperties = false; 194 195 200 public void setSrc(File srcFile) { 201 this.srcFile = srcFile; 202 } 203 204 210 public void setExpandProperties(boolean expandProperties) { 211 this.expandProperties = expandProperties; 212 } 213 214 220 public boolean getExpandProperties() { 221 return expandProperties; 222 } 223 224 230 public void addText(String sql) { 231 this.sqlCommand += sql; 234 } 235 236 241 public void addFileset(FileSet set) { 242 add(set); 243 } 244 245 251 public void add(ResourceCollection rc) { 252 resources.add(rc); 253 } 254 255 259 public Transaction createTransaction() { 260 Transaction t = new Transaction(); 261 transactions.addElement(t); 262 return t; 263 } 264 265 270 public void setEncoding(String encoding) { 271 this.encoding = encoding; 272 } 273 274 282 public void setDelimiter(String delimiter) { 283 this.delimiter = delimiter; 284 } 285 286 295 public void setDelimiterType(DelimiterType delimiterType) { 296 this.delimiterType = delimiterType.getValue(); 297 } 298 299 304 public void setPrint(boolean print) { 305 this.print = print; 306 } 307 308 313 public void setShowheaders(boolean showheaders) { 314 this.showheaders = showheaders; 315 } 316 317 323 public void setShowtrailers(boolean showtrailers) { 324 this.showtrailers = showtrailers; 325 } 326 327 332 public void setOutput(File output) { 333 this.output = output; 334 } 335 336 343 public void setAppend(boolean append) { 344 this.append = append; 345 } 346 347 348 353 public void setOnerror(OnError action) { 354 this.onError = action.getValue(); 355 } 356 357 363 public void setKeepformat(boolean keepformat) { 364 this.keepformat = keepformat; 365 } 366 367 372 public void setEscapeProcessing(boolean enable) { 373 escapeProcessing = enable; 374 } 375 376 380 public void execute() throws BuildException { 381 Vector savedTransaction = (Vector ) transactions.clone(); 382 String savedSqlCommand = sqlCommand; 383 384 sqlCommand = sqlCommand.trim(); 385 386 try { 387 if (srcFile == null && sqlCommand.length() == 0 388 && resources.size() == 0) { 389 if (transactions.size() == 0) { 390 throw new BuildException("Source file or resource " 391 + "collection, " 392 + "transactions or sql statement " 393 + "must be set!", getLocation()); 394 } 395 } 396 397 if (srcFile != null && !srcFile.exists()) { 398 throw new BuildException("Source file does not exist!", getLocation()); 399 } 400 401 Iterator iter = resources.iterator(); 403 while (iter.hasNext()) { 404 Resource r = (Resource) iter.next(); 405 Transaction t = createTransaction(); 407 t.setSrcResource(r); 408 } 409 410 Transaction t = createTransaction(); 412 t.setSrc(srcFile); 413 t.addText(sqlCommand); 414 conn = getConnection(); 415 if (!isValidRdbms(conn)) { 416 return; 417 } 418 try { 419 statement = conn.createStatement(); 420 statement.setEscapeProcessing(escapeProcessing); 421 422 PrintStream out = System.out; 423 try { 424 if (output != null) { 425 log("Opening PrintStream to output file " + output, 426 Project.MSG_VERBOSE); 427 out = new PrintStream ( 428 new BufferedOutputStream ( 429 new FileOutputStream (output 430 .getAbsolutePath(), 431 append))); 432 } 433 434 for (Enumeration e = transactions.elements(); 436 e.hasMoreElements();) { 437 438 ((Transaction) e.nextElement()).runTransaction(out); 439 if (!isAutocommit()) { 440 log("Committing transaction", Project.MSG_VERBOSE); 441 conn.commit(); 442 } 443 } 444 } finally { 445 if (out != null && out != System.out) { 446 out.close(); 447 } 448 } 449 } catch (IOException e) { 450 closeQuietly(); 451 throw new BuildException(e, getLocation()); 452 } catch (SQLException e) { 453 closeQuietly(); 454 throw new BuildException(e, getLocation()); 455 } finally { 456 try { 457 if (statement != null) { 458 statement.close(); 459 } 460 if (conn != null) { 461 conn.close(); 462 } 463 } catch (SQLException ex) { 464 } 466 } 467 468 log(goodSql + " of " + totalSql 469 + " SQL statements executed successfully"); 470 } finally { 471 transactions = savedTransaction; 472 sqlCommand = savedSqlCommand; 473 } 474 } 475 476 483 protected void runStatements(Reader reader, PrintStream out) 484 throws SQLException , IOException { 485 StringBuffer sql = new StringBuffer (); 486 String line; 487 488 BufferedReader in = new BufferedReader (reader); 489 490 while ((line = in.readLine()) != null) { 491 if (!keepformat) { 492 line = line.trim(); 493 } 494 line = getProject().replaceProperties(line); 495 if (!keepformat) { 496 if (line.startsWith("//")) { 497 continue; 498 } 499 if (line.startsWith("--")) { 500 continue; 501 } 502 StringTokenizer st = new StringTokenizer (line); 503 if (st.hasMoreTokens()) { 504 String token = st.nextToken(); 505 if ("REM".equalsIgnoreCase(token)) { 506 continue; 507 } 508 } 509 } 510 511 if (!keepformat) { 512 sql.append(" "); 513 sql.append(line); 514 } else { 515 sql.append("\n"); 516 sql.append(line); 517 } 518 519 if (!keepformat) { 523 if (line.indexOf("--") >= 0) { 524 sql.append("\n"); 525 } 526 } 527 if ((delimiterType.equals(DelimiterType.NORMAL) 528 && StringUtils.endsWith(sql, delimiter)) 529 || 530 (delimiterType.equals(DelimiterType.ROW) 531 && line.equals(delimiter))) { 532 execSQL(sql.substring(0, sql.length() - delimiter.length()), 533 out); 534 sql.replace(0, sql.length(), ""); 535 } 536 } 537 if (sql.length() > 0) { 539 execSQL(sql.toString(), out); 540 } 541 } 542 543 544 550 protected void execSQL(String sql, PrintStream out) throws SQLException { 551 if ("".equals(sql.trim())) { 553 return; 554 } 555 556 ResultSet resultSet = null; 557 try { 558 totalSql++; 559 log("SQL: " + sql, Project.MSG_VERBOSE); 560 561 boolean ret; 562 int updateCount = 0, updateCountTotal = 0; 563 564 ret = statement.execute(sql); 565 updateCount = statement.getUpdateCount(); 566 resultSet = statement.getResultSet(); 567 do { 568 if (!ret) { 569 if (updateCount != -1) { 570 updateCountTotal += updateCount; 571 } 572 } else { 573 if (print) { 574 printResults(resultSet, out); 575 } 576 } 577 ret = statement.getMoreResults(); 578 if (ret) { 579 updateCount = statement.getUpdateCount(); 580 resultSet = statement.getResultSet(); 581 } 582 } while (ret); 583 584 log(updateCountTotal + " rows affected", 585 Project.MSG_VERBOSE); 586 587 if (print && showtrailers) { 588 out.println(updateCountTotal + " rows affected"); 589 } 590 591 SQLWarning warning = conn.getWarnings(); 592 while (warning != null) { 593 log(warning + " sql warning", Project.MSG_VERBOSE); 594 warning = warning.getNextWarning(); 595 } 596 conn.clearWarnings(); 597 goodSql++; 598 } catch (SQLException e) { 599 log("Failed to execute: " + sql, Project.MSG_ERR); 600 if (!onError.equals("continue")) { 601 throw e; 602 } 603 log(e.toString(), Project.MSG_ERR); 604 } finally { 605 if (resultSet != null) { 606 resultSet.close(); 607 } 608 } 609 } 610 611 619 protected void printResults(PrintStream out) throws SQLException { 620 ResultSet rs = statement.getResultSet(); 621 try { 622 printResults(rs, out); 623 } finally { 624 if (rs != null) { 625 rs.close(); 626 } 627 } 628 } 629 630 637 protected void printResults(ResultSet rs, PrintStream out) 638 throws SQLException { 639 if (rs != null) { 640 log("Processing new result set.", Project.MSG_VERBOSE); 641 ResultSetMetaData md = rs.getMetaData(); 642 int columnCount = md.getColumnCount(); 643 StringBuffer line = new StringBuffer (); 644 if (showheaders) { 645 for (int col = 1; col < columnCount; col++) { 646 line.append(md.getColumnName(col)); 647 line.append(","); 648 } 649 line.append(md.getColumnName(columnCount)); 650 out.println(line); 651 line = new StringBuffer (); 652 } 653 while (rs.next()) { 654 boolean first = true; 655 for (int col = 1; col <= columnCount; col++) { 656 String columnValue = rs.getString(col); 657 if (columnValue != null) { 658 columnValue = columnValue.trim(); 659 } 660 661 if (first) { 662 first = false; 663 } else { 664 line.append(","); 665 } 666 line.append(columnValue); 667 } 668 out.println(line); 669 line = new StringBuffer (); 670 } 671 } 672 out.println(); 673 } 674 675 680 private void closeQuietly() { 681 if (!isAutocommit() && conn != null && onError.equals("abort")) { 682 try { 683 conn.rollback(); 684 } catch (SQLException ex) { 685 } 687 } 688 } 689 690 694 public static class OnError extends EnumeratedAttribute { 695 696 public String [] getValues() { 697 return new String [] {"continue", "stop", "abort"}; 698 } 699 } 700 701 707 public class Transaction { 708 private Resource tSrcResource = null; 709 private String tSqlCommand = ""; 710 711 715 public void setSrc(File src) { 716 if (src != null) { 719 setSrcResource(new FileResource(src)); 720 } 721 } 722 723 728 public void setSrcResource(Resource src) { 729 if (tSrcResource != null) { 730 throw new BuildException("only one resource per transaction"); 731 } 732 tSrcResource = src; 733 } 734 735 739 public void addText(String sql) { 740 if (sql != null) { 741 if (getExpandProperties()) { 742 sql = getProject().replaceProperties(sql); 743 } 744 this.tSqlCommand += sql; 745 } 746 } 747 748 753 public void addConfigured(ResourceCollection a) { 754 if (a.size() != 1) { 755 throw new BuildException("only single argument resource " 756 + "collections are supported."); 757 } 758 setSrcResource((Resource) a.iterator().next()); 759 } 760 761 764 private void runTransaction(PrintStream out) 765 throws IOException , SQLException { 766 if (tSqlCommand.length() != 0) { 767 log("Executing commands", Project.MSG_INFO); 768 runStatements(new StringReader (tSqlCommand), out); 769 } 770 771 if (tSrcResource != null) { 772 log("Executing resource: " + tSrcResource.toString(), 773 Project.MSG_INFO); 774 InputStream is = null; 775 Reader reader = null; 776 try { 777 is = tSrcResource.getInputStream(); 778 reader = 779 (encoding == null) ? new InputStreamReader (is) 780 : new InputStreamReader (is, encoding); 781 runStatements(reader, out); 782 } finally { 783 FileUtils.close(is); 784 FileUtils.close(reader); 785 } 786 } 787 } 788 } 789 } 790 | Popular Tags |