remove dao methods to delete data when user is removed

...will be done by foreign keys cascading. Therefore, also added foreign key to ChatBlockEntity

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
Marcel Hibbe 2024-08-09 20:01:32 +02:00
parent e951b3d53a
commit da04f536f7
No known key found for this signature in database
GPG Key ID: C793F8B59F43CE7B
7 changed files with 52 additions and 24 deletions

View File

@ -2,7 +2,7 @@
"formatVersion": 1,
"database": {
"version": 10,
"identityHash": "1b97b7e937102e4087f8534f1204fe94",
"identityHash": "c07a2543aa583e08e7b3208f44fcc7ac",
"entities": [
{
"tableName": "User",
@ -138,7 +138,7 @@
},
{
"tableName": "Conversations",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`internalId` TEXT NOT NULL, `accountId` INTEGER, `token` TEXT, `name` TEXT, `displayName` TEXT, `description` TEXT, `type` TEXT, `lastPing` INTEGER NOT NULL, `participantType` TEXT, `hasPassword` INTEGER NOT NULL, `sessionId` TEXT, `actorId` TEXT, `actorType` TEXT, `isFavorite` INTEGER NOT NULL, `lastActivity` INTEGER NOT NULL, `unreadMessages` INTEGER NOT NULL, `unreadMention` INTEGER NOT NULL, `lastMessageJson` TEXT, `objectType` TEXT, `notificationLevel` TEXT, `readOnly` TEXT, `lobbyState` TEXT, `lobbyTimer` INTEGER, `lastReadMessage` INTEGER NOT NULL, `lastCommonReadMessage` INTEGER NOT NULL, `hasCall` INTEGER NOT NULL, `callFlag` INTEGER NOT NULL, `canStartCall` INTEGER NOT NULL, `canLeaveConversation` INTEGER, `canDeleteConversation` INTEGER, `unreadMentionDirect` INTEGER, `notificationCalls` INTEGER, `permissions` INTEGER NOT NULL, `messageExpiration` INTEGER NOT NULL, `status` TEXT, `statusIcon` TEXT, `statusMessage` TEXT, `statusClearAt` INTEGER, `callRecording` INTEGER NOT NULL, `avatarVersion` TEXT, `isCustomAvatar` INTEGER, `callStartTime` INTEGER, `recordingConsent` INTEGER NOT NULL, `remoteServer` TEXT, `remoteToken` TEXT, PRIMARY KEY(`internalId`), FOREIGN KEY(`accountId`) REFERENCES `User`(`id`) ON UPDATE CASCADE ON DELETE CASCADE )",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`internalId` TEXT NOT NULL, `accountId` INTEGER NOT NULL, `token` TEXT, `name` TEXT, `displayName` TEXT, `description` TEXT, `type` TEXT, `lastPing` INTEGER NOT NULL, `participantType` TEXT, `hasPassword` INTEGER NOT NULL, `sessionId` TEXT, `actorId` TEXT, `actorType` TEXT, `isFavorite` INTEGER NOT NULL, `lastActivity` INTEGER NOT NULL, `unreadMessages` INTEGER NOT NULL, `unreadMention` INTEGER NOT NULL, `lastMessageJson` TEXT, `objectType` TEXT, `notificationLevel` TEXT, `readOnly` TEXT, `lobbyState` TEXT, `lobbyTimer` INTEGER, `lastReadMessage` INTEGER NOT NULL, `lastCommonReadMessage` INTEGER NOT NULL, `hasCall` INTEGER NOT NULL, `callFlag` INTEGER NOT NULL, `canStartCall` INTEGER NOT NULL, `canLeaveConversation` INTEGER, `canDeleteConversation` INTEGER, `unreadMentionDirect` INTEGER, `notificationCalls` INTEGER, `permissions` INTEGER NOT NULL, `messageExpiration` INTEGER NOT NULL, `status` TEXT, `statusIcon` TEXT, `statusMessage` TEXT, `statusClearAt` INTEGER, `callRecording` INTEGER NOT NULL, `avatarVersion` TEXT, `isCustomAvatar` INTEGER, `callStartTime` INTEGER, `recordingConsent` INTEGER NOT NULL, `remoteServer` TEXT, `remoteToken` TEXT, PRIMARY KEY(`internalId`), FOREIGN KEY(`accountId`) REFERENCES `User`(`id`) ON UPDATE CASCADE ON DELETE CASCADE )",
"fields": [
{
"fieldPath": "internalId",
@ -150,7 +150,7 @@
"fieldPath": "accountId",
"columnName": "accountId",
"affinity": "INTEGER",
"notNull": false
"notNull": true
},
{
"fieldPath": "token",
@ -633,7 +633,7 @@
},
{
"tableName": "ChatBlocks",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `internalConversationId` TEXT NOT NULL, `oldestMessageId` INTEGER NOT NULL, `newestMessageId` INTEGER NOT NULL, `hasHistory` INTEGER NOT NULL)",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `internalConversationId` TEXT NOT NULL, `accountId` INTEGER, `token` TEXT, `oldestMessageId` INTEGER NOT NULL, `newestMessageId` INTEGER NOT NULL, `hasHistory` INTEGER NOT NULL, FOREIGN KEY(`internalConversationId`) REFERENCES `Conversations`(`internalId`) ON UPDATE CASCADE ON DELETE CASCADE )",
"fields": [
{
"fieldPath": "id",
@ -647,6 +647,18 @@
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "accountId",
"columnName": "accountId",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "token",
"columnName": "token",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "oldestMessageId",
"columnName": "oldestMessageId",
@ -673,13 +685,25 @@
]
},
"indices": [],
"foreignKeys": []
"foreignKeys": [
{
"table": "Conversations",
"onDelete": "CASCADE",
"onUpdate": "CASCADE",
"columns": [
"internalConversationId"
],
"referencedColumns": [
"internalId"
]
}
]
}
],
"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, '1b97b7e937102e4087f8534f1204fe94')"
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'c07a2543aa583e08e7b3208f44fcc7ac')"
]
}
}

