Renamed function zebra_snippets_rec_keys to zebra_rec_keys_to_snippets.
[idzebra-moved-to-github.git] / index / retrieve.c
1 /* $Id: retrieve.c,v 1.46 2006-11-09 14:39:24 adam Exp $
2    Copyright (C) 1995-2006
3    Index Data ApS
4
5 This file is part of the Zebra server.
6
7 Zebra is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20
21 */
22
23 #include <stdio.h>
24 #include <assert.h>
25
26 #include <fcntl.h>
27 #ifdef WIN32
28 #include <io.h>
29 #include <process.h>
30 #endif
31 #if HAVE_UNISTD_H
32 #include <unistd.h>
33 #endif
34
35 #include "index.h"
36 #include <yaz/diagbib1.h>
37 #include <direntz.h>
38
39 int zebra_storedata_fetch(ZebraHandle zh, SYSNO sysno, ODR odr,
40                           Record rec,
41                           const char *element_set,
42                           oid_value input_format,
43                           oid_value *output_format,
44                           char **rec_bufp, int *rec_lenp)
45 {
46     WRBUF wrbuf = wrbuf_alloc();
47     zebra_rec_keys_t keys = zebra_rec_keys_open();
48     zebra_rec_keys_set_buf(keys,
49                            rec->info[recInfo_delKeys],
50                            rec->size[recInfo_delKeys],
51                            0);
52     if (zebra_rec_keys_rewind(keys))
53     {
54         size_t slen;
55         const char *str;
56         struct it_key key_in;
57         while(zebra_rec_keys_read(keys, &str, &slen, &key_in))
58         {
59             int i;
60             int ord = CAST_ZINT_TO_INT(key_in.mem[0]);
61             int index_type;
62             const char *db = 0;
63             const char *string_index = 0;
64             char dst_buf[IT_MAX_WORD];
65             
66             zebraExplain_lookup_ord(zh->reg->zei, ord, &index_type, &db,
67                                     &string_index);
68             
69             if (string_index)
70                 wrbuf_printf(wrbuf, "%s", string_index);
71             
72             zebra_term_untrans(zh, index_type, dst_buf, str);
73             wrbuf_printf(wrbuf, " %s", dst_buf);
74             
75             for (i = 1; i < key_in.len; i++)
76                 wrbuf_printf(wrbuf, " " ZINT_FORMAT, key_in.mem[i]);
77             wrbuf_printf(wrbuf, "\n");
78             
79         }
80     }
81     *output_format = VAL_SUTRS;
82     *rec_lenp = wrbuf_len(wrbuf);
83     *rec_bufp = odr_malloc(odr, *rec_lenp);
84     memcpy(*rec_bufp, wrbuf_buf(wrbuf), *rec_lenp);
85     wrbuf_free(wrbuf, 1);
86     zebra_rec_keys_close(keys);
87     return 0;
88 }
89                           
90 int zebra_record_fetch(ZebraHandle zh, SYSNO sysno, int score,
91                        zebra_snippets *hit_snippet, ODR odr,
92                        oid_value input_format, Z_RecordComposition *comp,
93                        oid_value *output_format,
94                        char **rec_bufp, int *rec_lenp, char **basenamep,
95                        char **addinfo)
96 {
97     Record rec;
98     char *fname, *file_type, *basename;
99     struct ZebraRecStream stream;
100     RecordAttr *recordAttr;
101     void *clientData;
102     int raw_mode = 0;
103     int return_code = 0;
104
105     *basenamep = 0;
106     *addinfo = 0;
107     if (comp && comp->which == Z_RecordComp_simple &&
108         comp->u.simple->which == Z_ElementSetNames_generic && 
109         !strcmp (comp->u.simple->u.generic, "_sysno_"))
110     {
111         char rec_str[60];
112         sprintf(rec_str, ZINT_FORMAT, sysno);
113         *output_format = VAL_SUTRS;
114         *rec_lenp = strlen(rec_str);
115         *rec_bufp = odr_strdup(odr, rec_str);
116         return 0;
117     }
118     rec = rec_get (zh->reg->records, sysno);
119     if (!rec)
120     {
121         yaz_log (YLOG_DEBUG, "rec_get fail on sysno=" ZINT_FORMAT, sysno);
122         *basenamep = 0;
123         return YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS;
124     }
125     recordAttr = rec_init_attr (zh->reg->zei, rec);
126
127     file_type = rec->info[recInfo_fileType];
128     fname = rec->info[recInfo_filename];
129     basename = rec->info[recInfo_databaseName];
130     *basenamep = (char *) odr_malloc (odr, strlen(basename)+1);
131     strcpy (*basenamep, basename);
132
133     if (comp && comp->which == Z_RecordComp_simple 
134         && comp->u.simple->which == Z_ElementSetNames_generic 
135         && strncmp(comp->u.simple->u.generic, "zebra:", 6) == 0)
136     {
137         int r = zebra_storedata_fetch(zh, sysno, odr, rec,
138                                       comp->u.simple->u.generic,
139                                       input_format, output_format,
140                                       rec_bufp, rec_lenp);
141
142         rec_free(&rec);
143         return r;
144     }
145
146     if (comp && comp->which == Z_RecordComp_simple &&
147         comp->u.simple->which == Z_ElementSetNames_generic && 
148         !strcmp (comp->u.simple->u.generic, "R"))
149     {
150         raw_mode = 1;
151     }
152     yaz_log (YLOG_DEBUG, "retrieve localno=" ZINT_FORMAT " score=%d",
153              sysno, score);
154     if (rec->size[recInfo_storeData] > 0)
155     {
156         zebra_create_stream_mem(&stream, rec->info[recInfo_storeData],
157                                 rec->size[recInfo_storeData]);
158     }
159     else
160     {
161         char full_rep[1024];
162         int fd;
163
164         if (zh->path_reg && !yaz_is_abspath (fname))
165         {
166             strcpy (full_rep, zh->path_reg);
167             strcat (full_rep, "/");
168             strcat (full_rep, fname);
169         }
170         else
171             strcpy (full_rep, fname);
172
173         if ((fd = open (full_rep, O_BINARY|O_RDONLY)) == -1)
174         {
175             yaz_log (YLOG_WARN|YLOG_ERRNO, "Retrieve fail; missing file: %s",
176                   full_rep);
177             rec_free(&rec);
178             return 14;
179         }
180         zebra_create_stream_fd(&stream, fd, recordAttr->recordOffset);
181     }
182
183     if (raw_mode)
184     {
185         *output_format = VAL_SUTRS;
186         *rec_lenp = recordAttr->recordSize;
187         *rec_bufp = (char *) odr_malloc(odr, *rec_lenp);
188         stream.readf(&stream, *rec_bufp, *rec_lenp);
189     }
190     else
191     {
192         /* snippets code */
193         zebra_snippets *snippet;
194         zebra_rec_keys_t reckeys = zebra_rec_keys_open();
195         RecType rt;
196         struct recRetrieveCtrl retrieveCtrl;
197
198         retrieveCtrl.stream = &stream;
199         retrieveCtrl.fname = fname;
200         retrieveCtrl.localno = sysno;
201         retrieveCtrl.staticrank = recordAttr->staticrank;
202         retrieveCtrl.score = score;
203         retrieveCtrl.recordSize = recordAttr->recordSize;
204         retrieveCtrl.odr = odr;
205         retrieveCtrl.input_format = retrieveCtrl.output_format = input_format;
206         retrieveCtrl.comp = comp;
207         retrieveCtrl.encoding = zh->record_encoding;
208         retrieveCtrl.diagnostic = 0;
209         retrieveCtrl.addinfo = 0;
210         retrieveCtrl.dh = zh->reg->dh;
211         retrieveCtrl.res = zh->res;
212         retrieveCtrl.rec_buf = 0;
213         retrieveCtrl.rec_len = -1;
214         retrieveCtrl.hit_snippet = hit_snippet;
215         retrieveCtrl.doc_snippet = zebra_snippets_create();
216
217         zebra_rec_keys_set_buf(reckeys,
218                                rec->info[recInfo_delKeys],
219                                rec->size[recInfo_delKeys], 
220                                0);
221         zebra_rec_keys_to_snippets(zh, reckeys, retrieveCtrl.doc_snippet);
222         zebra_rec_keys_close(reckeys);
223
224 #if 0
225         /* for debugging purposes */
226         yaz_log(YLOG_LOG, "DOC SNIPPET:");
227         zebra_snippets_log(retrieveCtrl.doc_snippet, YLOG_LOG);
228         yaz_log(YLOG_LOG, "HIT SNIPPET:");
229         zebra_snippets_log(retrieveCtrl.hit_snippet, YLOG_LOG);
230 #endif
231         snippet = zebra_snippets_window(retrieveCtrl.doc_snippet,
232                                         retrieveCtrl.hit_snippet,
233                                         10);
234 #if 0
235         /* for debugging purposes */
236         yaz_log(YLOG_LOG, "WINDOW SNIPPET:");
237         zebra_snippets_log(snippet, YLOG_LOG);
238 #endif
239
240         if (!(rt = recType_byName (zh->reg->recTypes, zh->res,
241                                    file_type, &clientData)))
242         {
243             return_code = YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS;
244         }
245         else
246         {
247             (*rt->retrieve)(clientData, &retrieveCtrl);
248             return_code = retrieveCtrl.diagnostic;
249
250             *output_format = retrieveCtrl.output_format;
251             *rec_bufp = (char *) retrieveCtrl.rec_buf;
252             *rec_lenp = retrieveCtrl.rec_len;
253             *addinfo = retrieveCtrl.addinfo;
254         }
255         zebra_snippets_destroy(snippet);
256         zebra_snippets_destroy(retrieveCtrl.doc_snippet);
257     }
258     stream.destroy(&stream);
259     rec_free(&rec);
260
261     return return_code;
262 }
263
264 /*
265  * Local variables:
266  * c-basic-offset: 4
267  * indent-tabs-mode: nil
268  * End:
269  * vim: shiftwidth=4 tabstop=8 expandtab
270  */
271