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