View File

@ -421,6 +421,8 @@ class OfflineFirstChatRepository @Inject constructor(
val newChatBlock = ChatBlockEntity(
internalConversationId = internalConversationId,
accountId = conversationModel.accountId,
token = conversationModel.token,
oldestMessageId = oldestMessageIdForNewChatBlock,
newestMessageId = newestMessageIdForNewChatBlock,
hasHistory = hasHistory
@ -531,6 +533,8 @@ class OfflineFirstChatRepository @Inject constructor(
val newChatBlock = ChatBlockEntity(
internalConversationId = internalConversationId,
accountId = conversationModel.accountId,
token = conversationModel.token,
oldestMessageId = oldestIdFromDbChatBlocks,
newestMessageId = newestIdFromDbChatBlocks,
hasHistory = hasHistory

View File

@ -16,6 +16,7 @@ import com.nextcloud.talk.models.json.conversations.Conversation
fun ConversationModel.asEntity() =
ConversationEntity(
internalId = internalId,
accountId = accountId,
token = token,
name = name,
displayName = displayName,
@ -64,6 +65,7 @@ fun ConversationModel.asEntity() =
fun ConversationEntity.asModel() =
ConversationModel(
internalId = internalId,
accountId = accountId,
token = token,
name = name,
displayName = displayName,

View File

@ -12,18 +12,24 @@ import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(
tableName = "ChatBlocks"
// indices = [
// androidx.room.Index(value = ["accountId"])
// ]
tableName = "ChatBlocks",
foreignKeys = [
androidx.room.ForeignKey(
entity = ConversationEntity::class,
parentColumns = arrayOf("internalId"),
childColumns = arrayOf("internalConversationId"),
onDelete = androidx.room.ForeignKey.CASCADE,
onUpdate = androidx.room.ForeignKey.CASCADE
)
],
)
data class ChatBlockEntity(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id") var id: Int = 0,
@ColumnInfo(name = "id") var id: Long = 0,
// accountId@token
@ColumnInfo(name = "internalConversationId") var internalConversationId: String,
// @ColumnInfo(name = "accountId") var accountId: Long? = null,
// @ColumnInfo(name = "token") var token: String?,
@ColumnInfo(name = "accountId") var accountId: Long? = null,
@ColumnInfo(name = "token") var token: String?,
@ColumnInfo(name = "oldestMessageId") var oldestMessageId: Long,
@ColumnInfo(name = "newestMessageId") var newestMessageId: Long,
@ColumnInfo(name = "hasHistory") var hasHistory: Boolean

View File

@ -36,7 +36,7 @@ data class ConversationEntity(
var internalId: String,
// Defines to which talk app account this conversation belongs to
@ColumnInfo(name = "accountId") var accountId: Long? = null,
@ColumnInfo(name = "accountId") var accountId: Long,
// We don't use token as primary key as we have to manage multiple talk app accounts on
// the phone, thus multiple accounts can have the same conversation in their list. That's why the servers

View File

@ -182,7 +182,6 @@ public class AccountRemovalWorker extends Worker {
try {
arbitraryStorageManager.deleteAllEntriesForAccountIdentifier(user.getId());
deleteAllUserInfo(user);
deleteUser(user);
} catch (Throwable e) {
Log.e(TAG, "error while trying to delete All Entries For Account Identifier", e);
@ -190,14 +189,6 @@ public class AccountRemovalWorker extends Worker {
}
}
private void deleteAllUserInfo(User user) {
String accountId = Objects.requireNonNull(user.getId()).toString();
String pattern = accountId + "@%"; // ... LIKE "<accountId>@%"
chatMessagesDao.clearAllMessagesForUser(pattern);
conversationsDao.clearAllConversationsForUser(user.getId());
chatBlocksDao.clearChatBlocksForUser(pattern);
}
private void deleteUser(User user) {
if (user.getId() != null) {
String username = user.getUsername();

View File

@ -15,6 +15,7 @@ import com.nextcloud.talk.models.json.participants.Participant
class ConversationModel(
var internalId: String,
var accountId: Long,
var roomId: String? = null,
var token: String? = null,
var name: String? = null,
@ -32,7 +33,6 @@ class ConversationModel(
var lastActivity: Long = 0,
var unreadMessages: Int = 0,
var unreadMention: Boolean = false,
// var lastMessageViaConversationList: LastMessageJson? = null,
var lastMessageViaConversationList: ChatMessageJson? = null,
var objectType: ConversationEnums.ObjectType? = null,
var notificationLevel: ConversationEnums.NotificationLevel? = null,
@ -67,6 +67,7 @@ class ConversationModel(
fun mapToConversationModel(conversation: Conversation, user: User): ConversationModel {
return ConversationModel(
internalId = user.id!!.toString() + "@" + conversation.token,
accountId = user.id!!,
roomId = conversation.roomId,
token = conversation.token,
name = conversation.name,