1 /*************************************************************************************************
2  * Mutual converter between a database of Depot and a TSV text
3  *                                                      Copyright (C) 2000-2007 Mikio Hirabayashi
4  * This file is part of QDBM, Quick Database Manager.
5  * QDBM is free software; you can redistribute it and/or modify it under the terms of the GNU
6  * Lesser General Public License as published by the Free Software Foundation; either version
7  * 2.1 of the License or any later version.  QDBM is distributed in the hope that it will be
8  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
10  * details.
11  * You should have received a copy of the GNU Lesser General Public License along with QDBM; if
12  * not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
13  * 02111-1307 USA.
14  *************************************************************************************************/
15 
16 
17 #include <depot.h>
18 #include <cabin.h>
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 
23 #undef TRUE
24 #define TRUE           1                 /* boolean true */
25 #undef FALSE
26 #define FALSE          0                 /* boolean false */
27 
28 
29 /* for RISC OS */
30 #if defined(__riscos__) || defined(__riscos)
31 #include <unixlib/local.h>
32 int __riscosify_control = __RISCOSIFY_NO_PROCESS;
33 #endif
34 
35 
36 /* global variables */
37 const char *progname;                    /* program name */
38 
39 
40 /* function prototypes */
41 int main(int argc, char **argv);
42 void usage(void);
43 int runimport(int argc, char **argv);
44 int runexport(int argc, char **argv);
45 void pdperror(const char *name);
46 char *getl(void);
47 int doimport(const char *name, int bnum, int bin);
48 int doexport(const char *name, int bin);
49 
50 
51 /* main routine */
main(int argc,char ** argv)52 int main(int argc, char **argv){
53   int rv;
54   cbstdiobin();
55   progname = argv[0];
56   if(argc < 2) usage();
57   rv = 0;
58   if(!strcmp(argv[1], "import")){
59     rv = runimport(argc, argv);
60   } else if(!strcmp(argv[1], "export")){
61     rv = runexport(argc, argv);
62   } else {
63     usage();
64   }
65   return rv;
66 }
67 
68 
69 /* print the usage and exit */
usage(void)70 void usage(void){
71   fprintf(stderr, "%s: mutual converter between TSV and Depot database\n", progname);
72   fprintf(stderr, "\n");
73   fprintf(stderr, "usage:\n");
74   fprintf(stderr, "  %s import [-bnum num] [-bin] name\n", progname);
75   fprintf(stderr, "  %s export [-bin] name\n", progname);
76   fprintf(stderr, "\n");
77   exit(1);
78 }
79 
80 
81 /* parse arguments of import command */
runimport(int argc,char ** argv)82 int runimport(int argc, char **argv){
83   char *name;
84   int i, bnum, bin, rv;
85   name = NULL;
86   bnum = -1;
87   bin = FALSE;
88   for(i = 2; i < argc; i++){
89     if(!name && argv[i][0] == '-'){
90       if(!strcmp(argv[i], "-bnum")){
91         if(++i >= argc) usage();
92         bnum = atoi(argv[i]);
93       } else if(!strcmp(argv[i], "-bin")){
94         bin = TRUE;
95       } else {
96         usage();
97       }
98     } else if(!name){
99       name = argv[i];
100     } else {
101       usage();
102     }
103   }
104   if(!name) usage();
105   rv = doimport(name, bnum, bin);
106   return rv;
107 }
108 
109 
110 /* parse arguments of export command */
runexport(int argc,char ** argv)111 int runexport(int argc, char **argv){
112   char *name;
113   int i, bin, rv;
114   name = NULL;
115   bin = FALSE;
116   for(i = 2; i < argc; i++){
117     if(!name && argv[i][0] == '-'){
118       if(!strcmp(argv[i], "-bin")){
119         bin = TRUE;
120       } else {
121         usage();
122       }
123     } else if(!name){
124       name = argv[i];
125     } else {
126       usage();
127     }
128   }
129   if(!name) usage();
130   rv = doexport(name, bin);
131   return rv;
132 }
133 
134 
135 /* print an error message */
pdperror(const char * name)136 void pdperror(const char *name){
137   fprintf(stderr, "%s: %s: %s\n", progname, name, dperrmsg(dpecode));
138 }
139 
140 
141 /* read a line */
getl(void)142 char *getl(void){
143   char *buf;
144   int c, len, blen;
145   buf = NULL;
146   len = 0;
147   blen = 256;
148   while((c = getchar()) != EOF){
149     if(blen <= len) blen *= 2;
150     buf = cbrealloc(buf, blen + 1);
151     if(c == '\n') c = '\0';
152     buf[len++] = c;
153     if(c == '\0') break;
154   }
155   if(!buf) return NULL;
156   buf[len] = '\0';
157   return buf;
158 }
159 
160 
161 /* perform import command */
doimport(const char * name,int bnum,int bin)162 int doimport(const char *name, int bnum, int bin){
163   DEPOT *depot;
164   char *buf, *kbuf, *vbuf, *ktmp, *vtmp;
165   int i, err, ktsiz, vtsiz;
166   /* open a database */
167   if(!(depot = dpopen(name, DP_OWRITER | DP_OCREAT, bnum))){
168     pdperror(name);
169     return 1;
170   }
171   /* loop for each line */
172   err = FALSE;
173   for(i = 1; (buf = getl()) != NULL; i++){
174     kbuf = buf;
175     if((vbuf = strchr(buf, '\t')) != NULL){
176       *vbuf = '\0';
177       vbuf++;
178       /* store a record */
179       if(bin){
180         ktmp = cbbasedecode(kbuf, &ktsiz);
181         vtmp = cbbasedecode(vbuf, &vtsiz);
182         if(!dpput(depot, ktmp, ktsiz, vtmp, vtsiz, DP_DOVER)){
183           pdperror(name);
184           err = TRUE;
185         }
186         free(vtmp);
187         free(ktmp);
188       } else {
189         if(!dpput(depot, kbuf, -1, vbuf, -1, DP_DOVER)){
190           pdperror(name);
191           err = TRUE;
192         }
193       }
194     } else {
195       fprintf(stderr, "%s: %s: invalid format in line %d\n", progname, name, i);
196     }
197     free(buf);
198     if(err) break;
199   }
200   /* close the database */
201   if(!dpclose(depot)){
202     pdperror(name);
203     return 1;
204   }
205   return err ? 1 : 0;
206 }
207 
208 
209 /* perform export command */
doexport(const char * name,int bin)210 int doexport(const char *name, int bin){
211   DEPOT *depot;
212   char *kbuf, *vbuf, *tmp;
213   int err, ksiz, vsiz;
214   /* open a database */
215   if(!(depot = dpopen(name, DP_OREADER, -1))){
216     pdperror(name);
217     return 1;
218   }
219   /* initialize the iterator */
220   dpiterinit(depot);
221   /* loop for each key */
222   err = FALSE;
223   while((kbuf = dpiternext(depot, &ksiz)) != NULL){
224     /* retrieve a value with a key */
225     if(!(vbuf = dpget(depot, kbuf, ksiz, 0, -1, &vsiz))){
226       pdperror(name);
227       free(kbuf);
228       err = TRUE;
229       break;
230     }
231     /* output data */
232     if(bin){
233       tmp = cbbaseencode(kbuf, ksiz);
234       printf("%s\t", tmp);
235       free(tmp);
236       tmp = cbbaseencode(vbuf, vsiz);
237       printf("%s\n", tmp);
238       free(tmp);
239     } else {
240       printf("%s\t%s\n", kbuf, vbuf);
241     }
242     /* free resources */
243     free(vbuf);
244     free(kbuf);
245   }
246   /* check whether all records were retrieved */
247   if(dpecode != DP_ENOITEM){
248     pdperror(name);
249     err = TRUE;
250   }
251   /* close the database */
252   if(!dpclose(depot)){
253     pdperror(name);
254     return 1;
255   }
256   return err ? 1 : 0;
257 }
258 
259 
260 
261 /* END OF FILE */
262