GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/** |
||
2 |
* This file is part of the CernVM File System. |
||
3 |
*/ |
||
4 |
|||
5 |
#include "reflog.h" |
||
6 |
|||
7 |
#include <fcntl.h> |
||
8 |
#include <unistd.h> |
||
9 |
|||
10 |
#include <cassert> |
||
11 |
|||
12 |
#include "util/posix.h" |
||
13 |
#include "util/string.h" |
||
14 |
|||
15 |
namespace manifest { |
||
16 |
|||
17 |
9 |
Reflog* Reflog::Open(const std::string &database_path) { |
|
18 |
9 |
Reflog *reflog = new Reflog(); |
|
19 |
✓✗✗✓ ✗✓ |
9 |
if (NULL == reflog || !reflog->OpenDatabase(database_path)) { |
20 |
delete reflog; |
||
21 |
return NULL; |
||
22 |
} |
||
23 |
|||
24 |
LogCvmfs(kLogReflog, kLogDebug, |
||
25 |
"opened Reflog database '%s' for repository '%s'", |
||
26 |
9 |
database_path.c_str(), reflog->fqrn().c_str()); |
|
27 |
|||
28 |
9 |
return reflog; |
|
29 |
} |
||
30 |
|||
31 |
|||
32 |
28 |
Reflog* Reflog::Create(const std::string &database_path, |
|
33 |
const std::string &repo_name) { |
||
34 |
28 |
Reflog *reflog = new Reflog(); |
|
35 |
✓✗✗✓ ✗✓ |
28 |
if (NULL == reflog || !reflog->CreateDatabase(database_path, repo_name)) { |
36 |
delete reflog; |
||
37 |
return NULL; |
||
38 |
} |
||
39 |
|||
40 |
LogCvmfs(kLogReflog, kLogDebug, "created empty reflog database '%s' for " |
||
41 |
"repository '%s'", |
||
42 |
28 |
database_path.c_str(), repo_name.c_str()); |
|
43 |
28 |
return reflog; |
|
44 |
} |
||
45 |
|||
46 |
|||
47 |
4 |
bool Reflog::ReadChecksum(const std::string &path, shash::Any* checksum) { |
|
48 |
4 |
int fd = open(path.c_str(), O_RDONLY); |
|
49 |
✗✓ | 4 |
if (fd < 0) { |
50 |
return false; |
||
51 |
} |
||
52 |
4 |
std::string hex_hash; |
|
53 |
4 |
bool retval = GetLineFd(fd, &hex_hash); |
|
54 |
✗✓ | 4 |
if (retval == 0) { |
55 |
close(fd); |
||
56 |
return false; |
||
57 |
} |
||
58 |
4 |
close(fd); |
|
59 |
✗✓ | 4 |
*checksum = shash::MkFromHexPtr(shash::HexPtr(Trim(hex_hash))); |
60 |
4 |
return true; |
|
61 |
} |
||
62 |
|||
63 |
|||
64 |
4 |
bool Reflog::WriteChecksum(const std::string &path, const shash::Any &value) { |
|
65 |
4 |
int fd = open(path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, kDefaultFileMode); |
|
66 |
✗✓ | 4 |
if (fd < 0) { |
67 |
return false; |
||
68 |
} |
||
69 |
4 |
std::string hex_hash = value.ToString(); |
|
70 |
4 |
bool retval = SafeWrite(fd, hex_hash.data(), hex_hash.length()); |
|
71 |
✗✓ | 4 |
if (retval == 0) { |
72 |
close(fd); |
||
73 |
return false; |
||
74 |
} |
||
75 |
4 |
close(fd); |
|
76 |
4 |
return true; |
|
77 |
} |
||
78 |
|||
79 |
|||
80 |
28 |
bool Reflog::CreateDatabase(const std::string &database_path, |
|
81 |
const std::string &repo_name) { |
||
82 |
✗✓ | 28 |
assert(!database_); |
83 |
28 |
database_ = ReflogDatabase::Create(database_path); |
|
84 |
✓✗✗✓ ✗✓ |
28 |
if (!database_ || !database_->InsertInitialValues(repo_name)) { |
85 |
LogCvmfs(kLogReflog, kLogDebug, |
||
86 |
"failed to initialize empty database '%s'", |
||
87 |
database_path.c_str()); |
||
88 |
return false; |
||
89 |
} |
||
90 |
|||
91 |
28 |
PrepareQueries(); |
|
92 |
28 |
return true; |
|
93 |
} |
||
94 |
|||
95 |
|||
96 |
9 |
bool Reflog::OpenDatabase(const std::string &database_path) { |
|
97 |
✗✓ | 9 |
assert(!database_); |
98 |
|||
99 |
9 |
ReflogDatabase::OpenMode mode = ReflogDatabase::kOpenReadWrite; |
|
100 |
9 |
database_ = ReflogDatabase::Open(database_path, mode); |
|
101 |
✗✓ | 9 |
if (!database_.IsValid()) { |
102 |
return false; |
||
103 |
} |
||
104 |
|||
105 |
9 |
PrepareQueries(); |
|
106 |
9 |
return true; |
|
107 |
} |
||
108 |
|||
109 |
|||
110 |
37 |
void Reflog::PrepareQueries() { |
|
111 |
✗✓ | 37 |
assert(database_); |
112 |
37 |
insert_reference_ = new SqlInsertReference(database_.weak_ref()); |
|
113 |
37 |
count_references_ = new SqlCountReferences(database_.weak_ref()); |
|
114 |
37 |
list_references_ = new SqlListReferences(database_.weak_ref()); |
|
115 |
37 |
remove_reference_ = new SqlRemoveReference(database_.weak_ref()); |
|
116 |
37 |
contains_reference_ = new SqlContainsReference(database_.weak_ref()); |
|
117 |
37 |
get_timestamp_ = new SqlGetTimestamp(database_.weak_ref()); |
|
118 |
37 |
} |
|
119 |
|||
120 |
|||
121 |
7 |
bool Reflog::AddCertificate(const shash::Any &certificate) { |
|
122 |
assert(certificate.HasSuffix() && |
||
123 |
✓✗✗✓ |
7 |
certificate.suffix == shash::kSuffixCertificate); |
124 |
7 |
return AddReference(certificate, SqlReflog::kRefCertificate); |
|
125 |
} |
||
126 |
|||
127 |
|||
128 |
10 |
bool Reflog::AddCatalog(const shash::Any &catalog) { |
|
129 |
✓✗✗✓ |
10 |
assert(catalog.HasSuffix() && catalog.suffix == shash::kSuffixCatalog); |
130 |
10 |
return AddReference(catalog, SqlReflog::kRefCatalog); |
|
131 |
} |
||
132 |
|||
133 |
|||
134 |
4 |
bool Reflog::AddHistory(const shash::Any &history) { |
|
135 |
✓✗✗✓ |
4 |
assert(history.HasSuffix() && history.suffix == shash::kSuffixHistory); |
136 |
4 |
return AddReference(history, SqlReflog::kRefHistory); |
|
137 |
} |
||
138 |
|||
139 |
|||
140 |
7 |
bool Reflog::AddMetainfo(const shash::Any &metainfo) { |
|
141 |
✓✗✗✓ |
7 |
assert(metainfo.HasSuffix() && metainfo.suffix == shash::kSuffixMetainfo); |
142 |
7 |
return AddReference(metainfo, SqlReflog::kRefMetainfo); |
|
143 |
} |
||
144 |
|||
145 |
|||
146 |
8 |
uint64_t Reflog::CountEntries() { |
|
147 |
✗✓ | 8 |
assert(database_); |
148 |
8 |
const bool success_exec = count_references_->Execute(); |
|
149 |
✗✓ | 8 |
assert(success_exec); |
150 |
8 |
const uint64_t count = count_references_->RetrieveCount(); |
|
151 |
8 |
const bool success_reset = count_references_->Reset(); |
|
152 |
✗✓ | 8 |
assert(success_reset); |
153 |
8 |
return count; |
|
154 |
} |
||
155 |
|||
156 |
|||
157 |
4 |
bool Reflog::List( |
|
158 |
SqlReflog::ReferenceType type, |
||
159 |
std::vector<shash::Any> *hashes) const |
||
160 |
{ |
||
161 |
4 |
return ListOlderThan(type, static_cast<uint64_t>(-1), hashes); |
|
162 |
} |
||
163 |
|||
164 |
|||
165 |
7 |
bool Reflog::ListOlderThan( |
|
166 |
SqlReflog::ReferenceType type, |
||
167 |
uint64_t timestamp, |
||
168 |
std::vector<shash::Any> *hashes) const |
||
169 |
{ |
||
170 |
✗✓ | 7 |
assert(database_); |
171 |
✗✓ | 7 |
assert(NULL != hashes); |
172 |
|||
173 |
7 |
hashes->clear(); |
|
174 |
|||
175 |
7 |
bool success_bind = list_references_->BindType(type); |
|
176 |
✗✓ | 7 |
assert(success_bind); |
177 |
7 |
success_bind = list_references_->BindOlderThan(timestamp); |
|
178 |
✗✓ | 7 |
assert(success_bind); |
179 |
✓✓ | 27 |
while (list_references_->FetchRow()) { |
180 |
13 |
hashes->push_back(list_references_->RetrieveHash()); |
|
181 |
} |
||
182 |
|||
183 |
7 |
return list_references_->Reset(); |
|
184 |
} |
||
185 |
|||
186 |
|||
187 |
4 |
bool Reflog::Remove(const shash::Any &hash) { |
|
188 |
✗✓ | 4 |
assert(database_); |
189 |
|||
190 |
SqlReflog::ReferenceType type; |
||
191 |
✓✓✓✓ ✗ |
4 |
switch (hash.suffix) { |
192 |
case shash::kSuffixCatalog: |
||
193 |
1 |
type = SqlReflog::kRefCatalog; |
|
194 |
1 |
break; |
|
195 |
case shash::kSuffixHistory: |
||
196 |
1 |
type = SqlReflog::kRefHistory; |
|
197 |
1 |
break; |
|
198 |
case shash::kSuffixCertificate: |
||
199 |
1 |
type = SqlReflog::kRefCertificate; |
|
200 |
1 |
break; |
|
201 |
case shash::kSuffixMetainfo: |
||
202 |
1 |
type = SqlReflog::kRefMetainfo; |
|
203 |
1 |
break; |
|
204 |
default: |
||
205 |
return false; |
||
206 |
} |
||
207 |
|||
208 |
return |
||
209 |
remove_reference_->BindReference(hash, type) && |
||
210 |
remove_reference_->Execute() && |
||
211 |
✓✗✓✗ ✓✗ |
4 |
remove_reference_->Reset(); |
212 |
} |
||
213 |
|||
214 |
|||
215 |
4 |
bool Reflog::ContainsCertificate(const shash::Any &certificate) const { |
|
216 |
assert(certificate.HasSuffix() && |
||
217 |
✓✗✗✓ |
4 |
certificate.suffix == shash::kSuffixCertificate); |
218 |
4 |
return ContainsReference(certificate, SqlReflog::kRefCertificate); |
|
219 |
} |
||
220 |
|||
221 |
|||
222 |
4 |
bool Reflog::ContainsCatalog(const shash::Any &catalog) const { |
|
223 |
✓✗✗✓ |
4 |
assert(catalog.HasSuffix() && catalog.suffix == shash::kSuffixCatalog); |
224 |
4 |
return ContainsReference(catalog, SqlReflog::kRefCatalog); |
|
225 |
} |
||
226 |
|||
227 |
|||
228 |
2 |
bool Reflog::GetCatalogTimestamp( |
|
229 |
const shash::Any &catalog, |
||
230 |
uint64_t *timestamp) const |
||
231 |
{ |
||
232 |
✓✗✗✓ |
2 |
assert(catalog.HasSuffix() && catalog.suffix == shash::kSuffixCatalog); |
233 |
bool result = GetReferenceTimestamp(catalog, SqlReflog::kRefCatalog, |
||
234 |
2 |
timestamp); |
|
235 |
2 |
return result; |
|
236 |
} |
||
237 |
|||
238 |
|||
239 |
4 |
bool Reflog::ContainsHistory(const shash::Any &history) const { |
|
240 |
✓✗✗✓ |
4 |
assert(history.HasSuffix() && history.suffix == shash::kSuffixHistory); |
241 |
4 |
return ContainsReference(history, SqlReflog::kRefHistory); |
|
242 |
} |
||
243 |
|||
244 |
|||
245 |
4 |
bool Reflog::ContainsMetainfo(const shash::Any &metainfo) const { |
|
246 |
✓✗✗✓ |
4 |
assert(metainfo.HasSuffix() && metainfo.suffix == shash::kSuffixMetainfo); |
247 |
4 |
return ContainsReference(metainfo, SqlReflog::kRefMetainfo); |
|
248 |
} |
||
249 |
|||
250 |
|||
251 |
28 |
bool Reflog::AddReference(const shash::Any &hash, |
|
252 |
const SqlReflog::ReferenceType type) { |
||
253 |
return |
||
254 |
insert_reference_->BindReference(hash, type) && |
||
255 |
insert_reference_->Execute() && |
||
256 |
✓✗✓✗ ✓✗ |
28 |
insert_reference_->Reset(); |
257 |
} |
||
258 |
|||
259 |
|||
260 |
16 |
bool Reflog::ContainsReference(const shash::Any &hash, |
|
261 |
const SqlReflog::ReferenceType type) const { |
||
262 |
const bool fetching = |
||
263 |
contains_reference_->BindReference(hash, type) && |
||
264 |
✓✗✓✗ |
16 |
contains_reference_->FetchRow(); |
265 |
✗✓ | 16 |
assert(fetching); |
266 |
|||
267 |
16 |
const bool answer = contains_reference_->RetrieveAnswer(); |
|
268 |
16 |
const bool reset = contains_reference_->Reset(); |
|
269 |
✗✓ | 16 |
assert(reset); |
270 |
|||
271 |
16 |
return answer; |
|
272 |
} |
||
273 |
|||
274 |
|||
275 |
2 |
bool Reflog::GetReferenceTimestamp( |
|
276 |
const shash::Any &hash, |
||
277 |
const SqlReflog::ReferenceType type, |
||
278 |
uint64_t *timestamp) const |
||
279 |
{ |
||
280 |
bool retval = |
||
281 |
get_timestamp_->BindReference(hash, type) && |
||
282 |
✓✗✓✓ |
2 |
get_timestamp_->FetchRow(); |
283 |
|||
284 |
✓✓ | 2 |
if (retval) { |
285 |
1 |
*timestamp = get_timestamp_->RetrieveTimestamp(); |
|
286 |
} |
||
287 |
|||
288 |
2 |
const bool reset = get_timestamp_->Reset(); |
|
289 |
✗✓ | 2 |
assert(reset); |
290 |
|||
291 |
2 |
return retval; |
|
292 |
} |
||
293 |
|||
294 |
|||
295 |
void Reflog::BeginTransaction() { |
||
296 |
assert(database_); |
||
297 |
database_->BeginTransaction(); |
||
298 |
} |
||
299 |
|||
300 |
|||
301 |
void Reflog::CommitTransaction() { |
||
302 |
assert(database_); |
||
303 |
database_->CommitTransaction(); |
||
304 |
} |
||
305 |
|||
306 |
|||
307 |
4 |
void Reflog::TakeDatabaseFileOwnership() { |
|
308 |
✗✓ | 4 |
assert(database_); |
309 |
4 |
database_->TakeFileOwnership(); |
|
310 |
4 |
} |
|
311 |
|||
312 |
|||
313 |
void Reflog::DropDatabaseFileOwnership() { |
||
314 |
assert(database_); |
||
315 |
database_->DropFileOwnership(); |
||
316 |
} |
||
317 |
|||
318 |
|||
319 |
/** |
||
320 |
* Use only once the database was closed. |
||
321 |
*/ |
||
322 |
26 |
void Reflog::HashDatabase( |
|
323 |
const std::string &database_path, |
||
324 |
shash::Any *hash_reflog) |
||
325 |
{ |
||
326 |
26 |
bool retval = HashFile(database_path, hash_reflog); |
|
327 |
✗✓ | 26 |
assert(retval); |
328 |
26 |
} |
|
329 |
|||
330 |
|||
331 |
20 |
std::string Reflog::fqrn() const { |
|
332 |
✗✓ | 20 |
assert(database_); |
333 |
20 |
return database_->GetProperty<std::string>(ReflogDatabase::kFqrnKey); |
|
334 |
} |
||
335 |
|||
336 |
|||
337 |
std::string Reflog::database_file() const { |
||
338 |
assert(database_); |
||
339 |
return database_->filename(); |
||
340 |
} |
||
341 |
|||
342 |
✓✗✓✗ |
45 |
} // namespace manifest |
Generated by: GCOVR (Version 4.1) |