monotone

monotone Mtn Source Tree

Root/database.hh

1#ifndef __DATABASE_HH__
2#define __DATABASE_HH__
3
4// copyright (C) 2002, 2003 graydon hoare <graydon@pobox.com>
5// all rights reserved.
6// licensed to the public under the terms of the GNU GPL (>= 2)
7// see the file COPYING for details
8
9struct sqlite3;
10struct cert;
11
12#include <vector>
13#include <set>
14#include <map>
15#include <string>
16
17#include <boost/filesystem/path.hpp>
18
19#include "commands.hh"
20#include "manifest.hh"
21#include "numeric_vocab.hh"
22#include "vocab.hh"
23
24struct revision_set;
25
26// this file defines a public, typed interface to the database.
27// the database class encapsulates all knowledge about sqlite,
28// the schema, and all SQL statements used to access the schema.
29//
30// one thing which is rather important to note is that this file
31// deals with two sorts of version relationships. the versions
32// stored in the database are all *backwards* from those the program
33// sees. so for example if you have two versions of a file
34//
35// file.1, file.2
36//
37// where file.2 was a modification of file.1, then as far as the rest of
38// the application is concerned -- and the ancestry graph -- file.1 is the
39// "old" version and file.2 is the "new" version. note the use of terms
40// which describe time, and the sequence of edits a user makes to a
41// file. those are ancestry terms. when the application composes a
42// patchset, for example, it'll contain the diff delta(file.1, file.2)
43//
44// from the database's perspective, however, file.1 is the derived version,
45// and file.2 is the base version. the base version is stored in the
46// "files" table, and the *reverse* diff delta(file.2, file.1) is stored in
47// the "file_deltas" table, under the id of file.1, with the id of file.2
48// listed as its base. note the use of the terms which describe
49// reconstruction; those are storage-system terms.
50//
51// the interface *to* the database, and the ancestry version graphs, use
52// the old / new metaphor of ancestry, but within the database (including
53// the private helper methods, and the storage version graphs) the
54// base/derived storage metaphor is used. the only real way to tell which
55// is which is to look at the parameter names and code. I might try to
56// express this in the type system some day, but not presently.
57//
58// the key phrase to keep repeating when working on this code is:
59//
60// "base files are new, derived files are old"
61//
62// it makes the code confusing, I know. this is possibly the worst part of
63// the program. I don't know if there's any way to make it clearer.
64
65class transaction_guard;
66struct posting;
67struct app_state;
68
69class database
70{
71 fs::path filename;
72 std::string const schema;
73 void check_schema();
74
75 struct app_state * __app;
76 struct sqlite3 * __sql;
77 struct sqlite3 * sql(bool init = false);
78 int transaction_level;
79
80 void install_functions(app_state * app);
81 void install_views();
82
83 typedef std::vector< std::vector<std::string> > results;
84 void execute(char const * query, ...);
85 void fetch(results & res,
86 int const want_cols,
87 int const want_rows,
88 char const * query, ...);
89
90 bool exists(hexenc<id> const & ident,
91 std::string const & table);
92 bool delta_exists(hexenc<id> const & ident,
93 std::string const & table);
94 bool delta_exists(hexenc<id> const & ident,
95 hexenc<id> const & base,
96 std::string const & table);
97
98 unsigned long count(std::string const & table);
99
100 void get_ids(std::string const & table, std::set< hexenc<id> > & ids);
101
102 void get(hexenc<id> const & new_id,
103 base64< gzip<data> > & dat,
104 std::string const & table);
105 void get_delta(hexenc<id> const & ident,
106 hexenc<id> const & base,
107 base64< gzip<delta> > & del,
108 std::string const & table);
109 void get_version(hexenc<id> const & id,
110 base64< gzip<data> > & dat,
111 std::string const & data_table,
112 std::string const & delta_table);
113
114 void put(hexenc<id> const & new_id,
115 base64< gzip<data> > const & dat,
116 std::string const & table);
117 void drop(hexenc<id> const & base,
118 std::string const & table);
119 void put_delta(hexenc<id> const & id,
120 hexenc<id> const & base,
121 base64< gzip<delta> > const & del,
122 std::string const & table);
123 void put_version(hexenc<id> const & old_id,
124 hexenc<id> const & new_id,
125 base64< gzip<delta> > const & del,
126 std::string const & data_table,
127 std::string const & delta_table);
128 void put_reverse_version(hexenc<id> const & new_id,
129 hexenc<id> const & old_id,
130 base64< gzip<delta> > const & reverse_del,
131 std::string const & data_table,
132 std::string const & delta_table);
133
134 void get_keys(std::string const & table, std::vector<rsa_keypair_id> & keys);
135
136 bool cert_exists(cert const & t,
137 std::string const & table);
138 void put_cert(cert const & t, std::string const & table);
139 void results_to_certs(results const & res,
140 std::vector<cert> & certs);
141
142 void get_certs(std::vector< cert > & certs,
143 std::string const & table);
144
145 void get_certs(hexenc<id> const & id,
146 std::vector< cert > & certs,
147 std::string const & table);
148
149 void get_certs(cert_name const & name,
150 std::vector< cert > & certs,
151 std::string const & table);
152
153 void get_certs(hexenc<id> const & id,
154 cert_name const & name,
155 std::vector< cert > & certs,
156 std::string const & table);
157
158 void get_certs(hexenc<id> const & id,
159 cert_name const & name,
160 base64<cert_value> const & val,
161 std::vector< cert > & certs,
162 std::string const & table);
163
164 void get_certs(cert_name const & name,
165 base64<cert_value> const & val,
166 std::vector<cert> & certs,
167 std::string const & table);
168
169 void begin_transaction();
170 void commit_transaction();
171 void rollback_transaction();
172 friend class transaction_guard;
173 friend void rcs_put_raw_file_edge(hexenc<id> const & old_id,
174 hexenc<id> const & new_id,
175 base64< gzip<delta> > const & del,
176 database & db);
177 friend void rcs_put_raw_manifest_edge(hexenc<id> const & old_id,
178 hexenc<id> const & new_id,
179 base64< gzip<delta> > const & del,
180 database & db);
181
182public:
183
184 database(fs::path const & file);
185
186 void set_filename(fs::path const & file);
187 void initialize();
188 void debug(std::string const & sql, std::ostream & out);
189 void dump(std::ostream &);
190 void load(std::istream &);
191 void info(std::ostream &);
192 void version(std::ostream &);
193 void migrate();
194 void rehash();
195 void ensure_open();
196
197 bool file_version_exists(file_id const & id);
198 bool manifest_version_exists(manifest_id const & id);
199 bool revision_exists(revision_id const & id);
200
201 void get_file_ids(std::set<file_id> & ids);
202 void get_manifest_ids(std::set<manifest_id> & ids);
203 void get_revision_ids(std::set<revision_id> & ids);
204
205 void set_app(app_state * app);
206
207 // get plain version if it exists, or reconstruct version
208 // from deltas (if they exist)
209 void get_file_version(file_id const & id,
210 file_data & dat);
211
212 // get file delta if it exists, else calculate it.
213 // both manifests must exist.
214 void get_file_delta(file_id const & src,
215 file_id const & dst,
216 file_delta & del);
217
218 // put file w/o predecessor into db
219 void put_file(file_id const & new_id,
220 file_data const & dat);
221
222 // store new version and update old version to be a delta
223 void put_file_version(file_id const & old_id,
224 file_id const & new_id,
225 file_delta const & del);
226
227 // load in a "direct" new -> old reverse edge (used during
228 // netsync and CVS load-in)
229 void put_file_reverse_version(file_id const & old_id,
230 file_id const & new_id,
231 file_delta const & del);
232
233 // get plain version if it exists, or reconstruct version
234 // from deltas (if they exist).
235 void get_manifest_version(manifest_id const & id,
236 manifest_data & dat);
237
238 // get a constructed manifest
239 void get_manifest(manifest_id const & id,
240 manifest_map & mm);
241
242 // get manifest delta if it exists, else calculate it.
243 // both manifests must exist.
244 void get_manifest_delta(manifest_id const & src,
245 manifest_id const & dst,
246 manifest_delta & del);
247
248 // put manifest w/o predecessor into db
249 void put_manifest(manifest_id const & new_id,
250 manifest_data const & dat);
251
252 // store new version and update old version to be a delta
253 void put_manifest_version(manifest_id const & old_id,
254 manifest_id const & new_id,
255 manifest_delta const & del);
256
257 // load in a "direct" new -> old reverse edge (used during
258 // netsync and CVS load-in)
259 void put_manifest_reverse_version(manifest_id const & old_id,
260 manifest_id const & new_id,
261 manifest_delta const & del);
262
263
264 void get_revision_ancestry(std::multimap<revision_id, revision_id> & graph);
265
266 void get_revision_parents(revision_id const & id,
267 std::set<revision_id> & parents);
268
269 void get_revision_children(revision_id const & id,
270 std::set<revision_id> & children);
271
272 void get_revision_manifest(revision_id const & cid,
273 manifest_id & mid);
274
275 void get_revision(revision_id const & id,
276 revision_set & cs);
277
278 void get_revision(revision_id const & id,
279 revision_data & dat);
280
281 void put_revision(revision_id const & new_id,
282 revision_set const & cs);
283
284 void put_revision(revision_id const & new_id,
285 revision_data const & dat);
286
287 void delete_existing_revs_and_certs();
288
289 // crypto key / cert operations
290
291 void get_key_ids(std::string const & pattern,
292 std::vector<rsa_keypair_id> & pubkeys,
293 std::vector<rsa_keypair_id> & privkeys);
294
295 void get_private_keys(std::vector<rsa_keypair_id> & privkeys);
296 void get_public_keys(std::vector<rsa_keypair_id> & pubkeys);
297
298 bool key_exists(rsa_keypair_id const & id);
299
300 bool public_key_exists(hexenc<id> const & hash);
301 bool public_key_exists(rsa_keypair_id const & id);
302 bool private_key_exists(rsa_keypair_id const & id);
303
304 void get_pubkey(hexenc<id> const & hash,
305 rsa_keypair_id & id,
306 base64<rsa_pub_key> & pub_encoded);
307
308 void get_key(rsa_keypair_id const & id,
309 base64<rsa_pub_key> & pub_encoded);
310
311 void get_key(rsa_keypair_id const & id,
312 base64< arc4<rsa_priv_key> > & priv_encoded);
313
314 void put_key(rsa_keypair_id const & id,
315 base64<rsa_pub_key> const & pub_encoded);
316
317 void put_key(rsa_keypair_id const & id,
318 base64< arc4<rsa_priv_key> > const & priv_encoded);
319
320 void put_key_pair(rsa_keypair_id const & pub_id,
321 base64<rsa_pub_key> const & pub_encoded,
322 base64< arc4<rsa_priv_key> > const & priv_encoded);
323
324 void delete_private_key(rsa_keypair_id const & pub_id);
325 void delete_public_key(rsa_keypair_id const & pub_id);
326
327 // note: this section is ridiculous. please do something about it.
328
329 bool manifest_cert_exists(manifest<cert> const & cert);
330 bool manifest_cert_exists(hexenc<id> const & hash);
331 void put_manifest_cert(manifest<cert> const & cert);
332
333 bool revision_cert_exists(revision<cert> const & cert);
334 bool revision_cert_exists(hexenc<id> const & hash);
335
336 void put_revision_cert(revision<cert> const & cert);
337
338 // this variant has to be rather coarse and fast, for netsync's use
339 void get_revision_cert_index(std::vector< std::pair<hexenc<id>,
340 std::pair<revision_id, rsa_keypair_id> > > & idx);
341
342 void get_revision_certs(std::vector< revision<cert> > & certs);
343
344 void get_revision_certs(cert_name const & name,
345 std::vector< revision<cert> > & certs);
346
347 void get_revision_certs(revision_id const & id,
348 cert_name const & name,
349 std::vector< revision<cert> > & certs);
350
351 void get_revision_certs(cert_name const & name,
352 base64<cert_value> const & val,
353 std::vector< revision<cert> > & certs);
354
355 void get_revision_certs(revision_id const & id,
356 cert_name const & name,
357 base64<cert_value> const & value,
358 std::vector< revision<cert> > & certs);
359
360 void get_revision_certs(revision_id const & id,
361 std::vector< revision<cert> > & certs);
362
363 void get_revision_cert(hexenc<id> const & hash,
364 revision<cert> & cert);
365
366 void get_manifest_certs(manifest_id const & id,
367 std::vector< manifest<cert> > & certs);
368
369 void get_manifest_certs(cert_name const & name,
370 std::vector< manifest<cert> > & certs);
371
372 void get_manifest_certs(manifest_id const & id,
373 cert_name const & name,
374 std::vector< manifest<cert> > & certs);
375
376 void get_manifest_cert(hexenc<id> const & hash,
377 manifest<cert> & cert);
378
379 // epochs
380
381 void get_epochs(std::map<cert_value, epoch_data> & epochs);
382
383 void get_epoch(epoch_id const & eid, cert_value & branch, epoch_data & epo);
384
385 bool epoch_exists(epoch_id const & eid);
386
387 void set_epoch(cert_value const & branch, epoch_data const & epo);
388
389 void clear_epoch(cert_value const & branch);
390
391 // vars
392
393 void get_vars(std::map<var_key, var_value > & vars);
394
395 void get_var(var_key const & key, var_value & value);
396
397 bool var_exists(var_key const & key);
398
399 void set_var(var_key const & key, var_value const & value);
400
401 void clear_var(var_key const & key);
402
403 // completion stuff
404
405 void complete(std::string const & partial,
406 std::set<revision_id> & completions);
407
408 void complete(std::string const & partial,
409 std::set<manifest_id> & completions);
410
411 void complete(std::string const & partial,
412 std::set<file_id> & completions);
413
414 void complete(commands::selector_type ty,
415 std::string const & partial,
416 std::vector<std::pair<commands::selector_type,
417 std::string> > const & limit,
418 std::set<std::string> & completions);
419
420 ~database();
421
422};
423
424// transaction guards nest. acquire one in any scope you'd like
425// transaction-protected, and it'll make sure the db aborts a
426// txn if there's any exception before you call commit()
427
428class transaction_guard
429{
430 bool committed;
431 database & db;
432public:
433 transaction_guard(database & d);
434 ~transaction_guard();
435 void commit();
436};
437
438
439
440#endif // __DATABASE_HH__

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status