1 |
|
|
/** |
2 |
|
|
* This file is part of the CernVM File System. |
3 |
|
|
*/ |
4 |
|
|
|
5 |
|
|
#ifndef CVMFS_HISTORY_SQL_H_ |
6 |
|
|
#define CVMFS_HISTORY_SQL_H_ |
7 |
|
|
|
8 |
|
|
#include <string> |
9 |
|
|
|
10 |
|
|
#include "history.h" |
11 |
|
|
#include "sql.h" |
12 |
|
|
|
13 |
|
|
namespace history { |
14 |
|
|
|
15 |
|
|
/** |
16 |
|
|
* This class wraps the database structure of the History SQLite database files. |
17 |
|
|
* For that it inherits from sqlite::Database<>, please look there for further |
18 |
|
|
* details. |
19 |
|
|
*/ |
20 |
|
117 |
class HistoryDatabase : public sqlite::Database<HistoryDatabase> { |
21 |
|
|
public: |
22 |
|
|
static const float kLatestSchema; |
23 |
|
|
static const float kLatestSupportedSchema; |
24 |
|
|
// backwards-compatible schema changes |
25 |
|
|
static const unsigned kLatestSchemaRevision; |
26 |
|
|
|
27 |
|
|
static const std::string kFqrnKey; |
28 |
|
|
|
29 |
|
|
bool CreateEmptyDatabase(); |
30 |
|
|
bool InsertInitialValues(const std::string &repository_name); |
31 |
|
|
|
32 |
|
|
bool ContainsRecycleBin() const; |
33 |
|
|
|
34 |
|
|
bool CheckSchemaCompatibility(); |
35 |
|
|
bool LiveSchemaUpgradeIfNecessary(); |
36 |
|
|
bool CompactDatabase() const { return true; } // no implementation specific |
37 |
|
|
// database compaction. |
38 |
|
|
protected: |
39 |
|
|
// TODO(rmeusel): C++11 - constructor inheritance |
40 |
|
|
friend class sqlite::Database<HistoryDatabase>; |
41 |
|
117 |
HistoryDatabase(const std::string &filename, |
42 |
|
|
const OpenMode open_mode) : |
43 |
|
117 |
sqlite::Database<HistoryDatabase>(filename, open_mode) {} |
44 |
|
|
|
45 |
|
|
private: |
46 |
|
|
bool CreateTagsTable(); |
47 |
|
|
bool CreateRecycleBinTable(); |
48 |
|
|
bool CreateBranchesTable(); |
49 |
|
|
|
50 |
|
|
bool UpgradeSchemaRevision_10_1(); |
51 |
|
|
bool UpgradeSchemaRevision_10_2(); |
52 |
|
|
bool UpgradeSchemaRevision_10_3(); |
53 |
|
|
}; |
54 |
|
|
|
55 |
|
|
|
56 |
|
|
//------------------------------------------------------------------------------ |
57 |
|
|
|
58 |
|
|
|
59 |
✗✓ |
3194 |
class SqlHistory : public sqlite::Sql {}; |
60 |
|
|
|
61 |
|
|
|
62 |
|
|
/** |
63 |
|
|
* A mixin that allows to inject the RetrieveTag() method if it is needed in an |
64 |
|
|
* SQL query subclass. |
65 |
|
|
* |
66 |
|
|
* This allows us to orchestrate specific functionality in those classes as we |
67 |
|
|
* need it, without relying on multiple inheritance. Otherwise one would inherit |
68 |
|
|
* from sqlite::Sql more than once when inheriting from more than one of those |
69 |
|
|
* mixin classes in a query subclass. |
70 |
|
|
* In contrast, the mixins produce a clear (single) inheritance graph for each |
71 |
|
|
* of the derived classes by chaining the functionality as seen below. |
72 |
|
|
* |
73 |
|
|
* Example: |
74 |
|
|
* class SqlListRollbackTags : public SqlRetrieveTag<SqlRollback<SqlHistory>> {} |
75 |
|
|
* |
76 |
|
|
* ################ Note: both SqlRetrieveTag and SqlRollback need the |
77 |
|
|
* # sqlite::Sql # functionality provided in sqlite::Sql, thus |
78 |
|
|
* ################ would otherwise be derived from it individually |
79 |
|
|
* ��|` |
80 |
|
|
* | |
81 |
|
|
* ################ #################### ################# |
82 |
|
|
* # SqlHistory # <--- # SqlRetrieveTag # <--- # SqlRollback # |
83 |
|
|
* ################ #################### ################# |
84 |
|
|
* ��|` |
85 |
|
|
* | |
86 |
|
|
* ######################### |
87 |
|
|
* # SqlListRollbackTags # |
88 |
|
|
* ######################### |
89 |
|
|
* |
90 |
|
|
* Note: MixinT needs to be eventually derived from sqlite::Sql as it uses |
91 |
|
|
* Sql::Retrieve...() methods to extract information from SQLite rows. |
92 |
|
|
* |
93 |
|
|
* @param MixinT the class that should gain RetrieveTag()'s functionality |
94 |
|
|
*/ |
95 |
|
|
template <class MixinT> |
96 |
✗✓✗✓
|
1352 |
class SqlRetrieveTag : public MixinT { |
97 |
|
|
public: |
98 |
|
|
/** |
99 |
|
|
* Retrieves a tag from a database row |
100 |
|
|
* See SqlHistory::db_fields for a listing of the used SQLite data fields |
101 |
|
|
* |
102 |
|
|
* @return a tag retrieved from the SQLite database row |
103 |
|
|
*/ |
104 |
|
1248 |
History::Tag RetrieveTag() const { |
105 |
|
1248 |
History::Tag result; |
106 |
|
1248 |
result.name = MixinT::RetrieveString(0); |
107 |
✓✗✗✗ ✓ |
1248 |
result.root_hash = shash::MkFromHexPtr( |
108 |
|
|
shash::HexPtr(MixinT::RetrieveString(1)), |
109 |
|
|
shash::kSuffixCatalog); |
110 |
|
1248 |
result.revision = MixinT::RetrieveInt64(2); |
111 |
|
1248 |
result.timestamp = MixinT::RetrieveInt64(3); |
112 |
|
1248 |
result.channel = static_cast<History::UpdateChannel>( |
113 |
|
|
MixinT::RetrieveInt64(4)); |
114 |
|
1248 |
result.description = MixinT::RetrieveString(5); |
115 |
|
1248 |
result.size = MixinT::RetrieveInt64(6); |
116 |
|
1248 |
result.branch = MixinT::RetrieveString(7); |
117 |
|
1248 |
return result; |
118 |
|
|
} |
119 |
|
|
}; |
120 |
|
|
|
121 |
|
|
|
122 |
✗✓ |
182 |
class SqlInsertTag : public SqlHistory { |
123 |
|
|
private: |
124 |
|
|
static const std::string db_placeholders; |
125 |
|
|
|
126 |
|
|
public: |
127 |
|
|
explicit SqlInsertTag(const HistoryDatabase *database); |
128 |
|
|
bool BindTag(const History::Tag &tag); |
129 |
|
|
}; |
130 |
|
|
|
131 |
|
|
|
132 |
✗✓ |
182 |
class SqlRemoveTag : public SqlHistory { |
133 |
|
|
public: |
134 |
|
|
explicit SqlRemoveTag(const HistoryDatabase *database); |
135 |
|
|
bool BindName(const std::string &name); |
136 |
|
|
}; |
137 |
|
|
|
138 |
|
|
|
139 |
✗✓ |
234 |
class SqlFindTag : public SqlRetrieveTag<SqlHistory> { |
140 |
|
|
public: |
141 |
|
|
explicit SqlFindTag(const HistoryDatabase *database); |
142 |
|
|
bool BindName(const std::string &name); |
143 |
|
|
}; |
144 |
|
|
|
145 |
|
|
|
146 |
✗✓ |
234 |
class SqlFindTagByDate : public SqlRetrieveTag<SqlHistory> { |
147 |
|
|
public: |
148 |
|
|
explicit SqlFindTagByDate(const HistoryDatabase *database); |
149 |
|
|
bool BindTimestamp(const time_t timestamp); |
150 |
|
|
}; |
151 |
|
|
|
152 |
|
|
|
153 |
✗✓ |
182 |
class SqlFindBranchHead : public SqlRetrieveTag<SqlHistory> { |
154 |
|
|
public: |
155 |
|
|
explicit SqlFindBranchHead(const HistoryDatabase *database); |
156 |
|
|
bool BindBranchName(const std::string &branch_name); |
157 |
|
|
}; |
158 |
|
|
|
159 |
|
|
|
160 |
✗✓ |
234 |
class SqlCountTags : public SqlHistory { |
161 |
|
|
public: |
162 |
|
|
explicit SqlCountTags(const HistoryDatabase *database); |
163 |
|
|
unsigned RetrieveCount() const; |
164 |
|
|
}; |
165 |
|
|
|
166 |
|
|
|
167 |
✗✓ |
234 |
class SqlListTags : public SqlRetrieveTag<SqlHistory> { |
168 |
|
|
public: |
169 |
|
|
explicit SqlListTags(const HistoryDatabase *database); |
170 |
|
|
}; |
171 |
|
|
|
172 |
|
|
|
173 |
✗✓ |
234 |
class SqlGetChannelTips : public SqlRetrieveTag<SqlHistory> { |
174 |
|
|
public: |
175 |
|
|
explicit SqlGetChannelTips(const HistoryDatabase *database); |
176 |
|
|
}; |
177 |
|
|
|
178 |
|
|
|
179 |
✗✓ |
234 |
class SqlGetHashes : public SqlHistory { |
180 |
|
|
public: |
181 |
|
|
explicit SqlGetHashes(const HistoryDatabase *database); |
182 |
|
|
shash::Any RetrieveHash() const; |
183 |
|
|
}; |
184 |
|
|
|
185 |
|
|
|
186 |
✗✓ |
234 |
class SqlListBranches : public SqlHistory { |
187 |
|
|
public: |
188 |
|
|
explicit SqlListBranches(const HistoryDatabase *database); |
189 |
|
|
History::Branch RetrieveBranch() const; |
190 |
|
|
}; |
191 |
|
|
|
192 |
|
|
|
193 |
✗✓ |
182 |
class SqlInsertBranch : public SqlHistory { |
194 |
|
|
public: |
195 |
|
|
explicit SqlInsertBranch(const HistoryDatabase *database); |
196 |
|
|
bool BindBranch(const History::Branch &branch); |
197 |
|
|
}; |
198 |
|
|
|
199 |
|
|
|
200 |
|
|
/** |
201 |
|
|
* Mixin to inject the rollback condition definition and the BindTargetTag() |
202 |
|
|
* method into other subclasses. |
203 |
|
|
* |
204 |
|
|
* Note: See documentation of the SqlRetrieveTag<> for further details. |
205 |
|
|
* |
206 |
|
|
* @param MixinT the class that should gain BindTargetTags()'s functionality |
207 |
|
|
* @param offset offset for SQLite placeholders, if used inside other complex |
208 |
|
|
* SQL queries with preceeding placeholders |
209 |
|
|
*/ |
210 |
|
|
template <class MixinT, int offset = 0> |
211 |
✗✓ |
416 |
class SqlRollback : public MixinT { |
212 |
|
|
protected: |
213 |
|
|
static const std::string rollback_condition; |
214 |
|
|
|
215 |
|
|
public: |
216 |
|
7 |
bool BindTargetTag(const History::Tag &target_tag) { |
217 |
|
|
return MixinT::BindInt64(offset + 1, target_tag.revision) && |
218 |
|
|
MixinT::BindText(offset + 2, target_tag.name) && |
219 |
✓✗✓✗ ✓✗ |
7 |
MixinT::BindInt64(offset + 3, target_tag.channel); |
220 |
|
|
} |
221 |
|
|
}; |
222 |
|
|
|
223 |
|
|
template <class MixinT, int offset> |
224 |
|
|
const std::string SqlRollback<MixinT, offset>::rollback_condition = |
225 |
|
|
"(revision > :target_rev OR " |
226 |
|
|
" name = :target_name) " |
227 |
|
|
"AND channel = :target_chan "; |
228 |
|
|
|
229 |
|
|
|
230 |
✗✓ |
182 |
class SqlRollbackTag : public SqlRollback<SqlHistory> { |
231 |
|
|
public: |
232 |
|
|
explicit SqlRollbackTag(const HistoryDatabase *database); |
233 |
|
|
}; |
234 |
|
|
|
235 |
|
|
|
236 |
✗✓ |
234 |
class SqlListRollbackTags : public SqlRetrieveTag<SqlRollback<SqlHistory> > { |
237 |
|
|
public: |
238 |
|
|
explicit SqlListRollbackTags(const HistoryDatabase *database); |
239 |
|
|
}; |
240 |
|
|
|
241 |
|
|
|
242 |
✗✓ |
412 |
class SqlRecycleBin : public SqlHistory { |
243 |
|
|
protected: |
244 |
|
|
static const unsigned int kFlagCatalog = 1; |
245 |
|
|
|
246 |
|
|
bool CheckSchema(const HistoryDatabase *database) const; |
247 |
|
|
}; |
248 |
|
|
|
249 |
|
|
|
250 |
✗✓ |
230 |
class SqlRecycleBinList : public SqlRecycleBin { |
251 |
|
|
public: |
252 |
|
|
explicit SqlRecycleBinList(const HistoryDatabase *database); |
253 |
|
|
shash::Any RetrieveHash(); |
254 |
|
|
}; |
255 |
|
|
|
256 |
|
|
|
257 |
✗✓ |
182 |
class SqlRecycleBinFlush : public SqlRecycleBin { |
258 |
|
|
public: |
259 |
|
|
explicit SqlRecycleBinFlush(const HistoryDatabase *database); |
260 |
|
|
}; |
261 |
|
|
|
262 |
|
|
} // namespace history |
263 |
|
|
|
264 |
|
|
#endif // CVMFS_HISTORY_SQL_H_ |