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