data/ConflictHistory.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "ConflictHistory.h" | ||
| 2 | |||
| 3 | #include <QLoggingCategory> | ||
| 4 | #include <QSqlError> | ||
| 5 | #include <QSqlQuery> | ||
| 6 | #include <QVariant> | ||
| 7 | |||
| 8 |
4/7✓ Branch 2 → 3 taken 11 times.
✓ Branch 2 → 8 taken 112 times.
✓ Branch 4 → 5 taken 11 times.
✗ Branch 4 → 8 not taken.
✓ Branch 5 → 6 taken 11 times.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 12 not taken.
|
123 | Q_LOGGING_CATEGORY(lcConflictHistory, "mailjd.conflict.history") |
| 9 | |||
| 10 | namespace ConflictHistory { | ||
| 11 | |||
| 12 | namespace { | ||
| 13 | |||
| 14 | const char *kColumns = "id, account, collection, uid, component, title, resolved_at, kept_side, losing_text"; | ||
| 15 | |||
| 16 | 194 | Entry entryOf(const QSqlQuery &q) { | |
| 17 | 194 | Entry entry; | |
| 18 |
2/2✓ Branch 2 → 3 taken 194 times.
✓ Branch 3 → 4 taken 194 times.
|
194 | entry.id = q.value(0).toLongLong(); |
| 19 |
2/2✓ Branch 5 → 6 taken 194 times.
✓ Branch 6 → 7 taken 194 times.
|
194 | entry.account = q.value(1).toString(); |
| 20 |
2/2✓ Branch 10 → 11 taken 194 times.
✓ Branch 11 → 12 taken 194 times.
|
194 | entry.collection = q.value(2).toString(); |
| 21 |
2/2✓ Branch 15 → 16 taken 194 times.
✓ Branch 16 → 17 taken 194 times.
|
194 | entry.uid = q.value(3).toString(); |
| 22 |
2/2✓ Branch 20 → 21 taken 194 times.
✓ Branch 21 → 22 taken 194 times.
|
194 | entry.component = q.value(4).toString(); |
| 23 |
2/2✓ Branch 25 → 26 taken 194 times.
✓ Branch 26 → 27 taken 194 times.
|
194 | entry.title = q.value(5).toString(); |
| 24 |
2/2✓ Branch 30 → 31 taken 194 times.
✓ Branch 31 → 32 taken 194 times.
|
194 | entry.resolvedAt = q.value(6).toLongLong(); |
| 25 |
2/2✓ Branch 33 → 34 taken 194 times.
✓ Branch 34 → 35 taken 194 times.
|
194 | entry.keptSide = q.value(7).toString(); |
| 26 |
2/2✓ Branch 38 → 39 taken 194 times.
✓ Branch 39 → 40 taken 194 times.
|
194 | entry.losingText = q.value(8).toString(); |
| 27 | 194 | return entry; | |
| 28 | ✗ | } | |
| 29 | |||
| 30 | } // namespace | ||
| 31 | |||
| 32 | 426 | QString createStatement() { | |
| 33 | 426 | return QStringLiteral("CREATE TABLE IF NOT EXISTS conflict_history (" | |
| 34 | " id INTEGER PRIMARY KEY AUTOINCREMENT," | ||
| 35 | " account TEXT NOT NULL DEFAULT ''," | ||
| 36 | " collection TEXT NOT NULL DEFAULT ''," | ||
| 37 | " uid TEXT NOT NULL," | ||
| 38 | " component TEXT NOT NULL DEFAULT ''," | ||
| 39 | " title TEXT NOT NULL DEFAULT ''," | ||
| 40 | " resolved_at INTEGER NOT NULL," | ||
| 41 | " kept_side TEXT NOT NULL DEFAULT ''," | ||
| 42 | " losing_text TEXT NOT NULL DEFAULT '')"); | ||
| 43 | } | ||
| 44 | |||
| 45 | 123 | bool add(QSqlDatabase &db, const Entry &entry, qint64 now) { | |
| 46 |
1/1✓ Branch 2 → 3 taken 123 times.
|
123 | QSqlQuery q(db); |
| 47 |
1/1✓ Branch 6 → 7 taken 123 times.
|
123 | q.prepare(QStringLiteral("INSERT INTO conflict_history (account, collection, uid, component, title, resolved_at, " |
| 48 | "kept_side, losing_text) VALUES (?, ?, ?, ?, ?, ?, ?, ?)")); | ||
| 49 | // A null QString binds as SQL NULL; the columns are NOT NULL. | ||
| 50 |
4/4✓ Branch 3 → 4 taken 331 times.
✓ Branch 3 → 7 taken 530 times.
✓ Branch 10 → 11 taken 331 times.
✓ Branch 10 → 12 taken 530 times.
|
1192 | const auto text = [](const QString &value) { return QVariant(value.isNull() ? QStringLiteral("") : value); }; |
| 51 | 1107 | for (const QVariant &value : {text(entry.account), text(entry.collection), text(entry.uid), text(entry.component), | |
| 52 |
9/13✓ Branch 9 → 10 taken 123 times.
✓ Branch 10 → 11 taken 123 times.
✓ Branch 11 → 12 taken 123 times.
✓ Branch 12 → 13 taken 123 times.
✓ Branch 13 → 14 taken 123 times.
✓ Branch 15 → 16 taken 123 times.
✓ Branch 16 → 17 taken 123 times.
✓ Branch 23 → 20 taken 984 times.
✓ Branch 23 → 24 taken 123 times.
✗ Branch 94 → 95 not taken.
✗ Branch 94 → 98 not taken.
✗ Branch 96 → 97 not taken.
✗ Branch 96 → 98 not taken.
|
2214 | text(entry.title), QVariant(now), text(entry.keptSide), text(entry.losingText)}) |
| 53 |
3/5✓ Branch 21 → 22 taken 984 times.
✓ Branch 25 → 26 taken 984 times.
✓ Branch 25 → 29 taken 123 times.
✗ Branch 101 → 102 not taken.
✗ Branch 101 → 105 not taken.
|
2091 | q.addBindValue(value); |
| 54 |
2/3✓ Branch 30 → 31 taken 123 times.
✗ Branch 31 → 32 not taken.
✓ Branch 31 → 48 taken 123 times.
|
123 | if (!q.exec()) { |
| 55 | ✗ | qCWarning(lcConflictHistory) << "insert failed:" << q.lastError().text(); | |
| 56 | ✗ | return false; | |
| 57 | } | ||
| 58 |
1/1✓ Branch 48 → 49 taken 123 times.
|
123 | QSqlQuery prune(db); |
| 59 |
1/1✓ Branch 52 → 53 taken 123 times.
|
123 | prune.prepare(QStringLiteral("DELETE FROM conflict_history WHERE resolved_at < ?")); |
| 60 |
1/1✓ Branch 57 → 58 taken 123 times.
|
123 | prune.addBindValue(now - qint64(kMaxAgeDays) * 86400); |
| 61 |
1/1✓ Branch 59 → 60 taken 123 times.
|
123 | prune.exec(); |
| 62 |
1/1✓ Branch 63 → 64 taken 123 times.
|
123 | prune.prepare(QStringLiteral("DELETE FROM conflict_history WHERE id NOT IN " |
| 63 | "(SELECT id FROM conflict_history ORDER BY resolved_at DESC, id DESC LIMIT ?)")); | ||
| 64 |
1/1✓ Branch 68 → 69 taken 123 times.
|
123 | prune.addBindValue(kLimit); |
| 65 |
1/1✓ Branch 70 → 71 taken 123 times.
|
123 | prune.exec(); |
| 66 |
8/8✓ Branch 71 → 72 taken 123 times.
✓ Branch 75 → 76 taken 123 times.
✓ Branch 76 → 77 taken 123 times.
✓ Branch 77 → 78 taken 123 times.
✓ Branch 78 → 79 taken 123 times.
✓ Branch 79 → 80 taken 123 times.
✓ Branch 83 → 73 taken 123 times.
✓ Branch 83 → 84 taken 123 times.
|
246 | qCInfo(lcConflictHistory) << "kept the replaced version of a" << entry.component << "resolved as" << entry.keptSide; |
| 67 | 123 | return true; | |
| 68 | 123 | } | |
| 69 | |||
| 70 | 1789 | QList<Entry> list(const QSqlDatabase &db, int limit) { | |
| 71 | 1789 | QList<Entry> entries; | |
| 72 |
1/1✓ Branch 2 → 3 taken 1789 times.
|
1789 | QSqlQuery q(db); |
| 73 |
1/1✓ Branch 9 → 10 taken 1789 times.
|
5367 | q.prepare(QStringLiteral("SELECT %1 FROM conflict_history ORDER BY resolved_at DESC, id DESC LIMIT ?") |
| 74 |
1/1✓ Branch 8 → 9 taken 1789 times.
|
5367 | .arg(QLatin1String(kColumns))); |
| 75 |
1/1✓ Branch 15 → 16 taken 1789 times.
|
1789 | q.addBindValue(limit); |
| 76 |
2/3✓ Branch 17 → 18 taken 1789 times.
✗ Branch 18 → 19 not taken.
✓ Branch 18 → 20 taken 1789 times.
|
1789 | if (!q.exec()) |
| 77 | ✗ | return entries; | |
| 78 |
3/3✓ Branch 25 → 26 taken 1978 times.
✓ Branch 26 → 21 taken 189 times.
✓ Branch 26 → 27 taken 1789 times.
|
1978 | while (q.next()) |
| 79 |
2/2✓ Branch 21 → 22 taken 189 times.
✓ Branch 22 → 23 taken 189 times.
|
189 | entries.append(entryOf(q)); |
| 80 | 1789 | return entries; | |
| 81 | 1789 | } | |
| 82 | |||
| 83 | 7 | std::optional<Entry> find(const QSqlDatabase &db, qint64 id) { | |
| 84 |
1/1✓ Branch 2 → 3 taken 7 times.
|
7 | QSqlQuery q(db); |
| 85 |
2/2✓ Branch 8 → 9 taken 7 times.
✓ Branch 9 → 10 taken 7 times.
|
14 | q.prepare(QStringLiteral("SELECT %1 FROM conflict_history WHERE id = ?").arg(QLatin1String(kColumns))); |
| 86 |
1/1✓ Branch 15 → 16 taken 7 times.
|
7 | q.addBindValue(id); |
| 87 |
7/8✓ Branch 17 → 18 taken 7 times.
✓ Branch 18 → 19 taken 7 times.
✗ Branch 18 → 22 not taken.
✓ Branch 19 → 20 taken 7 times.
✓ Branch 20 → 21 taken 5 times.
✓ Branch 20 → 22 taken 2 times.
✓ Branch 23 → 24 taken 5 times.
✓ Branch 23 → 28 taken 2 times.
|
7 | if (q.exec() && q.next()) |
| 88 |
1/1✓ Branch 24 → 25 taken 5 times.
|
5 | return entryOf(q); |
| 89 | 2 | return std::nullopt; | |
| 90 | 7 | } | |
| 91 | |||
| 92 | 5 | bool remove(QSqlDatabase &db, qint64 id) { | |
| 93 |
1/1✓ Branch 2 → 3 taken 5 times.
|
5 | QSqlQuery q(db); |
| 94 |
1/1✓ Branch 6 → 7 taken 5 times.
|
5 | q.prepare(QStringLiteral("DELETE FROM conflict_history WHERE id = ?")); |
| 95 |
1/1✓ Branch 11 → 12 taken 5 times.
|
5 | q.addBindValue(id); |
| 96 |
4/6✓ Branch 13 → 14 taken 5 times.
✓ Branch 14 → 15 taken 5 times.
✗ Branch 14 → 18 not taken.
✓ Branch 15 → 16 taken 5 times.
✓ Branch 16 → 17 taken 5 times.
✗ Branch 16 → 18 not taken.
|
10 | return q.exec() && q.numRowsAffected() > 0; |
| 97 | 5 | } | |
| 98 | |||
| 99 | } // namespace ConflictHistory | ||
| 100 |