Commit 4500a1db authored by Matt Tucker's avatar Matt Tucker Committed by matt

Backing out of dynamic proxy logic for connection profiling, as it was having...

Backing out of dynamic proxy logic for connection profiling, as it was having problems. Instead, use JAR of compiled classes that will run on 1.5 or 1.6.

git-svn-id: http://svn.igniterealtime.org/svn/repos/wildfire/trunk@6658 b35dd754-fafc-0310-a699-88a17e54d16e
parent 969e85b4
......@@ -374,6 +374,15 @@
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/build/lib/merge/dbutil.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntryProperties />
</component>
</module>
......
......@@ -9,6 +9,7 @@ commons-el.jar | Jetty 6.0.1 (1.0)
commons-httpclient.jar | 3.0
commons-codec.jar | 1.3
dom4j.jar | 1.6.1
dbutil.jar | Jive Code, no release version.
hsqldb.jar | 1.8.0.5
jetty.jar | Jetty 6.1.0 SVN SNAPSHOT (11/15/2006)
jetty-util.jar | Jetty 6.1.0 SVN SNAPSHOT (11/16/2006)
......
/**
* $RCSfile$
* $Revision: 3055 $
* $Date: 2005-11-10 21:57:51 -0300 (Thu, 10 Nov 2005) $
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.database;
import org.jivesoftware.util.Log;
import java.util.List;
import java.util.ArrayList;
import java.sql.Types;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* Allows PreparedStatement information to be cached. A prepared statement consists of
* a SQL statement containing bind variables as well as variable values. For example,
* the SQL statement <tt>"SELECT * FROM person WHERE age > ?"</tt> would have the integer
* variable <tt>18</tt> (which replaces the "?" chracter) to find all adults. This class
* encapsulates both the SQL string and bind variable values so that actual
* PreparedStatement can be created from that information later.
*
* @author Matt Tucker
*/
public class CachedPreparedStatement {
private String sql;
private List<Object> params;
private List<Integer> types;
/**
* Constructs a new CachedPreparedStatement.
*/
public CachedPreparedStatement() {
params = new ArrayList<Object>();
types = new ArrayList<Integer>();
}
/**
* Constructs a new CachedPreparedStatement.
*
* @param sql the SQL.
*/
public CachedPreparedStatement(String sql) {
this();
setSQL(sql);
}
/**
* Returns the SQL.
*
* @return the SQL.
*/
public String getSQL() {
return sql;
}
/**
* Sets the SQL.
*
* @param sql the SQL.
*/
public void setSQL(String sql) {
this.sql = sql;
}
/**
* Adds a boolean parameter to the prepared statement.
*
* @param value the boolean value.
*/
public void addBoolean(boolean value) {
params.add(value);
types.add(Types.BOOLEAN);
}
/**
* Adds an integer parameter to the prepared statement.
*
* @param value the int value.
*/
public void addInt(int value) {
params.add(value);
types.add(Types.INTEGER);
}
/**
* Adds a long parameter to the prepared statement.
*
* @param value the long value.
*/
public void addLong(long value) {
params.add(value);
types.add(Types.BIGINT);
}
/**
* Adds a String parameter to the prepared statement.
*
* @param value the String value.
*/
public void addString(String value) {
params.add(value);
types.add(Types.VARCHAR);
}
/**
* Sets all parameters on the given PreparedStatement. The standard code block
* for turning a CachedPreparedStatement into a PreparedStatement is as follows:
*
* <pre>
* PreparedStatement pstmt = con.prepareStatement(cachedPstmt.getSQL());
* cachedPstmt.setParams(pstmt);
* </pre>
*
* @param pstmt the prepared statement.
* @throws java.sql.SQLException if an SQL Exception occurs.
*/
public void setParams(PreparedStatement pstmt) throws SQLException {
for (int i=0; i<params.size(); i++) {
Object param = params.get(i);
int type = types.get(i);
// Set param, noting fact that params start at 1 and not 0.
switch(type) {
case Types.INTEGER:
pstmt.setInt(i+1, (Integer)param);
break;
case Types.BIGINT:
pstmt.setLong(i+1, (Long)param);
break;
case Types.VARCHAR:
pstmt.setString(i+1, (String)param);
break;
case Types.BOOLEAN:
pstmt.setBoolean(i+1, (Boolean)param);
}
}
}
public boolean equals(Object object) {
if (object == null) {
return false;
}
if (!(object instanceof CachedPreparedStatement)) {
return false;
}
if (this == object) {
return true;
}
CachedPreparedStatement otherStmt = (CachedPreparedStatement)object;
return (sql == null && otherStmt.sql == null) || sql != null && sql.equals(otherStmt.sql)
&& types.equals(otherStmt.types) && params.equals(otherStmt.params);
}
public int hashCode() {
int hashCode = 1;
if (sql != null) {
hashCode += sql.hashCode();
}
hashCode = hashCode * 31 + types.hashCode();
hashCode = hashCode * 31 + params.hashCode();
return hashCode;
}
public String toString() {
String toStringSql = sql;
try {
int index = toStringSql.indexOf('?');
int count = 0;
while (index > -1) {
Object param = params.get(count);
int type = types.get(count);
String val = null;
// Get param
switch(type) {
case Types.INTEGER:
val = "" + param;
break;
case Types.BIGINT:
val = "" + param;
break;
case Types.VARCHAR:
val = '\'' + (String) param + '\'';
break;
case Types.BOOLEAN:
val = "" + param;
}
toStringSql = toStringSql.substring(0, index) + val +
((index == toStringSql.length() -1) ? "" : toStringSql.substring(index + 1));
index = toStringSql.indexOf('?', index + val.length());
count++;
}
}
catch (Exception e) {
Log.error(e);
}
return "CachedPreparedStatement{ sql=" + toStringSql + '}';
}
}
......@@ -141,7 +141,7 @@ public class ConnectionPool implements Runnable {
wrapper.checkedout = true;
wrapper.lockTime = System.currentTimeMillis();
}
return wrapper.getConnection();
return wrapper;
}
else {
synchronized (waitLock) {
......@@ -156,7 +156,7 @@ public class ConnectionPool implements Runnable {
wrapper.checkedout = true;
wrapper.lockTime = System.currentTimeMillis();
}
return wrapper.getConnection();
return wrapper;
}
else {
waitLock.wait();
......
/**
* $RCSfile$
* $Revision: $
* $Date: $
* $Revision$
* $Date$
*
* Copyright (C) 2007 Jive Software. All rights reserved.
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
......@@ -11,9 +11,6 @@
package org.jivesoftware.database;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.SQLException;
......@@ -24,34 +21,18 @@ import java.sql.SQLException;
*
* @author Jive Software
*/
public class ConnectionWrapper {
public class ConnectionWrapper extends AbstractConnection {
private static Method close;
private static Method metaData;
private static Method prepareStatement;
static {
try {
close = Connection.class.getMethod("close");
metaData = Connection.class.getMethod("getMetaData");
prepareStatement = Connection.class.getMethod("prepareStatement", String.class);
}
catch (NoSuchMethodException e) {
throw new NoSuchMethodError(e.getMessage());
}
}
ConnectionPool pool;
boolean checkedout = false;
long createTime;
long lockTime;
long checkinTime;
Exception exception;
boolean hasLoggedException = false;
private Connection poolConnection;
public ConnectionPool pool;
public boolean checkedout = false;
public long createTime;
public long lockTime;
public long checkinTime;
public Exception exception;
public boolean hasLoggedException = false;
public ConnectionWrapper(Connection connection, ConnectionPool pool) {
setConnection(connection);
super(connection);
this.pool = pool;
createTime = System.currentTimeMillis();
......@@ -60,24 +41,28 @@ public class ConnectionWrapper {
}
public void setConnection(Connection connection) {
if (connection == null) {
this.poolConnection = null;
}
else {
this.poolConnection = (Connection)java.lang.reflect.Proxy.newProxyInstance(
connection.getClass().getClassLoader(),
connection.getClass().getInterfaces(),
new ConnectionProxy(connection));
}
super.connection = connection;
}
public Connection getConnection() {
return poolConnection;
/**
* Instead of closing the underlying connection, we simply release
* it back into the pool.
*/
public void close() throws SQLException {
synchronized (this) {
checkedout = false;
checkinTime = System.currentTimeMillis();
}
pool.freeConnection();
// Release object references. Any further method calls on the connection will fail.
// super.connection = null;
}
public String toString() {
if (poolConnection != null) {
return poolConnection.toString();
if (connection != null) {
return connection.toString();
}
else {
return "Jive Software Connection Wrapper";
......@@ -87,55 +72,4 @@ public class ConnectionWrapper {
public synchronized boolean isCheckedOut() {
return checkedout;
}
/**
* Dynamic proxy for connection object that returns connection to the pool when
* closing.
*/
public class ConnectionProxy implements InvocationHandler {
private Connection connection;
public ConnectionProxy(Connection connection) {
this.connection = connection;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.equals(prepareStatement)) {
return connection.prepareStatement((String) args[0]);
} else if (method.equals(metaData)) {
return connection.getMetaData();
} else if (method.equals(close)) {
close();
return null;
} else {
// Invoke the method normally if all else fails.
try {
return method.invoke(connection, args);
}
catch (InvocationTargetException ite) {
throw ite.getCause();
}
}
}
/**
* Instead of closing the underlying connection, we simply release
* it back into the pool.
*
* @throws SQLException if an SQL Exception occurs.
*/
private void close() throws SQLException {
synchronized (this) {
checkedout = false;
checkinTime = System.currentTimeMillis();
}
pool.freeConnection();
// Release object references. Any further method calls on the connection will fail.
poolConnection = null;
connection = null;
}
}
}
\ No newline at end of file
}
......@@ -98,7 +98,7 @@ public class DbConnectionManager {
// See if profiling is enabled. If yes, wrap the connection with a
// profiled connection.
if (profilingEnabled) {
return (Connection)ProfiledConnection.newInstance(con);
return new ProfiledConnection(con);
}
else {
return con;
......
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.database;
/**
* Simple class for tracking profiling stats for individual SQL queries.
*
* @author Jive Software
*/
public class ProfiledConnectionEntry {
/**
* The SQL query.
*/
public String sql;
/**
* Number of times the query has been executed.
*/
public int count;
/**
* The total time spent executing the query (in milliseconds).
*/
public int totalTime;
public ProfiledConnectionEntry(String sql) {
this.sql = sql;
count = 0;
totalTime = 0;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment