MailJDTourDownloadDocsQualityTestsCoverage

Which source lines and branches the tests execute. Lines 91.5 %, branches 75.0 % (minimum 85 % and 72 %). main @ 399ffe3d · 21 October 2026 · pipeline 7238.

GCC Code Coverage Report


Directory: src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 93.8% 137 / 0 / 146
Functions: 100.0% 9 / 0 / 9
Branches: 63.1% 262 / 0 / 415

data/ContactPeopleStore.cpp
Line Branch Exec Source
1 #include "ContactPeopleStore.h"
2
3 #include "ContactIndex.h"
4 #include "ContactSqlValue.h"
5 #include "RelationVocabulary.h"
6 #include "VCardCodec.h"
7
8 #include <QLoggingCategory>
9 #include <QSqlError>
10 #include <QSqlQuery>
11 #include <QVariant>
12
13
4/7
✓ Branch 2 → 3 taken 9 times.
✓ Branch 2 → 8 taken 40 times.
✓ Branch 4 → 5 taken 9 times.
✗ Branch 4 → 8 not taken.
✓ Branch 5 → 6 taken 9 times.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 12 not taken.
49 Q_LOGGING_CATEGORY(lcContactPeople, "mailjd.contacts.relations")
14
15 namespace ContactPeopleStore {
16
17 namespace {
18
19 const QStringList kSchema{
20 QStringLiteral("CREATE TABLE IF NOT EXISTS card_relations ("
21 " card_id INTEGER NOT NULL REFERENCES cards(id) ON DELETE CASCADE, position INTEGER NOT NULL,"
22 " role TEXT NOT NULL DEFAULT 'relation', type TEXT NOT NULL DEFAULT '', label TEXT NOT NULL DEFAULT '',"
23 " target_uid TEXT NOT NULL DEFAULT '', target_uri TEXT NOT NULL DEFAULT '',"
24 " target_name TEXT NOT NULL DEFAULT '', model TEXT NOT NULL DEFAULT '')"),
25 QStringLiteral("CREATE INDEX IF NOT EXISTS idx_card_relations_card ON card_relations(card_id)"),
26 QStringLiteral("CREATE INDEX IF NOT EXISTS idx_card_relations_uid ON card_relations(target_uid)"),
27 QStringLiteral("CREATE TABLE IF NOT EXISTS card_places ("
28 " card_id INTEGER NOT NULL REFERENCES cards(id) ON DELETE CASCADE, kind TEXT NOT NULL,"
29 " position INTEGER NOT NULL DEFAULT 0, text TEXT NOT NULL DEFAULT '', lat REAL, lon REAL,"
30 " precision TEXT NOT NULL DEFAULT '', source TEXT NOT NULL DEFAULT '', tz TEXT NOT NULL DEFAULT '',"
31 " street TEXT NOT NULL DEFAULT '', postal_code TEXT NOT NULL DEFAULT '',"
32 " locality TEXT NOT NULL DEFAULT '', region TEXT NOT NULL DEFAULT '',"
33 " country TEXT NOT NULL DEFAULT '', place_name TEXT NOT NULL DEFAULT '')"),
34 QStringLiteral("CREATE INDEX IF NOT EXISTS idx_card_places_pending ON card_places(source) WHERE source = ''"),
35 QStringLiteral("CREATE INDEX IF NOT EXISTS idx_card_places_card ON card_places(card_id)"),
36 QStringLiteral("CREATE TABLE IF NOT EXISTS place_cache ("
37 " address_hash TEXT PRIMARY KEY, lat REAL, lon REAL, precision TEXT NOT NULL DEFAULT '',"
38 " source TEXT NOT NULL DEFAULT '', tz TEXT NOT NULL DEFAULT '', looked_up TEXT NOT NULL DEFAULT '',"
39 " place_name TEXT NOT NULL DEFAULT '', country TEXT NOT NULL DEFAULT '')"),
40 QStringLiteral("CREATE TABLE IF NOT EXISTS card_social ("
41 " card_id INTEGER NOT NULL REFERENCES cards(id) ON DELETE CASCADE, kind TEXT NOT NULL DEFAULT '',"
42 " service TEXT NOT NULL DEFAULT '', handle TEXT NOT NULL DEFAULT '')"),
43 QStringLiteral("CREATE INDEX IF NOT EXISTS idx_card_social_card ON card_social(card_id)"),
44 QStringLiteral("CREATE TABLE IF NOT EXISTS card_mail_links ("
45 " card_id INTEGER NOT NULL REFERENCES cards(id) ON DELETE CASCADE, message_id TEXT NOT NULL,"
46 " subject TEXT NOT NULL DEFAULT '', date TEXT NOT NULL DEFAULT '')"),
47 QStringLiteral("CREATE INDEX IF NOT EXISTS idx_card_mail_links_card ON card_mail_links(card_id)"),
48 QStringLiteral("CREATE INDEX IF NOT EXISTS idx_card_mail_links_message ON card_mail_links(message_id)"),
49 QStringLiteral("CREATE TABLE IF NOT EXISTS card_traits ("
50 " card_id INTEGER PRIMARY KEY REFERENCES cards(id) ON DELETE CASCADE,"
51 " gender TEXT NOT NULL DEFAULT '', time_zone TEXT NOT NULL DEFAULT '')"),
52 QStringLiteral("CREATE TABLE IF NOT EXISTS graph_dismissed ("
53 " first_key TEXT NOT NULL, second_key TEXT NOT NULL, dismissed_at TEXT NOT NULL DEFAULT '',"
54 " PRIMARY KEY(first_key, second_key))"),
55 };
56
57 42244 bool exec(QSqlDatabase &db, const QString &sql) {
58
1/1
✓ Branch 2 → 3 taken 42244 times.
42244 QSqlQuery q(db);
59
2/3
✓ Branch 3 → 4 taken 42244 times.
✓ Branch 4 → 5 taken 42244 times.
✗ Branch 4 → 6 not taken.
42244 if (q.exec(sql))
60 42244 return true;
61 ✗ qCWarning(lcContactPeople) << "People schema statement failed:" << q.lastError().text() << sql.left(60);
62 ✗ return false;
63 42244 }
64
65 634 bool insertRelation(QSqlDatabase &db, qint64 cardId, int position, const QString &role, const QString &type,
66 const QString &label, const ContactPersonRef &target, const QString &model) {
67
1/1
✓ Branch 2 → 3 taken 634 times.
634 QSqlQuery q(db);
68
1/1
✓ Branch 6 → 7 taken 634 times.
634 q.prepare(QStringLiteral("INSERT INTO card_relations (card_id, position, role, type, label, target_uid, target_uri,"
69 " target_name, model) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"));
70 6340 for (const QVariant &value : {QVariant(cardId), QVariant(position), QVariant(role), QVariant(type), QVariant(label),
71
2/2
✓ Branch 26 → 21 taken 5706 times.
✓ Branch 26 → 27 taken 634 times.
12680 QVariant(target.uid), QVariant(target.uri), QVariant(target.name), QVariant(model)})
72
4/6
✓ Branch 22 → 23 taken 5706 times.
✓ Branch 23 → 24 taken 5706 times.
✓ Branch 28 → 29 taken 5706 times.
✓ Branch 28 → 32 taken 634 times.
✗ Branch 49 → 50 not taken.
✗ Branch 49 → 53 not taken.
12046 q.addBindValue(sqlValue(value));
73
1/1
✓ Branch 33 → 34 taken 634 times.
1268 return q.exec();
74 634 }
75
76 2355 bool insertPlace(QSqlDatabase &db, qint64 cardId, const QString &kind, int position, const QString &text,
77 const GeoPoint &geo, const QString &source, const ContactAddress &address = {}) {
78
1/1
✓ Branch 2 → 3 taken 2355 times.
2355 QSqlQuery q(db);
79
1/1
✓ Branch 6 → 7 taken 2355 times.
2355 q.prepare(QStringLiteral("INSERT INTO card_places (card_id, kind, position, text, lat, lon, precision, source,"
80 " street, postal_code, locality, region, country) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"));
81
2/2
✓ Branch 11 → 12 taken 2355 times.
✓ Branch 12 → 13 taken 2355 times.
2355 q.addBindValue(sqlValue(cardId));
82
2/2
✓ Branch 17 → 18 taken 2355 times.
✓ Branch 18 → 19 taken 2355 times.
2355 q.addBindValue(sqlValue(kind));
83
2/2
✓ Branch 23 → 24 taken 2355 times.
✓ Branch 24 → 25 taken 2355 times.
2355 q.addBindValue(sqlValue(position));
84
2/2
✓ Branch 29 → 30 taken 2355 times.
✓ Branch 30 → 31 taken 2355 times.
2355 q.addBindValue(sqlValue(text));
85
5/5
✓ Branch 34 → 35 taken 14 times.
✓ Branch 34 → 36 taken 2341 times.
✓ Branch 36 → 37 taken 2341 times.
✓ Branch 37 → 38 taken 2341 times.
✓ Branch 38 → 39 taken 2355 times.
2355 q.addBindValue(geo.valid ? QVariant(geo.latitude) : QVariant(QMetaType(QMetaType::Double)));
86
5/5
✓ Branch 41 → 42 taken 14 times.
✓ Branch 41 → 43 taken 2341 times.
✓ Branch 43 → 44 taken 2341 times.
✓ Branch 44 → 45 taken 2341 times.
✓ Branch 45 → 46 taken 2355 times.
2355 q.addBindValue(geo.valid ? QVariant(geo.longitude) : QVariant(QMetaType(QMetaType::Double)));
87
6/8
✓ Branch 48 → 49 taken 14 times.
✓ Branch 48 → 52 taken 2341 times.
✓ Branch 54 → 55 taken 2355 times.
✓ Branch 55 → 56 taken 2355 times.
✓ Branch 59 → 60 taken 14 times.
✓ Branch 59 → 61 taken 2341 times.
✗ Branch 147 → 148 not taken.
✗ Branch 147 → 149 not taken.
2369 q.addBindValue(sqlValue(geo.valid ? QStringLiteral("exact") : QString()));
88
4/4
✓ Branch 62 → 63 taken 14 times.
✓ Branch 62 → 64 taken 2341 times.
✓ Branch 66 → 67 taken 2355 times.
✓ Branch 67 → 68 taken 2355 times.
2355 q.addBindValue(sqlValue(geo.valid ? source : QString()));
89
2/2
✓ Branch 85 → 78 taken 11775 times.
✓ Branch 85 → 86 taken 2355 times.
25905 for (const QString &part : {address.street, address.postalCode, address.locality, address.region, address.country})
90
4/6
✓ Branch 80 → 81 taken 11775 times.
✓ Branch 81 → 82 taken 11775 times.
✓ Branch 87 → 88 taken 11775 times.
✓ Branch 87 → 91 taken 2355 times.
✗ Branch 173 → 174 not taken.
✗ Branch 173 → 177 not taken.
25905 q.addBindValue(sqlValue(part));
91
1/1
✓ Branch 92 → 93 taken 2355 times.
4710 return q.exec();
92 2355 }
93
94 // home / work / other from the address's TYPE values.
95 2215 QString placeKind(const ContactAddress &address) {
96
2/2
✓ Branch 4 → 5 taken 882 times.
✓ Branch 4 → 10 taken 1333 times.
2215 if (address.types.contains(QLatin1String("work")))
97 882 return QStringLiteral("work");
98
4/6
✓ Branch 12 → 13 taken 12 times.
✓ Branch 12 → 15 taken 1321 times.
✓ Branch 14 → 15 taken 12 times.
✗ Branch 14 → 16 not taken.
✓ Branch 17 → 18 taken 1333 times.
✗ Branch 17 → 23 not taken.
1333 if (address.types.contains(QLatin1String("home")) || address.types.isEmpty())
99 1333 return QStringLiteral("home");
100 ✗ return QStringLiteral("other");
101 }
102
103 30505 bool writePlaces(QSqlDatabase &db, qint64 cardId, const ContactCard &card) {
104 30505 bool ok = true;
105 30505 bool cardGeoUsed = false;
106
2/2
✓ Branch 32 → 3 taken 2215 times.
✓ Branch 32 → 33 taken 30505 times.
32720 for (int i = 0; i < card.addresses.size(); ++i) {
107 2215 const ContactAddress &address = card.addresses.at(i);
108 // Precedence D-10: pinned ADR;GEO, then the card's GEO for its first
109 // address, then (later) cache and gazetteer.
110 2215 GeoPoint geo = address.geo;
111 2215 QString source = QStringLiteral("pinned");
112
3/6
✓ Branch 8 → 9 taken 2201 times.
✓ Branch 8 → 18 taken 14 times.
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 18 taken 2201 times.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 18 not taken.
2215 if (!geo.valid && card.geo.valid && !cardGeoUsed) {
113 ✗ geo = card.geo;
114 ✗ source = QStringLiteral("card");
115 ✗ cardGeoUsed = true;
116 }
117
7/15
✓ Branch 18 → 19 taken 2215 times.
✓ Branch 19 → 20 taken 2215 times.
✓ Branch 20 → 21 taken 2215 times.
✓ Branch 21 → 22 taken 2215 times.
✗ Branch 21 → 24 not taken.
✓ Branch 22 → 23 taken 2215 times.
✗ Branch 22 → 24 not taken.
✓ Branch 25 → 26 taken 2215 times.
✗ Branch 25 → 27 not taken.
✓ Branch 27 → 28 taken 2215 times.
✗ Branch 27 → 29 not taken.
✗ Branch 110 → 111 not taken.
✗ Branch 110 → 112 not taken.
✗ Branch 114 → 115 not taken.
✗ Branch 114 → 116 not taken.
2215 ok = insertPlace(db, cardId, placeKind(address), i, address.oneLine(), geo, source, address) && ok;
118 2215 }
119
1/4
✗ Branch 33 → 34 not taken.
✓ Branch 33 → 60 taken 30505 times.
✗ Branch 34 → 35 not taken.
✗ Branch 34 → 60 not taken.
30505 if (card.geo.valid && !cardGeoUsed)
120 ✗ ok = insertPlace(db, cardId, QStringLiteral("other"), 0, QString(), card.geo, QStringLiteral("card")) && ok;
121
5/6
✓ Branch 61 → 62 taken 30388 times.
✓ Branch 61 → 63 taken 117 times.
✗ Branch 62 → 63 not taken.
✓ Branch 62 → 64 taken 30388 times.
✓ Branch 65 → 66 taken 117 times.
✓ Branch 65 → 88 taken 30388 times.
30505 if (!card.met.place.isEmpty() || card.met.placeGeo.valid)
122
8/25
✓ Branch 72 → 73 taken 117 times.
✓ Branch 73 → 74 taken 117 times.
✗ Branch 73 → 76 not taken.
✓ Branch 74 → 75 taken 117 times.
✗ Branch 74 → 76 not taken.
✓ Branch 77 → 78 taken 117 times.
✗ Branch 77 → 79 not taken.
✓ Branch 79 → 80 taken 117 times.
✗ Branch 79 → 81 not taken.
✓ Branch 81 → 82 taken 117 times.
✗ Branch 81 → 83 not taken.
✓ Branch 83 → 84 taken 117 times.
✗ Branch 83 → 85 not taken.
✓ Branch 85 → 86 taken 117 times.
✗ Branch 85 → 87 not taken.
✗ Branch 145 → 146 not taken.
✗ Branch 145 → 147 not taken.
✗ Branch 149 → 150 not taken.
✗ Branch 149 → 151 not taken.
✗ Branch 153 → 154 not taken.
✗ Branch 153 → 155 not taken.
✗ Branch 157 → 158 not taken.
✗ Branch 157 → 159 not taken.
✗ Branch 161 → 162 not taken.
✗ Branch 161 → 163 not taken.
351 ok = insertPlace(db, cardId, QStringLiteral("met"), 0, card.met.place, card.met.placeGeo, QStringLiteral("pinned")) &&
123 ok;
124
2/2
✓ Branch 89 → 90 taken 23 times.
✓ Branch 89 → 108 taken 30482 times.
30505 if (!card.birthplace.isEmpty())
125
7/21
✓ Branch 94 → 95 taken 23 times.
✓ Branch 95 → 96 taken 23 times.
✗ Branch 95 → 98 not taken.
✓ Branch 96 → 97 taken 23 times.
✗ Branch 96 → 98 not taken.
✓ Branch 99 → 100 taken 23 times.
✗ Branch 99 → 101 not taken.
✓ Branch 101 → 102 taken 23 times.
✗ Branch 101 → 103 not taken.
✓ Branch 103 → 104 taken 23 times.
✗ Branch 103 → 105 not taken.
✓ Branch 105 → 106 taken 23 times.
✗ Branch 105 → 107 not taken.
✗ Branch 165 → 166 not taken.
✗ Branch 165 → 167 not taken.
✗ Branch 169 → 170 not taken.
✗ Branch 169 → 171 not taken.
✗ Branch 174 → 175 not taken.
✗ Branch 174 → 176 not taken.
✗ Branch 178 → 179 not taken.
✗ Branch 178 → 180 not taken.
46 ok = insertPlace(db, cardId, QStringLiteral("birth"), 0, card.birthplace, {}, {}) && ok;
126 30505 return ok;
127 }
128
129 } // namespace
130
131 3017 bool createSchema(QSqlDatabase &db) {
132 3017 bool ok = true;
133 // card_places of the first v6 build (main, 2026-10-06) had no address
134 // components; the table is derived, so its rows are simply rebuilt.
135 {
136
1/1
✓ Branch 2 → 3 taken 3017 times.
3017 QSqlQuery info(db);
137 3017 QStringList columns;
138
2/3
✓ Branch 6 → 7 taken 3017 times.
✓ Branch 9 → 10 taken 3017 times.
✗ Branch 9 → 19 not taken.
3017 if (info.exec(QStringLiteral("PRAGMA table_info(card_places)")))
139
3/3
✓ Branch 17 → 18 taken 41674 times.
✓ Branch 18 → 11 taken 38657 times.
✓ Branch 18 → 19 taken 3017 times.
41674 while (info.next())
140
3/3
✓ Branch 11 → 12 taken 38657 times.
✓ Branch 12 → 13 taken 38657 times.
✓ Branch 13 → 14 taken 38657 times.
38657 columns << info.value(1).toString();
141
1/1
✓ Branch 19 → 20 taken 3017 times.
3017 info.finish();
142
6/6
✓ Branch 21 → 22 taken 2579 times.
✓ Branch 21 → 26 taken 438 times.
✓ Branch 24 → 25 taken 3 times.
✓ Branch 24 → 26 taken 2576 times.
✓ Branch 27 → 28 taken 3 times.
✓ Branch 27 → 63 taken 3014 times.
3017 if (!columns.isEmpty() && !columns.contains(QLatin1String("place_name"))) {
143
1/1
✓ Branch 31 → 32 taken 3 times.
3 ok = exec(db, QStringLiteral("DROP TABLE card_places"));
144
5/13
✓ Branch 37 → 38 taken 3 times.
✓ Branch 38 → 39 taken 3 times.
✗ Branch 38 → 41 not taken.
✓ Branch 39 → 40 taken 3 times.
✗ Branch 39 → 41 not taken.
✓ Branch 42 → 43 taken 3 times.
✗ Branch 42 → 44 not taken.
✓ Branch 44 → 45 taken 3 times.
✗ Branch 44 → 46 not taken.
✗ Branch 103 → 104 not taken.
✗ Branch 103 → 105 not taken.
✗ Branch 107 → 108 not taken.
✗ Branch 107 → 109 not taken.
6 ok = exec(db, QStringLiteral("DROP TABLE IF EXISTS place_cache")) && ok; // a cache, rebuilt on use
145
2/2
✓ Branch 56 → 48 taken 42 times.
✓ Branch 56 → 57 taken 3 times.
45 for (const QString &statement : kSchema)
146
3/5
✓ Branch 49 → 50 taken 42 times.
✓ Branch 50 → 51 taken 42 times.
✗ Branch 50 → 53 not taken.
✓ Branch 51 → 52 taken 42 times.
✗ Branch 51 → 53 not taken.
42 ok = exec(db, statement) && ok;
147
4/5
✓ Branch 57 → 58 taken 3 times.
✗ Branch 57 → 61 not taken.
✓ Branch 58 → 59 taken 3 times.
✓ Branch 59 → 60 taken 2 times.
✓ Branch 59 → 61 taken 1 time.
3 return ok && backfill(db);
148 }
149 3020 }
150
2/2
✓ Branch 82 → 74 taken 42196 times.
✓ Branch 82 → 83 taken 3014 times.
45210 for (const QString &statement : kSchema)
151
3/5
✓ Branch 75 → 76 taken 42196 times.
✓ Branch 76 → 77 taken 42196 times.
✗ Branch 76 → 79 not taken.
✓ Branch 77 → 78 taken 42196 times.
✗ Branch 77 → 79 not taken.
42196 ok = exec(db, statement) && ok;
152 3014 return ok;
153 }
154
155 30505 bool writeRows(QSqlDatabase &db, qint64 cardId, const ContactCard &card) {
156 30505 bool ok = true;
157
2/2
✓ Branch 28 → 4 taken 152525 times.
✓ Branch 28 → 29 taken 30505 times.
183030 for (const char *table : {"card_relations", "card_places", "card_social", "card_mail_links", "card_traits"}) {
158
1/1
✓ Branch 4 → 5 taken 152525 times.
152525 QSqlQuery clear(db);
159
2/2
✓ Branch 10 → 11 taken 152525 times.
✓ Branch 11 → 12 taken 152525 times.
305050 clear.prepare(QStringLiteral("DELETE FROM %1 WHERE card_id = ?").arg(QLatin1String(table)));
160
2/2
✓ Branch 17 → 18 taken 152525 times.
✓ Branch 18 → 19 taken 152525 times.
152525 clear.addBindValue(sqlValue(cardId));
161
3/5
✓ Branch 21 → 22 taken 152525 times.
✓ Branch 22 → 23 taken 152525 times.
✗ Branch 22 → 25 not taken.
✓ Branch 23 → 24 taken 152525 times.
✗ Branch 23 → 25 not taken.
152525 ok = clear.exec() && ok;
162 152525 }
163
2/2
✓ Branch 53 → 31 taken 529 times.
✓ Branch 53 → 54 taken 30505 times.
31034 for (const ContactRelation &relation : card.relations) {
164 529 const ContactPersonRef target{relation.targetUri, relation.targetUid, relation.targetName, -1};
165
2/8
✓ Branch 44 → 45 taken 529 times.
✗ Branch 44 → 46 not taken.
✓ Branch 46 → 47 taken 529 times.
✗ Branch 46 → 48 not taken.
✗ Branch 257 → 258 not taken.
✗ Branch 257 → 259 not taken.
✗ Branch 261 → 262 not taken.
✗ Branch 261 → 263 not taken.
1058 ok = insertRelation(db, cardId, relation.sourceIndex, QStringLiteral("relation"),
166
6/10
✓ Branch 35 → 36 taken 529 times.
✓ Branch 39 → 40 taken 529 times.
✓ Branch 40 → 41 taken 528 times.
✓ Branch 40 → 43 taken 1 time.
✓ Branch 41 → 42 taken 528 times.
✗ Branch 41 → 43 not taken.
✓ Branch 48 → 49 taken 529 times.
✗ Branch 48 → 50 not taken.
✗ Branch 265 → 266 not taken.
✗ Branch 265 → 267 not taken.
1587 RelationVocabulary::canonical(relation.type), relation.label, target, relation.model) &&
167 ok;
168 529 }
169
2/2
✓ Branch 80 → 56 taken 105 times.
✓ Branch 80 → 81 taken 30505 times.
30610 for (const ContactPersonRef &via : card.met.via)
170
8/25
✓ Branch 63 → 64 taken 105 times.
✓ Branch 64 → 65 taken 105 times.
✗ Branch 64 → 67 not taken.
✓ Branch 65 → 66 taken 105 times.
✗ Branch 65 → 67 not taken.
✓ Branch 68 → 69 taken 105 times.
✗ Branch 68 → 70 not taken.
✓ Branch 70 → 71 taken 105 times.
✗ Branch 70 → 72 not taken.
✓ Branch 72 → 73 taken 105 times.
✗ Branch 72 → 74 not taken.
✓ Branch 74 → 75 taken 105 times.
✗ Branch 74 → 76 not taken.
✓ Branch 76 → 77 taken 105 times.
✗ Branch 76 → 78 not taken.
✗ Branch 273 → 274 not taken.
✗ Branch 273 → 275 not taken.
✗ Branch 277 → 278 not taken.
✗ Branch 277 → 279 not taken.
✗ Branch 281 → 282 not taken.
✗ Branch 281 → 283 not taken.
✗ Branch 285 → 286 not taken.
✗ Branch 285 → 287 not taken.
✗ Branch 289 → 290 not taken.
✗ Branch 289 → 291 not taken.
210 ok = insertRelation(db, cardId, via.sourceIndex, QStringLiteral("via"), QString(), QString(), via, QString()) && ok;
171
3/4
✓ Branch 82 → 83 taken 30505 times.
✗ Branch 82 → 85 not taken.
✓ Branch 83 → 84 taken 30504 times.
✓ Branch 83 → 85 taken 1 time.
30505 ok = writePlaces(db, cardId, card) && ok;
172
2/2
✓ Branch 132 → 88 taken 189 times.
✓ Branch 132 → 133 taken 30505 times.
30694 for (const ContactSocial &social : card.social) {
173
1/1
✓ Branch 89 → 90 taken 189 times.
189 QSqlQuery q(db);
174
1/1
✓ Branch 93 → 94 taken 189 times.
189 q.prepare(QStringLiteral("INSERT INTO card_social (card_id, kind, service, handle) VALUES (?, ?, ?, ?)"));
175
2/2
✓ Branch 98 → 99 taken 189 times.
✓ Branch 99 → 100 taken 189 times.
189 q.addBindValue(sqlValue(cardId));
176
2/2
✓ Branch 104 → 105 taken 189 times.
✓ Branch 105 → 106 taken 189 times.
189 q.addBindValue(sqlValue(social.kind));
177
2/2
✓ Branch 110 → 111 taken 189 times.
✓ Branch 111 → 112 taken 189 times.
189 q.addBindValue(sqlValue(social.service));
178
4/4
✓ Branch 116 → 117 taken 114 times.
✓ Branch 116 → 118 taken 75 times.
✓ Branch 120 → 121 taken 189 times.
✓ Branch 121 → 122 taken 189 times.
189 q.addBindValue(sqlValue(social.user.isEmpty() ? social.value : social.user));
179
3/5
✓ Branch 124 → 125 taken 189 times.
✓ Branch 125 → 126 taken 189 times.
✗ Branch 125 → 128 not taken.
✓ Branch 126 → 127 taken 189 times.
✗ Branch 126 → 128 not taken.
189 ok = q.exec() && ok;
180 189 }
181
2/2
✓ Branch 179 → 135 taken 1342 times.
✓ Branch 179 → 180 taken 30505 times.
31847 for (const ContactMailLink &link : card.mailLinks) {
182
1/2
✗ Branch 137 → 138 not taken.
✓ Branch 137 → 139 taken 1342 times.
1342 if (link.messageId.isEmpty())
183 ✗ continue;
184
1/1
✓ Branch 139 → 140 taken 1342 times.
1342 QSqlQuery q(db);
185
1/1
✓ Branch 143 → 144 taken 1342 times.
1342 q.prepare(QStringLiteral("INSERT INTO card_mail_links (card_id, message_id, subject, date) VALUES (?, ?, ?, ?)"));
186
2/2
✓ Branch 148 → 149 taken 1342 times.
✓ Branch 149 → 150 taken 1342 times.
1342 q.addBindValue(sqlValue(cardId));
187
2/2
✓ Branch 154 → 155 taken 1342 times.
✓ Branch 155 → 156 taken 1342 times.
1342 q.addBindValue(sqlValue(link.messageId));
188
2/2
✓ Branch 160 → 161 taken 1342 times.
✓ Branch 161 → 162 taken 1342 times.
1342 q.addBindValue(sqlValue(link.subject));
189
2/2
✓ Branch 166 → 167 taken 1342 times.
✓ Branch 167 → 168 taken 1342 times.
1342 q.addBindValue(sqlValue(link.date));
190
3/5
✓ Branch 170 → 171 taken 1342 times.
✓ Branch 171 → 172 taken 1342 times.
✗ Branch 171 → 174 not taken.
✓ Branch 172 → 173 taken 1342 times.
✗ Branch 172 → 174 not taken.
1342 ok = q.exec() && ok;
191 1342 }
192
5/6
✓ Branch 181 → 182 taken 29967 times.
✓ Branch 181 → 184 taken 538 times.
✗ Branch 183 → 184 not taken.
✓ Branch 183 → 185 taken 29967 times.
✓ Branch 186 → 187 taken 538 times.
✓ Branch 186 → 219 taken 29967 times.
30505 if (!card.gender.isEmpty() || !card.timeZone.isEmpty()) {
193
1/1
✓ Branch 187 → 188 taken 538 times.
538 QSqlQuery q(db);
194
1/1
✓ Branch 191 → 192 taken 538 times.
538 q.prepare(QStringLiteral("INSERT INTO card_traits (card_id, gender, time_zone) VALUES (?, ?, ?)"));
195
2/2
✓ Branch 196 → 197 taken 538 times.
✓ Branch 197 → 198 taken 538 times.
538 q.addBindValue(sqlValue(cardId));
196
2/2
✓ Branch 202 → 203 taken 538 times.
✓ Branch 203 → 204 taken 538 times.
538 q.addBindValue(sqlValue(card.gender));
197
2/2
✓ Branch 208 → 209 taken 538 times.
✓ Branch 209 → 210 taken 538 times.
538 q.addBindValue(sqlValue(card.timeZone));
198
3/5
✓ Branch 212 → 213 taken 538 times.
✓ Branch 213 → 214 taken 538 times.
✗ Branch 213 → 216 not taken.
✓ Branch 214 → 215 taken 538 times.
✗ Branch 214 → 216 not taken.
538 ok = q.exec() && ok;
199 538 }
200
2/2
✓ Branch 219 → 220 taken 1 time.
✓ Branch 219 → 233 taken 30504 times.
30505 if (!ok)
201
7/7
✓ Branch 220 → 221 taken 1 time.
✓ Branch 224 → 225 taken 1 time.
✓ Branch 225 → 226 taken 1 time.
✓ Branch 226 → 227 taken 1 time.
✓ Branch 227 → 228 taken 1 time.
✓ Branch 231 → 222 taken 1 time.
✓ Branch 231 → 232 taken 1 time.
2 qCWarning(lcContactPeople) << "People rows of card" << cardId << "could not be written";
202 30505 return ok;
203 }
204
205 5 bool backfill(QSqlDatabase &db) {
206
1/1
✓ Branch 2 → 3 taken 5 times.
5 QSqlQuery all(db);
207 5 QList<QPair<qint64, QString>> rows;
208
2/3
✓ Branch 6 → 7 taken 5 times.
✓ Branch 9 → 10 taken 5 times.
✗ Branch 9 → 24 not taken.
5 if (all.exec(QStringLiteral("SELECT id, raw FROM cards")))
209
3/3
✓ Branch 22 → 23 taken 12 times.
✓ Branch 23 → 11 taken 7 times.
✓ Branch 23 → 24 taken 5 times.
12 while (all.next())
210
5/5
✓ Branch 11 → 12 taken 7 times.
✓ Branch 12 → 13 taken 7 times.
✓ Branch 13 → 14 taken 7 times.
✓ Branch 14 → 15 taken 7 times.
✓ Branch 16 → 17 taken 7 times.
7 rows.append({all.value(0).toLongLong(), all.value(1).toString()});
211
1/1
✓ Branch 24 → 25 taken 5 times.
5 all.finish();
212 5 bool ok = true;
213 5 int filled = 0;
214
4/4
✓ Branch 25 → 26 taken 5 times.
✓ Branch 26 → 27 taken 5 times.
✓ Branch 73 → 28 taken 7 times.
✓ Branch 73 → 74 taken 5 times.
12 for (const auto &row : rows) {
215
1/1
✓ Branch 29 → 30 taken 7 times.
7 ContactCard card;
216
2/3
✓ Branch 30 → 31 taken 7 times.
✗ Branch 31 → 32 not taken.
✓ Branch 31 → 33 taken 7 times.
7 if (!VCardCodec::parse(row.second, &card))
217 ✗ continue;
218
4/5
✓ Branch 33 → 34 taken 7 times.
✓ Branch 34 → 35 taken 6 times.
✓ Branch 34 → 37 taken 1 time.
✓ Branch 35 → 36 taken 6 times.
✗ Branch 35 → 37 not taken.
7 ok = writeRows(db, row.first, card) && ok;
219 // The search text gains the people words (ContactIndex::searchText).
220
1/1
✓ Branch 38 → 39 taken 7 times.
7 QSqlQuery update(db);
221
1/1
✓ Branch 42 → 43 taken 7 times.
7 update.prepare(QStringLiteral("UPDATE cards SET search_text = ? WHERE id = ?"));
222
3/3
✓ Branch 46 → 47 taken 7 times.
✓ Branch 48 → 49 taken 7 times.
✓ Branch 49 → 50 taken 7 times.
7 update.addBindValue(sqlValue(ContactIndex::searchText(card)));
223
2/2
✓ Branch 55 → 56 taken 7 times.
✓ Branch 56 → 57 taken 7 times.
7 update.addBindValue(sqlValue(row.first));
224
4/5
✓ Branch 59 → 60 taken 7 times.
✓ Branch 60 → 61 taken 7 times.
✗ Branch 60 → 63 not taken.
✓ Branch 61 → 62 taken 6 times.
✓ Branch 61 → 63 taken 1 time.
7 ok = update.exec() && ok;
225 7 ++filled;
226 7 }
227
7/7
✓ Branch 74 → 75 taken 5 times.
✓ Branch 78 → 79 taken 5 times.
✓ Branch 79 → 80 taken 5 times.
✓ Branch 80 → 81 taken 5 times.
✓ Branch 81 → 82 taken 5 times.
✓ Branch 85 → 76 taken 5 times.
✓ Branch 85 → 86 taken 5 times.
10 qCInfo(lcContactPeople) << "Schema v6: people rows derived for" << filled << "cards";
228 5 return ok;
229 5 }
230
231 } // namespace ContactPeopleStore
232