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