2 * Copyright 2005 the original author or authors.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.wamblee.persistence;
19 import java.io.PrintWriter;
20 import java.sql.Connection;
21 import java.sql.DriverManager;
22 import java.sql.SQLException;
23 import java.util.Properties;
25 import junit.framework.TestCase;
27 import org.apache.derby.drda.NetworkServerControl;
28 import org.apache.derby.jdbc.ClientDriver;
29 import org.apache.derby.jdbc.EmbeddedDriver;
30 import org.apache.log4j.Logger;
31 import org.wamblee.io.FileSystemUtils;
35 * Derby database setup.
36 * The external JDBC url used to connect to a running instance is
38 * jdbc:derby:net://localhost:1527/testdb
40 * and the driver class is
42 * com.ibm.db2.jcc.DB2Driver
44 * The following jars will have to be used
45 * <code>db2jcc.jar</code> and <code>db2jcc_license_c.jar</code>.
47 public class DerbyDatabase implements Database {
52 private static final Logger LOGGER
53 = Logger.getLogger( DerbyDatabase.class );
58 private static final String USERNAME = "sa";
63 private static final String PASSWORD = "123";
66 * Poll interval for the checking the server status.
68 private static final int POLL_INTERVAL = 100;
71 * Maximum time to wait until the server has started or stopped.
73 private static final int MAX_WAIT_TIME = 10000;
76 * Database name to use.
78 private static final String DATABASE_NAME = "testdb";
81 * Path on the file system where derby files are stored.
83 private static final String DATABASE_PATH = "target/db/persistence/derby";
86 * Derby property required to set the file system path
87 * {@link #DATABASE_PATH}.
89 private static final String SYSTEM_PATH_PROPERTY = "derby.system.home";
92 * Constructs derby database class to allow creation of derby
95 public DerbyDatabase( ) {
101 * @see org.wamblee.persistence.Database#start()
103 public void start( ) throws Exception {
104 // just in case a previous run was killed without the
106 cleanPersistentStorage( );
108 // set database path.
109 Properties lProperties = System.getProperties( );
110 lProperties.put( SYSTEM_PATH_PROPERTY, DATABASE_PATH );
112 Class.forName( "org.apache.derby.jdbc.EmbeddedDriver" ).newInstance( );
116 waitUntilStartedOrStopped( true );
118 // Force creation of the database.
119 Connection lConnection = createConnection( );
120 lConnection.close( );
124 * Waits until the database server has started or stopped.
127 * If true, waits until the server is up, if false, waits until
128 * the server is down.
129 * @throws InterruptedException
131 private void waitUntilStartedOrStopped( boolean aStarted )
132 throws InterruptedException {
135 while ( aStarted != isStarted( ) ) {
136 Thread.sleep( POLL_INTERVAL );
137 lWaited += POLL_INTERVAL;
139 if ( lWaited > MAX_WAIT_TIME ) {
140 throw new RuntimeException(
141 "Derby database did not start within " + MAX_WAIT_TIME
148 * Checks if the database server has started or not.
150 * @return True if started, false otherwise.
152 private boolean isStarted( ) {
154 getControl( ).ping( );
157 } catch ( Exception e ) {
163 * Gets the controller for the database server.
165 * @return Controller.
168 private NetworkServerControl getControl( ) throws Exception {
169 return new NetworkServerControl( );
176 private void runDatabase( ) {
178 getControl( ).start( new PrintWriter( System.out ) );
179 } catch ( Exception e ) {
180 throw new RuntimeException( e );
186 * @see org.wamblee.persistence.Database#getJdbcUrl()
188 public String getJdbcUrl( ) {
189 return getBaseJdbcUrl( )
190 + ";create=true;retrieveMessagesFromServerOnGetMessage=true;";
193 private String getBaseJdbcUrl( ) {
194 return "jdbc:derby:" + DATABASE_NAME;
199 * @see org.wamblee.persistence.Database#getExternalJdbcUrl()
201 public String getExternalJdbcUrl( ) {
202 return "jdbc:derby:net://localhost:1527/" + DATABASE_NAME;
206 * Shuts down the derby database and cleans up all created files.
209 private void shutdownDerby( ) {
211 DriverManager.getConnection( "jdbc:derby:;shutdown=true" );
212 throw new RuntimeException(
213 "Derby did not shutdown, "
214 + " should always throw exception at shutdown" );
215 } catch ( Exception e ) {
216 LOGGER.info( "Derby has been shut down." );
222 * @see org.wamblee.persistence.Database#getDriverClassName()
224 public String getDriverClassName( ) {
225 return ClientDriver.class.getName();
229 * Gets the user name.
231 public String getUsername( ) {
239 public String getPassword( ) {
245 * @see org.wamblee.persistence.Database#createConnection()
247 public Connection createConnection( ) throws SQLException {
249 DriverManager.getConnection( getJdbcUrl( ), getUsername( ),
256 * Stops the derby database and cleans up all derby files.
258 public void stop( ) throws Exception {
259 // shutdown network server.
260 getControl( ).shutdown( );
261 waitUntilStartedOrStopped( false );
263 // shutdown inmemory access.
265 cleanPersistentStorage( );
269 * Cleans up persistent storage of Derby.
271 private void cleanPersistentStorage( ) {
272 File lFile = new File( DATABASE_PATH );
274 if ( lFile.isFile( ) ) {
275 TestCase.fail( "A regular file by the name " + DATABASE_PATH
276 + " exists, clean this up first" );
279 if ( !lFile.isDirectory( ) ) {
280 return; // no-op already cleanup up.
283 FileSystemUtils.deleteDirRecursively( DATABASE_PATH );