1 10 11 package com.triactive.jdo.store; 12 13 import com.triactive.jdo.PersistenceManager; 14 import com.triactive.jdo.StateManager; 15 import java.sql.Connection ; 16 import java.sql.PreparedStatement ; 17 import java.sql.ResultSet ; 18 import java.sql.SQLException ; 19 import java.util.ArrayList ; 20 import java.util.Collection ; 21 import java.util.Iterator ; 22 import java.util.Set ; 23 import javax.jdo.JDODataStoreException; 24 import javax.jdo.JDOHelper; 25 import javax.jdo.JDOUserException; 26 import org.apache.log4j.Category; 27 28 29 abstract class AbstractSetStore implements SetStore 30 { 31 private static final Category LOG = Category.getInstance(AbstractSetStore.class); 32 33 protected Table setTable; 34 protected String setName; 35 protected StoreManager storeMgr; 36 protected DatabaseAdapter dba; 37 protected ColumnMapping ownerMapping; 38 protected ColumnMapping elementMapping; 39 protected Column ownerColumn; 40 protected Column elementColumn; 41 protected Class elementType; 42 protected boolean elementsAreEmbedded; 43 protected String loadStmt; 44 protected String sizeStmt; 45 protected String containsStmt; 46 protected String addStmt; 47 protected String removeStmt; 48 protected String clearStmt; 49 protected int[] prefetchFieldNumbers; 50 protected ColumnMapping[] prefetchFieldMappings; 51 52 53 protected AbstractSetStore() 54 { 55 } 56 57 58 public StoreManager getStoreManager() 59 { 60 return storeMgr; 61 } 62 63 public Class getElementType() 64 { 65 return elementType; 66 } 67 68 public boolean allowsNulls() 69 { 70 return elementColumn.isNullable(); 71 } 72 73 public Query.ResultObjectFactory newResultObjectFactory(StateManager sm, QueryStatement stmt) 74 { 75 PersistenceManager pm = sm.getPersistenceManager(); 76 77 if (stmt.getDistinctResults() || prefetchFieldMappings == null) 78 return new PersistentIDROF(pm, elementType); 79 else 80 { 81 int[] columnNumbersByField = new int[prefetchFieldMappings.length]; 82 83 for (int i = 0; i < prefetchFieldMappings.length; ++i) 84 { 85 ColumnMapping m = prefetchFieldMappings[i]; 86 87 if (m != null) 88 columnNumbersByField[i] = stmt.select(m.getColumn()); 89 } 90 91 return new PersistentIDROF(pm, 92 elementType, 93 prefetchFieldNumbers, 94 prefetchFieldMappings, 95 columnNumbersByField); 96 } 97 } 98 99 100 public QueryStatement getExistsSubquery(QueryStatement.QueryColumn ownerIDColumn, 101 SQLIdentifier setRangeVar) 102 { 103 QueryStatement stmt = dba.newQueryStatement(setTable, setRangeVar); 104 105 SQLExpression ownerExpr = new ObjectExpression(stmt, ownerIDColumn); 106 SQLExpression ownerInSetExpr = new ObjectExpression(stmt, stmt.getColumn(setRangeVar, ownerColumn)); 107 108 stmt.andCondition(ownerExpr.eq(ownerInSetExpr)); 109 110 stmt.select(setRangeVar, elementColumn); 111 112 return stmt; 113 } 114 115 116 protected boolean validateElementForReading(StateManager sm, Object element) 117 { 118 if (!elementsAreEmbedded) 119 { 120 PersistenceManager pm = sm.getPersistenceManager(); 121 122 if (!JDOHelper.isPersistent(element) || pm != JDOHelper.getPersistenceManager(element)) 123 return false; 124 } 125 126 return true; 127 } 128 129 130 protected void validateElementForWriting(StateManager sm, Object element) 131 { 132 if (!elementsAreEmbedded) 133 { 134 PersistenceManager pm = sm.getPersistenceManager(); 135 136 if (!JDOHelper.isPersistent(element)) 137 pm.makePersistent(element); 138 else if (pm != JDOHelper.getPersistenceManager(element)) 139 throw new JDOUserException("Can't write element from a different persistence manager", JDOHelper.getObjectId(element)); 140 } 141 } 142 143 144 public Collection load(StateManager sm) 145 { 146 ArrayList contents = new ArrayList (); 147 PersistenceManager pm = sm.getPersistenceManager(); 148 149 try 150 { 151 Connection conn = pm.getConnection(false); 152 153 try 154 { 155 PreparedStatement ps = conn.prepareStatement(loadStmt); 156 157 try 158 { 159 ownerMapping.setObject(pm, ps, 1, sm.getObject()); 160 161 long startTime = System.currentTimeMillis(); 162 163 ResultSet rs = ps.executeQuery(); 164 165 try 166 { 167 if (LOG.isDebugEnabled()) 168 LOG.debug("Time = " + (System.currentTimeMillis() - startTime) + " ms: " + loadStmt); 169 170 while (rs.next()) 171 contents.add(elementMapping.getObject(pm, rs, 1)); 172 } 173 finally 174 { 175 rs.close(); 176 } 177 } 178 finally 179 { 180 ps.close(); 181 } 182 } 183 finally 184 { 185 pm.releaseConnection(conn); 186 } 187 } 188 catch (SQLException e) 189 { 190 throw dba.newDataStoreException("Load request failed: " + loadStmt, e); 191 } 192 193 return contents; 194 } 195 196 197 public int size(StateManager sm) 198 { 199 int numRows; 200 PersistenceManager pm = sm.getPersistenceManager(); 201 202 try 203 { 204 Connection conn = pm.getConnection(false); 205 206 try 207 { 208 PreparedStatement ps = conn.prepareStatement(sizeStmt); 209 210 try 211 { 212 ownerMapping.setObject(pm, ps, 1, sm.getObject()); 213 214 long startTime = System.currentTimeMillis(); 215 216 ResultSet rs = ps.executeQuery(); 217 218 try 219 { 220 if (LOG.isDebugEnabled()) 221 LOG.debug("Time = " + (System.currentTimeMillis() - startTime) + " ms: " + sizeStmt); 222 223 if (!rs.next()) 224 throw new JDODataStoreException("Size request returned no result row: " + sizeStmt); 225 226 numRows = rs.getInt(1); 227 228 storeMgr.logSQLWarnings(rs); 229 } 230 finally 231 { 232 rs.close(); 233 } 234 } 235 finally 236 { 237 ps.close(); 238 } 239 } 240 finally 241 { 242 pm.releaseConnection(conn); 243 } 244 } 245 catch (SQLException e) 246 { 247 throw dba.newDataStoreException("Size request failed: " + sizeStmt, e); 248 } 249 250 return numRows; 251 } 252 253 254 public boolean isEmpty(StateManager sm) 255 { 256 257 return size(sm) == 0; 258 } 259 260 261 public boolean contains(StateManager sm, Object element) 262 { 263 if (!validateElementForReading(sm, element)) 264 return false; 265 266 boolean retval; 267 PersistenceManager pm = sm.getPersistenceManager(); 268 269 try 270 { 271 Connection conn = pm.getConnection(false); 272 273 try 274 { 275 PreparedStatement ps = conn.prepareStatement(containsStmt); 276 277 try 278 { 279 ownerMapping.setObject(pm, ps, 1, sm.getObject()); 280 elementMapping.setObject(pm, ps, 2, element); 281 282 long startTime = System.currentTimeMillis(); 283 284 ResultSet rs = ps.executeQuery(); 285 286 try 287 { 288 if (LOG.isDebugEnabled()) 289 LOG.debug("Time = " + (System.currentTimeMillis() - startTime) + " ms: " + containsStmt); 290 291 retval = rs.next(); 292 293 storeMgr.logSQLWarnings(rs); 294 } 295 finally 296 { 297 rs.close(); 298 } 299 } 300 finally 301 { 302 ps.close(); 303 } 304 } 305 finally 306 { 307 pm.releaseConnection(conn); 308 } 309 } 310 catch (SQLException e) 311 { 312 throw dba.newDataStoreException("Request failed to check if set contains an element: " + containsStmt, e); 313 } 314 315 return retval; 316 } 317 318 319 public boolean add(StateManager sm, Object element) 320 { 321 validateElementForWriting(sm, element); 322 323 boolean modified = false; 324 PersistenceManager pm = sm.getPersistenceManager(); 325 326 try 327 { 328 Connection conn = pm.getConnection(true); 329 330 try 331 { 332 PreparedStatement ps = conn.prepareStatement(addStmt); 333 334 try 335 { 336 ownerMapping.setObject(pm, ps, 1, sm.getObject()); 337 elementMapping.setObject(pm, ps, 2, element); 338 339 long startTime = System.currentTimeMillis(); 340 341 ps.executeUpdate(); 342 343 if (LOG.isDebugEnabled()) 344 LOG.debug("Time = " + (System.currentTimeMillis() - startTime) + " ms: " + addStmt); 345 346 modified = true; 347 } 348 finally 349 { 350 ps.close(); 351 } 352 } 353 finally 354 { 355 pm.releaseConnection(conn); 356 } 357 } 358 catch (SQLException e) 359 { 360 if (!contains(sm, element)) 361 throw dba.newDataStoreException("Add request failed: " + addStmt, e); 362 } 363 364 return modified; 365 } 366 367 368 public boolean addAll(StateManager sm, Collection elements) 369 { 370 boolean modified = false; 371 Iterator i = elements.iterator(); 372 373 while (i.hasNext()) 374 { 375 if (add(sm, i.next())) 376 modified = true; 377 } 378 379 return modified; 380 } 381 382 383 public boolean remove(StateManager sm, Object element) 384 { 385 if (!validateElementForReading(sm, element)) 386 return false; 387 388 boolean modified = false; 389 PersistenceManager pm = sm.getPersistenceManager(); 390 391 try 392 { 393 Connection conn = pm.getConnection(true); 394 395 try 396 { 397 PreparedStatement ps = conn.prepareStatement(removeStmt); 398 399 try 400 { 401 ownerMapping.setObject(pm, ps, 1, sm.getObject()); 402 elementMapping.setObject(pm, ps, 2, element); 403 404 long startTime = System.currentTimeMillis(); 405 406 int rowsDeleted = ps.executeUpdate(); 407 408 if (LOG.isDebugEnabled()) 409 LOG.debug("Time = " + (System.currentTimeMillis() - startTime) + " ms: " + removeStmt); 410 411 modified = rowsDeleted == 1; 412 } 413 finally 414 { 415 ps.close(); 416 } 417 } 418 finally 419 { 420 pm.releaseConnection(conn); 421 } 422 } 423 catch (SQLException e) 424 { 425 if (contains(sm, element)) 426 throw dba.newDataStoreException("Remove request failed: " + removeStmt, e); 427 } 428 429 return modified; 430 } 431 432 433 public void clear(StateManager sm) 434 { 435 PersistenceManager pm = sm.getPersistenceManager(); 436 437 try 438 { 439 Connection conn = pm.getConnection(true); 440 441 try 442 { 443 PreparedStatement ps = conn.prepareStatement(clearStmt); 444 445 try 446 { 447 ownerMapping.setObject(pm, ps, 1, sm.getObject()); 448 449 long startTime = System.currentTimeMillis(); 450 451 ps.executeUpdate(); 452 453 if (LOG.isDebugEnabled()) 454 LOG.debug("Time = " + (System.currentTimeMillis() - startTime) + " ms: " + clearStmt); 455 } 456 finally 457 { 458 ps.close(); 459 } 460 } 461 finally 462 { 463 pm.releaseConnection(conn); 464 } 465 } 466 catch (SQLException e) 467 { 468 throw dba.newDataStoreException("Clear request failed: " + clearStmt, e); 469 } 470 } 471 } 472 | Popular Tags |