Alternative caps store

This commit is contained in:
Paul Schaub 2019-08-10 21:50:03 +02:00
parent 513bf2bab0
commit 24d0e71cfe
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
20 changed files with 199 additions and 508 deletions

View file

@ -7,6 +7,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Build; import android.os.Build;
import org.mercury_im.messenger.core.ConnectionCenter;
import org.mercury_im.messenger.di.component.AppComponent; import org.mercury_im.messenger.di.component.AppComponent;
import org.mercury_im.messenger.di.component.DaggerAppComponent; import org.mercury_im.messenger.di.component.DaggerAppComponent;
import org.mercury_im.messenger.di.module.AppModule; import org.mercury_im.messenger.di.module.AppModule;
@ -35,6 +36,8 @@ public class MercuryImApplication extends Application {
initializeNotificationChannels(this); initializeNotificationChannels(this);
ConnectionCenter.get();
Intent serviceIntent = new Intent(getApplicationContext(), XmppConnectionService.class); Intent serviceIntent = new Intent(getApplicationContext(), XmppConnectionService.class);
serviceIntent.setAction(XmppConnectionService.ACTION_START); serviceIntent.setAction(XmppConnectionService.ACTION_START);

View file

@ -3,11 +3,14 @@ package org.mercury_im.messenger.core;
import org.jivesoftware.smack.AbstractXMPPConnection; import org.jivesoftware.smack.AbstractXMPPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnection; import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration; import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jivesoftware.smackx.caps.EntityCapsManager;
import org.mercury_im.messenger.persistence.model.AccountModel; import org.mercury_im.messenger.persistence.model.AccountModel;
import java.sql.SQLOutput;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
@Singleton @Singleton
@ -17,8 +20,14 @@ public class ConnectionCenter {
private final Map<Long, MercuryConnection> connectionMap = new HashMap<>(); private final Map<Long, MercuryConnection> connectionMap = new HashMap<>();
private ConnectionCenter() {
private ConnectionCenter() {
}
@Inject
void injectEntityCapsStore(EntityCapsStore store) {
System.out.println("Inject Store");
EntityCapsManager.setPersistentCache(store);
} }
public static ConnectionCenter get() { public static ConnectionCenter get() {

View file

@ -1,20 +1,24 @@
package org.mercury_im.messenger.core; package org.mercury_im.messenger.core;
import org.jivesoftware.smack.parsing.SmackParsingException;
import org.jivesoftware.smack.xml.SmackXmlParser;
import org.jivesoftware.smack.xml.XmlPullParserException;
import org.jivesoftware.smackx.caps.cache.EntityCapsPersistentCache; import org.jivesoftware.smackx.caps.cache.EntityCapsPersistentCache;
import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
import org.mercury_im.messenger.persistence.model.EntityCapsFeatureModel; import org.jivesoftware.smackx.disco.provider.DiscoverInfoProvider;
import org.mercury_im.messenger.persistence.model.EntityCapsIdentityModel; import org.mercury_im.messenger.persistence.model.EntityCapsModel;
import org.mercury_im.messenger.persistence.repository.EntityCapsRepository; import org.mercury_im.messenger.persistence.repository.EntityCapsRepository;
import java.util.ArrayList; import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
import io.reactivex.functions.Consumer; import io.reactivex.SingleObserver;
import io.reactivex.internal.observers.ConsumerSingleObserver; import io.reactivex.observers.DisposableSingleObserver;
import io.reactivex.schedulers.Schedulers; import io.reactivex.schedulers.Schedulers;
public class EntityCapsStore implements EntityCapsPersistentCache { public class EntityCapsStore implements EntityCapsPersistentCache {
@ -22,6 +26,8 @@ public class EntityCapsStore implements EntityCapsPersistentCache {
private final EntityCapsRepository entityCapsRepository; private final EntityCapsRepository entityCapsRepository;
private final Map<String, DiscoverInfo> discoverInfoMap = new HashMap<>(); private final Map<String, DiscoverInfo> discoverInfoMap = new HashMap<>();
private final DiscoverInfoProvider provider = new DiscoverInfoProvider();
@Inject @Inject
public EntityCapsStore(EntityCapsRepository repository) { public EntityCapsStore(EntityCapsRepository repository) {
this.entityCapsRepository = repository; this.entityCapsRepository = repository;
@ -30,63 +36,40 @@ public class EntityCapsStore implements EntityCapsPersistentCache {
private void populateFromDatabase() { private void populateFromDatabase() {
discoverInfoMap.clear(); discoverInfoMap.clear();
entityCapsRepository.getAllFeatures() SingleObserver observer = entityCapsRepository.getAllEntityCaps()
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation()) .observeOn(Schedulers.computation())
.zipWith(entityCapsRepository.getAllIdentities().) .subscribeWith(new DisposableSingleObserver<List<? extends EntityCapsModel>>() {
.subscribe((Consumer<List<? extends EntityCapsFeatureModel>>) features -> {
entityCapsRepository.getAllIdentities()
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.subscribe((ConsumerSingleObserver<List<? extends EntityCapsIdentityModel>>) identities -> {
for (EntityCapsFeatureModel f : features) { @Override
DiscoverInfo di = discoverInfoMap.get(f.getNodeVer()); public void onSuccess(List<? extends EntityCapsModel> entityCapsModels) {
if (di == null) { discoverInfoMap.clear();
di = new DiscoverInfo(); for (EntityCapsModel c : entityCapsModels) {
discoverInfoMap.put(f.getNodeVer(), di); DiscoverInfo info;
} try {
di.addFeature(f.getVar()); info = provider.parse(
} SmackXmlParser.newXmlParser(new StringReader(c.getXml())));
} catch (IOException | XmlPullParserException | SmackParsingException e) {
e.printStackTrace();
continue;
}
discoverInfoMap.put(c.getNodeVer(), info);
}
}
for (EntityCapsIdentityModel i : identities) { @Override
DiscoverInfo di = discoverInfoMap.get(i.getNodeVer()); public void onError(Throwable e) {
if (di == null) {
di = new DiscoverInfo(); }
discoverInfoMap.put(i.getNodeVer(), di);
}
di.addIdentity(new DiscoverInfo.Identity(i.getCategory(), i.getName(), i.getType()));
}
});
}); });
} }
@Override @Override
public void addDiscoverInfoByNodePersistent(String nodeVer, DiscoverInfo info) { public void addDiscoverInfoByNodePersistent(String nodeVer, DiscoverInfo info) {
discoverInfoMap.put(nodeVer, info); discoverInfoMap.put(nodeVer, info);
EntityCapsModel model = entityCapsRepository.newEntityCapsModel(nodeVer);
List<EntityCapsIdentityModel> identities = new ArrayList<>(); model.setXml(info.toXML().toString());
for (DiscoverInfo.Identity i : info.getIdentities()) { entityCapsRepository.insertOrReplaceEntityCaps(model);
EntityCapsIdentityModel identity = entityCapsRepository.newEntityCapsIdentityModel();
identity.setCategory(i.getCategory());
identity.setType(i.getType());
identity.setName(i.getName());
identity.setLanguage(i.getLanguage());
identity.setNodeVer(info.getNode());
identities.add(identity);
}
entityCapsRepository.insertIdentities(identities);
List<EntityCapsFeatureModel> features = new ArrayList<>();
for (DiscoverInfo.Feature f : info.getFeatures()) {
EntityCapsFeatureModel feature = entityCapsRepository.newEntityCapsFeatureModel();
feature.setVar(f.getVar());
feature.setNodeVer(info.getNode());
features.add(feature);
}
entityCapsRepository.insertFeatures(features);
} }
@Override @Override

View file

@ -9,9 +9,11 @@ import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler;
import org.jivesoftware.smack.iqrequest.IQRequestHandler; import org.jivesoftware.smack.iqrequest.IQRequestHandler;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.roster.Roster; import org.jivesoftware.smack.roster.Roster;
import org.jivesoftware.smackx.caps.EntityCapsManager;
import org.jivesoftware.smackx.carbons.CarbonManager; import org.jivesoftware.smackx.carbons.CarbonManager;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
import org.jivesoftware.smackx.iqversion.VersionManager;
import org.jivesoftware.smackx.iqversion.packet.Version; import org.jivesoftware.smackx.iqversion.packet.Version;
import org.jivesoftware.smackx.sid.StableUniqueStanzaIdManager; import org.jivesoftware.smackx.sid.StableUniqueStanzaIdManager;
@ -48,14 +50,8 @@ public class MercuryConnection implements ConnectionListener {
stanzaIdManager.enable(); stanzaIdManager.enable();
this.serviceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(connection); this.serviceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(connection);
VersionManager.getInstanceFor(connection).setVersion("Mercury", "0.0.1-stealth", "Android");
serviceDiscoveryManager.setIdentity(new DiscoverInfo.Identity("client", "Mercury", "phone")); serviceDiscoveryManager.setIdentity(new DiscoverInfo.Identity("client", "Mercury", "phone"));
connection.registerIQRequestHandler(new AbstractIqRequestHandler(Version.ELEMENT, Version.NAMESPACE, IQ.Type.get, IQRequestHandler.Mode.async) {
@Override
public IQ handleIQRequest(IQ iqRequest) {
return Version.createResultFor(iqRequest, new Version("Mercury", "stealth", "Android"));
}
});
roster.setRosterLoadedAtLogin(true); roster.setRosterLoadedAtLogin(true);
} }

View file

@ -2,7 +2,7 @@
"formatVersion": 1, "formatVersion": 1,
"database": { "database": {
"version": 1, "version": 1,
"identityHash": "e1e6ce9276bb4e2a97b5e2bfc25272c1", "identityHash": "606370403d8f862397c7c75b88be193e",
"entities": [ "entities": [
{ {
"tableName": "contacts", "tableName": "contacts",
@ -440,131 +440,36 @@
] ]
}, },
{ {
"tableName": "caps_identities", "tableName": "entity_caps",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`pk_caps_identity_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `category` TEXT, `type` TEXT, `name` TEXT, `nodeVer` TEXT)", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`pk_node_ver` TEXT NOT NULL, `xml` TEXT, PRIMARY KEY(`pk_node_ver`))",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "nodeVer",
"columnName": "pk_caps_identity_id", "columnName": "pk_node_ver",
"affinity": "INTEGER", "affinity": "TEXT",
"notNull": true "notNull": true
}, },
{ {
"fieldPath": "category", "fieldPath": "xml",
"columnName": "category", "columnName": "xml",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "nodeVer",
"columnName": "nodeVer",
"affinity": "TEXT", "affinity": "TEXT",
"notNull": false "notNull": false
} }
], ],
"primaryKey": { "primaryKey": {
"columnNames": [ "columnNames": [
"pk_caps_identity_id" "pk_node_ver"
], ],
"autoGenerate": true "autoGenerate": false
}, },
"indices": [ "indices": [
{ {
"name": "index_caps_identities_pk_caps_identity_id", "name": "index_entity_caps_pk_node_ver",
"unique": false, "unique": false,
"columnNames": [ "columnNames": [
"pk_caps_identity_id" "pk_node_ver"
], ],
"createSql": "CREATE INDEX `index_caps_identities_pk_caps_identity_id` ON `${TABLE_NAME}` (`pk_caps_identity_id`)" "createSql": "CREATE INDEX `index_entity_caps_pk_node_ver` ON `${TABLE_NAME}` (`pk_node_ver`)"
},
{
"name": "index_caps_identities_nodeVer",
"unique": false,
"columnNames": [
"nodeVer"
],
"createSql": "CREATE INDEX `index_caps_identities_nodeVer` ON `${TABLE_NAME}` (`nodeVer`)"
},
{
"name": "index_caps_identities_nodeVer_category_type_name",
"unique": true,
"columnNames": [
"nodeVer",
"category",
"type",
"name"
],
"createSql": "CREATE UNIQUE INDEX `index_caps_identities_nodeVer_category_type_name` ON `${TABLE_NAME}` (`nodeVer`, `category`, `type`, `name`)"
}
],
"foreignKeys": []
},
{
"tableName": "caps_features",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`pk_caps_feature_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `var` TEXT, `nodeVer` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "pk_caps_feature_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "var",
"columnName": "var",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "nodeVer",
"columnName": "nodeVer",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"pk_caps_feature_id"
],
"autoGenerate": true
},
"indices": [
{
"name": "index_caps_features_pk_caps_feature_id",
"unique": false,
"columnNames": [
"pk_caps_feature_id"
],
"createSql": "CREATE INDEX `index_caps_features_pk_caps_feature_id` ON `${TABLE_NAME}` (`pk_caps_feature_id`)"
},
{
"name": "index_caps_features_nodeVer",
"unique": false,
"columnNames": [
"nodeVer"
],
"createSql": "CREATE INDEX `index_caps_features_nodeVer` ON `${TABLE_NAME}` (`nodeVer`)"
},
{
"name": "index_caps_features_nodeVer_var",
"unique": true,
"columnNames": [
"nodeVer",
"var"
],
"createSql": "CREATE UNIQUE INDEX `index_caps_features_nodeVer_var` ON `${TABLE_NAME}` (`nodeVer`, `var`)"
} }
], ],
"foreignKeys": [] "foreignKeys": []
@ -573,7 +478,7 @@
"views": [], "views": [],
"setupQueries": [ "setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'e1e6ce9276bb4e2a97b5e2bfc25272c1')" "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '606370403d8f862397c7c75b88be193e')"
] ]
} }
} }

View file

@ -2,29 +2,23 @@ package org.mercury_im.messenger.persistence.room;
import android.content.Context; import android.content.Context;
import androidx.annotation.NonNull;
import androidx.room.Database; import androidx.room.Database;
import androidx.room.Room; import androidx.room.Room;
import androidx.room.RoomDatabase; import androidx.room.RoomDatabase;
import androidx.room.migration.Migration;
import androidx.sqlite.db.SupportSQLiteDatabase;
import org.mercury_im.messenger.persistence.model.EntityCapsIdentityModel;
import org.mercury_im.messenger.persistence.room.dao.AccountDao; import org.mercury_im.messenger.persistence.room.dao.AccountDao;
import org.mercury_im.messenger.persistence.room.dao.AvatarDao; import org.mercury_im.messenger.persistence.room.dao.AvatarDao;
import org.mercury_im.messenger.persistence.room.dao.ChatDao; import org.mercury_im.messenger.persistence.room.dao.ChatDao;
import org.mercury_im.messenger.persistence.room.dao.ContactDao;
import org.mercury_im.messenger.persistence.room.dao.ContactAttributesDao; import org.mercury_im.messenger.persistence.room.dao.ContactAttributesDao;
import org.mercury_im.messenger.persistence.room.dao.EntityCapsFeatureDao; import org.mercury_im.messenger.persistence.room.dao.ContactDao;
import org.mercury_im.messenger.persistence.room.dao.EntityCapsIdentityDao; import org.mercury_im.messenger.persistence.room.dao.EntityCapsDao;
import org.mercury_im.messenger.persistence.room.dao.EntityDao; import org.mercury_im.messenger.persistence.room.dao.EntityDao;
import org.mercury_im.messenger.persistence.room.dao.MessageDao; import org.mercury_im.messenger.persistence.room.dao.MessageDao;
import org.mercury_im.messenger.persistence.room.model.RoomAccountModel; import org.mercury_im.messenger.persistence.room.model.RoomAccountModel;
import org.mercury_im.messenger.persistence.room.model.RoomAvatarModel; import org.mercury_im.messenger.persistence.room.model.RoomAvatarModel;
import org.mercury_im.messenger.persistence.room.model.RoomChatModel; import org.mercury_im.messenger.persistence.room.model.RoomChatModel;
import org.mercury_im.messenger.persistence.room.model.RoomContactAttributes; import org.mercury_im.messenger.persistence.room.model.RoomContactAttributes;
import org.mercury_im.messenger.persistence.room.model.RoomEntityCapsFeatureModel; import org.mercury_im.messenger.persistence.room.model.RoomEntityCapsModel;
import org.mercury_im.messenger.persistence.room.model.RoomEntityCapsIdentityModel;
import org.mercury_im.messenger.persistence.room.model.RoomEntityModel; import org.mercury_im.messenger.persistence.room.model.RoomEntityModel;
import org.mercury_im.messenger.persistence.room.model.RoomMessageModel; import org.mercury_im.messenger.persistence.room.model.RoomMessageModel;
@ -36,8 +30,7 @@ import org.mercury_im.messenger.persistence.room.model.RoomMessageModel;
RoomMessageModel.class, RoomMessageModel.class,
RoomEntityModel.class, RoomEntityModel.class,
RoomAvatarModel.class, RoomAvatarModel.class,
RoomEntityCapsIdentityModel.class, RoomEntityCapsModel.class
RoomEntityCapsFeatureModel.class
}) })
public abstract class AppDatabase extends RoomDatabase { public abstract class AppDatabase extends RoomDatabase {
@ -67,7 +60,5 @@ public abstract class AppDatabase extends RoomDatabase {
public abstract AvatarDao avatarDao(); public abstract AvatarDao avatarDao();
public abstract EntityCapsIdentityDao capsIdentityDao(); public abstract EntityCapsDao entityCapsDao();
public abstract EntityCapsFeatureDao capsFeatureDao();
} }

View file

@ -5,10 +5,9 @@ import android.app.Application;
import org.mercury_im.messenger.persistence.room.dao.AccountDao; import org.mercury_im.messenger.persistence.room.dao.AccountDao;
import org.mercury_im.messenger.persistence.room.dao.AvatarDao; import org.mercury_im.messenger.persistence.room.dao.AvatarDao;
import org.mercury_im.messenger.persistence.room.dao.ChatDao; import org.mercury_im.messenger.persistence.room.dao.ChatDao;
import org.mercury_im.messenger.persistence.room.dao.ContactDao;
import org.mercury_im.messenger.persistence.room.dao.ContactAttributesDao; import org.mercury_im.messenger.persistence.room.dao.ContactAttributesDao;
import org.mercury_im.messenger.persistence.room.dao.EntityCapsFeatureDao; import org.mercury_im.messenger.persistence.room.dao.ContactDao;
import org.mercury_im.messenger.persistence.room.dao.EntityCapsIdentityDao; import org.mercury_im.messenger.persistence.room.dao.EntityCapsDao;
import org.mercury_im.messenger.persistence.room.dao.EntityDao; import org.mercury_im.messenger.persistence.room.dao.EntityDao;
import org.mercury_im.messenger.persistence.room.dao.MessageDao; import org.mercury_im.messenger.persistence.room.dao.MessageDao;
@ -81,13 +80,7 @@ public class RoomModule {
@Singleton @Singleton
@Provides @Provides
EntityCapsIdentityDao provideEntityCapsIdentityDao() { EntityCapsDao provideEntityCapsDao() {
return mAppDatabase.capsIdentityDao(); return mAppDatabase.entityCapsDao();
}
@Singleton
@Provides
EntityCapsFeatureDao providerEntityCapsFeatureDao() {
return mAppDatabase.capsFeatureDao();
} }
} }

View file

@ -13,8 +13,7 @@ import org.mercury_im.messenger.persistence.room.dao.AvatarDao;
import org.mercury_im.messenger.persistence.room.dao.ChatDao; import org.mercury_im.messenger.persistence.room.dao.ChatDao;
import org.mercury_im.messenger.persistence.room.dao.ContactAttributesDao; import org.mercury_im.messenger.persistence.room.dao.ContactAttributesDao;
import org.mercury_im.messenger.persistence.room.dao.ContactDao; import org.mercury_im.messenger.persistence.room.dao.ContactDao;
import org.mercury_im.messenger.persistence.room.dao.EntityCapsFeatureDao; import org.mercury_im.messenger.persistence.room.dao.EntityCapsDao;
import org.mercury_im.messenger.persistence.room.dao.EntityCapsIdentityDao;
import org.mercury_im.messenger.persistence.room.dao.EntityDao; import org.mercury_im.messenger.persistence.room.dao.EntityDao;
import org.mercury_im.messenger.persistence.room.dao.MessageDao; import org.mercury_im.messenger.persistence.room.dao.MessageDao;
import org.mercury_im.messenger.persistence.room.repository.IAccountRepository; import org.mercury_im.messenger.persistence.room.repository.IAccountRepository;
@ -78,8 +77,7 @@ public class RoomRepositoryModule {
@Singleton @Singleton
@Provides @Provides
EntityCapsRepository providerEntityCapsRepository(EntityCapsIdentityDao identityDao, EntityCapsRepository providerEntityCapsRepository(EntityCapsDao entityCapsDao) {
EntityCapsFeatureDao featureDao) { return new IEntityCapsRepository(entityCapsDao);
return new IEntityCapsRepository(identityDao, featureDao);
} }
} }

