1 21 22 package org.opensubsystems.core.persist.db; 23 24 import java.sql.Connection ; 25 import java.sql.ResultSet ; 26 import java.sql.SQLException ; 27 import java.util.logging.Level ; 28 import java.util.logging.Logger ; 29 30 import org.opensubsystems.core.error.OSSConfigException; 31 import org.opensubsystems.core.error.OSSDatabaseAccessException; 32 import org.opensubsystems.core.error.OSSException; 33 import org.opensubsystems.core.persist.db.db2.DB2DatabaseImpl; 34 import org.opensubsystems.core.persist.db.hsqldb.HsqlDBDatabaseImpl; 35 import org.opensubsystems.core.persist.db.maxdb.MaxDBDatabaseImpl; 36 import org.opensubsystems.core.persist.db.mssql.MSSQLDatabaseImpl; 37 import org.opensubsystems.core.persist.db.mysql.MySQLDatabaseImpl; 38 import org.opensubsystems.core.persist.db.oracle.OracleDatabaseImpl; 39 import org.opensubsystems.core.persist.db.postgresql.PostgreSQLDatabaseImpl; 40 import org.opensubsystems.core.persist.db.sapdb.SapDBDatabaseImpl; 41 import org.opensubsystems.core.persist.db.sybase.SybaseDatabaseImpl; 42 import org.opensubsystems.core.util.GlobalConstants; 43 import org.opensubsystems.core.util.Log; 44 45 59 public abstract class DatabaseImpl implements Database 60 { 61 63 68 public static final int MAX_SAFE_LENGTH = 1000; 69 70 73 private static final String DATABASEIMPL_LOCK = "DATABASEIMPL_LOCK"; 74 75 78 private static final String HSQLDB_DRIVER_IDENTIFIER = ".hsqldb."; 79 80 83 private static final String SAPDB_DRIVER_IDENTIFIER = ".sap."; 84 85 88 private static final String MAXDB_DRIVER_IDENTIFIER = ".maxdb."; 89 90 93 private static final String POSTGRESQL_DRIVER_IDENTIFIER = ".postgresql."; 94 95 98 private static final String MYSQL_DRIVER_IDENTIFIER = ".mysql."; 99 100 104 private static final String MSSQL_DRIVER_IDENTIFIER = ".sqlserver."; 105 106 109 private static final String DB2_DRIVER_IDENTIFIER = ".db2."; 110 111 114 private static final String SYBASE_DRIVER_IDENTIFIER = ".sybase."; 115 116 119 private static final String ORACLE_DRIVER_IDENTIFIER = "oracle."; 120 121 125 private static final String ORACLE_OCI_DRIVER_IDENTIFIER = ".oci."; 126 127 131 private static final String JTDS_DRIVER_IDENTIFIER = ".jtds."; 132 133 137 private static final String INET_DRIVER_IDENTIFIER = ".inet."; 138 139 143 private static final String JNETDIRECT_DRIVER_IDENTIFIER = ".jnetdirect."; 144 145 148 private static final String MSSQL_URL_IDENTIFIER = ":sqlserver:"; 149 150 153 private static final String SYBASE_URL_IDENTIFIER = ":sybase:"; 154 155 157 160 private static Logger s_logger = Log.getInstance(DatabaseImpl.class); 161 162 165 private static Database s_dbDefaultDatabase = null; 166 167 169 172 protected boolean m_bDatabaseSchemaInitialized; 173 174 177 protected boolean m_bDatabaseStartInProgress; 178 179 182 protected boolean m_bDatabaseStarted; 183 184 188 protected VersionedDatabaseSchema m_vdsSchema; 189 190 192 198 protected DatabaseImpl( 199 ) throws OSSException 200 { 201 m_vdsSchema = null; 204 m_bDatabaseSchemaInitialized = false; 205 m_bDatabaseStartInProgress = false; 206 m_bDatabaseStarted = false; 207 } 208 209 211 217 public static Database getInstance( 218 ) throws OSSException 219 { 220 if (s_dbDefaultDatabase == null) 221 { 222 synchronized (DATABASEIMPL_LOCK) 225 { 226 if (s_dbDefaultDatabase == null) 228 { 229 String strDriver; 230 String strURL; 231 DatabaseConnectionFactory dcfFactory; 232 233 try 234 { 235 dcfFactory = DatabaseConnectionFactoryImpl.getInstance(); 236 } 237 catch (OSSDatabaseAccessException bfeExc) 238 { 239 throw new OSSDatabaseAccessException("Cannot create connection factory.", 240 bfeExc); 241 } 242 strDriver = dcfFactory.getRealDatabaseDriver(); 243 strURL = dcfFactory.getDatabaseURL(); 244 if (strDriver == null || strURL == null) 245 { 246 dcfFactory.loadDefaultDatabaseProperties(); 249 strDriver = dcfFactory.getRealDatabaseDriver(); 250 strURL = dcfFactory.getDatabaseURL(); 251 } 252 if (strDriver != null) 253 { 254 strDriver = strDriver.toLowerCase(); 255 if (strDriver.indexOf(HSQLDB_DRIVER_IDENTIFIER) != -1) 259 { 260 setInstance(new HsqlDBDatabaseImpl()); 261 } 262 else if (strDriver.indexOf(SAPDB_DRIVER_IDENTIFIER) != -1) 263 { 264 setInstance(new SapDBDatabaseImpl()); 265 } 266 else if (strDriver.indexOf(MAXDB_DRIVER_IDENTIFIER) != -1) 267 { 268 setInstance(new MaxDBDatabaseImpl()); 269 } 270 else if (strDriver.indexOf(POSTGRESQL_DRIVER_IDENTIFIER) != -1) 271 { 272 setInstance(new PostgreSQLDatabaseImpl()); 273 } 274 else if (strDriver.indexOf(MYSQL_DRIVER_IDENTIFIER) != -1) 275 { 276 setInstance(new MySQLDatabaseImpl()); 277 } 278 else if (strDriver.indexOf(MSSQL_DRIVER_IDENTIFIER) != -1 279 || strDriver.indexOf(INET_DRIVER_IDENTIFIER) != -1 280 || strDriver.indexOf(JNETDIRECT_DRIVER_IDENTIFIER) != -1) 281 { 282 setInstance(new MSSQLDatabaseImpl()); 283 } 284 else if (strDriver.indexOf(DB2_DRIVER_IDENTIFIER) != -1) 285 { 286 setInstance(new DB2DatabaseImpl()); 287 } 288 else if (strDriver.indexOf(SYBASE_DRIVER_IDENTIFIER) != -1) 289 { 290 setInstance(new SybaseDatabaseImpl()); 291 } 292 else if (strDriver.indexOf(ORACLE_DRIVER_IDENTIFIER) != -1 293 || strDriver.indexOf(ORACLE_OCI_DRIVER_IDENTIFIER) != -1) 294 { 295 setInstance(new OracleDatabaseImpl()); 296 } 297 else if (strDriver.indexOf(JTDS_DRIVER_IDENTIFIER) != -1) 298 { 299 if (strURL.indexOf(MSSQL_URL_IDENTIFIER) != -1) 300 { 301 setInstance(new MSSQLDatabaseImpl()); 302 } 303 else if (strURL.indexOf(SYBASE_URL_IDENTIFIER) != -1) 304 { 305 setInstance(new SybaseDatabaseImpl()); 306 } 307 else 308 { 309 throw new OSSConfigException("Unsupported URL '" + strURL + 310 "' for JDBC driver: " + strDriver); 311 } 312 } 313 else 314 { 315 throw new OSSConfigException("Unsupported JDBC driver: " + strDriver); 316 } 317 } 318 else 319 { 320 throw new OSSConfigException("Cannot determine what JDBC driver to use."); 321 } 322 } 323 } 324 } 325 326 return s_dbDefaultDatabase; 327 } 328 329 335 public static Database getInstanceIfStarted( 336 ) throws OSSException 337 { 338 return ((s_dbDefaultDatabase != null) && (s_dbDefaultDatabase.isStarted())) 339 ? s_dbDefaultDatabase : null; 340 } 341 342 349 public static void setInstance( 350 Database dbDatabase 351 ) 352 { 353 if (GlobalConstants.ERROR_CHECKING) 354 { 355 assert dbDatabase != null : "Default database instance cannot be null"; 356 } 357 358 synchronized (DATABASEIMPL_LOCK) 359 { 360 s_dbDefaultDatabase = dbDatabase; 361 s_logger.fine("Default database is " 362 + s_dbDefaultDatabase.getClass().getName()); 363 } 364 } 365 366 368 371 public void start( 372 ) throws OSSException 373 { 374 376 try 377 { 378 if ((!m_bDatabaseStarted) || (!m_bDatabaseSchemaInitialized)) 379 { 380 m_bDatabaseStartInProgress = true; 381 382 Connection cntDBConnection = null; 383 384 try 385 { 386 try 387 { 388 startDatabaseServer(); 389 } 390 catch (OSSException bfeExc) 391 { 392 s_logger.log(Level.WARNING, 393 "Cannot start database server, trying to create.", 394 bfeExc); 395 try 396 { 397 createDatabaseInstance(); 398 } 399 catch (OSSException bfeExc1) 400 { 401 s_logger.log(Level.SEVERE, 402 "Error while creating database instance.", 403 bfeExc1); 404 } 405 } 406 try 409 { 410 cntDBConnection 412 = DatabaseConnectionFactoryImpl.getInstance().requestConnection(false); 413 } 414 catch (OSSDatabaseAccessException dceExc) 415 { 416 Connection cntAdminDBConnection = null; 417 418 421 try 422 { 423 cntAdminDBConnection = getAdminConnection(false); 427 428 s_logger.log(Level.FINER, 429 "Database exists or was just created."); 430 431 createUser(cntAdminDBConnection); 433 } 434 finally 435 { 436 DatabaseConnectionFactoryImpl.getInstance().returnConnection( 438 cntAdminDBConnection); 439 } 440 441 DatabaseConnectionFactoryImpl.getInstance().stop(); 447 450 cntDBConnection 454 = DatabaseConnectionFactoryImpl.getInstance().requestConnection(false); 455 if (cntDBConnection == null) 456 { 457 throw new OSSDatabaseAccessException("Cannot get connection to database" + 458 " after user was created."); 459 } 460 } 461 462 if (m_vdsSchema != null) 465 { 466 m_vdsSchema.init(cntDBConnection, 467 DatabaseConnectionFactoryImpl.getInstance().getDatabaseUser()); 468 } 469 470 DatabaseTransactionFactoryImpl.getInstance().commitTransaction(cntDBConnection); 475 476 m_bDatabaseSchemaInitialized = true; 477 s_logger.log(Level.FINER, "Database is initialized."); 478 } 479 catch (Throwable thr) 480 { 481 s_logger.log(Level.SEVERE, "Failed to initialize database.", 482 thr); 483 if (cntDBConnection != null) 484 { 485 try 486 { 487 DatabaseTransactionFactoryImpl.getInstance().rollbackTransaction( 492 cntDBConnection); 493 } 494 catch (SQLException sqleExc) 495 { 496 s_logger.log(Level.WARNING, 498 "Failed to rollback changes for creation of database.", 499 sqleExc); 500 } 501 } 502 throw new OSSDatabaseAccessException("Failed to initialize database.", 503 thr); 504 } 505 finally 506 { 507 DatabaseConnectionFactoryImpl.getInstance().returnConnection( 508 cntDBConnection); 509 m_bDatabaseStartInProgress = false; 510 } 511 m_bDatabaseStarted = true; 512 } 513 } 514 finally 515 { 516 } 518 } 519 520 523 public void stop( 524 ) throws OSSException 525 { 526 DatabaseTransactionFactoryImpl.getInstance().stop(); 528 DatabaseConnectionFactoryImpl.getInstance().stop(); 530 m_vdsSchema = (VersionedDatabaseSchema) DatabaseSchemaManager.getInstance( 531 VersionedDatabaseSchema.class); 532 m_bDatabaseStarted = false; 533 } 534 535 538 public boolean isStarted( 539 ) 540 { 541 return m_bDatabaseStarted; 542 } 543 544 553 public abstract void startDatabaseServer( 554 ) throws OSSException; 555 556 565 public abstract void createDatabaseInstance( 566 ) throws OSSException; 567 568 570 573 public void add( 574 DatabaseSchema dsSchema 575 ) throws OSSException 576 { 577 if (GlobalConstants.ERROR_CHECKING) 578 { 579 assert dsSchema != null : "Cannot add null schema."; 580 } 581 582 if (m_vdsSchema == null) 583 { 584 m_vdsSchema = (VersionedDatabaseSchema)DatabaseSchemaManager.getInstance( 585 VersionedDatabaseSchema.class); 586 } 587 m_vdsSchema.add(dsSchema); 588 589 m_bDatabaseSchemaInitialized = false; 590 591 s_logger.log(Level.FINEST, "Database schema " + dsSchema.getName() 593 + " added to the database versioned schema."); 594 } 595 596 599 public void add( 600 Class clsSchema 601 ) throws OSSException 602 { 603 add(DatabaseSchemaManager.getInstance(clsSchema)); 604 } 605 606 609 public String getConnectionTestStatement() 610 { 611 return "select count(*) from " + VersionedDatabaseSchema.SCHEMA_TABLE_NAME; 614 } 615 616 619 public int getTransactionIsolation( 620 int iTransactionIsolation 621 ) 622 { 623 return iTransactionIsolation; 626 } 627 628 631 public int getSelectListResultSetType( 632 ) 633 { 634 return ResultSet.TYPE_SCROLL_INSENSITIVE; 638 } 639 640 643 public boolean hasAbsolutePositioningSupport( 644 ) 645 { 646 return true; 650 } 651 652 655 public boolean preferCountToLast( 656 ) 657 { 658 return (!hasAbsolutePositioningSupport()); 660 } 661 662 665 public boolean hasSelectListRangeSupport( 666 ) 667 { 668 return false; 671 } 672 673 676 public int getSelectListResultSetConcurrency( 677 ) 678 { 679 return ResultSet.CONCUR_READ_ONLY; 683 } 684 685 687 694 protected abstract void createUser( 695 Connection cntAdminDBConnection 696 ) throws OSSException; 697 698 705 protected Connection getAdminConnection( 706 boolean bAutoCommit 707 ) throws OSSException 708 { 709 Connection cntAdminDBConnection; 710 DatabaseConnectionFactory connectionFactory; 711 712 connectionFactory = DatabaseConnectionFactoryImpl.getInstance(); 713 714 if (connectionFactory.getUseAdminDataSource()) 716 { 717 if (!connectionFactory.isDataSourceDefined( 718 DatabaseConnectionFactoryImpl.ADMIN_DATASOURCE_NAME)) 719 { 720 connectionFactory.addDataSource( 723 DatabaseConnectionFactoryImpl.ADMIN_DATASOURCE_NAME, 724 connectionFactory.getDatabaseDriver(), 725 connectionFactory.getDatabaseURL(), 726 connectionFactory.getDatabaseAdminUser(), 727 connectionFactory.getDatabaseAdminPassword()); 728 } 729 730 cntAdminDBConnection = connectionFactory.requestConnection( 735 bAutoCommit, 736 DatabaseConnectionFactoryImpl.ADMIN_DATASOURCE_NAME); 737 } 738 else 739 { 740 cntAdminDBConnection = connectionFactory.requestConnection( 741 bAutoCommit, 742 connectionFactory.getDatabaseAdminUser(), 743 connectionFactory.getDatabaseAdminPassword()); 744 } 745 746 return cntAdminDBConnection; 747 } 748 } 749
| Popular Tags
|