X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fzoom-z3950.c;h=5697865e5dff5d23dfa100d9ef62c726237ff0e0;hp=b91611579a49976a1c11759911c0604080ee6c87;hb=609ad9573e7ea6450727297bdd36080cf38a9032;hpb=79f02618682f616509d80665126918a07d1f9e80 diff --git a/src/zoom-z3950.c b/src/zoom-z3950.c index b916115..5697865 100644 --- a/src/zoom-z3950.c +++ b/src/zoom-z3950.c @@ -1,5 +1,5 @@ /* This file is part of the YAZ toolkit. - * Copyright (C) 1995-2012 Index Data + * Copyright (C) Index Data * See the file LICENSE for details. */ /** @@ -126,9 +126,7 @@ static Z_External *encode_ill_request(ZOOM_package p) r->which = Z_External_single; r->u.single_ASN1_type = - odr_create_Odr_oct(out, - (unsigned char *)illRequest_buf, - illRequest_size); + odr_create_Odr_oct(out, illRequest_buf, illRequest_size); } return r; } @@ -272,8 +270,7 @@ static Z_APDU *create_xmlupdate_package(ZOOM_package p) ext->indirect_reference = 0; ext->which = Z_External_octet; - ext->u.single_ASN1_type = - odr_create_Odr_oct(p->odr_out, (const unsigned char *) doc, len); + ext->u.single_ASN1_type = odr_create_Odr_oct(p->odr_out, doc, len); return apdu; } @@ -417,8 +414,7 @@ static Z_APDU *create_update_package(ZOOM_package p) if (recordIdOpaque) { notToKeep->elements[0]->u.opaque = - odr_create_Odr_oct(p->odr_out, - (const unsigned char *) recordIdOpaque, + odr_create_Odr_oct(p->odr_out, recordIdOpaque, recordIdOpaque_len); } else if (recordIdNumber) @@ -637,13 +633,14 @@ zoom_ret ZOOM_connection_Z3950_send_init(ZOOM_connection c) return send_APDU(c, apdu); } -zoom_ret ZOOM_connection_Z3950_send_search(ZOOM_connection c) +static zoom_ret Z3950_send_search(ZOOM_connection c) { ZOOM_resultset r; int lslb, ssub, mspn; const char *syntax; - Z_APDU *apdu = zget_APDU(c->odr_out, Z_APDU_searchRequest); - Z_SearchRequest *search_req = apdu->u.searchRequest; + const char *schema; + Z_APDU *apdu; + Z_SearchRequest *search_req; const char *elementSetName; const char *smallSetElementSetName; const char *mediumSetElementSetName; @@ -651,13 +648,14 @@ zoom_ret ZOOM_connection_Z3950_send_search(ZOOM_connection c) assert(c->tasks); assert(c->tasks->which == ZOOM_TASK_SEARCH); - r = c->tasks->u.search.resultset; + apdu = zget_APDU(c->odr_out, Z_APDU_searchRequest); + search_req = apdu->u.searchRequest; + yaz_log(c->log_details, "%p ZOOM_connection_send_search set=%p", c, r); - elementSetName = - ZOOM_options_get(r->options, "elementSetName"); + elementSetName = c->tasks->u.search.elementSetName; smallSetElementSetName = ZOOM_options_get(r->options, "smallSetElementSetName"); mediumSetElementSetName = @@ -673,8 +671,7 @@ zoom_ret ZOOM_connection_Z3950_send_search(ZOOM_connection c) if (facets) { Z_FacetList *facet_list = yaz_pqf_parse_facet_list(c->odr_out, facets); if (facet_list) { - Z_OtherInformation **oi; - yaz_oi_APDU(apdu, &oi); + Z_OtherInformation **oi = &search_req->additionalSearchInfo; yaz_oi_set_facetlist(oi, c->odr_out, facet_list); } else @@ -722,6 +719,8 @@ zoom_ret ZOOM_connection_Z3950_send_search(ZOOM_connection c) /* get syntax (no need to provide unless piggyback is in effect) */ syntax = c->tasks->u.search.syntax; + schema = c->tasks->u.search.schema; + lslb = ZOOM_options_get_int(r->options, "largeSetLowerBound", -1); ssub = ZOOM_options_get_int(r->options, "smallSetUpperBound", -1); mspn = ZOOM_options_get_int(r->options, "mediumSetPresentNumber", -1); @@ -733,7 +732,7 @@ zoom_ret ZOOM_connection_Z3950_send_search(ZOOM_connection c) *search_req->mediumSetPresentNumber = mspn; } else if (c->tasks->u.search.start == 0 && c->tasks->u.search.count > 0 - && r->piggyback && !r->r_sort_spec && !r->schema) + && r->piggyback && !r->r_sort_spec && !schema) { /* Regular piggyback - do it unless we're going to do sort */ *search_req->largeSetLowerBound = 2000000000; @@ -780,15 +779,6 @@ zoom_ret ZOOM_connection_Z3950_send_search(ZOOM_connection c) result sets on the server. */ for (ord = 1; ; ord++) { -#if ZOOM_RESULT_LISTS - ZOOM_resultsets rsp; - sprintf(setname, "%d", ord); - for (rsp = c->resultsets; rsp; rsp = rsp->next) - if (rsp->resultset->setname && !strcmp(rsp->resultset->setname, setname)) - break; - if (!rsp) - break; -#else ZOOM_resultset rp; sprintf(setname, "%d", ord); for (rp = c->resultsets; rp; rp = rp->next) @@ -796,8 +786,6 @@ zoom_ret ZOOM_connection_Z3950_send_search(ZOOM_connection c) break; if (!rp) break; -#endif - } r->setname = xstrdup(setname); yaz_log(c->log_details, "%p ZOOM_connection_send_search: " @@ -1048,12 +1036,12 @@ static int es_response_taskpackage(ZOOM_connection c, return 1; } - -static int handle_Z3950_es_response(ZOOM_connection c, - Z_ExtendedServicesResponse *res) +static void handle_Z3950_es_response(ZOOM_connection c, + Z_ExtendedServicesResponse *res) { - if (!c->tasks || c->tasks->which != ZOOM_TASK_PACKAGE) - return 0; + if (!c->tasks) + return; + assert(c->tasks->which == ZOOM_TASK_PACKAGE); switch (*res->operationStatus) { case Z_ExtendedServicesResponse_done: @@ -1081,7 +1069,6 @@ static int handle_Z3950_es_response(ZOOM_connection c, ZOOM_options_setl(c->tasks->u.package->options, "xmlUpdateDoc", (char*) doc->buf, doc->len); } - return 1; } static char *get_term_cstr(ODR odr, Z_Term *term) { @@ -1117,7 +1104,8 @@ static ZOOM_facet_field get_zoom_facet_field(ODR odr, Z_FacetField *facet) { } /* Can be share with SOLR/SRU/SRW requests */ -void handle_facet_list(ZOOM_resultset r, Z_FacetList *fl) { +void ZOOM_handle_facet_list(ZOOM_resultset r, Z_FacetList *fl) +{ int j; r->num_facets = fl->num; yaz_log(YLOG_DEBUG, "Facets found: %d", fl->num); @@ -1143,7 +1131,7 @@ static void handle_facet_result(ZOOM_connection c, ZOOM_resultset r, Z_External *ext = o->list[i]->information.externallyDefinedInfo; if (ext->which == Z_External_userFacets) { - handle_facet_list(r, ext->u.facetList); + ZOOM_handle_facet_list(r, ext->u.facetList); } } } @@ -1263,13 +1251,15 @@ static void handle_Z3950_search_response(ZOOM_connection c, ZOOM_Event event; if (!c->tasks || c->tasks->which != ZOOM_TASK_SEARCH) - return ; - - event = ZOOM_Event_create(ZOOM_EVENT_RECV_SEARCH); - ZOOM_connection_put_event(c, event); + return; resultset = c->tasks->u.search.resultset; + if (resultset->live_set == 0) + { + event = ZOOM_Event_create(ZOOM_EVENT_RECV_SEARCH); + ZOOM_connection_put_event(c, event); + } if (sr->resultSetStatus) { ZOOM_options_set_int(resultset->options, "resultSetStatus", @@ -1285,6 +1275,25 @@ static void handle_Z3950_search_response(ZOOM_connection c, handle_facet_result(c, resultset, sr->additionalSearchInfo); resultset->size = *sr->resultCount; + resultset->live_set = 2; + +#if HAVE_LIBMEMCACHED_MEMCACHED_H + if (c->mc_st) + { + uint32_t flags = 0; + memcached_return_t rc; + time_t expiration = 36000; + char str[40]; + + sprintf(str, ODR_INT_PRINTF, *sr->resultCount); + rc = memcached_set(c->mc_st, + wrbuf_buf(resultset->mc_key),wrbuf_len(resultset->mc_key), + str, strlen(str), expiration, flags); + yaz_log(YLOG_LOG, "Store Z39.50 hit count key=%s value=%s rc=%u %s", + wrbuf_cstr(resultset->mc_key), str, (unsigned) rc, + memcached_last_error_message(c->mc_st)); + } +#endif handle_Z3950_records(c, sr->records, 0); } @@ -1294,13 +1303,13 @@ static void handle_Z3950_sort_response(ZOOM_connection c, Z_SortResponse *res) response_diag(c, res->diagnostics[0]); } -static int handle_Z3950_scan_response(ZOOM_connection c, Z_ScanResponse *res) +static void handle_Z3950_scan_response(ZOOM_connection c, Z_ScanResponse *res) { NMEM nmem = odr_extract_mem(c->odr_in); ZOOM_scanset scan; if (!c->tasks || c->tasks->which != ZOOM_TASK_SCAN) - return 0; + return; scan = c->tasks->u.scan.scan; if (res->entries && res->entries->nonsurrogateDiagnostics) @@ -1318,7 +1327,6 @@ static int handle_Z3950_scan_response(ZOOM_connection c, Z_ScanResponse *res) ZOOM_options_set_int(scan->options, "number", *res->numberOfEntriesReturned); nmem_destroy(nmem); - return 1; } static void handle_Z3950_records(ZOOM_connection c, Z_Records *sr, @@ -1326,29 +1334,18 @@ static void handle_Z3950_records(ZOOM_connection c, Z_Records *sr, { ZOOM_resultset resultset; int *start, *count; - const char *syntax = 0, *elementSetName = 0; + const char *syntax = 0, *elementSetName = 0, *schema = 0; - if (!c->tasks) + if (!c->tasks || c->tasks->which != ZOOM_TASK_SEARCH) return ; - switch (c->tasks->which) - { - case ZOOM_TASK_SEARCH: - resultset = c->tasks->u.search.resultset; - start = &c->tasks->u.search.start; - count = &c->tasks->u.search.count; - syntax = c->tasks->u.search.syntax; - elementSetName = c->tasks->u.search.elementSetName; - break; - case ZOOM_TASK_RETRIEVE: - resultset = c->tasks->u.retrieve.resultset; - start = &c->tasks->u.retrieve.start; - count = &c->tasks->u.retrieve.count; - syntax = c->tasks->u.retrieve.syntax; - elementSetName = c->tasks->u.retrieve.elementSetName; - break; - default: - return; - } + + resultset = c->tasks->u.search.resultset; + start = &c->tasks->u.search.start; + count = &c->tasks->u.search.count; + syntax = c->tasks->u.search.syntax; + elementSetName = c->tasks->u.search.elementSetName; + schema = c->tasks->u.search.schema; + if (sr && sr->which == Z_Records_NSD) response_default_diag(c, sr->u.nonSurrogateDiagnostic); else if (sr && sr->which == Z_Records_multipleNSD) @@ -1373,8 +1370,7 @@ static void handle_Z3950_records(ZOOM_connection c, Z_Records *sr, for (i = 0; inum_records; i++) { ZOOM_record_cache_add(resultset, p->records[i], i + *start, - syntax, elementSetName, - elementSetName, 0); + syntax, elementSetName, schema, 0); } *count -= i; if (*count < 0) @@ -1396,7 +1392,8 @@ static void handle_Z3950_records(ZOOM_connection c, Z_Records *sr, YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS, "ZOOM C generated. Present phase and no records"); ZOOM_record_cache_add(resultset, myrec, *start, - syntax, elementSetName, 0, 0); + syntax, elementSetName, schema, 0); + *count = 0; } } else if (present_phase) @@ -1408,7 +1405,8 @@ static void handle_Z3950_records(ZOOM_connection c, Z_Records *sr, YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS, "ZOOM C generated: Present response and no records"); ZOOM_record_cache_add(resultset, myrec, *start, - syntax, elementSetName, 0, 0); + syntax, elementSetName, schema, 0); + *count = 0; } } } @@ -1451,98 +1449,31 @@ zoom_ret send_Z3950_sort(ZOOM_connection c, ZOOM_resultset resultset) return zoom_complete; } -zoom_ret send_Z3950_present(ZOOM_connection c) +static zoom_ret Z3950_send_present(ZOOM_connection c) { - Z_APDU *apdu = 0; - Z_PresentRequest *req = 0; - int i = 0; - const char *syntax = 0; - const char *elementSetName = 0; - ZOOM_resultset resultset; - int *start, *count; - - if (!c->tasks) - { - yaz_log(c->log_details, "%p send_present no tasks", c); - return zoom_complete; - } - - switch (c->tasks->which) - { - case ZOOM_TASK_SEARCH: - resultset = c->tasks->u.search.resultset; - start = &c->tasks->u.search.start; - count = &c->tasks->u.search.count; - syntax = c->tasks->u.search.syntax; - elementSetName = c->tasks->u.search.elementSetName; - break; - case ZOOM_TASK_RETRIEVE: - resultset = c->tasks->u.retrieve.resultset; - start = &c->tasks->u.retrieve.start; - count = &c->tasks->u.retrieve.count; - syntax = c->tasks->u.retrieve.syntax; - elementSetName = c->tasks->u.retrieve.elementSetName; - break; - default: - return zoom_complete; - } - yaz_log(c->log_details, "%p send_present start=%d count=%d", - c, *start, *count); - - if (*start < 0 || *count < 0 || *start + *count > resultset->size) - { - ZOOM_set_dset_error(c, YAZ_BIB1_PRESENT_REQUEST_OUT_OF_RANGE, "Bib-1", - "", 0); - } - if (c->error) /* don't continue on error */ - return zoom_complete; - yaz_log(c->log_details, "send_present resultset=%p start=%d count=%d", - resultset, *start, *count); - - for (i = 0; i < *count; i++) - { - ZOOM_record rec = - ZOOM_record_cache_lookup(resultset, i + *start, - syntax, elementSetName); - if (!rec) - break; - else - { - ZOOM_Event event = ZOOM_Event_create(ZOOM_EVENT_RECV_RECORD); - ZOOM_connection_put_event(c, event); - } - } - *start += i; - *count -= i; - - if (*count == 0) - { - yaz_log(c->log_details, "%p send_present skip=%d no more to fetch", c, i); - return zoom_complete; - } - - apdu = zget_APDU(c->odr_out, Z_APDU_presentRequest); - req = apdu->u.presentRequest; + Z_APDU *apdu = zget_APDU(c->odr_out, Z_APDU_presentRequest); + Z_PresentRequest *req = apdu->u.presentRequest; + ZOOM_resultset resultset = c->tasks->u.search.resultset; + const char *syntax = c->tasks->u.search.syntax; + const char *elementSetName = c->tasks->u.search.elementSetName; + const char *schema = c->tasks->u.search.schema; - if (i) - yaz_log(c->log_details, "%p send_present skip=%d", c, i); + *req->resultSetStartPoint = c->tasks->u.search.start + 1; - *req->resultSetStartPoint = *start + 1; - - if (resultset->step > 0 && resultset->step < *count) + if (resultset->step > 0 && resultset->step < c->tasks->u.search.count) *req->numberOfRecordsRequested = resultset->step; else - *req->numberOfRecordsRequested = *count; + *req->numberOfRecordsRequested = c->tasks->u.search.count; - if (*req->numberOfRecordsRequested + *start > resultset->size) - *req->numberOfRecordsRequested = resultset->size - *start; + if (*req->numberOfRecordsRequested + c->tasks->u.search.start > resultset->size) + *req->numberOfRecordsRequested = resultset->size - c->tasks->u.search.start; assert(*req->numberOfRecordsRequested > 0); if (syntax && *syntax) req->preferredRecordSyntax = zoom_yaz_str_to_z3950oid(c, CLASS_RECSYN, syntax); - if (resultset->schema && *resultset->schema) + if (schema && *schema) { Z_RecordComposition *compo = (Z_RecordComposition *) odr_malloc(c->odr_out, sizeof(*compo)); @@ -1560,14 +1491,14 @@ zoom_ret send_Z3950_present(ZOOM_connection c) compo->u.complex->generic->which = Z_Schema_oid; compo->u.complex->generic->schema.oid = (Odr_oid *) - zoom_yaz_str_to_z3950oid (c, CLASS_SCHEMA, resultset->schema); + zoom_yaz_str_to_z3950oid(c, CLASS_SCHEMA, schema); if (!compo->u.complex->generic->schema.oid) { /* OID wasn't a schema! Try record syntax instead. */ compo->u.complex->generic->schema.oid = (Odr_oid *) - zoom_yaz_str_to_z3950oid (c, CLASS_RECSYN, resultset->schema); + zoom_yaz_str_to_z3950oid(c, CLASS_RECSYN, schema); } if (elementSetName && *elementSetName) { @@ -1602,6 +1533,69 @@ zoom_ret send_Z3950_present(ZOOM_connection c) return send_APDU(c, apdu); } +zoom_ret ZOOM_connection_Z3950_search(ZOOM_connection c) +{ + int i = 0; + const char *syntax = 0; + const char *elementSetName = 0; + const char *schema = 0; + ZOOM_resultset resultset; + int *start, *count; + + if (!c->tasks) + return zoom_complete; + assert(c->tasks->which == ZOOM_TASK_SEARCH); + resultset = c->tasks->u.search.resultset; + start = &c->tasks->u.search.start; + count = &c->tasks->u.search.count; + syntax = c->tasks->u.search.syntax; + elementSetName = c->tasks->u.search.elementSetName; + schema = c->tasks->u.search.schema; + + yaz_log(c->log_details, "%p send_present start=%d count=%d", + c, *start, *count); + + if (*start < 0 || *count < 0) + { + ZOOM_set_dset_error(c, YAZ_BIB1_PRESENT_REQUEST_OUT_OF_RANGE, "Bib-1", + "", 0); + } + if (resultset->live_set && *start + *count > resultset->size) + { + ZOOM_set_dset_error(c, YAZ_BIB1_PRESENT_REQUEST_OUT_OF_RANGE, "Bib-1", + "", 0); + } + + if (c->error) /* don't continue on error */ + return zoom_complete; + yaz_log(c->log_details, "send_present resultset=%p start=%d count=%d", + resultset, *start, *count); + + for (i = 0; i < *count; i++) + { + ZOOM_record rec = + ZOOM_record_cache_lookup(resultset, i + *start, + syntax, elementSetName, schema); + if (!rec) + break; + else + { + ZOOM_Event event = ZOOM_Event_create(ZOOM_EVENT_RECV_RECORD); + ZOOM_connection_put_event(c, event); + } + } + *start += i; + *count -= i; + + if (*count == 0 && resultset->live_set) + return zoom_complete; + + if (resultset->live_set == 2) + return Z3950_send_present(c); + else + return Z3950_send_search(c); +} + static zoom_ret send_Z3950_sort_present(ZOOM_connection c) { zoom_ret r = zoom_complete; @@ -1609,7 +1603,7 @@ static zoom_ret send_Z3950_sort_present(ZOOM_connection c) if (c->tasks && c->tasks->which == ZOOM_TASK_SEARCH) r = send_Z3950_sort(c, c->tasks->u.search.resultset); if (r == zoom_complete) - r = send_Z3950_present(c); + r = ZOOM_connection_Z3950_search(c); return r; } @@ -1714,14 +1708,13 @@ void ZOOM_handle_Z3950_apdu(ZOOM_connection c, Z_APDU *apdu) case Z_APDU_presentResponse: yaz_log(c->log_api, "%p handle_Z3950_apdu Present response", c); handle_Z3950_present_response(c, apdu->u.presentResponse); - if (send_Z3950_present(c) == zoom_complete) + if (ZOOM_connection_Z3950_search(c) == zoom_complete) ZOOM_connection_remove_task(c); break; case Z_APDU_sortResponse: yaz_log(c->log_api, "%p handle_Z3950_apdu Sort response", c); handle_Z3950_sort_response(c, apdu->u.sortResponse); - if (send_Z3950_present(c) == zoom_complete) - ZOOM_connection_remove_task(c); + ZOOM_connection_remove_task(c); break; case Z_APDU_scanResponse: yaz_log(c->log_api, "%p handle_Z3950_apdu Scan response", c);