View file

@ -0,0 +1,33 @@
package org.mercury_im.messenger.persistence.room.dao;
import androidx.annotation.WorkerThread;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import org.mercury_im.messenger.persistence.room.model.RoomEntityCapsModel;
import java.util.List;
import io.reactivex.Completable;
import io.reactivex.Single;
import static androidx.room.OnConflictStrategy.REPLACE;
@Dao
@WorkerThread
public interface EntityCapsDao {
@Query("SELECT * FROM entity_caps WHERE pk_node_ver = :nodeVer")
Single<RoomEntityCapsModel> getEntityCapsForNodeVer(String nodeVer);
@Query("SELECT * FROM entity_caps")
Single<List<RoomEntityCapsModel>> getAllEntityCaps();
@Insert(onConflict = REPLACE)
Completable insert(RoomEntityCapsModel... models);
@Delete
Completable delete(RoomEntityCapsModel... models);
}

View file

@ -1,26 +0,0 @@
package org.mercury_im.messenger.persistence.room.dao;
import androidx.annotation.WorkerThread;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.Query;
import org.mercury_im.messenger.persistence.room.model.RoomEntityCapsFeatureModel;
import java.util.List;
import io.reactivex.Completable;
import io.reactivex.Single;
import static androidx.room.OnConflictStrategy.IGNORE;
@Dao
@WorkerThread
public interface EntityCapsFeatureDao extends BaseDao<RoomEntityCapsFeatureModel> {
@Query("SELECT * FROM caps_features ORDER BY nodeVer")
Single<List<RoomEntityCapsFeatureModel>> getAllFeatures();
@Insert(onConflict = IGNORE)
Completable insert(List<RoomEntityCapsFeatureModel> features);
}

