import 'package:bluebubbles/database/database.dart'; import 'package:bluebubbles/database/models.dart'; import 'package:bluebubbles/utils/logger/logger.dart'; import 'package:collection/collection.dart'; // UNUSED METHODS // List syncHandles(List handles) { // // Get a list of the addresses // List inputHandleAddresses = handles.map((element) => element.address).toList(); // // // Query the database for existing handles // QueryBuilder query = Database.handleBox.query(Handle_.address.oneOf(inputHandleAddresses)); // List existingHandles = query.build().find(); // List existingHandleAddresses = existingHandles.map((e) => e.address).toList(); // // // Insert any non-existing handles // List newHandles = handles.where((element) => !existingHandleAddresses.contains(element.address)).toList(); // Database.handleBox.putMany(newHandles); // // // Update any existing handles // if (existingHandles.isNotEmpty) { // int mods = 0; // for (var i = 0; i < existingHandles.length; i++) { // Handle? newHandle = handles.firstWhereOrNull((e) => e.address == existingHandles[i].address); // if (newHandle == null) continue; // // // We put newHandle first because we want the new info to take precedence // existingHandles[i] = Handle.merge(newHandle, existingHandles[i]); // mods += 1; // } // // if (mods > 0) { // Database.handleBox.putMany(existingHandles); // } // } // // // Return a list of the inserted/existing handles // QueryBuilder query2 = Database.handleBox.query(Handle_.address.oneOf(inputHandleAddresses)); // List syncedHandles = query2.build().find().toList(); // // // Insert the real IDs & other information // for (var i = 0; i < handles.length; i++) { // Handle? synced = syncedHandles.firstWhereOrNull((e) => e.address == handles[i].address); // if (synced == null) continue; // // handles[i] = Handle.merge(handles[i], synced); // } // // return handles; // } // // List syncChats(List chats) { // // Get a list of the GUIDs // List inputChatGuids = chats.map((element) => element.guid).toList(); // // // Query the database for existing chats // QueryBuilder query = Database.chatBox.query(Chat_.guid.oneOf(inputChatGuids)); // List existingChats = query.build().find(); // List existingChatGuids = existingChats.map((e) => e.guid).toList(); // // // Insert any non-existing chats // List newChats = chats.where((element) => !existingChatGuids.contains(element.guid)).toList(); // Database.chatBox.putMany(newChats); // // // Update any existing chats // if (existingChats.isNotEmpty) { // int mods = 0; // for (var i = 0; i < existingChats.length; i++) { // Chat? newChat = chats.firstWhereOrNull((e) => e.guid == existingChats[i].guid); // if (newChat == null) continue; // // // We put newChat first because we want the new info to take precedence // existingChats[i] = Chat.merge(newChat, existingChats[i]); // mods += 1; // } // // if (mods > 0) { // Database.chatBox.putMany(existingChats); // } // } // // // Return a list of the inserted/existing chats // QueryBuilder query2 = Database.chatBox.query(Chat_.guid.oneOf(inputChatGuids)); // List syncedChats = query2.build().find().toList(); // // // Insert the real ID // for (var i = 0; i < chats.length; i++) { // Chat? synced = syncedChats.firstWhereOrNull((e) => e.guid == chats[i].guid); // if (synced == null) continue; // // chats[i] = Chat.merge(chats[i], synced); // } // // return chats; // } List syncAttachments(List attachments) { // Get a list of the GUIDs List inputAttachmentGuids = attachments.map((element) => element.guid!).toList(); // Query the database for existing attachments final query = Database.attachments.query(Attachment_.guid.oneOf(inputAttachmentGuids)).build(); List existingAttachments = query.find(); List existingAttachmentGuids = existingAttachments.map((e) => e.guid!).toList(); // Insert any non-existing attachments List newAttachments = attachments.where( (element) => !existingAttachmentGuids.contains(element.guid)).toList(); Database.attachments.putMany(newAttachments); // Update any existing attachments if (existingAttachments.isNotEmpty) { int mods = 0; for (var i = 0; i < existingAttachments.length; i++) { Attachment? newAttachment = attachments.firstWhereOrNull((e) => e.guid == existingAttachments[i].guid); if (newAttachment == null) continue; // We put newAttachment first because we want the new info to take precedence existingAttachments[i] = Attachment.merge(newAttachment, existingAttachments[i]); mods += 1; } if (mods > 0) { Database.attachments.putMany(existingAttachments); } } // Return a list of the inserted/existing attachments final query2 = Database.attachments.query(Attachment_.guid.oneOf(inputAttachmentGuids)).build(); List syncedAttachments = query2.find().toList(); // Insert the real ID for (var i = 0; i < attachments.length; i++) { Attachment? synced = syncedAttachments.firstWhereOrNull((e) => e.guid == attachments[i].guid); if (synced == null) continue; attachments[i] = Attachment.merge(attachments[i], synced); } return attachments; } List syncMessages(Chat c, List messages) { // Get a list of the GUIDs List inputMessageGuids = messages.map((element) => element.guid!).toList(); // Query the database for existing messages final query = Database.messages.query(Message_.guid.oneOf(inputMessageGuids)).build(); List existingMessages = query.find(); List existingMessageGuids = existingMessages.map((e) => e.guid!).toList(); // Insert any non-existing messages List newMessages = messages.where((element) => !existingMessageGuids.contains(element.guid)).toList(); Database.messages.putMany(newMessages); // Update any existing messages if (existingMessages.isNotEmpty) { int mods = 0; for (var i = 0; i < existingMessages.length; i++) { Message? newMessage = messages.firstWhereOrNull((e) => e.guid == existingMessages[i].guid); if (newMessage == null) continue; // We put newMessage first because we want the new info to take precedence existingMessages[i] = Message.merge(newMessage, existingMessages[i]); mods += 1; } if (mods > 0) { Database.messages.putMany(existingMessages, mode: PutMode.update); } } matchChats() { // Return a list of the inserted/existing messages final query2 = Database.messages.query(Message_.guid.oneOf(inputMessageGuids)).build(); List syncedMessages = query2.find().toList(); // Insert the real ID & chat for (var i = 0; i < messages.length; i++) { Message? synced = syncedMessages.firstWhereOrNull((e) => e.guid == messages[i].guid); if (synced == null) continue; messages[i] = Message.merge(messages[i], synced); messages[i].chat.target = c; } // Apply the chats Database.messages.putMany(messages, mode: PutMode.update); } // Try the matchChats function 3 times, or until it succeeds int tries = 0; bool success = false; dynamic lastError; StackTrace? stackTrace; while (tries < 3) { try { matchChats(); success = true; break; } catch (ex, stack) { lastError = ex; stackTrace = stack; tries += 1; Logger.warn("Failed to match messages to chats, retrying... (Attempt $tries)", error: ex, trace: stackTrace); } } if (!success) { Logger.error("Failed to match messages to chats after 3 attempts, skipping...", error: lastError, trace: stackTrace); } else { Logger.debug("Successfully matched messages to chats after ${tries + 1} attempts!"); } return messages; }