1 /*************************************************************************************************
2 * The command line utility of the abstract database API
3 * Copyright (C) 2006-2008 Mikio Hirabayashi
4 * This file is part of Tokyo Cabinet.
5 * Tokyo Cabinet is free software; you can redistribute it and/or modify it under the terms of
6 * the GNU Lesser General Public License as published by the Free Software Foundation; either
7 * version 2.1 of the License or any later version. Tokyo Cabinet is distributed in the hope
8 * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
10 * License for more details.
11 * You should have received a copy of the GNU Lesser General Public License along with Tokyo
12 * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
13 * Boston, MA 02111-1307 USA.
14 *************************************************************************************************/
22 /* global variables */
23 const char *g_progname; // program name
26 /* function prototypes */
27 int main(int argc, char **argv);
28 static void usage(void);
29 static void printerr(TCADB *adb);
30 static int printdata(const char *ptr, int size, bool px);
31 static char *hextoobj(const char *str, int *sp);
32 static int runcreate(int argc, char **argv);
33 static int runinform(int argc, char **argv);
34 static int runput(int argc, char **argv);
35 static int runout(int argc, char **argv);
36 static int runget(int argc, char **argv);
37 static int runlist(int argc, char **argv);
38 static int runversion(int argc, char **argv);
39 static int proccreate(const char *name);
40 static int procinform(const char *name);
41 static int procput(const char *name, const char *kbuf, int ksiz, const char *vbuf, int vsiz,
43 static int procout(const char *name, const char *kbuf, int ksiz);
44 static int procget(const char *name, const char *kbuf, int ksiz, bool px, bool pz);
45 static int proclist(const char *name, int max, bool pv, bool px, const char *fmstr);
46 static int procversion(void);
50 int main(int argc, char **argv){
54 if(!strcmp(argv[1], "create")){
55 rv = runcreate(argc, argv);
56 } else if(!strcmp(argv[1], "inform")){
57 rv = runinform(argc, argv);
58 } else if(!strcmp(argv[1], "put")){
59 rv = runput(argc, argv);
60 } else if(!strcmp(argv[1], "out")){
61 rv = runout(argc, argv);
62 } else if(!strcmp(argv[1], "get")){
63 rv = runget(argc, argv);
64 } else if(!strcmp(argv[1], "list")){
65 rv = runlist(argc, argv);
66 } else if(!strcmp(argv[1], "version") || !strcmp(argv[1], "--version")){
67 rv = runversion(argc, argv);
75 /* print the usage and exit */
76 static void usage(void){
77 fprintf(stderr, "%s: the command line utility of the abstract database API\n", g_progname);
78 fprintf(stderr, "\n");
79 fprintf(stderr, "usage:\n");
80 fprintf(stderr, " %s create name\n", g_progname);
81 fprintf(stderr, " %s inform name\n", g_progname);
82 fprintf(stderr, " %s put [-sx] [-dk|-dc] name key value\n", g_progname);
83 fprintf(stderr, " %s out [-sx] name key\n", g_progname);
84 fprintf(stderr, " %s get [-sx] [-px] [-pz] name key\n", g_progname);
85 fprintf(stderr, " %s list [-m num] [-pv] [-px] [-fm str] name\n", g_progname);
86 fprintf(stderr, " %s version\n", g_progname);
87 fprintf(stderr, "\n");
92 /* print error information */
93 static void printerr(TCADB *adb){
94 fprintf(stderr, "%s: error\n", g_progname);
98 /* print record data */
99 static int printdata(const char *ptr, int size, bool px){
103 if(len > 0) putchar(' ');
104 len += printf("%02X", *(unsigned char *)ptr);
115 /* create a binary object from a hexadecimal string */
116 static char *hextoobj(const char *str, int *sp){
117 int len = strlen(str);
118 char *buf = tcmalloc(len + 1);
120 for(int i = 0; i < len; i += 2){
121 while(strchr(" \n\r\t\f\v", str[i])){
125 if((mbuf[0] = str[i]) == '\0') break;
126 if((mbuf[1] = str[i+1]) == '\0') break;
128 buf[j++] = (char)strtol(mbuf, NULL, 16);
136 /* parse arguments of create command */
137 static int runcreate(int argc, char **argv){
139 for(int i = 2; i < argc; i++){
140 if(!name && argv[i][0] == '-'){
149 int rv = proccreate(name);
154 /* parse arguments of inform command */
155 static int runinform(int argc, char **argv){
157 for(int i = 2; i < argc; i++){
158 if(!name && argv[i][0] == '-'){
167 name = tcsprintf("%s#mode=r", name);
168 int rv = procinform(name);
174 /* parse arguments of put command */
175 static int runput(int argc, char **argv){
181 for(int i = 2; i < argc; i++){
182 if(!name && argv[i][0] == '-'){
183 if(!strcmp(argv[i], "-dk")){
185 } else if(!strcmp(argv[i], "-dc")){
187 } else if(!strcmp(argv[i], "-sx")){
202 if(!name || !key || !value) usage();
206 kbuf = hextoobj(key, &ksiz);
207 vbuf = hextoobj(value, &vsiz);
210 kbuf = tcmemdup(key, ksiz);
211 vsiz = strlen(value);
212 vbuf = tcmemdup(value, vsiz);
214 int rv = procput(name, kbuf, ksiz, vbuf, vsiz, dmode);
221 /* parse arguments of out command */
222 static int runout(int argc, char **argv){
226 for(int i = 2; i < argc; i++){
227 if(!name && argv[i][0] == '-'){
228 if(!strcmp(argv[i], "-sx")){
241 if(!name || !key) usage();
245 kbuf = hextoobj(key, &ksiz);
248 kbuf = tcmemdup(key, ksiz);
250 int rv = procout(name, kbuf, ksiz);
256 /* parse arguments of get command */
257 static int runget(int argc, char **argv){
263 for(int i = 2; i < argc; i++){
264 if(!name && argv[i][0] == '-'){
265 if(!strcmp(argv[i], "-sx")){
267 } else if(!strcmp(argv[i], "-px")){
269 } else if(!strcmp(argv[i], "-pz")){
282 if(!name || !key) usage();
286 kbuf = hextoobj(key, &ksiz);
289 kbuf = tcmemdup(key, ksiz);
291 name = tcsprintf("%s#mode=r", name);
292 int rv = procget(name, kbuf, ksiz, px, pz);
299 /* parse arguments of list command */
300 static int runlist(int argc, char **argv){
306 for(int i = 2; i < argc; i++){
307 if(!name && argv[i][0] == '-'){
308 if(!strcmp(argv[i], "-m")){
309 if(++i >= argc) usage();
311 } else if(!strcmp(argv[i], "-pv")){
313 } else if(!strcmp(argv[i], "-px")){
315 } else if(!strcmp(argv[i], "-fm")){
316 if(++i >= argc) usage();
328 name = tcsprintf("%s#mode=r", name);
329 int rv = proclist(name, max, pv, px, fmstr);
335 /* parse arguments of version command */
336 static int runversion(int argc, char **argv){
337 int rv = procversion();
342 /* perform create command */
343 static int proccreate(const char *name){
344 TCADB *adb = tcadbnew();
345 if(!tcadbopen(adb, name)){
351 if(!tcadbclose(adb)){
360 /* perform inform command */
361 static int procinform(const char *name){
362 TCADB *adb = tcadbnew();
363 if(!tcadbopen(adb, name)){
369 printf("record number: %llu\n", (unsigned long long)tcadbrnum(adb));
370 printf("size: %llu\n", (unsigned long long)tcadbsize(adb));
371 if(!tcadbclose(adb)){
380 /* perform put command */
381 static int procput(const char *name, const char *kbuf, int ksiz, const char *vbuf, int vsiz,
383 TCADB *adb = tcadbnew();
384 if(!tcadbopen(adb, name)){
392 if(!tcadbputkeep(adb, kbuf, ksiz, vbuf, vsiz)){
398 if(!tcadbputcat(adb, kbuf, ksiz, vbuf, vsiz)){
404 if(!tcadbput(adb, kbuf, ksiz, vbuf, vsiz)){
410 if(!tcadbclose(adb)){
411 if(!err) printerr(adb);
419 /* perform out command */
420 static int procout(const char *name, const char *kbuf, int ksiz){
421 TCADB *adb = tcadbnew();
422 if(!tcadbopen(adb, name)){
428 if(!tcadbout(adb, kbuf, ksiz)){
432 if(!tcadbclose(adb)){
433 if(!err) printerr(adb);
441 /* perform get command */
442 static int procget(const char *name, const char *kbuf, int ksiz, bool px, bool pz){
443 TCADB *adb = tcadbnew();
444 if(!tcadbopen(adb, name)){
451 char *vbuf = tcadbget(adb, kbuf, ksiz, &vsiz);
453 printdata(vbuf, vsiz, px);
454 if(!pz) putchar('\n');
460 if(!tcadbclose(adb)){
461 if(!err) printerr(adb);
469 /* perform list command */
470 static int proclist(const char *name, int max, bool pv, bool px, const char *fmstr){
471 TCADB *adb = tcadbnew();
472 if(!tcadbopen(adb, name)){
479 TCLIST *keys = tcadbfwmkeys2(adb, fmstr, max);
480 for(int i = 0; i < tclistnum(keys); i++){
482 const char *kbuf = tclistval(keys, i, &ksiz);
483 printdata(kbuf, ksiz, px);
486 char *vbuf = tcadbget(adb, kbuf, ksiz, &vsiz);
489 printdata(vbuf, vsiz, px);
497 if(!tcadbiterinit(adb)){
504 while((kbuf = tcadbiternext(adb, &ksiz)) != NULL){
505 printdata(kbuf, ksiz, px);
508 char *vbuf = tcadbget(adb, kbuf, ksiz, &vsiz);
511 printdata(vbuf, vsiz, px);
517 if(max >= 0 && ++cnt >= max) break;
520 if(!tcadbclose(adb)){
521 if(!err) printerr(adb);
529 /* perform version command */
530 static int procversion(void){
531 printf("Tokyo Cabinet version %s (%d:%s)\n", tcversion, _TC_LIBVER, _TC_FORMATVER);
532 printf("Copyright (C) 2006-2008 Mikio Hirabayashi\n");