delete unused disco info on bind

This commit is contained in:
Daniel Gultsch 2023-03-08 16:04:18 +01:00
parent 9a0c2226c1
commit b2c348a1df
No known key found for this signature in database
GPG key ID: F43D18AD2A0982C2
5 changed files with 40 additions and 7 deletions

View file

@ -2,7 +2,7 @@
"formatVersion": 1, "formatVersion": 1,
"database": { "database": {
"version": 1, "version": 1,
"identityHash": "414be5ac9e68ecf9063dddbcc1cf993a", "identityHash": "1780dce1d6aca78c94a2c5c497d158c5",
"entities": [ "entities": [
{ {
"tableName": "account", "tableName": "account",
@ -1088,7 +1088,7 @@
}, },
{ {
"tableName": "disco", "tableName": "disco",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `accountId` INTEGER NOT NULL, `capsHash` BLOB, `caps2HashSha256` BLOB, FOREIGN KEY(`accountId`) REFERENCES `account`(`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, `capsHash` BLOB, `caps2HashSha256` BLOB, `cache` INTEGER NOT NULL, FOREIGN KEY(`accountId`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@ -1113,6 +1113,12 @@
"columnName": "caps2HashSha256", "columnName": "caps2HashSha256",
"affinity": "BLOB", "affinity": "BLOB",
"notNull": false "notNull": false
},
{
"fieldPath": "cache",
"columnName": "cache",
"affinity": "INTEGER",
"notNull": true
} }
], ],
"primaryKey": { "primaryKey": {
@ -2594,7 +2600,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, '414be5ac9e68ecf9063dddbcc1cf993a')" "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '1780dce1d6aca78c94a2c5c497d158c5')"
] ]
} }
} }

View file

@ -147,14 +147,15 @@ public abstract class DiscoDao {
final String node, final String node,
final byte[] capsHash, final byte[] capsHash,
final byte[] caps2HashSha256, final byte[] caps2HashSha256,
final InfoQuery infoQuery) { final InfoQuery infoQuery,
final boolean cache) {
final Long existingDiscoId = getDiscoId(account.id, caps2HashSha256); final Long existingDiscoId = getDiscoId(account.id, caps2HashSha256);
if (existingDiscoId != null) { if (existingDiscoId != null) {
updateDiscoId(account.id, entity, node, existingDiscoId); updateDiscoId(account.id, entity, node, existingDiscoId);
return; return;
} }
final long discoId = insert(DiscoEntity.of(account.id, capsHash, caps2HashSha256)); final long discoId = insert(DiscoEntity.of(account.id, capsHash, caps2HashSha256, cache));
insertDiscoIdentities( insertDiscoIdentities(
Collections2.transform( Collections2.transform(
@ -177,6 +178,12 @@ public abstract class DiscoDao {
updateDiscoId(account.id, entity, node, discoId); updateDiscoId(account.id, entity, node, discoId);
} }
@Query(
"DELETE FROM disco WHERE accountId=:account AND cache=0 AND id NOT IN(SELECT discoId"
+ " FROM presence WHERE discoId IS NOT NULL) AND id NOT IN(SELECT discoId FROM"
+ " disco_item WHERE discoId IS NOT NULL)")
public abstract void deleteUnused(long account);
@Query("SELECT id FROM disco WHERE accountId=:accountId AND caps2HashSha256=:caps2HashSha256") @Query("SELECT id FROM disco WHERE accountId=:accountId AND caps2HashSha256=:caps2HashSha256")
protected abstract Long getDiscoId(final long accountId, final byte[] caps2HashSha256); protected abstract Long getDiscoId(final long accountId, final byte[] caps2HashSha256);

View file

@ -30,12 +30,18 @@ public class DiscoEntity {
public byte[] capsHash; public byte[] capsHash;
public byte[] caps2HashSha256; public byte[] caps2HashSha256;
public boolean cache;
public static DiscoEntity of( public static DiscoEntity of(
final long accountId, final byte[] capsHash, final byte[] caps2HashSha256) { final long accountId,
final byte[] capsHash,
final byte[] caps2HashSha256,
final boolean cache) {
final var entity = new DiscoEntity(); final var entity = new DiscoEntity();
entity.accountId = accountId; entity.accountId = accountId;
entity.capsHash = capsHash; entity.capsHash = capsHash;
entity.caps2HashSha256 = caps2HashSha256; entity.caps2HashSha256 = caps2HashSha256;
entity.cache = cache;
return entity; return entity;
} }
} }

View file

@ -173,9 +173,22 @@ public class DiscoManager extends AbstractManager {
caps2, caps2,
EntityCapabilities2.EntityCaps2Hash.class); EntityCapabilities2.EntityCaps2Hash.class);
} }
// we want to avoid caching disco info for entities that put variable data (like
// number of occupants in a MUC) into it
final boolean cache =
Objects.nonNull(hash)
|| infoQuery.hasFeature(Namespace.ENTITY_CAPABILITIES)
|| infoQuery.hasFeature(Namespace.ENTITY_CAPABILITIES_2);
getDatabase() getDatabase()
.discoDao() .discoDao()
.set(getAccount(), entity, node, caps.hash, caps2.hash, infoQuery); .set(
getAccount(),
entity,
node,
caps.hash,
caps2.hash,
infoQuery,
cache);
return infoQuery; return infoQuery;
}, },
MoreExecutors.directExecutor()); MoreExecutors.directExecutor());

View file

@ -37,6 +37,7 @@ public class BindProcessor extends XmppConnection.Delegate implements Consumer<J
() -> { () -> {
database.chatDao().resetMucStates(); database.chatDao().resetMucStates();
database.presenceDao().deletePresences(account.id); database.presenceDao().deletePresences(account.id);
database.discoDao().deleteUnused(account.id);
}); });
getManager(RosterManager.class).fetch(); getManager(RosterManager.class).fetch();