Do not use sync(2) after commit. The fsync on individual files suffices.
[idzebra-moved-to-github.git] / index / main.c
1 /* $Id: main.c,v 1.112.2.6 2006-08-14 10:38:59 adam Exp $
2    Copyright (C) 1995-2005
3    Index Data Aps
4
5 This file is part of the Zebra server.
6
7 Zebra is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20
21 */
22
23
24 #include <stdio.h>
25 #include <string.h>
26 #include <assert.h>
27 #include <stdlib.h>
28 #ifdef WIN32
29 #include <io.h>
30 #else
31 #include <unistd.h>
32 #include <sys/time.h>
33 #endif
34 #include <time.h>
35 #if HAVE_SYS_TIMES_H
36 #include <sys/times.h>
37 #endif
38
39 #if HAVE_TCL_H
40 #include <tcl.h>
41 #endif
42
43 #if HAVE_EXPAT_H
44 #include <expat.h>
45 #endif
46
47 #include <data1.h>
48 #include "zebraapi.h"
49
50 char *prog;
51
52 int main (int argc, char **argv)
53 {
54     int ret;
55     int cmd = 0;
56     char *arg;
57     char *configName = 0;
58     int nsections = 0;
59     int enable_commit = 1;
60     char *database = 0;
61     Res res = res_open(0, 0, 0);
62     
63     int trans_started=0;
64 #if HAVE_SYS_TIMES_H
65     struct tms tms1, tms2;
66     struct timeval start_time, end_time;
67     double usec;
68 #endif
69 #ifndef WIN32
70     char nbuf[100];
71 #endif
72     ZebraService zs = 0;
73     ZebraHandle zh = 0;
74
75     nmem_init ();
76
77 #ifdef WIN32
78 #else
79     sprintf(nbuf, "%.40s(%d)", *argv, getpid());
80     yaz_log_init_prefix (nbuf);
81 #endif
82 #if HAVE_SYS_TIMES_H
83     times(&tms1);
84     gettimeofday(&start_time, 0);
85 #endif
86     prog = *argv;
87     if (argc < 2)
88     {
89         fprintf (stderr, "%s [options] command <dir> ...\n"
90         "Commands:\n"
91         " update <dir>  Update index with files below <dir>.\n"
92         "               If <dir> is empty filenames are read from stdin.\n"
93         " delete <dir>  Delete index with files below <dir>.\n"
94         " create <db>   Create database <db>\n"
95         " drop <db>     Drop database <db>\n"
96         " commit        Commit changes\n"
97         " clean         Clean shadow files\n"
98         "Options:\n"
99         " -t <type>     Index files as <type> (grs or text).\n"
100         " -c <config>   Read configuration file <config>.\n"
101         " -g <group>    Index files according to group settings.\n"
102         " -d <database> Records belong to Z39.50 database <database>.\n"
103         " -m <mbytes>   Use <mbytes> before flushing keys to disk.\n"
104         " -n            Don't use shadow system.\n"
105         " -s            Show analysis on stdout, but do no work.\n"
106         " -v <level>    Set logging to <level>.\n"
107         " -l <file>     Write log to <file>.\n"
108         " -L            Don't follow symbolic links.\n"
109         " -f <n>        Display information for the first <n> records.\n"
110         " -V            Show version.\n", *argv
111                  );
112         exit (1);
113     }
114     while ((ret = options ("sVt:c:g:d:m:v:nf:l:L"
115                            , argv, argc, &arg)) != -2)
116     {
117         if (ret == 0)
118         {
119             if(cmd == 0) /* command */
120             {
121                 if (!zs)
122                 {
123                     const char *config = configName ? configName : "zebra.cfg";
124                     zs = zebra_start_res (config, 0, res);
125                     if (!zs)
126                     {
127                         yaz_log (LOG_FATAL, "Cannot read config %s", config);
128                         exit (1);
129                     }   
130                     zh = zebra_open (zs);
131                     zebra_shadow_enable (zh, enable_commit);
132                 }
133
134                 if (database && zebra_select_database (zh, database))
135                 {
136                     logf(LOG_FATAL, "Could not select database %s errCode=%d",
137                          database, zebra_errCode(zh) );
138                     exit (1);
139                 }
140                 if (!strcmp (arg, "update"))
141                     cmd = 'u';
142                 else if (!strcmp (arg, "update1"))
143                     cmd = 'U';
144                 else if (!strcmp (arg, "update2"))
145                     cmd = 'm';
146                 else if (!strcmp (arg, "dump"))
147                     cmd = 's';
148                 else if (!strcmp (arg, "del") || !strcmp(arg, "delete"))
149                     cmd = 'd';
150                 else if (!strcmp (arg, "init"))
151                 {
152                     zebra_init (zh);
153                 }
154                 else if (!strcmp(arg, "drop"))
155                 {
156                     cmd = 'D';
157                 }
158                 else if (!strcmp(arg, "create"))
159                 {
160                     cmd = 'C';
161                 }
162                 else if (!strcmp (arg, "commit"))
163                 {
164                     zebra_commit (zh);
165                 }
166                 else if (!strcmp (arg, "clean"))
167                 {
168                     zebra_clean (zh);
169                 }
170                 else if (!strcmp (arg, "stat") || !strcmp (arg, "status"))
171                 {
172                     zebra_register_statistics (zh,0);
173                 }
174                 else if (!strcmp (arg, "dumpdict"))
175                 {
176                     zebra_register_statistics (zh,1);
177                 }
178                 else if (!strcmp (arg, "compact"))
179                 {
180                     zebra_compact (zh);
181                 }
182                 else
183                 {
184                     logf (LOG_FATAL, "unknown command: %s", arg);
185                     exit (1);
186                 }
187             }
188             else
189             {
190                 if (!trans_started)
191                 {
192                     trans_started=1;
193                     if (zebra_begin_trans (zh, 1))
194                         exit(1);
195                 }
196                 switch (cmd)
197                 {
198                 case 'u':
199                     zebra_repository_update (zh, arg);
200                     break;
201                 case 'd':
202                     zebra_repository_delete (zh, arg);
203                     break;
204                 case 's':
205                     zebra_repository_show (zh, arg);
206                     nsections = 0;
207                     break;
208                 case 'C':
209                     zebra_create_database(zh, arg);
210                     break;
211                 case 'D':
212                     zebra_drop_database(zh, arg);
213                     break;
214                 default:
215                     nsections = 0;
216                 }
217                 log_event_end (NULL, NULL);
218             }
219         }
220         else if (ret == 'V')
221         {
222             printf("Zebra %s %s\n", ZEBRAVER, ZEBRADATE);
223             printf(" (C) 1994-2005, Index Data ApS\n");
224 #ifdef WIN32
225 #ifdef _DEBUG
226             printf(" WIN32 Debug\n");
227 #else
228             printf(" WIN32 Release\n");
229 #endif
230 #endif
231 #if HAVE_BZLIB_H
232             printf("Using: libbzip2, (C) 1996-1999 Julian R Seward.  All rights reserved.\n");
233 #endif
234 #if HAVE_TCL_H
235             printf("Using: Tcl %s\n", TCL_VERSION);
236 #endif
237 #if HAVE_EXPAT_H
238             if (1)
239             {
240                 XML_Expat_Version v = XML_ExpatVersionInfo();
241                 printf ("Using: Expat %d.%d.%d\n",
242                         v.major, v.minor, v.micro);
243             }
244 #endif
245         }
246         else if (ret == 'v')
247             yaz_log_init_level (yaz_log_mask_str(arg));
248         else if (ret == 'l')
249             yaz_log_init_file (arg);
250         else if (ret == 'm')
251             res_set(res, "memMax", arg);
252         else if (ret == 'd')
253             database = arg;
254         else if (ret == 's')
255             res_set(res, "openRW", "0");
256         else if (ret == 'g')
257             res_set(res, "group", arg);
258         else if (ret == 'f')
259             res_set(res, "fileVerboseLimit", arg);
260         else if (ret == 'c')
261             configName = arg;
262         else if (ret == 't')
263             res_set(res, "recordType", arg);
264         else if (ret == 'n')
265             enable_commit = 0;
266         else if (ret == 'L')
267             res_set(res, "followLinks", "0");
268         else
269             logf (LOG_WARN, "unknown option '-%s'", arg);
270     } /* while arg */
271
272     if (trans_started)
273         zebra_end_trans (zh);
274
275     zebra_close (zh);
276     zebra_stop (zs);
277 #if HAVE_SYS_TIMES_H
278     if (trans_started)
279     {
280         gettimeofday(&end_time, 0);
281         usec = (end_time.tv_sec - start_time.tv_sec) * 1000000.0 +
282             end_time.tv_usec - start_time.tv_usec;
283         times(&tms2);
284         yaz_log (LOG_LOG, "zebraidx times: %5.2f %5.2f %5.2f",
285                 usec / 1000000,
286                 (double) (tms2.tms_utime - tms1.tms_utime)/100,
287                 (double) (tms2.tms_stime - tms1.tms_stime)/100);
288     }
289 #endif
290     nmem_exit();
291     exit (0);
292     return 0;
293 }
294