Work on update while servers are running. Three lock files introduced.
[idzebra-moved-to-github.git] / index / main.c
1 /*
2  * Copyright (C) 1994-1995, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: main.c,v $
7  * Revision 1.28  1995-12-08 16:22:56  adam
8  * Work on update while servers are running. Three lock files introduced.
9  * The servers reload their registers when necessary, but they don't
10  * reestablish result sets yet.
11  *
12  * Revision 1.27  1995/12/07  17:38:47  adam
13  * Work locking mechanisms for concurrent updates/commit.
14  *
15  * Revision 1.26  1995/12/06  12:41:23  adam
16  * New command 'stat' for the index program.
17  * Filenames can be read from stdin by specifying '-'.
18  * Bug fix/enhancement of the transformation from terms to regular
19  * expressons in the search engine.
20  *
21  * Revision 1.25  1995/12/01  16:24:39  adam
22  * Commit files use separate meta file area.
23  *
24  * Revision 1.24  1995/11/30  17:01:38  adam
25  * New setting commitCache: points to commit directories/files.
26  * New command commit: commits at the end of a zebraidx run.
27  *
28  * Revision 1.23  1995/11/30  08:34:31  adam
29  * Started work on commit facility.
30  * Changed a few malloc/free to xmalloc/xfree.
31  *
32  * Revision 1.22  1995/11/28  09:09:42  adam
33  * Zebra config renamed.
34  * Use setting 'recordId' to identify record now.
35  * Bug fix in recindex.c: rec_release_blocks was invokeded even
36  * though the blocks were already released.
37  * File traversal properly deletes records when needed.
38  *
39  * Revision 1.21  1995/11/27  14:27:39  adam
40  * Renamed 'update' command to 'dir'.
41  *
42  * Revision 1.20  1995/11/27  13:58:53  adam
43  * New option -t. storeStore data implemented in server.
44  *
45  * Revision 1.19  1995/11/25  10:24:06  adam
46  * More record fields - they are enumerated now.
47  * New options: flagStoreData flagStoreKey.
48  *
49  * Revision 1.18  1995/11/22  17:19:17  adam
50  * Record management uses the bfile system.
51  *
52  * Revision 1.17  1995/11/21  15:01:16  adam
53  * New general match criteria implemented.
54  * New feature: document groups.
55  *
56  * Revision 1.16  1995/11/20  11:56:27  adam
57  * Work on new traversal.
58  *
59  * Revision 1.15  1995/11/01  16:25:51  quinn
60  * *** empty log message ***
61  *
62  * Revision 1.14  1995/10/17  18:02:09  adam
63  * New feature: databases. Implemented as prefix to words in dictionary.
64  *
65  * Revision 1.13  1995/10/10  12:24:39  adam
66  * Temporary sort files are compressed.
67  *
68  * Revision 1.12  1995/10/04  16:57:20  adam
69  * Key input and merge sort in one pass.
70  *
71  * Revision 1.11  1995/09/29  14:01:45  adam
72  * Bug fixes.
73  *
74  * Revision 1.10  1995/09/28  14:22:57  adam
75  * Sort uses smaller temporary files.
76  *
77  * Revision 1.9  1995/09/14  07:48:24  adam
78  * Record control management.
79  *
80  * Revision 1.8  1995/09/06  16:11:18  adam
81  * Option: only one word key per file.
82  *
83  * Revision 1.7  1995/09/05  15:28:39  adam
84  * More work on search engine.
85  *
86  * Revision 1.6  1995/09/04  12:33:43  adam
87  * Various cleanup. YAZ util used instead.
88  *
89  * Revision 1.5  1995/09/04  09:10:39  adam
90  * More work on index add/del/update.
91  * Merge sort implemented.
92  * Initial work on z39 server.
93  *
94  * Revision 1.4  1995/09/01  14:06:36  adam
95  * Split of work into more files.
96  *
97  * Revision 1.3  1995/09/01  10:57:07  adam
98  * Minor changes.
99  *
100  * Revision 1.2  1995/09/01  10:30:24  adam
101  * More work on indexing. Not working yet.
102  *
103  * Revision 1.1  1995/08/31  14:50:24  adam
104  * New simple file index tool.
105  *
106  */
107 #include <stdio.h>
108 #include <assert.h>
109 #include <unistd.h>
110
111 #include <alexutil.h>
112 #include <data1.h>
113 #include "index.h"
114
115 char *prog;
116 size_t mem_max = 4*1024*1024;
117 extern char *data1_tabpath;
118
119 int main (int argc, char **argv)
120 {
121     int ret;
122     int cmd = 0;
123     char *arg;
124     char *configName = NULL;
125     int nsections;
126
127     struct recordGroup rGroupDef;
128     
129     rGroupDef.groupName = NULL;
130     rGroupDef.databaseName = NULL;
131     rGroupDef.path = NULL;
132     rGroupDef.recordId = NULL;
133     rGroupDef.recordType = NULL;
134     rGroupDef.flagStoreData = -1;
135     rGroupDef.flagStoreKeys = -1;
136
137     prog = *argv;
138     if (argc < 2)
139     {
140         fprintf (stderr, "zebraidx [options] command <dir> ...\n"
141         "Commands:\n"
142         " update <dir>  Update index with files below <dir>.\n"
143         "               If <dir> is empty filenames are read from stdin.\n"
144         " delete <dir>  Delete index with files below <dir>.\n"
145         "Options:\n"
146         " -t <type>     Index files as <type> (grs or text).\n"
147         " -c <config>   Read configuration file <config>.\n"
148         " -g <group>    Index files according to group settings.\n"
149         " -d <database> Records belong to Z39.50 database <database>.\n"
150         " -m <mbytes>   Use <mbytes> before flushing keys to disk.\n"
151         " -v <level>    Set logging to <level>.\n");
152         exit (1);
153     }
154     while ((ret = options ("t:c:g:d:m:v:", argv, argc, &arg)) != -2)
155     {
156         if (ret == 0)
157         {
158             const char *rval;
159             if(cmd == 0) /* command */
160             {
161                 if (!common_resource)
162                 {
163                     common_resource = res_open (configName ?
164                                                 configName : FNAME_CONFIG);
165                     if (!common_resource)
166                     {
167                         logf (LOG_FATAL, "Cannot open resource `%s'",
168                               configName);
169                         exit (1);
170                     }
171                     data1_tabpath = res_get (common_resource, "profilePath");
172                 }
173                 if (!strcmp (arg, "update"))
174                     cmd = 'u';
175                 else if (!strcmp (arg, "del") || !strcmp(arg, "delete"))
176                     cmd = 'd';
177                 else if (!strcmp (arg, "commit"))
178                 {
179                     zebraIndexLock (1);
180                     rval = res_get (common_resource, "commitEnable");
181                     if (rval && atoi (rval))
182                         bf_cache (1);
183
184                     if (bf_commitExists ())
185                     {
186                         logf (LOG_LOG, "Commit start");
187                         zebraIndexLockMsg ("c");
188                         zebraIndexWait (1);
189                         logf (LOG_LOG, "Commit execute");
190                         bf_commitExec ();
191                         zebraIndexLockMsg ("d");
192                         zebraIndexWait (0);
193                         logf (LOG_LOG, "Commit clean");
194                         bf_commitClean ();
195                     }
196                     else
197                         logf (LOG_LOG, "Nothing to commit");
198                 }
199                 else if (!strcmp (arg, "stat") || !strcmp (arg, "status"))
200                 {
201                     zebraIndexLock (0);
202                     bf_cache (0);
203                     rec_prstat ();
204                 }
205                 else if (!strcmp (arg, "cstat") || !strcmp (arg, "cstatus"))
206                 {
207                     zebraIndexLock (1);
208                     rval = res_get (common_resource, "commitEnable");
209                     if (rval && atoi(rval))
210                     {
211                         bf_cache (1);
212                         zebraIndexLockMsg ("r");
213                     }
214                     rec_prstat ();
215                 }
216                 else
217                 {
218                     logf (LOG_FATAL, "Unknown command: %s", arg);
219                     exit (1);
220                 }
221             }
222             else
223             {
224                 struct recordGroup rGroup;
225
226                 zebraIndexLock (0);
227                 rval = res_get (common_resource, "commitEnable");
228                 if (rval && atoi(rval))
229                 {
230                     bf_cache (1);
231                     zebraIndexLockMsg ("r");
232                 }
233                 else
234                     zebraIndexLockMsg ("w");
235                 zebraIndexWait (0);
236
237                 memcpy (&rGroup, &rGroupDef, sizeof(rGroup));
238                 key_open (mem_max);
239                 rGroup.path = arg;
240                 if (cmd == 'u')
241                 {
242                     logf (LOG_LOG, "Updating %s", rGroup.path);
243                     repositoryUpdate (&rGroup);
244                 }
245                 else if (cmd == 'd')
246                 {
247                     logf (LOG_LOG, "Deleting %s", rGroup.path);
248                     repositoryDelete (&rGroup);
249                 }
250                 cmd = 0;
251                 nsections = key_close ();
252                 if (nsections)
253                 {
254                     logf (LOG_LOG, "Merging with index");
255                     key_input (FNAME_WORD_DICT, FNAME_WORD_ISAM, nsections,
256                                60);
257                 }
258             }
259         }
260         else if (ret == 'v')
261         {
262             log_init (log_mask_str(arg), prog, NULL);
263         }
264         else if (ret == 'm')
265         {
266             mem_max = 1024*1024*atoi(arg);
267         }
268         else if (ret == 'd')
269         {
270             rGroupDef.databaseName = arg;
271         }
272         else if (ret == 'g')
273         {
274             rGroupDef.groupName = arg;
275         }
276         else if (ret == 'c')
277             configName = arg;
278         else if (ret == 't')
279             rGroupDef.recordType = arg;
280         else
281         {
282             logf (LOG_FATAL, "Unknown option '-%s'", arg);
283             exit (1);
284         }
285     }
286     zebraIndexUnlock ();
287     exit (0);
288 }
289