X-Git-Url: http://git.indexdata.com/?p=idzebra-moved-to-github.git;a=blobdiff_plain;f=index%2Fzebrasrv.c;h=2560f4eb82966b4ef0b8dd56229ef8a2c5cbdd4e;hp=6a0efdc24573f8633344718c7411aee93aa72949;hb=e2e073b5c947e996304ed7d577497af5e9a879ee;hpb=a030c87bc444608639905eca95e29f84a4f1d991 diff --git a/index/zebrasrv.c b/index/zebrasrv.c index 6a0efdc..2560f4e 100644 --- a/index/zebrasrv.c +++ b/index/zebrasrv.c @@ -1,5 +1,5 @@ /* This file is part of the Zebra server. - Copyright (C) 1994-2011 Index Data + Copyright (C) Index Data Zebra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -17,6 +17,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#if HAVE_CONFIG_H +#include +#endif #include #include #include @@ -34,8 +37,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include #include #include +#include #include - +#include +#include #include #include @@ -128,7 +133,7 @@ bend_initresult *bend_init(bend_initrequest *q) yaz_get_proposal_charneg(nmem, q->charneg_request, &charsets, &num_charsets, &langs, &num_langs, &selected); - + for (i = 0; i < num_charsets; i++) { const char *right_name = ""; @@ -138,7 +143,7 @@ bend_initresult *bend_init(bend_initrequest *q) * because a lot servers in Russia to use own in during * character set and language negotiation still. */ - + if (!yaz_matchstr(charsets[i], "win")) { right_name = "WINDOWS-1251"; } else if (!yaz_matchstr(charsets[i], "koi")) { @@ -207,7 +212,7 @@ static void search_terms(ZebraHandle zh, bend_search_rr *r) sr->num = no_terms; sr->elements = odr_malloc(r->stream, sr->num * sizeof(*sr->elements)); - for (i = 0; ielements[i] = odr_malloc(r->stream, sizeof(**sr->elements)); - se->subqueryId = term_ref_id ? + se->subqueryId = term_ref_id ? odr_strdup(r->stream, term_ref_id) : 0; - + se->fullQuery = odr_booldup(r->stream, 0); - se->subqueryExpression = + se->subqueryExpression = odr_malloc(r->stream, sizeof(Z_QueryExpression)); - se->subqueryExpression->which = + se->subqueryExpression->which = Z_QueryExpression_term; se->subqueryExpression->u.term = odr_malloc(r->stream, sizeof(Z_QueryExpressionTerm)); @@ -241,10 +246,11 @@ static void search_terms(ZebraHandle zh, bend_search_rr *r) break; case Z_Term_general: term->which = Z_Term_general; - term->u.general = odr_malloc(r->stream, sizeof(*term->u.general)); - term->u.general->size = term->u.general->len = len; - term->u.general->buf = odr_malloc(r->stream, len); - memcpy(term->u.general->buf, outbuf, len); + term->u.general = odr_create_Odr_oct(r->stream, +#if YAZ_VERSIONL < 0x50000 + (unsigned char *) +#endif + outbuf, len); break; default: term->which = Z_Term_general; @@ -253,28 +259,100 @@ static void search_terms(ZebraHandle zh, bend_search_rr *r) se->subqueryExpression->u.term->termComment = 0; se->subqueryInterpretation = 0; se->subqueryRecommendation = 0; - if (count > 2147483646) - count = 2147483647; - se->subqueryCount = odr_intdup(r->stream, CAST_ZINT_TO_INT(count)); + se->subqueryCount = odr_intdup(r->stream, count); se->subqueryWeight = 0; se->resultsByDB = 0; } } - static int break_handler(void *client_data) { - bend_association assoc =(bend_association) client_data; + bend_association assoc =(bend_association) client_data; if (!bend_assoc_is_alive(assoc)) return 1; return 0; } +static Z_RPNQuery *query_add_sortkeys(ODR o, Z_RPNQuery *query, + const char *sortKeys) +{ +#if YAZ_VERSIONL >= 0x40200 + /* sortkey layour: path,schema,ascending,caseSensitive,missingValue */ + /* see cql_sortby_to_sortkeys of YAZ. */ + char **sortspec; + int num_sortspec = 0; + int i; + + if (sortKeys) + nmem_strsplit_blank(odr_getmem(o), sortKeys, &sortspec, &num_sortspec); + if (num_sortspec > 0) + { + Z_RPNQuery *nquery; + WRBUF w = wrbuf_alloc(); + + /* left operand 'd' will be replaced by original query */ + wrbuf_puts(w, "@or d"); + for (i = 0; i < num_sortspec; i++) + { + char **arg; + int num_arg; + int ascending = 1; + nmem_strsplitx(odr_getmem(o), ",", sortspec[i], &arg, &num_arg, 0); + + if (num_arg > 5 || num_arg < 1) + { + yaz_log(YLOG_WARN, "Invalid sort spec '%s' num_arg=%d", + sortspec[i], num_arg); + break; + } + if (num_arg > 2 && arg[2][0]) + ascending = atoi(arg[2]); + + if (i < num_sortspec-1) + wrbuf_puts(w, " @or"); + wrbuf_puts(w, " @attr 1="); + yaz_encode_pqf_term(w, arg[0], strlen(arg[0])); + wrbuf_printf(w, "@attr 7=%d %d", ascending ? 1 : 2, i); + } + nquery = p_query_rpn(o, wrbuf_cstr(w)); + if (!nquery) + { + yaz_log(YLOG_WARN, "query_add_sortkeys: bad RPN: '%s'", + wrbuf_cstr(w)); + } + else + { + Z_RPNStructure *s = nquery->RPNStructure; + + if (s->which != Z_RPNStructure_complex) + { + yaz_log(YLOG_WARN, "query_add_sortkeys: not complex operand"); + } + else + { + /* left operand 'd' is replaced by origial query */ + s->u.complex->s1 = query->RPNStructure; + /* and original query points to our new or+sort things */ + query->RPNStructure = s; + } + } + wrbuf_destroy(w); + } +#else + if (sortKeys) + { + yaz_log(YLOG_WARN, "sortkeys ignored because YAZ version < 4.2.0"); + } +#endif + return query; +} + int bend_search(void *handle, bend_search_rr *r) { ZebraHandle zh = (ZebraHandle) handle; zint zhits = 0; ZEBRA_RES res; + Z_RPNQuery *q2; res = zebra_select_databases(zh, r->num_bases, (const char **) r->basenames); @@ -288,7 +366,8 @@ int bend_search(void *handle, bend_search_rr *r) switch (r->query->which) { case Z_Query_type_1: case Z_Query_type_101: - res = zebra_search_RPN_x(zh, r->stream, r->query->u.type_1, + q2 = query_add_sortkeys(r->stream, r->query->u.type_1, r->srw_sortKeys); + res = zebra_search_RPN_x(zh, r->stream, q2, r->setname, &zhits, &r->estimated_hit_count, &r->partial_resultset); @@ -296,9 +375,7 @@ int bend_search(void *handle, bend_search_rr *r) zebra_result(zh, &r->errcode, &r->errstring); else { - if (zhits > 2147483646) - zhits = 2147483647; - r->hits = CAST_ZINT_TO_INT(zhits); + r->hits = zhits; search_terms(zh, r); } break; @@ -321,7 +398,7 @@ int bend_fetch(void *handle, bend_fetch_rr *r) ZEBRA_RES res; retrievalRecord.position = r->number; - + r->last_in_set = 0; res = zebra_records_retrieve(zh, r->stream, r->setname, r->comp, r->request_format, 1, &retrievalRecord); @@ -355,7 +432,7 @@ static int bend_scan(void *handle, bend_scan_rr *r) int is_partial, i; ZEBRA_RES res; - res = zebra_select_databases(zh, r->num_bases, + res = zebra_select_databases(zh, r->num_bases, (const char **) r->basenames); if (res != ZEBRA_OK) { @@ -370,7 +447,7 @@ static int bend_scan(void *handle, bend_scan_rr *r) res = zebra_scan(zh, r->stream, r->term, r->attributeset, &r->term_position, - &r->num_entries, &entries, &is_partial, + &r->num_entries, &entries, &is_partial, 0 /* setname */); if (res == ZEBRA_OK) { @@ -382,8 +459,7 @@ static int bend_scan(void *handle, bend_scan_rr *r) { r->entries[i].term = entries[i].term; r->entries[i].display_term = entries[i].display_term; - r->entries[i].occurrences = - CAST_ZINT_TO_INT(entries[i].occurrences); + r->entries[i].occurrences = entries[i].occurrences; } } else @@ -515,7 +591,7 @@ int bend_segment(void *handle, bend_segment_rr *rr) int bend_esrequest(void *handle, bend_esrequest_rr *rr) { ZebraHandle zh = (ZebraHandle) handle; - + yaz_log(YLOG_LOG, "function: " ODR_INT_PRINTF, *rr->esr->function); if (rr->esr->packageName) yaz_log(YLOG_LOG, "packagename: %s", rr->esr->packageName); @@ -538,7 +614,7 @@ int bend_esrequest(void *handle, bend_esrequest_rr *rr) Z_IUUpdateEsRequest *esRequest = up->u.esRequest; Z_IUOriginPartToKeep *toKeep = esRequest->toKeep; Z_IUSuppliedRecords *notToKeep = esRequest->notToKeep; - + yaz_log(YLOG_LOG, "action"); if (toKeep->action) { @@ -671,7 +747,7 @@ int bend_esrequest(void *handle, bend_esrequest_rr *rr) rr->errstring = "unsupported ES Update action"; break; } - + if (opaque_recid) { size_t l = opaque_recid->len; @@ -712,7 +788,7 @@ int bend_esrequest(void *handle, bend_esrequest_rr *rr) yaz_log(YLOG_WARN, "Unknown Extended Service(%d)", rr->esr->taskSpecificParameters->which); rr->errcode = YAZ_BIB1_ES_EXTENDED_SERVICE_TYPE_UNSUPP; - + } return 0; } @@ -733,9 +809,9 @@ static void bend_start(struct statserv_options_block *sob) exit(1); } #ifdef WIN32 - + #else - if (!sob->inetd && !sob->background) + if (!sob->inetd && !sob->background) { char pidfname[4096]; struct flock area; @@ -769,7 +845,7 @@ static void bend_start(struct statserv_options_block *sob) else { char pidstr[30]; - + sprintf(pidstr, "%ld", (long) getpid()); if (write(fd, pidstr, strlen(pidstr)) != strlen(pidstr)) { @@ -786,7 +862,7 @@ static void bend_stop(struct statserv_options_block *sob) #ifdef WIN32 #else - if (!sob->inetd && !sob->background && sob->handle) + if (!sob->inetd && !sob->background && sob->handle) { char pidfname[4096]; zebra_pidfname(sob->handle, pidfname);