refactor(History): Split peers table into chats and authors
peers had combined meaning, both being referenced by history for which
chat a message was in, and being reference by aliases for who authored a
message. This means that peers had conceptually different sub-groups:
all friends are both a chat and an author, but self is an author but not
a chat. With the addition of group chats this is amplified by groups
themselves being chats but not authors, and group members being authors
but not chats. Instead of having four sub-groups all within peers,
splitting peers into chats and authors gives a clean mapping,
simplifying interactions with the data.
In the new chats and authors tables, store what used to be a public_key
string as a BLOB, since it’s inherently a 32-byte binary value in both
cases. Call the public_key a UUID for chats, since group IDs are not
defined as public keys by toxcore.
Even though the data change is quite minor, the upgrade is large because
of SQLite's lack of support for modifying foreign key constrains for
existing tables. This means when peers are moved to new tables, all
tables referencing peers need to be cloned with a new foreign key
constraint, as well as all tables referencing those, recursively.
2022-03-22 19:43:27 +08:00
|
|
|
/*
|
|
|
|
Copyright © 2022 by The qTox Project Contributors
|
|
|
|
|
|
|
|
This file is part of qTox, a Qt-based graphical interface for Tox.
|
|
|
|
|
|
|
|
qTox is libre 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.
|
|
|
|
|
|
|
|
qTox 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 qTox. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "src/core/toxpk.h"
|
|
|
|
#include "src/persistence/db/rawdatabase.h"
|
|
|
|
#include "src/persistence/db/upgrades/dbto11.h"
|
|
|
|
|
|
|
|
#include "dbutility/dbutility.h"
|
|
|
|
|
|
|
|
#include <QByteArray>
|
|
|
|
#include <QTemporaryFile>
|
|
|
|
#include <QTest>
|
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
const auto selfPk = ToxPk{QByteArray(32, 0)};
|
2022-04-01 08:34:38 +08:00
|
|
|
const auto aPk = ToxPk{QByteArray(32, '=')};
|
refactor(History): Split peers table into chats and authors
peers had combined meaning, both being referenced by history for which
chat a message was in, and being reference by aliases for who authored a
message. This means that peers had conceptually different sub-groups:
all friends are both a chat and an author, but self is an author but not
a chat. With the addition of group chats this is amplified by groups
themselves being chats but not authors, and group members being authors
but not chats. Instead of having four sub-groups all within peers,
splitting peers into chats and authors gives a clean mapping,
simplifying interactions with the data.
In the new chats and authors tables, store what used to be a public_key
string as a BLOB, since it’s inherently a 32-byte binary value in both
cases. Call the public_key a UUID for chats, since group IDs are not
defined as public keys by toxcore.
Even though the data change is quite minor, the upgrade is large because
of SQLite's lack of support for modifying foreign key constrains for
existing tables. This means when peers are moved to new tables, all
tables referencing peers need to be cloned with a new foreign key
constraint, as well as all tables referencing those, recursively.
2022-03-22 19:43:27 +08:00
|
|
|
const auto bPk = ToxPk{QByteArray(32, 2)};
|
|
|
|
const auto cPk = ToxPk{QByteArray(32, 3)};
|
|
|
|
const auto selfName = QStringLiteral("Self");
|
|
|
|
const auto aName = QStringLiteral("Alice");
|
|
|
|
const auto bName = QStringLiteral("Bob");
|
|
|
|
const auto selfAliasId = 1;
|
|
|
|
const auto aPeerId = 2;
|
2022-04-01 08:34:38 +08:00
|
|
|
const auto aPeerDuplicateId = 5;
|
|
|
|
const auto aChatId = 3;
|
refactor(History): Split peers table into chats and authors
peers had combined meaning, both being referenced by history for which
chat a message was in, and being reference by aliases for who authored a
message. This means that peers had conceptually different sub-groups:
all friends are both a chat and an author, but self is an author but not
a chat. With the addition of group chats this is amplified by groups
themselves being chats but not authors, and group members being authors
but not chats. Instead of having four sub-groups all within peers,
splitting peers into chats and authors gives a clean mapping,
simplifying interactions with the data.
In the new chats and authors tables, store what used to be a public_key
string as a BLOB, since it’s inherently a 32-byte binary value in both
cases. Call the public_key a UUID for chats, since group IDs are not
defined as public keys by toxcore.
Even though the data change is quite minor, the upgrade is large because
of SQLite's lack of support for modifying foreign key constrains for
existing tables. This means when peers are moved to new tables, all
tables referencing peers need to be cloned with a new foreign key
constraint, as well as all tables referencing those, recursively.
2022-03-22 19:43:27 +08:00
|
|
|
const auto aAliasId = 2;
|
2022-04-01 08:34:38 +08:00
|
|
|
const auto aAliasDuplicateId = 4;
|
refactor(History): Split peers table into chats and authors
peers had combined meaning, both being referenced by history for which
chat a message was in, and being reference by aliases for who authored a
message. This means that peers had conceptually different sub-groups:
all friends are both a chat and an author, but self is an author but not
a chat. With the addition of group chats this is amplified by groups
themselves being chats but not authors, and group members being authors
but not chats. Instead of having four sub-groups all within peers,
splitting peers into chats and authors gives a clean mapping,
simplifying interactions with the data.
In the new chats and authors tables, store what used to be a public_key
string as a BLOB, since it’s inherently a 32-byte binary value in both
cases. Call the public_key a UUID for chats, since group IDs are not
defined as public keys by toxcore.
Even though the data change is quite minor, the upgrade is large because
of SQLite's lack of support for modifying foreign key constrains for
existing tables. This means when peers are moved to new tables, all
tables referencing peers need to be cloned with a new foreign key
constraint, as well as all tables referencing those, recursively.
2022-03-22 19:43:27 +08:00
|
|
|
const auto bPeerId = 3;
|
2022-04-01 08:34:38 +08:00
|
|
|
const auto bChatId = 1;
|
refactor(History): Split peers table into chats and authors
peers had combined meaning, both being referenced by history for which
chat a message was in, and being reference by aliases for who authored a
message. This means that peers had conceptually different sub-groups:
all friends are both a chat and an author, but self is an author but not
a chat. With the addition of group chats this is amplified by groups
themselves being chats but not authors, and group members being authors
but not chats. Instead of having four sub-groups all within peers,
splitting peers into chats and authors gives a clean mapping,
simplifying interactions with the data.
In the new chats and authors tables, store what used to be a public_key
string as a BLOB, since it’s inherently a 32-byte binary value in both
cases. Call the public_key a UUID for chats, since group IDs are not
defined as public keys by toxcore.
Even though the data change is quite minor, the upgrade is large because
of SQLite's lack of support for modifying foreign key constrains for
existing tables. This means when peers are moved to new tables, all
tables referencing peers need to be cloned with a new foreign key
constraint, as well as all tables referencing those, recursively.
2022-03-22 19:43:27 +08:00
|
|
|
const auto bAliasId = 3;
|
|
|
|
const auto cPeerId = 4;
|
2022-04-01 08:34:38 +08:00
|
|
|
const auto cChatId = 2;
|
refactor(History): Split peers table into chats and authors
peers had combined meaning, both being referenced by history for which
chat a message was in, and being reference by aliases for who authored a
message. This means that peers had conceptually different sub-groups:
all friends are both a chat and an author, but self is an author but not
a chat. With the addition of group chats this is amplified by groups
themselves being chats but not authors, and group members being authors
but not chats. Instead of having four sub-groups all within peers,
splitting peers into chats and authors gives a clean mapping,
simplifying interactions with the data.
In the new chats and authors tables, store what used to be a public_key
string as a BLOB, since it’s inherently a 32-byte binary value in both
cases. Call the public_key a UUID for chats, since group IDs are not
defined as public keys by toxcore.
Even though the data change is quite minor, the upgrade is large because
of SQLite's lack of support for modifying foreign key constrains for
existing tables. This means when peers are moved to new tables, all
tables referencing peers need to be cloned with a new foreign key
constraint, as well as all tables referencing those, recursively.
2022-03-22 19:43:27 +08:00
|
|
|
|
|
|
|
void appendAddPeersQueries(QVector<RawDatabase::Query>& setupQueries)
|
|
|
|
{
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO peers (id, public_key) VALUES (1, ?)"),
|
|
|
|
{selfPk.toString().toUtf8()}});
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO peers (id, public_key) VALUES (2, ?)"),
|
|
|
|
{aPk.toString().toUtf8()}});
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO peers (id, public_key) VALUES (3, ?)"),
|
|
|
|
{bPk.toString().toUtf8()}});
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO peers (id, public_key) VALUES (4, ?)"),
|
|
|
|
{cPk.toString().toUtf8()}});
|
2022-04-01 08:34:38 +08:00
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO peers (id, public_key) VALUES (5, ?)"),
|
|
|
|
{aPk.toString().toLower().toUtf8()}});
|
refactor(History): Split peers table into chats and authors
peers had combined meaning, both being referenced by history for which
chat a message was in, and being reference by aliases for who authored a
message. This means that peers had conceptually different sub-groups:
all friends are both a chat and an author, but self is an author but not
a chat. With the addition of group chats this is amplified by groups
themselves being chats but not authors, and group members being authors
but not chats. Instead of having four sub-groups all within peers,
splitting peers into chats and authors gives a clean mapping,
simplifying interactions with the data.
In the new chats and authors tables, store what used to be a public_key
string as a BLOB, since it’s inherently a 32-byte binary value in both
cases. Call the public_key a UUID for chats, since group IDs are not
defined as public keys by toxcore.
Even though the data change is quite minor, the upgrade is large because
of SQLite's lack of support for modifying foreign key constrains for
existing tables. This means when peers are moved to new tables, all
tables referencing peers need to be cloned with a new foreign key
constraint, as well as all tables referencing those, recursively.
2022-03-22 19:43:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void appendVerifyChatsQueries(QVector<RawDatabase::Query>& verifyQueries)
|
|
|
|
{
|
|
|
|
verifyQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"SELECT COUNT(*) FROM chats"),
|
|
|
|
[&](const QVector<QVariant>& row) {
|
|
|
|
QVERIFY(row[0].toLongLong() == 3);
|
|
|
|
}});
|
|
|
|
|
|
|
|
struct Functor {
|
|
|
|
const std::vector<QByteArray> chatIds{aPk.getByteArray(), bPk.getByteArray(), cPk.getByteArray()};
|
|
|
|
void operator()(const QVector<QVariant>& row) {
|
2022-04-01 11:14:10 +08:00
|
|
|
QVERIFY(std::find(chatIds.begin(), chatIds.end(), row[0].toByteArray()) != chatIds.end());
|
refactor(History): Split peers table into chats and authors
peers had combined meaning, both being referenced by history for which
chat a message was in, and being reference by aliases for who authored a
message. This means that peers had conceptually different sub-groups:
all friends are both a chat and an author, but self is an author but not
a chat. With the addition of group chats this is amplified by groups
themselves being chats but not authors, and group members being authors
but not chats. Instead of having four sub-groups all within peers,
splitting peers into chats and authors gives a clean mapping,
simplifying interactions with the data.
In the new chats and authors tables, store what used to be a public_key
string as a BLOB, since it’s inherently a 32-byte binary value in both
cases. Call the public_key a UUID for chats, since group IDs are not
defined as public keys by toxcore.
Even though the data change is quite minor, the upgrade is large because
of SQLite's lack of support for modifying foreign key constrains for
existing tables. This means when peers are moved to new tables, all
tables referencing peers need to be cloned with a new foreign key
constraint, as well as all tables referencing those, recursively.
2022-03-22 19:43:27 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
verifyQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"SELECT uuid FROM chats"),
|
|
|
|
Functor()});
|
|
|
|
}
|
|
|
|
|
|
|
|
void appendVerifyAuthorsQueries(QVector<RawDatabase::Query>& verifyQueries)
|
|
|
|
{
|
|
|
|
verifyQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"SELECT COUNT(*) FROM authors"),
|
|
|
|
[&](const QVector<QVariant>& row) {
|
|
|
|
QVERIFY(row[0].toLongLong() == 3);
|
|
|
|
}});
|
|
|
|
|
|
|
|
struct Functor {
|
2022-04-01 11:14:10 +08:00
|
|
|
const std::vector<QByteArray> authorIds{selfPk.getByteArray(), aPk.getByteArray(), bPk.getByteArray()};
|
refactor(History): Split peers table into chats and authors
peers had combined meaning, both being referenced by history for which
chat a message was in, and being reference by aliases for who authored a
message. This means that peers had conceptually different sub-groups:
all friends are both a chat and an author, but self is an author but not
a chat. With the addition of group chats this is amplified by groups
themselves being chats but not authors, and group members being authors
but not chats. Instead of having four sub-groups all within peers,
splitting peers into chats and authors gives a clean mapping,
simplifying interactions with the data.
In the new chats and authors tables, store what used to be a public_key
string as a BLOB, since it’s inherently a 32-byte binary value in both
cases. Call the public_key a UUID for chats, since group IDs are not
defined as public keys by toxcore.
Even though the data change is quite minor, the upgrade is large because
of SQLite's lack of support for modifying foreign key constrains for
existing tables. This means when peers are moved to new tables, all
tables referencing peers need to be cloned with a new foreign key
constraint, as well as all tables referencing those, recursively.
2022-03-22 19:43:27 +08:00
|
|
|
void operator()(const QVector<QVariant>& row) {
|
2022-04-01 11:14:10 +08:00
|
|
|
QVERIFY(std::find(authorIds.begin(), authorIds.end(), row[0].toByteArray()) != authorIds.end());
|
refactor(History): Split peers table into chats and authors
peers had combined meaning, both being referenced by history for which
chat a message was in, and being reference by aliases for who authored a
message. This means that peers had conceptually different sub-groups:
all friends are both a chat and an author, but self is an author but not
a chat. With the addition of group chats this is amplified by groups
themselves being chats but not authors, and group members being authors
but not chats. Instead of having four sub-groups all within peers,
splitting peers into chats and authors gives a clean mapping,
simplifying interactions with the data.
In the new chats and authors tables, store what used to be a public_key
string as a BLOB, since it’s inherently a 32-byte binary value in both
cases. Call the public_key a UUID for chats, since group IDs are not
defined as public keys by toxcore.
Even though the data change is quite minor, the upgrade is large because
of SQLite's lack of support for modifying foreign key constrains for
existing tables. This means when peers are moved to new tables, all
tables referencing peers need to be cloned with a new foreign key
constraint, as well as all tables referencing those, recursively.
2022-03-22 19:43:27 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
verifyQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"SELECT public_key FROM authors"),
|
|
|
|
Functor()});
|
|
|
|
}
|
|
|
|
|
|
|
|
void appendAddAliasesQueries(QVector<RawDatabase::Query>& setupQueries)
|
|
|
|
{
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO aliases (id, owner, display_name) VALUES (1, 1, ?)"),
|
|
|
|
{selfName.toUtf8()}});
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO aliases (id, owner, display_name) VALUES (2, 2, ?)"),
|
|
|
|
{aName.toUtf8()}});
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO aliases (id, owner, display_name) VALUES (3, 3, ?)"),
|
|
|
|
{bName.toUtf8()}});
|
2022-04-01 08:34:38 +08:00
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO aliases (id, owner, display_name) VALUES (4, 5, ?)"),
|
|
|
|
{aName.toUtf8()}});
|
refactor(History): Split peers table into chats and authors
peers had combined meaning, both being referenced by history for which
chat a message was in, and being reference by aliases for who authored a
message. This means that peers had conceptually different sub-groups:
all friends are both a chat and an author, but self is an author but not
a chat. With the addition of group chats this is amplified by groups
themselves being chats but not authors, and group members being authors
but not chats. Instead of having four sub-groups all within peers,
splitting peers into chats and authors gives a clean mapping,
simplifying interactions with the data.
In the new chats and authors tables, store what used to be a public_key
string as a BLOB, since it’s inherently a 32-byte binary value in both
cases. Call the public_key a UUID for chats, since group IDs are not
defined as public keys by toxcore.
Even though the data change is quite minor, the upgrade is large because
of SQLite's lack of support for modifying foreign key constrains for
existing tables. This means when peers are moved to new tables, all
tables referencing peers need to be cloned with a new foreign key
constraint, as well as all tables referencing those, recursively.
2022-03-22 19:43:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void appendVerifyAliasesQueries(QVector<RawDatabase::Query>& verifyQueries)
|
|
|
|
{
|
|
|
|
verifyQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"SELECT COUNT(*) FROM aliases"),
|
|
|
|
[&](const QVector<QVariant>& row) {
|
|
|
|
QVERIFY(row[0].toLongLong() == 3);
|
|
|
|
}});
|
|
|
|
|
|
|
|
struct Functor {
|
|
|
|
const std::vector<QByteArray> names{selfName.toUtf8(), aName.toUtf8(), bName.toUtf8()};
|
|
|
|
void operator()(const QVector<QVariant>& row) {
|
2022-04-01 11:14:10 +08:00
|
|
|
QVERIFY(std::find(names.begin(), names.end(), row[0].toByteArray()) != names.end());
|
refactor(History): Split peers table into chats and authors
peers had combined meaning, both being referenced by history for which
chat a message was in, and being reference by aliases for who authored a
message. This means that peers had conceptually different sub-groups:
all friends are both a chat and an author, but self is an author but not
a chat. With the addition of group chats this is amplified by groups
themselves being chats but not authors, and group members being authors
but not chats. Instead of having four sub-groups all within peers,
splitting peers into chats and authors gives a clean mapping,
simplifying interactions with the data.
In the new chats and authors tables, store what used to be a public_key
string as a BLOB, since it’s inherently a 32-byte binary value in both
cases. Call the public_key a UUID for chats, since group IDs are not
defined as public keys by toxcore.
Even though the data change is quite minor, the upgrade is large because
of SQLite's lack of support for modifying foreign key constrains for
existing tables. This means when peers are moved to new tables, all
tables referencing peers need to be cloned with a new foreign key
constraint, as well as all tables referencing those, recursively.
2022-03-22 19:43:27 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
verifyQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"SELECT display_name FROM aliases"),
|
|
|
|
Functor()});
|
|
|
|
}
|
|
|
|
|
|
|
|
void appendAddAChatMessagesQueries(QVector<RawDatabase::Query>& setupQueries)
|
|
|
|
{
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO history (id, message_type, timestamp, chat_id) VALUES (1, 'T', 0, '%1')").arg(aPeerId)});
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO text_messages (id, message_type, sender_alias, message) VALUES (1, 'T', '%1', ?)").arg(aAliasId),
|
|
|
|
{QStringLiteral("Message 1 from A to Self").toUtf8()}});
|
|
|
|
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO history (id, message_type, timestamp, chat_id) VALUES (2, 'T', 0, '%1')").arg(aPeerId)});
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
2022-04-01 08:34:38 +08:00
|
|
|
"INSERT INTO text_messages (id, message_type, sender_alias, message) VALUES (2, 'T', '%1', ?)").arg(aAliasDuplicateId),
|
refactor(History): Split peers table into chats and authors
peers had combined meaning, both being referenced by history for which
chat a message was in, and being reference by aliases for who authored a
message. This means that peers had conceptually different sub-groups:
all friends are both a chat and an author, but self is an author but not
a chat. With the addition of group chats this is amplified by groups
themselves being chats but not authors, and group members being authors
but not chats. Instead of having four sub-groups all within peers,
splitting peers into chats and authors gives a clean mapping,
simplifying interactions with the data.
In the new chats and authors tables, store what used to be a public_key
string as a BLOB, since it’s inherently a 32-byte binary value in both
cases. Call the public_key a UUID for chats, since group IDs are not
defined as public keys by toxcore.
Even though the data change is quite minor, the upgrade is large because
of SQLite's lack of support for modifying foreign key constrains for
existing tables. This means when peers are moved to new tables, all
tables referencing peers need to be cloned with a new foreign key
constraint, as well as all tables referencing those, recursively.
2022-03-22 19:43:27 +08:00
|
|
|
{QStringLiteral("Message 2 from A to Self").toUtf8()}});
|
|
|
|
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
2022-04-01 08:34:38 +08:00
|
|
|
"INSERT INTO history (id, message_type, timestamp, chat_id) VALUES (10, 'F', 0, '%1')").arg(aPeerDuplicateId)});
|
refactor(History): Split peers table into chats and authors
peers had combined meaning, both being referenced by history for which
chat a message was in, and being reference by aliases for who authored a
message. This means that peers had conceptually different sub-groups:
all friends are both a chat and an author, but self is an author but not
a chat. With the addition of group chats this is amplified by groups
themselves being chats but not authors, and group members being authors
but not chats. Instead of having four sub-groups all within peers,
splitting peers into chats and authors gives a clean mapping,
simplifying interactions with the data.
In the new chats and authors tables, store what used to be a public_key
string as a BLOB, since it’s inherently a 32-byte binary value in both
cases. Call the public_key a UUID for chats, since group IDs are not
defined as public keys by toxcore.
Even though the data change is quite minor, the upgrade is large because
of SQLite's lack of support for modifying foreign key constrains for
existing tables. This means when peers are moved to new tables, all
tables referencing peers need to be cloned with a new foreign key
constraint, as well as all tables referencing those, recursively.
2022-03-22 19:43:27 +08:00
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO file_transfers (id, message_type, sender_alias, file_restart_id, "
|
|
|
|
"file_name, file_path, file_hash, file_size, direction, file_state) "
|
|
|
|
"VALUES(10, 'F', '%1', ?, 'dummy name', 'dummy/path', ?, 1024, 1, 5)").arg(aAliasId),
|
|
|
|
{QByteArray(32, 1), QByteArray(32, 2)}});
|
|
|
|
}
|
|
|
|
|
|
|
|
void appendVerifyAChatMessagesQueries(QVector<RawDatabase::Query>& verifyQueries)
|
|
|
|
{
|
|
|
|
verifyQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"SELECT COUNT(*) FROM history WHERE chat_id = '%1'").arg(aChatId),
|
|
|
|
[&](const QVector<QVariant>& row) {
|
|
|
|
QVERIFY(row[0].toLongLong() == 3);
|
|
|
|
}});
|
|
|
|
verifyQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"SELECT COUNT(*) FROM text_messages WHERE sender_alias = '%1'").arg(aAliasId),
|
|
|
|
[&](const QVector<QVariant>& row) {
|
|
|
|
QVERIFY(row[0].toLongLong() == 2);
|
|
|
|
}});
|
|
|
|
verifyQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"SELECT COUNT(*) FROM file_transfers WHERE sender_alias = '%1'").arg(aAliasId),
|
|
|
|
[&](const QVector<QVariant>& row) {
|
|
|
|
QVERIFY(row[0].toLongLong() == 1);
|
|
|
|
}});
|
|
|
|
}
|
|
|
|
|
|
|
|
void appendAddBChatMessagesQueries(QVector<RawDatabase::Query>& setupQueries)
|
|
|
|
{
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO history (id, message_type, timestamp, chat_id) VALUES (3, 'T', 0, '%1')").arg(bPeerId)});
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO text_messages (id, message_type, sender_alias, message) VALUES (3, 'T', '%1', ?)").arg(bAliasId),
|
|
|
|
{QStringLiteral("Message 1 from B to Self").toUtf8()}});
|
|
|
|
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO history (id, message_type, timestamp, chat_id) VALUES (4, 'T', 0, '%1')").arg(bPeerId)});
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO text_messages (id, message_type, sender_alias, message) VALUES (4, 'T', '%1', ?)").arg(selfAliasId),
|
|
|
|
{QStringLiteral("Message 1 from Self to B").toUtf8()}});
|
|
|
|
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO history (id, message_type, timestamp, chat_id) VALUES (5, 'T', 0, '%1')").arg(bPeerId)});
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO text_messages (id, message_type, sender_alias, message) VALUES (5, 'T', '%1', ?)").arg(selfAliasId),
|
|
|
|
{QStringLiteral("Pending message 1 from Self to B").toUtf8()}});
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO faux_offline_pending (id) VALUES (5)")});
|
|
|
|
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO history (id, message_type, timestamp, chat_id) VALUES (8, 'S', 0, '%1')").arg(bPeerId)});
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO system_messages (id, message_type, system_message_type) VALUES (8, 'S', 1)")});
|
|
|
|
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO history (id, message_type, timestamp, chat_id) VALUES (9, 'F', 0, '%1')").arg(bPeerId)});
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO file_transfers (id, message_type, sender_alias, file_restart_id, "
|
|
|
|
"file_name, file_path, file_hash, file_size, direction, file_state) "
|
|
|
|
"VALUES(9, 'F', '%1', ?, 'dummy name', 'dummy/path', ?, 1024, 0, 5)").arg(selfAliasId),
|
|
|
|
{QByteArray(32, 1), QByteArray(32, 2)}});
|
|
|
|
}
|
|
|
|
|
|
|
|
void appendVerifyBChatMessagesQueries(QVector<RawDatabase::Query>& verifyQueries)
|
|
|
|
{
|
|
|
|
verifyQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"SELECT COUNT(*) FROM history WHERE chat_id = '%1'").arg(bChatId),
|
|
|
|
[&](const QVector<QVariant>& row) {
|
|
|
|
QVERIFY(row[0].toLongLong() == 5);
|
|
|
|
}});
|
|
|
|
verifyQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"SELECT COUNT(*) FROM history JOIN text_messages ON "
|
|
|
|
"history.id = text_messages.id WHERE chat_id = '%1'").arg(bChatId),
|
|
|
|
[&](const QVector<QVariant>& row) {
|
|
|
|
QVERIFY(row[0].toLongLong() == 3);
|
|
|
|
}});
|
|
|
|
verifyQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"SELECT COUNT(*) FROM history JOIN faux_offline_pending ON "
|
|
|
|
"history.id = faux_offline_pending.id WHERE chat_id = '%1'").arg(bChatId),
|
|
|
|
[&](const QVector<QVariant>& row) {
|
|
|
|
QVERIFY(row[0].toLongLong() == 1);
|
|
|
|
}});
|
|
|
|
verifyQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"SELECT COUNT(*) FROM file_transfers WHERE sender_alias = '%1'").arg(selfAliasId),
|
|
|
|
[&](const QVector<QVariant>& row) {
|
|
|
|
QVERIFY(row[0].toLongLong() == 1);
|
|
|
|
}});
|
|
|
|
verifyQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"SELECT COUNT(*) FROM history JOIN system_messages ON "
|
|
|
|
"history.id = system_messages.id WHERE chat_id = '%1'").arg(bChatId),
|
|
|
|
[&](const QVector<QVariant>& row) {
|
|
|
|
QVERIFY(row[0].toLongLong() == 1);
|
|
|
|
}});
|
|
|
|
}
|
|
|
|
|
|
|
|
void appendAddCChatMessagesQueries(QVector<RawDatabase::Query>& setupQueries)
|
|
|
|
{
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO history (id, message_type, timestamp, chat_id) VALUES (6, 'T', 0, '%1')").arg(cPeerId)});
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO text_messages (id, message_type, sender_alias, message) VALUES (6, 'T', '%1', ?)").arg(selfAliasId),
|
|
|
|
{QStringLiteral("Message 1 from Self to B").toUtf8()}});
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO broken_messages (id) VALUES (6)")});
|
|
|
|
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO history (id, message_type, timestamp, chat_id) VALUES (7, 'T', 0, '%1')").arg(cPeerId)});
|
|
|
|
setupQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"INSERT INTO text_messages (id, message_type, sender_alias, message) VALUES (7, 'T', '%1', ?)").arg(selfAliasId),
|
|
|
|
{QStringLiteral("Message 1 from Self to B").toUtf8()}});
|
|
|
|
}
|
|
|
|
|
|
|
|
void appendVerifyCChatMessagesQueries(QVector<RawDatabase::Query>& verifyQueries)
|
|
|
|
{
|
|
|
|
verifyQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"SELECT COUNT(*) FROM history WHERE chat_id = '%1'").arg(cChatId),
|
|
|
|
[&](const QVector<QVariant>& row) {
|
|
|
|
QVERIFY(row[0].toLongLong() == 2);
|
|
|
|
}});
|
|
|
|
verifyQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"SELECT COUNT(*) FROM history JOIN broken_messages ON "
|
|
|
|
"history.id = broken_messages.id WHERE chat_id = '%1'").arg(cChatId),
|
|
|
|
[&](const QVector<QVariant>& row) {
|
|
|
|
QVERIFY(row[0].toLongLong() == 1);
|
|
|
|
}});
|
|
|
|
verifyQueries.append(RawDatabase::Query{QStringLiteral(
|
|
|
|
"SELECT COUNT(*) FROM history JOIN text_messages ON "
|
|
|
|
"history.id = text_messages.id WHERE chat_id = '%1'").arg(cChatId),
|
|
|
|
[&](const QVector<QVariant>& row) {
|
|
|
|
QVERIFY(row[0].toLongLong() == 2);
|
|
|
|
}});
|
|
|
|
}
|
|
|
|
|
|
|
|
void appendAddHistoryQueries(QVector<RawDatabase::Query>& setupQueries)
|
|
|
|
{
|
|
|
|
appendAddAChatMessagesQueries(setupQueries);
|
|
|
|
appendAddBChatMessagesQueries(setupQueries);
|
|
|
|
appendAddCChatMessagesQueries(setupQueries);
|
|
|
|
}
|
|
|
|
|
|
|
|
void appendVerifyHistoryQueries(QVector<RawDatabase::Query>& verifyQueries)
|
|
|
|
{
|
|
|
|
appendVerifyAChatMessagesQueries(verifyQueries);
|
|
|
|
appendVerifyBChatMessagesQueries(verifyQueries);
|
|
|
|
appendVerifyCChatMessagesQueries(verifyQueries);
|
|
|
|
}
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
class Test10to11 : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
private slots:
|
|
|
|
void test10to11();
|
|
|
|
private:
|
|
|
|
QTemporaryFile testDatabaseFile;
|
|
|
|
};
|
|
|
|
|
|
|
|
void Test10to11::test10to11()
|
|
|
|
{
|
|
|
|
QVERIFY(testDatabaseFile.open());
|
|
|
|
testDatabaseFile.close();
|
|
|
|
auto db = std::shared_ptr<RawDatabase>{new RawDatabase{testDatabaseFile.fileName(), {}, {}}};
|
|
|
|
QVERIFY(db->execNow(RawDatabase::Query{QStringLiteral("PRAGMA foreign_keys = ON;")}));
|
|
|
|
createSchemaAtVersion(db, DbUtility::schema10);
|
|
|
|
QVector<RawDatabase::Query> setupQueries;
|
|
|
|
appendAddPeersQueries(setupQueries);
|
|
|
|
appendAddAliasesQueries(setupQueries);
|
|
|
|
appendAddHistoryQueries(setupQueries);
|
|
|
|
QVERIFY(db->execNow(setupQueries));
|
|
|
|
QVERIFY(DbTo11::dbSchema10to11(*db));
|
|
|
|
verifyDb(db, DbUtility::schema11);
|
|
|
|
QVector<RawDatabase::Query> verifyQueries;
|
|
|
|
appendVerifyChatsQueries(verifyQueries);
|
|
|
|
appendVerifyAuthorsQueries(verifyQueries);
|
|
|
|
appendVerifyAliasesQueries(verifyQueries);
|
|
|
|
appendVerifyHistoryQueries(verifyQueries);
|
|
|
|
QVERIFY(db->execNow(verifyQueries));
|
|
|
|
}
|
|
|
|
|
|
|
|
QTEST_GUILESS_MAIN(Test10to11)
|
|
|
|
#include "dbTo11_test.moc"
|