include parentNode in disco items table
This commit is contained in:
parent
d25cc059c5
commit
c31fa7ed2b
|
@ -2,7 +2,7 @@
|
|||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 1,
|
||||
"identityHash": "8f1d4d8d2bdb8b2358132202037aba7a",
|
||||
"identityHash": "e2dbbac3327bc8ef188286642b379e7d",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "account",
|
||||
|
@ -601,7 +601,7 @@
|
|||
},
|
||||
{
|
||||
"tableName": "disco_item",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `accountId` INTEGER NOT NULL, `address` TEXT NOT NULL, `node` TEXT NOT NULL, `parent` TEXT NOT NULL, `discoId` INTEGER, FOREIGN KEY(`accountId`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`discoId`) REFERENCES `disco`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `accountId` INTEGER NOT NULL, `address` TEXT NOT NULL, `node` TEXT NOT NULL, `parentAddress` TEXT NOT NULL, `parentNode` TEXT NOT NULL, `discoId` INTEGER, FOREIGN KEY(`accountId`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`discoId`) REFERENCES `disco`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
|
@ -628,8 +628,14 @@
|
|||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "parent",
|
||||
"columnName": "parent",
|
||||
"fieldPath": "parentAddress",
|
||||
"columnName": "parentAddress",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "parentNode",
|
||||
"columnName": "parentNode",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
|
@ -648,26 +654,27 @@
|
|||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_disco_item_accountId_address_node_parent",
|
||||
"name": "index_disco_item_accountId_address_node_parentAddress_parentNode",
|
||||
"unique": true,
|
||||
"columnNames": [
|
||||
"accountId",
|
||||
"address",
|
||||
"node",
|
||||
"parent"
|
||||
"parentAddress",
|
||||
"parentNode"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_disco_item_accountId_address_node_parent` ON `${TABLE_NAME}` (`accountId`, `address`, `node`, `parent`)"
|
||||
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_disco_item_accountId_address_node_parentAddress_parentNode` ON `${TABLE_NAME}` (`accountId`, `address`, `node`, `parentAddress`, `parentNode`)"
|
||||
},
|
||||
{
|
||||
"name": "index_disco_item_accountId_parent",
|
||||
"name": "index_disco_item_accountId_parentAddress",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"accountId",
|
||||
"parent"
|
||||
"parentAddress"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_disco_item_accountId_parent` ON `${TABLE_NAME}` (`accountId`, `parent`)"
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_disco_item_accountId_parentAddress` ON `${TABLE_NAME}` (`accountId`, `parentAddress`)"
|
||||
},
|
||||
{
|
||||
"name": "index_disco_item_discoId",
|
||||
|
@ -1337,7 +1344,7 @@
|
|||
"views": [],
|
||||
"setupQueries": [
|
||||
"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, '8f1d4d8d2bdb8b2358132202037aba7a')"
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'e2dbbac3327bc8ef188286642b379e7d')"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -37,6 +37,11 @@ public class Element {
|
|||
return child;
|
||||
}
|
||||
|
||||
public <T extends Extension> T addChild(T child) {
|
||||
this.addChild(child);
|
||||
return child;
|
||||
}
|
||||
|
||||
public Element addChild(String name) {
|
||||
this.content = null;
|
||||
Element child = new Element(name);
|
||||
|
|
|
@ -44,10 +44,13 @@ public abstract class DiscoDao {
|
|||
protected abstract void insertDiscoFeatures(Collection<DiscoFeatureEntity> features);
|
||||
|
||||
@Query(
|
||||
"DELETE FROM disco_item WHERE accountId=:account AND parent=:parent AND address NOT"
|
||||
+ " IN(:existent)")
|
||||
"DELETE FROM disco_item WHERE accountId=:account AND parentAddress=:parent AND"
|
||||
+ " parentNode=:parentNode AND address NOT IN(:existent)")
|
||||
protected abstract void deleteNonExistentDiscoItems(
|
||||
final long account, final Jid parent, final Collection<Jid> existent);
|
||||
final long account,
|
||||
final Jid parent,
|
||||
final String parentNode,
|
||||
final Collection<Jid> existent);
|
||||
|
||||
@Query(
|
||||
"UPDATE presence SET discoId=:discoId WHERE accountId=:account AND address=:address"
|
||||
|
@ -76,13 +79,19 @@ public abstract class DiscoDao {
|
|||
|
||||
@Transaction
|
||||
public void set(
|
||||
final Account account, final Entity.DiscoItem parent, final Collection<Item> items) {
|
||||
final Account account,
|
||||
final Entity.DiscoItem parent,
|
||||
final String parentNode,
|
||||
final Collection<Item> items) {
|
||||
final var entities =
|
||||
Collections2.transform(
|
||||
items, i -> DiscoItemEntity.of(account.id, parent.address, i));
|
||||
items, i -> DiscoItemEntity.of(account.id, parent.address, parentNode, i));
|
||||
insertDiscoItems(entities);
|
||||
deleteNonExistentDiscoItems(
|
||||
account.id, parent.address, Collections2.transform(items, Item::getJid));
|
||||
account.id,
|
||||
parent.address,
|
||||
Strings.nullToEmpty(parentNode),
|
||||
Collections2.transform(items, Item::getJid));
|
||||
}
|
||||
|
||||
@Transaction
|
||||
|
|
|
@ -25,10 +25,10 @@ import im.conversations.android.xmpp.model.disco.items.Item;
|
|||
},
|
||||
indices = {
|
||||
@Index(
|
||||
value = {"accountId", "address", "node", "parent"},
|
||||
value = {"accountId", "address", "node", "parentAddress", "parentNode"},
|
||||
unique = true),
|
||||
@Index(
|
||||
value = {"accountId", "parent"},
|
||||
value = {"accountId", "parentAddress"},
|
||||
unique = false),
|
||||
@Index(value = {"discoId"})
|
||||
})
|
||||
|
@ -43,16 +43,20 @@ public class DiscoItemEntity {
|
|||
|
||||
@NonNull public String node;
|
||||
|
||||
@NonNull public String parent;
|
||||
@NonNull public String parentAddress;
|
||||
|
||||
@NonNull public String parentNode;
|
||||
|
||||
public Long discoId;
|
||||
|
||||
public static DiscoItemEntity of(long accountId, final Jid parent, Item item) {
|
||||
public static DiscoItemEntity of(
|
||||
long accountId, final Jid parent, final String parentNode, final Item item) {
|
||||
final var entity = new DiscoItemEntity();
|
||||
entity.accountId = accountId;
|
||||
entity.address = item.getJid();
|
||||
entity.node = Strings.nullToEmpty(item.getNode());
|
||||
entity.parent = parent.toEscapedString();
|
||||
entity.parentAddress = parent.toEscapedString();
|
||||
entity.parentNode = Strings.nullToEmpty(parentNode);
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
@ -62,7 +66,7 @@ public class DiscoItemEntity {
|
|||
entity.accountId = accountId;
|
||||
entity.address = address;
|
||||
entity.node = Strings.nullToEmpty(node);
|
||||
entity.parent = "";
|
||||
entity.parentAddress = "";
|
||||
entity.discoId = discoId;
|
||||
return entity;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package im.conversations.android.xmpp.manager;
|
|||
import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Collections2;
|
||||
import com.google.common.io.BaseEncoding;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
|
@ -53,11 +54,10 @@ public class DiscoManager extends AbstractManager {
|
|||
final var requestNode = hash != null && node != null ? hash.capabilityNode(node) : node;
|
||||
final var iqRequest = new IqPacket(IqPacket.TYPE.GET);
|
||||
iqRequest.setTo(entity.address);
|
||||
final var infoQueryRequest = new InfoQuery();
|
||||
final var infoQueryRequest = iqRequest.addChild(new InfoQuery());
|
||||
if (requestNode != null) {
|
||||
infoQueryRequest.setNode(requestNode);
|
||||
}
|
||||
iqRequest.addChild(infoQueryRequest);
|
||||
final var future = connection.sendIqPacket(iqRequest);
|
||||
// TODO we need to remove the disco info associated with $entity in case of failure
|
||||
// this might happen in (rather unlikely) scenarios where an item no longer speaks disco
|
||||
|
@ -108,9 +108,18 @@ public class DiscoManager extends AbstractManager {
|
|||
}
|
||||
|
||||
public ListenableFuture<Collection<Item>> items(final Entity.DiscoItem entity) {
|
||||
return items(entity, null);
|
||||
}
|
||||
|
||||
public ListenableFuture<Collection<Item>> items(
|
||||
@NonNull final Entity.DiscoItem entity, @Nullable final String node) {
|
||||
final var requestNode = Strings.emptyToNull(node);
|
||||
final var iqPacket = new IqPacket(IqPacket.TYPE.GET);
|
||||
iqPacket.setTo(entity.address);
|
||||
iqPacket.addChild(new ItemsQuery());
|
||||
final var itemsQueryRequest = iqPacket.addChild(new ItemsQuery());
|
||||
if (requestNode != null) {
|
||||
itemsQueryRequest.setNode(requestNode);
|
||||
}
|
||||
final var future = connection.sendIqPacket(iqPacket);
|
||||
return Futures.transform(
|
||||
future,
|
||||
|
@ -119,10 +128,14 @@ public class DiscoManager extends AbstractManager {
|
|||
if (itemsQuery == null) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
if (!Objects.equals(requestNode, itemsQuery.getNode())) {
|
||||
throw new IllegalStateException(
|
||||
"Node in response did not match node in request");
|
||||
}
|
||||
final var items = itemsQuery.getExtensions(Item.class);
|
||||
final var validItems =
|
||||
Collections2.filter(items, i -> Objects.nonNull(i.getJid()));
|
||||
getDatabase().discoDao().set(getAccount(), entity, validItems);
|
||||
getDatabase().discoDao().set(getAccount(), entity, requestNode, validItems);
|
||||
return validItems;
|
||||
},
|
||||
MoreExecutors.directExecutor());
|
||||
|
|
|
@ -8,4 +8,12 @@ public class ItemsQuery extends Extension {
|
|||
public ItemsQuery() {
|
||||
super(ItemsQuery.class);
|
||||
}
|
||||
|
||||
public void setNode(final String node) {
|
||||
this.setAttribute("node", node);
|
||||
}
|
||||
|
||||
public String getNode() {
|
||||
return this.getAttribute("node");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue