1 /* $Id: retrieve.c,v 1.52 2006-11-16 11:10:46 adam Exp $
2 Copyright (C) 1995-2006
5 This file is part of the Zebra server.
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
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
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
36 #include <yaz/diagbib1.h>
42 static int zebra_create_record_stream(ZebraHandle zh,
44 struct ZebraRecStream *stream){
46 RecordAttr *recordAttr = rec_init_attr(zh->reg->zei, *rec);
48 if ((*rec)->size[recInfo_storeData] > 0){
49 zebra_create_stream_mem(stream, (*rec)->info[recInfo_storeData],
50 (*rec)->size[recInfo_storeData]);
56 if (zh->path_reg && !yaz_is_abspath((*rec)->info[recInfo_filename])){
57 strcpy(full_rep, zh->path_reg);
58 strcat(full_rep, "/");
59 strcat(full_rep, (*rec)->info[recInfo_filename]);
62 strcpy(full_rep, (*rec)->info[recInfo_filename]);
64 if ((fd = open (full_rep, O_BINARY|O_RDONLY)) == -1){
65 yaz_log (YLOG_WARN|YLOG_ERRNO, "Retrieve fail; missing file: %s",
70 zebra_create_stream_fd(stream, fd, recordAttr->recordOffset);
77 static void parse_zebra_elem(const char *elem,
78 const char **index, size_t *index_len,
79 const char **type, size_t *type_len)
89 const char *cp = strchr(elem, ':');
91 if (!cp) /* no colon */
94 *index_len = strlen(elem);
96 else if (cp[1] == '\0') /* 'index:' */
99 *index_len = cp - elem;
104 *index_len = cp - elem;
106 *type_len = strlen(cp+1);
112 int zebra_special_index_fetch(ZebraHandle zh, SYSNO sysno, ODR odr,
114 const char *elemsetname,
115 oid_value input_format,
116 oid_value *output_format,
117 char **rec_bufp, int *rec_lenp)
119 const char *retrieval_index;
120 size_t retrieval_index_len;
121 const char *retrieval_type;
122 size_t retrieval_type_len;
124 zebra_rec_keys_t keys;
126 /* only accept XML and SUTRS requests */
127 if (input_format != VAL_TEXT_XML
128 && input_format != VAL_SUTRS){
129 yaz_log(YLOG_WARN, "unsupported format for element set zebra::%s",
131 *output_format = VAL_NONE;
132 return YAZ_BIB1_NO_SYNTAXES_AVAILABLE_FOR_THIS_REQUEST;
135 parse_zebra_elem(elemsetname,
136 &retrieval_index, &retrieval_index_len,
137 &retrieval_type, &retrieval_type_len);
139 if (retrieval_type_len != 0 && retrieval_type_len != 1)
141 return YAZ_BIB1_SPECIFIED_ELEMENT_SET_NAME_NOT_VALID_FOR_SPECIFIED_;
144 if (retrieval_index_len)
146 char retrieval_index_cstr[256];
148 if (retrieval_index_len < sizeof(retrieval_index_cstr) -1)
150 memcpy(retrieval_index_cstr, retrieval_index, retrieval_index_len);
151 retrieval_index_cstr[retrieval_index_len] = '\0';
153 if (zebraExplain_lookup_attr_str(zh->reg->zei,
154 zinfo_index_category_index,
155 (retrieval_type_len == 0 ? -1 :
157 retrieval_index_cstr) == -1)
159 return YAZ_BIB1_SPECIFIED_ELEMENT_SET_NAME_NOT_VALID_FOR_SPECIFIED_;
164 keys = zebra_rec_keys_open();
165 zebra_rec_keys_set_buf(keys, rec->info[recInfo_delKeys],
166 rec->size[recInfo_delKeys], 0);
168 wrbuf = wrbuf_alloc();
169 if (zebra_rec_keys_rewind(keys)){
172 struct it_key key_in;
174 if (input_format == VAL_TEXT_XML){
175 *output_format = VAL_TEXT_XML;
176 /*wrbuf_printf(wrbuf,
177 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");*/
181 "\"http://www.indexdata.com/zebra/\""
182 " sysno=\"" ZINT_FORMAT "\""
183 " set=\"zebra::index::%s/\">\n",
186 else if (input_format == VAL_SUTRS)
187 *output_format = VAL_SUTRS;
190 while(zebra_rec_keys_read(keys, &str, &slen, &key_in)){
192 int ord = CAST_ZINT_TO_INT(key_in.mem[0]);
195 const char *string_index = 0;
196 size_t string_index_len;
197 char dst_buf[IT_MAX_WORD];
199 zebraExplain_lookup_ord(zh->reg->zei, ord, &index_type, &db,
201 string_index_len = strlen(string_index);
202 if (retrieval_index == 0
203 || (string_index_len == retrieval_index_len
204 && !memcmp(string_index, retrieval_index,
207 if (retrieval_type == 0
208 || (retrieval_type_len == 1
209 && retrieval_type[0] == index_type)){
211 if (input_format == VAL_TEXT_XML){
212 wrbuf_printf(wrbuf, " <index name=\"%s\"",
215 wrbuf_printf(wrbuf, " type=\"%c\"", index_type);
217 wrbuf_printf(wrbuf, " seq=\"" ZINT_FORMAT "\">",
218 key_in.mem[key_in.len -1]);
220 zebra_term_untrans(zh, index_type, dst_buf, str);
221 wrbuf_xmlputs(wrbuf, dst_buf);
222 wrbuf_printf(wrbuf, "</index>\n");
224 else if (input_format == VAL_SUTRS){
225 wrbuf_printf(wrbuf, "%s ", string_index);
227 wrbuf_printf(wrbuf, "%c", index_type);
229 for (i = 1; i < key_in.len; i++)
230 wrbuf_printf(wrbuf, " " ZINT_FORMAT,
233 zebra_term_untrans(zh, index_type, dst_buf, str);
234 wrbuf_printf(wrbuf, " %s", dst_buf);
236 wrbuf_printf(wrbuf, "\n");
241 if (input_format == VAL_TEXT_XML)
242 wrbuf_printf(wrbuf, "</record>\n");
245 *rec_lenp = wrbuf_len(wrbuf);
246 *rec_bufp = odr_malloc(odr, *rec_lenp);
247 memcpy(*rec_bufp, wrbuf_buf(wrbuf), *rec_lenp);
248 wrbuf_free(wrbuf, 1);
249 zebra_rec_keys_close(keys);
254 int zebra_special_fetch(ZebraHandle zh, SYSNO sysno, ODR odr,
255 const char *elemsetname,
256 oid_value input_format,
257 oid_value *output_format,
258 char **rec_bufp, int *rec_lenp)
262 /* only accept XML and SUTRS requests */
263 if (input_format != VAL_TEXT_XML
264 && input_format != VAL_SUTRS){
265 yaz_log(YLOG_WARN, "unsupported format for element set zebra::%s",
267 return YAZ_BIB1_NO_SYNTAXES_AVAILABLE_FOR_THIS_REQUEST;
270 /* processing zebra::meta::sysno elemset without fetching binary data */
271 if (elemsetname && 0 == strcmp(elemsetname, "meta::sysno"))
274 if (input_format == VAL_SUTRS){
275 sprintf(rec_str, ZINT_FORMAT, sysno);
276 *output_format = VAL_SUTRS;
278 else if (input_format == VAL_TEXT_XML){
279 sprintf(rec_str, "<record xmlns="
280 "\"http://www.indexdata.com/zebra/\""
281 " sysno=\"" ZINT_FORMAT "\""
282 " set=\"zebra::%s\"/>\n",
284 *output_format = VAL_TEXT_XML;
286 *rec_lenp = strlen(rec_str);
288 *rec_bufp = odr_strdup(odr, rec_str);
291 return YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS;
295 /* fetching binary record up for all other display elementsets */
296 rec = rec_get(zh->reg->records, sysno);
298 yaz_log(YLOG_WARN, "rec_get fail on sysno=" ZINT_FORMAT, sysno);
299 return YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS;
302 /* processing special elementsetnames zebra::index:: */
303 if (elemsetname && 0 == strncmp(elemsetname, "index::", 7)){
305 int ret = zebra_special_index_fetch(zh, sysno, odr, rec,
307 input_format, output_format,
314 /* processing special elementsetnames zebra::data */
315 if (elemsetname && 0 == strcmp(elemsetname, "data")){
316 struct ZebraRecStream stream;
317 RecordAttr *recordAttr = rec_init_attr(zh->reg->zei, rec);
318 zebra_create_record_stream(zh, &rec, &stream);
319 *output_format = input_format;
320 *rec_lenp = recordAttr->recordSize;
321 *rec_bufp = (char *) odr_malloc(odr, *rec_lenp);
322 stream.readf(&stream, *rec_bufp, *rec_lenp);
323 stream.destroy(&stream);
330 return YAZ_BIB1_SPECIFIED_ELEMENT_SET_NAME_NOT_VALID_FOR_SPECIFIED_;
334 int zebra_record_fetch(ZebraHandle zh, SYSNO sysno, int score,
335 zebra_snippets *hit_snippet, ODR odr,
336 oid_value input_format, Z_RecordComposition *comp,
337 oid_value *output_format,
338 char **rec_bufp, int *rec_lenp, char **basenamep,
342 char *fname, *file_type, *basename;
343 const char *elemsetname;
344 struct ZebraRecStream stream;
345 RecordAttr *recordAttr;
351 elemsetname = yaz_get_esn(comp);
353 /* processing zebra special elementset names of form 'zebra:: */
354 /* SUGGESTION: do not check elemset nema here, buuuut ... */
355 if (elemsetname && 0 == strncmp(elemsetname, "zebra::", 7))
356 return zebra_special_fetch(zh, sysno, odr,
358 input_format, output_format,
362 /* processing all other element set names */
363 rec = rec_get(zh->reg->records, sysno);
366 yaz_log(YLOG_WARN, "rec_get fail on sysno=" ZINT_FORMAT, sysno);
368 return YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS;
372 recordAttr = rec_init_attr(zh->reg->zei, rec);
374 file_type = rec->info[recInfo_fileType];
375 fname = rec->info[recInfo_filename];
376 basename = rec->info[recInfo_databaseName];
377 *basenamep = (char *) odr_malloc (odr, strlen(basename)+1);
378 strcpy (*basenamep, basename);
380 yaz_log(YLOG_DEBUG, "retrieve localno=" ZINT_FORMAT " score=%d",
383 zebra_create_record_stream(zh, &rec, &stream);
387 zebra_snippets *snippet;
388 zebra_rec_keys_t reckeys = zebra_rec_keys_open();
390 struct recRetrieveCtrl retrieveCtrl;
392 retrieveCtrl.stream = &stream;
393 retrieveCtrl.fname = fname;
394 retrieveCtrl.localno = sysno;
395 retrieveCtrl.staticrank = recordAttr->staticrank;
396 retrieveCtrl.score = score;
397 retrieveCtrl.recordSize = recordAttr->recordSize;
398 retrieveCtrl.odr = odr;
399 retrieveCtrl.input_format = retrieveCtrl.output_format = input_format;
400 retrieveCtrl.comp = comp;
401 retrieveCtrl.encoding = zh->record_encoding;
402 retrieveCtrl.diagnostic = 0;
403 retrieveCtrl.addinfo = 0;
404 retrieveCtrl.dh = zh->reg->dh;
405 retrieveCtrl.res = zh->res;
406 retrieveCtrl.rec_buf = 0;
407 retrieveCtrl.rec_len = -1;
408 retrieveCtrl.hit_snippet = hit_snippet;
409 retrieveCtrl.doc_snippet = zebra_snippets_create();
411 zebra_rec_keys_set_buf(reckeys,
412 rec->info[recInfo_delKeys],
413 rec->size[recInfo_delKeys],
415 zebra_rec_keys_to_snippets(zh, reckeys, retrieveCtrl.doc_snippet);
416 zebra_rec_keys_close(reckeys);
419 /* for debugging purposes */
420 yaz_log(YLOG_LOG, "DOC SNIPPET:");
421 zebra_snippets_log(retrieveCtrl.doc_snippet, YLOG_LOG);
422 yaz_log(YLOG_LOG, "HIT SNIPPET:");
423 zebra_snippets_log(retrieveCtrl.hit_snippet, YLOG_LOG);
425 snippet = zebra_snippets_window(retrieveCtrl.doc_snippet,
426 retrieveCtrl.hit_snippet,
429 /* for debugging purposes */
430 yaz_log(YLOG_LOG, "WINDOW SNIPPET:");
431 zebra_snippets_log(snippet, YLOG_LOG);
434 /* SUGGESTION: do not check elemset name here, buuuut ...
435 add another recType Struct with zebra internal stuff here,
436 which overrides the Alvis/GRS-1/Safari filters ....
438 if (!(rt = recType_byName(zh->reg->recTypes, zh->res,
439 file_type, &clientData)))
441 return_code = YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS;
445 /* SUGGESTION: do not check elemset name here, buuuut ...
446 add another recType Struct with zebra internal stuff here,
447 which overrides the Alvis/GRS-1/Safari filters ....
448 (*rt->retrieve) method to make the correct encoded, etc, retrieval,
449 where all needed info already is found in the &retrieveCtr
450 parameter. This way, we do not need to re-code/dublicate a lot of
453 (*rt->retrieve)(clientData, &retrieveCtrl);
454 return_code = retrieveCtrl.diagnostic;
456 *output_format = retrieveCtrl.output_format;
457 *rec_bufp = (char *) retrieveCtrl.rec_buf;
458 *rec_lenp = retrieveCtrl.rec_len;
459 *addinfo = retrieveCtrl.addinfo;
461 /* another SUGGESTION: throw out all this snippet stuff in this
462 file, and do it correctly - either inside filters, or in another
463 new (*rt->retrieve)(clientData, &retrieveCtrl); type 'snippet'
466 zebra_snippets_destroy(snippet);
467 zebra_snippets_destroy(retrieveCtrl.doc_snippet);
470 stream.destroy(&stream);
479 * indent-tabs-mode: nil
481 * vim: shiftwidth=4 tabstop=8 expandtab