summaryrefslogtreecommitdiff
path: root/src/tcfdb/tools/jbfmgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tcfdb/tools/jbfmgr.c')
-rw-r--r--src/tcfdb/tools/jbfmgr.c782
1 files changed, 782 insertions, 0 deletions
diff --git a/src/tcfdb/tools/jbfmgr.c b/src/tcfdb/tools/jbfmgr.c
new file mode 100644
index 0000000..8fe3632
--- /dev/null
+++ b/src/tcfdb/tools/jbfmgr.c
@@ -0,0 +1,782 @@
+/*************************************************************************************************
+ * The command line utility of the fixed-length database API
+ * Copyright (C) 2006-2012 FAL Labs
+ * This file is part of Tokyo Cabinet.
+ * Tokyo Cabinet is free software; you can redistribute it and/or modify it under the terms of
+ * the GNU Lesser General Public License as published by the Free Software Foundation; either
+ * version 2.1 of the License or any later version. Tokyo Cabinet is distributed in the hope
+ * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ * You should have received a copy of the GNU Lesser General Public License along with Tokyo
+ * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307 USA.
+ *************************************************************************************************/
+
+
+#include <tcutil.h>
+#include <tcfdb.h>
+#include "myconf.h"
+
+
+/* global variables */
+const char *g_progname; // program name
+HANDLE g_dbgfd = INVALID_HANDLE_VALUE; // debugging output
+
+
+/* function prototypes */
+int main(int argc, char **argv);
+static void usage(void);
+static void printerr(TCFDB *fdb);
+static int printdata(const char *ptr, int size, bool px);
+static char *mygetline(FILE *ifp);
+static int runcreate(int argc, char **argv);
+static int runinform(int argc, char **argv);
+static int runput(int argc, char **argv);
+static int runout(int argc, char **argv);
+static int runget(int argc, char **argv);
+static int runlist(int argc, char **argv);
+static int runoptimize(int argc, char **argv);
+static int runimporttsv(int argc, char **argv);
+static int runversion(int argc, char **argv);
+static int proccreate(const char *path, int width, int64_t limsiz);
+static int procinform(const char *path, int omode);
+static int procput(const char *path, const char *kbuf, int ksiz, const char *vbuf, int vsiz,
+ int omode, int dmode);
+static int procout(const char *path, const char *kbuf, int ksiz, int omode);
+static int procget(const char *path, const char *kbuf, int ksiz, int omode, bool px, bool pz);
+static int proclist(const char *path, int omode, int max, bool pv, bool px,
+ const char *rlstr, const char *rustr, const char *ristr);
+static int procoptimize(const char *path, int width, int64_t limsiz, int omode);
+static int procimporttsv(const char *path, const char *file, int omode, bool sc);
+static int procversion(void);
+
+/* main routine */
+int main(int argc, char **argv) {
+ g_progname = argv[0];
+ g_dbgfd = INVALID_HANDLE_VALUE;
+ const char *ebuf = getenv("TCDBGFD");
+ if (ebuf) {
+ int debugfd = tcatoix(ebuf);
+#ifdef _WIN32
+ g_dbgfd = (HANDLE) _get_osfhandle(debugfd);
+#else
+ g_dbgfd = debugfd;
+#endif
+ }
+ if (argc < 2) usage();
+ int rv = 0;
+ if (!strcmp(argv[1], "create")) {
+ rv = runcreate(argc, argv);
+ } else if (!strcmp(argv[1], "inform")) {
+ rv = runinform(argc, argv);
+ } else if (!strcmp(argv[1], "put")) {
+ rv = runput(argc, argv);
+ } else if (!strcmp(argv[1], "out")) {
+ rv = runout(argc, argv);
+ } else if (!strcmp(argv[1], "get")) {
+ rv = runget(argc, argv);
+ } else if (!strcmp(argv[1], "list")) {
+ rv = runlist(argc, argv);
+ } else if (!strcmp(argv[1], "optimize")) {
+ rv = runoptimize(argc, argv);
+ } else if (!strcmp(argv[1], "importtsv")) {
+ rv = runimporttsv(argc, argv);
+ } else if (!strcmp(argv[1], "version") || !strcmp(argv[1], "--version")) {
+ rv = runversion(argc, argv);
+ } else {
+ usage();
+ }
+ return rv;
+}
+
+/* print the usage and exit */
+static void usage(void) {
+ fprintf(stderr, "%s: the command line utility of the fixed-length database API\n", g_progname);
+ fprintf(stderr, "\n");
+ fprintf(stderr, "usage:\n");
+ fprintf(stderr, " %s create path [width [limsiz]]\n", g_progname);
+ fprintf(stderr, " %s inform [-nl|-nb] path\n", g_progname);
+ fprintf(stderr, " %s put [-nl|-nb] [-sx] [-dk|-dc|-dai|-dad] path key value\n", g_progname);
+ fprintf(stderr, " %s out [-nl|-nb] [-sx] path key\n", g_progname);
+ fprintf(stderr, " %s get [-nl|-nb] [-sx] [-px] [-pz] path key\n", g_progname);
+ fprintf(stderr, " %s list [-nl|-nb] [-m num] [-pv] [-px] [-rb lkey ukey] [-ri str] path\n",
+ g_progname);
+ fprintf(stderr, " %s optimize [-nl|-nb] path [width [limsiz]]\n", g_progname);
+ fprintf(stderr, " %s importtsv [-nl|-nb] [-sc] path [file]\n", g_progname);
+ fprintf(stderr, " %s version\n", g_progname);
+ fprintf(stderr, "\n");
+ exit(1);
+}
+
+/* print error information */
+static void printerr(TCFDB *fdb) {
+ const char *path = tcfdbpath(fdb);
+ int ecode = tcfdbecode(fdb);
+ fprintf(stderr, "%s: %s: %d: %s\n", g_progname, path ? path : "-", ecode, tcfdberrmsg(ecode));
+}
+
+/* print record data */
+static int printdata(const char *ptr, int size, bool px) {
+ int len = 0;
+ while (size-- > 0) {
+ if (px) {
+ if (len > 0) putchar(' ');
+ len += printf("%02X", *(unsigned char *) ptr);
+ } else {
+ putchar(*ptr);
+ len++;
+ }
+ ptr++;
+ }
+ return len;
+}
+
+/* read a line from a file descriptor */
+static char *mygetline(FILE *ifp) {
+ int len = 0;
+ int blen = 1024;
+ char *buf = tcmalloc(blen + 1);
+ bool end = true;
+ int c;
+ while ((c = fgetc(ifp)) != EOF) {
+ end = false;
+ if (c == '\0') continue;
+ if (blen <= len) {
+ blen *= 2;
+ buf = tcrealloc(buf, blen + 1);
+ }
+ if (c == '\n' || c == '\r') c = '\0';
+ buf[len++] = c;
+ if (c == '\0') break;
+ }
+ if (end) {
+ tcfree(buf);
+ return NULL;
+ }
+ buf[len] = '\0';
+ return buf;
+}
+
+/* parse arguments of create command */
+static int runcreate(int argc, char **argv) {
+ char *path = NULL;
+ char *wstr = NULL;
+ char *lstr = NULL;
+ for (int i = 2; i < argc; i++) {
+ if (!path && argv[i][0] == '-') {
+ usage();
+ } else if (!path) {
+ path = argv[i];
+ } else if (!wstr) {
+ wstr = argv[i];
+ } else if (!lstr) {
+ lstr = argv[i];
+ } else {
+ usage();
+ }
+ }
+ if (!path) usage();
+ int width = wstr ? tcatoix(wstr) : -1;
+ int64_t limsiz = lstr ? tcatoix(lstr) : -1;
+ int rv = proccreate(path, width, limsiz);
+ return rv;
+}
+
+/* parse arguments of inform command */
+static int runinform(int argc, char **argv) {
+ char *path = NULL;
+ int omode = 0;
+ for (int i = 2; i < argc; i++) {
+ if (!path && argv[i][0] == '-') {
+ if (!strcmp(argv[i], "-nl")) {
+ omode |= FDBONOLCK;
+ } else if (!strcmp(argv[i], "-nb")) {
+ omode |= FDBOLCKNB;
+ } else {
+ usage();
+ }
+ } else if (!path) {
+ path = argv[i];
+ } else {
+ usage();
+ }
+ }
+ if (!path) usage();
+ int rv = procinform(path, omode);
+ return rv;
+}
+
+/* parse arguments of put command */
+static int runput(int argc, char **argv) {
+ char *path = NULL;
+ char *key = NULL;
+ char *value = NULL;
+ int omode = 0;
+ int dmode = 0;
+ bool sx = false;
+ for (int i = 2; i < argc; i++) {
+ if (!path && argv[i][0] == '-') {
+ if (!strcmp(argv[i], "-nl")) {
+ omode |= FDBONOLCK;
+ } else if (!strcmp(argv[i], "-nb")) {
+ omode |= FDBOLCKNB;
+ } else if (!strcmp(argv[i], "-dk")) {
+ dmode = -1;
+ } else if (!strcmp(argv[i], "-dc")) {
+ dmode = 1;
+ } else if (!strcmp(argv[i], "-dai")) {
+ dmode = 10;
+ } else if (!strcmp(argv[i], "-dad")) {
+ dmode = 11;
+ } else if (!strcmp(argv[i], "-sx")) {
+ sx = true;
+ } else {
+ usage();
+ }
+ } else if (!path) {
+ path = argv[i];
+ } else if (!key) {
+ key = argv[i];
+ } else if (!value) {
+ value = argv[i];
+ } else {
+ usage();
+ }
+ }
+ if (!path || !key || !value) usage();
+ char *kbuf, *vbuf;
+ int ksiz, vsiz;
+ if (sx) {
+ kbuf = tchexdecode(key, &ksiz);
+ vbuf = tchexdecode(value, &vsiz);
+ } else {
+ ksiz = strlen(key);
+ kbuf = tcmemdup(key, ksiz);
+ vsiz = strlen(value);
+ vbuf = tcmemdup(value, vsiz);
+ }
+ int rv = procput(path, kbuf, ksiz, vbuf, vsiz, omode, dmode);
+ tcfree(vbuf);
+ tcfree(kbuf);
+ return rv;
+}
+
+/* parse arguments of out command */
+static int runout(int argc, char **argv) {
+ char *path = NULL;
+ char *key = NULL;
+ int omode = 0;
+ bool sx = false;
+ for (int i = 2; i < argc; i++) {
+ if (!path && argv[i][0] == '-') {
+ if (!strcmp(argv[i], "-nl")) {
+ omode |= FDBONOLCK;
+ } else if (!strcmp(argv[i], "-nb")) {
+ omode |= FDBOLCKNB;
+ } else if (!strcmp(argv[i], "-sx")) {
+ sx = true;
+ } else {
+ usage();
+ }
+ } else if (!path) {
+ path = argv[i];
+ } else if (!key) {
+ key = argv[i];
+ } else {
+ usage();
+ }
+ }
+ if (!path || !key) usage();
+ int ksiz;
+ char *kbuf;
+ if (sx) {
+ kbuf = tchexdecode(key, &ksiz);
+ } else {
+ ksiz = strlen(key);
+ kbuf = tcmemdup(key, ksiz);
+ }
+ int rv = procout(path, kbuf, ksiz, omode);
+ tcfree(kbuf);
+ return rv;
+}
+
+/* parse arguments of get command */
+static int runget(int argc, char **argv) {
+ char *path = NULL;
+ char *key = NULL;
+ int omode = 0;
+ bool sx = false;
+ bool px = false;
+ bool pz = false;
+ for (int i = 2; i < argc; i++) {
+ if (!path && argv[i][0] == '-') {
+ if (!strcmp(argv[i], "-nl")) {
+ omode |= FDBONOLCK;
+ } else if (!strcmp(argv[i], "-nb")) {
+ omode |= FDBOLCKNB;
+ } else if (!strcmp(argv[i], "-sx")) {
+ sx = true;
+ } else if (!strcmp(argv[i], "-px")) {
+ px = true;
+ } else if (!strcmp(argv[i], "-pz")) {
+ pz = true;
+ } else {
+ usage();
+ }
+ } else if (!path) {
+ path = argv[i];
+ } else if (!key) {
+ key = argv[i];
+ } else {
+ usage();
+ }
+ }
+ if (!path || !key) usage();
+ int ksiz;
+ char *kbuf;
+ if (sx) {
+ kbuf = tchexdecode(key, &ksiz);
+ } else {
+ ksiz = strlen(key);
+ kbuf = tcmemdup(key, ksiz);
+ }
+ int rv = procget(path, kbuf, ksiz, omode, px, pz);
+ tcfree(kbuf);
+ return rv;
+}
+
+/* parse arguments of list command */
+static int runlist(int argc, char **argv) {
+ char *path = NULL;
+ int omode = 0;
+ int max = -1;
+ bool pv = false;
+ bool px = false;
+ char *rlstr = NULL;
+ char *rustr = NULL;
+ char *ristr = NULL;
+ for (int i = 2; i < argc; i++) {
+ if (!path && argv[i][0] == '-') {
+ if (!strcmp(argv[i], "-nl")) {
+ omode |= FDBONOLCK;
+ } else if (!strcmp(argv[i], "-nb")) {
+ omode |= FDBOLCKNB;
+ } else if (!strcmp(argv[i], "-m")) {
+ if (++i >= argc) usage();
+ max = tcatoix(argv[i]);
+ } else if (!strcmp(argv[i], "-pv")) {
+ pv = true;
+ } else if (!strcmp(argv[i], "-px")) {
+ px = true;
+ } else if (!strcmp(argv[i], "-rb")) {
+ if (++i >= argc) usage();
+ rlstr = argv[i];
+ if (++i >= argc) usage();
+ rustr = argv[i];
+ } else if (!strcmp(argv[i], "-ri")) {
+ if (++i >= argc) usage();
+ ristr = argv[i];
+ } else {
+ usage();
+ }
+ } else if (!path) {
+ path = argv[i];
+ } else {
+ usage();
+ }
+ }
+ if (!path) usage();
+ int rv = proclist(path, omode, max, pv, px, rlstr, rustr, ristr);
+ return rv;
+}
+
+/* parse arguments of optimize command */
+static int runoptimize(int argc, char **argv) {
+ char *path = NULL;
+ char *wstr = NULL;
+ char *lstr = NULL;
+ int omode = 0;
+ for (int i = 2; i < argc; i++) {
+ if (!path && argv[i][0] == '-') {
+ if (!strcmp(argv[i], "-nl")) {
+ omode |= FDBONOLCK;
+ } else if (!strcmp(argv[i], "-nb")) {
+ omode |= FDBOLCKNB;
+ } else {
+ usage();
+ }
+ } else if (!path) {
+ path = argv[i];
+ } else if (!wstr) {
+ wstr = argv[i];
+ } else if (!lstr) {
+ lstr = argv[i];
+ } else {
+ usage();
+ }
+ }
+ if (!path) usage();
+ int width = wstr ? tcatoix(wstr) : -1;
+ int64_t limsiz = lstr ? tcatoix(lstr) : -1;
+ int rv = procoptimize(path, width, limsiz, omode);
+ return rv;
+}
+
+/* parse arguments of importtsv command */
+static int runimporttsv(int argc, char **argv) {
+ char *path = NULL;
+ char *file = NULL;
+ int omode = 0;
+ bool sc = false;
+ for (int i = 2; i < argc; i++) {
+ if (!path && argv[i][0] == '-') {
+ if (!strcmp(argv[i], "-nl")) {
+ omode |= FDBONOLCK;
+ } else if (!strcmp(argv[i], "-nb")) {
+ omode |= FDBOLCKNB;
+ } else if (!strcmp(argv[i], "-sc")) {
+ sc = true;
+ } else {
+ usage();
+ }
+ } else if (!path) {
+ path = argv[i];
+ } else if (!file) {
+ file = argv[i];
+ } else {
+ usage();
+ }
+ }
+ if (!path) usage();
+ int rv = procimporttsv(path, file, omode, sc);
+ return rv;
+}
+
+/* parse arguments of version command */
+static int runversion(int argc, char **argv) {
+ int rv = procversion();
+ return rv;
+}
+
+/* perform create command */
+static int proccreate(const char *path, int width, int64_t limsiz) {
+ TCFDB *fdb = tcfdbnew();
+ if (!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if (!tcfdbtune(fdb, width, limsiz)) {
+ printerr(fdb);
+ tcfdbdel(fdb);
+ return 1;
+ }
+ if (!tcfdbopen(fdb, path, FDBOWRITER | FDBOCREAT | FDBOTRUNC)) {
+ printerr(fdb);
+ tcfdbdel(fdb);
+ return 1;
+ }
+ bool err = false;
+ if (!tcfdbclose(fdb)) {
+ printerr(fdb);
+ err = true;
+ }
+ tcfdbdel(fdb);
+ return err ? 1 : 0;
+}
+
+/* perform inform command */
+static int procinform(const char *path, int omode) {
+ TCFDB *fdb = tcfdbnew();
+ if (!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if (!tcfdbopen(fdb, path, FDBOREADER | omode)) {
+ printerr(fdb);
+ tcfdbdel(fdb);
+ return 1;
+ }
+ bool err = false;
+ const char *npath = tcfdbpath(fdb);
+ if (!npath) npath = "(unknown)";
+ printf("path: %s\n", npath);
+ const char *type = "(unknown)";
+ switch (tcfdbtype(fdb)) {
+ case TCDBTHASH: type = "hash";
+ break;
+ case TCDBTBTREE: type = "btree";
+ break;
+ case TCDBTFIXED: type = "fixed";
+ break;
+ case TCDBTTABLE: type = "table";
+ break;
+ }
+ printf("database type: %s\n", type);
+ uint8_t flags = tcfdbflags(fdb);
+ printf("additional flags:");
+ if (flags & FDBFOPEN) printf(" open");
+ if (flags & FDBFFATAL) printf(" fatal");
+ printf("\n");
+ printf("minimum ID number: %" PRIuMAX "\n", (uint64_t) tcfdbmin(fdb));
+ printf("maximum ID number: %" PRIuMAX "\n", (uint64_t) tcfdbmax(fdb));
+ printf("width of the value: %u\n", (unsigned int) tcfdbwidth(fdb));
+ printf("limit file size: %" PRIuMAX "\n", (uint64_t) tcfdblimsiz(fdb));
+ printf("limit ID number: %" PRIuMAX "\n", (uint64_t) tcfdblimid(fdb));
+ printf("inode number: %" PRIdMAX "\n", (int64_t) tcfdbinode(fdb));
+ char date[48];
+ tcdatestrwww(tcfdbmtime(fdb), INT_MAX, date);
+ printf("modified time: %s\n", date);
+ printf("record number: %" PRIuMAX "\n", (uint64_t) tcfdbrnum(fdb));
+ printf("file size: %" PRIuMAX "\n", (uint64_t) tcfdbfsiz(fdb));
+ if (!tcfdbclose(fdb)) {
+ if (!err) printerr(fdb);
+ err = true;
+ }
+ tcfdbdel(fdb);
+ return err ? 1 : 0;
+}
+
+/* perform put command */
+static int procput(const char *path, const char *kbuf, int ksiz, const char *vbuf, int vsiz,
+ int omode, int dmode) {
+ TCFDB *fdb = tcfdbnew();
+ if (!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if (!tcfdbopen(fdb, path, FDBOWRITER | omode)) {
+ printerr(fdb);
+ tcfdbdel(fdb);
+ return 1;
+ }
+ bool err = false;
+ int inum;
+ double dnum;
+ switch (dmode) {
+ case -1:
+ if (!tcfdbputkeep2(fdb, kbuf, ksiz, vbuf, vsiz)) {
+ printerr(fdb);
+ err = true;
+ }
+ break;
+ case 1:
+ if (!tcfdbputcat2(fdb, kbuf, ksiz, vbuf, vsiz)) {
+ printerr(fdb);
+ err = true;
+ }
+ break;
+ case 10:
+ inum = tcfdbaddint(fdb, tcfdbkeytoid(kbuf, ksiz), tcatoi(vbuf));
+ if (inum == INT_MIN) {
+ printerr(fdb);
+ err = true;
+ } else {
+ printf("%d\n", inum);
+ }
+ break;
+ case 11:
+ dnum = tcfdbadddouble(fdb, tcfdbkeytoid(kbuf, ksiz), tcatof(vbuf));
+ if (isnan(dnum)) {
+ printerr(fdb);
+ err = true;
+ } else {
+ printf("%.6f\n", dnum);
+ }
+ break;
+ default:
+ if (!tcfdbput2(fdb, kbuf, ksiz, vbuf, vsiz)) {
+ printerr(fdb);
+ err = true;
+ }
+ break;
+ }
+ if (!tcfdbclose(fdb)) {
+ if (!err) printerr(fdb);
+ err = true;
+ }
+ tcfdbdel(fdb);
+ return err ? 1 : 0;
+}
+
+/* perform out command */
+static int procout(const char *path, const char *kbuf, int ksiz, int omode) {
+ TCFDB *fdb = tcfdbnew();
+ if (!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if (!tcfdbopen(fdb, path, FDBOWRITER | omode)) {
+ printerr(fdb);
+ tcfdbdel(fdb);
+ return 1;
+ }
+ bool err = false;
+ if (!tcfdbout2(fdb, kbuf, ksiz)) {
+ printerr(fdb);
+ err = true;
+ }
+ if (!tcfdbclose(fdb)) {
+ if (!err) printerr(fdb);
+ err = true;
+ }
+ tcfdbdel(fdb);
+ return err ? 1 : 0;
+}
+
+/* perform get command */
+static int procget(const char *path, const char *kbuf, int ksiz, int omode, bool px, bool pz) {
+ TCFDB *fdb = tcfdbnew();
+ if (!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if (!tcfdbopen(fdb, path, FDBOREADER | omode)) {
+ printerr(fdb);
+ tcfdbdel(fdb);
+ return 1;
+ }
+ bool err = false;
+ int vsiz;
+ char *vbuf = tcfdbget2(fdb, kbuf, ksiz, &vsiz);
+ if (vbuf) {
+ printdata(vbuf, vsiz, px);
+ if (!pz) putchar('\n');
+ tcfree(vbuf);
+ } else {
+ printerr(fdb);
+ err = true;
+ }
+ if (!tcfdbclose(fdb)) {
+ if (!err) printerr(fdb);
+ err = true;
+ }
+ tcfdbdel(fdb);
+ return err ? 1 : 0;
+}
+
+/* perform list command */
+static int proclist(const char *path, int omode, int max, bool pv, bool px,
+ const char *rlstr, const char *rustr, const char *ristr) {
+ TCFDB *fdb = tcfdbnew();
+ if (!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if (!tcfdbopen(fdb, path, FDBOREADER | omode)) {
+ printerr(fdb);
+ tcfdbdel(fdb);
+ return 1;
+ }
+ bool err = false;
+ if (rlstr || ristr) {
+ TCLIST *keys = ristr ? tcfdbrange5(fdb, ristr, max) : tcfdbrange3(fdb, rlstr, rustr, max);
+ for (int i = 0; i < tclistnum(keys); i++) {
+ int ksiz;
+ const char *kbuf = tclistval(keys, i, &ksiz);
+ printf("%s", kbuf);
+ if (pv) {
+ int vsiz;
+ char *vbuf = tcfdbget2(fdb, kbuf, ksiz, &vsiz);
+ if (vbuf) {
+ putchar('\t');
+ printdata(vbuf, vsiz, px);
+ tcfree(vbuf);
+ }
+ }
+ putchar('\n');
+ }
+ tclistdel(keys);
+ } else {
+ if (!tcfdbiterinit(fdb)) {
+ printerr(fdb);
+ err = true;
+ }
+ int cnt = 0;
+ uint64_t id;
+ while ((id = tcfdbiternext(fdb)) > 0) {
+ printf("%" PRIuMAX "", (uint64_t) id);
+ if (pv) {
+ int vsiz;
+ char *vbuf = tcfdbget(fdb, id, &vsiz);
+ if (vbuf) {
+ putchar('\t');
+ printdata(vbuf, vsiz, px);
+ tcfree(vbuf);
+ }
+ }
+ putchar('\n');
+ if (max >= 0 && ++cnt >= max) break;
+ }
+ }
+ if (!tcfdbclose(fdb)) {
+ if (!err) printerr(fdb);
+ err = true;
+ }
+ tcfdbdel(fdb);
+ return err ? 1 : 0;
+}
+
+/* perform optimize command */
+static int procoptimize(const char *path, int width, int64_t limsiz, int omode) {
+ TCFDB *fdb = tcfdbnew();
+ if (!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if (!tcfdbopen(fdb, path, FDBOWRITER | omode)) {
+ printerr(fdb);
+ tcfdbdel(fdb);
+ return 1;
+ }
+ bool err = false;
+ if (!tcfdboptimize(fdb, width, limsiz)) {
+ printerr(fdb);
+ err = true;
+ }
+ if (!tcfdbclose(fdb)) {
+ if (!err) printerr(fdb);
+ err = true;
+ }
+ tcfdbdel(fdb);
+ return err ? 1 : 0;
+}
+
+/* perform importtsv command */
+static int procimporttsv(const char *path, const char *file, int omode, bool sc) {
+ FILE *ifp = file ? fopen(file, "rb") : stdin;
+ if (!ifp) {
+ fprintf(stderr, "%s: could not open\n", file ? file : "(stdin)");
+ return 1;
+ }
+ TCFDB *fdb = tcfdbnew();
+ if (!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if (!tcfdbopen(fdb, path, FDBOWRITER | FDBOCREAT | omode)) {
+ printerr(fdb);
+ tcfdbdel(fdb);
+ if (ifp != stdin) fclose(ifp);
+ return 1;
+ }
+ bool err = false;
+ char *line;
+ int cnt = 0;
+ while (!err && (line = mygetline(ifp)) != NULL) {
+ char *pv = strchr(line, '\t');
+ if (!pv) {
+ tcfree(line);
+ continue;
+ }
+ *pv = '\0';
+ if (sc) tcstrutfnorm(line, TCUNSPACE | TCUNLOWER | TCUNNOACC | TCUNWIDTH);
+ if (!tcfdbput3(fdb, line, pv + 1)) {
+ printerr(fdb);
+ err = true;
+ }
+ tcfree(line);
+ if (cnt > 0 && cnt % 100 == 0) {
+ putchar('.');
+ fflush(stdout);
+ if (cnt % 5000 == 0) printf(" (%08d)\n", cnt);
+ }
+ cnt++;
+ }
+ printf(" (%08d)\n", cnt);
+ if (!tcfdbclose(fdb)) {
+ if (!err) printerr(fdb);
+ err = true;
+ }
+ tcfdbdel(fdb);
+ if (ifp != stdin) fclose(ifp);
+ return err ? 1 : 0;
+}
+
+/* perform version command */
+static int procversion(void) {
+ printf("Tokyo Cabinet version %s (%d:%s) for %s\n",
+ tcversion, _TC_LIBVER, _TC_FORMATVER, TCSYSNAME);
+ printf("Copyright (C) 2006-2012 FAL Labs\n");
+ return 0;
+}
+
+
+
+// END OF FILE