1 22 23 24 package com.mchange.v2.c3p0.impl; 25 26 import java.beans.*; 27 import java.util.*; 28 import java.lang.reflect.*; 29 import java.sql.*; 30 import javax.sql.*; 31 import com.mchange.v2.c3p0.*; 32 import com.mchange.v2.c3p0.cfg.*; 33 import com.mchange.v2.async.*; 34 import com.mchange.v2.coalesce.*; 35 import com.mchange.v1.db.sql.*; 36 import com.mchange.v2.log.*; 37 import com.mchange.v1.lang.BooleanUtils; 38 import com.mchange.v2.sql.SqlUtils; 39 import com.mchange.v2.resourcepool.ResourcePoolFactory; 40 import com.mchange.v2.resourcepool.BasicResourcePoolFactory; 41 42 public final class C3P0PooledConnectionPoolManager 43 { 44 private final static MLogger logger = MLog.getLogger( C3P0PooledConnectionPoolManager.class ); 45 46 private final static boolean POOL_EVENT_SUPPORT = false; 47 48 private final static CoalesceChecker COALESCE_CHECKER = IdentityTokenizedCoalesceChecker.INSTANCE; 49 50 final static Coalescer COALESCER = CoalescerFactory.createCoalescer( COALESCE_CHECKER, true, false ); 52 53 final static int DFLT_NUM_TASK_THREADS_PER_DATA_SOURCE = 3; 54 55 ThreadPoolAsynchronousRunner taskRunner; 57 Timer timer; 58 ResourcePoolFactory rpfact; 59 Map authsToPools; 60 61 62 final ConnectionPoolDataSource cpds; 63 final Map propNamesToReadMethods; 64 final Map flatPropertyOverrides; 65 final Map userOverrides; 66 final DbAuth defaultAuth; 67 final String parentDataSourceIdentityToken; 68 69 70 71 int num_task_threads = DFLT_NUM_TASK_THREADS_PER_DATA_SOURCE; 72 73 74 75 public int getThreadPoolSize() 76 { return taskRunner.getThreadCount(); } 77 78 public int getThreadPoolNumActiveThreads() 79 { return taskRunner.getActiveCount(); } 80 81 public int getThreadPoolNumIdleThreads() 82 { return taskRunner.getIdleCount(); } 83 84 public int getThreadPoolNumTasksPending() 85 { return taskRunner.getPendingTaskCount(); } 86 87 public String getThreadPoolStackTraces() 88 { return taskRunner.getStackTraces(); } 89 90 public String getThreadPoolStatus() 91 { return taskRunner.getStatus(); } 92 93 private synchronized void poolsInit() 94 { 95 this.timer = new Timer( true ); 96 97 int matt = this.getMaxAdministrativeTaskTime( null ); 98 if ( matt > 0 ) 99 { 100 int matt_ms = matt * 1000; 101 this.taskRunner = new ThreadPoolAsynchronousRunner( num_task_threads, 102 103 true, 105 matt_ms, 107 matt_ms * 3, 109 matt_ms * 6, 114 timer ); 115 } 116 else 117 this.taskRunner = new ThreadPoolAsynchronousRunner( num_task_threads, true, timer ); 118 if (POOL_EVENT_SUPPORT) 121 this.rpfact = ResourcePoolFactory.createInstance( taskRunner, null, timer ); 122 else 123 this.rpfact = BasicResourcePoolFactory.createNoEventSupportInstance( taskRunner, timer ); 124 this.authsToPools = new HashMap(); 125 } 126 127 private void poolsDestroy() 128 { poolsDestroy( true ); } 129 130 private synchronized void poolsDestroy( boolean close_outstanding_connections ) 131 { 132 for (Iterator ii = authsToPools.values().iterator(); ii.hasNext(); ) 134 { 135 try 136 { ((C3P0PooledConnectionPool) ii.next()).close( close_outstanding_connections ); } 137 catch ( Exception e ) 138 { 139 logger.log(MLevel.WARNING, "An Exception occurred while trying to clean up a pool!", e); 141 } 142 } 143 144 this.taskRunner.close( true ); 145 this.timer.cancel(); 146 147 this.taskRunner = null; 148 this.timer = null; 149 this.rpfact = null; 150 this.authsToPools = null; 151 } 152 153 public C3P0PooledConnectionPoolManager(ConnectionPoolDataSource cpds, 154 Map flatPropertyOverrides, Map forceUserOverrides, int num_task_threads, 157 String parentDataSourceIdentityToken) 158 throws SQLException 159 { 160 try 161 { 162 this.cpds = cpds; 163 this.flatPropertyOverrides = flatPropertyOverrides; 164 this.num_task_threads = num_task_threads; 165 this.parentDataSourceIdentityToken = parentDataSourceIdentityToken; 166 167 DbAuth auth = null; 168 169 if ( flatPropertyOverrides != null ) 170 { 171 String overrideUser = (String ) flatPropertyOverrides.get("overrideDefaultUser"); 172 String overridePassword = (String ) flatPropertyOverrides.get("overrideDefaultPassword"); 173 174 if (overrideUser == null) 175 { 176 overrideUser = (String ) flatPropertyOverrides.get("user"); 177 overridePassword = (String ) flatPropertyOverrides.get("password"); 178 } 179 180 if (overrideUser != null) 181 auth = new DbAuth( overrideUser, overridePassword ); 182 } 183 184 if (auth == null) 185 auth = C3P0ImplUtils.findAuth( cpds ); 186 187 this.defaultAuth = auth; 188 189 Map tmp = new HashMap(); 190 BeanInfo bi = Introspector.getBeanInfo( cpds.getClass() ); 191 PropertyDescriptor[] pds = bi.getPropertyDescriptors(); 192 PropertyDescriptor pd = null; 193 for (int i = 0, len = pds.length; i < len; ++i) 194 { 195 pd = pds[i]; 196 197 String name = pd.getName(); 198 Method m = pd.getReadMethod(); 199 200 if (m != null) 201 tmp.put( name, m ); 202 } 203 this.propNamesToReadMethods = tmp; 204 205 if (forceUserOverrides == null) 206 { 207 Method uom = (Method) propNamesToReadMethods.get( "userOverridesAsString" ); 208 if (uom != null) 209 { 210 String uoas = (String ) uom.invoke( cpds, null ); 211 Map uo = C3P0ImplUtils.parseUserOverridesAsString( uoas ); 213 this.userOverrides = uo; 214 } 215 else 216 this.userOverrides = Collections.EMPTY_MAP; 217 } 218 else 219 this.userOverrides = forceUserOverrides; 220 221 poolsInit(); 222 } 223 catch (Exception e) 224 { 225 if (Debug.DEBUG) 226 logger.log(MLevel.FINE, null, e); 227 throw SqlUtils.toSQLException(e); 229 } 230 } 231 232 public synchronized C3P0PooledConnectionPool getPool(String username, String password, boolean create) throws SQLException 233 { 234 if (create) 235 return getPool( username, password ); 236 else 237 { 238 DbAuth checkAuth = new DbAuth( username, password ); 239 C3P0PooledConnectionPool out = (C3P0PooledConnectionPool) authsToPools.get(checkAuth); 240 if (out == null) 241 throw new SQLException("No pool has been initialized for databse user '" + username + "' with the specified password."); 242 else 243 return out; 244 } 245 } 246 247 public C3P0PooledConnectionPool getPool(String username, String password) 248 throws SQLException 249 { return getPool( new DbAuth( username, password ) ); } 250 251 public synchronized C3P0PooledConnectionPool getPool(DbAuth auth) 252 throws SQLException 253 { 254 C3P0PooledConnectionPool out = (C3P0PooledConnectionPool) authsToPools.get(auth); 255 if (out == null) 256 { 257 out = createPooledConnectionPool(auth); 258 authsToPools.put( auth, out ); 259 } 260 return out; 261 } 262 263 public synchronized Set getManagedAuths() 264 { return Collections.unmodifiableSet( authsToPools.keySet() ); } 265 266 public synchronized int getNumManagedAuths() 267 { return authsToPools.size(); } 268 269 public C3P0PooledConnectionPool getPool() 270 throws SQLException 271 { return getPool( defaultAuth ); } 272 273 public synchronized int getNumIdleConnectionsAllAuths() throws SQLException 274 { 275 int out = 0; 276 for (Iterator ii = authsToPools.values().iterator(); ii.hasNext(); ) 277 out += ((C3P0PooledConnectionPool) ii.next()).getNumIdleConnections(); 278 return out; 279 } 280 281 public synchronized int getNumBusyConnectionsAllAuths() throws SQLException 282 { 283 int out = 0; 284 for (Iterator ii = authsToPools.values().iterator(); ii.hasNext(); ) 285 out += ((C3P0PooledConnectionPool) ii.next()).getNumBusyConnections(); 286 return out; 287 } 288 289 public synchronized int getNumConnectionsAllAuths() throws SQLException 290 { 291 int out = 0; 292 for (Iterator ii = authsToPools.values().iterator(); ii.hasNext(); ) 293 out += ((C3P0PooledConnectionPool) ii.next()).getNumConnections(); 294 return out; 295 } 296 297 public synchronized int getNumUnclosedOrphanedConnectionsAllAuths() throws SQLException 298 { 299 int out = 0; 300 for (Iterator ii = authsToPools.values().iterator(); ii.hasNext(); ) 301 out += ((C3P0PooledConnectionPool) ii.next()).getNumUnclosedOrphanedConnections(); 302 return out; 303 } 304 305 public synchronized int getStatementCacheNumStatementsAllUsers() throws SQLException 306 { 307 int out = 0; 308 for (Iterator ii = authsToPools.values().iterator(); ii.hasNext(); ) 309 out += ((C3P0PooledConnectionPool) ii.next()).getStatementCacheNumStatements(); 310 return out; 311 } 312 313 public synchronized int getStatementCacheNumCheckedOutStatementsAllUsers() throws SQLException 314 { 315 int out = 0; 316 for (Iterator ii = authsToPools.values().iterator(); ii.hasNext(); ) 317 out += ((C3P0PooledConnectionPool) ii.next()).getStatementCacheNumCheckedOut(); 318 return out; 319 } 320 321 public synchronized int getStatementCacheNumConnectionsWithCachedStatementsAllUsers() throws SQLException 322 { 323 int out = 0; 324 for (Iterator ii = authsToPools.values().iterator(); ii.hasNext(); ) 325 out += ((C3P0PooledConnectionPool) ii.next()).getStatementCacheNumConnectionsWithCachedStatements(); 326 return out; 327 } 328 329 public synchronized void softResetAllAuths() throws SQLException 330 { 331 for (Iterator ii = authsToPools.values().iterator(); ii.hasNext(); ) 332 ((C3P0PooledConnectionPool) ii.next()).reset(); 333 } 334 335 public void close() 336 { this.close( true ); } 337 338 public synchronized void close( boolean close_outstanding_connections ) 339 { 340 if (authsToPools != null) 342 poolsDestroy( close_outstanding_connections ); 343 } 344 345 protected synchronized void finalize() 346 { 347 this.close(); 349 } 350 351 private Object getObject(String propName, String userName) 352 { 353 Object out = null; 354 355 if (userName != null) 356 { 357 Map specificUserOverrides = (Map) userOverrides.get( userName ); 359 if (specificUserOverrides != null) 360 out = specificUserOverrides.get( propName ); 361 } 362 363 if (out == null && flatPropertyOverrides != null) out = flatPropertyOverrides.get( propName ); 365 366 if (out == null) 369 { 370 try 371 { 372 Method m = (Method) propNamesToReadMethods.get( propName ); 373 if (m != null) 374 { 375 Object readProp = m.invoke( cpds, null ); 376 if (readProp != null) 377 out = readProp.toString(); 378 } 379 } 380 catch (Exception e) 381 { 382 if (logger.isLoggable( MLevel.WARNING )) 383 logger.log(MLevel.WARNING, 384 "An exception occurred while trying to read property '" + propName + 385 "' from ConnectionPoolDataSource: " + cpds + 386 ". Default config value will be used.", 387 e ); 388 } 389 } 390 391 if (out == null) 395 out = C3P0Config.getUnspecifiedUserProperty( propName, null ); 396 397 return out; 398 } 399 400 private String getString(String propName, String userName) 401 { 402 Object o = getObject( propName, userName); 403 return (o == null ? null : o.toString()); 404 } 405 406 private int getInt(String propName, String userName) throws Exception 407 { 408 Object o = getObject( propName, userName); 409 if (o instanceof Integer ) 410 return ((Integer ) o).intValue(); 411 else if (o instanceof String ) 412 return Integer.parseInt( (String ) o ); 413 else 414 throw new Exception ("Unexpected object found for putative int property '" + propName +"': " + o); 415 } 416 417 private boolean getBoolean(String propName, String userName) throws Exception 418 { 419 Object o = getObject( propName, userName); 420 if (o instanceof Boolean ) 421 return ((Boolean ) o).booleanValue(); 422 else if (o instanceof String ) 423 return BooleanUtils.parseBoolean( (String ) o ); 424 else 425 throw new Exception ("Unexpected object found for putative boolean property '" + propName +"': " + o); 426 } 427 428 public String getAutomaticTestTable(String userName) 429 { return getString("automaticTestTable", userName ); } 430 431 public String getPreferredTestQuery(String userName) 432 { return getString("preferredTestQuery", userName ); } 433 434 private int getInitialPoolSize(String userName) 435 { 436 try 437 { return getInt("initialPoolSize", userName ); } 438 catch (Exception e) 439 { 440 if ( logger.isLoggable( MLevel.FINE ) ) 441 logger.log( MLevel.FINE, "Could not fetch int property", e); 442 return C3P0Defaults.initialPoolSize(); 443 } 444 } 445 446 public int getMinPoolSize(String userName) 447 { 448 try 449 { return getInt("minPoolSize", userName ); } 450 catch (Exception e) 451 { 452 if ( logger.isLoggable( MLevel.FINE ) ) 453 logger.log( MLevel.FINE, "Could not fetch int property", e); 454 return C3P0Defaults.minPoolSize(); 455 } 456 } 457 458 private int getMaxPoolSize(String userName) 459 { 460 try 461 { return getInt("maxPoolSize", userName ); } 462 catch (Exception e) 463 { 464 if ( logger.isLoggable( MLevel.FINE ) ) 465 logger.log( MLevel.FINE, "Could not fetch int property", e); 466 return C3P0Defaults.maxPoolSize(); 467 } 468 } 469 470 private int getMaxStatements(String userName) 471 { 472 try 473 { return getInt("maxStatements", userName ); } 474 catch (Exception e) 475 { 476 if ( logger.isLoggable( MLevel.FINE ) ) 477 logger.log( MLevel.FINE, "Could not fetch int property", e); 478 return C3P0Defaults.maxStatements(); 479 } 480 } 481 482 private int getMaxStatementsPerConnection(String userName) 483 { 484 try 485 { return getInt("maxStatementsPerConnection", userName ); } 486 catch (Exception e) 487 { 488 if ( logger.isLoggable( MLevel.FINE ) ) 489 logger.log( MLevel.FINE, "Could not fetch int property", e); 490 return C3P0Defaults.maxStatementsPerConnection(); 491 } 492 } 493 494 private int getAcquireIncrement(String userName) 495 { 496 try 497 { return getInt("acquireIncrement", userName ); } 498 catch (Exception e) 499 { 500 if ( logger.isLoggable( MLevel.FINE ) ) 501 logger.log( MLevel.FINE, "Could not fetch int property", e); 502 return C3P0Defaults.acquireIncrement(); 503 } 504 } 505 506 private int getAcquireRetryAttempts(String userName) 507 { 508 try 509 { return getInt("acquireRetryAttempts", userName ); } 510 catch (Exception e) 511 { 512 if ( logger.isLoggable( MLevel.FINE ) ) 513 logger.log( MLevel.FINE, "Could not fetch int property", e); 514 return C3P0Defaults.acquireRetryAttempts(); 515 } 516 } 517 518 private int getAcquireRetryDelay(String userName) 519 { 520 try 521 { return getInt("acquireRetryDelay", userName ); } 522 catch (Exception e) 523 { 524 if ( logger.isLoggable( MLevel.FINE ) ) 525 logger.log( MLevel.FINE, "Could not fetch int property", e); 526 return C3P0Defaults.acquireRetryDelay(); 527 } 528 } 529 530 private boolean getBreakAfterAcquireFailure(String userName) 531 { 532 try 533 { return getBoolean("breakAfterAcquireFailure", userName ); } 534 catch (Exception e) 535 { 536 if ( logger.isLoggable( MLevel.FINE ) ) 537 logger.log( MLevel.FINE, "Could not fetch boolean property", e); 538 return C3P0Defaults.breakAfterAcquireFailure(); 539 } 540 } 541 542 private int getCheckoutTimeout(String userName) 543 { 544 try 545 { return getInt("checkoutTimeout", userName ); } 546 catch (Exception e) 547 { 548 if ( logger.isLoggable( MLevel.FINE ) ) 549 logger.log( MLevel.FINE, "Could not fetch int property", e); 550 return C3P0Defaults.checkoutTimeout(); 551 } 552 } 553 554 private int getIdleConnectionTestPeriod(String userName) 555 { 556 try 557 { return getInt("idleConnectionTestPeriod", userName ); } 558 catch (Exception e) 559 { 560 if ( logger.isLoggable( MLevel.FINE ) ) 561 logger.log( MLevel.FINE, "Could not fetch int property", e); 562 return C3P0Defaults.idleConnectionTestPeriod(); 563 } 564 } 565 566 private int getMaxIdleTime(String userName) 567 { 568 try 569 { return getInt("maxIdleTime", userName ); } 570 catch (Exception e) 571 { 572 if ( logger.isLoggable( MLevel.FINE ) ) 573 logger.log( MLevel.FINE, "Could not fetch int property", e); 574 return C3P0Defaults.maxIdleTime(); 575 } 576 } 577 578 private int getUnreturnedConnectionTimeout(String userName) 579 { 580 try 581 { return getInt("unreturnedConnectionTimeout", userName ); } 582 catch (Exception e) 583 { 584 if ( logger.isLoggable( MLevel.FINE ) ) 585 logger.log( MLevel.FINE, "Could not fetch int property", e); 586 return C3P0Defaults.unreturnedConnectionTimeout(); 587 } 588 } 589 590 private boolean getTestConnectionOnCheckout(String userName) 591 { 592 try 593 { return getBoolean("testConnectionOnCheckout", userName ); } 594 catch (Exception e) 595 { 596 if ( logger.isLoggable( MLevel.FINE ) ) 597 logger.log( MLevel.FINE, "Could not fetch boolean property", e); 598 return C3P0Defaults.testConnectionOnCheckout(); 599 } 600 } 601 602 private boolean getTestConnectionOnCheckin(String userName) 603 { 604 try 605 { return getBoolean("testConnectionOnCheckin", userName ); } 606 catch (Exception e) 607 { 608 if ( logger.isLoggable( MLevel.FINE ) ) 609 logger.log( MLevel.FINE, "Could not fetch boolean property", e); 610 return C3P0Defaults.testConnectionOnCheckin(); 611 } 612 } 613 614 private boolean getDebugUnreturnedConnectionStackTraces(String userName) 615 { 616 try 617 { return getBoolean("debugUnreturnedConnectionStackTraces", userName ); } 618 catch (Exception e) 619 { 620 if ( logger.isLoggable( MLevel.FINE ) ) 621 logger.log( MLevel.FINE, "Could not fetch boolean property", e); 622 return C3P0Defaults.debugUnreturnedConnectionStackTraces(); 623 } 624 } 625 626 private String getConnectionTesterClassName(String userName) 627 { return getString("connectionTesterClassName", userName ); } 628 629 private ConnectionTester getConnectionTester(String userName) 630 { return C3P0Registry.getConnectionTester( getConnectionTesterClassName( userName ) ); } 631 632 private String getConnectionCustomizerClassName(String userName) 633 { return getString("connectionCustomizerClassName", userName ); } 634 635 private ConnectionCustomizer getConnectionCustomizer(String userName) throws SQLException 636 { return C3P0Registry.getConnectionCustomizer( getConnectionCustomizerClassName( userName ) ); } 637 638 private int getMaxIdleTimeExcessConnections(String userName) 639 { 640 try 641 { return getInt("maxIdleTimeExcessConnections", userName ); } 642 catch (Exception e) 643 { 644 if ( logger.isLoggable( MLevel.FINE ) ) 645 logger.log( MLevel.FINE, "Could not fetch int property", e); 646 return C3P0Defaults.maxIdleTimeExcessConnections(); 647 } 648 } 649 650 private int getMaxAdministrativeTaskTime(String userName) 651 { 652 try 653 { return getInt("maxAdministrativeTaskTime", userName ); } 654 catch (Exception e) 655 { 656 if ( logger.isLoggable( MLevel.FINE ) ) 657 logger.log( MLevel.FINE, "Could not fetch int property", e); 658 return C3P0Defaults.maxAdministrativeTaskTime(); 659 } 660 } 661 662 private int getMaxConnectionAge(String userName) 663 { 664 try 665 { return getInt("maxConnectionAge", userName ); } 666 catch (Exception e) 667 { 668 if ( logger.isLoggable( MLevel.FINE ) ) 669 logger.log( MLevel.FINE, "Could not fetch int property", e); 670 return C3P0Defaults.maxConnectionAge(); 671 } 672 } 673 674 private int getPropertyCycle(String userName) 675 { 676 try 677 { return getInt("propertyCycle", userName ); } 678 catch (Exception e) 679 { 680 if ( logger.isLoggable( MLevel.FINE ) ) 681 logger.log( MLevel.FINE, "Could not fetch int property", e); 682 return C3P0Defaults.propertyCycle(); 683 } 684 } 685 686 687 private C3P0PooledConnectionPool createPooledConnectionPool(DbAuth auth) throws SQLException 689 { 690 String userName = auth.getUser(); 691 String automaticTestTable = getAutomaticTestTable( userName ); 692 String realTestQuery; 693 694 if (automaticTestTable != null) 695 { 696 realTestQuery = initializeAutomaticTestTable( automaticTestTable, auth ); 697 if (this.getPreferredTestQuery( userName ) != null) 698 { 699 if ( logger.isLoggable( MLevel.WARNING ) ) 700 { 701 logger.logp(MLevel.WARNING, 702 C3P0PooledConnectionPoolManager.class.getName(), 703 "createPooledConnectionPool", 704 "[c3p0] Both automaticTestTable and preferredTestQuery have been set! " + 705 "Using automaticTestTable, and ignoring preferredTestQuery. Real test query is ''{0}''.", 706 realTestQuery 707 ); 708 } 709 } 710 } 711 else 712 { 713 732 if (! defaultAuth.equals( auth )) 733 ensureFirstConnectionAcquisition( auth ); 734 735 realTestQuery = this.getPreferredTestQuery( userName ); 736 } 737 738 C3P0PooledConnectionPool out = new C3P0PooledConnectionPool( cpds, 739 auth, 740 this.getMinPoolSize( userName ), 741 this.getMaxPoolSize( userName ), 742 this.getInitialPoolSize( userName ), 743 this.getAcquireIncrement( userName ), 744 this.getAcquireRetryAttempts( userName ), 745 this.getAcquireRetryDelay( userName ), 746 this.getBreakAfterAcquireFailure( userName ), 747 this.getCheckoutTimeout( userName ), 748 this.getIdleConnectionTestPeriod( userName ), 749 this.getMaxIdleTime( userName ), 750 this.getMaxIdleTimeExcessConnections( userName ), 751 this.getMaxConnectionAge( userName ), 752 this.getPropertyCycle( userName ), 753 this.getUnreturnedConnectionTimeout( userName ), 754 this.getDebugUnreturnedConnectionStackTraces( userName ), 755 this.getTestConnectionOnCheckout( userName ), 756 this.getTestConnectionOnCheckin( userName ), 757 this.getMaxStatements( userName ), 758 this.getMaxStatementsPerConnection( userName ), 759 this.getConnectionTester( userName ), 760 this.getConnectionCustomizer( userName ), 761 realTestQuery, 762 rpfact, 763 taskRunner, 764 parentDataSourceIdentityToken ); 765 return out; 766 } 767 768 769 private String initializeAutomaticTestTable(String automaticTestTable, DbAuth auth) throws SQLException 771 { 772 PooledConnection throwawayPooledConnection = auth.equals( defaultAuth ) ? 773 cpds.getPooledConnection() : 774 cpds.getPooledConnection(auth.getUser(), auth.getPassword()); 775 Connection c = null; 776 PreparedStatement testStmt = null; 777 PreparedStatement createStmt = null; 778 ResultSet mdrs = null; 779 ResultSet rs = null; 780 boolean exists; 781 boolean has_rows; 782 String out; 783 try 784 { 785 c = throwawayPooledConnection.getConnection(); 786 787 DatabaseMetaData dmd = c.getMetaData(); 788 String q = dmd.getIdentifierQuoteString(); 789 String quotedTableName = q + automaticTestTable + q; 790 out = "SELECT * FROM " + quotedTableName; 791 mdrs = dmd.getTables( null, null, automaticTestTable, new String [] {"TABLE"} ); 792 exists = mdrs.next(); 793 794 796 if (exists) 797 { 798 testStmt = c.prepareStatement( out ); 799 rs = testStmt.executeQuery(); 800 has_rows = rs.next(); 801 if (has_rows) 802 throw new SQLException("automatic test table '" + automaticTestTable + 803 "' contains rows, and it should not! Please set this " + 804 "parameter to the name of a table c3p0 can create on its own, " + 805 "that is not used elsewhere in the database!"); 806 } 807 else 808 { 809 String createSql = "CREATE TABLE " + quotedTableName + " ( a CHAR(1) )"; 810 try 811 { 812 createStmt = c.prepareStatement( createSql ); 813 createStmt.executeUpdate(); 814 } 815 catch (SQLException e) 816 { 817 if (logger.isLoggable( MLevel.WARNING )) 818 logger.log(MLevel.WARNING, 819 "An attempt to create an automatic test table failed. Create SQL: " + 820 createSql, 821 e ); 822 throw e; 823 } 824 } 825 return out; 826 } 827 finally 828 { 829 ResultSetUtils.attemptClose( mdrs ); 830 ResultSetUtils.attemptClose( rs ); 831 StatementUtils.attemptClose( testStmt ); 832 StatementUtils.attemptClose( createStmt ); 833 ConnectionUtils.attemptClose( c ); 834 try{ if (throwawayPooledConnection != null) throwawayPooledConnection.close(); } 835 catch ( Exception e ) 836 { 837 logger.log(MLevel.WARNING, "A PooledConnection failed to close.", e); 839 } 840 } 841 } 842 843 private void ensureFirstConnectionAcquisition(DbAuth auth) throws SQLException 844 { 845 PooledConnection throwawayPooledConnection = auth.equals( defaultAuth ) ? 846 cpds.getPooledConnection() : 847 cpds.getPooledConnection(auth.getUser(), auth.getPassword()); 848 Connection c = null; 849 try 850 { 851 c = throwawayPooledConnection.getConnection(); 852 } 853 finally 854 { 855 ConnectionUtils.attemptClose( c ); 856 try{ if (throwawayPooledConnection != null) throwawayPooledConnection.close(); } 857 catch ( Exception e ) 858 { 859 logger.log(MLevel.WARNING, "A PooledConnection failed to close.", e); 861 } 862 } 863 } 864 } 865 866 867 868 869 870 901 928 938 962 992 1012 1013 1023 1025 1090 1092 | Popular Tags |