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

Archive Download this file

Branches

Tags

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