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