1 22 package org.enhydra.jdbc.standard; 23 24 import java.sql.CallableStatement ; 25 import java.sql.PreparedStatement ; 26 import java.sql.SQLException ; 27 import java.util.Enumeration ; 28 import java.util.Hashtable ; 29 import java.sql.Connection ; 30 import org.enhydra.jdbc.core.CoreConnection; 31 import org.enhydra.jdbc.util.LRUCache; 32 33 43 public class StandardConnectionHandle extends CoreConnection { 44 45 StandardPooledConnection pooledCon; 46 protected Hashtable masterPrepStmtCache; 48 int preparedStmtCacheSize; protected LRUCache preparedStatementCache = null; 51 public Hashtable inUse; private boolean closed; public boolean isReallyUsed = false; 55 56 59 public StandardConnectionHandle( 60 StandardPooledConnection pooledCon, 61 Hashtable preparedStatementCache, 62 int preparedStmtCacheSize) { 63 super(pooledCon.getPhysicalConnection()); this.pooledCon = pooledCon; masterPrepStmtCache = preparedStatementCache; 66 this.preparedStmtCacheSize = preparedStmtCacheSize; 67 log = pooledCon.dataSource.log; 68 setupPreparedStatementCache(); 69 inUse = new Hashtable (10, 0.5f); 70 71 log.debug( 72 "StandardConnectionHandle:new StandardConnectionHandle with " 73 + preparedStmtCacheSize 74 + " prepared statement"); 75 } 76 77 protected void setupPreparedStatementCache() { 78 log.debug("StandardConnectionHandle:setupPreparedStatementCache start"); 79 if (preparedStmtCacheSize == 0) { 80 log.debug( 81 "StandardConnectionHandle:setupPreparedStatementCache return with 0"); 82 preparedStatementCache = null; 83 return; 84 } 85 if (con == null) 86 log.warn("Connection is null"); 87 else { 88 preparedStatementCache = 89 (LRUCache) masterPrepStmtCache.get(con.toString()); 90 if (preparedStatementCache == null) { 91 preparedStatementCache = 92 new PreparedStatementCache(preparedStmtCacheSize); 93 preparedStatementCache.setLogger(log); 94 masterPrepStmtCache.put(con.toString(), preparedStatementCache); 95 log.debug( 96 "StandardConnectionHandle:setupPreparedStatementCache " 97 + "preparedStatementCache.size(lru)='" 98 + preparedStatementCache.LRUSize() 99 + "' " 100 + "preparedStatementCache.size(cache)='" 101 + preparedStatementCache.cacheSize() 102 + "' " 103 + "masterPrepStmtCache.size='" 104 + masterPrepStmtCache.size() 105 + "' "); 106 } else preparedStatementCache.setLogger(log); 107 } 108 log.debug("StandardConnectionHandle:setupPreparedStatementCache end"); 109 } 110 111 115 public void preInvoke() throws SQLException { 116 if (closed) 117 throw new SQLException ("Connection is closed"); 118 } 119 120 123 public void catchInvoke(SQLException e) throws SQLException { 124 throw (e); } 128 129 134 synchronized public void close() throws SQLException { 135 log.debug("StandardConnectionHandle:close"); 136 closed = true; Enumeration keys = inUse.keys(); while (keys.hasMoreElements()) { Object key = keys.nextElement(); returnToCache(key); } 143 pooledCon.closeEvent(); 145 if (preparedStatementCache != null) 146 preparedStatementCache.cleanupAll(); 147 if ((preparedStatementCache != null) && (masterPrepStmtCache != null) && (log != null)) 148 log.debug( 149 "StandardConnectionHandle:close " 150 + "preparedStatementCache.size(lru)='" 151 + preparedStatementCache.LRUSize() 152 + "' " 153 + "preparedStatementCache.size(cache)='" 154 + preparedStatementCache.cacheSize() 155 + "' " 156 + "masterPrepStmtCache.size='" 157 + masterPrepStmtCache.size() 158 + "' "); 159 } 160 161 165 void returnToCache(Object key, Connection theCon) { 166 Object value = inUse.remove(key); 167 if (value != null) { 169 LRUCache theCache = 170 (LRUCache) masterPrepStmtCache.get(theCon.toString()); 171 theCache.put(key, value); } 173 } 174 175 void returnToCache(Object key) { 176 returnToCache(key, con); 177 } 178 179 190 synchronized PreparedStatement checkPreparedCache( 191 String sql, 192 int type, 193 int concurrency, 194 int holdability) 195 throws SQLException { 196 log.debug( 197 "StandardConnectionHandle:checkPreparedCache sql='" + sql + "'"); 198 PreparedStatement ret = null; String lookupKey = sql + type + concurrency; 203 if (preparedStatementCache != null) { 205 Object obj = preparedStatementCache.get(lookupKey); 206 if (obj != null) { ret = (PreparedStatement ) obj; try { 210 ret.clearParameters(); } catch (SQLException e) { 212 ret = createPreparedStatement(sql, type, concurrency, holdability); 214 } 215 216 preparedStatementCache.remove(lookupKey); 217 inUse.put(lookupKey, ret); 219 } else { ret = createPreparedStatement(sql, type, concurrency, holdability); 222 inUse.put(lookupKey, ret); 223 } 225 } else { 226 ret = createPreparedStatement(sql, type, concurrency, holdability); 227 } 228 232 ret = new StandardPreparedStatement(this, ret, lookupKey); 233 return ret; 234 } 235 236 237 synchronized PreparedStatement checkPreparedCache( 238 String sql, 239 int autogeneratedkeys) 240 throws SQLException { 241 log.debug( 242 "StandardConnectionHandle:checkPreparedCache sql='" + sql + "'"); 243 PreparedStatement ret = null; String lookupKey = sql + autogeneratedkeys; 248 if (preparedStatementCache != null) { 250 Object obj = preparedStatementCache.get(lookupKey); 251 if (obj != null) { ret = (PreparedStatement ) obj; try { 255 ret.clearParameters(); } catch (SQLException e) { 257 ret = createPreparedStatement(sql, autogeneratedkeys); 259 } 260 261 preparedStatementCache.remove(lookupKey); 262 inUse.put(lookupKey, ret); 264 } else { ret = createPreparedStatement(sql, autogeneratedkeys); 267 inUse.put(lookupKey, ret); 268 } 270 } else { 271 ret = createPreparedStatement(sql, autogeneratedkeys); 272 } 273 277 ret = new StandardPreparedStatement(this, ret, lookupKey); 278 return ret; 279 } 280 281 282 283 protected PreparedStatement createPreparedStatement( 284 String sql, 285 int type, 286 int concurrency, 287 int holdability) 288 throws SQLException { 289 log.debug( 290 "StandardConnectionHandle:createPreparedStatement type ='" 291 + type 292 + "'"); 293 if (type == 0 && holdability == 0) { return con.prepareStatement(sql); } else if (holdability == 0) { 296 return con.prepareStatement(sql, type, concurrency); 297 } else return con.prepareStatement(sql, type, concurrency, holdability); 299 } 300 301 302 protected PreparedStatement createPreparedStatement( 303 String sql, 304 int autogeneratedkeys) 305 throws SQLException { 306 log.debug( 307 "StandardConnectionHandle:createPreparedStatement autogeneratedkeys ='" 308 + autogeneratedkeys 309 + "'"); 310 return con.prepareStatement(sql, autogeneratedkeys); } 312 313 317 public PreparedStatement prepareStatement(String sql) throws SQLException { 318 log.debug( 319 "StandardConnectionHandle:prepareStatement sql='" + sql + "'"); 320 preInvoke(); 321 try { 322 return checkPreparedCache(sql, 0, 0, 0); 323 } catch (SQLException e) { 324 catchInvoke(e); 325 } 326 return null; 327 } 328 329 333 public PreparedStatement prepareStatement( 334 String sql, 335 int resultSetType, 336 int resultSetConcurrency) 337 throws SQLException { 338 preInvoke(); 339 try { 340 return checkPreparedCache(sql, resultSetType, resultSetConcurrency, 0); 341 } catch (SQLException e) { 342 catchInvoke(e); 343 } 344 return null; 345 } 346 347 public PreparedStatement prepareStatement( 348 String sql, 349 int resultSetType, 350 int resultSetConcurrency, 351 int resultSetHoldability) 352 throws SQLException { 353 preInvoke(); 354 try { 355 return checkPreparedCache(sql, resultSetType, resultSetConcurrency, resultSetHoldability); 356 } catch (SQLException e) { 357 catchInvoke(e); 358 } 359 return null; 360 } 361 362 public boolean isClosed() throws SQLException { 363 return closed; 364 } 365 366 public CallableStatement prepareCall( 367 String sql, 368 int resultSetType, 369 int resultSetConcurrency) 370 throws SQLException { 371 preInvoke(); 372 try { 373 return con.prepareCall(sql, resultSetType, resultSetConcurrency); 374 } catch (SQLException e) { 375 catchInvoke(e); 376 } 377 return null; 378 } 379 } 380 | Popular Tags |