X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fseshigh.c;h=d357095a9386ba4bfe02792b43daff935278ec55;hp=25558230b3ef739c8f40f0fdf5b05c1ff199d7a9;hb=4b72516157f967c0bf70e1ca1e61e89a6c7daa5e;hpb=62d24093ae987d90e07a40a8d75f1338b5bbb14b diff --git a/src/seshigh.c b/src/seshigh.c index 2555823..d357095 100644 --- a/src/seshigh.c +++ b/src/seshigh.c @@ -1,5 +1,5 @@ /* This file is part of the YAZ toolkit. - * Copyright (C) 1995-2012 Index Data + * Copyright (C) 1995-2013 Index Data * See the file LICENSE for details. */ /** @@ -56,6 +56,7 @@ #include #endif +#include #include #include #include "eventl.h" @@ -639,23 +640,57 @@ static int retrieve_fetch(association *assoc, bend_fetch_rr *rr) rr->request_format = backend_syntax; } (*assoc->init->bend_fetch)(assoc->backend, rr); - if (rc && rr->record && rr->errcode == 0 && rr->len > 0) + if (rc && rr->record && rr->errcode == 0) { /* post conversion must take place .. */ WRBUF output_record = wrbuf_alloc(); - int r = yaz_record_conv_record(rc, rr->record, rr->len, output_record); - if (r) - { - const char *details = yaz_record_conv_get_error(rc); - rr->errcode = YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS; - if (details) - rr->errstring = odr_strdup(rr->stream, details); + int r = 1; + const char *details = 0; + if (rr->len > 0) + { + r = yaz_record_conv_record(rc, rr->record, rr->len, output_record); + if (r) + details = yaz_record_conv_get_error(rc); + } + else if (rr->len == -1 && rr->output_format && + !oid_oidcmp(rr->output_format, yaz_oid_recsyn_opac)) + { + r = yaz_record_conv_opac_record( + rc, (Z_OPACRecord *) rr->record, output_record); + if (r) + details = yaz_record_conv_get_error(rc); + } + if (r == 0 && match_syntax && + !oid_oidcmp(match_syntax, yaz_oid_recsyn_opac)) + { + yaz_marc_t mt = yaz_marc_create(); + Z_OPACRecord *opac = 0; + if (yaz_xml_to_opac(mt, wrbuf_buf(output_record), + wrbuf_len(output_record), + &opac, 0 /* iconv */, rr->stream->mem, 0) + && opac) + { + rr->len = -1; + rr->record = (char *) opac; + } + else + { + details = "XML to OPAC conversion failed"; + r = 1; + } + yaz_marc_destroy(mt); } - else + else if (r == 0) { rr->len = wrbuf_len(output_record); rr->record = (char *) odr_malloc(rr->stream, rr->len); memcpy(rr->record, wrbuf_buf(output_record), rr->len); } + if (r) + { + rr->errcode = YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS; + if (details) + rr->errstring = odr_strdup(rr->stream, details); + } wrbuf_destroy(output_record); } if (match_syntax) @@ -671,7 +706,7 @@ static int retrieve_fetch(association *assoc, bend_fetch_rr *rr) static int srw_bend_fetch(association *assoc, int pos, Z_SRW_searchRetrieveRequest *srw_req, Z_SRW_record *record, - const char **addinfo) + const char **addinfo, int *last_in_set) { bend_fetch_rr rr; ODR o = assoc->encode; @@ -730,6 +765,8 @@ static int srw_bend_fetch(association *assoc, int pos, retrieve_fetch(assoc, &rr); + *last_in_set = rr.last_in_set; + if (rr.errcode && rr.surrogate_flag) { int code = yaz_diag_bib1_to_srw(rr.errcode); @@ -894,12 +931,14 @@ static void srw_bend_search(association *assoc, rr.query->u.type_1 = 0; rr.extra_args = sr->extra_args; rr.extra_response_data = 0; + rr.present_number = srw_req->maximumRecords ? + *srw_req->maximumRecords : 0; - if (srw_req->query_type == Z_SRW_query_type_cql) + if (!srw_req->queryType || !strcmp(srw_req->queryType, "cql")) { if (assoc->server && assoc->server->cql_transform) { - int srw_errcode = cql2pqf(assoc->encode, srw_req->query.cql, + int srw_errcode = cql2pqf(assoc->encode, srw_req->query, assoc->server->cql_transform, rr.query, &rr.srw_sortKeys); @@ -921,21 +960,20 @@ static void srw_bend_search(association *assoc, ext->indirect_reference = 0; ext->descriptor = 0; ext->which = Z_External_CQL; - ext->u.cql = srw_req->query.cql; + ext->u.cql = srw_req->query; rr.query->which = Z_Query_type_104; rr.query->u.type_104 = ext; } } - else if (srw_req->query_type == Z_SRW_query_type_pqf) + else if (!strcmp(srw_req->queryType, "pqf")) { Z_RPNQuery *RPNquery; YAZ_PQF_Parser pqf_parser; pqf_parser = yaz_pqf_create(); - RPNquery = yaz_pqf_parse(pqf_parser, assoc->decode, - srw_req->query.pqf); + RPNquery = yaz_pqf_parse(pqf_parser, assoc->decode, srw_req->query); if (!RPNquery) { const char *pqf_msg; @@ -971,6 +1009,11 @@ static void srw_bend_search(association *assoc, rr.errstring = 0; rr.search_info = 0; rr.search_input = 0; + + if (srw_req->facetList) + yaz_oi_set_facetlist(&rr.search_input, assoc->encode, + srw_req->facetList); + yaz_log_zquery_level(log_requestdetail,rr.query); (assoc->init->bend_search)(assoc->backend, &rr); @@ -1009,6 +1052,7 @@ static void srw_bend_search(association *assoc, odr_intdup(assoc->encode, *rr.srw_setnameIdleTime ); } + srw_res->facetList = yaz_oi_get_facetlist(&rr.search_info); if (start > rr.hits || start < 1) { /* if hits<=0 and start=1 we don't return a diagnostic */ @@ -1088,6 +1132,7 @@ static void srw_bend_search(association *assoc, for (i = 0; irecords[j].recordPacking = packing; @@ -1096,7 +1141,7 @@ static void srw_bend_search(association *assoc, yaz_log(YLOG_DEBUG, "srw_bend_fetch %d", i+start); errcode = srw_bend_fetch(assoc, i+start, srw_req, srw_res->records + j, - &addinfo); + &addinfo, &last_in_set); if (errcode) { yaz_add_srw_diagnostic(assoc->encode, @@ -1109,6 +1154,8 @@ static void srw_bend_search(association *assoc, } if (srw_res->records[j].recordData_buf) j++; + if (last_in_set) + break; } srw_res->num_records = j; if (!j) @@ -1120,7 +1167,19 @@ static void srw_bend_search(association *assoc, res->extraResponseData_buf = rr.extra_response_data; res->extraResponseData_len = strlen(rr.extra_response_data); } - if (rr.estimated_hit_count || rr.partial_resultset) + if (strcmp(res->srw_version, "2.") > 0) + { + if (rr.estimated_hit_count) + srw_res->resultCountPrecision = + odr_strdup(assoc->encode, "estimate"); + else if (rr.partial_resultset) + srw_res->resultCountPrecision = + odr_strdup(assoc->encode, "minimum"); + else + srw_res->resultCountPrecision = + odr_strdup(assoc->encode, "exact"); + } + else if (rr.estimated_hit_count || rr.partial_resultset) { yaz_add_srw_diagnostic( assoc->encode, @@ -1134,21 +1193,8 @@ static void srw_bend_search(association *assoc, } if (log_request) { - const char *querystr = "?"; - const char *querytype = "?"; WRBUF wr = wrbuf_alloc(); - switch (srw_req->query_type) - { - case Z_SRW_query_type_cql: - querytype = "CQL"; - querystr = srw_req->query.cql; - break; - case Z_SRW_query_type_pqf: - querytype = "PQF"; - querystr = srw_req->query.pqf; - break; - } wrbuf_printf(wr, "SRWSearch %s ", srw_req->database); if (srw_res->num_diagnostics) wrbuf_printf(wr, "ERROR %s", srw_res->diagnostics[0].uri); @@ -1165,7 +1211,8 @@ static void srw_bend_search(association *assoc, srw_res->resultSetId : "-"), (srw_req->startRecord ? *srw_req->startRecord : 1), srw_res->num_records); - yaz_log(log_request, "%s %s: %s", wrbuf_cstr(wr), querytype, querystr); + yaz_log(log_request, "%s %s: %s", wrbuf_cstr(wr), srw_req->queryType, + srw_req->query); wrbuf_destroy(wr); } } @@ -1256,10 +1303,11 @@ static void srw_bend_explain(association *assoc, static void srw_bend_scan(association *assoc, Z_SRW_PDU *sr, - Z_SRW_scanResponse *srw_res, + Z_SRW_PDU *res, int *http_code) { Z_SRW_scanRequest *srw_req = sr->u.scan_request; + Z_SRW_scanResponse *srw_res = res->u.scan_response; yaz_log(log_requestdetail, "Got SRW ScanRequest"); *http_code = 200; @@ -1287,6 +1335,8 @@ static void srw_bend_scan(association *assoc, bsrr->step_size = &step_size; bsrr->entries = 0; bsrr->setname = 0; + bsrr->extra_args = sr->extra_args; + bsrr->extra_response_data = 0; if (bsrr->num_entries > 0) { @@ -1305,20 +1355,20 @@ static void srw_bend_scan(association *assoc, } save_entries = bsrr->entries; /* save it so we can compare later */ - if (srw_req->query_type == Z_SRW_query_type_pqf && + if (srw_req->queryType && !strcmp(srw_req->queryType, "pqf") && assoc->init->bend_scan) { YAZ_PQF_Parser pqf_parser = yaz_pqf_create(); bsrr->term = yaz_pqf_scan(pqf_parser, assoc->decode, &bsrr->attributeset, - srw_req->scanClause.pqf); + srw_req->scanClause); yaz_pqf_destroy(pqf_parser); bsrr->scanClause = 0; ((int (*)(void *, bend_scan_rr *)) (*assoc->init->bend_scan))(assoc->backend, bsrr); } - else if (srw_req->query_type == Z_SRW_query_type_cql + else if ((!srw_req->queryType || !strcmp(srw_req->queryType, "cql")) && assoc->init->bend_scan && assoc->server && assoc->server->cql_transform) { @@ -1328,7 +1378,7 @@ static void srw_bend_scan(association *assoc, bsrr->term = (Z_AttributesPlusTerm *) odr_malloc(assoc->decode, sizeof(*bsrr->term)); srw_error = cql2pqf_scan(assoc->encode, - srw_req->scanClause.cql, + srw_req->scanClause, assoc->server->cql_transform, bsrr->term); if (srw_error) @@ -1341,12 +1391,12 @@ static void srw_bend_scan(association *assoc, (*assoc->init->bend_scan))(assoc->backend, bsrr); } } - else if (srw_req->query_type == Z_SRW_query_type_cql + else if ((!srw_req->queryType || !strcmp(srw_req->queryType, "cql")) && assoc->init->bend_srw_scan) { bsrr->term = 0; bsrr->attributeset = 0; - bsrr->scanClause = srw_req->scanClause.cql; + bsrr->scanClause = srw_req->scanClause; ((int (*)(void *, bend_scan_rr *)) (*assoc->init->bend_srw_scan))(assoc->backend, bsrr); } @@ -1356,6 +1406,11 @@ static void srw_bend_scan(association *assoc, &srw_res->num_diagnostics, YAZ_SRW_UNSUPP_OPERATION, "scan"); } + if (bsrr->extra_response_data) + { + res->extraResponseData_buf = bsrr->extra_response_data; + res->extraResponseData_len = strlen(bsrr->extra_response_data); + } if (bsrr->errcode) { int srw_error; @@ -1402,24 +1457,6 @@ static void srw_bend_scan(association *assoc, if (log_request) { WRBUF wr = wrbuf_alloc(); - const char *querytype = 0; - const char *querystr = 0; - - switch(srw_req->query_type) - { - case Z_SRW_query_type_pqf: - querytype = "PQF"; - querystr = srw_req->scanClause.pqf; - break; - case Z_SRW_query_type_cql: - querytype = "CQL"; - querystr = srw_req->scanClause.cql; - break; - default: - querytype = "UNKNOWN"; - querystr = ""; - } - wrbuf_printf(wr, "SRWScan %s ", srw_req->database); if (srw_res->num_diagnostics) @@ -1435,7 +1472,7 @@ static void srw_bend_scan(association *assoc, (srw_req->maximumTerms ? *srw_req->maximumTerms : 1)); /* there is no step size in SRU/W ??? */ - wrbuf_printf(wr, "%s: %s ", querytype, querystr); + wrbuf_printf(wr, "%s: %s ", srw_req->queryType, srw_req->scanClause); yaz_log(log_request, "%s ", wrbuf_cstr(wr) ); wrbuf_destroy(wr); } @@ -1840,7 +1877,7 @@ static void process_http_request(association *assoc, request *req) res->u.scan_response->diagnostics = diagnostic; res->u.scan_response->num_diagnostics = num_diagnostic; } - srw_bend_scan(assoc, sr, res->u.scan_response, &http_code); + srw_bend_scan(assoc, sr, res, &http_code); if (http_code == 200) soap_package->u.generic->p = res; } @@ -2595,6 +2632,8 @@ static Z_Records *pack_records(association *a, char *setname, Odr_int start, return 0; reclist->records[reclist->num_records] = thisrec; reclist->num_records++; + if (freq.last_in_set) + break; } *num = reclist->num_records; return records; @@ -2642,7 +2681,10 @@ static Z_APDU *process_searchRequest(association *assoc, request *reqb) bsrr->errcode = 0; bsrr->errstring = NULL; bsrr->search_info = NULL; - bsrr->search_input = req->otherInfo; + bsrr->search_input = req->additionalSearchInfo; + if (!bsrr->search_input) + bsrr->search_input = req->otherInfo; + bsrr->present_number = *req->mediumSetPresentNumber; if (assoc->server && assoc->server->cql_transform && req->query->which == Z_Query_type_104 @@ -3000,6 +3042,8 @@ static Z_APDU *process_scanRequest(association *assoc, request *reqb) bsrr->setname = yaz_oi_get_string_oid(&req->otherInfo, yaz_oid_userinfo_scan_set, 1, 0); bsrr->entries = 0; + bsrr->extra_args = 0; + bsrr->extra_response_data = 0; /* For YAZ 2.0 and earlier it was the backend handler that initialized entries (member display_term did not exist) YAZ 2.0 and later sets 'entries' and initialize all members @@ -3056,7 +3100,6 @@ static Z_APDU *process_scanRequest(association *assoc, request *reqb) { Z_Entry *e; Z_TermInfo *t; - Odr_oct *o; tab[i] = e = (Z_Entry *)odr_malloc(assoc->encode, sizeof(*e)); if (bsrr->entries[i].occurrences >= 0) @@ -3083,12 +3126,10 @@ static Z_APDU *process_scanRequest(association *assoc, request *reqb) t->term = (Z_Term *) odr_malloc(assoc->encode, sizeof(*t->term)); t->term->which = Z_Term_general; - t->term->u.general = o = - (Odr_oct *)odr_malloc(assoc->encode, sizeof(Odr_oct)); - o->buf = (unsigned char *) - odr_malloc(assoc->encode, o->len = o->size = - strlen(bsrr->entries[i].term)); - memcpy(o->buf, bsrr->entries[i].term, o->len); + t->term->u.general = + odr_create_Odr_oct(assoc->encode, + bsrr->entries[i].term, + strlen(bsrr->entries[i].term)); yaz_log(YLOG_DEBUG, " term #%d: '%s' (" ODR_INT_PRINTF ")", i, bsrr->entries[i].term, bsrr->entries[i].occurrences); }