2 * SDBM Database Utility
4 * (c) 2000--2001 Martin Mares <mj@ucw.cz>
6 * This software may be freely distributed and used according to the terms
7 * of the GNU Lesser General Public License.
12 #include "ucw/db_internal.h"
13 #include "ucw/fastbuf.h"
14 #include "ucw/ff-binary.h"
24 static int cache=1024;
25 static int force_key=-2;
26 static int force_val=-2;
27 static int force_page=-1;
29 #define SDBM_DUMP_MAGIC 0x321f120e
30 #define SDBM_DUMP_VERSION 1
33 dump(char *db, char *dmp)
37 struct sdbm_options op;
40 bzero(&op, sizeof(op));
46 die("Source open failed: %m");
48 dest = bopen(dmp, O_WRONLY | O_CREAT | O_TRUNC, 65536);
49 bputl(dest, SDBM_DUMP_MAGIC);
50 bputl(dest, SDBM_DUMP_VERSION);
51 bputl(dest, src->page_order);
52 bputl(dest, src->key_size);
53 bputl(dest, src->val_size);
55 fprintf(stderr, "Dumping database...\n");
59 byte key[65536], val[65536];
60 int klen = sizeof(key);
61 int vlen = sizeof(val);
62 e = sdbm_get_next(src, key, &klen, val, &vlen);
66 fprintf(stderr, "sdbm_get_next: error %d\n", e);
69 fprintf(stderr, "%d\r", c);
73 bwrite(dest, key, klen);
75 bwrite(dest, val, vlen);
80 fprintf(stderr, "Dumped %d records\n", c);
84 restore(char *dmp, char *db)
88 struct sdbm_options op;
91 src = bopen(dmp, O_RDONLY, 65536);
92 if (bgetl(src) != SDBM_DUMP_MAGIC ||
93 bgetl(src) != SDBM_DUMP_VERSION)
94 die("%s: not a sdbm dump", dmp);
96 bzero(&op, sizeof(op));
99 if (e < 0 && errno != ENOENT)
101 op.cache_size = cache;
102 op.flags = SDBM_CREAT | SDBM_WRITE | SDBM_FAST;
103 op.page_order = bgetl(src);
105 op.page_order = force_page;
106 op.key_size = bgetl(src);
108 op.key_size = force_key;
109 op.val_size = bgetl(src);
111 op.val_size = force_val;
112 dest = sdbm_open(&op);
114 die("Destination open failed");
116 fprintf(stderr, "Restoring database...\n");
119 byte key[65536], val[65536];
124 breadb(src, key, klen);
127 die("Corrupted dump file: value missing");
128 breadb(src, val, vlen);
131 fprintf(stderr, "%d\r", c);
134 if (sdbm_store(dest, key, klen, val, vlen) == 0)
135 fprintf(stderr, "sdbm_store: duplicate key\n");
140 fprintf(stderr, "Restored %d records\n", c);
144 rebuild(char *sdb, char *ddb)
146 struct sdbm *src, *dest;
147 struct sdbm_options op;
150 bzero(&op, sizeof(op));
154 src = sdbm_open(&op);
156 die("Source open failed: %m");
160 if (e < 0 && errno != ENOENT)
162 op.cache_size = cache;
163 op.flags = SDBM_CREAT | SDBM_WRITE | SDBM_FAST;
164 op.page_order = (force_page >= 0) ? (u32) force_page : src->root->page_order;
165 op.key_size = (force_key >= -1) ? force_key : src->root->key_size;
166 op.val_size = (force_val >= -1) ? force_val : src->root->val_size;
167 dest = sdbm_open(&op);
169 die("Destination open failed");
171 fprintf(stderr, "Rebuilding database...\n");
175 byte key[65536], val[65536];
176 int klen = sizeof(key);
177 int vlen = sizeof(val);
178 e = sdbm_get_next(src, key, &klen, val, &vlen);
182 fprintf(stderr, "sdbm_get_next: error %d\n", e);
185 fprintf(stderr, "%d\r", c);
188 if (sdbm_store(dest, key, klen, val, vlen) == 0)
189 fprintf(stderr, "sdbm_store: duplicate key\n");
194 fprintf(stderr, "Copied %d records\n", c);
198 main(int argc, char **argv)
202 while ((o = getopt(argc, argv, "vc:k:d:p:")) >= 0)
212 force_key=atol(optarg);
215 force_val=atol(optarg);
218 force_page=atol(optarg);
222 fprintf(stderr, "Usage: db-tool [<options>] <command> <database>\n\
226 -c<n>\t\tUse cache of <n> pages\n\
227 -d<n>\t\tSet data size to <n> (-1=variable) [restore,rebuild]\n\
228 -k<n>\t\tSet key size to <n> (-1=variable) [restore,rebuild]\n\
229 -p<n>\t\tSet page order to <n> [restore,rebuild]\n\
232 b <db> <new>\tRebuild database\n\
233 d <db> <dump>\tDump database\n\
234 r <dump> <db>\tRestore database from dump\n\
240 if (argc < 1 || strlen(argv[0]) != 1)
248 rebuild(argv[1], argv[2]);
253 dump(argv[1], argv[2]);
258 restore(argv[1], argv[2]);