Improve usage or rx, start working on message storage

This commit is contained in:
Paul Schaub 2019-12-07 02:04:31 +01:00
parent 1767a24fde
commit ba15acf659
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
24 changed files with 655 additions and 381 deletions

View file

@ -9,8 +9,6 @@ import android.content.Context;
import android.content.Intent;
import android.os.Build;
import org.mercury_im.messenger.data.di.MappingModule;
import org.mercury_im.messenger.data.di.RepositoryModule;
import org.mercury_im.messenger.di.component.AppComponent;
import org.mercury_im.messenger.di.component.DaggerAppComponent;
import org.mercury_im.messenger.di.module.AppModule;

View file

@ -7,6 +7,7 @@ import androidx.lifecycle.ViewModel;
import org.jxmpp.jid.EntityBareJid;
import org.mercury_im.messenger.MercuryImApplication;
import org.mercury_im.messenger.data.repository.DirectChatRepository;
import org.mercury_im.messenger.data.repository.MessageRepository;
import org.mercury_im.messenger.data.repository.PeerRepository;
import org.mercury_im.messenger.entity.chat.DirectChat;
import org.mercury_im.messenger.entity.contact.Peer;
@ -30,6 +31,9 @@ public class ChatViewModel extends ViewModel {
@Inject
DirectChatRepository chatRepository;
@Inject
MessageRepository messageRepository;
private MutableLiveData<Peer> contact = new MutableLiveData<>();
private MutableLiveData<List<Message>> messages = new MutableLiveData<>();
private MutableLiveData<String> contactDisplayName = new MutableLiveData<>();
@ -58,7 +62,7 @@ public class ChatViewModel extends ViewModel {
.subscribe(peer -> contactDisplayName.setValue(peer.getItem().getName())));
// Subscribe messages
disposable.add(chatRepository.observeMessages(chat)
disposable.add(messageRepository.observeMessages(chat)
.subscribe(ChatViewModel.this.messages::setValue));
}

View file

@ -3,9 +3,9 @@ package org.mercury_im.messenger.data.di;
import org.mercury_im.messenger.data.mapping.AccountMapping;
import org.mercury_im.messenger.data.mapping.DirectChatMapping;
import org.mercury_im.messenger.data.mapping.GroupChatMapping;
import org.mercury_im.messenger.data.mapping.MessageContentMapping;
import org.mercury_im.messenger.data.mapping.MessageMapping;
import org.mercury_im.messenger.data.mapping.MessagePayloadMapping;
import org.mercury_im.messenger.data.mapping.MessageMapping;
import org.mercury_im.messenger.data.mapping.MessagePayloadContainerMapping;
import org.mercury_im.messenger.data.mapping.PeerMapping;
import javax.inject.Singleton;
@ -48,13 +48,13 @@ public class MappingModule {
@Provides
@Singleton
static MessagePayloadMapping provideMessagePayloadMapping() {
return new MessagePayloadMapping(provideMessageContentMapping());
static MessagePayloadContainerMapping provideMessagePayloadMapping() {
return new MessagePayloadContainerMapping(provideMessageContentMapping());
}
@Provides
@Singleton
static MessageContentMapping provideMessageContentMapping() {
return new MessageContentMapping();
static MessagePayloadMapping provideMessageContentMapping() {
return new MessagePayloadMapping();
}
}

View file

@ -3,15 +3,18 @@ package org.mercury_im.messenger.data.di;
import org.mercury_im.messenger.data.mapping.AccountMapping;
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.mapping.PeerMapping;
import org.mercury_im.messenger.data.repository.AccountRepository;
import org.mercury_im.messenger.data.repository.GroupChatRepository;
import org.mercury_im.messenger.data.repository.MessageRepository;
import org.mercury_im.messenger.data.repository.PeerRepository;
import org.mercury_im.messenger.data.repository.DirectChatRepository;
import org.mercury_im.messenger.data.repository.EntityCapsRepository;
import org.mercury_im.messenger.data.repository.XmppAccountRepository;
import org.mercury_im.messenger.data.repository.XmppDirectChatRepository;
import org.mercury_im.messenger.data.repository.XmppGroupChatRepository;
import org.mercury_im.messenger.data.repository.XmppMessageRepository;
import org.mercury_im.messenger.data.repository.XmppPeerRepository;
import org.mercury_im.messenger.util.ThreadUtils;
@ -69,6 +72,21 @@ public class RepositoryModule {
return new XmppGroupChatRepository(data, ioScheduler, uiScheduler, groupChatMapping);
}
@Provides
@Singleton
public static MessageRepository provideMessageRepository(
ReactiveEntityStore<Persistable> data,
@Named(value = ThreadUtils.SCHEDULER_IO) Scheduler ioScheduler,
@Named(value = ThreadUtils.SCHEDULER_UI) Scheduler uiScheduler,
MessageMapping messageMapping,
DirectChatMapping directChatMapping,
GroupChatMapping groupChatMapping,
DirectChatRepository directChatRepository,
GroupChatRepository groupChatRepository) {
return new XmppMessageRepository(data, ioScheduler, uiScheduler, messageMapping,
directChatMapping, groupChatMapping, directChatRepository, groupChatRepository);
}
@Provides
@Singleton
public static EntityCapsRepository provideCapsRepository(

View file

@ -0,0 +1,76 @@
package org.mercury_im.messenger.data.mapping;
import lombok.NonNull;
public abstract class AbstractMapping<E, M> implements Mapping<E, M> {
@Override
public M toModel(E entity) {
if (entity == null) {
return null;
}
return toModel(entity, newModel(entity));
}
@Override
public E toEntity(M model) {
if (model == null) {
return null;
}
return toEntity(model, newEntity(model));
}
@Override
public M toModel(E entity, M model) {
if (entity == null) {
return null;
}
if (model == null) {
model = newModel(entity);
}
return mapToModel(entity, model);
}
@Override
public E toEntity(M model, E entity) {
if (model == null) {
return null;
}
if (entity == null) {
entity = newEntity(model);
}
return mapToEntity(model, entity);
}
/**
* Return a new entity object.
*
* @return entity
*/
protected abstract E newEntity(@NonNull M model);
/**
* Return a new database model object.
*
* @return model
*/
protected abstract M newModel(@NonNull E entity);
/**
* Copy data from the entity to the given model.
*
* @param entity application entity
* @param model database model
* @return the database model
*/
protected abstract M mapToModel(@NonNull E entity, @NonNull M model);
/**
* Copy data from the database model to the entity.
*
* @param model database model
* @param entity entity
* @return the application entity
*/
protected abstract E mapToEntity(@NonNull M model, @NonNull E entity);
}

View file

@ -7,7 +7,7 @@ import org.mercury_im.messenger.entity.PasswordAuthentication;
import javax.inject.Inject;
public class AccountMapping implements Mapping<Account, AccountModel> {
public class AccountMapping extends AbstractMapping<Account, AccountModel> {
@Inject
public AccountMapping() {
@ -15,32 +15,30 @@ public class AccountMapping implements Mapping<Account, AccountModel> {
}
@Override
public AccountModel entityToModel(Account entity, AccountModel model) {
if (entity == null) {
return null;
}
if (model == null) {
model = new AccountModel();
}
model.setPassword(entity.getAuthentication().getPassword());
public Account newEntity(AccountModel model) {
return new IAccount();
}
@Override
public AccountModel newModel(Account entity) {
return new AccountModel();
}
@Override
public AccountModel mapToModel(Account entity, AccountModel model) {
model.setAddress(entity.getAddress());
model.setPassword(entity.getAuthentication().getPassword());
model.setEnabled(entity.isEnabled());
return model;
}
@Override
public Account modelToEntity(AccountModel model, Account entity) {
if (model == null) {
return null;
}
if (entity == null) {
entity = new IAccount();
}
public Account mapToEntity(AccountModel model, Account entity) {
entity.setId(model.getId());
entity.setAddress(model.getAddress());
entity.setEnabled(model.isEnabled());
entity.setAuthentication(new PasswordAuthentication(model.getPassword()));
entity.setEnabled(model.isEnabled());
return entity;
}

View file

@ -7,7 +7,7 @@ import org.mercury_im.messenger.entity.contact.Peer;
import javax.inject.Inject;
public class DirectChatMapping implements Mapping<DirectChat, DirectChatModel> {
public class DirectChatMapping extends AbstractMapping<DirectChat, DirectChatModel> {
private final PeerMapping peerMapping;
@ -17,27 +17,25 @@ public class DirectChatMapping implements Mapping<DirectChat, DirectChatModel> {
}
@Override
public DirectChatModel entityToModel(DirectChat entity, DirectChatModel model) {
if (entity == null) {
return null;
}
if (model == null) {
model = new DirectChatModel();
}
model.setPeer(peerMapping.entityToModel(entity.getPeer(), model.getPeer()));
public DirectChat newEntity(DirectChatModel model) {
return new IDirectChat();
}
@Override
public DirectChatModel newModel(DirectChat entity) {
return new DirectChatModel();
}
@Override
public DirectChatModel mapToModel(DirectChat entity, DirectChatModel model) {
model.setPeer(peerMapping.toModel(entity.getPeer(), model.getPeer()));
return model;
}
@Override
public DirectChat modelToEntity(DirectChatModel model, DirectChat entity) {
if (model == null) {
return null;
}
if (entity == null) {
entity = new IDirectChat();
}
public DirectChat mapToEntity(DirectChatModel model, DirectChat entity) {
entity.setId(model.getId());
Peer peer = peerMapping.modelToEntity(model.getPeer(), entity.getPeer());
Peer peer = peerMapping.toEntity(model.getPeer(), entity.getPeer());
entity.setPeer(peer);
entity.setAccount(peer.getAccount());
return entity;

View file

@ -6,7 +6,7 @@ import org.mercury_im.messenger.entity.chat.IGroupChat;
import javax.inject.Inject;
public class GroupChatMapping implements Mapping<GroupChat, GroupChatModel> {
public class GroupChatMapping extends AbstractMapping<GroupChat, GroupChatModel> {
private final AccountMapping accountMapping;
@ -16,29 +16,27 @@ public class GroupChatMapping implements Mapping<GroupChat, GroupChatModel> {
}
@Override
public GroupChatModel entityToModel(GroupChat entity, GroupChatModel model) {
if (entity == null) {
return null;
}
if (model == null) {
model = new GroupChatModel();
}
model.setAccount(accountMapping.entityToModel(entity.getAccount(), model.getAccount()));
public GroupChat newEntity(GroupChatModel model) {
return new IGroupChat();
}
@Override
public GroupChatModel newModel(GroupChat entity) {
return new GroupChatModel();
}
@Override
public GroupChatModel mapToModel(GroupChat entity, GroupChatModel model) {
model.setAccount(accountMapping.toModel(entity.getAccount(), model.getAccount()));
model.setAddress(entity.getRoomAddress());
model.setName(entity.getRoomName());
return model;
}
@Override
public GroupChat modelToEntity(GroupChatModel model, GroupChat entity) {
if (model == null) {
return null;
}
if (entity == null) {
entity = new IGroupChat();
}
public GroupChat mapToEntity(GroupChatModel model, GroupChat entity) {
entity.setId(model.getId());
entity.setAccount(accountMapping.modelToEntity(model.getAccount(), entity.getAccount()));
entity.setAccount(accountMapping.toEntity(model.getAccount(), entity.getAccount()));
entity.setRoomAddress(model.getAddress());
entity.setRoomName(model.getName());
return entity;

View file

@ -9,18 +9,37 @@ package org.mercury_im.messenger.data.mapping;
public interface Mapping<E, M> {
/**
* Copy data from the entity to the model.
* Map data from the entity to a new model.
*
* @param entity application entity
* @param model database model
* @return new database model
*/
M entityToModel(E entity, M model);
M toModel(E entity);
/**
* Copy data from the database model to the entity.
*
* Copy data from the model to a new entity.
* @param model database model
* @param entity entity
* @return new application entity
*/
E modelToEntity(M model, E entity);
E toEntity(M model);
/**
* Map an entity to a model.
*
* @param entity entity
* @param model model
* @return model
*/
M toModel(E entity, M model);
/**
* Map a model to an entity.
*
* @param model model
* @param entity entity
* @return entity
*/
E toEntity(M model, E entity);
}

View file

@ -1,44 +0,0 @@
package org.mercury_im.messenger.data.mapping;
import org.mercury_im.messenger.data.model.MessagePayloadModel;
import org.mercury_im.messenger.entity.message.content.Payload;
import org.mercury_im.messenger.entity.message.content.TextPayload;
import static org.mercury_im.messenger.data.enums.MessageContentType.body;
public class MessageContentMapping implements Mapping<Payload, MessagePayloadModel> {
@Override
public MessagePayloadModel entityToModel(Payload entity, MessagePayloadModel model) {
if (entity == null) {
return null;
}
if (model == null) {
model = new MessagePayloadModel();
}
if (entity instanceof TextPayload) {
model.setType(body);
model.setBody(((TextPayload) entity).getBody());
}
// else if (...)
return model;
}
@Override
public Payload modelToEntity(MessagePayloadModel model, Payload entity) {
if (model == null) {
model = new MessagePayloadModel();
}
switch (model.getType()) {
case body:
if (entity == null) {
TextPayload body = new TextPayload();
body.setId(model.getId());
body.setBody(model.getBody());
entity = body;
}
}
return entity;
}
}

View file

@ -8,30 +8,34 @@ import org.mercury_im.messenger.entity.message.PayloadContainer;
import javax.inject.Inject;
public class MessageMapping implements Mapping<Message, MessageModel> {
public class MessageMapping extends AbstractMapping<Message, MessageModel> {
private final MessagePayloadMapping messagePayloadMapping;
private final MessagePayloadContainerMapping messagePayloadContainerMapping;
@Inject
public MessageMapping(MessagePayloadMapping messagePayloadMapping) {
this.messagePayloadMapping = messagePayloadMapping;
public MessageMapping(MessagePayloadContainerMapping messagePayloadContainerMapping) {
this.messagePayloadContainerMapping = messagePayloadContainerMapping;
}
@Override
public MessageModel entityToModel(Message entity, MessageModel model) {
if (entity == null) {
return null;
}
if (model == null) {
model = new MessageModel();
}
public Message newEntity(MessageModel model) {
return new IMessage();
}
@Override
public MessageModel newModel(Message entity) {
return new MessageModel();
}
@Override
public MessageModel mapToModel(Message entity, MessageModel model) {
model.setSender(entity.getSender());
model.setRecipient(entity.getRecipient());
model.setTimestamp(entity.getTimestamp());
model.getPayloads().clear();
for (PayloadContainer payload : entity.getMessagePayloads()) {
MessagePayloadContainerModel payloadModel = messagePayloadMapping.entityToModel(payload, new MessagePayloadContainerModel());
MessagePayloadContainerModel payloadModel = messagePayloadContainerMapping.toModel(payload, new MessagePayloadContainerModel());
payloadModel.setMessage(model);
model.getPayloads().add(payloadModel);
}
@ -40,13 +44,7 @@ public class MessageMapping implements Mapping<Message, MessageModel> {
}
@Override
public Message modelToEntity(MessageModel model, Message entity) {
if (model == null) {
return null;
}
if (entity == null) {
entity = new IMessage();
}
public Message mapToEntity(MessageModel model, Message entity) {
return null;
}
}

View file

@ -0,0 +1,58 @@
package org.mercury_im.messenger.data.mapping;
import org.mercury_im.messenger.data.model.MessagePayloadModel;
import org.mercury_im.messenger.data.model.MessagePayloadContainerModel;
import org.mercury_im.messenger.entity.message.IPayloadContainer;
import org.mercury_im.messenger.entity.message.PayloadContainer;
import org.mercury_im.messenger.entity.message.content.Payload;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
public class MessagePayloadContainerMapping extends AbstractMapping<PayloadContainer, MessagePayloadContainerModel> {
private final MessagePayloadMapping messagePayloadMapping;
@Inject
public MessagePayloadContainerMapping(MessagePayloadMapping messagePayloadMapping) {
this.messagePayloadMapping = messagePayloadMapping;
}
@Override
public PayloadContainer newEntity(MessagePayloadContainerModel model) {
return new IPayloadContainer();
}
@Override
public MessagePayloadContainerModel newModel(PayloadContainer entity) {
return new MessagePayloadContainerModel();
}
@Override
public MessagePayloadContainerModel mapToModel(PayloadContainer entity, MessagePayloadContainerModel model) {
model.getContents().clear();
for (Payload contentEntity : entity.getMessageContents()) {
MessagePayloadModel contentModel = messagePayloadMapping.toModel(contentEntity, new MessagePayloadModel());
contentModel.setPayload(model);
model.getContents().add(contentModel);
}
return model;
}
@Override
public PayloadContainer mapToEntity(MessagePayloadContainerModel model, PayloadContainer entity) {
entity.setId(model.getId());
List<Payload> contents = new ArrayList<>(model.getContents().size());
for (MessagePayloadModel contentModel : model.getContents()) {
Payload contentEntity = messagePayloadMapping.toEntity(contentModel, null);
contents.add(contentEntity);
}
entity.setMessageContents(contents);
return entity;
}
}

View file

@ -1,62 +1,47 @@
package org.mercury_im.messenger.data.mapping;
import org.mercury_im.messenger.data.model.MessagePayloadModel;
import org.mercury_im.messenger.data.model.MessagePayloadContainerModel;
import org.mercury_im.messenger.entity.message.IPayloadContainer;
import org.mercury_im.messenger.entity.message.PayloadContainer;
import org.mercury_im.messenger.entity.message.content.Payload;
import org.mercury_im.messenger.entity.message.content.TextPayload;
import java.util.ArrayList;
import java.util.List;
import static org.mercury_im.messenger.data.enums.MessageContentType.body;
import javax.inject.Inject;
public class MessagePayloadMapping extends AbstractMapping<Payload, MessagePayloadModel> {
public class MessagePayloadMapping implements Mapping<PayloadContainer, MessagePayloadContainerModel> {
private final MessageContentMapping messageContentMapping;
@Inject
public MessagePayloadMapping(MessageContentMapping messageContentMapping) {
this.messageContentMapping = messageContentMapping;
@Override
public Payload newEntity(MessagePayloadModel model) {
switch (model.getType()) {
case body:
return new TextPayload();
default:
return null;
}
}
@Override
public MessagePayloadContainerModel entityToModel(PayloadContainer entity, MessagePayloadContainerModel model) {
if (entity == null) {
return null;
}
if (model == null) {
model = new MessagePayloadContainerModel();
}
public MessagePayloadModel newModel(Payload entity) {
return new MessagePayloadModel();
}
model.getContents().clear();
for (Payload contentEntity : entity.getMessageContents()) {
MessagePayloadModel contentModel = messageContentMapping.entityToModel(contentEntity, new MessagePayloadModel());
contentModel.setPayload(model);
model.getContents().add(contentModel);
@Override
public MessagePayloadModel mapToModel(Payload entity, MessagePayloadModel model) {
if (entity instanceof TextPayload) {
model.setType(body);
model.setBody(((TextPayload) entity).getBody());
}
// else if (...)
return model;
}
@Override
public PayloadContainer modelToEntity(MessagePayloadContainerModel model, PayloadContainer entity) {
if (model == null) {
return null;
}
if (entity == null) {
entity = new IPayloadContainer();
}
public Payload mapToEntity(MessagePayloadModel model, Payload entity) {
entity.setId(model.getId());
List<Payload> contents = new ArrayList<>(model.getContents().size());
for (MessagePayloadModel contentModel : model.getContents()) {
Payload contentEntity = messageContentMapping.modelToEntity(contentModel, null);
contents.add(contentEntity);
switch (model.getType()) {
case body:
TextPayload body = (TextPayload) entity;
body.setBody(model.getBody());
break;
}
entity.setMessageContents(contents);
return entity;
}
}

View file

@ -7,7 +7,7 @@ import org.mercury_im.messenger.entity.contact.Peer;
import javax.inject.Inject;
public class PeerMapping implements Mapping<Peer, PeerModel> {
public class PeerMapping extends AbstractMapping<Peer, PeerModel> {
private final AccountMapping accountMapping;
@ -17,14 +17,18 @@ public class PeerMapping implements Mapping<Peer, PeerModel> {
}
@Override
public PeerModel entityToModel(Peer entity, PeerModel model) {
if (entity == null) {
return null;
}
if (model == null) {
model = new PeerModel();
}
model.setAccount(accountMapping.entityToModel(entity.getAccount(), model.getAccount()));
public Peer newEntity(PeerModel model) {
return new IPeer();
}
@Override
public PeerModel newModel(Peer entity) {
return new PeerModel();
}
@Override
public PeerModel mapToModel(Peer entity, PeerModel model) {
model.setAccount(accountMapping.toModel(entity.getAccount(), model.getAccount()));
model.setAddress(entity.getAddress());
model.setName(entity.getName());
@ -34,14 +38,8 @@ public class PeerMapping implements Mapping<Peer, PeerModel> {
}
@Override
public Peer modelToEntity(PeerModel model, Peer entity) {
if (model == null) {
return null;
}
if (entity == null) {
entity = new IPeer();
}
entity.setAccount(accountMapping.modelToEntity(model.getAccount(), entity.getAccount()));
public Peer mapToEntity(PeerModel model, Peer entity) {
entity.setAccount(accountMapping.toEntity(model.getAccount(), entity.getAccount()));
entity.setAddress(model.getAddress());
entity.setId(model.getId());

View file

@ -39,8 +39,10 @@ public class XmppAccountRepository
@Override
public Single<Account> insertAccount(Account account) {
return data().insert(accountMapping.entityToModel(account, new AccountModel()))
.map(model -> accountMapping.modelToEntity(model, account))
return Single.just(account)
.map(accountMapping::toModel)
.flatMap(data()::insert)
.map(model -> accountMapping.toEntity(model, account))
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@ -50,7 +52,9 @@ public class XmppAccountRepository
return data().select(AccountModel.class)
.where(AccountModel.ID.eq(accountId))
.get().observableResult()
.map(result -> new Optional<>(accountMapping.modelToEntity(result.firstOrNull(), new IAccount())))
.map(ResultDelegate::firstOrNull)
.map(accountMapping::toEntity)
.map(Optional::new)
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@ -60,7 +64,7 @@ public class XmppAccountRepository
return data().select(AccountModel.class)
.where(AccountModel.ID.eq(accountId))
.get().maybe()
.map(model -> accountMapping.modelToEntity(model, new IAccount()))
.map(accountMapping::toEntity)
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@ -70,7 +74,9 @@ public class XmppAccountRepository
return data().select(AccountModel.class)
.where(AccountModel.ADDRESS.eq(address))
.get().observableResult()
.map(result -> new Optional<>(accountMapping.modelToEntity(result.firstOrNull(), new IAccount())))
.map(ResultDelegate::firstOrNull)
.map(accountMapping::toEntity)
.map(Optional::new)
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@ -80,7 +86,7 @@ public class XmppAccountRepository
return data().select(AccountModel.class)
.where(AccountModel.ADDRESS.eq(address))
.get().maybe()
.map(model -> accountMapping.modelToEntity(model, new IAccount()))
.map(accountMapping::toEntity)
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@ -93,7 +99,7 @@ public class XmppAccountRepository
.map(list -> {
List<Account> entities = new ArrayList<>(list.size());
for (AccountModel model : list) {
entities.add(accountMapping.modelToEntity(model, new IAccount()));
entities.add(accountMapping.toEntity(model));
}
return entities;
})
@ -109,13 +115,12 @@ public class XmppAccountRepository
// fetch model
return data().select(AccountModel.class)
.where(AccountModel.ID.eq(account.getId()))
.get().maybe().toSingle() // to single
.flatMap(model -> {
// copy changes from the entity to the model
model = accountMapping.entityToModel(account, model);
// write the updated model back
return data().update(model);
}).map(model -> accountMapping.modelToEntity(model, account))
.get().maybe().toSingle()
// copy changes from the entity to the model
.map(model -> accountMapping.toModel(account, model))
// write the updated model back
.flatMap(updatedModel -> data().update(updatedModel))
.map(model -> accountMapping.toEntity(model, account))
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@ -127,14 +132,16 @@ public class XmppAccountRepository
.where(AccountModel.ID.eq(account.getId()))
.get().maybe()
// If it does not exist, create a new model from the entity
.switchIfEmpty(data().insert(accountMapping.entityToModel(account, new AccountModel())))
.flatMap(model -> {
// update the model
model = accountMapping.entityToModel(account, model);
// write the updated model back
return data().update(model);
})
.map(model -> accountMapping.modelToEntity(model, account))
.switchIfEmpty(
Single.just(account)
.map(accountMapping::toModel)
.flatMap(data()::insert)
)
// update the model
.map(model -> accountMapping.toModel(account, model))
// write the updated model back
.flatMap(data()::update)
.map(model -> accountMapping.toEntity(model, account))
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}

View file

@ -4,11 +4,11 @@ import org.mercury_im.messenger.data.mapping.AccountMapping;
import org.mercury_im.messenger.data.mapping.DirectChatMapping;
import org.mercury_im.messenger.data.mapping.PeerMapping;
import org.mercury_im.messenger.data.model.DirectChatModel;
import org.mercury_im.messenger.data.repository.dao.DirectChatDao;
import org.mercury_im.messenger.data.util.Optional;
import org.mercury_im.messenger.entity.chat.DirectChat;
import org.mercury_im.messenger.entity.chat.IDirectChat;
import org.mercury_im.messenger.entity.contact.Peer;
import org.mercury_im.messenger.entity.message.Message;
import org.mercury_im.messenger.util.ThreadUtils;
import java.util.ArrayList;
@ -25,6 +25,7 @@ import io.reactivex.Single;
import io.requery.Persistable;
import io.requery.query.ResultDelegate;
import io.requery.reactivex.ReactiveEntityStore;
import io.requery.reactivex.ReactiveResult;
public class XmppDirectChatRepository
extends RequeryRepository
@ -36,6 +37,8 @@ public class XmppDirectChatRepository
private final DirectChatMapping directChatMapping;
private final DirectChatDao dao;
@Inject
public XmppDirectChatRepository(
ReactiveEntityStore<Persistable> data,
@ -48,14 +51,18 @@ public class XmppDirectChatRepository
this.accountMapping = accountMapping;
this.peerMapping = peerMapping;
this.directChatMapping = directChatMapping;
this.dao = new DirectChatDao(data);
}
@Override
public Single<DirectChat> insertDirectChat(DirectChat chat) {
return data().insert(directChatMapping.entityToModel(chat, new DirectChatModel()))
.map(model -> directChatMapping.modelToEntity(model, chat))
return Single.just(chat)
// map entity to model
.map(directChatMapping::toModel)
.flatMap(dao::insert)
// map back to entity
.map(model -> directChatMapping.toEntity(model, chat))
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@ -65,8 +72,9 @@ public class XmppDirectChatRepository
return data().select(DirectChatModel.class)
.where(DirectChatModel.ID.eq(chatId))
.get().observableResult()
.map(result -> new Optional<>(
directChatMapping.modelToEntity(result.firstOrNull(), new IDirectChat())))
.map(ResultDelegate::firstOrNull)
.map(directChatMapping::toEntity)
.map(Optional::new)
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@ -76,18 +84,18 @@ public class XmppDirectChatRepository
return data().select(DirectChatModel.class)
.where(DirectChatModel.ID.eq(chatId))
.get().maybe()
.map(result -> directChatMapping.modelToEntity(result, new IDirectChat()))
.map(result -> directChatMapping.toEntity(result, new IDirectChat()))
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@Override
public Single<DirectChat> getOrCreateChatWithPeer(Peer _peer) {
return getDirectChatByPeer(_peer)
public Single<DirectChat> getOrCreateChatWithPeer(Peer peer) {
return getDirectChatByPeer(peer)
.switchIfEmpty(insertDirectChat(new IDirectChat(){
{
setAccount(_peer.getAccount());
setPeer(_peer);
setAccount(peer.getAccount());
setPeer(peer);
}
}))
.subscribeOn(subscriberScheduler())
@ -99,8 +107,9 @@ public class XmppDirectChatRepository
return data().select(DirectChatModel.class)
.where(DirectChatModel.PEER_ID.eq(peer.getId()))
.get().observableResult()
.map(result -> new Optional<>(
directChatMapping.modelToEntity(result.firstOrNull(), new IDirectChat())))
.map(ReactiveResult::firstOrNull)
.map(model -> directChatMapping.toEntity(model, new IDirectChat()))
.map(Optional::new)
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@ -110,7 +119,7 @@ public class XmppDirectChatRepository
return data().select(DirectChatModel.class)
.where(DirectChatModel.PEER_ID.eq(peer.getId()))
.get().maybe()
.map(model -> directChatMapping.modelToEntity(model, new IDirectChat()))
.map(model -> directChatMapping.toEntity(model, new IDirectChat()))
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@ -123,7 +132,7 @@ public class XmppDirectChatRepository
.map(list -> {
List<DirectChat> entities = new ArrayList<>(list.size());
for (DirectChatModel model : list) {
entities.add(directChatMapping.modelToEntity(model, new IDirectChat()));
entities.add(directChatMapping.toEntity(model, new IDirectChat()));
}
return entities;
})
@ -133,29 +142,36 @@ public class XmppDirectChatRepository
@Override
public Single<DirectChat> updateDirectChat(DirectChat chat) {
return data().select(DirectChatModel.class)
return dao.get(chat.getId())
// fail if not exists
.toSingle()
.map(model -> directChatMapping.toModel(chat, model))
.flatMap(data()::update)
.map(model -> directChatMapping.toEntity(model, chat))
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
Single<DirectChatModel> getOrCreateDirectChatModel(DirectChat chat) {
return data()
// fetch existing chat
.select(DirectChatModel.class)
.where(DirectChatModel.ID.eq(chat.getId()))
.get().maybe().toSingle()
.flatMap(model -> {
model = directChatMapping.entityToModel(chat, model);
return data().update(model);
})
.map(model -> directChatMapping.modelToEntity(model, chat))
.get().maybe()
.switchIfEmpty(
// If not exists, insert chat as new model and return
data().insert(directChatMapping.toModel(chat, new DirectChatModel()))
)
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@Override
public Single<DirectChat> upsertDirectChat(DirectChat chat) {
return data().select(DirectChatModel.class)
.where(DirectChatModel.ID.eq(chat.getId()))
.get().maybe()
.switchIfEmpty(data().insert(directChatMapping.entityToModel(chat, new DirectChatModel())))
.flatMap(model -> {
model = directChatMapping.entityToModel(chat, model);
return data().update(model);
})
.map(model -> directChatMapping.modelToEntity(model, chat))
return getOrCreateDirectChatModel(chat)
.map(directChatModel -> directChatMapping.toModel(chat, directChatModel))
.flatMap(data()::update)
.map(model -> directChatMapping.toEntity(model, chat))
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@ -168,29 +184,4 @@ public class XmppDirectChatRepository
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@Override
public Single<Message> insertMessage(DirectChat chat, Message message) {
return null;
}
@Override
public Observable<List<Message>> observeMessages(DirectChat chat) {
return null;
}
@Override
public Single<Message> updateMessage(Message message) {
return null;
}
@Override
public Single<Message> upsertMessage(DirectChat chat, Message message) {
return null;
}
@Override
public Completable deleteMessage(Message message) {
return null;
}
}

View file

@ -6,7 +6,6 @@ import org.mercury_im.messenger.data.util.Optional;
import org.mercury_im.messenger.entity.Account;
import org.mercury_im.messenger.entity.chat.GroupChat;
import org.mercury_im.messenger.entity.chat.IGroupChat;
import org.mercury_im.messenger.entity.message.Message;
import org.mercury_im.messenger.util.ThreadUtils;
import java.util.ArrayList;
@ -42,8 +41,10 @@ public class XmppGroupChatRepository
@Override
public Single<GroupChat> insertGroupChat(GroupChat chat) {
return data().insert(groupChatMapping.entityToModel(chat, new GroupChatModel()))
.map(model -> groupChatMapping.modelToEntity(model, chat))
return Single.just(chat)
.map(groupChatMapping::toModel)
.flatMap(data()::insert)
.map(model -> groupChatMapping.toEntity(model, chat))
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@ -53,8 +54,9 @@ public class XmppGroupChatRepository
return data().select(GroupChatModel.class)
.where(GroupChatModel.ID.eq(chatId))
.get().observableResult()
.map(result -> new Optional<>(
groupChatMapping.modelToEntity(result.firstOrNull(), new IGroupChat())))
.map(ResultDelegate::firstOrNull)
.map(groupChatMapping::toEntity)
.map(Optional::new)
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@ -64,7 +66,7 @@ public class XmppGroupChatRepository
return data().select(GroupChatModel.class)
.where(GroupChatModel.ID.eq(chatId))
.get().maybe()
.map(model -> groupChatMapping.modelToEntity(model, new IGroupChat()))
.map(groupChatMapping::toEntity)
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@ -72,12 +74,14 @@ public class XmppGroupChatRepository
@Override
public Single<GroupChat> getOrCreateGroupChat(Account account, String roomAddress) {
return getGroupChatByRoomAddress(account, roomAddress)
.switchIfEmpty(insertGroupChat(new IGroupChat(){
{
setAccount(account);
setRoomAddress(roomAddress);
}
}))
.switchIfEmpty(Single
.just((GroupChat) new IGroupChat() {
{
setAccount(account);
setRoomAddress(roomAddress);
}
})
.flatMap(this::insertGroupChat))
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@ -88,8 +92,9 @@ public class XmppGroupChatRepository
.where(GroupChatModel.ADDRESS.eq(roomAddress))
.and(GroupChatModel.ACCOUNT_ID.eq(accountId))
.get().observableResult()
.map(result -> new Optional<>(
groupChatMapping.modelToEntity(result.firstOrNull(), new IGroupChat())))
.map(ResultDelegate::firstOrNull)
.map(groupChatMapping::toEntity)
.map(Optional::new)
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@ -100,7 +105,7 @@ public class XmppGroupChatRepository
.where(GroupChatModel.ADDRESS.eq(roomAddress))
.and(GroupChatModel.ACCOUNT_ID.eq(accountId))
.get().maybe()
.map(model -> groupChatMapping.modelToEntity(model, new IGroupChat()))
.map(groupChatMapping::toEntity)
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@ -113,7 +118,7 @@ public class XmppGroupChatRepository
.map(list -> {
List<GroupChat> entities = new ArrayList<>(list.size());
for (GroupChatModel model : list) {
entities.add(groupChatMapping.modelToEntity(model, new IGroupChat()));
entities.add(groupChatMapping.toEntity(model));
}
return entities;
})
@ -126,13 +131,26 @@ public class XmppGroupChatRepository
return data().select(GroupChatModel.class)
.where(GroupChatModel.ID.eq(chat.getId()))
.get().maybe().toSingle() // to single
.flatMap(model -> {
// copy changes from entity to the model
model = groupChatMapping.entityToModel(chat, model);
// write the updated model back
return data().update(model);
})
.map(model -> groupChatMapping.modelToEntity(model, chat))
// copy changes from entity to the model
.map(model -> groupChatMapping.toModel(chat, model))
// write the updated model back
.flatMap(data()::update)
// map back
.map(model -> groupChatMapping.toEntity(model, chat))
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
Single<GroupChatModel> getOrCreateGroupChatModel(GroupChat chat) {
// fetch existing model
return data().select(GroupChatModel.class)
.where(GroupChatModel.ID.eq(chat.getId()))
.get().maybe()
// if not found, create a new one and insert it
.switchIfEmpty(
Single.just(chat)
.map(groupChatMapping::toModel)
.flatMap(data()::insert))
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@ -140,18 +158,12 @@ public class XmppGroupChatRepository
@Override
public Single<GroupChat> upsertGroupChat(GroupChat chat) {
// Try to fetch model
return data().select(GroupChatModel.class)
.where(GroupChatModel.ID.eq(chat.getId()))
.get().maybe()
// If it does not exist, create a new model from the entity
.switchIfEmpty(data().insert(groupChatMapping.entityToModel(chat, new GroupChatModel())))
.flatMap(model -> {
// update the model
model = groupChatMapping.entityToModel(chat, model);
// write the updated model back
return data().update(model);
})
.map(model -> groupChatMapping.modelToEntity(model, chat))
return getOrCreateGroupChatModel(chat)
// update the model
.map(model -> groupChatMapping.toModel(chat, model))
// write the updated model back
.flatMap(data()::update)
.map(model -> groupChatMapping.toEntity(model, chat))
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@ -164,29 +176,4 @@ public class XmppGroupChatRepository
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@Override
public Single<Message> insertMessage(GroupChat chat, Message message) {
return null;
}
@Override
public Observable<List<Message>> observeMessages(GroupChat chat) {
return null;
}
@Override
public Single<Message> updateMessage(Message message) {
return null;
}
@Override
public Single<Message> upsertMessage(GroupChat chat, Message message) {
return null;
}
@Override
public Completable deleteMessage(Message message) {
return null;
}
}

View file

@ -0,0 +1,127 @@
package org.mercury_im.messenger.data.repository;
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.MessageModel;
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 org.mercury_im.messenger.util.ThreadUtils;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
import io.reactivex.Completable;
import io.reactivex.Observable;
import io.reactivex.Scheduler;
import io.reactivex.Single;
import io.requery.Persistable;
import io.requery.reactivex.ReactiveEntityStore;
public class XmppMessageRepository
extends RequeryRepository
implements MessageRepository {
private final MessageMapping messageMapping;
private final DirectChatMapping directChatMapping;
private final GroupChatMapping groupChatMapping;
private final DirectChatRepository directChatRepository;
private final GroupChatRepository groupChatRepository;
@Inject
public XmppMessageRepository(ReactiveEntityStore<Persistable> data,
@Named(value = ThreadUtils.SCHEDULER_IO) Scheduler subscriberScheduler,
@Named(value = ThreadUtils.SCHEDULER_UI) Scheduler observerScheduler,
MessageMapping messageMapping,
DirectChatMapping directChatMapping,
GroupChatMapping groupChatMapping,
DirectChatRepository directChatRepository,
GroupChatRepository groupChatRepository) {
super(data, subscriberScheduler, observerScheduler);
this.messageMapping = messageMapping;
this.directChatMapping = directChatMapping;
this.groupChatMapping = groupChatMapping;
this.directChatRepository = directChatRepository;
this.groupChatRepository = groupChatRepository;
}
@Override
public Single<Message> insertMessage(DirectChat chat, Message message) {
return data()
// fetch chat model
.select(DirectChatModel.class)
.where(DirectChatModel.ID.eq(chat.getId()))
.get().maybe()
// if not exists, insert chat into db
.switchIfEmpty(data().insert(directChatMapping.toModel(chat, new DirectChatModel())))
// place chat and message in relation
.map(chatModel -> {
DirectMessagesRelation relation = new DirectMessagesRelation();
relation.setChat(chatModel);
relation.setMessage(messageMapping.toModel(message, new MessageModel()));
return relation;
})
// insert relation
.flatMap(relationModel -> data().insert(relationModel))
// prepare resulting message to be returned
.map(DirectMessagesRelation::getMessage)
.map(messageModel -> messageMapping.toEntity(messageModel, message))
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@Override
public Single<Message> insertMessage(GroupChat chat, Message message) {
return null;
}
@Override
public Observable<List<Message>> observeMessages(DirectChat chat) {
return null;
}
@Override
public Observable<List<Message>> observeMessages(GroupChat chat) {
return null;
}
@Override
public Observable<List<Message>> findMessagesWithBody(String body) {
return null;
}
@Override
public Observable<List<Message>> findMessagesWithBody(DirectChat chat, String body) {
return null;
}
@Override
public Observable<List<Message>> findMessagesWithBody(GroupChat chat, String body) {
return null;
}
@Override
public Single<Message> upsertMessage(DirectChat chat, Message message) {
return null;
}
@Override
public Single<Message> upsertMessage(GroupChat chat, Message message) {
return null;
}
@Override
public Single<Message> updateMessage(Message message) {
return null;
}
@Override
public Completable deleteMessage(Message message) {
return null;
}
}

View file

@ -20,6 +20,7 @@ import io.reactivex.Observable;
import io.reactivex.Scheduler;
import io.reactivex.Single;
import io.requery.Persistable;
import io.requery.query.ResultDelegate;
import io.requery.reactivex.ReactiveEntityStore;
public class XmppPeerRepository
@ -42,8 +43,8 @@ public class XmppPeerRepository
@Override
public Single<Peer> insertPeer(Peer peer) {
return data().insert(peerMapping.entityToModel(peer, new PeerModel()))
.map(model -> peerMapping.modelToEntity(model, peer))
return data().insert(peerMapping.toModel(peer, new PeerModel()))
.map(model -> peerMapping.toEntity(model, peer))
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@ -53,7 +54,7 @@ public class XmppPeerRepository
return data().select(PeerModel.class)
.where(PeerModel.ID.eq(peerId))
.get().observableResult()
.map(result -> new Optional<>(peerMapping.modelToEntity(result.firstOrNull(), new IPeer())))
.map(result -> new Optional<>(peerMapping.toEntity(result.firstOrNull(), new IPeer())))
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@ -63,7 +64,7 @@ public class XmppPeerRepository
return data().select(PeerModel.class)
.where(PeerModel.ID.eq(peerId))
.get().maybe()
.map(model -> peerMapping.modelToEntity(model, new IPeer()))
.map(model -> peerMapping.toEntity(model, new IPeer()))
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@ -74,7 +75,9 @@ public class XmppPeerRepository
.where(PeerModel.ACCOUNT_ID.eq(accountId))
.and(PeerModel.ADDRESS.eq(address))
.get().observableResult()
.map(result -> new Optional<>(peerMapping.modelToEntity(result.firstOrNull(), new IPeer())))
.map(ResultDelegate::firstOrNull)
.map(peerMapping::toEntity)
.map(Optional::new)
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@ -91,20 +94,22 @@ public class XmppPeerRepository
.where(PeerModel.ACCOUNT_ID.eq(accountId))
.and(PeerModel.ADDRESS.eq(address))
.get().maybe()
.map(model -> peerMapping.modelToEntity(model, new IPeer()))
.map(peerMapping::toEntity)
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@Override
public Single<Peer> getOrCreatePeer(Account _account, String _address) {
return getPeerByAddress(_account, _address)
.switchIfEmpty(insertPeer(new IPeer(){
{
setAccount(_account);
setAddress(_address);
}
}))
public Single<Peer> getOrCreatePeer(Account account, String address) {
return getPeerByAddress(account, address)
.switchIfEmpty(Single
.just(new IPeer(){
{
setAccount(account);
setAddress(address);
}
})
.flatMap(this::insertPeer))
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@ -113,11 +118,11 @@ public class XmppPeerRepository
public Observable<List<Peer>> observeAllPeers() {
return data().select(PeerModel.class)
.get().observableResult()
.map(result -> {
List<PeerModel> peerModels = result.toList();
.map(ResultDelegate::toList)
.map(peerModels -> {
List<Peer> peerEntities = new ArrayList<>(peerModels.size());
for (PeerModel model : peerModels) {
peerEntities.add(peerMapping.modelToEntity(model, new IPeer()));
peerEntities.add(peerMapping.toEntity(model));
}
return peerEntities;
})
@ -131,13 +136,10 @@ public class XmppPeerRepository
return data().select(PeerModel.class)
.where(PeerModel.ID.eq(peer.getId()))
.get().maybe().toSingle()
.flatMap(model -> {
// write changes into model
model = peerMapping.entityToModel(peer, model);
// write model back to db
return data().update(model);
})
.map(model -> peerMapping.modelToEntity(model, peer))
// write changes into model
.map(model -> peerMapping.toModel(peer, model))
.flatMap(data()::update)
.map(model -> peerMapping.toEntity(model, peer))
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}
@ -148,14 +150,14 @@ public class XmppPeerRepository
.where(PeerModel.ID.eq(peer.getId()))
.get().maybe()
// if not exists, create
.switchIfEmpty(data().insert(peerMapping.entityToModel(peer, new PeerModel())))
.flatMap(model -> {
// write changes into fetched model
model = peerMapping.entityToModel(peer, model);
// write changed model back to db
return data().update(model);
})
.map(model -> peerMapping.modelToEntity(model, peer))
.switchIfEmpty(Single.just(peer)
.map(peerMapping::toModel)
.flatMap(data()::insert))
// write changes into fetched model
.map(model -> peerMapping.toModel(peer, model))
// write changed model back to db
.flatMap(data()::update)
.map(model -> peerMapping.toEntity(model, peer))
.subscribeOn(subscriberScheduler())
.observeOn(observerScheduler());
}

View file

@ -0,0 +1,25 @@
package org.mercury_im.messenger.data.repository.dao;
import org.mercury_im.messenger.data.model.DirectChatModel;
import io.reactivex.Maybe;
import io.reactivex.Single;
import io.requery.Persistable;
import io.requery.reactivex.ReactiveEntityStore;
public class DirectChatDao extends RequeryDao {
public DirectChatDao(ReactiveEntityStore<Persistable> data) {
super(data);
}
public Single<DirectChatModel> insert(DirectChatModel model) {
return data().insert(model);
}
public Maybe<DirectChatModel> get(long chatId) {
return data().select(DirectChatModel.class)
.where(DirectChatModel.ID.eq(chatId))
.get().maybe();
}
}

View file

@ -0,0 +1,17 @@
package org.mercury_im.messenger.data.repository.dao;
import io.requery.Persistable;
import io.requery.reactivex.ReactiveEntityStore;
public abstract class RequeryDao {
private final ReactiveEntityStore<Persistable> data;
public RequeryDao(ReactiveEntityStore<Persistable> data) {
this.data = data;
}
public ReactiveEntityStore<Persistable> data() {
return data;
}
}

View file

@ -38,15 +38,4 @@ public interface DirectChatRepository {
Completable deleteDirectChat(DirectChat chat);
// Messages
Single<Message> insertMessage(DirectChat chat, Message message);
Observable<List<Message>> observeMessages(DirectChat chat);
Single<Message> updateMessage(Message message);
Single<Message> upsertMessage(DirectChat chat, Message message);
Completable deleteMessage(Message message);
}

View file

@ -42,15 +42,4 @@ public interface GroupChatRepository {
Completable deleteGroupChat(GroupChat chat);
// Messages
Single<Message> insertMessage(GroupChat chat, Message message);
Observable<List<Message>> observeMessages(GroupChat chat);
Single<Message> updateMessage(Message message);
Single<Message> upsertMessage(GroupChat chat, Message message);
Completable deleteMessage(Message message);
}

View file

@ -0,0 +1,36 @@
package org.mercury_im.messenger.data.repository;
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.List;
import io.reactivex.Completable;
import io.reactivex.Observable;
import io.reactivex.Single;
public interface MessageRepository {
Single<Message> insertMessage(DirectChat chat, Message message);
Single<Message> insertMessage(GroupChat chat, Message message);
Observable<List<Message>> observeMessages(DirectChat chat);
Observable<List<Message>> observeMessages(GroupChat chat);
Observable<List<Message>> findMessagesWithBody(String body);
Observable<List<Message>> findMessagesWithBody(DirectChat chat, String body);
Observable<List<Message>> findMessagesWithBody(GroupChat chat, String body);
Single<Message> upsertMessage(DirectChat chat, Message message);
Single<Message> upsertMessage(GroupChat chat, Message message);
Single<Message> updateMessage(Message message);
Completable deleteMessage(Message message);
}