1 19 package com.mysql.jdbc; 20 21 import java.io.ByteArrayInputStream ; 22 import java.io.ByteArrayOutputStream ; 23 import java.io.IOException ; 24 import java.io.InputStream ; 25 import java.io.ObjectOutputStream ; 26 import java.io.Reader ; 27 import java.io.StringReader ; 28 import java.io.UnsupportedEncodingException ; 29 30 import java.math.BigDecimal ; 31 32 import java.net.URL ; 33 34 import java.sql.Array ; 35 import java.sql.Clob ; 36 import java.sql.ParameterMetaData ; 37 import java.sql.Ref ; 38 import java.sql.SQLException ; 39 import java.sql.Time ; 40 import java.sql.Timestamp ; 41 import java.sql.Types ; 42 43 import java.text.ParsePosition ; 44 import java.text.SimpleDateFormat ; 45 46 import java.util.ArrayList ; 47 import java.util.Calendar ; 48 import java.util.TimeZone ; 49 50 51 74 public class PreparedStatement extends com.mysql.jdbc.Statement 75 implements java.sql.PreparedStatement { 76 private java.sql.DatabaseMetaData dbmd = null; 77 private ParseInfo parseInfo; 78 private java.sql.ResultSetMetaData pstmtResultMetaData; 79 private SimpleDateFormat tsdf = null; 80 private String originalSql = null; 81 private boolean[] isNull = null; 82 private boolean[] isStream = null; 83 private InputStream [] parameterStreams = null; 84 private byte[][] parameterValues = null; 85 private byte[][] staticSqlStrings = null; 86 private byte[] streamConvertBuf = new byte[4096]; 87 private int[] streamLengths = null; 88 private boolean hasLimitClause = false; 89 private boolean isLoadDataQuery = false; 90 private boolean retrieveGeneratedKeys = false; 91 private boolean useTrueBoolean = false; 92 private char firstCharOfStmt = 0; 93 94 104 public PreparedStatement(Connection conn, String sql, String catalog) 105 throws SQLException { 106 super(conn, catalog); 107 108 if (sql == null) { 109 throw new SQLException ("SQL String can not be NULL", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); 110 } 111 112 originalSql = sql; 113 114 this.dbmd = this.connection.getMetaData(); 115 116 useTrueBoolean = connection.getIO().versionMeetsMinimum(3, 21, 23); 117 118 this.parseInfo = new ParseInfo(sql, this.connection, this.dbmd, 119 this.charEncoding, this.charConverter); 120 121 initializeFromParseInfo(); 122 } 123 124 135 public PreparedStatement(Connection conn, String sql, String catalog, 136 ParseInfo cachedParseInfo) throws SQLException { 137 super(conn, catalog); 138 139 if (sql == null) { 140 throw new SQLException ("SQL String can not be NULL", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); 141 } 142 143 originalSql = sql; 144 145 this.dbmd = this.connection.getMetaData(); 146 147 useTrueBoolean = connection.getIO().versionMeetsMinimum(3, 21, 23); 148 149 this.parseInfo = cachedParseInfo; 150 151 initializeFromParseInfo(); 152 } 153 154 163 public void setArray(int i, Array x) throws SQLException { 164 throw new NotImplemented(); 165 } 166 167 185 public synchronized void setAsciiStream(int parameterIndex, InputStream x, 186 int length) throws SQLException { 187 if (x == null) { 188 setNull(parameterIndex, java.sql.Types.VARCHAR); 189 } else { 190 setBinaryStream(parameterIndex, x, length); 191 } 192 } 193 194 203 public void setBigDecimal(int parameterIndex, BigDecimal x) 204 throws SQLException { 205 if (x == null) { 206 setNull(parameterIndex, java.sql.Types.DECIMAL); 207 } else { 208 setInternal(parameterIndex, fixDecimalExponent(x.toString())); 209 } 210 } 211 212 229 public void setBinaryStream(int parameterIndex, InputStream x, int length) 230 throws SQLException { 231 if (x == null) { 232 setNull(parameterIndex, java.sql.Types.BINARY); 233 } else { 234 if ((parameterIndex < 1) 235 || (parameterIndex > staticSqlStrings.length)) { 236 throw new java.sql.SQLException ( 237 "Parameter index out of range (" + parameterIndex + " > " 238 + staticSqlStrings.length + ")", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); 239 } 240 241 parameterStreams[parameterIndex - 1] = x; 242 isStream[parameterIndex - 1] = true; 243 streamLengths[parameterIndex - 1] = length; 244 isNull[parameterIndex - 1] = false; 245 } 246 } 247 248 256 public void setBlob(int i, java.sql.Blob x) throws SQLException { 257 setBinaryStream(i, x.getBinaryStream(), (int) x.length()); 258 } 259 260 269 public void setBoolean(int parameterIndex, boolean x) 270 throws SQLException { 271 if (useTrueBoolean) { 272 setInternal(parameterIndex, x ? "'1'" : "'0'"); 273 } else { 274 setInternal(parameterIndex, x ? "'t'" : "'f'"); 275 } 276 } 277 278 287 public void setByte(int parameterIndex, byte x) throws SQLException { 288 setInternal(parameterIndex, String.valueOf(x)); 289 } 290 291 302 public void setBytes(int parameterIndex, byte[] x) 303 throws SQLException { 304 if (x == null) { 305 setNull(parameterIndex, java.sql.Types.BINARY); 306 } else { 307 int numBytes = x.length; 309 310 ByteArrayOutputStream bOut = new ByteArrayOutputStream (numBytes); 311 312 bOut.write('\''); 313 314 for (int i = 0; i < numBytes; ++i) { 315 byte b = x[i]; 316 317 switch (b) { 318 case 0: 319 bOut.write('\\'); 320 bOut.write('0'); 321 322 break; 323 324 case '\n': 325 bOut.write('\\'); 326 bOut.write('n'); 327 328 break; 329 330 case '\r': 331 bOut.write('\\'); 332 bOut.write('r'); 333 334 break; 335 336 case '\\': 337 bOut.write('\\'); 338 bOut.write('\\'); 339 340 break; 341 342 case '\'': 343 bOut.write('\\'); 344 bOut.write('\''); 345 346 break; 347 348 case '"': 349 bOut.write('\\'); 350 bOut.write('"'); 351 352 break; 353 354 case '\032': 355 bOut.write('\\'); 356 bOut.write('Z'); 357 358 break; 359 360 default: 361 bOut.write(b); 362 } 363 } 364 365 bOut.write('\''); 366 367 setInternal(parameterIndex, bOut.toByteArray()); 368 } 369 } 370 371 389 public void setCharacterStream(int parameterIndex, java.io.Reader reader, 390 int length) throws SQLException { 391 try { 392 if (reader == null) { 393 setNull(parameterIndex, Types.LONGVARCHAR); 394 } else { 395 char[] c = null; 396 int len = 0; 397 398 boolean useLength = this.connection.useStreamLengthsInPrepStmts(); 399 400 if (useLength && (length != -1)) { 401 c = new char[length]; 402 403 int numCharsRead = readFully(reader, c, length); 405 setString(parameterIndex, new String (c, 0, numCharsRead)); 406 } else { 407 c = new char[4096]; 408 409 StringBuffer buf = new StringBuffer (); 410 411 while ((len = reader.read(c)) != -1) { 412 buf.append(c, 0, len); 413 } 414 415 setString(parameterIndex, buf.toString()); 416 } 417 } 418 } catch (java.io.IOException ioEx) { 419 throw new SQLException (ioEx.toString(), SQLError.SQL_STATE_GENERAL_ERROR); 420 } 421 } 422 423 431 public void setClob(int i, Clob x) throws SQLException { 432 setString(i, x.getSubString(1L, (int) x.length())); 433 } 434 435 444 public void setDate(int parameterIndex, java.sql.Date x) 445 throws SQLException { 446 if (x == null) { 447 setNull(parameterIndex, java.sql.Types.DATE); 448 } else { 449 SimpleDateFormat dateFormatter = new SimpleDateFormat ( 452 "''yyyy-MM-dd''"); 453 setInternal(parameterIndex, dateFormatter.format(x)); 454 } 455 } 456 457 467 public void setDate(int parameterIndex, java.sql.Date x, Calendar cal) 468 throws SQLException { 469 setDate(parameterIndex, x); 470 } 471 472 481 public void setDouble(int parameterIndex, double x) 482 throws SQLException { 483 setInternal(parameterIndex, fixDecimalExponent(String.valueOf(x))); 484 } 485 486 495 public void setFloat(int parameterIndex, float x) throws SQLException { 496 setInternal(parameterIndex, fixDecimalExponent(String.valueOf(x))); 497 } 498 499 508 public void setInt(int parameterIndex, int x) throws SQLException { 509 setInternal(parameterIndex, String.valueOf(x)); 510 } 511 512 521 public void setLong(int parameterIndex, long x) throws SQLException { 522 setInternal(parameterIndex, String.valueOf(x)); 523 } 524 525 533 public synchronized java.sql.ResultSetMetaData getMetaData() throws SQLException { 534 PreparedStatement mdStmt = null; 535 java.sql.ResultSet mdRs = null; 536 537 if (this.pstmtResultMetaData == null) { 538 try { 539 mdStmt = new PreparedStatement(this.connection, 540 this.originalSql, this.currentCatalog, this.parseInfo); 541 542 mdStmt.setMaxRows(0); 543 544 int paramCount = this.parameterValues.length; 545 546 for (int i = 1; i <= paramCount; i++) { 547 mdStmt.setString(i, ""); 548 } 549 550 boolean hadResults = mdStmt.execute(); 551 552 if (hadResults) { 553 mdRs = mdStmt.getResultSet(); 554 555 this.pstmtResultMetaData = mdRs.getMetaData(); 556 } else { 557 this.pstmtResultMetaData = new ResultSetMetaData(new Field[0]); 558 } 559 } finally { 560 SQLException sqlExRethrow = null; 561 562 if (mdRs != null) { 563 try { 564 mdRs.close(); 565 } catch (SQLException sqlEx) { 566 sqlExRethrow = sqlEx; 567 } 568 569 mdRs = null; 570 } 571 572 if (mdStmt != null) { 573 try { 574 mdStmt.close(); 575 } catch (SQLException sqlEx) { 576 sqlExRethrow = sqlEx; 577 } 578 579 mdStmt = null; 580 } 581 582 if (sqlExRethrow != null) { 583 throw sqlExRethrow; 584 } 585 } 586 } 587 588 return this.pstmtResultMetaData; 589 } 590 591 604 public void setNull(int parameterIndex, int sqlType) 605 throws SQLException { 606 setInternal(parameterIndex, "null"); 607 isNull[parameterIndex - 1] = true; 608 } 609 610 612 625 public void setNull(int parameterIndex, int sqlType, String arg) 626 throws SQLException { 627 setNull(parameterIndex, sqlType); 628 } 629 630 655 public void setObject(int parameterIndex, Object parameterObj, 656 int targetSqlType, int scale) throws SQLException { 657 if (parameterObj == null) { 658 setNull(parameterIndex, java.sql.Types.OTHER); 659 } else { 660 try { 661 switch (targetSqlType) { 662 case Types.BIT: 663 case Types.TINYINT: 664 case Types.SMALLINT: 665 case Types.INTEGER: 666 case Types.BIGINT: 667 case Types.REAL: 668 case Types.FLOAT: 669 case Types.DOUBLE: 670 case Types.DECIMAL: 671 case Types.NUMERIC: 672 673 Number parameterAsNum; 674 675 if (parameterObj instanceof Boolean ) { 676 parameterAsNum = ((Boolean ) parameterObj).booleanValue() 677 ? new Integer (1) : new Integer (0); 678 } else if (parameterObj instanceof String ) { 679 switch (targetSqlType) { 680 case Types.BIT: 681 parameterAsNum = (Boolean.getBoolean((String ) parameterObj) 682 ? new Integer ("1") : new Integer ("0")); 683 684 break; 685 686 case Types.TINYINT: 687 case Types.SMALLINT: 688 case Types.INTEGER: 689 parameterAsNum = Integer.valueOf((String ) parameterObj); 690 691 break; 692 693 case Types.BIGINT: 694 parameterAsNum = Long.valueOf((String ) parameterObj); 695 696 break; 697 698 case Types.REAL: 699 parameterAsNum = Float.valueOf((String ) parameterObj); 700 701 break; 702 703 case Types.FLOAT: 704 case Types.DOUBLE: 705 parameterAsNum = Double.valueOf((String ) parameterObj); 706 707 break; 708 709 case Types.DECIMAL: 710 case Types.NUMERIC:default: 711 parameterAsNum = new java.math.BigDecimal ((String ) parameterObj); 712 } 713 } else { 714 parameterAsNum = (Number ) parameterObj; 715 } 716 717 switch (targetSqlType) { 718 case Types.BIT: 719 case Types.TINYINT: 720 case Types.SMALLINT: 721 case Types.INTEGER: 722 setInt(parameterIndex, parameterAsNum.intValue()); 723 724 break; 725 726 case Types.BIGINT: 727 setLong(parameterIndex, parameterAsNum.longValue()); 728 729 break; 730 731 case Types.REAL: 732 setFloat(parameterIndex, parameterAsNum.floatValue()); 733 734 break; 735 736 case Types.FLOAT: 737 case Types.DOUBLE: 738 setDouble(parameterIndex, parameterAsNum.doubleValue()); 739 740 break; 741 742 case Types.DECIMAL: 743 case Types.NUMERIC:default: 744 745 if (parameterAsNum instanceof java.math.BigDecimal ) { 746 setBigDecimal(parameterIndex, 747 (java.math.BigDecimal ) parameterAsNum); 748 } else if (parameterAsNum instanceof java.math.BigInteger ) { 749 setBigDecimal(parameterIndex, 750 new java.math.BigDecimal ( 751 (java.math.BigInteger ) parameterAsNum, scale)); 752 } else { 753 setBigDecimal(parameterIndex, 754 new java.math.BigDecimal ( 755 parameterAsNum.doubleValue())); 756 } 757 758 break; 759 } 760 761 break; 762 763 case Types.CHAR: 764 case Types.VARCHAR: 765 case Types.LONGVARCHAR: 766 setString(parameterIndex, parameterObj.toString()); 767 768 break; 769 770 case Types.CLOB: 771 772 if (parameterObj instanceof java.sql.Clob ) { 773 setClob(parameterIndex, (java.sql.Clob ) parameterObj); 774 } else { 775 setString(parameterIndex, parameterObj.toString()); 776 } 777 778 break; 779 780 case Types.BINARY: 781 case Types.VARBINARY: 782 case Types.LONGVARBINARY: 783 case Types.BLOB: 784 785 if (parameterObj instanceof byte[]) { 786 setBytes(parameterIndex, (byte[]) parameterObj); 787 } else if (parameterObj instanceof java.sql.Blob ) { 788 setBlob(parameterIndex, (java.sql.Blob ) parameterObj); 789 } else { 790 setBytes(parameterIndex, 791 StringUtils.getBytes(parameterObj.toString(), 792 this.charConverter, this.charEncoding)); 793 } 794 795 break; 796 797 case Types.DATE: 798 case Types.TIMESTAMP: 799 800 java.util.Date parameterAsDate; 801 802 if (parameterObj instanceof String ) { 803 ParsePosition pp = new ParsePosition (0); 804 java.text.DateFormat sdf = new java.text.SimpleDateFormat (getDateTimePattern( 805 (String ) parameterObj, false)); 806 parameterAsDate = sdf.parse((String ) parameterObj, pp); 807 } else { 808 parameterAsDate = (java.util.Date ) parameterObj; 809 } 810 811 switch (targetSqlType) { 812 case Types.DATE: 813 814 if (parameterAsDate instanceof java.sql.Date ) { 815 setDate(parameterIndex, 816 (java.sql.Date ) parameterAsDate); 817 } else { 818 setDate(parameterIndex, 819 new java.sql.Date (parameterAsDate.getTime())); 820 } 821 822 break; 823 824 case Types.TIMESTAMP: 825 826 if (parameterAsDate instanceof java.sql.Timestamp ) { 827 setTimestamp(parameterIndex, 828 (java.sql.Timestamp ) parameterAsDate); 829 } else { 830 setTimestamp(parameterIndex, 831 new java.sql.Timestamp ( 832 parameterAsDate.getTime())); 833 } 834 835 break; 836 } 837 838 break; 839 840 case Types.TIME: 841 842 if (parameterObj instanceof String ) { 843 java.text.DateFormat sdf = new java.text.SimpleDateFormat (getDateTimePattern( 844 (String ) parameterObj, true)); 845 setTime(parameterIndex, 846 new java.sql.Time (sdf.parse((String ) parameterObj) 847 .getTime())); 848 } else if (parameterObj instanceof Timestamp ) { 849 Timestamp xT = (Timestamp ) parameterObj; 850 setTime(parameterIndex, new java.sql.Time (xT.getTime())); 851 } else { 852 setTime(parameterIndex, (java.sql.Time ) parameterObj); 853 } 854 855 break; 856 857 case Types.OTHER: 858 setSerializableObject(parameterIndex, parameterObj); 859 860 break; 861 862 default: 863 throw new java.sql.SQLException ("Unknown Types value", 864 SQLError.SQL_STATE_GENERAL_ERROR); 865 } 866 } catch (Exception ex) { 867 if (ex instanceof java.sql.SQLException ) { 868 throw (java.sql.SQLException ) ex; 869 } else { 870 throw new java.sql.SQLException ("Cannot convert " 871 + parameterObj.getClass().toString() 872 + " to SQL type requested due to " 873 + ex.getClass().getName() + " - " + ex.getMessage(), 874 SQLError.SQL_STATE_GENERAL_ERROR); 875 } 876 } 877 } 878 } 879 880 890 public void setObject(int parameterIndex, Object parameterObj, 891 int targetSqlType) throws SQLException { 892 setObject(parameterIndex, parameterObj, targetSqlType, 0); 893 } 894 895 903 public void setObject(int parameterIndex, Object parameterObj) 904 throws SQLException { 905 if (parameterObj == null) { 906 setNull(parameterIndex, java.sql.Types.OTHER); 907 } else { 908 if (parameterObj instanceof Byte ) { 909 setInt(parameterIndex, ((Byte ) parameterObj).intValue()); 910 } else if (parameterObj instanceof String ) { 911 setString(parameterIndex, (String ) parameterObj); 912 } else if (parameterObj instanceof BigDecimal ) { 913 setBigDecimal(parameterIndex, (BigDecimal ) parameterObj); 914 } else if (parameterObj instanceof Short ) { 915 setShort(parameterIndex, ((Short ) parameterObj).shortValue()); 916 } else if (parameterObj instanceof Integer ) { 917 setInt(parameterIndex, ((Integer ) parameterObj).intValue()); 918 } else if (parameterObj instanceof Long ) { 919 setLong(parameterIndex, ((Long ) parameterObj).longValue()); 920 } else if (parameterObj instanceof Float ) { 921 setFloat(parameterIndex, ((Float ) parameterObj).floatValue()); 922 } else if (parameterObj instanceof Double ) { 923 setDouble(parameterIndex, ((Double ) parameterObj).doubleValue()); 924 } else if (parameterObj instanceof byte[]) { 925 setBytes(parameterIndex, (byte[]) parameterObj); 926 } else if (parameterObj instanceof java.sql.Date ) { 927 setDate(parameterIndex, (java.sql.Date ) parameterObj); 928 } else if (parameterObj instanceof Time ) { 929 setTime(parameterIndex, (Time ) parameterObj); 930 } else if (parameterObj instanceof Timestamp ) { 931 setTimestamp(parameterIndex, (Timestamp ) parameterObj); 932 } else if (parameterObj instanceof Boolean ) { 933 setBoolean(parameterIndex, 934 ((Boolean ) parameterObj).booleanValue()); 935 } else if (parameterObj instanceof InputStream ) { 936 setBinaryStream(parameterIndex, (InputStream ) parameterObj, -1); 937 } else if (parameterObj instanceof java.sql.Blob ) { 938 setBlob(parameterIndex, (java.sql.Blob ) parameterObj); 939 } else if (parameterObj instanceof java.sql.Clob ) { 940 setClob(parameterIndex, (java.sql.Clob ) parameterObj); 941 } else { 942 setSerializableObject(parameterIndex, parameterObj); 943 } 944 } 945 } 946 947 950 public ParameterMetaData getParameterMetaData() throws SQLException { 951 throw new NotImplemented(); 952 } 953 954 963 public void setRef(int i, Ref x) throws SQLException { 964 throw new NotImplemented(); 965 } 966 967 976 public void setShort(int parameterIndex, short x) throws SQLException { 977 setInternal(parameterIndex, String.valueOf(x)); 978 } 979 980 991 public void setString(int parameterIndex, String x) 992 throws SQLException { 993 if (x == null) { 995 try { 996 setInternal(parameterIndex, 997 StringUtils.getBytes("null", this.charConverter, 998 this.charEncoding)); 999 } catch (UnsupportedEncodingException uue) { 1000 throw new SQLException ("Unsupported character encoding '" 1001 + this.charEncoding + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); 1002 } 1003 } else { 1004 StringBuffer buf = new StringBuffer ((int) (x.length() * 1.1)); 1005 buf.append('\''); 1006 1007 int stringLength = x.length(); 1008 1009 for (int i = 0; i < stringLength; ++i) { 1010 char c = x.charAt(i); 1011 1012 switch (c) { 1013 case 0: 1014 buf.append('\\'); 1015 buf.append('0'); 1016 1017 break; 1018 1019 case '\n': 1020 buf.append('\\'); 1021 buf.append('n'); 1022 1023 break; 1024 1025 case '\r': 1026 buf.append('\\'); 1027 buf.append('r'); 1028 1029 break; 1030 1031 case '\\': 1032 buf.append('\\'); 1033 buf.append('\\'); 1034 1035 break; 1036 1037 case '\'': 1038 buf.append('\\'); 1039 buf.append('\''); 1040 1041 break; 1042 1043 case '"': 1044 buf.append('\\'); 1045 buf.append('"'); 1046 1047 break; 1048 1049 case '\032': 1050 buf.append('\\'); 1051 buf.append('Z'); 1052 1053 break; 1054 1055 default: 1056 buf.append(c); 1057 } 1058 } 1059 1060 buf.append('\''); 1061 1062 String parameterAsString = buf.toString(); 1063 1064 try { 1065 byte[] parameterAsBytes = null; 1066 1067 if (!this.isLoadDataQuery) { 1068 parameterAsBytes = StringUtils.getBytes(parameterAsString, 1069 this.charConverter, this.charEncoding); 1070 } else { 1071 parameterAsBytes = parameterAsString.getBytes(); 1073 } 1074 1075 setInternal(parameterIndex, parameterAsBytes); 1076 } catch (UnsupportedEncodingException uue) { 1077 throw new SQLException ("Unsupported character encoding '" 1078 + this.charEncoding + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); 1079 } 1080 } 1081 } 1082 1083 1092 public void setTime(int parameterIndex, Time x) throws SQLException { 1093 setTimeInternal(parameterIndex, x, this.connection.getDefaultTimeZone()); 1094 } 1095 1096 1106 public void setTime(int parameterIndex, java.sql.Time x, Calendar cal) 1107 throws SQLException { 1108 setTimeInternal(parameterIndex, x, cal.getTimeZone()); 1109 } 1110 1111 1120 public void setTimestamp(int parameterIndex, Timestamp x) 1121 throws SQLException { 1122 setTimestampInternal(parameterIndex, x, this.connection.getDefaultTimeZone()); 1123 } 1124 1125 1135 public void setTimestamp(int parameterIndex, java.sql.Timestamp x, 1136 Calendar cal) throws SQLException { 1137 setTimestampInternal(parameterIndex, x, cal.getTimeZone()); 1138 } 1139 1140 1143 public void setURL(int parameterIndex, URL arg) throws SQLException { 1144 if (arg != null) { 1145 setString(parameterIndex, arg.toString()); 1146 } else { 1147 setNull(parameterIndex, Types.CHAR); 1148 } 1149 } 1150 1151 1171 public void setUnicodeStream(int parameterIndex, InputStream x, int length) 1172 throws SQLException { 1173 if (x == null) { 1174 setNull(parameterIndex, java.sql.Types.VARCHAR); 1175 } else { 1176 setBinaryStream(parameterIndex, x, length); 1177 } 1178 } 1179 1180 1187 public void addBatch() throws SQLException { 1188 if (batchedArgs == null) { 1189 batchedArgs = new ArrayList (); 1190 } 1191 1192 batchedArgs.add(new BatchParams(parameterValues, parameterStreams, 1193 isStream, streamLengths, isNull)); 1194 } 1195 1196 1205 public void clearParameters() throws SQLException { 1206 for (int i = 0; i < parameterValues.length; i++) { 1207 parameterValues[i] = null; 1208 parameterStreams[i] = null; 1209 isStream[i] = false; 1210 isNull[i] = false; 1211 } 1212 } 1213 1214 1219 public void close() throws SQLException { 1220 super.close(); 1221 1222 this.parseInfo = null; 1223 this.dbmd = null; 1224 this.originalSql = null; 1225 this.staticSqlStrings = null; 1226 this.parameterValues = null; 1227 this.parameterStreams = null; 1228 this.isStream = null; 1229 this.streamLengths = null; 1230 this.isNull = null; 1231 this.streamConvertBuf = null; 1232 } 1233 1234 1244 public boolean execute() throws SQLException { 1245 if (connection.isReadOnly() && (firstCharOfStmt != 'S')) { 1246 throw new SQLException ("Connection is read-only. " 1247 + "Queries leading to data modification are not allowed", 1248 SQLError.SQL_STATE_ILLEGAL_ARGUMENT); 1249 } 1250 1251 checkClosed(); 1252 1253 ResultSet rs = null; 1254 1255 synchronized (connection.getMutex()) { 1256 Buffer sendPacket = fillSendPacket(); 1257 1258 String oldCatalog = null; 1259 1260 if (!this.connection.getCatalog().equals(currentCatalog)) { 1261 oldCatalog = this.connection.getCatalog(); 1262 this.connection.setCatalog(currentCatalog); 1263 } 1264 1265 boolean oldInfoMsgState = false; 1266 1267 if (this.retrieveGeneratedKeys) { 1268 oldInfoMsgState = this.connection.isReadInfoMsgEnabled(); 1269 this.connection.setReadInfoMsgEnabled(true); 1270 } 1271 1272 if (this.connection.useMaxRows()) { 1282 if (firstCharOfStmt == 'S') { 1283 if (hasLimitClause) { 1284 rs = this.connection.execSQL((String ) null, maxRows, 1285 sendPacket, resultSetConcurrency, 1286 createStreamingResultSet(), true, 1287 this.currentCatalog); 1288 } else { 1289 if (maxRows <= 0) { 1290 this.connection.execSQL("SET OPTION SQL_SELECT_LIMIT=DEFAULT", 1291 -1, this.currentCatalog); 1292 } else { 1293 this.connection.execSQL( 1294 "SET OPTION SQL_SELECT_LIMIT=" + maxRows, -1, 1295 this.currentCatalog); 1296 } 1297 } 1298 } else { 1299 this.connection.execSQL("SET OPTION SQL_SELECT_LIMIT=DEFAULT", 1300 -1, this.currentCatalog); 1301 } 1302 1303 rs = this.connection.execSQL(null, -1, sendPacket, 1305 resultSetConcurrency, createStreamingResultSet(), 1306 (firstCharOfStmt == 'S'), this.currentCatalog); 1307 } else { 1308 rs = this.connection.execSQL(null, -1, sendPacket, 1309 resultSetConcurrency, createStreamingResultSet(), 1310 (firstCharOfStmt == 'S'), this.currentCatalog); 1311 } 1312 1313 if (this.retrieveGeneratedKeys) { 1314 this.connection.setReadInfoMsgEnabled(oldInfoMsgState); 1315 } 1316 1317 if (oldCatalog != null) { 1318 this.connection.setCatalog(oldCatalog); 1319 } 1320 } 1321 1322 lastInsertId = rs.getUpdateID(); 1323 1324 if (rs != null) { 1325 this.results = rs; 1326 } 1327 1328 rs.setFirstCharOfQuery(this.firstCharOfStmt); 1329 rs.setConnection(connection); 1330 rs.setResultSetType(resultSetType); 1331 rs.setResultSetConcurrency(resultSetConcurrency); 1332 rs.setStatement(this); 1333 1334 return ((rs != null) && rs.reallyResult()); 1335 } 1336 1337 1349 public int[] executeBatch() throws SQLException { 1350 if (connection.isReadOnly()) { 1351 throw new SQLException ("Connection is read-only. " 1352 + "Queries leading to data modification are not allowed", 1353 SQLError.SQL_STATE_ILLEGAL_ARGUMENT); 1354 } 1355 1356 try { 1357 int[] updateCounts = null; 1358 1359 if (batchedArgs != null) { 1360 int nbrCommands = batchedArgs.size(); 1361 updateCounts = new int[nbrCommands]; 1362 1363 for (int i = 0; i < nbrCommands; i++) { 1364 updateCounts[i] = -3; 1365 } 1366 1367 SQLException sqlEx = null; 1368 1369 int commandIndex = 0; 1370 1371 for (commandIndex = 0; commandIndex < nbrCommands; 1372 commandIndex++) { 1373 Object arg = batchedArgs.get(commandIndex); 1374 1375 if (arg instanceof String ) { 1376 updateCounts[commandIndex] = executeUpdate((String ) arg); 1377 } else { 1378 BatchParams paramArg = (BatchParams) arg; 1379 1380 try { 1381 updateCounts[commandIndex] = executeUpdate(paramArg.parameterStrings, 1382 paramArg.parameterStreams, 1383 paramArg.isStream, paramArg.streamLengths, 1384 paramArg.isNull); 1385 } catch (SQLException ex) { 1386 updateCounts[commandIndex] = EXECUTE_FAILED; 1387 1388 if (this.connection.continueBatchOnError()) { 1389 sqlEx = ex; 1390 } else { 1391 int[] newUpdateCounts = new int[commandIndex]; 1392 System.arraycopy(updateCounts, 0, 1393 newUpdateCounts, 0, commandIndex); 1394 1395 throw new java.sql.BatchUpdateException (ex 1396 .getMessage(), ex.getSQLState(), 1397 ex.getErrorCode(), newUpdateCounts); 1398 } 1399 } 1400 } 1401 } 1402 1403 if (sqlEx != null) { 1404 throw new java.sql.BatchUpdateException (sqlEx.getMessage(), 1405 sqlEx.getSQLState(), sqlEx.getErrorCode(), updateCounts); 1406 } 1407 } 1408 1409 return (updateCounts != null) ? updateCounts : new int[0]; 1410 } finally { 1411 clearBatch(); 1412 } 1413 } 1414 1415 1423 public synchronized java.sql.ResultSet executeQuery() 1424 throws SQLException { 1425 checkClosed(); 1426 1427 if ((this.firstCharOfStmt == 'I') || (this.firstCharOfStmt == 'U') 1428 || (this.firstCharOfStmt == 'D') 1429 || (this.firstCharOfStmt == 'A') 1430 || (this.firstCharOfStmt == 'C')) { 1431 if (StringUtils.startsWithIgnoreCaseAndWs(this.originalSql, "INSERT") 1432 || StringUtils.startsWithIgnoreCaseAndWs(this.originalSql, 1433 "UPDATE") 1434 || StringUtils.startsWithIgnoreCaseAndWs(this.originalSql, 1435 "DELETE") 1436 || StringUtils.startsWithIgnoreCaseAndWs(this.originalSql, 1437 "DROP") 1438 || StringUtils.startsWithIgnoreCaseAndWs(this.originalSql, 1439 "CREATE") 1440 || StringUtils.startsWithIgnoreCaseAndWs(this.originalSql, 1441 "ALTER")) { 1442 throw new SQLException ("Can not issue data manipulation statements with executeQuery()", 1443 SQLError.SQL_STATE_ILLEGAL_ARGUMENT); 1444 } 1445 } 1446 1447 synchronized (connection.getMutex()) { 1452 Buffer sendPacket = fillSendPacket(); 1453 1454 if (this.results != null) { 1455 this.results.close(); 1456 } 1457 1458 String oldCatalog = null; 1459 1460 if (!this.connection.getCatalog().equals(currentCatalog)) { 1461 oldCatalog = this.connection.getCatalog(); 1462 this.connection.setCatalog(currentCatalog); 1463 } 1464 1465 if (this.connection.useMaxRows()) { 1466 if (hasLimitClause) { 1473 results = this.connection.execSQL((String ) null, maxRows, 1474 sendPacket, resultSetConcurrency, 1475 createStreamingResultSet(), true, 1476 this.currentCatalog); 1477 } else { 1478 if (maxRows <= 0) { 1479 this.connection.execSQL("SET OPTION SQL_SELECT_LIMIT=DEFAULT", 1480 -1, this.currentCatalog); 1481 } else { 1482 this.connection.execSQL("SET OPTION SQL_SELECT_LIMIT=" 1483 + maxRows, -1, this.currentCatalog); 1484 } 1485 1486 this.results = this.connection.execSQL(null, -1, 1487 sendPacket, resultSetConcurrency, 1488 createStreamingResultSet(), true, 1489 this.currentCatalog); 1490 1491 if (oldCatalog != null) { 1492 this.connection.setCatalog(oldCatalog); 1493 } 1494 } 1495 } else { 1496 this.results = this.connection.execSQL(null, -1, sendPacket, 1497 resultSetConcurrency, createStreamingResultSet(), true, 1498 this.currentCatalog); 1499 } 1500 1501 if (oldCatalog != null) { 1502 this.connection.setCatalog(oldCatalog); 1503 } 1504 } 1505 1506 lastInsertId = this.results.getUpdateID(); 1507 nextResults = this.results; 1508 this.results.setConnection(connection); 1509 this.results.setResultSetType(resultSetType); 1510 this.results.setResultSetConcurrency(resultSetConcurrency); 1511 this.results.setStatement(this); 1512 1513 return (java.sql.ResultSet ) this.results; 1514 } 1515 1516 1526 public synchronized int executeUpdate() throws SQLException { 1527 return executeUpdate(parameterValues, parameterStreams, isStream, 1528 streamLengths, isNull); 1529 } 1530 1531 1538 public String toString() { 1539 StringBuffer buf = new StringBuffer (); 1540 buf.append(super.toString()); 1541 buf.append(": "); 1542 1543 try { 1544 for (int i = 0; i < parameterValues.length; ++i) { 1545 if (this.charEncoding != null) { 1546 buf.append(new String (staticSqlStrings[i], this.charEncoding)); 1547 } else { 1548 buf.append(new String (staticSqlStrings[i])); 1549 } 1550 1551 if ((parameterValues[i] == null) && !isStream[i]) { 1552 buf.append("** NOT SPECIFIED **"); 1553 } else if (isStream[i]) { 1554 buf.append("** STREAM DATA **"); 1555 } else { 1556 if (this.charConverter != null) { 1557 buf.append(this.charConverter.toString( 1558 parameterValues[i])); 1559 } else { 1560 if (this.charEncoding != null) { 1561 buf.append(new String (parameterValues[i], 1562 this.charEncoding)); 1563 } else { 1564 buf.append(StringUtils.toAsciiString( 1565 parameterValues[i])); 1566 } 1567 } 1568 } 1569 } 1570 1571 if (this.charEncoding != null) { 1572 buf.append(new String ( 1573 staticSqlStrings[parameterValues.length], 1574 this.charEncoding)); 1575 } else { 1576 buf.append(staticSqlStrings[parameterValues.length]); 1577 } 1578 } catch (UnsupportedEncodingException uue) { 1579 throw new RuntimeException ("Unsupported character encoding '" 1580 + this.charEncoding + "'"); 1581 } 1582 1583 return buf.toString(); 1584 } 1585 1586 1595 protected void setBytesNoEscape(int parameterIndex, byte[] parameterAsBytes) 1596 throws SQLException { 1597 byte[] parameterWithQuotes = new byte[parameterAsBytes.length + 2]; 1598 parameterWithQuotes[0] = '\''; 1599 System.arraycopy(parameterAsBytes, 0, parameterWithQuotes, 1, 1600 parameterAsBytes.length); 1601 parameterWithQuotes[parameterAsBytes.length + 1] = '\''; 1602 1603 setInternal(parameterIndex, parameterWithQuotes); 1604 } 1605 1606 1611 protected void setRetrieveGeneratedKeys(boolean retrieveGeneratedKeys) { 1612 this.retrieveGeneratedKeys = retrieveGeneratedKeys; 1613 } 1614 1615 1629 protected synchronized int executeUpdate(byte[][] batchedParameterStrings, 1630 InputStream [] batchedParameterStreams, boolean[] batchedIsStream, 1631 int[] batchedStreamLengths, boolean[] batchedIsNull) 1632 throws SQLException { 1633 if (connection.isReadOnly()) { 1634 throw new SQLException ("Connection is read-only. " 1635 + "Queries leading to data modification are not allowed", 1636 SQLError.SQL_STATE_ILLEGAL_ARGUMENT); 1637 } 1638 1639 checkClosed(); 1640 1641 if ((this.firstCharOfStmt == 'S') 1642 && StringUtils.startsWithIgnoreCaseAndWs(this.originalSql, 1643 "SELECT")) { 1644 throw new java.sql.SQLException ("Can not issue executeUpdate() for SELECTs", 1645 SQLError.SQL_STATE_ILLEGAL_ARGUMENT); 1646 } 1647 1648 ResultSet rs = null; 1649 1650 synchronized (connection.getMutex()) { 1654 Buffer sendPacket = fillSendPacket(batchedParameterStrings, 1655 batchedParameterStreams, batchedIsStream, 1656 batchedStreamLengths); 1657 1658 String oldCatalog = null; 1659 1660 if (!this.connection.getCatalog().equals(currentCatalog)) { 1661 oldCatalog = this.connection.getCatalog(); 1662 this.connection.setCatalog(currentCatalog); 1663 } 1664 1665 if (this.connection.useMaxRows()) { 1669 this.connection.execSQL("SET OPTION SQL_SELECT_LIMIT=DEFAULT", 1670 -1, this.currentCatalog); 1671 } 1672 1673 boolean oldInfoMsgState = false; 1674 1675 if (this.retrieveGeneratedKeys) { 1676 oldInfoMsgState = this.connection.isReadInfoMsgEnabled(); 1677 this.connection.setReadInfoMsgEnabled(true); 1678 } 1679 1680 rs = this.connection.execSQL(null, -1, sendPacket, 1681 resultSetConcurrency, false, false, this.currentCatalog); 1682 1683 if (this.retrieveGeneratedKeys) { 1684 this.connection.setReadInfoMsgEnabled(oldInfoMsgState); 1685 } 1686 1687 if (oldCatalog != null) { 1688 this.connection.setCatalog(oldCatalog); 1689 } 1690 } 1691 1692 this.results = rs; 1693 1694 rs.setFirstCharOfQuery(this.firstCharOfStmt); 1695 1696 updateCount = rs.getUpdateCount(); 1697 1698 int truncatedUpdateCount = 0; 1699 1700 if (updateCount > Integer.MAX_VALUE) { 1701 truncatedUpdateCount = Integer.MAX_VALUE; 1702 } else { 1703 truncatedUpdateCount = (int) updateCount; 1704 } 1705 1706 lastInsertId = rs.getUpdateID(); 1707 this.results = rs; 1708 1709 return truncatedUpdateCount; 1710 } 1711 1712 byte[] getBytes(int parameterIndex) throws SQLException { 1713 if (isStream[parameterIndex]) { 1714 return streamToBytes(parameterStreams[parameterIndex], false, 1715 streamLengths[parameterIndex], 1716 this.connection.useStreamLengthsInPrepStmts()); 1717 } else { 1718 byte[] parameterVal = parameterValues[parameterIndex]; 1719 1720 if (parameterVal == null) { 1721 return null; 1722 } 1723 1724 if ((parameterVal[0] == '\'') 1725 && (parameterVal[parameterVal.length - 1] == '\'')) { 1726 byte[] valNoQuotes = new byte[parameterVal.length - 2]; 1727 System.arraycopy(parameterVal, 1, valNoQuotes, 0, 1728 parameterVal.length - 2); 1729 1730 return valNoQuotes; 1731 } else { 1732 return parameterVal; 1733 } 1734 } 1735 } 1736 1737 boolean isNull(int paramIndex) { 1738 return isNull[paramIndex]; 1739 } 1740 1741 ParseInfo getParseInfo() { 1742 return this.parseInfo; 1743 } 1744 1745 1751 void setResultSetConcurrency(int concurrencyFlag) { 1752 resultSetConcurrency = concurrencyFlag; 1753 } 1754 1755 1760 void setResultSetType(int typeFlag) { 1761 resultSetType = typeFlag; 1762 } 1763 1764 private final String getDateTimePattern(String dt, boolean toTime) 1765 throws Exception { 1766 int dtLength = (dt != null) ? dt.length() : 0; 1770 1771 if ((dtLength >= 8) && (dtLength <= 10)) { 1772 int dashCount = 0; 1773 boolean isDateOnly = true; 1774 1775 for (int i = 0; i < dtLength; i++) { 1776 char c = dt.charAt(i); 1777 1778 if (!Character.isDigit(c) && (c != '-')) { 1779 isDateOnly = false; 1780 1781 break; 1782 } 1783 1784 if (c == '-') { 1785 dashCount++; 1786 } 1787 } 1788 1789 if (isDateOnly && (dashCount == 2)) { 1790 return "yyyy-MM-dd"; 1791 } 1792 } 1793 1794 boolean colonsOnly = true; 1798 1799 for (int i = 0; i < dtLength; i++) { 1800 char c = dt.charAt(i); 1801 1802 if (!Character.isDigit(c) && (c != ':')) { 1803 colonsOnly = false; 1804 1805 break; 1806 } 1807 } 1808 1809 if (colonsOnly) { 1810 return "HH:mm:ss"; 1811 } 1812 1813 int n; 1814 int z; 1815 int count; 1816 int maxvecs; 1817 char c; 1818 char separator; 1819 StringReader reader = new StringReader (dt + " "); 1820 ArrayList vec = new ArrayList (); 1821 ArrayList vecRemovelist = new ArrayList (); 1822 Object [] nv = new Object [3]; 1823 Object [] v; 1824 nv[0] = new Character ('y'); 1825 nv[1] = new StringBuffer (); 1826 nv[2] = new Integer (0); 1827 vec.add(nv); 1828 1829 if (toTime) { 1830 nv = new Object [3]; 1831 nv[0] = new Character ('h'); 1832 nv[1] = new StringBuffer (); 1833 nv[2] = new Integer (0); 1834 vec.add(nv); 1835 } 1836 1837 while ((z = reader.read()) != -1) { 1838 separator = (char) z; 1839 maxvecs = vec.size(); 1840 1841 for (count = 0; count < maxvecs; count++) { 1842 v = (Object []) vec.get(count); 1843 n = ((Integer ) v[2]).intValue(); 1844 c = getSuccessor(((Character ) v[0]).charValue(), n); 1845 1846 if (!Character.isLetterOrDigit(separator)) { 1847 if ((c == ((Character ) v[0]).charValue()) && (c != 'S')) { 1848 vecRemovelist.add(v); 1849 } else { 1850 ((StringBuffer ) v[1]).append(separator); 1851 1852 if ((c == 'X') || (c == 'Y')) { 1853 v[2] = new Integer (4); 1854 } 1855 } 1856 } else { 1857 if (c == 'X') { 1858 c = 'y'; 1859 nv = new Object [3]; 1860 nv[1] = (new StringBuffer (((StringBuffer ) v[1]) 1861 .toString())).append('M'); 1862 nv[0] = new Character ('M'); 1863 nv[2] = new Integer (1); 1864 vec.add(nv); 1865 } else if (c == 'Y') { 1866 c = 'M'; 1867 nv = new Object [3]; 1868 nv[1] = (new StringBuffer (((StringBuffer ) v[1]) 1869 .toString())).append('d'); 1870 nv[0] = new Character ('d'); 1871 nv[2] = new Integer (1); 1872 vec.add(nv); 1873 } 1874 1875 ((StringBuffer ) v[1]).append(c); 1876 1877 if (c == ((Character ) v[0]).charValue()) { 1878 v[2] = new Integer (n + 1); 1879 } else { 1880 v[0] = new Character (c); 1881 v[2] = new Integer (1); 1882 } 1883 } 1884 } 1885 1886 int size = vecRemovelist.size(); 1887 1888 for (int i = 0; i < size; i++) { 1889 v = (Object []) vecRemovelist.get(i); 1890 vec.remove(v); 1891 } 1892 1893 vecRemovelist.clear(); 1894 } 1895 1896 int size = vec.size(); 1897 1898 for (int i = 0; i < size; i++) { 1899 v = (Object []) vec.get(i); 1900 c = ((Character ) v[0]).charValue(); 1901 n = ((Integer ) v[2]).intValue(); 1902 1903 boolean bk = getSuccessor(c, n) != c; 1904 boolean atEnd = (((c == 's') || (c == 'm') 1905 || ((c == 'h') && toTime)) && bk); 1906 boolean finishesAtDate = (bk && (c == 'd') && !toTime); 1907 boolean containsEnd = (((StringBuffer ) v[1]).toString().indexOf('W') != -1); 1908 1909 if ((!atEnd && !finishesAtDate) || (containsEnd)) { 1910 vecRemovelist.add(v); 1911 } 1912 } 1913 1914 size = vecRemovelist.size(); 1915 1916 for (int i = 0; i < size; i++) { 1917 vec.remove(vecRemovelist.get(i)); 1918 } 1919 1920 vecRemovelist.clear(); 1921 v = (Object []) vec.get(0); 1923 StringBuffer format = (StringBuffer ) v[1]; 1924 format.setLength(format.length() - 1); 1925 1926 return format.toString(); 1927 } 1928 1929 private final void setInternal(int paramIndex, byte[] val) 1930 throws SQLException { 1931 if (this.isClosed) { 1932 throw new SQLException ("PreparedStatement has been closed. No further operations allowed.", 1933 SQLError.SQL_STATE_ILLEGAL_ARGUMENT); 1934 } 1935 1936 if ((paramIndex < 1)) { 1937 throw new SQLException ("Parameter index out of range (" 1938 + paramIndex + " < 1 ).", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); 1939 } else if (paramIndex >= staticSqlStrings.length) { 1940 throw new SQLException ("Parameter index out of range (" 1941 + paramIndex + " > " + (staticSqlStrings.length - 1) + ").", 1942 SQLError.SQL_STATE_ILLEGAL_ARGUMENT); 1943 } 1944 1945 isStream[paramIndex - 1] = false; 1946 isNull[paramIndex - 1] = false; 1947 parameterStreams[paramIndex - 1] = null; 1948 parameterValues[paramIndex - 1] = val; 1949 } 1950 1951 private final void setInternal(int paramIndex, String val) 1952 throws SQLException { 1953 byte[] parameterAsBytes = null; 1954 1955 if (this.charConverter != null) { 1956 parameterAsBytes = this.charConverter.toBytes(val); 1957 } else { 1958 try { 1959 parameterAsBytes = StringUtils.getBytes(val, 1960 this.charConverter, this.charEncoding); 1961 } catch (UnsupportedEncodingException uEE) { 1962 throw new SQLException ("Unsupported encoding '" 1963 + this.charEncoding + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); 1964 } 1965 } 1966 1967 setInternal(paramIndex, parameterAsBytes); 1968 } 1969 1970 1980 private final void setSerializableObject(int parameterIndex, 1981 Object parameterObj) throws SQLException { 1982 try { 1983 ByteArrayOutputStream bytesOut = new ByteArrayOutputStream (); 1984 ObjectOutputStream objectOut = new ObjectOutputStream (bytesOut); 1985 objectOut.writeObject(parameterObj); 1986 objectOut.flush(); 1987 objectOut.close(); 1988 bytesOut.flush(); 1989 bytesOut.close(); 1990 1991 byte[] buf = bytesOut.toByteArray(); 1992 ByteArrayInputStream bytesIn = new ByteArrayInputStream (buf); 1993 setBinaryStream(parameterIndex, bytesIn, buf.length); 1994 } catch (Exception ex) { 1995 throw new java.sql.SQLException ("Invalid argument value: " 1996 + ex.getClass().getName(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT); 1997 } 1998 } 1999 2000 private final char getSuccessor(char c, int n) { 2001 return ((c == 'y') && (n == 2)) ? 'X' 2002 : (((c == 'y') && (n < 4)) ? 'y' 2003 : ((c == 'y') 2004 ? 'M' 2005 : (((c == 'M') && (n == 2)) ? 'Y' 2006 : (((c == 'M') && (n < 3)) ? 'M' 2007 : ((c == 'M') 2008 ? 'd' 2009 : (((c == 'd') && (n < 2)) ? 'd' 2010 : ((c == 'd') ? 'H' 2011 : (((c == 'H') && (n < 2)) 2012 ? 'H' 2013 : ((c == 'H') ? 'm' 2014 : (((c == 'm') && (n < 2)) ? 'm' 2015 : ((c == 'm') ? 's' 2016 : (((c == 's') 2017 && (n < 2)) ? 's' : 'W')))))))))))); 2018 } 2019 2020 2031 private void setTimeInternal(int parameterIndex, Time x, TimeZone tz) 2032 throws SQLException { 2033 if (x == null) { 2034 setNull(parameterIndex, java.sql.Types.TIME); 2035 } else { 2036 x = TimeUtil.changeTimezone(this.connection, x, tz, 2037 this.connection.getServerTimezone()); 2038 setInternal(parameterIndex, "'" + x.toString() + "'"); 2039 } 2040 } 2041 2042 2052 private synchronized void setTimestampInternal(int parameterIndex, 2053 Timestamp x, TimeZone tz) throws SQLException { 2054 if (x == null) { 2055 setNull(parameterIndex, java.sql.Types.TIMESTAMP); 2056 } else { 2057 String timestampString = null; 2058 x = TimeUtil.changeTimezone(this.connection, x, tz, 2059 this.connection.getServerTimezone()); 2060 2061 if (this.tsdf == null) { 2062 this.tsdf = new SimpleDateFormat ("''yyyy-MM-dd HH:mm:ss''"); 2063 } 2064 2065 timestampString = this.tsdf.format(x); 2066 2067 setInternal(parameterIndex, timestampString); } 2069 } 2070 2071 private final void escapeblockFast(byte[] buf, 2072 ByteArrayOutputStream bytesOut, int size) { 2073 int lastwritten = 0; 2074 2075 for (int i = 0; i < size; i++) { 2076 byte b = buf[i]; 2077 2078 if (b == '\0') { 2079 if (i > lastwritten) { 2081 bytesOut.write(buf, lastwritten, i - lastwritten); 2082 } 2083 2084 bytesOut.write('\\'); 2086 bytesOut.write('0'); 2087 lastwritten = i + 1; 2088 } else { 2089 if ((b == '\\') || (b == '\'') || (b == '"')) { 2090 if (i > lastwritten) { 2092 bytesOut.write(buf, lastwritten, i - lastwritten); 2093 } 2094 2095 bytesOut.write('\\'); 2097 lastwritten = i; } 2099 } 2100 } 2101 2102 if (lastwritten < size) { 2104 bytesOut.write(buf, lastwritten, size - lastwritten); 2105 } 2106 } 2107 2108 private final void escapeblockFast(byte[] buf, Buffer packet, int size) 2109 throws SQLException { 2110 int lastwritten = 0; 2111 2112 for (int i = 0; i < size; i++) { 2113 byte b = buf[i]; 2114 2115 if (b == '\0') { 2116 if (i > lastwritten) { 2118 packet.writeBytesNoNull(buf, lastwritten, i - lastwritten); 2119 } 2120 2121 packet.writeByte((byte) '\\'); 2123 packet.writeByte((byte) '0'); 2124 lastwritten = i + 1; 2125 } else { 2126 if ((b == '\\') || (b == '\'') || (b == '"')) { 2127 if (i > lastwritten) { 2129 packet.writeBytesNoNull(buf, lastwritten, 2130 i - lastwritten); 2131 } 2132 2133 packet.writeByte((byte) '\\'); 2135 lastwritten = i; } 2137 } 2138 } 2139 2140 if (lastwritten < size) { 2142 packet.writeBytesNoNull(buf, lastwritten, size - lastwritten); 2143 } 2144 } 2145 2146 2153 private Buffer fillSendPacket() throws SQLException { 2154 return fillSendPacket(this.parameterValues, this.parameterStreams, 2155 this.isStream, this.streamLengths); 2156 } 2157 2158 2171 private Buffer fillSendPacket(byte[][] batchedParameterStrings, 2172 InputStream [] batchedParameterStreams, boolean[] batchedIsStream, 2173 int[] batchedStreamLengths) throws SQLException { 2174 Buffer sendPacket = this.connection.getIO().getSharedSendPacket(); 2175 2176 sendPacket.clear(); 2177 2178 sendPacket.writeByte((byte) MysqlDefs.QUERY); 2179 2180 boolean useStreamLengths = this.connection.useStreamLengthsInPrepStmts(); 2181 2182 int ensurePacketSize = 0; 2187 2188 for (int i = 0; i < batchedParameterStrings.length; i++) { 2189 if (batchedIsStream[i] && useStreamLengths) { 2190 ensurePacketSize += batchedStreamLengths[i]; 2191 } 2192 } 2193 2194 if (ensurePacketSize != 0) { 2195 sendPacket.ensureCapacity(ensurePacketSize); 2196 } 2197 2198 for (int i = 0; i < batchedParameterStrings.length; i++) { 2199 if ((batchedParameterStrings[i] == null) 2200 && (batchedParameterStreams[i] == null)) { 2201 throw new java.sql.SQLException ( 2202 "No value specified for parameter " + (i + 1), SQLError.SQL_STATE_WRONG_NO_OF_PARAMETERS); 2203 } 2204 2205 sendPacket.writeBytesNoNull(staticSqlStrings[i]); 2206 2207 if (batchedIsStream[i]) { 2208 streamToBytes(sendPacket, batchedParameterStreams[i], true, 2209 batchedStreamLengths[i], useStreamLengths); 2210 } else { 2211 sendPacket.writeBytesNoNull(batchedParameterStrings[i]); 2212 } 2213 } 2214 2215 sendPacket.writeBytesNoNull(staticSqlStrings[batchedParameterStrings.length]); 2216 2217 return sendPacket; 2218 } 2219 2220 private static final String fixDecimalExponent(String dString) { 2225 int ePos = dString.indexOf("E"); 2226 2227 if (ePos == -1) { 2228 ePos = dString.indexOf("e"); 2229 } 2230 2231 if (ePos != -1) { 2232 if (dString.length() > (ePos + 1)) { 2233 char maybeMinusChar = dString.charAt(ePos + 1); 2234 2235 if (maybeMinusChar != '-') { 2236 StringBuffer buf = new StringBuffer (dString.length() + 1); 2237 buf.append(dString.substring(0, ePos + 1)); 2238 buf.append('+'); 2239 buf.append(dString.substring(ePos + 1, dString.length())); 2240 dString = buf.toString(); 2241 } 2242 } 2243 } 2244 2245 return dString; 2246 } 2247 2248 private void initializeFromParseInfo() throws SQLException { 2249 this.staticSqlStrings = this.parseInfo.staticSql; 2250 this.hasLimitClause = this.parseInfo.foundLimitClause; 2251 this.isLoadDataQuery = this.parseInfo.foundLoadData; 2252 this.firstCharOfStmt = this.parseInfo.firstStmtChar; 2253 2254 int numberOfParameters = staticSqlStrings.length - 1; 2255 2256 parameterValues = new byte[numberOfParameters][]; 2257 parameterStreams = new InputStream [numberOfParameters]; 2258 isStream = new boolean[numberOfParameters]; 2259 streamLengths = new int[numberOfParameters]; 2260 isNull = new boolean[numberOfParameters]; 2261 2262 clearParameters(); 2263 2264 for (int j = 0; j < numberOfParameters; j++) { 2265 isStream[j] = false; 2266 } 2267 } 2268 2269 private final int readblock(InputStream i, byte[] b, int length) 2270 throws SQLException { 2271 try { 2272 int lengthToRead = length; 2273 2274 if (lengthToRead > b.length) { 2275 lengthToRead = b.length; 2276 } 2277 2278 return i.read(b, 0, lengthToRead); 2279 } catch (Throwable E) { 2280 throw new java.sql.SQLException ("Error reading from InputStream " 2281 + E.getClass().getName(), SQLError.SQL_STATE_GENERAL_ERROR); 2282 } 2283 } 2284 2285 private final int readblock(InputStream i, byte[] b) 2286 throws SQLException { 2287 try { 2288 return i.read(b); 2289 } catch (Throwable E) { 2290 throw new java.sql.SQLException ("Error reading from InputStream " 2291 + E.getClass().getName(), SQLError.SQL_STATE_GENERAL_ERROR); 2292 } 2293 } 2294 2295 2307 private final byte[] streamToBytes(InputStream in, int streamLength, 2308 boolean useLength) throws SQLException { 2309 return streamToBytes(in, true, streamLength, useLength); 2310 } 2311 2312 private final byte[] streamToBytes(InputStream in, boolean escape, 2313 int streamLength, boolean useLength) throws SQLException { 2314 try { 2315 if (streamLength == -1) { 2316 useLength = false; 2317 } 2318 2319 ByteArrayOutputStream bytesOut = new ByteArrayOutputStream (); 2320 2321 int bc = -1; 2322 2323 if (useLength) { 2324 bc = readblock(in, streamConvertBuf, streamLength); 2325 } else { 2326 bc = readblock(in, streamConvertBuf); 2327 } 2328 2329 int lengthLeftToRead = streamLength - bc; 2330 2331 if (escape) { 2332 bytesOut.write('\''); 2333 } 2334 2335 while (bc > 0) { 2336 if (escape) { 2337 escapeblockFast(streamConvertBuf, bytesOut, bc); 2338 } else { 2339 bytesOut.write(streamConvertBuf, 0, bc); 2340 } 2341 2342 if (useLength) { 2343 bc = readblock(in, streamConvertBuf, lengthLeftToRead); 2344 2345 if (bc > 0) { 2346 lengthLeftToRead -= bc; 2347 } 2348 } else { 2349 bc = readblock(in, streamConvertBuf); 2350 } 2351 } 2352 2353 if (escape) { 2354 bytesOut.write('\''); 2355 } 2356 2357 return bytesOut.toByteArray(); 2358 } finally { 2359 try { 2360 in.close(); 2361 } catch (IOException ioEx) { 2362 ; 2363 } 2364 2365 in = null; 2366 } 2367 } 2368 2369 private final void streamToBytes(Buffer packet, InputStream in, 2370 boolean escape, int streamLength, boolean useLength) 2371 throws SQLException { 2372 try { 2373 if (streamLength == -1) { 2374 useLength = false; 2375 } 2376 2377 int bc = -1; 2378 2379 if (useLength) { 2380 bc = readblock(in, streamConvertBuf, streamLength); 2381 } else { 2382 bc = readblock(in, streamConvertBuf); 2383 } 2384 2385 int lengthLeftToRead = streamLength - bc; 2386 2387 if (escape) { 2388 packet.writeByte((byte) '\''); 2389 } 2390 2391 while (bc > 0) { 2392 if (escape) { 2393 escapeblockFast(streamConvertBuf, packet, bc); 2394 } else { 2395 packet.writeBytesNoNull(streamConvertBuf, 0, bc); 2396 } 2397 2398 if (useLength) { 2399 bc = readblock(in, streamConvertBuf, lengthLeftToRead); 2400 2401 if (bc > 0) { 2402 lengthLeftToRead -= bc; 2403 } 2404 } else { 2405 bc = readblock(in, streamConvertBuf); 2406 } 2407 } 2408 2409 if (escape) { 2410 packet.writeByte((byte) '\''); 2411 } 2412 } finally { 2413 try { 2414 in.close(); 2415 } catch (IOException ioEx) { 2416 ; 2417 } 2418 2419 in = null; 2420 } 2421 } 2422 2423 2435 private static int readFully(Reader reader, char[] buf, int length) 2436 throws IOException { 2437 int numCharsRead = 0; 2438 2439 while (numCharsRead < length) { 2440 int count = reader.read(buf, numCharsRead, length - numCharsRead); 2441 2442 if (count < 0) { 2443 break; 2444 } 2445 2446 numCharsRead += count; 2447 } 2448 2449 return numCharsRead; 2450 } 2451 2452 class BatchParams { 2453 boolean[] isNull = null; 2454 boolean[] isStream = null; 2455 InputStream [] parameterStreams = null; 2456 byte[][] parameterStrings = null; 2457 int[] streamLengths = null; 2458 2459 BatchParams(byte[][] strings, InputStream [] streams, 2460 boolean[] isStreamFlags, int[] lengths, boolean[] isNullFlags) { 2461 parameterStrings = new byte[strings.length][]; 2465 parameterStreams = new InputStream [streams.length]; 2466 isStream = new boolean[isStreamFlags.length]; 2467 streamLengths = new int[lengths.length]; 2468 isNull = new boolean[isNullFlags.length]; 2469 System.arraycopy(strings, 0, parameterStrings, 0, strings.length); 2470 System.arraycopy(streams, 0, parameterStreams, 0, streams.length); 2471 System.arraycopy(isStreamFlags, 0, isStream, 0, isStreamFlags.length); 2472 System.arraycopy(lengths, 0, streamLengths, 0, lengths.length); 2473 System.arraycopy(isNullFlags, 0, isNull, 0, isNullFlags.length); 2474 } 2475 } 2476 2477 class ParseInfo { 2478 byte[][] staticSql = null; 2479 boolean foundLimitClause = false; 2480 boolean foundLoadData = false; 2481 char firstStmtChar = 0; 2482 int statementLength = 0; 2483 long lastUsed = 0; 2484 2485 2488 public ParseInfo(String sql, Connection conn, 2489 java.sql.DatabaseMetaData dbmd, String encoding, 2490 SingleByteCharsetConverter converter) throws SQLException { 2491 if (sql == null) { 2492 throw new SQLException ("SQL String can not be NULL", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); 2493 } 2494 2495 lastUsed = System.currentTimeMillis(); 2496 2497 String quotedIdentifierString = dbmd.getIdentifierQuoteString(); 2498 2499 char quotedIdentifierChar = 0; 2500 2501 if ((quotedIdentifierString != null) 2502 && !quotedIdentifierString.equals(" ") 2503 && (quotedIdentifierString.length() > 0)) { 2504 quotedIdentifierChar = quotedIdentifierString.charAt(0); 2505 } 2506 2507 statementLength = sql.length(); 2508 2509 ArrayList endpointList = new ArrayList (); 2510 boolean inQuotes = false; 2511 boolean inQuotedId = false; 2512 int lastParmEnd = 0; 2513 int i; 2514 2515 int pre1 = 0; 2516 int pre2 = 0; 2517 2518 int lastAlphaCharPos = 0; 2519 int stopLookingForLimitClause = statementLength - 5; 2520 2521 foundLimitClause = false; 2522 2523 for (i = 0; i < statementLength; ++i) { 2524 char c = sql.charAt(i); 2525 2526 if ((firstStmtChar == 0) && !Character.isWhitespace(c)) { 2527 firstStmtChar = Character.toUpperCase(c); 2529 } 2530 2531 if (Character.isLetter(c)) { 2532 lastAlphaCharPos = i; 2533 } 2534 2535 if (!inQuotes && (quotedIdentifierChar != 0) 2538 && (c == quotedIdentifierChar)) { 2539 inQuotedId = !inQuotedId; 2540 } 2541 2542 if (!inQuotedId) { 2544 if ((c == '\'') && (pre1 == '\\') && (pre2 == '\\')) { 2545 inQuotes = !inQuotes; 2546 } else if ((c == '\'') && (pre1 != '\\')) { 2547 inQuotes = !inQuotes; 2548 } 2549 } 2550 2551 if ((c == '?') && !inQuotes) { 2552 endpointList.add(new int[] { lastParmEnd, i }); 2553 lastParmEnd = i + 1; 2554 } 2555 2556 if (!inQuotes && (i < stopLookingForLimitClause)) { 2557 if ((c == 'L') || (c == 'l')) { 2558 char posI1 = sql.charAt(i + 1); 2559 2560 if ((posI1 == 'I') || (posI1 == 'i')) { 2561 char posM = sql.charAt(i + 2); 2562 2563 if ((posM == 'M') || (posM == 'm')) { 2564 char posI2 = sql.charAt(i + 3); 2565 2566 if ((posI2 == 'I') || (posI2 == 'i')) { 2567 char posT = sql.charAt(i + 4); 2568 2569 if ((posT == 'T') || (posT == 't')) { 2570 foundLimitClause = true; 2571 } 2572 } 2573 } 2574 } 2575 } 2576 } 2577 2578 pre2 = pre1; 2579 pre1 = c; 2580 } 2581 2582 if (firstStmtChar == 'L') { 2583 if (StringUtils.startsWithIgnoreCaseAndWs(sql, "LOAD DATA")) { 2584 foundLoadData = true; 2585 } else { 2586 foundLoadData = false; 2587 } 2588 } else { 2589 foundLoadData = false; 2590 } 2591 2592 endpointList.add(new int[] { lastParmEnd, statementLength }); 2593 staticSql = new byte[endpointList.size()][]; 2594 2595 for (i = 0; i < staticSql.length; i++) { 2596 int[] ep = (int[]) endpointList.get(i); 2597 int end = ep[1]; 2598 int begin = ep[0]; 2599 int len = end - begin; 2600 2601 if (foundLoadData) { 2602 String temp = new String (sql.toCharArray(), begin, len); 2603 staticSql[i] = temp.getBytes(); 2604 } else if (encoding == null) { 2605 byte[] buf = new byte[len]; 2606 2607 for (int j = 0; j < len; j++) { 2608 buf[j] = (byte) sql.charAt(begin + j); 2609 } 2610 2611 staticSql[i] = buf; 2612 } else { 2613 try { 2614 if (converter != null) { 2615 staticSql[i] = StringUtils.getBytes(sql, converter, 2616 encoding, begin, len); 2617 } else { 2618 String temp = new String (sql.toCharArray(), begin, 2619 len); 2620 staticSql[i] = StringUtils.getBytes(temp, null, 2621 encoding); 2622 } 2623 } catch (java.io.UnsupportedEncodingException ue) { 2624 throw new SQLException (ue.toString()); 2625 } 2626 } 2627 } 2628 2629 int numberOfParameters = staticSql.length - 1; 2630 } 2631 } 2632} 2633
| Popular Tags
|