View file

@ -1,26 +0,0 @@
package org.mercury_im.messenger.persistence.room.dao;
import androidx.annotation.WorkerThread;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.Query;
import org.mercury_im.messenger.persistence.room.model.RoomEntityCapsIdentityModel;
import java.util.List;
import io.reactivex.Completable;
import io.reactivex.Single;
import static androidx.room.OnConflictStrategy.IGNORE;
@Dao
@WorkerThread
public interface EntityCapsIdentityDao extends BaseDao<RoomEntityCapsIdentityModel> {
@Query("SELECT * FROM caps_identities ORDER BY nodeVer")
Single<List<RoomEntityCapsIdentityModel>> getAllIdentities();
@Insert(onConflict = IGNORE)
Completable insert(List<RoomEntityCapsIdentityModel> identities);
}

View file

@ -1,70 +0,0 @@
package org.mercury_im.messenger.persistence.room.model;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Index;
import androidx.room.PrimaryKey;
import org.mercury_im.messenger.persistence.model.EntityCapsFeatureModel;
import static org.mercury_im.messenger.persistence.room.model.RoomEntityCapsFeatureModel.KEY_ID;
import static org.mercury_im.messenger.persistence.room.model.RoomEntityCapsFeatureModel.KEY_NODE_VER;
import static org.mercury_im.messenger.persistence.room.model.RoomEntityCapsFeatureModel.KEY_VAR;
import static org.mercury_im.messenger.persistence.room.model.RoomEntityCapsFeatureModel.TABLE;
@Entity(tableName = TABLE,
indices = {
@Index(KEY_ID),
@Index(KEY_NODE_VER),
@Index(value = {
KEY_NODE_VER,
KEY_VAR},
unique = true)
})
public class RoomEntityCapsFeatureModel implements EntityCapsFeatureModel {
public static final String TABLE = "caps_features";
public static final String KEY_ID ="pk_caps_feature_id";
public static final String KEY_VAR = "var";
public static final String KEY_NODE_VER = "nodeVer";
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = KEY_ID)
private long id;
@ColumnInfo(name = KEY_VAR)
private String var;
@ColumnInfo(name = KEY_NODE_VER)
private String nodeVer;
@Override
public long getId() {
return id;
}
@Override
public void setId(long id) {
this.id = id;
}
@Override
public String getVar() {
return var;
}
@Override
public void setVar(String var) {
this.var = var;
}
@Override
public String getNodeVer() {
return nodeVer;
}
@Override
public void setNodeVer(String nodeVer) {
this.nodeVer = nodeVer;
}
}

