package org.myeslib.util.hazelcast;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.sql.DataSource;
import lombok.extern.slf4j.Slf4j;
import org.myeslib.util.jdbi.ClobToStringMapper;
import org.skife.jdbi.v2.DBI;
import org.skife.jdbi.v2.Handle;
import org.skife.jdbi.v2.PreparedBatch;
import org.skife.jdbi.v2.TransactionCallback;
import org.skife.jdbi.v2.TransactionIsolationLevel;
import org.skife.jdbi.v2.TransactionStatus;
import org.skife.jdbi.v2.tweak.HandleCallback;
import com.hazelcast.core.QueueStore;
@Slf4j
public class HzStringQueueStore implements QueueStore<String> {
private final DBI dbi;
private final String tableName;
public HzStringQueueStore(final DataSource ds, final String tableName){
this.dbi = new DBI(ds);
this.tableName = tableName;
}
public void createTableForQueue() {
log.warn(String.format("checking if table %s exists for queue storage", tableName));
dbi.inTransaction(new TransactionCallback<Integer>() {
@Override
public Integer inTransaction(Handle h, TransactionStatus ts)
throws Exception {
h.execute(String.format("create table if not exists %s(id bigint, value clob)", tableName));
return 0;
}
}) ;
}
@Override
public void delete(Long id) {
deleteAll(Arrays.asList(id));
}
@Override
public void deleteAll(final Collection<Long> ids) {
log.info(String.format("deleting all within table %s", tableName));
dbi.inTransaction(new TransactionCallback<Integer>() {
@Override
public Integer inTransaction(Handle h, TransactionStatus ts)
throws Exception {
PreparedBatch pb = h.prepareBatch(String.format("delete from %s where id = :id", tableName));
for (Long id: ids){
pb.add().bind("id", id);
}
return pb.execute().length;
}
}) ;
}
@Override
public String load(final Long id) {
String result = null;
try {
log.info("will load {} from table {}", id.toString(), tableName);
result = dbi.inTransaction(TransactionIsolationLevel.READ_COMMITTED,
new TransactionCallback<String>() {
@Override
public String inTransaction(Handle h, TransactionStatus ts) throws Exception {
String sql = String.format("select value from %s where id = :id", tableName);
return h.createQuery(sql).bind("id", id).map(ClobToStringMapper.FIRST).first();
}
});
if (result==null) {
log.warn("found a null value for id {}", id.toString());
} else {
log.info("loaded {} {} from table {}", id.toString(), result, tableName);
}
} catch (Exception e) {
log.error("error when loading {} from table {}", id.toString(), tableName);
e.printStackTrace();
}
return result;
}
@Override
public Map<Long, String> loadAll(Collection<Long> ids) {
log.info(String.format("loading all within table %s", tableName));
Map<Long, String> result = new HashMap<>();
for (Long id : ids){
result.put(id, load(id));
}
return result;
}
@Override
public Set<Long> loadAllKeys() {
log.info(String.format("loading all keys within table %s", tableName));
List<Long> result = dbi.withHandle(new HandleCallback<List<Long>>() {
@Override
public List<Long> withHandle(Handle h) throws Exception {
return h.createQuery(String.format("select id from %s", tableName))
.map(Long.class).list();
}
});
return new HashSet<Long>(result);
}
@Override
public void store(Long id, String value) {
Map<Long, String> map = new HashMap<>();
map.put(id, value);
storeAll(map);
}
@Override
public void storeAll(final Map<Long, String> items) {
log.info(String.format("storing all within table %s", tableName));
dbi.inTransaction(new TransactionCallback<Integer>() {
@Override
public Integer inTransaction(Handle h, TransactionStatus ts)
throws Exception {
PreparedBatch pb = h.prepareBatch(String.format("append into %s (id, value) values (:id, :value)", tableName));
for (Map.Entry<Long, String> entry : items.entrySet()){
log.info("store " + entry.getKey() + ", value = " + entry.getValue());
pb.add().bind("id", entry.getKey()).bind("value", entry.getValue());
}
return pb.execute().length;
}
}) ;
}
}