package uk.ac.lkl.common.util.database;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.sql.SQLException;
import java.sql.Statement;
import org.apache.derby.drda.NetworkServerControl;
import uk.ac.lkl.common.util.database.comparison.DefinitionComparer;
import uk.ac.lkl.common.util.database.comparison.DefinitionComparisonException;
import uk.ac.lkl.common.util.database.comparison.FullDatabaseComparer;
import uk.ac.lkl.common.util.database.extract.DatabaseExtractionException;
public class DatabaseServer {
private NetworkServerControl networkServerControl;
public DatabaseServer() throws DatabaseException {
this("localhost", 1527);
}
public DatabaseServer(String hostName, int port) throws DatabaseException {
try {
InetAddress inetAddress = InetAddress.getByName(hostName);
networkServerControl = new NetworkServerControl(inetAddress, port);
} catch (Exception e) {
throw new DatabaseException(e);
}
}
public void start() throws DatabaseException {
try {
networkServerControl.start(new PrintWriter(System.out, true));
boolean pingSuccessful = false;
do {
try {
Thread.sleep(1000);
networkServerControl.ping();
pingSuccessful = true;
} catch (Exception e) {
System.out.println(e);
}
} while (!pingSuccessful);
System.out.println("Database server ready.");
} catch (Exception e) {
throw new DatabaseException(e);
}
}
// connect without any constraints on format of database
public StructuredConnection connectDirect(String databaseName)
throws DatabaseConnectionException, DatabaseDriverException {
StructuredConnection connection = new ClientConnection("localhost",
1527, databaseName);
connection.connect();
return connection;
}
public StructuredConnection connectByDefinition(
DatabaseDefinition expectedDatabaseDefinition)
throws DefinitionComparisonException, DatabaseConnectionException,
DatabaseDriverException, DatabaseExtractionException {
String databaseName = expectedDatabaseDefinition.getName();
return connectByDefinition(expectedDatabaseDefinition, databaseName,
true);
}
public StructuredConnection connectByDefinition(
DatabaseDefinition expectedDatabaseDefinition, String databaseName)
throws DefinitionComparisonException, DatabaseConnectionException,
DatabaseDriverException, DatabaseExtractionException {
return connectByDefinition(expectedDatabaseDefinition, databaseName,
false);
}
public StructuredConnection connectByDefinition(
DatabaseDefinition expectedDatabaseDefinition, String databaseName,
boolean comparingNames) throws DefinitionComparisonException,
DatabaseConnectionException, DatabaseDriverException,
DatabaseExtractionException {
StructuredConnection connection = new ClientConnection("localhost",
1527, databaseName);
try {
connection.connect();
compareExistingDatabase(connection, expectedDatabaseDefinition);
} catch (DatabaseConnectionException e) {
connection.close();
connection = new AutoCreatedConnection(connection);
connection.connect();
createDatabase(connection, expectedDatabaseDefinition);
}
return connection;
}
private void compareExistingDatabase(StructuredConnection connection,
DatabaseDefinition expectedDatabaseDefinition)
throws DefinitionComparisonException, DatabaseConnectionException,
DatabaseDriverException, DatabaseExtractionException {
DatabaseDefinition actualDatabaseDefinition = DefinitionFactory
.createDatabaseFromConnection(connection);
DefinitionComparer<DatabaseDefinition> comparator = new FullDatabaseComparer(
false);
comparator
.compare(expectedDatabaseDefinition, actualDatabaseDefinition);
}
private void createDatabase(StructuredConnection connection,
DatabaseDefinition expectedDatabaseDefinition)
throws DatabaseConnectionException {
try {
System.out.println("Creating database...");
Statement statement = connection.createStatement();
for (TableDefinition tableDefinition : expectedDatabaseDefinition) {
String sql = tableDefinition.generateSQL();
statement.execute(sql);
System.out.println(" Table \"" + tableDefinition.getName()
+ "\" created.");
}
System.out.println("Database created.");
} catch (SQLException e) {
connection.close();
// todo: do more here -- delete existing definition since is in
// indeterminate state.
System.out.println(e);
} catch (DatabaseStatementException e) {
// todo: more here -- delete existing definition since is in
// indeterminate state.
connection.close();
System.out.println(e);
}
}
public void shutdown() throws DatabaseException {
try {
networkServerControl.shutdown();
} catch (Exception e) {
throw new DatabaseException(e);
}
}
/**
* Returns true if the DB server is on and answering to ping(), false otherwise.
*
* @return true if the DB server is on and answering to ping(), false otherwise.
*/
public boolean isOn() {
try {
this.networkServerControl.ping();
} catch (Exception e) {
return false;
}
return true;
}
}
|