package org.icij.extract.queue;
import org.icij.extract.document.Document;
import org.icij.extract.document.DocumentFactory;
import org.icij.kaxxa.sql.concurrent.SQLQueueCodec;
import org.icij.task.Options;
import org.icij.task.annotation.Option;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
@Option(name = "queueIdKey", description = "For queues that provide an ID, use this option to specify the key.",
parameter = "name")
@Option(name = "queueForeignIdKey", description = "For queues that have a foreign ID column, specify the column name.",
parameter = "name")
@Option(name = "queuePathKey", description = "The table key for storing the document path. Must be unique in the " +
"table. Defaults to \"path\".", parameter = "name")
@Option(name = "queueStatusKey", description = "The table key for storing the queue status.", parameter = "name")
@Option(name = "queueWaitingStatus", description = "The status value for waiting documents.", parameter = "value")
@Option(name = "queueProcessedStatus", description = "The status value for non-waiting documents.", parameter = "value")
public class SQLDocumentQueueCodec implements SQLQueueCodec<Document> {
private final DocumentFactory factory;
private final String idKey;
private final String foreignIdKey;
private final String pathKey;
private final String statusKey;
private final String waitingStatus;
private final String processedStatus;
SQLDocumentQueueCodec(final DocumentFactory factory, final Options<String> options) {
this.factory = factory;
this.idKey = options.get("queueIdKey").value().orElse(null);
this.foreignIdKey = options.get("queueForeignIdKey").value().orElse(null);
this.pathKey = options.get("queuePathKey").value().orElse("path");
this.statusKey = options.get("queueStatusKey").value().orElse("queue_status");
this.waitingStatus = options.get("queueWaitingStatus").value().orElse("waiting");
this.processedStatus = options.get("queueProcessedStatus").value().orElse("processed");
}
@Override
public Map<String, Object> encodeKey(final Object o) {
final Document document = (Document) o;
final Map<String, Object> map = new HashMap<>();
if (null != idKey) {
map.put(idKey, document.getId());
} else {
map.put(pathKey, document.getPath().toString());
}
if (null != foreignIdKey) {
map.put(foreignIdKey, document.getForeignId());
}
return map;
}
@Override
public String getStatusKey() {
return statusKey;
}
@Override
public String getWaitingStatus() {
return waitingStatus;
}
@Override
public String getProcessedStatus() {
return processedStatus;
}
@Override
public Document decodeValue(final ResultSet rs) throws SQLException {
final Path path = Paths.get(rs.getString(pathKey));
final Document document;
if (null != idKey) {
document = factory.create(rs.getString(idKey), path);
} else {
document = factory.create(path);
}
if (null != foreignIdKey) {
document.setForeignId(rs.getString(foreignIdKey));
}
return document;
}
@Override
public Map<String, Object> encodeValue(final Object o) {
final Document document = (Document) o;
final Map<String, Object> map = new HashMap<>();
if (null != idKey) {
map.put(idKey, document.getId());
}
if (null != foreignIdKey) {
map.put(foreignIdKey, document.getForeignId());
}
map.put(pathKey, document.getPath().toString());
map.put(statusKey, waitingStatus);
return map;
}
}