-
Notifications
You must be signed in to change notification settings - Fork 1
/
purge.c
81 lines (72 loc) · 2.89 KB
/
purge.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include "his.h"
void purge() {
SqlCtx *readctx, *xrefctx, *cmdctx, *argsctx;
char *stamp;
int cmd_id, cmd_timestamp, args_id;
/* We need a first and a last timestamp to avoid mistakes. */
if (!first_timestamp || !last_timestamp)
error("purge requires --first=FROM and --last=TO");
/* The procedure is as follows:
- Select the cmds that fall in the timestamps with the args_ids that
they point to (via crossref).
- Select the same args_ids that fall outside of the timestamp range.
- Subtract.
- Delete the result.
*/
readctx = sqlnew("SELECT cmd.cmd_id, cmd.timestamp, args.args_id "
"FROM cmd, crossref, args "
"WHERE cmd.cmd_id=crossref.cmd_id "
" AND args.args_id=crossref.args_id "
" AND cmd.timestamp >= ? AND cmd.timestamp <= ? "
" AND args.args_id NOT IN "
"(SELECT args.args_id "
" FROM cmd, crossref, args "
" WHERE cmd.cmd_id=crossref.cmd_id "
" AND args.args_id=crossref.args_id "
" AND (cmd.timestamp < ? OR cmd.timestamp > ?))",
4,
INT, first_timestamp, INT, last_timestamp,
INT, first_timestamp, INT, last_timestamp);
while (sqlrun(readctx) == SQLITE_ROW) {
cmd_id = sqlcolint(readctx, 0);
cmd_timestamp = sqlcolint(readctx, 1);
args_id = sqlcolint(readctx, 2);
stamp = timestamp2str(cmd_timestamp);
msg("purge candidate: cmd_id=%d, args_id=%d, timestamp=%s",
cmd_id, args_id, stamp);
free(stamp);
/* This args_id occurs only within the timestamp */
argsctx = sqlnew("DELETE FROM args WHERE args_id = ?",
1,
INT, args_id);
sqlrun(argsctx);
sqlend(argsctx);
/* cmd entry can go. */
cmdctx = sqlnew("DELETE FROM cmd "
"WHERE cmd_id = ? AND timestamp = ?",
2,
INT, cmd_id,
INT, cmd_timestamp);
sqlrun(cmdctx);
sqlend(cmdctx);
/* crossref is cleaned up last as it has foreign keys */
xrefctx = sqlnew("DELETE FROM crossref "
"WHERE cmd_id = ? AND args_id = ?",
2,
INT, cmd_id,
INT, args_id);
sqlrun(xrefctx);
sqlend(xrefctx);
}
/* Whatever is left over should just be duplicates of other cmd entries
occurring in the given timeframe. We can delete those and ignore
constraint errors. */
cmdctx = sqlnew("DELETE FROM cmd "
"WHERE timestamp >= ? AND timestamp <=? "
"AND cmd_id NOT IN (SELECT cmd_id FROM crossref)",
2,
INT, first_timestamp,
INT, last_timestamp);
sqlrun(cmdctx);
sqlend(cmdctx);
}