View file

@ -1,103 +0,0 @@
package org.mercury_im.messenger.persistence.room.model;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Index;
import androidx.room.PrimaryKey;
import org.mercury_im.messenger.persistence.model.EntityCapsIdentityModel;
import static org.mercury_im.messenger.persistence.room.model.RoomEntityCapsIdentityModel.KEY_CATEGORY;
import static org.mercury_im.messenger.persistence.room.model.RoomEntityCapsIdentityModel.KEY_ID;
import static org.mercury_im.messenger.persistence.room.model.RoomEntityCapsIdentityModel.KEY_NAME;
import static org.mercury_im.messenger.persistence.room.model.RoomEntityCapsIdentityModel.KEY_NODE_VER;
import static org.mercury_im.messenger.persistence.room.model.RoomEntityCapsIdentityModel.KEY_TYPE;
import static org.mercury_im.messenger.persistence.room.model.RoomEntityCapsIdentityModel.TABLE;
@Entity(tableName = TABLE,
indices = {
@Index(KEY_ID),
@Index(KEY_NODE_VER),
@Index(value = {
KEY_NODE_VER,
KEY_CATEGORY,
KEY_TYPE,
KEY_NAME},
unique = true)
})
public class RoomEntityCapsIdentityModel implements EntityCapsIdentityModel {
public static final String TABLE = "caps_identities";
public static final String KEY_ID = "pk_caps_identity_id";
public static final String KEY_CATEGORY = "category";
public static final String KEY_TYPE = "type";
public static final String KEY_NAME = "name";
public static final String KEY_NODE_VER = "nodeVer";
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = KEY_ID)
private long id;
@ColumnInfo(name = KEY_CATEGORY)
private String category;
@ColumnInfo(name = KEY_TYPE)
private String type;
@ColumnInfo(name = KEY_NAME)
private String name;
@ColumnInfo(name = KEY_NODE_VER)
private String nodeVer;
@Override
public long getId() {
return id;
}
@Override
public void setId(long id) {
this.id = id;
}
@Override
public String getCategory() {
return category;
}
@Override
public void setCategory(String category) {
this.category = category;
}
@Override
public String getType() {
return type;
}
@Override
public void setType(String type) {
this.type = type;
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public String getNodeVer() {
return nodeVer;
}
@Override
public void setNodeVer(String nodeVer) {
this.nodeVer = nodeVer;
}
}

