package org.mercury_im.messenger.data.repository; 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.DirectChatModel; import org.mercury_im.messenger.data.model.DirectMessagesRelation; import org.mercury_im.messenger.data.model.GroupChatModel; import org.mercury_im.messenger.data.model.GroupMessagesRelation; 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.Message; import java.util.ArrayList; import java.util.List; 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(DirectChat chat, Message message) { return directChatDao.get(chat.getId()).maybe() .switchIfEmpty(directChatDao.insert(directChatMapping.toModel(chat))) .map(chatModel -> toRelation(chatModel, messageMapping.toModel(message))) .flatMap(data()::insert) .map(DirectMessagesRelation::getMessage) .map(messageModel -> messageMapping.toEntity(messageModel, message)); } @Override public Single insertMessage(GroupChat chat, Message message) { return groupChatDao.get(chat.getId()).maybe() .switchIfEmpty(groupChatDao.insert(groupChatMapping.toModel(chat))) .map(chatModel -> toRelation(chatModel, messageMapping.toModel(message))) .flatMap(data()::insert) .map(GroupMessagesRelation::getMessage) .map(messageModel -> messageMapping.toEntity(messageModel, message)); } @Override public Observable> observeMessages(DirectChat chat) { return data().select(MessageModel.class) .from(MessageModel.class) .join(DirectMessagesRelation.class) .on(DirectMessagesRelation.MESSAGE_ID.eq(MessageModel.ID)) .where(DirectMessagesRelation.CHAT_ID.eq(chat.getId())) .get().observableResult() .map(ResultDelegate::toList) .map(this::messageModelsToEntities); } @Override public Observable> observeMessages(GroupChat chat) { return data().select(MessageModel.class) .from(MessageModel.class) .join(GroupMessagesRelation.class) .on(GroupMessagesRelation.MESSAGE_ID.eq(MessageModel.ID)) .where(GroupMessagesRelation.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.eq(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) .join(DirectMessagesRelation.class) .on(DirectMessagesRelation.MESSAGE_ID.eq(MessageModel.ID)) .where(MessageModel.BODY.eq(body)) .and(DirectMessagesRelation.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) .join(GroupMessagesRelation.class) .on(GroupMessagesRelation.MESSAGE_ID.eq(MessageModel.ID)) .where(MessageModel.BODY.eq(body)) .and(GroupMessagesRelation.CHAT_ID.eq(chat.getId())) .get().observableResult() .map(ResultDelegate::toList) .map(this::messageModelsToEntities); } @Override public Single upsertMessage(DirectChat chat, Message message) { return null; } @Override public Single upsertMessage(GroupChat chat, Message message) { return null; } @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(); } private DirectMessagesRelation toRelation(DirectChatModel chat, MessageModel message) { DirectMessagesRelation relation = new DirectMessagesRelation(); relation.setChat(chat); relation.setMessage(message); return relation; } private GroupMessagesRelation toRelation(GroupChatModel chat, MessageModel message) { GroupMessagesRelation relation = new GroupMessagesRelation(); relation.setChat(chat); relation.setMessage(message); return relation; } private List messageModelsToEntities(List models) { List entities = new ArrayList<>(models.size()); for (MessageModel model : models) { entities.add(messageMapping.toEntity(model)); } return entities; } }