package org.mercury_im.messenger.data.repository; import org.mercury_im.messenger.core.data.repository.GroupChatRepository; import org.mercury_im.messenger.core.util.Optional; import org.mercury_im.messenger.data.mapping.GroupChatMapping; import org.mercury_im.messenger.data.model.GroupChatModel; import org.mercury_im.messenger.data.repository.dao.GroupChatDao; import org.mercury_im.messenger.entity.Account; import org.mercury_im.messenger.entity.chat.GroupChat; import java.util.ArrayList; import java.util.List; import java.util.UUID; import javax.inject.Inject; import io.reactivex.Completable; import io.reactivex.Maybe; import io.reactivex.Observable; import io.reactivex.Single; import io.requery.Persistable; import io.requery.query.ResultDelegate; import io.requery.reactivex.ReactiveEntityStore; public class RxGroupChatRepository extends RequeryRepository implements GroupChatRepository { private final GroupChatMapping groupChatMapping; private final GroupChatDao dao; @Inject public RxGroupChatRepository( ReactiveEntityStore data, GroupChatMapping groupChatMapping) { super(data); this.groupChatMapping = groupChatMapping; this.dao = new GroupChatDao(data); } @Override public Single insertGroupChat(GroupChat chat) { return Single.just(chat) .map(groupChatMapping::toModel) .flatMap(dao::insert) .map(model -> groupChatMapping.toEntity(model, chat)); } @Override public Observable> observeGroupChat(UUID chatId) { return dao.get(chatId).observableResult() .map(result -> new Optional<>(result.firstOrNull())) .map(groupChatMapping::toEntity); } @Override public Maybe getGroupChat(UUID chatId) { return dao.get(chatId).maybe() .map(groupChatMapping::toEntity); } @Override public Single getOrCreateGroupChat(Account account, String roomAddress) { return getGroupChatByRoomAddress(account, roomAddress) .switchIfEmpty(Single.just(new GroupChat()) .map(chat -> { chat.setAccount(account); chat.setRoomAddress(roomAddress); return chat; }) .flatMap(this::insertGroupChat)); } @Override public Observable> observeGroupChatByRoomAddress(UUID accountId, String roomAddress) { return dao.get(accountId, roomAddress).observableResult() .map(result -> new Optional<>(result.firstOrNull())) .map(groupChatMapping::toEntity); } @Override public Maybe getGroupChatByRoomAddress(UUID accountId, String roomAddress) { return dao.get(accountId, roomAddress).maybe() .map(groupChatMapping::toEntity); } @Override public Observable> observeAllGroupChats() { return dao.getAll().observableResult() .map(ResultDelegate::toList) .map(this::modelsToEntities); } @Override public Observable> observeAllGroupChatsOfAccount(UUID accountId) { return data().select(GroupChatModel.class) .where(GroupChatModel.ACCOUNT_ID.eq(accountId)) .get().observableResult() .map(ResultDelegate::toList) .map(this::modelsToEntities); } private List modelsToEntities(List models) { List entities = new ArrayList<>(models.size()); for (GroupChatModel model : models) { entities.add(groupChatMapping.toEntity(model)); } return entities; } @Override public Single updateGroupChat(GroupChat chat) { return dao.get(chat.getId()).maybe().toSingle() .map(model -> groupChatMapping.toModel(chat, model)) .flatMap(data()::update) .map(model -> groupChatMapping.toEntity(model, chat)); } @Override public Single upsertGroupChat(GroupChat chat) { return dao.get(chat.getId()).maybe() .switchIfEmpty(Single.just(chat).map(groupChatMapping::toModel) .flatMap(dao::insert)) .map(model -> groupChatMapping.toModel(chat, model)) .flatMap(data()::update) .map(model -> groupChatMapping.toEntity(model, chat)); } @Override public Completable deleteGroupChat(UUID chatId) { return dao.delete(chatId).ignoreElement(); } }