1 19 package com.mysql.jdbc; 20 21 import java.sql.DriverPropertyInfo ; 22 import java.sql.SQLException ; 23 24 import java.util.Properties ; 25 import java.util.StringTokenizer ; 26 27 28 56 public class NonRegisteringDriver implements java.sql.Driver { 57 58 public static final boolean DEBUG = false; 59 60 61 public static final boolean TRACE = false; 62 63 68 public NonRegisteringDriver() throws java.sql.SQLException { 69 } 71 72 77 public int getMajorVersion() { 78 return getMajorVersionInternal(); 79 } 80 81 86 public int getMinorVersion() { 87 return getMinorVersionInternal(); 88 } 89 90 113 public DriverPropertyInfo [] getPropertyInfo(String url, Properties info) 114 throws java.sql.SQLException { 115 if (info == null) { 116 info = new Properties (); 117 } 118 119 if ((url != null) && url.startsWith("jdbc:mysql://")) { 120 info = parseURL(url, info); 121 } 122 123 DriverPropertyInfo hostProp = new DriverPropertyInfo ("HOST", 124 info.getProperty("HOST")); 125 hostProp.required = true; 126 hostProp.description = "Hostname of MySQL Server"; 127 128 DriverPropertyInfo portProp = new DriverPropertyInfo ("PORT", 129 info.getProperty("PORT", "3306")); 130 portProp.required = false; 131 portProp.description = "Port number of MySQL Server"; 132 133 DriverPropertyInfo dbProp = new DriverPropertyInfo ("DBNAME", 134 info.getProperty("DBNAME")); 135 dbProp.required = false; 136 dbProp.description = "Database name"; 137 138 DriverPropertyInfo userProp = new DriverPropertyInfo ("user", 139 info.getProperty("user")); 140 userProp.required = true; 141 userProp.description = "Username to authenticate as"; 142 143 DriverPropertyInfo passwordProp = new DriverPropertyInfo ("password", 144 info.getProperty("password")); 145 passwordProp.required = true; 146 passwordProp.description = "Password to use for authentication"; 147 148 DriverPropertyInfo autoReconnect = new DriverPropertyInfo ("autoReconnect", 149 info.getProperty("autoReconnect", "false")); 150 autoReconnect.required = false; 151 autoReconnect.choices = new String [] { "true", "false" }; 152 autoReconnect.description = "Should the driver try to re-establish bad connections?"; 153 154 DriverPropertyInfo maxReconnects = new DriverPropertyInfo ("maxReconnects", 155 info.getProperty("maxReconnects", "3")); 156 maxReconnects.required = false; 157 maxReconnects.description = "Maximum number of reconnects to attempt if autoReconnect is true"; 158 ; 159 160 DriverPropertyInfo initialTimeout = new DriverPropertyInfo ("initialTimeout", 161 info.getProperty("initialTimeout", "2")); 162 initialTimeout.required = false; 163 initialTimeout.description = "Initial timeout (seconds) to wait between failed connections"; 164 165 DriverPropertyInfo profileSql = new DriverPropertyInfo ("profileSql", 166 info.getProperty("profileSql", "false")); 167 profileSql.required = false; 168 profileSql.choices = new String [] { "true", "false" }; 169 profileSql.description = "Trace queries and their execution/fetch times on STDERR (true/false) defaults to false"; 170 ; 171 172 DriverPropertyInfo socketTimeout = new DriverPropertyInfo ("socketTimeout", 173 info.getProperty("socketTimeout", "0")); 174 socketTimeout.required = false; 175 socketTimeout.description = "Timeout on network socket operations (0 means no timeout)"; 176 ; 177 178 DriverPropertyInfo useSSL = new DriverPropertyInfo ("useSSL", 179 info.getProperty("useSSL", "false")); 180 useSSL.required = false; 181 useSSL.choices = new String [] { "true", "false" }; 182 useSSL.description = "Use SSL when communicating with the server?"; 183 ; 184 185 DriverPropertyInfo useCompression = new DriverPropertyInfo ("useCompression", 186 info.getProperty("useCompression", "false")); 187 useCompression.required = false; 188 useCompression.choices = new String [] { "true", "false" }; 189 useCompression.description = "Use zlib compression when communicating with the server?"; 190 ; 191 192 DriverPropertyInfo paranoid = new DriverPropertyInfo ("paranoid", 193 info.getProperty("paranoid", "false")); 194 paranoid.required = false; 195 paranoid.choices = new String [] { "true", "false" }; 196 paranoid.description = "Expose sensitive information in error messages and clear " 197 + "data structures holding sensitiven data when possible?"; 198 ; 199 200 DriverPropertyInfo useHostsInPrivileges = new DriverPropertyInfo ("useHostsInPrivileges", 201 info.getProperty("useHostsInPrivileges", "true")); 202 useHostsInPrivileges.required = false; 203 useHostsInPrivileges.choices = new String [] { "true", "false" }; 204 useHostsInPrivileges.description = "Add '@hostname' to users in DatabaseMetaData.getColumn/TablePrivileges()"; 205 ; 206 207 DriverPropertyInfo interactiveClient = new DriverPropertyInfo ("interactiveClient", 208 info.getProperty("interactiveClient", "false")); 209 interactiveClient.required = false; 210 interactiveClient.choices = new String [] { "true", "false" }; 211 interactiveClient.description = "Set the CLIENT_INTERACTIVE flag, which tells MySQL " 212 + "to timeout connections based on INTERACTIVE_TIMEOUT instead of WAIT_TIMEOUT"; 213 ; 214 215 DriverPropertyInfo useTimezone = new DriverPropertyInfo ("useTimezone", 216 info.getProperty("useTimezone", "false")); 217 useTimezone.required = false; 218 useTimezone.choices = new String [] { "true", "false" }; 219 useTimezone.description = "Convert time/date types between client and server timezones"; 220 221 DriverPropertyInfo serverTimezone = new DriverPropertyInfo ("serverTimezone", 222 info.getProperty("serverTimezone", "")); 223 serverTimezone.required = false; 224 serverTimezone.description = "Override detection/mapping of timezone. Used when timezone from server doesn't map to Java timezone"; 225 226 DriverPropertyInfo connectTimeout = new DriverPropertyInfo ("connectTimeout", 227 info.getProperty("connectTimeout", "0")); 228 connectTimeout.required = false; 229 connectTimeout.description = "Timeout for socket connect (in milliseconds), with 0 being no timeout. Only works on JDK-1.4 or newer. Defaults to '0'."; 230 231 DriverPropertyInfo queriesBeforeRetryMaster = new DriverPropertyInfo ("queriesBeforeRetryMaster", 232 info.getProperty("queriesBeforeRetryMaster", "50")); 233 queriesBeforeRetryMaster.required = false; 234 queriesBeforeRetryMaster.description = "Number of queries to issue before falling back to master when failed over " 235 + "(when using multi-host failover). Whichever condition is met first, " 236 + "'queriesBeforeRetryMaster' or 'secondsBeforeRetryMaster' will cause an " 237 + "attempt to be made to reconnect to the master. Defaults to 50."; 238 ; 239 240 DriverPropertyInfo secondsBeforeRetryMaster = new DriverPropertyInfo ("secondsBeforeRetryMaster", 241 info.getProperty("secondsBeforeRetryMaster", "30")); 242 secondsBeforeRetryMaster.required = false; 243 secondsBeforeRetryMaster.description = "How long should the driver wait, when failed over, before attempting " 244 + "to reconnect to the master server? Whichever condition is met first, " 245 + "'queriesBeforeRetryMaster' or 'secondsBeforeRetryMaster' will cause an " 246 + "attempt to be made to reconnect to the master. Time in seconds, defaults to 30"; 247 248 DriverPropertyInfo useStreamLengthsInPrepStmts = new DriverPropertyInfo ("useStreamLengthsInPrepStmts", 249 info.getProperty("useStreamLengthsInPrepStmts", "true")); 250 useStreamLengthsInPrepStmts.required = false; 251 useStreamLengthsInPrepStmts.choices = new String [] { "true", "false" }; 252 useStreamLengthsInPrepStmts.description = "Honor stream length parameter in " 253 + "PreparedStatement/ResultSet.setXXXStream() method calls (defaults to 'true')"; 254 255 DriverPropertyInfo continueBatchOnError = new DriverPropertyInfo ("continueBatchOnError", 256 info.getProperty("continueBatchOnError", "true")); 257 continueBatchOnError.required = false; 258 continueBatchOnError.choices = new String [] { "true", "false" }; 259 continueBatchOnError.description = "Should the driver continue processing batch commands if " 260 + "one statement fails. The JDBC spec allows either way (defaults to 'true')."; 261 262 DriverPropertyInfo allowLoadLocalInfile = new DriverPropertyInfo ("allowLoadLocalInfile", 263 info.getProperty("allowLoadLocalInfile", "true")); 264 allowLoadLocalInfile.required = false; 265 allowLoadLocalInfile.choices = new String [] { "true", "false" }; 266 allowLoadLocalInfile.description = "Should the driver allow use of 'LOAD DATA LOCAL INFILE...' (defaults to 'true')."; 267 268 DriverPropertyInfo strictUpdates = new DriverPropertyInfo ("strictUpdates", 269 info.getProperty("strictUpdates", "true")); 270 strictUpdates.required = false; 271 strictUpdates.choices = new String [] { "true", "false" }; 272 strictUpdates.description = "Should the driver do strict checking (all primary keys selected) of updatable result sets?...' (defaults to 'true')."; 273 274 DriverPropertyInfo ignoreNonTxTables = new DriverPropertyInfo ("ignoreNonTxTables", 275 info.getProperty("ignoreNonTxTables", "false")); 276 ignoreNonTxTables.required = false; 277 ignoreNonTxTables.choices = new String [] { "true", "false" }; 278 ignoreNonTxTables.description = "Ignore non-transactional table warning for rollback? (defaults to 'false')."; 279 280 DriverPropertyInfo clobberStreamingResults = new DriverPropertyInfo ("clobberStreamingResults", 281 info.getProperty("clobberStreamingResults", "false")); 282 clobberStreamingResults.required = false; 283 clobberStreamingResults.choices = new String [] { "true", "false" }; 284 clobberStreamingResults.description = "This will cause a 'streaming' ResultSet to be automatically closed, " 285 + "and any oustanding data still streaming from the server to be discarded if another query is executed " 286 + "before all the data has been read from the server."; 287 288 DriverPropertyInfo reconnectAtTxEnd = new DriverPropertyInfo ("reconnectAtTxEnd", 289 info.getProperty("reconnectAtTxEnd", "false")); 290 reconnectAtTxEnd.required = false; 291 reconnectAtTxEnd.choices = new String [] { "true", "false" }; 292 reconnectAtTxEnd.description = "If autoReconnect is set to true, should the driver attempt reconnections" 293 + "at the end of every transaction? (true/false, defaults to false)"; 294 295 DriverPropertyInfo alwaysClearStream = new DriverPropertyInfo ("alwaysClearStream", 296 info.getProperty("alwaysClearStream", "false")); 297 alwaysClearStream.required = false; 298 alwaysClearStream.choices = new String [] { "true", "false" }; 299 alwaysClearStream.description = "Should the driver clear any remaining data from the input stream before issuing" 300 + " a query? Normally not needed (approx 1-2% perf. penalty, true/false, defaults to false)"; 301 302 DriverPropertyInfo cachePrepStmts = new DriverPropertyInfo ("cachePrepStmts", 303 info.getProperty("cachePrepStmts", "false")); 304 cachePrepStmts.required = false; 305 cachePrepStmts.choices = new String [] { "true", "false" }; 306 cachePrepStmts.description = "Should the driver cache the parsing stage of PreparedStatements (true/false, default is 'false')"; 307 308 DriverPropertyInfo prepStmtCacheSize = new DriverPropertyInfo ("prepStmtCacheSize", 309 info.getProperty("prepStmtCacheSize", "25")); 310 prepStmtCacheSize.required = false; 311 prepStmtCacheSize.description = "If prepared statement caching is enabled, " 312 + "how many prepared statements should be cached? (default is '25')"; 313 314 DriverPropertyInfo prepStmtCacheSqlLimit = new DriverPropertyInfo ("prepStmtCacheSqlLimit", 315 info.getProperty("prepStmtCacheSqlLimit", "256")); 316 prepStmtCacheSqlLimit.required = false; 317 prepStmtCacheSqlLimit.description = "If prepared statement caching is enabled, " 318 + "what's the largest SQL the driver will cache the parsing for? (in chars, default is '256')"; 319 320 DriverPropertyInfo useUnbufferedInput = new DriverPropertyInfo ("useUnbufferedInput", 321 info.getProperty("useUnbufferedInput", "true")); 322 useUnbufferedInput.required = false; 323 useUnbufferedInput.description = "Don't use BufferedInputStream for reading data from the server true/false (default is 'true')"; 324 325 DriverPropertyInfo [] dpi = { 326 hostProp, portProp, dbProp, userProp, passwordProp, autoReconnect, 327 maxReconnects, initialTimeout, profileSql, socketTimeout, useSSL, 328 paranoid, useHostsInPrivileges, interactiveClient, useCompression, 329 useTimezone, serverTimezone, connectTimeout, 330 secondsBeforeRetryMaster, queriesBeforeRetryMaster, 331 useStreamLengthsInPrepStmts, continueBatchOnError, 332 allowLoadLocalInfile, strictUpdates, ignoreNonTxTables, 333 reconnectAtTxEnd, alwaysClearStream, cachePrepStmts, 334 prepStmtCacheSize, prepStmtCacheSqlLimit, useUnbufferedInput 335 }; 336 337 return dpi; 338 } 339 340 353 public boolean acceptsURL(String url) throws java.sql.SQLException { 354 return (parseURL(url, null) != null); 355 } 356 357 392 public java.sql.Connection connect(String url, Properties info) 393 throws java.sql.SQLException { 394 Properties props = null; 395 396 if ((props = parseURL(url, info)) == null) { 397 return null; 398 } else { 399 try { 400 Connection newConn = new com.mysql.jdbc.Connection(host(props), 401 port(props), props, database(props), url, this); 402 403 return (java.sql.Connection ) newConn; 404 } catch (SQLException sqlEx) { 405 throw sqlEx; 408 } catch (Exception ex) { 409 throw new SQLException ( 410 "Cannot load connection class because of underlying exception: '" 411 + ex.toString() + "'.", 412 SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE); 413 } 414 } 415 } 416 417 421 428 public String database(Properties props) { 429 return props.getProperty("DBNAME"); 430 } 431 432 440 public String host(Properties props) { 441 return props.getProperty("HOST", "localhost"); 442 } 443 444 456 public boolean jdbcCompliant() { 457 return false; 458 } 459 460 467 public int port(Properties props) { 468 return Integer.parseInt(props.getProperty("PORT", "3306")); 469 } 470 471 475 483 public String property(String name, Properties props) { 484 return props.getProperty(name); 485 } 486 487 492 static int getMajorVersionInternal() { 493 return safeIntParse("3"); 494 } 495 496 501 static int getMinorVersionInternal() { 502 return safeIntParse("0"); 503 } 504 505 516 517 Properties parseURL(String url, Properties defaults) 522 throws java.sql.SQLException { 523 Properties urlProps = new Properties (defaults); 524 525 if (url == null) { 526 return null; 527 } else { 528 532 int index = url.indexOf("?"); 533 534 if (index != -1) { 535 String paramString = url.substring(index + 1, url.length()); 536 url = url.substring(0, index); 537 538 StringTokenizer queryParams = new StringTokenizer (paramString, 539 "&"); 540 541 while (queryParams.hasMoreTokens()) { 542 StringTokenizer vp = new StringTokenizer (queryParams 543 .nextToken(), "="); 544 String param = ""; 545 546 if (vp.hasMoreTokens()) { 547 param = vp.nextToken(); 548 } 549 550 String value = ""; 551 552 if (vp.hasMoreTokens()) { 553 value = vp.nextToken(); 554 } 555 556 if ((value.length() > 0) && (param.length() > 0)) { 557 urlProps.put(param, value); 558 } 559 } 560 } 561 562 StringTokenizer st = new StringTokenizer (url, ":/", true); 563 564 if (st.hasMoreTokens()) { 565 String protocol = st.nextToken(); 566 567 if (protocol != null) { 568 if (!protocol.equalsIgnoreCase("jdbc")) { 569 return null; 570 } 571 } else { 572 return null; 573 } 574 } else { 575 return null; 576 } 577 578 if (st.hasMoreTokens()) { 580 String colon = st.nextToken(); 581 582 if (colon != null) { 583 if (!colon.equals(":")) { 584 return null; 585 } 586 } else { 587 return null; 588 } 589 } else { 590 return null; 591 } 592 593 if (st.hasMoreTokens()) { 595 String subProto = st.nextToken(); 596 597 if (subProto != null) { 598 if (!subProto.equalsIgnoreCase("mysql")) { 599 return null; 600 } 601 } else { 602 return null; 603 } 604 } else { 605 return null; 606 } 607 608 if (st.hasMoreTokens()) { 610 String colon = st.nextToken(); 611 612 if (colon != null) { 613 if (!colon.equals(":")) { 614 return null; 615 } 616 } else { 617 return null; 618 } 619 } else { 620 return null; 621 } 622 623 if (st.hasMoreTokens()) { 625 String slash = st.nextToken(); 626 String slash2 = ""; 627 628 if (st.hasMoreTokens()) { 629 slash2 = st.nextToken(); 630 } 631 632 if ((slash != null) && (slash2 != null)) { 633 if (!slash.equals("/") && !slash2.equals("/")) { 634 return null; 635 } 636 } else { 637 return null; 638 } 639 } else { 640 return null; 641 } 642 643 if (st.hasMoreTokens()) { 645 String token = st.nextToken(); 646 647 if (token != null) { 648 if (!token.equals(":") && !token.equals("/")) { 649 urlProps.put("HOST", token); 651 652 if (st.hasMoreTokens()) { 653 token = st.nextToken(); 654 } else { 655 return null; 656 } 657 } 658 659 if (token.equals(":")) { 661 if (st.hasMoreTokens()) { 662 token = st.nextToken(); 663 urlProps.put("PORT", token); 664 665 if (st.hasMoreTokens()) { 666 token = st.nextToken(); 667 } 668 } 669 } 670 671 if (token.equals("/")) { 672 if (st.hasMoreTokens()) { 673 token = st.nextToken(); 674 urlProps.put("DBNAME", token); 675 676 return urlProps; 678 } else { 679 urlProps.put("DBNAME", ""); 680 681 return urlProps; 682 } 683 } 684 } else { 685 return null; 686 } 687 } else { 688 return null; 689 } 690 } 691 692 return urlProps; 693 } 694 695 private static int safeIntParse(String intAsString) { 696 try { 697 return Integer.parseInt(intAsString); 698 } catch (NumberFormatException nfe) { 699 return 0; 700 } 701 } 702 } 703 | Popular Tags |