package plugins.CENO.Bridge;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import plugins.CENO.CENOErrCode;
import plugins.CENO.CENOException;
import plugins.CENO.Bridge.Signaling.Channel;
import freenet.support.Logger;
public class BridgeDatabase
{
//String databasePath;
Connection _conn = null;
/**
* Constructor
*
* It opens the sqlite bridge database, creates it if it doesn't exists.
* then create the table structure if doesn't exists
*
* @param databasePath is the path ot the file which stores sqlite
* database
*/
public BridgeDatabase(String databasePath) throws CENOException
//: databasePath(databasePath)
{
//Sanity check
if (_conn != null) {
Logger.error(this, "Already connected to the database.");
} else {
try {
Class.forName("org.sqlite.JDBC");
String jdbcString = "jdbc:sqlite:"+databasePath;
_conn = DriverManager.getConnection(jdbcString);
CreateDatabaseStructure();
} catch ( Exception e ) {
throw new CENOException(CENOErrCode.LCS_DATABASE_CONNECT_FAILED, "Could not connect to the bridge database");
}
}
}
/**
* Called by constructors Creates all the necessary tables in case
* they do not exsit.
*
*/
public void CreateDatabaseStructure() throws CENOException {
Statement sqlCommand = null;
//Sanity check
if (_conn == null) {
Logger.error(this, "Not connected to the database yet.");
throw new CENOException(CENOErrCode.RR_DATABASE_OPERATION_FAILED, "Failed to create channel table");
}
//Creating the channel table
try {
sqlCommand = _conn.createStatement();
String sqlString = "CREATE TABLE IF NOT EXISTS channels " +
"(privateSSK TEXT PRIMARY KEY," +
"lastKnownVersion INT DEFAULT 0," +
"lastSynced INT DEFAULT CURRENT_TIMESTAMP);";
sqlCommand.executeUpdate(sqlString);
sqlCommand.close();
} catch ( Exception e ) {
throw new CENOException(CENOErrCode.RR_DATABASE_OPERATION_FAILED, "Failed to create channel table");
}
}
/**
* reads the list of the registered channels from the channel table
*
* @return list of channels
*/
public List<Channel> retrieveChannels() throws CENOException
{
Statement sqlCommand;
List<Channel> storedChannels = new ArrayList<Channel>();
try {
sqlCommand = _conn.createStatement();
String sqlString = "SELECT * FROM channels; ";
ResultSet result = sqlCommand.executeQuery(sqlString);
while ( result.next() ) {
try {
storedChannels.add(new Channel(result.getString("privateSSK"),
result.getLong("lastKnownVersion"), result.getLong("lastSynced")));
} catch ( Exception e ) {
Logger.error(this, "failed to add a channel for a stored SSK");
}
}
result.close();
sqlCommand.close();
} catch ( Exception e ) {
Logger.error(this, "failed to access the stored channel table");
throw new CENOException(CENOErrCode.RR_DATABASE_OPERATION_FAILED, "Failed to read the stored channel");
}
return storedChannels;
}
/**
* stores the given channel in the database for later retrieval
*
* @param new channel ssk
* @param provided edition
*/
public void storeChannel(String insertSSK, Long providedEdition, Long lastSynced) throws CENOException
{
Statement sqlCommand;
try {
sqlCommand = _conn.createStatement();
String sqlString = "INSERT OR REPLACE INTO channels (privateSSK,lastKnownVersion,lastSynced) " +
"VALUES ('" + insertSSK+ "', " + providedEdition + ", " + lastSynced + ");";
sqlCommand.executeUpdate(sqlString);
sqlCommand.close();
//_conn.commit(); auto commit is enabled by default
} catch ( Exception e ) {
Logger.error(this,"Failed to store channel");
//throw new CENOException(CENOErrCode.LCS_DATABASE_OPERATION_FAILED, "Failed to store channel");
}
}
public void storeChannel(Channel channel) throws CENOException {
storeChannel(channel.getInsertSSK(), channel.getLastKnownEdition(), channel.getLastSynced());
}
}