| 1 19 package com.mysql.jdbc; 20 21 import java.io.UnsupportedEncodingException ; 22 23 import java.sql.SQLException ; 24 import java.sql.SQLWarning ; 25 import java.sql.Types ; 26 27 import java.util.ArrayList ; 28 import java.util.Iterator ; 29 import java.util.List ; 30 31 32 50 public class Statement implements java.sql.Statement { 51 52 protected Connection connection = null; 53 54 55 protected List batchedArgs; 56 57 58 protected List openResults = new ArrayList (); 59 60 61 protected ResultSet nextResults = null; 62 63 64 protected ResultSet results = null; 65 66 67 protected SQLWarning warningChain = null; 68 69 70 protected SQLWarning pendingWarnings = null; 71 72 73 protected SingleByteCharsetConverter charConverter = null; 74 75 76 protected String charEncoding = null; 77 78 79 protected String currentCatalog = null; 80 81 82 protected boolean doEscapeProcessing = true; 83 84 85 protected boolean isClosed = false; 86 87 88 protected boolean maxRowsChanged = false; 89 90 91 protected boolean pedantic = false; 92 93 94 protected int maxFieldSize = MysqlIO.getMaxBuf(); 95 96 100 protected int maxRows = -1; 101 102 103 protected int resultSetConcurrency = 0; 104 105 106 protected int resultSetType = 0; 107 108 109 protected int timeout = 0; 110 111 112 protected long lastInsertId = -1; 113 114 115 protected long updateCount = -1; 116 117 118 private int fetchSize = 0; 119 120 121 private boolean serverSupportsConvertFn; 122 123 131 public Statement(Connection c, String catalog) throws SQLException { 132 if (Driver.TRACE) { 133 Object [] args = { c }; 134 Debug.methodCall(this, "constructor", args); 135 } 136 137 if ((c == null) || ((com.mysql.jdbc.Connection) c).isClosed()) { 138 throw new SQLException ("Connection is closed.", "08003"); 139 } 140 141 this.connection = c; 142 this.currentCatalog = catalog; 143 this.pedantic = this.connection.isPedantic(); 144 this.serverSupportsConvertFn = this.connection.getIO().versionMeetsMinimum(4, 0, 2); 145 146 if (connection != null) { 150 maxFieldSize = connection.getMaxAllowedPacket(); 151 } 152 153 if (this.connection.useUnicode()) { 154 this.charEncoding = connection.getEncoding(); 155 this.charConverter = this.connection.getCharsetConverter(this.charEncoding); 156 } 157 158 int maxRowsConn = this.connection.getMaxRows(); 159 160 if (maxRowsConn != -1) { 161 setMaxRows(maxRowsConn); 162 } 163 } 164 165 172 public java.sql.Connection getConnection() throws SQLException { 173 return (java.sql.Connection ) connection; 174 } 175 176 191 public void setCursorName(String name) throws java.sql.SQLException { 192 if (Driver.TRACE) { 193 Object [] args = { name }; 194 Debug.methodCall(this, "setCursorName", args); 195 } 196 197 } 199 200 208 public void setEscapeProcessing(boolean enable) 209 throws java.sql.SQLException { 210 if (Driver.TRACE) { 211 Object [] args = { new Boolean (enable) }; 212 Debug.methodCall(this, "setEscapeProcessing", args); 213 } 214 215 doEscapeProcessing = enable; 216 } 217 218 220 232 public void setFetchDirection(int direction) throws SQLException { 233 switch (direction) { 234 case java.sql.ResultSet.FETCH_FORWARD: 235 case java.sql.ResultSet.FETCH_REVERSE: 236 case java.sql.ResultSet.FETCH_UNKNOWN: 237 break; 238 239 default: 240 throw new SQLException ("Illegal value for setFetchDirection()", 241 SQLError.SQL_STATE_ILLEGAL_ARGUMENT); 242 } 243 } 244 245 252 public int getFetchDirection() throws SQLException { 253 return java.sql.ResultSet.FETCH_FORWARD; 254 } 255 256 269 public void setFetchSize(int rows) throws SQLException { 270 if (((rows < 0) && (rows != Integer.MIN_VALUE)) 271 || ((maxRows != 0) && (maxRows != -1) 272 && (rows > this.getMaxRows()))) { 273 throw new SQLException ("Illegal value for setFetchSize()", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); 274 } 275 276 fetchSize = rows; 277 } 278 279 286 public int getFetchSize() throws SQLException { 287 return fetchSize; 288 } 289 290 297 public java.sql.ResultSet getGeneratedKeys() throws SQLException { 298 Field[] fields = new Field[1]; 299 fields[0] = new Field("", "GENERATED_KEY", Types.BIGINT, 17); 300 301 ArrayList rowSet = new ArrayList (); 302 303 long beginAt = getLastInsertID(); 304 int numKeys = getUpdateCount(); 305 306 String serverInfo = this.results.getServerInfo(); 307 308 313 if ((numKeys > 0) 314 && this.results.getFirstCharOfQuery() == 'R' 315 && (serverInfo != null) 316 && (serverInfo.length() > 0)) { 317 numKeys = getRecordCountFromInfo(serverInfo); 318 } 319 320 if ((beginAt > 0) && (numKeys > 0)) { 321 for (int i = 0; i < numKeys; i++) { 322 byte[][] row = new byte[1][]; 323 row[0] = Long.toString(beginAt++).getBytes(); 324 rowSet.add(row); 325 } 326 } 327 328 return new com.mysql.jdbc.ResultSet(currentCatalog, fields, 329 new RowDataStatic(rowSet), connection); 330 } 331 332 345 public long getLastInsertID() { 346 if (Driver.TRACE) { 347 Object [] args = new Object [0]; 348 Debug.methodCall(this, "getLastInsertID", args); 349 } 350 351 return lastInsertId; 352 } 353 354 366 public long getLongUpdateCount() { 367 if (Driver.TRACE) { 368 Object [] args = new Object [0]; 369 Debug.methodCall(this, "getLongUpdateCount", args); 370 } 371 372 if (results == null) { 373 return -1; 374 } 375 376 if (results.reallyResult()) { 377 return -1; 378 } 379 380 return updateCount; 381 } 382 383 391 public void setMaxFieldSize(int max) throws SQLException { 392 if (Driver.TRACE) { 393 Object [] args = { new Integer (max) }; 394 Debug.methodCall(this, "setMaxFieldSize", args); 395 } 396 397 if (max < 0) { 398 throw new SQLException ("Illegal value for setMaxFieldSize()", 399 SQLError.SQL_STATE_ILLEGAL_ARGUMENT); 400 } 401 402 int maxBuf = (connection != null) ? connection.getMaxAllowedPacket() 403 : MysqlIO.getMaxBuf(); 404 405 if (max > maxBuf) { 406 throw new java.sql.SQLException ( 407 "Can not set max field size > max allowed packet: " + maxBuf, 408 SQLError.SQL_STATE_ILLEGAL_ARGUMENT); 409 } else { 410 maxFieldSize = max; 411 } 412 } 413 414 424 public int getMaxFieldSize() throws java.sql.SQLException { 425 if (Driver.TRACE) { 426 Object [] args = new Object [0]; 427 Debug.methodCall(this, "getMaxFieldSize", args); 428 } 429 430 return maxFieldSize; 431 } 432 433 442 public void setMaxRows(int max) throws java.sql.SQLException { 443 if (Driver.TRACE) { 444 Object [] args = { new Integer (max) }; 445 Debug.methodCall(this, "setMaxRows", args); 446 } 447 448 if ((max > MysqlDefs.MAX_ROWS) || (max < 0)) { 449 throw new java.sql.SQLException ("setMaxRows() out of range. " + max 450 + " > " + MysqlDefs.MAX_ROWS + ".", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); 451 } 452 453 if (max == 0) { 454 max = -1; 455 } 456 457 this.maxRows = max; 458 this.maxRowsChanged = true; 459 460 if (maxRows == -1) { 461 connection.unsetMaxRows(this); 462 this.maxRowsChanged = false; 463 } else { 464 connection.maxRowsChanged(this); 470 } 471 } 472 473 482 public int getMaxRows() throws java.sql.SQLException { 483 if (Driver.TRACE) { 484 Object [] args = new Object [0]; 485 Debug.methodCall(this, "getMaxRows", args); 486 } 487 488 if (maxRows <= 0) { 489 return 0; 490 } else { 491 return maxRows; 492 } 493 } 494 495 503 public boolean getMoreResults() throws java.sql.SQLException { 504 if (Driver.TRACE) { 505 Object [] args = new Object [0]; 506 Debug.methodCall(this, "getMoreResults", args); 507 } 508 509 return getMoreResults(CLOSE_CURRENT_RESULT); 510 } 511 512 515 public synchronized boolean getMoreResults(int current) 516 throws SQLException { 517 switch (current) { 518 case Statement.CLOSE_CURRENT_RESULT: 519 520 if (results != null) { 521 results.close(); 522 } 523 524 break; 525 526 case Statement.CLOSE_ALL_RESULTS: 527 528 if (results != null) { 529 results.close(); 530 } 531 532 closeAllOpenResults(); 533 534 break; 535 536 case Statement.KEEP_CURRENT_RESULT: 537 openResults.add(results); 538 539 break; 540 541 default: 542 throw new SQLException ("Illegal flag for getMoreResults(int)", 543 SQLError.SQL_STATE_ILLEGAL_ARGUMENT); 544 } 545 546 results = nextResults; 547 548 nextResults = null; 549 550 return ((results != null) && results.reallyResult()) ? true : false; 551 } 552 553 560 public void setQueryTimeout(int seconds) throws SQLException { 561 if (Driver.TRACE) { 562 Object [] args = { new Integer (seconds) }; 563 Debug.methodCall(this, "setQueryTimeout", args); 564 } 565 566 if (seconds < 0) { 567 throw new SQLException ("Illegal value for setQueryTimeout()", 568 SQLError.SQL_STATE_ILLEGAL_ARGUMENT); 569 } 570 571 timeout = seconds; 572 } 573 574 583 public int getQueryTimeout() throws java.sql.SQLException { 584 if (Driver.TRACE) { 585 Object [] args = new Object [0]; 586 Debug.methodCall(this, "getQueryTimeout", args); 587 } 588 589 return timeout; 590 } 591 592 601 public synchronized java.sql.ResultSet getResultSet() 602 throws java.sql.SQLException { 603 if (Driver.TRACE) { 604 Object [] args = new Object [0]; 605 Debug.methodCall(this, "getResultSet", args); 606 } 607 608 return ((results != null) && results.reallyResult()) 609 ? (java.sql.ResultSet ) results : null; 610 } 611 612 619 public int getResultSetConcurrency() throws SQLException { 620 return resultSetConcurrency; 621 } 622 623 626 public int getResultSetHoldability() throws SQLException { 627 return ResultSet.HOLD_CURSORS_OVER_COMMIT; 628 } 629 630 637 public int getResultSetType() throws SQLException { 638 return resultSetType; 639 } 640 641 650 public synchronized int getUpdateCount() throws java.sql.SQLException { 651 if (Driver.TRACE) { 652 Object [] args = new Object [0]; 653 Debug.methodCall(this, "getUpdateCount", args); 654 } 655 656 if (results == null) { 657 return -1; 658 } 659 660 if (results.reallyResult()) { 661 return -1; 662 } 663 664 int truncatedUpdateCount = 0; 665 666 if (results.getUpdateCount() > Integer.MAX_VALUE) { 667 truncatedUpdateCount = Integer.MAX_VALUE; 668 } else { 669 truncatedUpdateCount = (int) results.getUpdateCount(); 670 } 671 672 return truncatedUpdateCount; 673 } 674 675 696 public synchronized java.sql.SQLWarning getWarnings() 697 throws java.sql.SQLException { 698 if (Driver.TRACE) { 699 Object [] args = new Object [0]; 700 Debug.methodCall(this, "getWarnings", args); 701 } 702 703 return warningChain; 704 } 705 706 713 public synchronized void addBatch(String sql) throws SQLException { 714 if (batchedArgs == null) { 715 batchedArgs = new ArrayList (); 716 } 717 718 if (sql != null) { 719 batchedArgs.add(sql); 720 } 721 } 722 723 731 public void cancel() throws java.sql.SQLException { 732 if (Driver.TRACE) { 733 Object [] args = new Object [0]; 734 Debug.methodCall(this, "cancel", args); 735 } 736 737 } 739 740 747 public synchronized void clearBatch() throws SQLException { 748 if (batchedArgs != null) { 749 batchedArgs.clear(); 750 } 751 } 752 753 760 public synchronized void clearWarnings() throws java.sql.SQLException { 761 if (Driver.TRACE) { 762 Object [] args = new Object [0]; 763 Debug.methodCall(this, "clearWarnings", args); 764 } 765 766 this.warningChain = this.pendingWarnings; 767 this.pendingWarnings = null; 768 } 769 770 784 public synchronized void close() throws java.sql.SQLException { 785 if (Driver.TRACE) { 786 Object [] args = new Object [0]; 787 Debug.methodCall(this, "close", args); 788 } 789 790 if (this.isClosed) { 791 return; 792 } 793 794 if (results != null) { 795 try { 796 results.close(); 797 } catch (Exception ex) { 798 ; 799 } 800 } 801 802 if (this.maxRowsChanged && this.connection != null) { 803 this.connection.unsetMaxRows(this); 804 } 805 806 this.results = null; 807 this.connection = null; 808 this.warningChain = null; 809 this.isClosed = true; 810 this.closeAllOpenResults(); 811 this.openResults = null; 812 } 813 814 826 public synchronized boolean execute(String sql) throws SQLException { 827 if (Driver.TRACE) { 828 Object [] args = { sql }; 829 Debug.methodCall(this, "execute", args); 830 } 831 832 char firstNonWsChar = StringUtils.firstNonWsCharUc(sql); 833 834 if (connection.isReadOnly()) { 835 if (firstNonWsChar != 'S') { 836 throw new SQLException ("Connection is read-only. " 837 + "Queries leading to data modification are not allowed", 838 SQLError.SQL_STATE_ILLEGAL_ARGUMENT); 839 } 840 } 841 842 checkClosed(); 843 844 if (this.doEscapeProcessing) { 845 sql = EscapeProcessor.escapeSQL(sql, this.serverSupportsConvertFn); 846 } 847 848 if (results != null) { 849 results.close(); 850 } 851 852 ResultSet rs = null; 853 854 synchronized (connection.getMutex()) { 861 clearWarnings(); 862 863 String oldCatalog = null; 864 865 if (!connection.getCatalog().equals(currentCatalog)) { 866 oldCatalog = connection.getCatalog(); 867 connection.setCatalog(currentCatalog); 868 } 869 870 boolean isSelect = (firstNonWsChar == 'S'); 871 872 if (connection.useMaxRows()) { 876 int rowLimit = -1; 877 878 if (isSelect) { 879 if (sql.toUpperCase().indexOf("LIMIT") != -1) { 880 rowLimit = this.maxRows; 881 } else { 882 if (maxRows <= 0) { 883 connection.execSQL("SET OPTION SQL_SELECT_LIMIT=DEFAULT", 884 -1, this.currentCatalog); 885 } else { 886 connection.execSQL("SET OPTION SQL_SELECT_LIMIT=" 887 + maxRows, -1, this.currentCatalog); 888 } 889 } 890 } else { 891 connection.execSQL("SET OPTION SQL_SELECT_LIMIT=DEFAULT", 892 -1, this.currentCatalog); 893 } 894 895 &nbs
|