Changes to support element set names and espec1
[idzebra-moved-to-github.git] / index / zserver.c
1 /*
2  * Copyright (C) 1994-1995, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: zserver.c,v $
7  * Revision 1.18  1995-10-16 14:03:09  quinn
8  * Changes to support element set names and espec1
9  *
10  * Revision 1.17  1995/10/16  09:32:40  adam
11  * More work on relational op.
12  *
13  * Revision 1.16  1995/10/13  12:26:44  adam
14  * Optimization of truncation.
15  *
16  * Revision 1.15  1995/10/12  12:40:55  adam
17  * Bug fixes in rpn_prox.
18  *
19  * Revision 1.14  1995/10/09  16:18:37  adam
20  * Function dict_lookup_grep got extra client data parameter.
21  *
22  * Revision 1.13  1995/10/06  14:38:00  adam
23  * New result set method: r_score.
24  * Local no (sysno) and score is transferred to retrieveCtrl.
25  *
26  * Revision 1.12  1995/10/06  13:52:06  adam
27  * Bug fixes. Handler may abort further scanning.
28  *
29  * Revision 1.11  1995/10/06  10:43:57  adam
30  * Scan added. 'occurrences' in scan entries not set yet.
31  *
32  * Revision 1.10  1995/10/02  16:43:32  quinn
33  * Set default resulting record type in fetch.
34  *
35  * Revision 1.9  1995/10/02  15:18:52  adam
36  * New member in recRetrieveCtrl: diagnostic.
37  *
38  * Revision 1.8  1995/09/28  09:19:47  adam
39  * xfree/xmalloc used everywhere.
40  * Extract/retrieve method seems to work for text records.
41  *
42  * Revision 1.7  1995/09/27  16:17:32  adam
43  * More work on retrieve.
44  *
45  * Revision 1.6  1995/09/08  08:53:22  adam
46  * Record buffer maintained in server_info.
47  *
48  * Revision 1.5  1995/09/06  16:11:18  adam
49  * Option: only one word key per file.
50  *
51  * Revision 1.4  1995/09/06  10:33:04  adam
52  * More work on present. Some log messages removed.
53  *
54  * Revision 1.3  1995/09/05  15:28:40  adam
55  * More work on search engine.
56  *
57  * Revision 1.2  1995/09/04  12:33:43  adam
58  * Various cleanup. YAZ util used instead.
59  *
60  * Revision 1.1  1995/09/04  09:10:41  adam
61  * More work on index add/del/update.
62  * Merge sort implemented.
63  * Initial work on z39 server.
64  *
65  */
66 #include <stdio.h>
67 #include <assert.h>
68 #include <unistd.h>
69 #include <fcntl.h>
70
71 #include <recctrl.h>
72 #include <dmalloc.h>
73 #include "zserver.h"
74
75 ZServerInfo server_info;
76
77 bend_initresult *bend_init (bend_initrequest *q)
78 {
79     static bend_initresult r;
80     static char *name = "zserver";
81
82     r.errcode = 0;
83     r.errstring = 0;
84     r.handle = name;
85
86     logf (LOG_DEBUG, "bend_init");
87     server_info.sets = NULL;
88     if (!(server_info.sys_idx_fd = open (FNAME_SYS_IDX, O_RDONLY)))
89     {
90         logf (LOG_WARN|LOG_ERRNO, "sys_idx open fail");
91         r.errcode = 1;
92         r.errstring = "sys_idx open fail";
93         return &r;
94     }
95     if (!(server_info.fileDict = dict_open (FNAME_FILE_DICT, 10, 0)))
96     {
97         logf (LOG_WARN, "dict_open fail: fname dict");
98         r.errcode = 1;
99         r.errstring = "dict_open fail: fname dict";
100         return &r;
101     }    
102     if (!(server_info.wordDict = dict_open (FNAME_WORD_DICT, 40, 0)))
103     {
104         logf (LOG_WARN, "dict_open fail: word dict");
105         dict_close (server_info.fileDict);
106         r.errcode = 1;
107         r.errstring = "dict_open fail: word dict";
108         return &r;
109     }    
110     if (!(server_info.wordIsam = is_open (FNAME_WORD_ISAM, key_compare, 0,
111                                           sizeof (struct it_key))))
112     {
113         logf (LOG_WARN, "is_open fail: word isam");
114         dict_close (server_info.wordDict);
115         dict_close (server_info.fileDict);
116         r.errcode = 1;
117         r.errstring = "is_open fail: word isam";
118         return &r;
119     }
120     server_info.odr = odr_createmem (ODR_ENCODE);
121     return &r;
122 }
123
124 bend_searchresult *bend_search (void *handle, bend_searchrequest *q, int *fd)
125 {
126     static bend_searchresult r;
127
128     r.errcode = 0;
129     r.errstring = 0;
130     r.hits = 0;
131
132     odr_reset (server_info.odr);
133     server_info.errCode = 0;
134     switch (q->query->which)
135     {
136     case Z_Query_type_1:
137         r.errcode = rpn_search (&server_info, q->query->u.type_1,
138                                 q->num_bases, q->basenames, q->setname,
139                                 &r.hits);
140         break;
141     default:
142         r.errcode = 107;
143     }
144     return &r;
145 }
146
147 static int record_read (int fd, char *buf, size_t count)
148 {
149     return read (fd, buf, count);
150 }
151
152 static int record_fetch (ZServerInfo *zi, int sysno, int score, ODR stream,
153                           oid_value input_format, Z_RecordComposition *comp,
154                           oid_value *output_format, char **rec_bufp,
155                           int *rec_lenp)
156 {
157     char record_info[SYS_IDX_ENTRY_LEN];
158     char *fname, *file_type;
159     RecType rt;
160     struct recRetrieveCtrl retrieveCtrl;
161
162     if (lseek (zi->sys_idx_fd, sysno * SYS_IDX_ENTRY_LEN,
163                SEEK_SET) == -1)
164     {
165         logf (LOG_FATAL|LOG_ERRNO, "Retrieve: lseek of sys_idx");
166         exit (1);
167     }
168     if (read (zi->sys_idx_fd, record_info, SYS_IDX_ENTRY_LEN) == -1)
169     {
170         logf (LOG_FATAL|LOG_ERRNO, "Retrieve: read of sys_idx");
171         exit (1);
172     }
173     file_type = record_info;
174     fname = record_info + strlen(record_info) + 1;
175     if (!(rt = recType_byName (file_type)))
176     {
177         logf (LOG_FATAL|LOG_ERRNO, "Retrieve: Cannot handle type %s", 
178               file_type);
179         exit (1);
180     }
181     logf (LOG_DEBUG, "retrieve localno=%d score=%d", sysno, score);
182     if ((retrieveCtrl.fd = open (fname, O_RDONLY)) == -1)
183     {
184         char *msg = "Record doesn't exist";
185         logf (LOG_WARN|LOG_ERRNO, "Retrieve: Open record file %s", fname);
186         *output_format = VAL_SUTRS;
187         *rec_bufp = msg;
188         *rec_lenp = strlen (msg);
189         return 0;     /* or 14: System error in presenting records */
190     }
191     retrieveCtrl.localno = sysno;
192     retrieveCtrl.score = score;
193     retrieveCtrl.odr = stream;
194     retrieveCtrl.readf = record_read;
195     retrieveCtrl.input_format = retrieveCtrl.output_format = input_format;
196     retrieveCtrl.comp = comp;
197     retrieveCtrl.diagnostic = 0;
198     (*rt->retrieve)(&retrieveCtrl);
199     *output_format = retrieveCtrl.output_format;
200     *rec_bufp = retrieveCtrl.rec_buf;
201     *rec_lenp = retrieveCtrl.rec_len;
202     close (retrieveCtrl.fd);
203     return retrieveCtrl.diagnostic;
204 }
205
206 bend_fetchresult *bend_fetch (void *handle, bend_fetchrequest *q, int *num)
207 {
208     static bend_fetchresult r;
209     int positions[2];
210     ZServerSetSysno *records;
211
212     r.errstring = 0;
213     r.last_in_set = 0;
214     r.basename = "base";
215
216     odr_reset (server_info.odr);
217     server_info.errCode = 0;
218
219     positions[0] = q->number;
220     records = resultSetSysnoGet (&server_info, q->setname, 1, positions);
221     if (!records)
222     {
223         logf (LOG_DEBUG, "resultSetRecordGet, error");
224         r.errcode = 13;
225         return &r;
226     }
227     if (!records[0].sysno)
228     {
229         r.errcode = 13;
230         logf (LOG_DEBUG, "Out of range. pos=%d", q->number);
231         return &r;
232     }
233     r.errcode = record_fetch (&server_info, records[0].sysno,
234                               records[0].score, q->stream,
235                               q->format, q->comp, &r.format, &r.record, &r.len);
236     return &r;
237 }
238
239 bend_deleteresult *bend_delete (void *handle, bend_deleterequest *q, int *num)
240 {
241     return 0;
242 }
243
244 bend_scanresult *bend_scan (void *handle, bend_scanrequest *q, int *num)
245 {
246     static bend_scanresult r;
247     int status;
248
249     odr_reset (server_info.odr);
250     server_info.errCode = 0;
251
252     r.errstring = 0;
253     r.term_position = q->term_position;
254     r.num_entries = q->num_entries;
255     r.errcode = rpn_scan (&server_info, server_info.odr, q->term,
256                           &r.term_position,
257                           &r.num_entries, &r.entries, &status);
258     r.status = status;
259     return &r;
260 }
261
262 void bend_close (void *handle)
263 {
264     dict_close (server_info.fileDict);
265     dict_close (server_info.wordDict);
266     is_close (server_info.wordIsam);
267     close (server_info.sys_idx_fd);
268     return;
269 }
270
271 int main (int argc, char **argv)
272 {
273     char *base_name = "base";
274
275     if (!(common_resource = res_open (base_name)))
276     {
277         logf (LOG_FATAL, "Cannot open resource `%s'", base_name);
278         exit (1);
279     }
280     return statserv_main (argc, argv);
281 }