Subject Patch: pooled prepared statements
Author Ken Richard
I have heard that pooled prepared statements are part of JDBC3.0 but
have not looked at the spec. Here is a patch that will implement
prepared statement pooling. The patch is against the 1.0 version of the
driver.

Pooling is off by default and enabled by calling
FBWrappingDataSource.setPreparedStatementPooling(true);


?
client-java/src/main/org/firebirdsql/jca/.FBManagedConnectionFactory.jav
a.marks
? client-java/src/main/org/firebirdsql/jdbc/.FBConnection.java.marks
Index: client-java/src/main/org/firebirdsql/jca/FBManagedConnection.java
===================================================================
RCS file:
/cvsroot/firebird/client-java/src/main/org/firebirdsql/jca/FBManagedConn
ection.java,v
retrieving revision 1.19
diff -r1.19 FBManagedConnection.java
29a30
> import java.util.HashMap;
53a55
> import org.firebirdsql.jdbc.FBCallableStatement;
54a57
> import org.firebirdsql.jdbc.FBPreparedStatement;
97a101,104
> private boolean poolPreparedStatements = false;
> private HashMap pooledCallableStatements = null;
> private HashMap pooledPreparedStatements = null;
>
336a344,361
> try {
> // close pooled statements if applicable
> if (pooledCallableStatements!=null) {
> Iterator it =
pooledCallableStatements.values().iterator();
> while (it.hasNext()) {
>
((FBCallableStatement)it.next()).destroy();
> }
> }
> // close pooled statements if applicable
> if (pooledPreparedStatements!=null) {
> Iterator it =
pooledPreparedStatements.values().iterator();
> while (it.hasNext()) {
>
((FBPreparedStatement)it.next()).destroy();
> }
> }
> } catch (SQLException ex) {
> if (log!=null) log.error("Error
cleaning up statements", ex);
> }
1238a1264,1320
>
> public void setPoolPreparedStatements(boolean
poolPreparedStatements)
> {
> this.poolPreparedStatements = poolPreparedStatements;
> }
>
> public boolean getPoolPreparedStatements() {
> return mcf.getPoolPreparedStatements();
> }
>
> public synchronized FBCallableStatement
getPooledCallableStatement(FBConnection connection, String sql) {
> if (pooledCallableStatements==null) {
> return null;
> }
> if (pooledCallableStatements.containsKey(sql)) {
> FBCallableStatement stmt =
(FBCallableStatement)pooledCallableStatements.get(sql);
> pooledCallableStatements.remove(stmt);
> if (stmt.isClosed()) {
> return null;
> }
> stmt.initializeFromPool(connection);
> return stmt;
> } else {
> return null;
> }
> }
>
> public synchronized FBPreparedStatement
getPooledPreparedStatement(FBConnection connection, String sql) {
> if (pooledPreparedStatements==null) {
> return null;
> }
> if (pooledPreparedStatements.containsKey(sql)) {
> FBPreparedStatement stmt =
(FBPreparedStatement)pooledPreparedStatements.get(sql);
> pooledPreparedStatements.remove(stmt);
> if (stmt.isClosed()) {
> return null;
> }
> stmt.initializeFromPool(connection);
> return stmt;
> } else {
> return null;
> }
> }
>
> public void releaseStatement(FBPreparedStatement stmt) {
> if (stmt instanceof FBCallableStatement) {
> if (pooledCallableStatements==null) {
> pooledCallableStatements = new
HashMap();
> }
>
pooledCallableStatements.put(stmt.getSQL(),stmt);
> } else {
> if (pooledPreparedStatements==null) {
> pooledPreparedStatements = new
HashMap();
> }
>
pooledPreparedStatements.put(stmt.getSQL(),stmt);
> }
> }
Index:
client-java/src/main/org/firebirdsql/jca/FBManagedConnectionFactory.java
===================================================================
RCS file:
/cvsroot/firebird/client-java/src/main/org/firebirdsql/jca/FBManagedConn
ectionFactory.java,v
retrieving revision 1.19
diff -r1.19 FBManagedConnectionFactory.java
139c139,141
<
---
>
> private boolean poolPreparedStatements = false;
>
145,146c147,148
<
<
---
>
>
285a288,296
>
> public void setPoolPreparedStatements(boolean
poolPreparedStatements)
> {
> this.poolPreparedStatements = poolPreparedStatements;
> }
>
> public boolean getPoolPreparedStatements() {
> return poolPreparedStatements;
> }
287c298
<
---
>
Index:
client-java/src/main/org/firebirdsql/jca/FBPoolingConnectionManager.java
===================================================================
RCS file:
/cvsroot/firebird/client-java/src/main/org/firebirdsql/jca/FBPoolingConn
ectionManager.java,v
retrieving revision 1.2
diff -r1.2 FBPoolingConnectionManager.java
50c50,51
<
---
>
> private boolean preparedStatementPooling = false;
Index:
client-java/src/main/org/firebirdsql/jdbc/FBCallableStatement.java
===================================================================
RCS file:
/cvsroot/firebird/client-java/src/main/org/firebirdsql/jdbc/FBCallableSt
atement.java,v
retrieving revision 1.3
diff -r1.3 FBCallableStatement.java
136c136
<
---
>
Index: client-java/src/main/org/firebirdsql/jdbc/FBConnection.java
===================================================================
RCS file:
/cvsroot/firebird/client-java/src/main/org/firebirdsql/jdbc/FBConnection
.java,v
retrieving revision 1.19
diff -r1.19 FBConnection.java
79c79
<
---
>
243,244c243,250
< PreparedStatement stmt = new FBPreparedStatement(this, sql);
< activeStatements.add(stmt);
---
> PreparedStatement stmt = null;
> if (mc.getPoolPreparedStatements()) {
> stmt = mc.getPooledPreparedStatement(this,sql);
> }
> if (stmt==null) {
> stmt = new FBPreparedStatement(this, sql);
> activeStatements.add(stmt);
> }
341,343c347,355
< CallableStatement stmt = new FBCallableStatement(this, sql);
< activeStatements.add(stmt);
< return stmt;
---
> CallableStatement stmt = null;
> if (mc.getPoolPreparedStatements()) {
> stmt = mc.getPooledCallableStatement(this,
sql);
> }
> if(stmt==null) {
> stmt = new FBCallableStatement(this, sql);
> activeStatements.add(stmt);
> }
> return stmt;
1233a1246,1253
>
> public boolean getPoolPreparedStatements() {
> return mc==null ? false :
mc.getPoolPreparedStatements();
> }
>
> public void releaseStatement(FBPreparedStatement stmt) {
> mc.releaseStatement(stmt);
> }
Index:
client-java/src/main/org/firebirdsql/jdbc/FBPreparedStatement.java
===================================================================
RCS file:
/cvsroot/firebird/client-java/src/main/org/firebirdsql/jdbc/FBPreparedSt
atement.java,v
retrieving revision 1.19
diff -r1.19 FBPreparedStatement.java
72a73,74
>
> String sql = null;
75a78
> this.sql = sql;
145a149,168
>
> public void close() throws SQLException {
> if (c.getPoolPreparedStatements()) {
> c.releaseStatement(this);
> } else {
> destroy();
> }
> }
>
>
> public void initializeFromPool(FBConnection connection) {
> this.c = connection;
> }
>
>
>
> public String getSQL() {
> return sql;
> }
>
Index: client-java/src/main/org/firebirdsql/jdbc/FBStatement.java
===================================================================
RCS file:
/cvsroot/firebird/client-java/src/main/org/firebirdsql/jdbc/FBStatement.
java,v
retrieving revision 1.14
diff -r1.14 FBStatement.java
210a211,215
> destroy();
> }
>
>
> public void destroy() throws SQLException {
243c248
< boolean isClosed() {
---
> public boolean isClosed() {
958a964
>
Index:
client-java/src/main/org/firebirdsql/jdbc/FBWrappingDataSource.java
===================================================================
RCS file:
/cvsroot/firebird/client-java/src/main/org/firebirdsql/jdbc/FBWrappingDa
taSource.java,v
retrieving revision 1.3
diff -r1.3 FBWrappingDataSource.java
72c72
<
---
>
77a78,87
> public void setPreparedStatementPooling(boolean
poolPreparedStatements)
> {
> mcf.setPoolPreparedStatements(poolPreparedStatements);
> }
>
> public boolean getPreparedStatementPooling()
> {
> return mcf.getPoolPreparedStatements();
> }
>
182c192
< ds = (FBDataSource)mcf.createConnectionFactory(cm);
---
> ds =
(FBDataSource)mcf.createConnectionFactory(cm);