1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
|
/*
Copyright (C) 2019-2024 Selwin van Dijk
This file is part of signalbackup-tools.
signalbackup-tools is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
signalbackup-tools is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with signalbackup-tools. If not, see <https://www.gnu.org/licenses/>.
*/
#include "signalbackup.ih"
void SignalBackup::mergeGroups(std::vector<std::string> const &groupids)
{
if (groupids.size() < 2)
{
Logger::error("Too few addresses");
return;
}
Logger::message("\nTHIS FUNCTION MAY NEED UPDATING. PLEASE OPEN AN ISSUE\n"
"IF YOU NEED IT.\n");
std::string targetgroup = groupids.back();
SqliteDB::QueryResults res;
std::set<std::string> targetmembersvec;
if (d_database.tableContainsColumn("groups", "members"))
{
d_database.exec("SELECT members FROM groups WHERE group_id = ?", targetgroup, &res);
std::string targetmembers = res.getValueAs<std::string>(0, 0);
std::stringstream ss(targetmembers);
while (ss.good())
{
std::string substr;
std::getline(ss, substr, ',');
targetmembersvec.insert(substr);
}
}
else
{
d_database.exec("SELECT DISTINCT recipient_id FROM group_membership WHERE group_id = ?", targetgroup, &res);
for (unsigned int i = 0; i < res.rows(); ++i)
targetmembersvec.insert(res.valueAsString(i, 0));
}
// get the thread_id of the target
long long int tid = getThreadIdFromRecipient(targetgroup);
if (tid != -1)
{
// update all messages from this addresses[i] to belong to that same thread and change address in new number
for (unsigned int i = 0; i < groupids.size() - 1; ++i)
{
long long int oldtid = getThreadIdFromRecipient(groupids[i]);
if (oldtid == -1)
{
Logger::error("Failed to find thread for old group: ", groupids[i]);
continue;
}
Logger::message("Dealing with group: ", groupids[i]);
if (d_database.containsTable("sms"))
{
d_database.exec("UPDATE sms SET thread_id = ? WHERE thread_id = ?", {tid, oldtid});
Logger::message("Updated ", d_database.changed(), " entries in 'sms' table");
d_database.exec("UPDATE sms SET " + d_sms_recipient_id + " = ? WHERE " + d_sms_recipient_id + " = ?",
{targetgroup, groupids[i]});
Logger::message("Updated ", d_database.changed(), " entries in 'sms' table");
}
d_database.exec("UPDATE " + d_mms_table + " SET thread_id = ? WHERE thread_id = ?", {tid, oldtid});
Logger::message("Updated ", d_database.changed(), " entries in 'mms' table");
if (!d_database.tableContainsColumn(d_mms_table, "to_recipient_id")) // < dbv185
{
d_database.exec("UPDATE " + d_mms_table + " SET " + d_mms_recipient_id + " = ? WHERE " + d_mms_recipient_id + " = ?",
{targetgroup, groupids[i]});
Logger::message("Updated ", d_database.changed(), " entries in 'mms' table");
}
else
{
// adjust to_recipient (= group id on outgoing messages)
d_database.exec("UPDATE " + d_mms_table + " SET to_recipient_id = ? WHERE to_recipient_id = ?",
{targetgroup, groupids[i]});
Logger::message("Updated ", d_database.changed(), " entries in 'mms' table");
}
if (d_database.containsTable("mention"))
{
d_database.exec("UPDATE mention SET thread_id = ? WHERE thread_id = ?", {tid, oldtid});
Logger::message("Updated ", d_database.changed(), " entries in 'sms' table");
}
if (d_database.containsTable("msl_recipient"))
d_database.exec("UPDATE msl_recipient SET recipient_id = ? WHERE recipient_id = ?", {targetgroup, groupids[i]});
if (d_database.containsTable("reaction")) // dbv >= 121
d_database.exec("UPDATE reaction SET author_id = ? WHERE author_id = ?", {targetgroup, groupids[i]});
// delete old (now empty) thread
d_database.exec("DELETE FROM thread WHERE " + d_thread_recipient_id + " = ?", groupids[i]);
Logger::message("Removed ", d_database.changed(), " threads from table");
// get members of groupids[i] and merge them into targetgroup
if (d_database.tableContainsColumn("groups", "members"))
{
d_database.exec("SELECT members FROM groups WHERE group_id = ?", groupids[i], &res);
std::string members = res.getValueAs<std::string>(0, 0);
std::stringstream ss2(members);
while (ss2.good())
{
std::string substr;
std::getline(ss2, substr, ',');
auto [it, inserted] = targetmembersvec.insert(substr);
if (inserted)
Logger::message("Added ", substr, " to memberlist of group");
else
Logger::message("Skipped adding ", substr, " to group: already a member");
}
}
else
{
d_database.exec("SELECT DISTINCT recipient_id FROM group_membership WHERE group_id = ?", groupids[i], &res);
for (unsigned int g = 0; g < res.rows(); ++g)
d_database.exec("INSERT OR IGNORE INTO group_membership (group_id, recipient_id) VALUES (?, ?)", {targetgroup, res.getValueAs<long long int>(g, "recipient_id")});
}
// delete the merged group
d_database.exec("DELETE FROM groups WHERE group_id = ?", groupids[i]);
Logger::message("Removed ", d_database.changed(), " groups from table");
if (d_database.containsTable("group_membership"))
d_database.exec("DELETE FROM group_membership WHERE group_id = ?", groupids[i]);
}
// set new member list
if (d_database.tableContainsColumn("groups", "members"))
{
Logger::message("Setting new memberlist");
std::string newmemberlist;
for (auto const &it : targetmembersvec)
newmemberlist += it + ',';
newmemberlist.pop_back(); // remove trailing comma...
d_database.exec("UPDATE groups SET members = ? WHERE group_id = ?", {newmemberlist, targetgroup});
}
}
else
{
Logger::warning("No group thread with id ", tid, " found");
}
updateThreadsEntries();
}
|