package divconq.cms.feed.proc;
import java.util.concurrent.atomic.AtomicReference;
import org.joda.time.DateTime;
import divconq.db.DatabaseInterface;
import divconq.db.DatabaseResult;
import divconq.db.ObjectResult;
import divconq.db.DatabaseTask;
import divconq.db.IStoredProc;
import divconq.db.TablesAdapter;
import divconq.db.query.LoadRecordRequest;
import divconq.db.query.SelectFields;
import divconq.db.update.DbRecordRequest;
import divconq.db.update.InsertRecordRequest;
import divconq.db.update.UpdateRecordRequest;
import divconq.lang.BigDateTime;
import divconq.lang.op.OperationResult;
import divconq.struct.CompositeStruct;
import divconq.struct.ListStruct;
import divconq.struct.RecordStruct;
import divconq.struct.builder.ICompositeBuilder;
import divconq.util.StringUtil;
import divconq.util.TimeUtil;
public class UpdateFeed implements IStoredProc {
@Override
public void execute(DatabaseInterface conn, DatabaseTask task, OperationResult log) {
RecordStruct params = task.getParamsAsRecord();
String chann = params.getFieldAsString("Channel");
String path = params.getFieldAsString("Path");
Boolean edflag = params.getFieldAsBoolean("Editable");
ListStruct atags = params.getFieldAsList("AuthorizationTags");
ListStruct ctags = params.getFieldAsList("ContentTags");
ListStruct fields = params.getFieldAsList("Fields");
ListStruct prefields = params.getFieldAsList("PreviewFields");
ListStruct parts = params.getFieldAsList("PartContent");
ListStruct preparts = params.getFieldAsList("PreviewPartContent");
// TODO replicating
// if (task.isReplicating())
// TODO support site
TablesAdapter db = new TablesAdapter(conn, task);
BigDateTime when = BigDateTime.nowDateTime();
Object oid = db.firstInIndex("dcmFeed", "dcmPath", path, when, false);
AtomicReference<RecordStruct> oldvalues = new AtomicReference<>();
AtomicReference<DateTime> updatepub = new AtomicReference<>();
AtomicReference<DateTime> updateprepub = new AtomicReference<>();
DatabaseResult fromUpdate = new ObjectResult() {
@Override
public void process(CompositeStruct result) {
/*
* Update index
*
* ^dcmFeedIndex(did, channel, publish datetime, id)=[content tags]
*
* ^dcmFeedPreviewIndex(did, channel, publish datetime, id)=[content tags]
*
*/
log.touch();
String recid = null;
if (oid != null)
recid = oid.toString();
else if (result != null)
recid = ((RecordStruct) result).getFieldAsString("Id");
if (StringUtil.isEmpty(recid)) {
log.error("Unable to update feed index - no id available");
task.complete();
return;
}
String did = task.getDomain();
String ochan = null;
DateTime opubtime = null;
// TODO
//DateTime oprepubtime = null;
String otags = "|";
if (oldvalues.get() != null) {
ochan = oldvalues.get().getFieldAsString("Channel");
opubtime = oldvalues.get().getFieldAsDateTime("Published");
// TODO
//oprepubtime = oldvalues.get().getFieldAsDateTime("PreviewPublished");
ListStruct otlist = oldvalues.get().getFieldAsList("ContentTags");
if (ctags != null)
otags = "|" + StringUtil.join(otlist.toStringList(), "|") + "|";
}
String nchan = chann;
DateTime npubtime = updatepub.get();
// TODO
//DateTime nprepubtime = updateprepub.get();
String ntags = "|";
if (StringUtil.isEmpty(nchan))
nchan = ochan;
if (StringUtil.isEmpty(nchan)) {
log.error("Unable to update feed index - no channel available");
task.complete();
return;
}
if (npubtime == null)
npubtime = opubtime;
// TODO
//if (nprepubtime == null)
// nprepubtime = oprepubtime;
if (ctags != null) {
ntags = "|" + StringUtil.join(ctags.toStringList(), "|") + "|";
}
else {
ntags = otags;
}
//boolean diff1 = !ochan.equals(nchan) || !opubtime.equals(npubtime) || !oprepubtime.equals(nprepubtime);
// TODO fix this so we update only if pubtime changes
boolean diff1 = !nchan.equals(ochan) || ((opubtime == null) || (npubtime == null) || !opubtime.equals(npubtime));
boolean diff2 = !ntags.equals(otags);
try {
if (diff1 || diff2) {
if (diff1 && StringUtil.isNotEmpty(ochan)) {
if (opubtime != null)
conn.kill("dcmFeedIndex", did, ochan, conn.inverseTime(opubtime), recid);
// TODO
//if (oprepubtime != null)
// conn.kill("dcmFeedPreviewIndex", did, ochan, conn.inverseTime(oprepubtime), recid);
}
if (npubtime != null)
conn.set("dcmFeedIndex", did, nchan, conn.inverseTime(npubtime), recid, ntags);
// TODO
//if (nprepubtime != null)
// conn.set("dcmFeedPreviewIndex", did, nchan, conn.inverseTime(nprepubtime), recid, ntags);
}
}
catch (Exception x) {
log.error("Error updating feed index: " + x);
}
try {
ICompositeBuilder out = task.getBuilder();
out.startRecord();
out.field("Id", recid);
out.endRecord();
}
catch (Exception x) {
log.error("Error writing record id: " + x);
}
task.complete();
}
};
DatabaseResult fromLoad = new ObjectResult() {
@Override
public void process(CompositeStruct result) {
if ((oid != null) && (result == null)) {
log.error("Unable to update feed - id found but no record loaded");
task.complete();
return;
}
log.touch();
oldvalues.set((RecordStruct) result);
if (oid == null) {
if (StringUtil.isEmpty(path) || StringUtil.isEmpty(chann)) {
log.error("Unable to insert feed - missing Path or Channel");
task.complete();
return;
}
}
DbRecordRequest req = (oid == null) ? new InsertRecordRequest() : new UpdateRecordRequest();
req.withTable("dcmFeed");
if (oid != null) {
req.withId(oid.toString());
}
else {
//req.withUpdateField("dcmUuid", uuid);
req.withUpdateField("dcmImported", new DateTime());
}
if (chann != null)
req.withUpdateField("dcmChannel", chann);
if (path != null)
req.withUpdateField("dcmPath", path);
if (edflag != null)
req.withUpdateField("dcmEditable", edflag);
if (atags != null)
req.withSetList("dcmAuthorizationTags", atags);
if (ctags != null)
req.withSetList("dcmContentTags", ctags);
if (fields != null) {
for (int i = 0; i < fields.getSize(); i++) {
RecordStruct entry = fields.getItemAsRecord(i);
String key = entry.getFieldAsString("Name") + "." + entry.getFieldAsString("Locale");
req.withUpdateField("dcmFields", key, entry.getFieldAsString("Value"));
if ("Published".equals(entry.getFieldAsString("Name"))) {
DateTime pd = TimeUtil.parseDateTime(entry.getFieldAsString("Value")).withMillisOfSecond(0).withSecondOfMinute(0);
updatepub.set(pd);
req.withUpdateField("dcmPublished", pd);
}
if ("AuthorUsername".equals(entry.getFieldAsString("Name"))) {
Object userid = db.firstInIndex("dcUser", "dcUsername", entry.getFieldAsString("Value"), when, false);
if (userid != null) {
String uid = userid.toString();
req.withUpdateField("dcmAuthor", uid, uid);
}
}
}
}
if (prefields != null) {
for (int i = 0; i < prefields.getSize(); i++) {
RecordStruct entry = prefields.getItemAsRecord(i);
String key = entry.getFieldAsString("Name") + "." + entry.getFieldAsString("Locale");
req.withUpdateField("dcmPreviewFields", key, entry.getFieldAsString("Value"));
if ("Published".equals(entry.getFieldAsString("Name"))) {
DateTime pd = TimeUtil.parseDateTime(entry.getFieldAsString("Value")).withMillisOfSecond(0).withSecondOfMinute(0);
updateprepub.set(pd);
req.withUpdateField("dcmPreviewPublished", pd);
}
if ("AuthorUsername".equals(entry.getFieldAsString("Name"))) {
Object userid = db.firstInIndex("dcUser", "dcUsername", entry.getFieldAsString("Value"), when, false);
if (userid != null) {
String uid = userid.toString();
req.withUpdateField("dcmAuthor", uid, uid);
}
}
}
}
if (parts != null) {
for (int i = 0; i < parts.getSize(); i++) {
RecordStruct entry = parts.getItemAsRecord(i);
String key = entry.getFieldAsString("Name") + "." + entry.getFieldAsString("Locale");
// TODO process different format types to their indexable state (html -> text, etc)
// String fmt = entry.getFieldAsString("Format");
req.withUpdateField("dcmPartContent", key, entry.getFieldAsString("Value"));
}
}
if (preparts != null) {
for (int i = 0; i < preparts.getSize(); i++) {
RecordStruct entry = preparts.getItemAsRecord(i);
String key = entry.getFieldAsString("Name") + "." + entry.getFieldAsString("Locale");
// TODO process different format types to their indexable state (html -> text, etc)
// String fmt = entry.getFieldAsString("Format");
req.withUpdateField("dcmPreviewPartContent", key, entry.getFieldAsString("Value"));
}
}
req.withUpdateField("dcmModified", new DateTime());
task.getDbm().submit(req, fromUpdate);
}
};
if (oid != null) {
LoadRecordRequest lr1 = new LoadRecordRequest()
.withTable("dcmFeed")
.withId(oid.toString())
.withSelect(new SelectFields()
.withField("Id")
.withField("dcmChannel", "Channel")
.withField("dcmPublished", "Published")
.withField("dcmPreviewPublished", "PreviewPublished")
.withField("dcmContentTags", "ContentTags")
);
task.getDbm().submit(lr1, fromLoad);
}
else {
fromLoad.complete();
}
}
}