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