View file

@ -0,0 +1,51 @@
package org.mercury_im.messenger.persistence.room.model;
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
import org.mercury_im.messenger.persistence.model.EntityCapsModel;
import static org.mercury_im.messenger.persistence.room.model.RoomEntityCapsModel.TABLE;
@Entity(tableName = TABLE)
public class RoomEntityCapsModel implements EntityCapsModel {
public static final String TABLE = "entity_caps";
public static final String KEY_NODE_VER = "pk_node_ver";
public static final String KEY_XML = "xml";
@PrimaryKey
@NonNull
@ColumnInfo(name = KEY_NODE_VER, index = true)
private String nodeVer;
@ColumnInfo(name = KEY_XML)
private String xml;
public RoomEntityCapsModel(@NonNull String nodeVer) {
this.nodeVer = nodeVer;
}
@Override
@NonNull
public String getNodeVer() {
return nodeVer;
}
@Override
public void setNodeVer(@NonNull String nodeVer) {
this.nodeVer = nodeVer;
}
@Override
public String getXml() {
return xml;
}
@Override
public void setXml(String xml) {
this.xml = xml;
}
}

View file

@ -1,10 +1,10 @@
package org.mercury_im.messenger.persistence.room.repository; package org.mercury_im.messenger.persistence.room.repository;
import androidx.annotation.NonNull;
import org.mercury_im.messenger.persistence.repository.EntityCapsRepository; import org.mercury_im.messenger.persistence.repository.EntityCapsRepository;
import org.mercury_im.messenger.persistence.room.dao.EntityCapsFeatureDao; import org.mercury_im.messenger.persistence.room.dao.EntityCapsDao;
import org.mercury_im.messenger.persistence.room.dao.EntityCapsIdentityDao; import org.mercury_im.messenger.persistence.room.model.RoomEntityCapsModel;
import org.mercury_im.messenger.persistence.room.model.RoomEntityCapsFeatureModel;
import org.mercury_im.messenger.persistence.room.model.RoomEntityCapsIdentityModel;
import java.util.List; import java.util.List;
@ -14,46 +14,37 @@ import io.reactivex.Completable;
import io.reactivex.Single; import io.reactivex.Single;
public class IEntityCapsRepository implements EntityCapsRepository<RoomEntityCapsIdentityModel, public class IEntityCapsRepository implements EntityCapsRepository<RoomEntityCapsModel> {
RoomEntityCapsFeatureModel> {
private final EntityCapsIdentityDao identityDao; private final EntityCapsDao dao;
private final EntityCapsFeatureDao featureDao;
@Inject @Inject
public IEntityCapsRepository(EntityCapsIdentityDao identityDao, public IEntityCapsRepository(EntityCapsDao dao) {
EntityCapsFeatureDao featureDao) { this.dao = dao;
this.identityDao = identityDao;
this.featureDao = featureDao;
} }
@Override @Override
public RoomEntityCapsIdentityModel newEntityCapsIdentityModel() { public RoomEntityCapsModel newEntityCapsModel(@NonNull String nodeVer) {
return new RoomEntityCapsIdentityModel(); return new RoomEntityCapsModel(nodeVer);
} }
@Override @Override
public RoomEntityCapsFeatureModel newEntityCapsFeatureModel() { public Single<List<RoomEntityCapsModel>> getAllEntityCaps() {
return new RoomEntityCapsFeatureModel(); return dao.getAllEntityCaps();
} }
@Override @Override
public Single<List<RoomEntityCapsFeatureModel>> getAllFeatures() { public Single<RoomEntityCapsModel> getEntityCapsForNodeVer(String nodeVer) {
return featureDao.getAllFeatures(); return dao.getEntityCapsForNodeVer(nodeVer);
} }
@Override @Override
public Completable insertFeatures(List<RoomEntityCapsFeatureModel> features) { public Completable insertOrReplaceEntityCaps(RoomEntityCapsModel... entityCaps) {
return featureDao.insert(features); return dao.insert(entityCaps);
} }
@Override @Override
public Single<List<RoomEntityCapsIdentityModel>> getAllIdentities() { public Completable deleteOrReplaceEntityCaps(RoomEntityCapsModel... entityCaps) {
return identityDao.getAllIdentities(); return dao.delete(entityCaps);
}
@Override
public Completable insertIdentities(List<RoomEntityCapsIdentityModel> identities) {
return identityDao.insert(identities);
} }
} }

