Scan added. 'occurrences' in scan entries not set yet.
[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.11  1995-10-06 10:43:57  adam
8  * Scan added. 'occurrences' in scan entries not set yet.
9  *
10  * Revision 1.10  1995/10/02  16:43:32  quinn
11  * Set default resulting record type in fetch.
12  *
13  * Revision 1.9  1995/10/02  15:18:52  adam
14  * New member in recRetrieveCtrl: diagnostic.
15  *
16  * Revision 1.8  1995/09/28  09:19:47  adam
17  * xfree/xmalloc used everywhere.
18  * Extract/retrieve method seems to work for text records.
19  *
20  * Revision 1.7  1995/09/27  16:17:32  adam
21  * More work on retrieve.
22  *
23  * Revision 1.6  1995/09/08  08:53:22  adam
24  * Record buffer maintained in server_info.
25  *
26  * Revision 1.5  1995/09/06  16:11:18  adam
27  * Option: only one word key per file.
28  *
29  * Revision 1.4  1995/09/06  10:33:04  adam
30  * More work on present. Some log messages removed.
31  *
32  * Revision 1.3  1995/09/05  15:28:40  adam
33  * More work on search engine.
34  *
35  * Revision 1.2  1995/09/04  12:33:43  adam
36  * Various cleanup. YAZ util used instead.
37  *
38  * Revision 1.1  1995/09/04  09:10:41  adam
39  * More work on index add/del/update.
40  * Merge sort implemented.
41  * Initial work on z39 server.
42  *
43  */
44 #include <stdio.h>
45 #include <assert.h>
46 #include <unistd.h>
47 #include <fcntl.h>
48
49 #include <recctrl.h>
50 #include <dmalloc.h>
51 #include "zserver.h"
52
53 ZServerInfo server_info;
54
55 bend_initresult *bend_init (bend_initrequest *q)
56 {
57     static bend_initresult r;
58     static char *name = "zserver";
59
60     r.errcode = 0;
61     r.errstring = 0;
62     r.handle = name;
63
64     server_info.sets = NULL;
65     if (!(server_info.sys_idx_fd = open (FNAME_SYS_IDX, O_RDONLY)))
66     {
67         r.errcode = 1;
68         r.errstring = "dict_open fail: filedict";
69         return &r;
70     }
71     if (!(server_info.fileDict = dict_open (FNAME_FILE_DICT, 10, 0)))
72     {
73         r.errcode = 1;
74         r.errstring = "dict_open fail: filedict";
75         return &r;
76     }    
77     if (!(server_info.wordDict = dict_open (FNAME_WORD_DICT, 40, 0)))
78     {
79         dict_close (server_info.fileDict);
80         r.errcode = 1;
81         r.errstring = "dict_open fail: worddict";
82         return &r;
83     }    
84     if (!(server_info.wordIsam = is_open (FNAME_WORD_ISAM, key_compare, 0,
85                                           sizeof (struct it_key))))
86     {
87         dict_close (server_info.wordDict);
88         dict_close (server_info.fileDict);
89         r.errcode = 1;
90         r.errstring = "is_open fail: wordisam";
91         return &r;
92     }
93     server_info.recordBuf = NULL;
94     server_info.odr = odr_createmem (ODR_ENCODE);
95     return &r;
96 }
97
98 bend_searchresult *bend_search (void *handle, bend_searchrequest *q, int *fd)
99 {
100     static bend_searchresult r;
101
102     r.errcode = 0;
103     r.errstring = 0;
104     r.hits = 0;
105
106     switch (q->query->which)
107     {
108     case Z_Query_type_1:
109         r.errcode = rpn_search (&server_info, q->query->u.type_1,
110                                 q->num_bases, q->basenames, q->setname,
111                                 &r.hits);
112         break;
113     default:
114         r.errcode = 107;
115     }
116     return &r;
117 }
118
119 static int record_read (int fd, char *buf, size_t count)
120 {
121     return read (fd, buf, count);
122 }
123
124 static int record_fetch (ZServerInfo *zi, int sysno, ODR stream,
125                           oid_value input_format, oid_value *output_format,
126                           char **rec_bufp, int *rec_lenp)
127 {
128     char record_info[SYS_IDX_ENTRY_LEN];
129     char *fname, *file_type;
130     RecType rt;
131     struct recRetrieveCtrl retrieveCtrl;
132
133     if (lseek (zi->sys_idx_fd, sysno * SYS_IDX_ENTRY_LEN,
134                SEEK_SET) == -1)
135     {
136         logf (LOG_FATAL|LOG_ERRNO, "Retrieve: lseek of sys_idx");
137         exit (1);
138     }
139     if (read (zi->sys_idx_fd, record_info, SYS_IDX_ENTRY_LEN) == -1)
140     {
141         logf (LOG_FATAL|LOG_ERRNO, "Retrieve: read of sys_idx");
142         exit (1);
143     }
144     file_type = record_info;
145     fname = record_info + strlen(record_info) + 1;
146     if (!(rt = recType_byName (file_type)))
147     {
148         logf (LOG_FATAL|LOG_ERRNO, "Retrieve: Cannot handle type %s", 
149               file_type);
150         exit (1);
151     }
152     if ((retrieveCtrl.fd = open (fname, O_RDONLY)) == -1)
153     {
154         logf (LOG_FATAL|LOG_ERRNO, "Retrieve: Open record file %s", fname);
155         exit (1);
156     }
157     retrieveCtrl.odr = stream;
158     retrieveCtrl.readf = record_read;
159     retrieveCtrl.input_format = retrieveCtrl.output_format = input_format;
160     retrieveCtrl.diagnostic = 0;
161     (*rt->retrieve)(&retrieveCtrl);
162     *output_format = retrieveCtrl.output_format;
163     *rec_bufp = retrieveCtrl.rec_buf;
164     *rec_lenp = retrieveCtrl.rec_len;
165     close (retrieveCtrl.fd);
166     return retrieveCtrl.diagnostic;
167 }
168
169 bend_fetchresult *bend_fetch (void *handle, bend_fetchrequest *q, int *num)
170 {
171     static bend_fetchresult r;
172     int positions[2];
173     ZServerSetSysno *records;
174
175     r.errstring = 0;
176     r.last_in_set = 0;
177     r.basename = "base";
178
179     xfree (server_info.recordBuf);
180     server_info.recordBuf = NULL;
181     positions[0] = q->number;
182     records = resultSetSysnoGet (&server_info, q->setname, 1, positions);
183     if (!records)
184     {
185         logf (LOG_DEBUG, "resultSetRecordGet, error");
186         r.errcode = 13;
187         return &r;
188     }
189     if (!records[0].sysno)
190     {
191         r.errcode = 13;
192         logf (LOG_DEBUG, "Out of range. pos=%d", q->number);
193         return &r;
194     }
195     r.errcode = record_fetch (&server_info, records[0].sysno, q->stream,
196                               q->format, &r.format, &r.record, &r.len);
197     return &r;
198 }
199
200 bend_deleteresult *bend_delete (void *handle, bend_deleterequest *q, int *num)
201 {
202     return 0;
203 }
204
205 bend_scanresult *bend_scan (void *handle, bend_scanrequest *q, int *num)
206 {
207     static bend_scanresult r;
208
209     odr_reset (server_info.odr);
210
211     r.term_position = q->term_position;
212     r.num_entries = q->num_entries;
213     r.errcode = rpn_scan (&server_info, server_info.odr, q->term,
214                           &r.term_position,
215                           &r.num_entries, &r.entries);
216     r.errstring = 0;
217     return &r;
218 }
219
220 void bend_close (void *handle)
221 {
222     dict_close (server_info.fileDict);
223     dict_close (server_info.wordDict);
224     is_close (server_info.wordIsam);
225     close (server_info.sys_idx_fd);
226     xfree (server_info.recordBuf);
227     server_info.recordBuf = NULL;
228     return;
229 }
230
231 int main (int argc, char **argv)
232 {
233     char *base_name = "base";
234
235     if (!(common_resource = res_open (base_name)))
236     {
237         logf (LOG_FATAL, "Cannot open resource `%s'", base_name);
238         exit (1);
239     }
240     return statserv_main (argc, argv);
241 }