package com.datascience.datastoring.adapters.mixed; import com.datascience.datastoring.adapters.kv.IKVStorage; import com.datascience.datastoring.backends.db.DBBackend; import com.datascience.datastoring.backends.db.SQLCommandOperator; import org.apache.log4j.Logger; import java.sql.*; /** * @Author: konrad */ public class DBKVStorage<T> implements IKVStorage<T> { private static Logger logger = Logger.getLogger(DBKVStorage.class); private static final String GET = "SELECT value FROM %s WHERE id = ?;"; private static final String EXISTS = "SELECT COUNT(*) as c FROM %s WHERE id = ?;"; private static final String INSERT_PARAMS = "(id, value)"; private static final String DELETE = "DELETE FROM %s WHERE id = ?;"; protected String table; protected DBBackend backend; public DBKVStorage(String table, DBBackend backend){ this.table = table; this.backend = backend; } protected String prepare(String sql){ return String.format(sql, table); } protected String startLog(String method, String key){ String logmsg = "DBKV (" + table + ") " + method + " " + key; logger.debug(logmsg); return logmsg; } protected void handleError(String msg, SQLException ex) throws SQLException { logger.error(msg + " FAIL", ex); throw ex; } @Override public void put(String key, T value) throws SQLException{ String logmsg = startLog("put", key); PreparedStatement sql = null; SQLCommandOperator sqlCO = backend.getSQLCmdOperator(); try { sql = sqlCO.getPreparedInsertReplacing(table, INSERT_PARAMS); sql.setString(1, key); sql.setString(2, (String) value); //TODO: casting sql.executeUpdate(); logger.debug(logmsg + " DONE"); } catch (SQLException ex) { handleError(logmsg, ex); } finally { sqlCO.cleanup(sql, null); } } @Override public T get(String key) throws SQLException{ String logmsg = startLog("get", key); PreparedStatement sql = null; ResultSet result = null; String value = null; SQLCommandOperator sqlCO = backend.getSQLCmdOperator(); try { sql = sqlCO.initStatement(prepare(GET)); sql.setString(1, key); result = sql.executeQuery(); if (!result.next()) { logger.debug(logmsg + " DONE no results"); return (T) value; } value = result.getString("value"); logger.debug(logmsg + " DONE"); } catch (SQLException ex) { handleError(logmsg, ex); } finally { sqlCO.cleanup(sql, result); } return (T) value; } @Override public void remove(String key) throws SQLException{ String logmsg = startLog("remove ", key); PreparedStatement sql = null; SQLCommandOperator sqlCO = backend.getSQLCmdOperator(); try { sql = sqlCO.initStatement(prepare(DELETE)); sql.setString(1, key); sql.executeUpdate(); logger.debug(logmsg + " DONE"); } catch (SQLException ex) { handleError(logmsg, ex); } finally { sqlCO.cleanup(sql, null); } } @Override public boolean contains(String key) throws SQLException{ String logmsg = startLog("contains", key); PreparedStatement sql = null; ResultSet result = null; long value = 0; SQLCommandOperator sqlCO = backend.getSQLCmdOperator(); try { sql = sqlCO.initStatement(prepare(EXISTS)); sql.setString(1, key); result = sql.executeQuery(); result.next(); value = result.getLong("c"); logger.debug(logmsg + " DONE"); } catch (SQLException ex) { handleError(logmsg, ex); } finally { sqlCO.cleanup(sql, result); } return value == 1; } @Override public void shutdown() throws SQLException{ // TODO XXX FIXME THINK - I think we don't should close DB here // dbStorage.close(); } }