View file

@ -9,7 +9,7 @@ dependencies {
} }
// RxJava2 // RxJava2
implementation "io.reactivex.rxjava2:rxjava:$rxJava2Version" api "io.reactivex.rxjava2:rxjava:$rxJava2Version"
// Dagger 2 for dependency injection // Dagger 2 for dependency injection
implementation "com.google.dagger:dagger:$daggerVersion" implementation "com.google.dagger:dagger:$daggerVersion"

View file

@ -1,16 +0,0 @@
package org.mercury_im.messenger.persistence.model;
public interface EntityCapsFeatureModel {
long getId();
void setId(long id);
String getVar();
void setVar(String var);
String getNodeVer();
void setNodeVer(String nodeVer);
}

View file

@ -1,28 +0,0 @@
package org.mercury_im.messenger.persistence.model;
public interface EntityCapsIdentityModel {
long getId();
void setId(long id);
String getCategory();
void setCategory(String category);
String getType();
void setType(String type);
String getName();
void setName(String name);
String getLanguage();
void setLanguage(String lang);
String getNodeVer();
void setNodeVer(String nodeVer);
}

View file

@ -0,0 +1,12 @@
package org.mercury_im.messenger.persistence.model;
public interface EntityCapsModel {
String getNodeVer();
void setNodeVer(String nodeVer);
String getXml();
void setXml(String xml);
}

