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