1 21 22 package org.opensubsystems.core.persist.db.mysql; 23 24 import java.sql.Connection ; 25 import java.sql.PreparedStatement ; 26 import java.sql.ResultSet ; 27 import java.sql.SQLException ; 28 29 import org.opensubsystems.core.data.BasicDataObject; 30 import org.opensubsystems.core.data.DataObject; 31 import org.opensubsystems.core.data.ModifiableDataObject; 32 import org.opensubsystems.core.error.OSSDataCreateException; 33 import org.opensubsystems.core.error.OSSDataSaveException; 34 import org.opensubsystems.core.error.OSSDatabaseAccessException; 35 import org.opensubsystems.core.error.OSSException; 36 import org.opensubsystems.core.error.OSSInconsistentDataException; 37 import org.opensubsystems.core.persist.db.DatabaseDataUtils; 38 import org.opensubsystems.core.util.DatabaseUtils; 39 40 49 public final class MySQLDataUtils 50 { 51 57 public static class CachedInsertStatements 58 { 59 62 private boolean m_bIsInDomain; 63 64 67 private PreparedStatement m_selectID; 68 69 72 private PreparedStatement m_select; 73 74 79 public CachedInsertStatements( 80 boolean bIsInDomain, 81 PreparedStatement selectID, 82 PreparedStatement select 83 ) 84 { 85 super(); 86 87 m_bIsInDomain = bIsInDomain; 88 m_selectID = selectID; 89 m_select = select; 90 } 91 92 95 private PreparedStatement getSelectID() 96 { 97 return m_selectID; 98 } 99 100 103 private PreparedStatement getSelect() 104 { 105 return m_select; 106 } 107 108 111 public boolean isInDomain() 112 { 113 return m_bIsInDomain; 114 } 115 116 } 117 118 124 public static class CachedUpdateStatements 125 { 126 129 private boolean m_bIsInDomain; 130 131 134 private PreparedStatement m_select; 135 136 140 public CachedUpdateStatements( 141 boolean bIsInDomain, 142 PreparedStatement select 143 ) 144 { 145 super(); 146 147 m_bIsInDomain = bIsInDomain; 148 m_select = select; 149 } 150 151 154 public PreparedStatement getSelect() 155 { 156 return m_select; 157 } 158 159 162 public boolean isInDomain() 163 { 164 return m_bIsInDomain; 165 } 166 } 167 168 170 173 private MySQLDataUtils( 174 ) 175 { 176 } 178 179 181 196 public static void insertAndFetchGeneratedValues( 197 Connection dbConnection, 198 PreparedStatement insertStatement, 199 boolean bIsInDomain, 200 String strTableName, 201 BasicDataObject data 202 ) throws SQLException , 203 OSSException 204 { 205 CachedInsertStatements cache = null; 206 207 try 208 { 209 cache = cacheStatementsForInsert( 210 dbConnection, bIsInDomain, strTableName, 211 data instanceof ModifiableDataObject); 212 insertAndFetchGeneratedValues(insertStatement, cache, data); 213 } 214 finally 215 { 216 closeStatements(cache); 217 } 218 } 219 220 233 public static void insertAndFetchGeneratedValues( 234 PreparedStatement insertStatement, 235 CachedInsertStatements cache, 236 BasicDataObject data 237 ) throws OSSException, 238 SQLException 239 { 240 ResultSet rsResults = null; 241 int iGeneratedKey = DataObject.NEW_ID; 242 243 insertStatement.executeUpdate(); 244 245 try 246 { 247 248 try 251 { 252 rsResults = cache.getSelectID().executeQuery(); 253 if (rsResults.next()) 254 { 255 iGeneratedKey = rsResults.getInt(1); 256 } 257 else 258 { 259 throw new OSSDataCreateException( 260 "Cannot read the generated ID from the database."); 261 } 262 } 263 finally 264 { 265 DatabaseUtils.closeResultSet(rsResults); 266 } 267 268 if (iGeneratedKey != DataObject.NEW_ID) 269 { 270 PreparedStatement selectStatement = null; 271 272 try 273 { 274 275 selectStatement = cache.getSelect(); 276 selectStatement.clearParameters(); 277 selectStatement.setInt(1, iGeneratedKey); 278 if (cache.isInDomain()) 279 { 280 selectStatement.setInt(2, data.getDomainId()); 281 } 282 rsResults = selectStatement.executeQuery(); 283 if (rsResults.next()) 284 { 285 data.setId(iGeneratedKey); 286 data.setCreationTimestamp(rsResults.getTimestamp(1)); 287 if (data instanceof ModifiableDataObject) 288 { 289 ((ModifiableDataObject)data).setModificationTimestamp( 290 rsResults.getTimestamp(2)); 291 } 292 } 293 else 294 { 295 throw new OSSDataCreateException( 296 "Cannot read the generated creation and modification " + 297 "time from the database."); 298 } 299 } 300 finally 301 { 302 DatabaseUtils.closeResultSet(rsResults); 303 } 304 } 305 } 306 catch (SQLException eExc) 307 { 308 throw new OSSDataCreateException( 309 "Cannot read the generated creation and modification time" + 310 " from the database.", eExc); 311 } 312 } 313 314 326 public static CachedInsertStatements cacheStatementsForInsert( 327 Connection dbConnection, 328 boolean bIsInDomain, 329 String strTableName, 330 boolean bModifiable 331 ) throws OSSException 332 { 333 StringBuffer sbQueryID = new StringBuffer (); 334 StringBuffer sbQuery = new StringBuffer (); 335 CachedInsertStatements cache; 336 337 sbQueryID.append("select LAST_INSERT_ID() from "); 339 sbQueryID.append(strTableName); 340 341 sbQuery.append("select CREATION_DATE"); 342 if (bModifiable) 343 { 344 sbQuery.append(", MODIFICATION_DATE"); 345 } 346 sbQuery.append(" from "); 347 sbQuery.append(strTableName); 348 sbQuery.append(" where ID = ?"); 349 if (bIsInDomain) 350 { 351 sbQuery.append(" and DOMAIN_ID = ?"); 352 } 353 354 try 355 { 356 cache = new CachedInsertStatements( 357 bIsInDomain, 358 dbConnection.prepareStatement(sbQueryID.toString()), 359 dbConnection.prepareStatement(sbQuery.toString())); 360 } 361 catch (SQLException eExc) 362 { 363 throw new OSSDatabaseAccessException( 364 "Cannot create jdbc statements to access the database.", 365 eExc); 366 } 367 368 return cache; 369 } 370 371 376 public static void closeStatements( 377 CachedInsertStatements cache 378 ) 379 { 380 if (cache != null) 381 { 382 DatabaseUtils.closeStatement(cache.getSelectID()); 383 DatabaseUtils.closeStatement(cache.getSelect()); 384 } 385 } 386 387 403 public static void updatedAndFetchGeneratedValues( 404 String strDataName, 405 Connection dbConnection, 406 PreparedStatement updateStatement, 407 boolean bIsInDomain, 408 String strTableName, 409 ModifiableDataObject data 410 ) throws SQLException , 411 OSSException 412 { 413 CachedUpdateStatements cache = null; 414 415 try 416 { 417 int iUpdateCount; 418 419 iUpdateCount = updateStatement.executeUpdate(); 420 if (iUpdateCount == 0) 421 { 422 DatabaseDataUtils.checkUpdateError(dbConnection, strDataName, 423 strTableName, data.getId(), data.getModificationTimestamp()); 424 } 425 else if (iUpdateCount > 1) 426 { 427 throw new OSSInconsistentDataException( 428 "Inconsistent database contains multiple (" 429 + iUpdateCount + ") records with the same ID" 430 + " and modified at the same time"); 431 } 432 433 cache = MySQLDataUtils.cacheStatementsForUpdate(dbConnection, bIsInDomain, 434 strTableName); 435 MySQLDataUtils.fetchModifiedTimestamps(cache, data); 436 } 437 finally 438 { 439 MySQLDataUtils.closeStatements(cache); 440 } 441 } 442 443 451 public static void fetchModifiedTimestamps( 452 CachedUpdateStatements cache, 453 ModifiableDataObject data 454 ) throws OSSException 455 { 456 ResultSet rsResults = null; 457 PreparedStatement selectStatement = null; 458 459 try 460 { 461 selectStatement = cache.getSelect(); 462 selectStatement.setInt(1, data.getId()); 463 if (cache.isInDomain()) 464 { 465 selectStatement.setInt(2, data.getDomainId()); 466 } 467 rsResults = selectStatement.executeQuery(); 468 if (rsResults.next()) 469 { 470 data.setModificationTimestamp(rsResults.getTimestamp(1)); 471 } 472 else 473 { 474 throw new OSSDataSaveException("Cannot read the generated modification " + 475 "time from the database."); 476 477 } 478 } 479 catch (SQLException eExc) 480 { 481 throw new OSSDataSaveException( 482 "Cannot read the generated modification time" + 483 " from the database.", 484 eExc); 485 } 486 finally 487 { 488 DatabaseUtils.closeResultSet(rsResults); 489 } 490 } 491 492 503 public static CachedUpdateStatements cacheStatementsForUpdate( 504 Connection dbConnection, 505 boolean bIsInDomain, 506 String strTableName 507 ) throws OSSException 508 { 509 StringBuffer sbQuery = new StringBuffer (); 510 CachedUpdateStatements cache; 511 512 sbQuery.append("select MODIFICATION_DATE from "); 513 sbQuery.append(strTableName); 514 sbQuery.append(" where ID = ?"); 515 if (bIsInDomain) 516 { 517 sbQuery.append(" and DOMAIN_ID = ?"); 518 } 519 520 try 521 { 522 cache = new CachedUpdateStatements( 523 bIsInDomain, 524 dbConnection.prepareStatement(sbQuery.toString())); 525 } 526 catch (SQLException eExc) 527 { 528 throw new OSSDatabaseAccessException( 529 "Cannot create jdbc statements to access the database.", 530 eExc); 531 } 532 533 return cache; 534 } 535 536 541 public static void closeStatements( 542 CachedUpdateStatements cache 543 ) 544 { 545 if (cache != null) 546 { 547 DatabaseUtils.closeStatement(cache.getSelect()); 548 } 549 } 550 } 551 | Popular Tags |