GCC Code Coverage Report
Directory: cvmfs/ Exec Total Coverage
File: cvmfs/history.h Lines: 21 28 75.0 %
Date: 2019-02-03 02:48:13 Branches: 8 22 36.4 %

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 "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_ update channel. This can be used in clients
25
 * to selectively apply file system snapshots of a specific update channel.
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
360
class History {
34
 public:
35
  /**
36
   * Available update channels
37
   *   o Trunk (the default)
38
   *   o Development
39
   *   o Testing
40
   *   o Production
41
   */
42
  enum UpdateChannel {
43
    kChannelTrunk = 0,
44
    kChannelDevel = 4,
45
    kChannelTest = 16,
46
    kChannelProd = 64,
47
  };
48
49
1815
  struct Branch {
50
208
    Branch() : initial_revision(0) { }
51
274
    Branch(const std::string &b, const std::string &p, unsigned r)
52
274
      : branch(b), parent(p), initial_revision(r) { }
53
    std::string branch;
54
    std::string parent;
55
    unsigned initial_revision;
56
57
22
    bool operator ==(const Branch &other) const {
58
      return (this->branch == other.branch) &&
59
             (this->parent == other.parent) &&
60

22
             (this->initial_revision == other.initial_revision);
61
    }
62
63
    // Used for sorting in unit tests
64
44
    bool operator <(const Branch &other) const {
65
44
      return (this->branch < other.branch);
66
    }
67
  };
68
69
  /**
70
   * The Tag structure contains information about one specific named snap-
71
   * shot stored in the history database. Tags can be retrieved from this
72
   * history class both by 'name' and by 'date'. By 'date' branches only look
73
   * in the default branch.  Naturally, tags can also be saved into the History
74
   * using this struct as a container.
75
   */
76

131421
  struct Tag {
77
14570
    Tag() :
78
14570
      size(0), revision(0), timestamp(0), channel(kChannelTrunk) {}
79
80
438
    Tag(const std::string &n, const shash::Any &h, const uint64_t s,
81
        const unsigned r, const time_t t, const UpdateChannel c,
82
        const std::string &d, const std::string &b) :
83
      name(n), root_hash(h), size(s), revision(r), timestamp(t), channel(c),
84
438
      description(d), branch(b) {}
85
86
    inline const char* GetChannelName() const {
87
      switch (channel) {
88
        case kChannelTrunk: return "trunk";
89
        case kChannelDevel: return "development";
90
        case kChannelTest:  return "testing";
91
        case kChannelProd:  return "production";
92
        default: assert(false && "unknown channel id");
93
      }
94
    }
95
96
    bool operator ==(const Tag &other) const {
97
      return (this->branch == other.branch) &&
98
             (this->revision == other.revision);
99
    }
100
101
33247
    bool operator <(const Tag &other) const {
102
33247
      if (this->timestamp == other.timestamp)
103
33070
        return this->revision < other.revision;
104
177
      return this->timestamp < other.timestamp;
105
    }
106
107
    bool operator >(const Tag &other) const {
108
      if (this->timestamp == other.timestamp)
109
        return this->revision > other.revision;
110
      return this->timestamp > other.timestamp;
111
    }
112
113
    std::string    name;
114
    shash::Any     root_hash;
115
    uint64_t       size;
116
    unsigned       revision;
117
    time_t         timestamp;
118
    UpdateChannel  channel;
119
    std::string    description;
120
    /**
121
     * The default branch is the empty string.
122
     */
123
    std::string    branch;
124
  };  // struct Tag
125
126
127
 public:
128
360
  virtual ~History() { }
129
130
  virtual bool IsWritable() const     = 0;
131
  virtual unsigned GetNumberOfTags() const = 0;
132
133
  /**
134
   * Opens a new database transaction in the underlying SQLite database
135
   * This can greatly improve performance when used before inserting or
136
   * removing multiple tags.
137
   */
138
  virtual bool BeginTransaction()  const = 0;
139
140
  /**
141
   * Closes a transaction (see BeginTransaction())
142
   */
143
  virtual bool CommitTransaction() const = 0;
144
145
  /**
146
   * Sets the internal pointer to the previous revision of this History file.
147
   * Note: This must be handled by the user code.
148
   *
149
   * @param history_hash  the content hash of the previous revision
150
   */
151
  virtual bool SetPreviousRevision(const shash::Any &history_hash)   = 0;
152
  virtual shash::Any previous_revision() const                       = 0;
153
154
  virtual bool Insert(const Tag &tag)                                = 0;
155
  virtual bool Remove(const std::string &name)                       = 0;
156
  virtual bool Exists(const std::string &name) const                 = 0;
157
  virtual bool GetByName(const std::string &name, Tag *tag) const    = 0;
158
  virtual bool GetByDate(const time_t timestamp, Tag *tag) const     = 0;
159
  virtual bool List(std::vector<Tag> *tags) const                    = 0;
160
  virtual bool Tips(std::vector<Tag> *channel_tips) const            = 0;
161
162
  virtual bool GetBranchHead(const std::string &branch_name, Tag *tag)
163
    const = 0;
164
  virtual bool ExistsBranch(const std::string &branch_name) const = 0;
165
  virtual bool InsertBranch(const Branch &branch) = 0;
166
  /**
167
   * When removing tags, branches can become abandonded. Remove abandoned
168
   * branches and redirect the parent pointer of their child branches.
169
   */
170
  virtual bool PruneBranches() = 0;
171
  virtual bool ListBranches(std::vector<Branch> *branches) const = 0;
172
173
  /**
174
   * The recycle bin operations are deprecated, only emptying and listing are
175
   * preserved for migration and testing.
176
   */
177
  virtual bool ListRecycleBin(std::vector<shash::Any> *hashes) const = 0;
178
  virtual bool EmptyRecycleBin()                                     = 0;
179
180
  /**
181
   * Rolls back the history to the provided target tag and deletes all tags
182
   * of the containing channel in between.  Works on the default branch only.
183
   *
184
   * Note: this assumes that the provided target tag was already updated with
185
   *       the republished root catalog information.
186
   *
187
   * @param updated_target_tag  the tag to be rolled back to (updated: see Note)
188
   * @return                    true on success
189
   */
190
  virtual bool Rollback(const Tag &updated_target_tag) = 0;
191
192
  /**
193
   * Lists the tags that would be deleted by a rollback to the tag specified.
194
   *
195
   * Note: This doesn't change the database but is mainly used for sanity checks
196
   *       and user output.
197
   *
198
   * @param target_tag_name  the tag name for the planned rollback
199
   * @param tags             pointer to the result tag list to be filled
200
   * @return                 true on success
201
   */
202
  virtual bool ListTagsAffectedByRollback(const std::string  &target_tag_name,
203
                                          std::vector<Tag>   *tags) const = 0;
204
205
  /**
206
   * Provides a list of all referenced catalog hashes in this History.
207
   * The hashes will be ordered by their timestamp in acending order.
208
   *
209
   * @param hashes  pointer to the result vector to be filled
210
   */
211
  virtual bool GetHashes(std::vector<shash::Any> *hashes) const = 0;
212
213
  // database file management controls
214
  virtual void TakeDatabaseFileOwnership() = 0;
215
  virtual void DropDatabaseFileOwnership() = 0;
216
  virtual bool OwnsDatabaseFile() const    = 0;
217
218
  virtual bool Vacuum() = 0;
219
220
227
  const std::string& fqrn() const { return fqrn_; }
221
222
 protected:
223
360
  void set_fqrn(const std::string &fqrn) { fqrn_ = fqrn; }
224
225
 private:
226
  std::string   fqrn_;
227
};
228
229
}  // namespace history
230
231
#endif  // CVMFS_HISTORY_H_