| 1 19 package com.mysql.jdbc; 20 21 import java.io.IOException ; 22 import java.io.InputStream ; 23 import java.io.Reader ; 24 import java.io.UnsupportedEncodingException ; 25 26 import java.math.BigDecimal ; 27 28 import java.net.URL ; 29 30 import java.sql.Clob ; 31 import java.sql.Date ; 32 import java.sql.ParameterMetaData ; 33 import java.sql.Ref ; 34 import java.sql.SQLException ; 35 import java.sql.Savepoint ; 36 import java.sql.Time ; 37 import java.sql.Timestamp ; 38 39 import java.util.ArrayList ; 40 import java.util.Calendar ; 41 import java.util.HashMap ; 42 import java.util.Iterator ; 43 import java.util.List ; 44 import java.util.Map ; 45 import java.util.Properties ; 46 import java.util.TimeZone ; 47 48 49 66 public class Connection implements java.sql.Connection { 67 private static final String PING_COMMAND = "SELECT 1"; 71 72 76 private static Map mapTransIsolationName2Value = null; 77 78 82 private static Map charsetMap; 83 84 85 private static Map multibyteCharsetsMap; 86 87 88 private static final String DEFAULT_SOCKET_FACTORY = StandardSocketFactory.class 89 .getName(); 90 91 static { 92 loadCharacterSetMapping(); 93 mapTransIsolationName2Value = new HashMap (8); 94 mapTransIsolationName2Value.put("READ-UNCOMMITED", 95 new Integer (TRANSACTION_READ_UNCOMMITTED)); 96 mapTransIsolationName2Value.put("READ-UNCOMMITTED", 97 new Integer (TRANSACTION_READ_UNCOMMITTED)); 98 mapTransIsolationName2Value.put("READ-COMMITTED", 99 new Integer (TRANSACTION_READ_COMMITTED)); 100 mapTransIsolationName2Value.put("REPEATABLE-READ", 101 new Integer (TRANSACTION_REPEATABLE_READ)); 102 mapTransIsolationName2Value.put("SERIALIZABLE", 103 new Integer (TRANSACTION_SERIALIZABLE)); 104 } 105 106 110 private final static Object CHARSET_CONVERTER_NOT_AVAILABLE_MARKER = new Object (); 111 112 113 private DatabaseMetaData dbmd = null; 114 115 116 private List hostList = null; 117 118 119 private Map cachedPreparedStatementParams; 120 121 126 private Map charsetConverterMap = new HashMap (CharsetMapping.JAVA_TO_MYSQL_CHARSET_MAP 127 .size()); 128 129 130 private Map statementsUsingMaxRows; 131 132 136 private Map typeMap; 137 138 139 private MysqlIO io = null; 140 141 142 private final Object mutex = new Object (); 143 144 145 private Map serverVariables = null; 146 147 148 private NonRegisteringDriver myDriver; 149 150 151 private Properties props = null; 152 153 154 private String database = null; 155 156 157 private String encoding = null; 158 159 160 private String host = null; 161 162 163 private String myURL = null; 164 165 166 private String mysqlEncodingName = null; 167 private String negativeInfinityRep = MysqlDefs.MIN_DOUBLE_VAL_STRING; 168 private String notANumberRep = MysqlDefs.NAN_VAL_STRING; 169 170 171 private String password = null; 172 private String positiveInfinityRep = MysqlDefs.MAX_DOUBLE_VAL_STRING; 173 174 175 private String socketFactoryClassName = null; 176 177 178 private String user = null; 179 180 181 private Throwable explicitCloseLocation; 182 183 184 private Throwable forcedCloseReason; 185 private TimeZone defaultTimeZone; 186 187 188 private TimeZone serverTimezone = null; 189 190 191 private boolean allowLoadLocalInfile = true; 192 193 194 private boolean alwaysClearStream = false; 195 196 197 private boolean autoCommit = true; 198 199 200 private boolean cachePreparedStatements = false; 201 202 203 private boolean capitalizeDBMDTypes = false; 204 205 206 private boolean clobberStreamingResults = false; 207 208 212 private boolean continueBatchOnError = true; 213 214 215 private boolean doUnicode = false; 216 217 218 private boolean failedOver = false; 219 220 221 private boolean hasIsolationLevels = false; 222 223 224 private boolean hasQuotedIdentifiers = false; 225 226 private boolean highAvailability = false; 230 231 232 private boolean ignoreNonTxTables = false; 233 234 235 private boolean isClosed = true; 236 237 238 private boolean isInteractiveClient = false; 239 240 241 private boolean lowerCaseTableNames = false; 242 243 244 private boolean maxRowsChanged = false; 245 private boolean negativeInfinityRepIsClipped = true; 246 private boolean notANumberRepIsClipped = true; 247 248 249 private boolean paranoid = false; 250 251 252 private boolean pedantic = false; 253 private boolean positiveInfinityRepIsClipped = true; 254 255 256 private boolean readInfoMsg = false; 257 258 259 private boolean readOnly = false; 260 261 265 private boolean reconnectAtTxEnd = false; 266 267 268 private boolean relaxAutoCommit = false; 269 270 271 private boolean strictFloatingPoint = false; 272 273 274 private boolean strictUpdates = true; 275 276 277 private boolean transactionsSupported = false; 278 279 280 private boolean useAnsiQuotes = false; 281 282 283 private boolean useCompression = false; 284 285 286 private boolean useFastPing = false; 287 288 289 private boolean useHostsInPrivileges = true; 290 291 292 private boolean useSSL = false; 293 294 298 private boolean useStreamLengthsInPrepStmts = true; 299 300 301 private boolean useTimezone = false; 302 303 304 private boolean useUltraDevWorkAround = false; 305 private boolean useUnbufferedInput = true; 306 private double initialTimeout = 2.0D; 307 308 309 private int hostListSize = 0; 310 311 312 private int isolationLevel = java.sql.Connection.TRANSACTION_READ_COMMITTED; 313 314 318 private int maxAllowedPacket = 65536; 319 private int maxReconnects = 3; 320 321 325 private int maxRows = -1; 326 private int netBufferLength = 16384; 327 328 329 private int port = 3306; 330 331 335 private int preparedStatementCacheMaxSqlSize = 256; 336 337 338 private int preparedStatementCacheSize = 25; 339 340 344 private int queriesBeforeRetryMaster = 50; 345 346 347 private int socketTimeout = 0; 349 350 private long lastQueryFinishedTime = 0; 351 352 353 private long masterFailTimeMillis = 0L; 354 355 356 private long queriesIssuedFailedOver = 0; 357 358 363 private long secondsBeforeRetryMaster = 30L; 364 365 378 Connection(String host, int port, Properties info, String database, 379 String url, NonRegisteringDriver d) throws java.sql.SQLException { 380 if (Driver.TRACE) { 381 Object [] args = { host, new Integer (port), info, database, url, d }; 382 Debug.methodCall(this, "constructor", args); 383 } 384 385 this.defaultTimeZone = TimeZone.getDefault(); 386 387 this.serverVariables = new HashMap (); 388 389 if (host == null) { 390 this.host = "localhost"; 391 hostList = new ArrayList (); 392 hostList.add(this.host); 393 } else if (host.indexOf(",") != -1) { 394 hostList = StringUtils.split(host, ",", true); 396 } else { 397 this.host = host; 398 hostList = new ArrayList (); 399 hostList.add(this.host); 400 } 401 402 hostListSize = hostList.size(); 403 this.port = port; 404 405 if (database == null) { 406 throw new SQLException ("Malformed URL '" + url + "'.", 407 SQLError.SQL_STATE_GENERAL_ERROR); 408 } 409 410 this.database = database; 411 this.myURL = url; 412 this.myDriver = d; 413 this.user = info.getProperty("user"); 414 this.password = info.getProperty("password"); 415 416 if ((this.user == null) || this.user.equals("")) { 417 this.user = "nobody"; 418 } 419 420 if (this.password == null) { 421 this.password = ""; 422 } 423 424 this.props = info; 425 initializeDriverProperties(info); 426 427 if (Driver.DEBUG) { 428 System.out.println("Connect: " + this.user + " to " + this.database); 429 } 430 431 try { 432 createNewIO(false); 433 this.dbmd = new DatabaseMetaData(this, this.database); 434 } catch (java.sql.SQLException ex) { 435 cleanup(ex); 436 437 throw ex; 439 } catch (Exception ex) { 440 cleanup(ex); 441 442 StringBuffer mesg = new StringBuffer (); 443 444 if (!useParanoidErrorMessages()) { 445 mesg.append("Cannot connect to MySQL server on "); 446 mesg.append(this.host); 447 mesg.append(":"); 448 mesg.append(this.port); 449 mesg.append(".\n\n"); 450 mesg.append("Make sure that there is a MySQL server "); 451 mesg.append("running on the machine/port you are trying "); 452 mesg.append( 453 "to connect to and that the machine this software is " 454 + "running on "); 455 mesg.append("is able to connect to this host/port " 456 + "(i.e. not firewalled). "); 457 mesg.append( 458 "Also make sure that the server has not been started " 459 + "with the --skip-networking "); 460 mesg.append("flag.\n\n"); 461 } else { 462 mesg.append("Unable to connect to database."); 463 } 464 465 mesg.append("Underlying exception: \n\n"); 466 mesg.append(ex.getClass().getName()); 467 throw new java.sql.SQLException (mesg.toString(), 468 SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE); 469 } 470 } 471 472 495 public void setAutoCommit(boolean autoCommit) throws java.sql.SQLException { 496 if (Driver.TRACE) { 497 Object [] args = { new Boolean (autoCommit) }; 498 Debug.methodCall(this, "setAutoCommit", args); 499 } 500 501 checkClosed(); 502 503 if (this.transactionsSupported) { 504 this.autoCommit = autoCommit; 512 513 if ((this.highAvailability || this.failedOver) && !this.autoCommit) { 518 pingAndReconnect(true); 519 } 520 521 String sql = "SET autocommit=" + (autoCommit ? "1" : "0"); 522 execSQL(sql, -1, this.database); 523 } else { 524 if ((autoCommit == false) && (this.relaxAutoCommit == false)) { 525 throw new SQLException ("MySQL Versions Older than 3.23.15 " 526 + "do not support transactions", 527 SQLError.SQL_STATE_DRIVER_NOT_CAPABLE); 528 } else { 529 this.autoCommit = autoCommit; 530 } 531 } 532 533 return; 534 } 535 536 545 public boolean getAutoCommit() throws java.sql.SQLException { 546 if (Driver.TRACE) { 547 Object [] args = new Object [0]; 548 Debug.methodCall(this, "getAutoCommit", args); 549 Debug.returnValue(this, "getAutoCommit", 550 new Boolean (this.autoCommit)); 551 } 552 553 return this.autoCommit; 554 } 555 556 569 public void setCatalog(String catalog) throws java.sql.SQLException { 570 if (Driver.TRACE) { 571 Object [] args = { catalog }; 572 Debug.methodCall(this, "setCatalog", args); 573 } 574 575 checkClosed(); 576 577 String quotedId = this.dbmd.getIdentifierQuoteString(); 578 579 if ((quotedId == null) || quotedId.equals(" ")) { 580 quotedId = ""; 581 } 582 583 StringBuffer query = new StringBuffer ("USE "); 584 query.append(quotedId); 585 query.append(catalog); 586 query.append(quotedId); 587 588 execSQL(query.toString(), -1, catalog); 589 this.database = catalog; 590 } 591 592 604 public String getCatalog() throws java.sql.SQLException { 605 if (Driver.TRACE) { 606 Object [] args = new Object [0]; 607 Debug.methodCall(this, "getCatalog", args); 608 Debug.returnValue(this, "getCatalog", this.database); 609 } 610 611 return this.database; 612 } 613 614 621 public boolean getClobberStreamingResults() { 622 return this.clobberStreamingResults; 623 } 624 625 630 public boolean isClosed() { 631 if (Driver.TRACE) { 632 Object [] args = new Object [0]; 633 Debug.methodCall(this, "isClosed", args); 634 Debug.returnValue(this, "isClosed", new Boolean (this.isClosed)); 635 } 636 637 return this.isClosed; 638 } 639 640 645 public String getEncoding() { 646 return this.encoding; 647 } 648 649 652 public void setHoldability(int arg0) throws SQLException { 653 } 655 656 659 public int getHoldability() throws SQLException { 660 return ResultSet.CLOSE_CURSORS_AT_COMMIT; 661 } 662 663 671 public long getIdleFor() { 672 if (this.lastQueryFinishedTime == 0) { 673 return 0; 674 } else { 675 long now = System.currentTimeMillis(); 676 long idleTime = now - this.lastQueryFinishedTime; 677 678 return idleTime; 679 } 680 } 681 682 687 public boolean isInteractiveClient() { 688 return isInteractiveClient; 689 } 690 691 701 public java.sql.DatabaseMetaData getMetaData() throws java.sql.SQLException { 702 checkClosed(); 703 704 return new DatabaseMetaData(this, this.database); 705 } 706 707 712 public String getNegativeInfinityRep() { 713 return negativeInfinityRep; 714 } 715 716 721 public boolean isNegativeInfinityRepIsClipped() { 722 return negativeInfinityRepIsClipped; 723 } 724 725 730 public String getNotANumberRep() { 731 return notANumberRep; 732 } 733 734 739 public boolean isNotANumberRepIsClipped() { 740 return notANumberRepIsClipped; 741 } 742 743 748 public String getPositiveInfinityRep() { 749 return positiveInfinityRep; 750 } 751 752 757 public boolean isPositiveInfinityRepIsClipped() { 758 return positiveInfinityRepIsClipped; 759 } 760 761 768 public void setProfileSql(boolean flag) throws SQLException { 769 this.props.setProperty("profileSql", String.valueOf(flag)); 771 getIO().setProfileSql(flag); 772 } 773 774 783 public void setReadOnly(boolean readOnly) throws java.sql.SQLException { 784 if (Driver.TRACE) { 785 Object [] args = { new Boolean (readOnly) }; 786 Debug.methodCall(this, "setReadOnly", args); 787 Debug.returnValue(this, "setReadOnly", new Boolean (readOnly)); 788 } 789 790 checkClosed(); 791 this.readOnly = readOnly; 792 } 793 794 803 public boolean isReadOnly() throws java.sql.SQLException { 804 if (Driver.TRACE) { 805 Object [] args = new Object [0]; 806 Debug.methodCall(this, "isReadOnly", args); 807 Debug.returnValue(this, "isReadOnly", new Boolean (this.readOnly)); 808 } 809 810 return this.readOnly; 811 } 812 813 816 public java.sql.Savepoint setSavepoint() throws SQLException { 817 throw new NotImplemented(); 818 } 819 820 823 public java.sql.Savepoint setSavepoint(String arg0) 824 throws SQLException { 825 throw new NotImplemented(); 826 } 827 828 833 public TimeZone getServerTimezone() { 834 return this.serverTimezone; 835 } 836 837 845 public void setTransactionIsolation(int level) throws java.sql.SQLException { 846 if (Driver.TRACE) { 847 Object [] args = { new Integer (level) }; 848 Debug.methodCall(this, "setTransactionIsolation", args); 849 } 850 851 checkClosed(); 852 853 if (this.hasIsolationLevels) { 854 StringBuffer sql = new StringBuffer ( 855 "SET SESSION TRANSACTION ISOLATION LEVEL "); 856 857 switch (level) { 858 case java.sql.Connection.TRANSACTION_NONE: 859 throw new SQLException ("Transaction isolation level " 860 + "NONE not supported by MySQL"); 861 862 case java.sql.Connection.TRANSACTION_READ_COMMITTED: 863 sql.append("READ COMMITTED"); 864 865 break; 866 867 case java.sql.Connection.TRANSACTION_READ_UNCOMMITTED: 868 sql.append("READ UNCOMMITTED"); 869 870 break; 871 872 case java.sql.Connection.TRANSACTION_REPEATABLE_READ: 873 &n
|