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