Minor changes.
[idzebra-moved-to-github.git] / index / zebraapi.c
1 /*
2  * Copyright (C) 1995-1998, Index Data ApS
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: zebraapi.c,v $
7  * Revision 1.8  1998-08-24 17:29:23  adam
8  * Minor changes.
9  *
10  * Revision 1.7  1998/06/24 12:16:13  adam
11  * Support for relations on text operands. Open range support in
12  * DFA module (i.e. [-j], [g-]).
13  *
14  * Revision 1.6  1998/06/22 11:36:47  adam
15  * Added authentication check facility to zebra.
16  *
17  * Revision 1.5  1998/06/13 00:14:08  adam
18  * Minor changes.
19  *
20  * Revision 1.4  1998/06/12 12:22:12  adam
21  * Work on Zebra API.
22  *
23  * Revision 1.3  1998/05/27 16:57:44  adam
24  * Zebra returns surrogate diagnostic for single records when
25  * appropriate.
26  *
27  * Revision 1.2  1998/05/20 10:12:19  adam
28  * Implemented automatic EXPLAIN database maintenance.
29  * Modified Zebra to work with ASN.1 compiled version of YAZ.
30  *
31  * Revision 1.1  1998/03/05 08:45:13  adam
32  * New result set model and modular ranking system. Moved towards
33  * descent server API. System information stored as "SGML" records.
34  *
35  */
36
37 #include <stdio.h>
38 #ifdef WINDOWS
39 #include <io.h>
40 #include <process.h>
41 #else
42 #include <unistd.h>
43 #endif
44
45 #include <diagbib1.h>
46 #include "zserver.h"
47
48 static int zebra_register_lock (ZebraHandle zh)
49 {
50     time_t lastChange;
51     int state = zebra_server_lock_get_state(zh, &lastChange);
52
53     switch (state)
54     {
55     case 'c':
56         state = 1;
57         break;
58     default:
59         state = 0;
60     }
61     zebra_server_lock (zh, state);
62 #if USE_TIMES
63     times (&zh->tms1);
64 #endif
65     if (zh->registerState == state)
66     {
67         if (zh->registerChange >= lastChange)
68             return 0;
69         logf (LOG_LOG, "Register completely updated since last access");
70     }
71     else if (zh->registerState == -1)
72         logf (LOG_LOG, "Reading register using state %d pid=%ld", state,
73               (long) getpid());
74     else
75         logf (LOG_LOG, "Register has changed state from %d to %d",
76               zh->registerState, state);
77     zh->registerChange = lastChange;
78     if (zh->records)
79     {
80         zebraExplain_close (zh->zei, 0, 0);
81         dict_close (zh->dict);
82         sortIdx_close (zh->sortIdx);
83         if (zh->isam)
84             is_close (zh->isam);
85         if (zh->isamc)
86             isc_close (zh->isamc);
87         rec_close (&zh->records);
88     }
89     bf_cache (zh->bfs, state ? res_get (zh->res, "shadow") : NULL);
90     zh->registerState = state;
91     zh->records = rec_open (zh->bfs, 0);
92     if (!(zh->dict = dict_open (zh->bfs, FNAME_DICT, 40, 0)))
93     {
94         logf (LOG_WARN, "dict_open");
95         return -1;
96     }
97     if (!(zh->sortIdx = sortIdx_open (zh->bfs, 0)))
98     {
99         logf (LOG_WARN, "sortIdx_open");
100         return -1;
101     }
102     zh->isam = NULL;
103     zh->isamc = NULL;
104     if (!res_get_match (zh->res, "isam", "i", NULL))
105     {
106         if (!(zh->isamc = isc_open (zh->bfs, FNAME_ISAMC,
107                                     0, key_isamc_m(zh->res))))
108         {
109             logf (LOG_WARN, "isc_open");
110             return -1;
111         }
112
113     }
114     else
115     {
116         if (!(zh->isam = is_open (zh->bfs, FNAME_ISAM, key_compare, 0,
117                                   sizeof (struct it_key), zh->res)))
118         {
119             logf (LOG_WARN, "is_open");
120             return -1;
121         }
122     }
123     zh->zei = zebraExplain_open (zh->records, zh->dh, zh->res, 0, 0, 0);
124
125     return 0;
126 }
127
128 static void zebra_register_unlock (ZebraHandle zh)
129 {
130     static int waitSec = -1;
131
132 #if USE_TIMES
133     times (&zh->tms2);
134     logf (LOG_LOG, "user/system: %ld/%ld",
135                         (long) (zh->tms2.tms_utime - zh->tms1.tms_utime),
136                         (long) (zh->tms2.tms_stime - zh->tms1.tms_stime));
137 #endif
138     if (waitSec == -1)
139     {
140         char *s = res_get (zh->res, "debugRequestWait");
141         if (s)
142             waitSec = atoi (s);
143         else
144             waitSec = 0;
145     }
146 #ifdef WINDOWS
147 #else
148     if (waitSec > 0)
149         sleep (waitSec);
150 #endif
151     if (zh->registerState != -1)
152         zebra_server_unlock (zh, zh->registerState);
153 }
154
155 ZebraHandle zebra_open (const char *configName)
156 {
157     ZebraHandle zh = xmalloc (sizeof(*zh));
158
159     if (!(zh->res = res_open (configName)))
160     {
161         logf (LOG_WARN, "Failed to read resources `%s'", configName);
162         return NULL;
163     }
164     zebra_server_lock_init (zh);
165     zh->dh = data1_create ();
166     zh->bfs = bfs_create (res_get (zh->res, "register"));
167     bf_lockDir (zh->bfs, res_get (zh->res, "lockDir"));
168     data1_set_tabpath (zh->dh, res_get(zh->res, "profilePath"));
169     zh->sets = NULL;
170     zh->registerState = -1;  /* trigger open of registers! */
171     zh->registerChange = 0;
172     
173     zh->records = NULL;
174     zh->zebra_maps = zebra_maps_open (zh->res);
175     zh->rank_classes = NULL;
176     zh->errCode = 0;
177     zh->errString = 0;
178     
179     zebraRankInstall (zh, rank1_class);
180
181     if (!res_get (zh->res, "passwd"))
182         zh->passwd_db = NULL;
183     else
184     {
185         zh->passwd_db = passwd_db_open ();
186         if (!zh->passwd_db)
187             logf (LOG_WARN|LOG_ERRNO, "passwd_db_open failed");
188         else
189             passwd_db_file (zh->passwd_db, res_get (zh->res, "passwd"));
190     }
191     return zh;
192 }
193
194 void zebra_close (ZebraHandle zh)
195 {
196     if (zh->records)
197     {
198         resultSetDestroy (zh);
199         zebraExplain_close (zh->zei, 0, 0);
200         dict_close (zh->dict);
201         sortIdx_close (zh->sortIdx);
202         if (zh->isam)
203             is_close (zh->isam);
204         if (zh->isamc)
205             isc_close (zh->isamc);
206         rec_close (&zh->records);
207         zebra_register_unlock (zh);
208     }
209     zebra_maps_close (zh->zebra_maps);
210     zebraRankDestroy (zh);
211     bfs_destroy (zh->bfs);
212     data1_destroy (zh->dh);
213     zebra_server_lock_destroy (zh);
214
215     if (zh->passwd_db)
216         passwd_db_close (zh->passwd_db);
217     res_close (zh->res);
218     xfree (zh);
219 }
220
221 void zebra_search_rpn (ZebraHandle zh, ODR stream,
222                        Z_RPNQuery *query, int num_bases, char **basenames, 
223                        const char *setname)
224 {
225     zebra_register_lock (zh);
226     zh->errCode = 0;
227     zh->errString = NULL;
228     zh->hits = 0;
229     rpn_search (zh, stream, query, num_bases, basenames, setname);
230     zebra_register_unlock (zh);
231 }
232
233 void zebra_records_retrieve (ZebraHandle zh, ODR stream,
234                              const char *setname, Z_RecordComposition *comp,
235                              oid_value input_format, int num_recs,
236                              ZebraRetrievalRecord *recs)
237 {
238     ZebraPosSet poset;
239     int i, *pos_array;
240
241     zh->errCode = 0;
242     zh->errString = NULL;
243     pos_array = xmalloc (num_recs * sizeof(*pos_array));
244     for (i = 0; i<num_recs; i++)
245         pos_array[i] = recs[i].position;
246
247     zebra_register_lock (zh);
248
249     poset = zebraPosSetCreate (zh, setname, num_recs, pos_array);
250     if (!poset)
251     {
252         logf (LOG_DEBUG, "zebraPosSetCreate error");
253         zh->errCode = 13;
254     }
255     else
256     {
257         for (i = 0; i<num_recs; i++)
258         {
259             if (!poset[i].sysno)
260             {
261                 zh->errCode = 13;
262                 logf (LOG_DEBUG, "Out of range. pos=%d", pos_array[i]);
263             }
264             else
265             {
266                 recs[i].errCode =
267                     zebra_record_fetch (zh, poset[i].sysno, poset[i].score,
268                                         stream, input_format, comp,
269                                         &recs[i].format, &recs[i].buf,
270                                         &recs[i].len,
271                                         &recs[i].base);
272                 recs[i].errString = NULL;
273             }
274         }
275         zebraPosSetDestroy (zh, poset, num_recs);
276     }
277     zebra_register_unlock (zh);
278     xfree (pos_array);
279 }
280
281 void zebra_scan (ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt,
282                  oid_value attributeset,
283                  int num_bases, char **basenames,
284                  int *position, int *num_entries, ZebraScanEntry **entries,
285                  int *is_partial)
286 {
287     zh->errCode = 0;
288     zh->errString = NULL;
289     zebra_register_lock (zh);
290     rpn_scan (zh, stream, zapt, attributeset,
291               num_bases, basenames, position,
292               num_entries, entries, is_partial);
293     zebra_register_unlock (zh);
294 }
295
296 void zebra_sort (ZebraHandle zh, ODR stream,
297                  int num_input_setnames, const char **input_setnames,
298                  const char *output_setname, Z_SortKeySpecList *sort_sequence,
299                  int *sort_status)
300 {
301     zh->errCode = 0;
302     zh->errString = NULL;
303     zebra_register_lock (zh);
304     resultSetSort (zh, stream, num_input_setnames, input_setnames,
305                    output_setname, sort_sequence, sort_status);
306     zebra_register_unlock (zh);
307 }
308
309 int zebra_errCode (ZebraHandle zh)
310 {
311     return zh->errCode;
312 }
313
314 const char *zebra_errString (ZebraHandle zh)
315 {
316     return diagbib1_str (zh->errCode);
317 }
318
319 char *zebra_errAdd (ZebraHandle zh)
320 {
321     return zh->errString;
322 }
323
324 int zebra_hits (ZebraHandle zh)
325 {
326     return zh->hits;
327 }
328
329 int zebra_auth (ZebraHandle zh, const char *user, const char *pass)
330 {
331     if (!zh->passwd_db || !passwd_db_auth (zh->passwd_db, user, pass))
332         return 0;
333     return 1;
334 }
335
336 void zebra_setDB (ZebraHandle zh, int num_bases, char **basenames)
337 {
338
339 }
340
341 void zebra_setRecordType (ZebraHandle zh, const char *type)
342 {
343
344 }
345
346 void zebra_setGroup (ZebraHandle zh, const char *group)
347 {
348
349 }
350
351 void zebra_admin (ZebraHandle zh, const char *command)
352 {
353
354 }