📄 connectionmanager.java
字号:
/**
* $RCSfile: ConnectionManager.java,v $
* $Revision: 1.1.1.1 $
* $Date: 2002/09/09 13:50:48 $
*
* New Jive from Jdon.com.
*
* This software is the proprietary information of CoolServlets, Inc.
* Use is subject to license terms.
*/
package com.jivesoftware.forum.database;
import java.sql.*;
import java.io.*;
import java.util.*;
import java.lang.reflect.*;
import com.jivesoftware.forum.*;
/**
* Central manager of database connections. All methods are static so that they
* can be easily accessed throughout the classes in the database package.<p>
*
* This class also provides a set of utility methods that abstract out
* operations that may not work on all databases such as setting the max number
* or rows that a query should return.
*
* @see ConnectionProvider
*/
public class ConnectionManager {
private static ConnectionProvider connectionProvider;
private static Object providerLock = new Object();
// True if connection profiling is turned on. Always false by default.
private static boolean profilingEnabled = false;
// True if the database support transactions.
protected static boolean supportsTransactions;
// True if the database requires large text fields to be streamed.
protected static boolean streamLargeText;
// True if the database supports the Statement.setMaxRows() method.
protected static boolean supportsMaxRows;
// True if the database supports the Statement.setFetchSize() method.
protected static boolean supportsFetchSize;
// True if the database supports correlated subqueries.
protected static boolean supportsSubqueries;
private static DatabaseType databaseType = DatabaseType.OTHER;
static {
// Add a shutdown hook to the VM if we're running JDK 1.3. When the
// thread is executed, it will call the destroy() method of the
// current connection provider. This is necessary for some connection
// providers -- especially those for in-VM Java databases.
Runtime runtime = Runtime.getRuntime();
Class c = runtime.getClass();
try {
Method m = c.getMethod("addShutdownHook", new Class[] { Thread.class } );
m.invoke(runtime, new Object[] { new ShutdownThread() });
}
catch (NoSuchMethodException nsme) {
// Ignore -- the user might not be running JDK 1.3.
}
catch (Exception e) {
e.printStackTrace();
}
}
/**
* Returns a database connection from the currently active connection
* provider.
*/
public static Connection getConnection() throws SQLException {
if (connectionProvider == null) {
synchronized (providerLock) {
if (connectionProvider == null) {
// Attempt to load the connection provider classname as
// a Jive property.
String className =
JiveGlobals.getJiveProperty("connectionProvider.className");
if (className != null) {
// Attempt to load the class.
try {
Class conClass = Class.forName(className);
setConnectionProvider((ConnectionProvider)conClass.newInstance());
}
catch(Exception e) {
e.printStackTrace();
System.err.println("Warning: failed to create the " +
"connection provider specified by connection" +
"Provider.className. Using the default pool.");
setConnectionProvider(new DefaultConnectionProvider());
}
}
else {
setConnectionProvider(new DefaultConnectionProvider());
}
}
}
}
Connection con = connectionProvider.getConnection();
if (con == null) {
System.err.println("WARNING: ConnectionManager.getConnection() " +
"failed to obtain a connection.");
}
// See if profiling is enabled. If yes, wrap the connection with a
// profiled connection.
//if (profilingEnabled) {
//return new ProfiledConnection(con);
//}
//else {
return con;
//}
}
/**
* Returns a Connection from the currently active connection provider that
* is ready to participate in transactions (auto commit is set to false).
*/
public static Connection getTransactionConnection() throws SQLException {
Connection con = getConnection();
if (supportsTransactions) {
con.setAutoCommit(false);
}
return con;
}
/**
* Closes a Connection. However, it first rolls back the transaction or
* commits it depending on the value of <code>abortTransaction</code>.
*/
public static void closeTransactionConnection(Connection con,
boolean abortTransaction)
{
// Rollback or commit the transaction
if (supportsTransactions) {
try {
if (abortTransaction) {
con.rollback();
}
else {
con.commit();
}
}
catch (Exception e) { e.printStackTrace(); }
}
try {
// Reset the connection to auto-commit mode.
if (supportsTransactions) {
con.setAutoCommit(true);
}
// Finally, close the db connection.
con.close();
}
catch (Exception e) { e.printStackTrace(); }
}
/**
* Returns the current connection provider. The only case in which this
* method should be called is if more information about the current
* connection provider is needed. Database connections should always be
* obtained by calling the getConnection method of this class.
*/
public static ConnectionProvider getConnectionProvider() {
return connectionProvider;
}
/**
* Sets the connection provider. The old provider (if it exists) is shut
* down before the new one is started. A connection provider <b>should
* not</b> be started before being passed to the connection manager
* because the manager will call the start() method automatically.
*
* @param provider the ConnectionProvider that the manager should obtain
* connections from.
*/
public static void setConnectionProvider(ConnectionProvider provider) {
synchronized (providerLock) {
if (connectionProvider != null) {
connectionProvider.destroy();
connectionProvider = null;
}
connectionProvider = provider;
connectionProvider.start();
// Now, get a connection to determine meta data.
Connection con = null;
try {
con = connectionProvider.getConnection();
setMetaData(con);
}
catch (Exception e) {
e.printStackTrace();
}
finally {
try { con.close(); } catch (Exception e) { }
}
}
// Remember what connection provider we want to use for restarts.
JiveGlobals.setJiveProperty("connectionProvider.className",
provider.getClass().getName());
}
/**
* Retrives a large text column from a result set, automatically performing
* streaming if the JDBC driver requires it. This is necessary because
* different JDBC drivers have different capabilities and methods for
* retrieving large text values.
*
* @param rs the ResultSet to retrieve the text field from.
* @param columnIndex the column in the ResultSet of the text field.
* @return the String value of the text field.
*/
public static String getLargeTextField(ResultSet rs, int columnIndex)
throws SQLException
{
if (streamLargeText) {
Reader bodyReader = null;
String value = null;
try {
bodyReader = rs.getCharacterStream(columnIndex);
if (bodyReader == null) {
return null;
}
char [] buf = new char[256];
int len;
StringWriter out = new StringWriter(256);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -