package org.atlasapi.persistence.content.mongo;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.metabroadcast.common.persistence.mongo.MongoBuilders.where;
import static com.metabroadcast.common.persistence.mongo.MongoConstants.ID;
import static com.metabroadcast.common.persistence.mongo.MongoConstants.SINGLE;
import static com.metabroadcast.common.persistence.mongo.MongoConstants.UPSERT;
import static org.atlasapi.persistence.media.entity.TopicTranslator.NAMESPACE;
import static org.atlasapi.persistence.media.entity.TopicTranslator.PUBLISHER;
import static org.atlasapi.persistence.media.entity.TopicTranslator.VALUE;
import org.atlasapi.content.criteria.ContentQuery;
import org.atlasapi.media.entity.Publisher;
import org.atlasapi.media.entity.Topic;
import org.atlasapi.persistence.audit.PersistenceAuditLog;
import org.atlasapi.persistence.media.entity.TopicTranslator;
import org.atlasapi.persistence.topic.TopicQueryResolver;
import org.atlasapi.persistence.topic.TopicStore;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import com.metabroadcast.common.base.Maybe;
import com.metabroadcast.common.persistence.mongo.DatabasedMongo;
import com.metabroadcast.common.persistence.mongo.MongoConstants;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
public class MongoTopicStore implements TopicStore, TopicQueryResolver {
private final DBCollection collection;
private final TopicTranslator translator;
private final MongoDBQueryBuilder queryBuilder;
private final PersistenceAuditLog persistenceAuditLog;
public MongoTopicStore(DatabasedMongo mongo, PersistenceAuditLog persistenceAuditLog) {
this.collection = mongo.collection("topics");
this.translator = new TopicTranslator();
this.queryBuilder = new MongoDBQueryBuilder();
this.persistenceAuditLog = checkNotNull(persistenceAuditLog);
}
@Override
public void write(Topic topic) {
checkNotNull(topic.getId(), "Can't persist topic with no ID");
DBObject dbo = translator.toDBObject(topic);
if (!topic.hashChanged(translator.hashCodeOf(topic))) {
persistenceAuditLog.logNoWrite(topic);
return;
}
persistenceAuditLog.logWrite(topic);
collection.update(where().idEquals((Long)dbo.get(ID)).build(), dbo, UPSERT, SINGLE);
}
@Override
public Maybe<Topic> topicForId(Long id) {
return topicForQuery(where().idEquals(id).build());
}
private Maybe<Topic> topicForQuery(DBObject query) {
DBObject dbo = collection.findOne(query);
if (dbo == null) {
return Maybe.nothing();
}
return Maybe.just(translator.fromDBObject(dbo));
}
@Override
public Maybe<Topic> topicFor(String namespace, String value) {
return topicForQuery(where().fieldEquals(VALUE, value).fieldEquals(NAMESPACE, namespace).build());
}
@Override
public Maybe<Topic> topicFor(Publisher publisher, String namespace, String value) {
return topicForQuery(where().fieldEquals(VALUE, value).fieldEquals(NAMESPACE, namespace).fieldEquals(PUBLISHER, Publisher.TO_KEY.apply(publisher)).build());
}
@Override
public Iterable<Topic> topicsForIds(Iterable<Long> ids) {
DBCursor dbos = collection.find(new BasicDBObject(MongoConstants.ID, new BasicDBObject(MongoConstants.IN, ids)));
return transform(dbos);
}
private Iterable<Topic> transform(DBCursor dbos) {
return Iterables.transform(dbos, new Function<DBObject, Topic>() {
@Override
public Topic apply(DBObject input) {
return translator.fromDBObject(input);
}
});
}
@Override
public Iterable<Topic> topicsFor(ContentQuery query) {
DBObject dbQuery = queryBuilder.buildQuery(query);
return transform(collection.find(dbQuery));
}
public Iterable<Topic> all() {
return transform(collection.find());
}
}