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