GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/reflog_sql.cc
Date: 2026-07-19 02:35:15
Exec Total Coverage
Lines: 72 74 97.3%
Branches: 66 142 46.5%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5 #include "reflog_sql.h"
6
7 #include <cassert>
8 #include <limits>
9
10 #include "util/string.h"
11
12 const float ReflogDatabase::kLatestSchema = 1.0;
13 const float ReflogDatabase::kLatestSupportedSchema = 1.0;
14 const unsigned ReflogDatabase::kLatestSchemaRevision = 0;
15
16 /**
17 * Database Schema ChangeLog:
18 *
19 * Schema Version 1.0
20 * -> Revision 0: initial revision
21 */
22
23
24 const std::string ReflogDatabase::kFqrnKey = "fqrn";
25
26 318 bool ReflogDatabase::CreateEmptyDatabase() {
27
3/6
✓ Branch 2 taken 318 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 318 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 318 times.
✗ Branch 9 not taken.
636 return sqlite::Sql(sqlite_db(),
28 "CREATE TABLE refs (hash TEXT, type INTEGER, "
29 "timestamp INTEGER, "
30 "CONSTRAINT pk_refs PRIMARY KEY (hash));")
31
1/2
✓ Branch 1 taken 318 times.
✗ Branch 2 not taken.
636 .Execute();
32 }
33
34
35 84 bool ReflogDatabase::CheckSchemaCompatibility() {
36
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 84 times.
84 assert(IsEqualSchema(schema_version(), kLatestSupportedSchema));
37 84 return true; // only one schema version at the moment
38 }
39
40
41 84 bool ReflogDatabase::LiveSchemaUpgradeIfNecessary() {
42
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 84 times.
84 assert(schema_revision() == kLatestSchemaRevision);
43 84 return true; // only one schema revision at the moment, i.e. no migration...
44 }
45
46
47 318 bool ReflogDatabase::InsertInitialValues(const std::string &repo_name) {
48
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 318 times.
318 assert(read_write());
49
1/2
✓ Branch 2 taken 318 times.
✗ Branch 3 not taken.
318 return this->SetProperty(kFqrnKey, repo_name);
50 }
51
52
53 //------------------------------------------------------------------------------
54
55 #define DB_FIELDS_V1R0 "hash, type, timestamp"
56 #define DB_PLACEHOLDERS ":hash, :type, :timestamp"
57
58 #define MAKE_STATEMENT(STMT_TMPL, REV) \
59 static const std::string REV = ReplaceAll( \
60 ReplaceAll(STMT_TMPL, "@DB_FIELDS@", DB_FIELDS_##REV), \
61 "@DB_PLACEHOLDERS@", DB_PLACEHOLDERS)
62
63 #define MAKE_STATEMENTS(STMT_TMPL) MAKE_STATEMENT(STMT_TMPL, V1R0)
64
65 #define DEFERRED_INIT(DB, REV) DeferredInit((DB)->sqlite_db(), (REV).c_str())
66
67 #define DEFERRED_INITS(DB) DEFERRED_INIT((DB), V1R0)
68
69
70 2102 shash::Suffix SqlReflog::ToSuffix(const ReferenceType type) {
71
4/5
✓ Branch 0 taken 1994 times.
✓ Branch 1 taken 38 times.
✓ Branch 2 taken 26 times.
✓ Branch 3 taken 44 times.
✗ Branch 4 not taken.
2102 switch (type) {
72 1994 case kRefCatalog:
73 1994 return shash::kSuffixCatalog;
74 38 case kRefCertificate:
75 38 return shash::kSuffixCertificate;
76 26 case kRefHistory:
77 26 return shash::kSuffixHistory;
78 44 case kRefMetainfo:
79 44 return shash::kSuffixMetainfo;
80 default:
81 assert(false && "unknown reference type");
82 }
83 }
84
85
86 //------------------------------------------------------------------------------
87
88
89 402 SqlInsertReference::SqlInsertReference(const ReflogDatabase *database) {
90
10/20
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 382 times.
✓ Branch 3 taken 20 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 20 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 20 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 20 times.
✗ Branch 16 not taken.
✓ Branch 19 taken 20 times.
✗ Branch 20 not taken.
✓ Branch 23 taken 20 times.
✗ Branch 24 not taken.
✓ Branch 26 taken 20 times.
✗ Branch 27 not taken.
✓ Branch 29 taken 20 times.
✗ Branch 30 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
402 MAKE_STATEMENTS("INSERT OR REPLACE INTO refs (@DB_FIELDS@) "
91 "VALUES (@DB_PLACEHOLDERS@);");
92
2/4
✓ Branch 2 taken 402 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 402 times.
✗ Branch 6 not taken.
402 DEFERRED_INITS(database);
93 402 }
94
95 168 bool SqlInsertReference::BindReference(const shash::Any &reference_hash,
96 const ReferenceType type) {
97
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
168 return BindTextTransient(1, reference_hash.ToString())
98
2/4
✓ Branch 1 taken 168 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 168 times.
✗ Branch 4 not taken.
168 && BindInt64(2, static_cast<uint64_t>(type))
99
6/15
✓ Branch 1 taken 168 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 168 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 168 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 168 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 168 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 168 times.
✗ Branch 15 not taken.
504 && BindInt64(3, static_cast<uint64_t>(time(NULL)));
100 }
101
102
103 //------------------------------------------------------------------------------
104
105
106 402 SqlCountReferences::SqlCountReferences(const ReflogDatabase *database) {
107
2/4
✓ Branch 1 taken 402 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 402 times.
✗ Branch 5 not taken.
402 DeferredInit(database->sqlite_db(), "SELECT count(*) as count FROM refs;");
108 402 }
109
110 48 uint64_t SqlCountReferences::RetrieveCount() {
111 48 return static_cast<uint64_t>(RetrieveInt64(0));
112 }
113
114
115 //------------------------------------------------------------------------------
116
117
118 402 SqlListReferences::SqlListReferences(const ReflogDatabase *database) {
119
2/4
✓ Branch 1 taken 402 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 402 times.
✗ Branch 5 not taken.
402 DeferredInit(database->sqlite_db(), "SELECT hash, type FROM refs "
120 "WHERE type = :type AND "
121 "timestamp < :timestamp "
122 "ORDER BY timestamp DESC;");
123 402 }
124
125 42 bool SqlListReferences::BindType(const ReferenceType type) {
126 42 return BindInt64(1, static_cast<uint64_t>(type));
127 }
128
129 42 bool SqlListReferences::BindOlderThan(const uint64_t timestamp) {
130 42 int64_t sqlite_timestamp = static_cast<uint64_t>(timestamp);
131
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 12 times.
42 if (sqlite_timestamp < 0) {
132 30 sqlite_timestamp = std::numeric_limits<int64_t>::max();
133 }
134 42 return BindInt64(2, sqlite_timestamp);
135 }
136
137 78 shash::Any SqlListReferences::RetrieveHash() const {
138 78 const ReferenceType type = static_cast<ReferenceType>(RetrieveInt64(1));
139 78 const shash::Suffix suffix = ToSuffix(type);
140
1/2
✓ Branch 3 taken 78 times.
✗ Branch 4 not taken.
78 return shash::MkFromHexPtr(shash::HexPtr(RetrieveString(0)), suffix);
141 }
142
143
144 //------------------------------------------------------------------------------
145
146
147 402 SqlRemoveReference::SqlRemoveReference(const ReflogDatabase *database) {
148
2/4
✓ Branch 1 taken 402 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 402 times.
✗ Branch 5 not taken.
402 DeferredInit(database->sqlite_db(), "DELETE FROM refs WHERE hash = :hash "
149 "AND type = :type;");
150 402 }
151
152 24 bool SqlRemoveReference::BindReference(const shash::Any &reference_hash,
153 const ReferenceType type) {
154
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
24 return BindTextTransient(1, reference_hash.ToString())
155
6/14
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 24 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 24 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 24 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 24 times.
✗ Branch 14 not taken.
48 && BindInt64(2, static_cast<uint64_t>(type));
156 }
157
158
159 //------------------------------------------------------------------------------
160
161
162 402 SqlContainsReference::SqlContainsReference(const ReflogDatabase *database) {
163
2/4
✓ Branch 1 taken 402 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 402 times.
✗ Branch 5 not taken.
402 DeferredInit(database->sqlite_db(), "SELECT count(*) as answer FROM refs "
164 "WHERE type = :type "
165 " AND hash = :hash");
166 402 }
167
168 96 bool SqlContainsReference::BindReference(const shash::Any &reference_hash,
169 const ReferenceType type) {
170 192 return BindInt64(1, static_cast<uint64_t>(type))
171
6/16
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 96 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 96 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 96 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 96 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 96 times.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
96 && BindTextTransient(2, reference_hash.ToString());
172 }
173
174 96 bool SqlContainsReference::RetrieveAnswer() {
175 96 const int64_t count = RetrieveInt64(0);
176
3/4
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 48 times.
96 assert(count == 0 || count == 1);
177 96 return count > 0;
178 }
179
180
181 //------------------------------------------------------------------------------
182
183
184 402 SqlGetTimestamp::SqlGetTimestamp(const ReflogDatabase *database) {
185
2/4
✓ Branch 1 taken 402 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 402 times.
✗ Branch 5 not taken.
402 DeferredInit(database->sqlite_db(), "SELECT timestamp FROM refs "
186 "WHERE type = :type "
187 " AND hash = :hash");
188 402 }
189
190 12 bool SqlGetTimestamp::BindReference(const shash::Any &reference_hash,
191 const ReferenceType type) {
192 24 return BindInt64(1, static_cast<uint64_t>(type))
193
6/16
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 12 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 12 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 12 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 12 times.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
12 && BindTextTransient(2, reference_hash.ToString());
194 }
195
196 6 uint64_t SqlGetTimestamp::RetrieveTimestamp() { return RetrieveInt64(0); }
197