1 /* sdb - MIT - Copyright 2011-2016 - pancake */
2 
3 #include "sdb.h"
4 #include <fcntl.h>
5 
sdb_journal_filename(Sdb * s)6 static const char *sdb_journal_filename(Sdb *s) {
7 	return (s && s->name)
8 		? sdb_fmt ("%s.journal", s->name)
9 		: NULL;
10 }
11 
sdb_journal_close(Sdb * s)12 SDB_API bool sdb_journal_close(Sdb *s) {
13 	if (s->journal == -1) {
14 		return false;
15 	}
16 	close (s->journal);
17 	s->journal = -1;
18 	unlink (sdb_journal_filename (s));
19 	return true;
20 }
21 
sdb_journal_open(Sdb * s)22 SDB_API bool sdb_journal_open(Sdb *s) {
23 	const char *filename;
24 	if (!s || !s->name) {
25 		return false;
26 	}
27 	filename = sdb_journal_filename (s);
28 	if (!filename) {
29 		return false;
30 	}
31 	close (s->journal);
32 	s->journal = open (filename, O_CREAT | O_RDWR | O_APPEND, 0600);
33 	return s->journal != -1;
34 }
35 
36 // TODO boolify and save changes somewhere else? or just dont count that?
sdb_journal_load(Sdb * s)37 SDB_API int sdb_journal_load(Sdb *s) {
38 	int rr, sz, fd, changes = 0;
39 	char *eq, *str, *cur, *ptr = NULL;
40 	if (!s) {
41 		return 0;
42 	}
43 	fd = s->journal;
44 	if (fd == -1) {
45 		return 0;
46 	}
47 	sz = lseek (fd, 0, SEEK_END);
48 	if (sz < 1) {
49 		return 0;
50 	}
51 	lseek (fd, 0, SEEK_SET);
52 	str = malloc (sz + 1);
53 	if (!str) {
54 		return 0;
55 	}
56 	rr = read (fd, str, sz);
57 	if (rr < 0) {
58 		free (str);
59 		return 0;
60 	}
61 	str[sz] = 0;
62 	for (cur = str; ; ) {
63 		ptr = strchr (cur, '\n');
64 		if (!ptr) {
65 			break;
66 		}
67 		*ptr = 0;
68 		eq = strchr (cur, '=');
69 		if (eq) {
70 			*eq++ = 0;
71 			sdb_set (s, cur, eq, 0);
72 			changes ++;
73 		}
74 		cur = ptr + 1;
75 	}
76 	free (str);
77 	return changes;
78 }
79 
sdb_journal_log(Sdb * s,const char * key,const char * val)80 SDB_API bool sdb_journal_log(Sdb *s, const char *key, const char *val) {
81 	if (s->journal == -1) {
82 		return false;
83 	}
84 	const char *str = sdb_fmt ("%s=%s\n", key, val);
85 	int len = strlen (str);
86 	if (write (s->journal, str, len) != len) {
87 		return false;
88 	}
89 #if USE_MMAN
90 	(void)fsync (s->journal);
91 #endif
92 	return true;
93 }
94 
sdb_journal_clear(Sdb * s)95 SDB_API bool sdb_journal_clear(Sdb *s) {
96 	if (s->journal != -1) {
97 		return !ftruncate (s->journal, 0);
98 	}
99 	return false;
100 }
101 
sdb_journal_unlink(Sdb * s)102 SDB_API bool sdb_journal_unlink(Sdb *s) {
103 	const char *filename = sdb_journal_filename (s);
104 	sdb_journal_close (s);
105 	if (filename) {
106 		return !unlink (filename);
107 	}
108 	return false;
109 }
110