package org.mercury_im.messenger.data.repository; import org.jxmpp.jid.EntityBareJid; import org.mercury_im.messenger.core.data.repository.MessageRepository; import org.mercury_im.messenger.data.mapping.DirectChatMapping; import org.mercury_im.messenger.data.mapping.GroupChatMapping; import org.mercury_im.messenger.data.mapping.MessageMapping; import org.mercury_im.messenger.data.model.MessageModel; import org.mercury_im.messenger.data.repository.dao.DirectChatDao; import org.mercury_im.messenger.data.repository.dao.GroupChatDao; import org.mercury_im.messenger.data.repository.dao.MessageDao; import org.mercury_im.messenger.entity.chat.DirectChat; import org.mercury_im.messenger.entity.chat.GroupChat; import org.mercury_im.messenger.entity.message.ChatMarkerState; import org.mercury_im.messenger.entity.message.Message; import org.mercury_im.messenger.entity.message.MessageDeliveryState; import java.util.ArrayList; import java.util.List; import java.util.UUID; import javax.inject.Inject; import io.reactivex.Completable; import io.reactivex.Observable; import io.reactivex.Single; import io.requery.Persistable; import io.requery.query.ResultDelegate; import io.requery.reactivex.ReactiveEntityStore; public class RxMessageRepository extends RequeryRepository implements MessageRepository { private final MessageMapping messageMapping; private final DirectChatMapping directChatMapping; private final GroupChatMapping groupChatMapping; private final DirectChatDao directChatDao; private final GroupChatDao groupChatDao; private final MessageDao dao; @Inject public RxMessageRepository(ReactiveEntityStore data, MessageMapping messageMapping, DirectChatMapping directChatMapping, GroupChatMapping groupChatMapping) { super(data); this.messageMapping = messageMapping; this.directChatMapping = directChatMapping; this.groupChatMapping = groupChatMapping; this.directChatDao = new DirectChatDao(data); this.groupChatDao = new GroupChatDao(data); this.dao = new MessageDao(data); } @Override public Single insertMessage(Message message) { return Single.just(message) .map(messageMapping::toModel) .flatMap(dao::insert) .map(messageMapping::toEntity); } @Override public Observable> observeMessages(DirectChat chat) { return data().select(MessageModel.class) .from(MessageModel.class) .where(MessageModel.CHAT_ID.eq(chat.getId())) .get().observableResult() .map(ResultDelegate::toList) .map(this::messageModelsToEntities); } public Observable> observeAllMessages() { return data().select(MessageModel.class) .from(MessageModel.class) .get().observableResult() .map(ResultDelegate::toList) .map(this::messageModelsToEntities); } @Override public Observable> observeMessages(GroupChat chat) { return data().select(MessageModel.class) .from(MessageModel.class) .where(MessageModel.CHAT_ID.eq(chat.getId())) .get().observableResult() .map(ResultDelegate::toList) .map(this::messageModelsToEntities); } @Override public Observable> findMessagesWithBody(String body) { return data().select(MessageModel.class) .from(MessageModel.class) .where(MessageModel.BODY.like("%" + body + "%")) .get().observableResult() .map(ResultDelegate::toList) .map(this::messageModelsToEntities); } @Override public Observable> findMessagesWithBody(DirectChat chat, String body) { return data().select(MessageModel.class) .from(MessageModel.class) .where(MessageModel.BODY.like("%" + body + "%") .and(MessageModel.CHAT_ID.eq(chat.getId()))) .get().observableResult() .map(ResultDelegate::toList) .map(this::messageModelsToEntities); } @Override public Observable> findMessagesWithBody(GroupChat chat, String body) { return data().select(MessageModel.class) .from(MessageModel.class) .where(MessageModel.BODY.like("%" + body + "%") .and(MessageModel.CHAT_ID.eq(chat.getId()))) .get().observableResult() .map(ResultDelegate::toList) .map(this::messageModelsToEntities); } @Override public Single upsertMessage(Message message) { return Single.just(message) .map(messageMapping::toModel) .flatMap(data()::upsert) .map(messageMapping::toEntity); } @Override public Single updateMessage(Message message) { return dao.get(message.getId()).maybe().toSingle() .map(model -> messageMapping.toModel(message, model)) .flatMap(data()::update) .map(model -> messageMapping.toEntity(model, message)); } @Override public Completable deleteMessage(Message message) { return data().delete(MessageModel.class) .where(MessageModel.ID.eq(message.getId())) .get().single().ignoreElement(); } @Override public Completable markMessage(String stanzaId, EntityBareJid recipientJid, ChatMarkerState state) { return data().update(MessageModel.class) .set(MessageModel.CHAT_MARKER_STATE, state) .where(MessageModel.LEGACY_ID.eq(stanzaId) .and(MessageModel.RECIPIENT.eq(recipientJid))) .get().single().ignoreElement(); } @Override public Completable updateDeliveryState(UUID messageId, MessageDeliveryState deliveryState) { return data().update(MessageModel.class) .set(MessageModel.DELIVERY_STATE, deliveryState) .where(MessageModel.ID.eq(messageId)) .get().single() .ignoreElement(); } private List messageModelsToEntities(List models) { List entities = new ArrayList<>(models.size()); for (MessageModel model : models) { entities.add(messageMapping.toEntity(model)); } return entities; } }