GCC Code Coverage Report
Directory: cvmfs/ Exec Total Coverage
File: cvmfs/reflog_sql.cc Lines: 59 60 98.3 %
Date: 2019-02-03 02:48:13 Branches: 30 61 49.2 %

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
15
const std::string ReflogDatabase::kFqrnKey = "fqrn";
25
26
28
bool ReflogDatabase::CreateEmptyDatabase() {
27
  return sqlite::Sql(sqlite_db(),
28
                     "CREATE TABLE refs (hash TEXT, type INTEGER, "
29
                     "timestamp INTEGER, "
30
28
                     "CONSTRAINT pk_refs PRIMARY KEY (hash));").Execute();
31
}
32
33
34
9
bool ReflogDatabase::CheckSchemaCompatibility() {
35
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
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
28
  assert(read_write());
48
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
151
shash::Suffix SqlReflog::ToSuffix(const ReferenceType type) {
75

151
  switch (type) {
76
    case kRefCatalog:
77
113
      return shash::kSuffixCatalog;
78
    case kRefCertificate:
79
13
      return shash::kSuffixCertificate;
80
    case kRefHistory:
81
11
      return shash::kSuffixHistory;
82
    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
  MAKE_STATEMENTS("INSERT OR REPLACE INTO refs (@DB_FIELDS@) "
95

37
                  "VALUES (@DB_PLACEHOLDERS@);");
96
37
  DEFERRED_INITS(database);
97
}
98
99
28
bool SqlInsertReference::BindReference(const shash::Any    &reference_hash,
100
                                       const ReferenceType  type) {
101
  return
102
    BindTextTransient(1, reference_hash.ToString()) &&
103
    BindInt64(2, static_cast<uint64_t>(type))       &&
104


28
    BindInt64(3, static_cast<uint64_t>(time(NULL)));
105
}
106
107
108
//------------------------------------------------------------------------------
109
110
111
37
SqlCountReferences::SqlCountReferences(const ReflogDatabase *database) {
112
37
  DeferredInit(database->sqlite_db(), "SELECT count(*) as count FROM refs;");
113
}
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
  DeferredInit(database->sqlite_db(), "SELECT hash, type FROM refs "
125
                                      "WHERE type = :type AND "
126
                                      "timestamp < :timestamp "
127
37
                                      "ORDER BY timestamp DESC;");
128
}
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
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
13
  return shash::MkFromHexPtr(shash::HexPtr(RetrieveString(0)), suffix);
146
}
147
148
149
//------------------------------------------------------------------------------
150
151
152
37
SqlRemoveReference::SqlRemoveReference(const ReflogDatabase *database) {
153
  DeferredInit(database->sqlite_db(), "DELETE FROM refs WHERE hash = :hash "
154
37
                                      "AND type = :type;");
155
}
156
157
4
bool SqlRemoveReference::BindReference(const shash::Any    &reference_hash,
158
                                       const ReferenceType  type) {
159
  return
160
    BindTextTransient(1, reference_hash.ToString()) &&
161


4
    BindInt64(2, static_cast<uint64_t>(type));
162
}
163
164
165
//------------------------------------------------------------------------------
166
167
168
37
SqlContainsReference::SqlContainsReference(const ReflogDatabase *database) {
169
  DeferredInit(database->sqlite_db(), "SELECT count(*) as answer FROM refs "
170
                                      "WHERE type = :type "
171
37
                                      "  AND hash = :hash");
172
}
173
174
16
bool SqlContainsReference::BindReference(const shash::Any    &reference_hash,
175
                                         const ReferenceType  type) {
176
  return
177
    BindInt64(1, static_cast<uint64_t>(type)) &&
178


16
    BindTextTransient(2, reference_hash.ToString());
179
}
180
181
16
bool SqlContainsReference::RetrieveAnswer() {
182
16
  const int64_t count = RetrieveInt64(0);
183

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
  DeferredInit(database->sqlite_db(), "SELECT timestamp FROM refs "
193
                                      "WHERE type = :type "
194
37
                                      "  AND hash = :hash");
195
}
196
197
2
bool SqlGetTimestamp::BindReference(const shash::Any    &reference_hash,
198
                                    const ReferenceType  type) {
199
  return
200
    BindInt64(1, static_cast<uint64_t>(type)) &&
201


2
    BindTextTransient(2, reference_hash.ToString());
202
}
203
204
1
uint64_t SqlGetTimestamp::RetrieveTimestamp() {
205
1
  return RetrieveInt64(0);
206

45
}