GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/history.h
Date: 2024-04-21 02:33:16
Exec Total Coverage
Lines: 21 21 100.0%
Branches: 9 16 56.2%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5 #ifndef CVMFS_HISTORY_H_
6 #define CVMFS_HISTORY_H_
7
8 #include <stdint.h>
9 #include <time.h>
10
11 #include <string>
12 #include <vector>
13
14 #include "crypto/hash.h"
15
16 namespace history {
17
18 /**
19 * This is the abstract base class for repository history. It maintains a list
20 * of named snapshots in a Tag structure.
21 *
22 * Each tag contains meta information (i.e. description, date) and points to
23 * one specific catalog revision (revision, root catalog hash). Furthermore
24 * tags are associated with _one_ branch. This can be used in clients
25 * to selectively apply file system snapshots of a specific branch.
26 *
27 * Note: The public interface of the History class is virtual, in order to over-
28 * write it in a testing environment. As we are dealing with an SQLite
29 * database anyway, the overhead of this should not matter.
30 * It could be implemented using CRTP if necessary, but would require com-
31 * plex code to do so.
32 */
33 class History {
34 public:
35 struct Branch {
36 173 Branch() : initial_revision(0) { }
37 239 Branch(const std::string &b, const std::string &p, uint64_t r)
38
1/2
✓ Branch 2 taken 239 times.
✗ Branch 3 not taken.
239 : branch(b), parent(p), initial_revision(r) { }
39 std::string branch;
40 std::string parent;
41 uint64_t initial_revision;
42
43 22 bool operator ==(const Branch &other) const {
44
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 return (this->branch == other.branch) &&
45
1/2
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
44 (this->parent == other.parent) &&
46
1/2
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
44 (this->initial_revision == other.initial_revision);
47 }
48
49 // Used for sorting in unit tests
50 44 bool operator <(const Branch &other) const {
51 44 return (this->branch < other.branch);
52 }
53 };
54
55 /**
56 * The Tag structure contains information about one specific named snap-
57 * shot stored in the history database. Tags can be retrieved from this
58 * history class both by 'name' and by 'date'. By 'date' branches only look
59 * in the default branch. Naturally, tags can also be saved into the History
60 * using this struct as a container.
61 */
62 struct Tag {
63
1/2
✓ Branch 2 taken 17652 times.
✗ Branch 3 not taken.
17652 Tag() : size(0), revision(0), timestamp(0) {}
64
65 294 Tag(const std::string &n, const shash::Any &h, const uint64_t s,
66 const uint64_t r, const time_t t, const std::string &d,
67 294 const std::string &b) :
68 294 name(n), root_hash(h), size(s), revision(r), timestamp(t),
69
2/4
✓ Branch 1 taken 294 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 294 times.
✗ Branch 5 not taken.
294 description(d), branch(b) {}
70
71 bool operator ==(const Tag &other) const {
72 return (this->branch == other.branch) &&
73 (this->revision == other.revision);
74 }
75
76 35131 bool operator <(const Tag &other) const {
77
2/2
✓ Branch 0 taken 34931 times.
✓ Branch 1 taken 200 times.
35131 if (this->timestamp == other.timestamp)
78 34931 return this->revision < other.revision;
79 200 return this->timestamp < other.timestamp;
80 }
81
82 bool operator >(const Tag &other) const {
83 if (this->timestamp == other.timestamp)
84 return this->revision > other.revision;
85 return this->timestamp > other.timestamp;
86 }
87
88 std::string name;
89 shash::Any root_hash;
90 uint64_t size;
91 uint64_t revision;
92 time_t timestamp;
93 std::string description;
94 /**
95 * The default branch is the empty string.
96 */
97 std::string branch;
98 }; // struct Tag
99
100
101 public:
102 632 virtual ~History() { }
103
104 virtual bool IsWritable() const = 0;
105 virtual unsigned GetNumberOfTags() const = 0;
106
107 /**
108 * Opens a new database transaction in the underlying SQLite database
109 * This can greatly improve performance when used before inserting or
110 * removing multiple tags.
111 */
112 virtual bool BeginTransaction() const = 0;
113
114 /**
115 * Closes a transaction (see BeginTransaction())
116 */
117 virtual bool CommitTransaction() const = 0;
118
119 /**
120 * Sets the internal pointer to the previous revision of this History file.
121 * Note: This must be handled by the user code.
122 *
123 * @param history_hash the content hash of the previous revision
124 */
125 virtual bool SetPreviousRevision(const shash::Any &history_hash) = 0;
126 virtual shash::Any previous_revision() const = 0;
127
128 virtual bool Insert(const Tag &tag) = 0;
129 virtual bool Remove(const std::string &name) = 0;
130 virtual bool Exists(const std::string &name) const = 0;
131 virtual bool GetByName(const std::string &name, Tag *tag) const = 0;
132 virtual bool GetByDate(const time_t timestamp, Tag *tag) const = 0;
133 virtual bool List(std::vector<Tag> *tags) const = 0;
134
135 virtual bool GetBranchHead(const std::string &branch_name, Tag *tag)
136 const = 0;
137 virtual bool ExistsBranch(const std::string &branch_name) const = 0;
138 virtual bool InsertBranch(const Branch &branch) = 0;
139 /**
140 * When removing tags, branches can become abandoned. Remove abandoned
141 * branches and redirect the parent pointer of their child branches.
142 */
143 virtual bool PruneBranches() = 0;
144 virtual bool ListBranches(std::vector<Branch> *branches) const = 0;
145
146 /**
147 * The recycle bin operations are deprecated, only emptying and listing are
148 * preserved for migration and testing.
149 */
150 virtual bool ListRecycleBin(std::vector<shash::Any> *hashes) const = 0;
151 virtual bool EmptyRecycleBin() = 0;
152
153 /**
154 * Rolls back the history to the provided target tag and deletes all tags
155 * in between. Works on the default branch only.
156 *
157 * Note: this assumes that the provided target tag was already updated with
158 * the republished root catalog information.
159 *
160 * @param updated_target_tag the tag to be rolled back to (updated: see Note)
161 * @return true on success
162 */
163 virtual bool Rollback(const Tag &updated_target_tag) = 0;
164
165 /**
166 * Lists the tags that would be deleted by a rollback to the tag specified.
167 *
168 * Note: This doesn't change the database but is mainly used for sanity checks
169 * and user output.
170 *
171 * @param target_tag_name the tag name for the planned rollback
172 * @param tags pointer to the result tag list to be filled
173 * @return true on success
174 */
175 virtual bool ListTagsAffectedByRollback(const std::string &target_tag_name,
176 std::vector<Tag> *tags) const = 0;
177
178 /**
179 * Provides a list of all referenced catalog hashes in this History.
180 * The hashes will be ordered by their timestamp in ascending order.
181 *
182 * @param hashes pointer to the result vector to be filled
183 */
184 virtual bool GetHashes(std::vector<shash::Any> *hashes) const = 0;
185
186 // database file management controls
187 virtual void TakeDatabaseFileOwnership() = 0;
188 virtual void DropDatabaseFileOwnership() = 0;
189 virtual bool OwnsDatabaseFile() const = 0;
190
191 virtual bool Vacuum() = 0;
192
193 228 const std::string& fqrn() const { return fqrn_; }
194
195 protected:
196 316 void set_fqrn(const std::string &fqrn) { fqrn_ = fqrn; }
197
198 private:
199 std::string fqrn_;
200 };
201
202 } // namespace history
203
204 #endif // CVMFS_HISTORY_H_
205