/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
public class DerbyDatabase extends AbstractDatabase {
- /**
- * Logger.
- */
- private static final Logger LOGGER = Logger.getLogger(DerbyDatabase.class
- .getName());
-
- /**
- * Database user name.
- */
- private static final String USERNAME = "sa";
-
- /**
- * Database password.
- */
- private static final String PASSWORD = "123";
- /**
- * Poll interval for the checking the server status.
- */
- private static final int POLL_INTERVAL = 100;
-
- /**
- * Maximum time to wait until the server has started or stopped.
- */
- private static final int MAX_WAIT_TIME = 10000;
-
- /**
- * Database name to use.
- */
- private static final String DATABASE_NAME = "testdb";
-
- /**
- * Path on the file system where derby files are stored.
- */
- private static final String DATABASE_PATH = "target/db/persistence/derby";
-
- /**
- * Derby property required to set the file system path
- * {@link #DATABASE_PATH}.
- */
- private static final String SYSTEM_PATH_PROPERTY = "derby.system.home";
-
-
- private boolean inmemory;
-
-
- /**
- * Constructs derby database class to allow creation of derby database
- * instances.
- */
- public DerbyDatabase() {
- inmemory = true;
- }
-
- public DerbyDatabase(boolean aInMemoryFlag) {
- inmemory = aInMemoryFlag;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.wamblee.persistence.Database#start()
- */
- public void doStart() {
- try {
- // just in case a previous run was killed without the
- // cleanup
- cleanPersistentStorage();
-
- if (!inmemory) {
- // set database path.
- Properties lProperties = System.getProperties();
- lProperties.put(SYSTEM_PATH_PROPERTY, DATABASE_PATH);
- }
-
- Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
-
- runDatabase();
-
- waitUntilStartedOrStopped(true);
-
- // Force creation of the database.
- Connection lConnection = createConnection();
- lConnection.close();
-
- LOGGER.info("Database started: \n URL = " + getExternalJdbcUrl() + "\n user = " + getUsername() + "\n password = "
- + getPassword());
-
- createDataSource();
-
- Runtime.getRuntime().addShutdownHook(new Thread() {
- @Override
- public void run() {
- if (isStarted()) {
- LOGGER.warning("Shutting down db");
- DerbyDatabase.this.stop();
- }
- }
- });
- } catch (Exception e) {
- throw new RuntimeException("Problem starting database", e);
- }
- }
-
- /**
- * Waits until the database server has started or stopped.
- *
- * @param aStarted
- * If true, waits until the server is up, if false, waits until
- * the server is down.
- * @throws InterruptedException
- */
- private void waitUntilStartedOrStopped(boolean aStarted)
- throws InterruptedException {
- long lWaited = 0;
-
- while (aStarted != isStarted()) {
- Thread.sleep(POLL_INTERVAL);
- lWaited += POLL_INTERVAL;
-
- if (lWaited > MAX_WAIT_TIME) {
- throw new RuntimeException(
- "Derby database did not start within " + MAX_WAIT_TIME
- + "ms");
- }
- }
- }
-
- /**
- * Checks if the database server has started or not.
- *
- * @return True if started, false otherwise.
- */
- private boolean isStarted() {
- try {
- getControl().ping();
-
- return true;
- } catch (Exception e) {
- return false;
- }
- }
-
- /**
- * Gets the controller for the database server.
- *
- * @return Controller.
- * @throws Exception
- */
- private NetworkServerControl getControl() throws Exception {
- return new NetworkServerControl();
- }
-
- /**
- * Runs the database.
- *
- */
- private void runDatabase() {
- try {
- getControl().start(new PrintWriter(System.out));
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.wamblee.persistence.Database#getJdbcUrl()
- */
- public String getJdbcUrl() {
- return getBaseJdbcUrl()
- + ";create=true;retrieveMessagesFromServerOnGetMessage=true;";
- }
-
- private String getBaseJdbcUrl() {
- return (inmemory ? "jdbc:derby:memory:": "jdbc:derby:") + DATABASE_NAME;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.wamblee.persistence.Database#getExternalJdbcUrl()
- */
- public String getExternalJdbcUrl() {
- return "jdbc:derby://localhost:1527/" + (inmemory ? "memory:" : "") + DATABASE_NAME;
- }
-
- /**
- * Shuts down the derby database and cleans up all created files.
- *
- */
- private void shutdownDerby() {
- try {
- DriverManager.getConnection("jdbc:derby:;shutdown=true");
- throw new RuntimeException("Derby did not shutdown, "
- + " should always throw exception at shutdown");
- } catch (Exception e) {
- LOGGER.info("Derby has been shut down.");
- }
- }
-
- /**
- * Gets the user name.
- */
- public String getUsername() {
- return USERNAME;
- }
-
- /**
- * Gets the password.
- *
- * @return
- */
- public String getPassword() {
- return PASSWORD;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.wamblee.persistence.Database#createConnection()
- */
- public Connection createConnection() throws SQLException {
- Connection c = DriverManager.getConnection(getJdbcUrl(), getUsername(),
- getPassword());
-
- return c;
- }
-
-
- /**
- * Stops the derby database and cleans up all derby files.
- */
- public void doStop() {
- try {
- // shutdown network server.
- getControl().shutdown();
- waitUntilStartedOrStopped(false);
-
- // shutdown inmemory access.
- shutdownDerby();
- cleanPersistentStorage();
- } catch (Exception e) {
- LOGGER.log(Level.WARNING, "Problem stopping database", e);
- }
- }
-
- /**
- * Cleans up persistent storage of Derby.
- */
- private void cleanPersistentStorage() {
- File lFile = new File(DATABASE_PATH);
-
- if (lFile.isFile()) {
- TestCase.fail("A regular file by the name " + DATABASE_PATH
- + " exists, clean this up first");
- }
-
- if (!lFile.isDirectory()) {
- return; // no-op already cleanup up.
- }
- FileSystemUtils.deleteDirRecursively(DATABASE_PATH);
- }
+ /**
+ * Logger.
+ */
+ private static final Logger LOGGER = Logger.getLogger(DerbyDatabase.class
+ .getName());
+
+ /**
+ * Database user name.
+ */
+ private static final String USERNAME = "sa";
+
+ /**
+ * Database password.
+ */
+ private static final String PASSWORD = "123";
+ /**
+ * Poll interval for the checking the server status.
+ */
+ private static final int POLL_INTERVAL = 100;
+
+ /**
+ * Maximum time to wait until the server has started or stopped.
+ */
+ private static final int MAX_WAIT_TIME = 10000;
+
+ /**
+ * Database name to use.
+ */
+ private static final String DATABASE_NAME = "testdb";
+
+ /**
+ * Path on the file system where derby files are stored.
+ */
+ private static final String DATABASE_PATH = "target/db/persistence/derby";
+
+ /**
+ * Derby property required to set the file system path
+ * {@link #DATABASE_PATH}.
+ */
+ private static final String SYSTEM_PATH_PROPERTY = "derby.system.home";
+
+ private boolean inmemory;
+
+ /**
+ * Constructs derby database class to allow creation of derby database
+ * instances.
+ */
+ public DerbyDatabase() {
+ inmemory = true;
+ }
+
+ public DerbyDatabase(boolean aInMemoryFlag) {
+ inmemory = aInMemoryFlag;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.wamblee.persistence.Database#start()
+ */
+ public void doStart() {
+ try {
+ // just in case a previous run was killed without the
+ // cleanup
+ cleanPersistentStorage();
+
+ if (!inmemory) {
+ // set database path.
+ Properties lProperties = System.getProperties();
+ lProperties.put(SYSTEM_PATH_PROPERTY, DATABASE_PATH);
+ }
+
+ Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
+
+ runDatabase();
+
+ waitUntilStartedOrStopped(true);
+
+ // Force creation of the database.
+ Connection lConnection = createConnection();
+ lConnection.close();
+
+ LOGGER.info("Database started: \n URL = " +
+ getExternalJdbcUrl() + "\n user = " + getUsername() +
+ "\n password = " + getPassword());
+
+ createDataSource();
+
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ @Override
+ public void run() {
+ if (isStarted()) {
+ LOGGER.warning("Shutting down db");
+ DerbyDatabase.this.stop();
+ }
+ }
+ });
+ } catch (Exception e) {
+ throw new RuntimeException("Problem starting database", e);
+ }
+ }
+
+ /**
+ * Waits until the database server has started or stopped.
+ *
+ * @param aStarted
+ * If true, waits until the server is up, if false, waits until
+ * the server is down.
+ * @throws InterruptedException
+ */
+ private void waitUntilStartedOrStopped(boolean aStarted)
+ throws InterruptedException {
+ long lWaited = 0;
+
+ while (aStarted != isStarted()) {
+ Thread.sleep(POLL_INTERVAL);
+ lWaited += POLL_INTERVAL;
+
+ if (lWaited > MAX_WAIT_TIME) {
+ throw new RuntimeException(
+ "Derby database did not start within " + MAX_WAIT_TIME +
+ "ms");
+ }
+ }
+ }
+
+ /**
+ * Checks if the database server has started or not.
+ *
+ * @return True if started, false otherwise.
+ */
+ private boolean isStarted() {
+ try {
+ getControl().ping();
+
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ /**
+ * Gets the controller for the database server.
+ *
+ * @return Controller.
+ * @throws Exception
+ */
+ private NetworkServerControl getControl() throws Exception {
+ return new NetworkServerControl();
+ }
+
+ /**
+ * Runs the database.
+ *
+ */
+ private void runDatabase() {
+ try {
+ getControl().start(new PrintWriter(System.out));
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.wamblee.persistence.Database#getJdbcUrl()
+ */
+ public String getJdbcUrl() {
+ return getBaseJdbcUrl() +
+ ";create=true;retrieveMessagesFromServerOnGetMessage=true;";
+ }
+
+ private String getBaseJdbcUrl() {
+ return (inmemory ? "jdbc:derby:memory:" : "jdbc:derby:") +
+ DATABASE_NAME;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.wamblee.persistence.Database#getExternalJdbcUrl()
+ */
+ public String getExternalJdbcUrl() {
+ return "jdbc:derby://localhost:1527/" + (inmemory ? "memory:" : "") +
+ DATABASE_NAME;
+ }
+
+ /**
+ * Shuts down the derby database and cleans up all created files.
+ *
+ */
+ private void shutdownDerby() {
+ try {
+ DriverManager.getConnection("jdbc:derby:;shutdown=true");
+ throw new RuntimeException(
+ "Derby did not shutdown, should always throw exception at shutdown");
+ } catch (Exception e) {
+ LOGGER.info("Derby has been shut down.");
+ }
+ }
+
+ /**
+ * Gets the user name.
+ */
+ public String getUsername() {
+ return USERNAME;
+ }
+
+ /**
+ * Gets the password.
+ *
+ * @return
+ */
+ public String getPassword() {
+ return PASSWORD;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.wamblee.persistence.Database#createConnection()
+ */
+ public Connection createConnection() throws SQLException {
+ Connection c = DriverManager.getConnection(getJdbcUrl(), getUsername(),
+ getPassword());
+
+ return c;
+ }
+
+ /**
+ * Stops the derby database and cleans up all derby files.
+ */
+ public void doStop() {
+ try {
+ // shutdown network server.
+ getControl().shutdown();
+ waitUntilStartedOrStopped(false);
+
+ // shutdown inmemory access.
+ shutdownDerby();
+ cleanPersistentStorage();
+ } catch (Exception e) {
+ LOGGER.log(Level.WARNING, "Problem stopping database", e);
+ }
+ }
+
+ /**
+ * Cleans up persistent storage of Derby.
+ */
+ private void cleanPersistentStorage() {
+ File lFile = new File(DATABASE_PATH);
+
+ if (lFile.isFile()) {
+ TestCase.fail("A regular file by the name " + DATABASE_PATH +
+ " exists, clean this up first");
+ }
+
+ if (!lFile.isDirectory()) {
+ return; // no-op already cleanup up.
+ }
+ FileSystemUtils.deleteDirRecursively(DATABASE_PATH);
+ }
}