package com.pugh.sockso;
import com.pugh.sockso.db.Database;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.google.inject.Inject;
import com.google.inject.Singleton;
/**
* Adds persistence by DB to the StringProperties class
*
*/
@Singleton
public class DBProperties extends StringProperties {
private final Database db;
/**
* creates the properties object.
*
* @param db the database connection
*
*/
@Inject
public DBProperties( final Database db ) {
this.db = db;
}
/**
* inits the object
*
* @throws java.sql.SQLException
*
*/
@Override
public void init() throws SQLException {
refresh();
new Thread() {
@Override
public void run() {
final int THIRTY_SECONDS = 30000;
while ( true ) {
try { Thread.sleep(THIRTY_SECONDS); }
catch ( final InterruptedException e ) { /* ignore */ }
try { refresh(); }
catch ( final SQLException e ) {
log.debug( e );
}
}
}
}.start();
}
/**
* refreshes the properties from the database
*
* @throws java.sql.SQLException
*
*/
private void refresh() throws SQLException {
ResultSet rs = null;
PreparedStatement st = null;
try {
final String sql = " select p.name as name, p.value as value " +
" from properties p ";
st = db.prepare( sql );
rs = st.executeQuery();
while ( rs.next() ) {
set( rs.getString("name"), rs.getString("value") );
}
}
finally {
Utils.close( rs );
Utils.close( st );
}
}
/**
* saves any changes to the properties so they are written
* to the database.
*
*/
@Override
public void save() {
PreparedStatement st = null;
try {
// @TODO use a batch transaction here?
// delete old properties
String sql = " delete from properties ";
st = db.prepare( sql );
st.execute();
Utils.close( st );
// insert new properties
for ( final String name : data.keySet() ) {
sql = " insert into properties ( name, value ) " +
" values ( ?, ? ) ";
st = db.prepare( sql );
st.setString( 1, name );
st.setString( 2, get(name) );
st.execute();
Utils.close( st );
}
firePropertiesSavedEvent();
}
catch ( final SQLException e ) {
log.error( e );
}
finally {
Utils.close( st );
}
}
}