View file

@ -1,26 +1,21 @@
package org.mercury_im.messenger.persistence.repository; package org.mercury_im.messenger.persistence.repository;
import org.mercury_im.messenger.persistence.model.EntityCapsFeatureModel; import org.mercury_im.messenger.persistence.model.EntityCapsModel;
import org.mercury_im.messenger.persistence.model.EntityCapsIdentityModel;
import java.util.List; import java.util.List;
import io.reactivex.Completable; import io.reactivex.Completable;
import io.reactivex.Single; import io.reactivex.Single;
public interface EntityCapsRepository< public interface EntityCapsRepository<E extends EntityCapsModel> {
I extends EntityCapsIdentityModel,
F extends EntityCapsFeatureModel> {
I newEntityCapsIdentityModel(); E newEntityCapsModel(String nodeVer);
F newEntityCapsFeatureModel(); Single<List<E>> getAllEntityCaps();
Single<List<F>> getAllFeatures(); Single<E> getEntityCapsForNodeVer(String nodeVer);
Completable insertFeatures(List<F> features); Completable insertOrReplaceEntityCaps(E... entityCaps);
Single<List<I>> getAllIdentities(); Completable deleteOrReplaceEntityCaps(E... entityCaps);
Completable insertIdentities(List<I> identities);
} }