001package com.hfg.sql; 002 003import java.io.BufferedReader; 004import java.io.IOException; 005import java.io.Reader; 006import java.sql.*; 007import java.util.ArrayList; 008import java.util.Collection; 009import java.util.List; 010import java.util.logging.Level; 011import java.util.logging.Logger; 012 013import com.hfg.datetime.DateUtil; 014import com.hfg.sql.jdbc.JDBCException; 015import com.hfg.sql.jdbc.JDBCResultSet; 016import com.hfg.sql.jdbc.SQLStatementOptions; 017import com.hfg.sql.table.DatabaseCol; 018import com.hfg.sql.table.DatabaseTable; 019import com.hfg.util.StackTraceElementFilter; 020import com.hfg.util.StackTraceUtil; 021import com.hfg.util.StringBuilderPlus; 022import com.hfg.util.StringUtil; 023import com.hfg.util.collection.CollectionUtil; 024 025//------------------------------------------------------------------------------ 026/** 027 SQL utility functions. 028 <div> 029 @author J. Alex Taylor, hairyfatguy.com 030 </div> 031 */ 032//------------------------------------------------------------------------------ 033// com.hfg XML/HTML Coding Library 034// 035// This library is free software; you can redistribute it and/or 036// modify it under the terms of the GNU Lesser General Public 037// License as published by the Free Software Foundation; either 038// version 2.1 of the License, or (at your option) any later version. 039// 040// This library is distributed in the hope that it will be useful, 041// but WITHOUT ANY WARRANTY; without even the implied warranty of 042// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 043// Lesser General Public License for more details. 044// 045// You should have received a copy of the GNU Lesser General Public 046// License along with this library; if not, write to the Free Software 047// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 048// 049// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com 050// jataylor@hairyfatguy.com 051//------------------------------------------------------------------------------ 052 053public class SQLUtil 054{ 055 public static Level sSQLLoggingLevel = Level.FINE; 056 057 private final static Logger LOGGER = Logger.getLogger(SQLUtil.class.getName()); 058 059 private static List<StackTraceElementFilter> sExclusions = new ArrayList<>(4); 060 061 static 062 { 063 LOGGER.setUseParentHandlers(false); 064 065 sExclusions.add(new StackTraceElementFilter().setPackage(SQLUtil.class.getPackage())); 066 sExclusions.add(new StackTraceElementFilter().setPackage(DatabaseTable.class.getPackage())); 067 } 068 069 //--------------------------------------------------------------------------- 070 public static Logger getLogger() 071 { 072 return LOGGER; 073 } 074 075 //--------------------------------------------------------------------------- 076 public static String sqlString(Object inValue) 077 { 078 return inValue != null ? sqlString(inValue.toString()) : "null"; 079 } 080 081 //--------------------------------------------------------------------------- 082 public static String sqlString(String inValue) 083 { 084 return inValue != null ? "'" + StringUtil.replaceAll(inValue, "\'", "\'\'") + "'" : "null"; 085 } 086 087 //--------------------------------------------------------------------------- 088 /** 089 All single and double quotes internal to the string are doubled for escaping. 090 @param inValue the value string to be escaped for single and double quotes 091 @return the escaped value 092 */ 093 public static String sqlStringWithDoubleQuotes(String inValue) 094 { 095 return inValue != null ? "\"" + StringUtil.replaceAll(StringUtil.replaceAll(inValue, "\"", "\"\""), "\'", "\'\'") + "\"" : "null"; 096 } 097 098 //--------------------------------------------------------------------------- 099 public static String sqlStringList(Collection<? extends Object> inValues) 100 { 101 String listString = ""; 102 103 if (CollectionUtil.hasValues(inValues)) 104 { 105 List<String> sqlStrings = new ArrayList<>(inValues.size()); 106 for (Object object : inValues) 107 { 108 sqlStrings.add(sqlString(object)); 109 } 110 111 listString = StringUtil.join(sqlStrings, ", "); 112 } 113 114 return listString; 115 } 116 117 //--------------------------------------------------------------------------- 118 public static boolean execute(Connection inConn, String inSQL) 119 throws SQLException 120 { 121 boolean result; 122 123 Statement stmt = null; 124 try 125 { 126 stmt = inConn.createStatement(); 127 result = execute(stmt, inSQL); 128 } 129 finally 130 { 131 SQLUtil.close(stmt); 132 } 133 134 return result; 135 } 136 137 //--------------------------------------------------------------------------- 138 public static boolean execute(PreparedStatement inPreparedStatement) 139 throws JDBCException 140 { 141 return execute(inPreparedStatement, null); 142 } 143 144 //--------------------------------------------------------------------------- 145 public static boolean execute(Statement inStatement, String inSQL) 146 throws JDBCException 147 { 148 boolean result; 149 150 long startTime = System.currentTimeMillis(); 151 152 try 153 { 154 if (inStatement instanceof PreparedStatement) 155 { 156 PreparedStatement ps = (PreparedStatement) inStatement; 157 inSQL = ps.toString(); 158 result = ((PreparedStatement) inStatement).execute(); 159 } 160 else 161 { 162 result = inStatement.execute(inSQL); 163 } 164 } 165 catch (Exception e) 166 { 167 throw new JDBCException("Error executing SQL:\n" + inSQL, e); 168 } 169 170 if (LOGGER.isLoggable(sSQLLoggingLevel)) 171 { 172 // Generate debugging info w/ the SQL run and its execution time 173 StringBuilderPlus msg = new StringBuilderPlus() 174 .appendln("[" + StackTraceUtil.getCallingStackTraceElement(sExclusions) + "] SQL:\n") 175 .appendln(inSQL) 176 .appendln("Execution Time: " + DateUtil.generateElapsedTimeString(startTime)); 177 178 LOGGER.log(sSQLLoggingLevel, msg.toString()); 179 } 180 181 return result; 182 } 183 184 //--------------------------------------------------------------------------- 185 public static int executeUpdate(Connection inConn, String inSQL) 186 throws SQLException 187 { 188 int rowsUpdated; 189 190 Statement stmt = null; 191 try 192 { 193 stmt = inConn.createStatement(); 194 rowsUpdated = executeUpdate(stmt, inSQL); 195 } 196 finally 197 { 198 SQLUtil.close(stmt); 199 } 200 201 return rowsUpdated; 202 } 203 204 //--------------------------------------------------------------------------- 205 public static int executeUpdate(PreparedStatement inPreparedStatement) 206 throws SQLException 207 { 208 return executeUpdate(inPreparedStatement, null); 209 } 210 211 //--------------------------------------------------------------------------- 212 public static int executeUpdate(Statement inStatement, CharSequence inSQL) 213 throws SQLException 214 { 215 int result; 216 217 long startTime = System.currentTimeMillis(); 218 219 try 220 { 221 if (inStatement instanceof PreparedStatement) 222 { 223 PreparedStatement ps = (PreparedStatement) inStatement; 224 inSQL = ps.toString(); 225 result = ((PreparedStatement) inStatement).executeUpdate(); 226 } 227 else 228 { 229 result = inStatement.executeUpdate(inSQL.toString()); 230 } 231 } 232 catch (Exception e) 233 { 234 throw new JDBCException("Error executing SQL:\n" + inSQL, e); 235 } 236 237 if (LOGGER.isLoggable(sSQLLoggingLevel)) 238 { 239 // Generate debugging info w/ the SQL run and its execution time 240 StringBuilderPlus msg = new StringBuilderPlus() 241 .appendln("[" + StackTraceUtil.getCallingStackTraceElement(sExclusions) + "] SQL:") 242 .appendln(inSQL) 243 .appendln("Rows " + (isDelete(inSQL) ? "Deleted" : "Updated") + ": " + result) 244 .appendln("Execution Time: " + DateUtil.generateElapsedTimeString(startTime)); 245 246 LOGGER.log(sSQLLoggingLevel, msg.toString()); 247 } 248 249 return result; 250 } 251 252 //--------------------------------------------------------------------------- 253 public static ResultSet executeQuery(Connection inConn, String inSQL) 254 throws SQLException 255 { 256 return executeQuery(inConn, inSQL, null); 257 } 258 259 //--------------------------------------------------------------------------- 260 public static ResultSet executeQuery(Connection inConn, String inSQL, SQLStatementOptions inOptions) 261 throws SQLException 262 { 263 Statement stmt = null; 264 ResultSet rs; 265 266 try 267 { 268 stmt = inConn.createStatement(); 269 270 if (inOptions != null) 271 { 272 inOptions.configureStmt(stmt); 273 } 274 275 rs = executeQuery(stmt, inSQL); 276 } 277 catch (SQLException e) 278 { 279 close(stmt); 280 throw e; 281 } 282 283 return rs; 284 } 285 286 //--------------------------------------------------------------------------- 287 public static int executeQuery(PreparedStatement inPreparedStatement) 288 throws SQLException 289 { 290 return executeUpdate(inPreparedStatement, null); 291 } 292 293 //--------------------------------------------------------------------------- 294 public static ResultSet executeQuery(Statement inStatement, String inSQL) 295 throws JDBCException 296 { 297 ResultSet rs; 298 299 long startTime = System.currentTimeMillis(); 300 301 try 302 { 303 if (inStatement instanceof PreparedStatement) 304 { 305 PreparedStatement ps = (PreparedStatement) inStatement; 306 inSQL = ps.toString(); 307 rs = ((PreparedStatement) inStatement).executeQuery(); 308 } 309 else 310 { 311 rs = inStatement.executeQuery(inSQL); 312 } 313 } 314 catch (Exception e) 315 { 316 throw new JDBCException("Error executing SQL:\n" + inSQL, e); 317 } 318 319 if (LOGGER.isLoggable(sSQLLoggingLevel)) 320 { 321 // Generate debugging info w/ the SQL run and its execution time 322 StringBuilderPlus msg = new StringBuilderPlus() 323 .appendln("[" + StackTraceUtil.getCallingStackTraceElement(sExclusions) + "] SQL:\n") 324 .appendln(inSQL) 325 .appendln("Execution Time: " + DateUtil.generateElapsedTimeString(startTime)); 326 327 LOGGER.log(sSQLLoggingLevel, msg.toString()); 328 } 329 330 return new JDBCResultSet(rs); 331 } 332 333 //--------------------------------------------------------------------------- 334 public static void closeResultSetAndStatement(ResultSet inResultSet) 335 throws JDBCException 336 { 337 try 338 { 339 if (inResultSet != null) 340 { 341 Statement stmt = inResultSet.getStatement(); 342 stmt.close(); 343 inResultSet.close(); 344 } 345 } catch (SQLException e) 346 { 347 throw new JDBCException(e); 348 } 349 } 350 351 //--------------------------------------------------------------------------- 352 public static void close(ResultSet inResultSet) 353 throws JDBCException 354 { 355 try 356 { 357 if (inResultSet != null) 358 { 359 inResultSet.close(); 360 } 361 } catch (SQLException e) 362 { 363 throw new JDBCException(e); 364 } 365 } 366 367 //--------------------------------------------------------------------------- 368 public static void close(Statement inStmt) 369 throws JDBCException 370 { 371 try 372 { 373 if (inStmt != null) 374 { 375 inStmt.close(); 376 } 377 } 378 catch (SQLException e) 379 { 380 throw new JDBCException(e); 381 } 382 } 383 384 //--------------------------------------------------------------------------- 385 public static void close(Connection inConn) 386 throws JDBCException 387 { 388 try 389 { 390 if (inConn != null) 391 { 392 inConn.close(); 393 } 394 } 395 catch (SQLException e) 396 { 397 throw new JDBCException(e); 398 } 399 } 400 401 //--------------------------------------------------------------------------- 402 public static List<String> splitBatchSQL(Reader inSQL) 403 throws IOException 404 { 405 List<String> sqlCommands = new ArrayList<String>(); 406 407 BufferedReader bufferedReader; 408 if (inSQL instanceof BufferedReader) 409 { 410 bufferedReader = (BufferedReader) inSQL; 411 } 412 else 413 { 414 bufferedReader = new BufferedReader(inSQL); 415 } 416 417 StringBuilderPlus currentSQLCommand = new StringBuilderPlus(); 418 419 // In-line SQL comments start with two dashes and continue to the end of the line. Ex: '-- my comment' 420 // Block SQL comments look like block comments in C or Java. Ex: '/* my comment */' 421 boolean inInlineComment = false; 422 boolean inBlockComment = false; 423 boolean inQuotedContent = false; 424 425 String line; 426 while ((line = bufferedReader.readLine()) != null) 427 { 428 inInlineComment = false; 429 char[] lineChars = line.toCharArray(); 430 431 for (int i = 0; i < line.length(); i++) 432 { 433 char theChar = lineChars[i]; 434 if (theChar == ';' 435 && ! inInlineComment 436 && ! inBlockComment 437 && ! inQuotedContent) 438 { 439 String sql = currentSQLCommand.toString().trim(); 440 if (StringUtil.isSet(sql)) 441 { 442 sqlCommands.add(sql); 443 } 444 445 currentSQLCommand.setLength(0); 446 } 447 else 448 { 449 currentSQLCommand.append(theChar); 450 451 // Is this the beginning of an inline comment? 452 if (theChar == ' ' 453 && i > 1 454 && lineChars[i - 1] == '-' 455 && lineChars[i - 2] == '-') 456 { 457 inInlineComment = true; 458 } 459 else if (inBlockComment // Is it the end of a block comment? 460 && theChar == '/' 461 && i > 0 462 && lineChars[i - 1] == '*') 463 { 464 inBlockComment = false; 465 } 466 else if (! inBlockComment // Is it the beginning of a block comment? 467 && theChar == '*' 468 && i > 0 469 && lineChars[i - 1] == '/') 470 { 471 inBlockComment = true; 472 } 473 else if (inQuotedContent // Is it end of some quoted content? 474 && theChar == '\'' 475 && (0 == i || lineChars[i - 1] != '\\')) 476 { 477 inQuotedContent = false; 478 } 479 else if (! inQuotedContent // Is it start of some quoted content? 480 && theChar == '\'' 481 && (0 == i || lineChars[i - 1] != '\\')) 482 { 483 inQuotedContent = true; 484 } 485 } 486 } 487 488 currentSQLCommand.appendln(); 489 } 490 491 // Process remaining content 492 String sql = currentSQLCommand.toString().trim(); 493 if (StringUtil.isSet(sql)) 494 { 495 sqlCommands.add(sql); 496 } 497 498 bufferedReader.close(); 499 500 return sqlCommands; 501 } 502 503 504 //--------------------------------------------------------------------------- 505 public static Integer getInteger(ResultSet inResultSet, String inColumnLabel) 506 throws SQLException 507 { 508 Integer value = inResultSet.getInt(inColumnLabel); 509 return (inResultSet.wasNull() ? null : value); 510 } 511 512 //--------------------------------------------------------------------------- 513 public static Integer getInteger(ResultSet inResultSet, DatabaseCol inColumn) 514 throws SQLException 515 { 516 Integer value = inResultSet.getInt(inColumn.name()); 517 return (inResultSet.wasNull() ? null : value); 518 } 519 520 //--------------------------------------------------------------------------- 521 public static Integer getInteger(ResultSet inResultSet, int inColumnIndex) 522 throws SQLException 523 { 524 Integer value = inResultSet.getInt(inColumnIndex); 525 return (inResultSet.wasNull() ? null : value); 526 } 527 528 529 //--------------------------------------------------------------------------- 530 public static Long getLong(ResultSet inResultSet, String inColumnLabel) 531 throws SQLException 532 { 533 Long value = inResultSet.getLong(inColumnLabel); 534 return (inResultSet.wasNull() ? null : value); 535 } 536 537 //--------------------------------------------------------------------------- 538 public static Long getLong(ResultSet inResultSet, DatabaseCol inColumn) 539 throws SQLException 540 { 541 Long value = inResultSet.getLong(inColumn.name()); 542 return (inResultSet.wasNull() ? null : value); 543 } 544 545 //--------------------------------------------------------------------------- 546 public static Long getLong(ResultSet inResultSet, int inColumnIndex) 547 throws SQLException 548 { 549 Long value = inResultSet.getLong(inColumnIndex); 550 return (inResultSet.wasNull() ? null : value); 551 } 552 553 554 //--------------------------------------------------------------------------- 555 public static Float getFloat(ResultSet inResultSet, String inColumnLabel) 556 throws SQLException 557 { 558 Float value = inResultSet.getFloat(inColumnLabel); 559 return (inResultSet.wasNull() ? null : value); 560 } 561 562 //--------------------------------------------------------------------------- 563 public static Float getFloat(ResultSet inResultSet, DatabaseCol inColumn) 564 throws SQLException 565 { 566 Float value = inResultSet.getFloat(inColumn.name()); 567 return (inResultSet.wasNull() ? null : value); 568 } 569 570 //--------------------------------------------------------------------------- 571 public static Float getFloat(ResultSet inResultSet, int inColumnIndex) 572 throws SQLException 573 { 574 Float value = inResultSet.getFloat(inColumnIndex); 575 return (inResultSet.wasNull() ? null : value); 576 } 577 578 579 //--------------------------------------------------------------------------- 580 public static Double getDouble(ResultSet inResultSet, String inColumnLabel) 581 throws SQLException 582 { 583 Double value = inResultSet.getDouble(inColumnLabel); 584 return (inResultSet.wasNull() ? null : value); 585 } 586 587 //--------------------------------------------------------------------------- 588 public static Double getDouble(ResultSet inResultSet, DatabaseCol inColumn) 589 throws SQLException 590 { 591 Double value = inResultSet.getDouble(inColumn.name()); 592 return (inResultSet.wasNull() ? null : value); 593 } 594 595 //--------------------------------------------------------------------------- 596 public static Double getDouble(ResultSet inResultSet, int inColumnIndex) 597 throws SQLException 598 { 599 Double value = inResultSet.getDouble(inColumnIndex); 600 return (inResultSet.wasNull() ? null : value); 601 } 602 603 //--------------------------------------------------------------------------- 604 /** 605 A null-tolerant wrapper for PreparedStatement's setString(). 606 @param inPreparedStatement the PreparedStatement in which to set the value 607 @param inIndex the parameter index where the value should be placed 608 @param inValue the value to insert into the PreparedStatement 609 @throws SQLException 610 */ 611 public static void setString(PreparedStatement inPreparedStatement, int inIndex, String inValue) 612 throws SQLException 613 { 614 if (inValue != null) 615 { 616 inPreparedStatement.setString(inIndex, inValue); 617 } 618 else 619 { 620 inPreparedStatement.setNull(inIndex, Types.VARCHAR); 621 } 622 } 623 624 //--------------------------------------------------------------------------- 625 /** 626 A null-tolerant wrapper for PreparedStatement's setFloat(). 627 @param inPreparedStatement the PreparedStatement in which to set the value 628 @param inIndex the parameter index where the value should be placed 629 @param inValue the value to insert into the PreparedStatement 630 @throws SQLException 631 */ 632 public static void setFloat(PreparedStatement inPreparedStatement, int inIndex, Float inValue) 633 throws SQLException 634 { 635 if (inValue != null) 636 { 637 inPreparedStatement.setFloat(inIndex, inValue); 638 } 639 else 640 { 641 inPreparedStatement.setNull(inIndex, Types.FLOAT); 642 } 643 } 644 645 //--------------------------------------------------------------------------- 646 /** 647 A null-tolerant wrapper for PreparedStatement's setDouble(). 648 @param inPreparedStatement the PreparedStatement in which to set the value 649 @param inIndex the parameter index where the value should be placed 650 @param inValue the value to insert into the PreparedStatement 651 @throws SQLException 652 */ 653 public static void setDouble(PreparedStatement inPreparedStatement, int inIndex, Double inValue) 654 throws SQLException 655 { 656 if (inValue != null) 657 { 658 inPreparedStatement.setDouble(inIndex, inValue); 659 } 660 else 661 { 662 inPreparedStatement.setNull(inIndex, Types.FLOAT); 663 } 664 } 665 666 //--------------------------------------------------------------------------- 667 /** 668 A null-tolerant wrapper for PreparedStatement's setInt(). 669 @param inPreparedStatement the PreparedStatement in which to set the value 670 @param inIndex the parameter index where the value should be placed 671 @param inValue the value to insert into the PreparedStatement 672 @throws SQLException 673 */ 674 public static void setInt(PreparedStatement inPreparedStatement, int inIndex, Integer inValue) 675 throws SQLException 676 { 677 if (inValue != null) 678 { 679 inPreparedStatement.setInt(inIndex, inValue); 680 } 681 else 682 { 683 inPreparedStatement.setNull(inIndex, Types.BIGINT); 684 } 685 } 686 687 //--------------------------------------------------------------------------- 688 /** 689 A null-tolerant wrapper for PreparedStatement's setShort(). 690 @param inPreparedStatement the PreparedStatement in which to set the value 691 @param inIndex the parameter index where the value should be placed 692 @param inValue the value to insert into the PreparedStatement 693 @throws SQLException 694 */ 695 public static void setShort(PreparedStatement inPreparedStatement, int inIndex, Short inValue) 696 throws SQLException 697 { 698 if (inValue != null) 699 { 700 inPreparedStatement.setShort(inIndex, inValue); 701 } 702 else 703 { 704 inPreparedStatement.setNull(inIndex, Types.SMALLINT); 705 } 706 } 707 708 //--------------------------------------------------------------------------- 709 /** 710 A null-tolerant wrapper for PreparedStatement's setLong(). 711 @param inPreparedStatement the PreparedStatement in which to set the value 712 @param inIndex the parameter index where the value should be placed 713 @param inValue the value to insert into the PreparedStatement 714 @throws SQLException 715 */ 716 public static void setLong(PreparedStatement inPreparedStatement, int inIndex, Long inValue) 717 throws SQLException 718 { 719 if (inValue != null) 720 { 721 inPreparedStatement.setLong(inIndex, inValue); 722 } 723 else 724 { 725 inPreparedStatement.setNull(inIndex, Types.BIGINT); 726 } 727 } 728 729 //--------------------------------------------------------------------------- 730 /** 731 A null-tolerant wrapper for PreparedStatement's setDate(). 732 @param inPreparedStatement the PreparedStatement in which to set the value 733 @param inIndex the parameter index where the value should be placed 734 @param inValue the value to insert into the PreparedStatement 735 @throws SQLException 736 */ 737 public static void setDate(PreparedStatement inPreparedStatement, int inIndex, java.util.Date inValue) 738 throws SQLException 739 { 740 if (inValue != null) 741 { 742 inPreparedStatement.setDate(inIndex, new Date(inValue.getTime())); 743 } 744 else 745 { 746 inPreparedStatement.setNull(inIndex, Types.BIGINT); 747 } 748 } 749 750 //--------------------------------------------------------------------------- 751 /** 752 A null-tolerant wrapper for PreparedStatement's setDate(). 753 @param inPreparedStatement the PreparedStatement in which to set the value 754 @param inIndex the parameter index where the value should be placed 755 @param inValue the value to insert into the PreparedStatement 756 @throws SQLException 757 */ 758 public static void setDate(PreparedStatement inPreparedStatement, int inIndex, Date inValue) 759 throws SQLException 760 { 761 if (inValue != null) 762 { 763 inPreparedStatement.setDate(inIndex, inValue); 764 } 765 else 766 { 767 inPreparedStatement.setNull(inIndex, Types.BIGINT); 768 } 769 } 770 771 //--------------------------------------------------------------------------- 772 /** 773 A null-tolerant wrapper for PreparedStatement's setTimestamp(). 774 @param inPreparedStatement the PreparedStatement in which to set the value 775 @param inIndex the parameter index where the value should be placed 776 @param inValue the value to insert into the PreparedStatement 777 @throws SQLException 778 */ 779 public static void setTimestamp(PreparedStatement inPreparedStatement, int inIndex, Timestamp inValue) 780 throws SQLException 781 { 782 if (inValue != null) 783 { 784 inPreparedStatement.setTimestamp(inIndex, inValue); 785 } 786 else 787 { 788 inPreparedStatement.setNull(inIndex, Types.BIGINT); 789 } 790 } 791 792 793 //--------------------------------------------------------------------------- 794 /** 795 A convenience method for getting a count of rows that meet a specific criteria. 796 @param inConn the database connection 797 @param inTable the database table 798 @param inWhereClause the where clause to use 799 */ 800 public static int getRowCount(Connection inConn, DatabaseTable inTable, WhereClause inWhereClause) 801 throws SQLException 802 { 803 List<SQLClause> clauses = new ArrayList<>(1); 804 clauses.add(inWhereClause); 805 806 return getRowCount(inConn, inTable, clauses); 807 } 808 809 810 //--------------------------------------------------------------------------- 811 /** 812 A convenience method for getting a count of rows that meet a specific criteria. 813 @param inConn the database connection 814 @param inTable the database table 815 @param inClauses additional clauses to use 816 */ 817 public static int getRowCount(Connection inConn, DatabaseTable inTable, Collection<SQLClause> inClauses) 818 throws SQLException 819 { 820 int count = 0; 821 822 SQLQuery query = new SQLQuery() 823 .addSelect("count('x')") 824 .addFrom(inTable); 825 826 if (CollectionUtil.hasValues(inClauses)) 827 { 828 query.addClauses(inClauses); 829 } 830 831 ResultSet rs = null; 832 try 833 { 834 rs = query.execute(inConn); 835 if (rs.next()) 836 { 837 count = rs.getInt(1); 838 } 839 } 840 finally 841 { 842 SQLUtil.close(rs); 843 } 844 845 return count; 846 } 847 848 //--------------------------------------------------------------------------- 849 private static boolean isDelete(CharSequence inSQL) 850 { 851 boolean isDelete = false; 852 853 String[] lines = StringUtil.lines(inSQL); 854 for (String line : lines) 855 { 856 line = line.trim(); 857 if (! line.startsWith("-- ")) // Skip any comment lines 858 { 859 isDelete = line.toUpperCase().startsWith("DELETE"); 860 break; 861 } 862 } 863 864 return isDelete; 865 } 866}