X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fsru_facet.c;h=a7c06296f5b7dd5fc7cd1559bb48e7ec6e458bf2;hp=29c5a681d05988b98b124edd3cdbca75e7e0dda7;hb=4d1fabb92a48f8fad70e715ecc0a419b1874b4f3;hpb=c5ebd327a29b3ec88eedbea53f9a0f6cda164de7 diff --git a/src/sru_facet.c b/src/sru_facet.c index 29c5a68..a7c0629 100644 --- a/src/sru_facet.c +++ b/src/sru_facet.c @@ -1,5 +1,5 @@ /* This file is part of the YAZ toolkit. - * Copyright (C) 1995-2013 Index Data + * Copyright (C) Index Data * See the file LICENSE for details. */ /** @@ -24,68 +24,164 @@ #include #include -void yaz_sru_facet_request(ODR o, Z_FacetList **facetList, const char **limit) +static void insert_field(WRBUF w, const char *field, size_t length, + const char *attr) +{ + const char *cp0 = wrbuf_cstr(w); + const char *cp = cp0; + + while (1) + { + const char *cp2 = strstr(cp, "@attr 1="); + if (!cp2) + break; + cp = cp2 + 8; + if (!strncmp(cp, field, length) && + (cp[length] == ' ' || cp[length] == ',' || cp[length] == '\0')) + { + /* found the field */ + + cp += length; + wrbuf_insert(w, cp - cp0, attr, strlen(attr)); + wrbuf_insert(w, cp - cp0, " ", 1); + return; + } + while (*cp && *cp != ',') + cp++; + } + if (wrbuf_len(w)) + wrbuf_puts(w, ","); + wrbuf_puts(w, "@attr 1="); + wrbuf_write(w, field, length); + wrbuf_puts(w, " "); + wrbuf_puts(w, attr); +} + +void yaz_sru_facet_request(ODR o, Z_FacetList **facetList, const char **limit, + const char **start, const char **sort) { if (o->direction == ODR_ENCODE) { Z_FacetList *fl = *facetList; if (fl) { + WRBUF w_limit = wrbuf_alloc(); + int general_start = -1; + int general_sortorder = -1; + int general_limit = -1; int i; - WRBUF w = wrbuf_alloc(); for (i = 0; i < fl->num; i++) { struct yaz_facet_attr av; yaz_facet_attr_init(&av); + av.start = -1; + av.sortorder = -1; + av.limit = -1; yaz_facet_attr_get_z_attributes(fl->elements[i]->attributes, &av); if (av.errcode == 0) { - wrbuf_printf(w, "%d", av.limit ? av.limit : -1); - if (av.useattr) - wrbuf_printf(w, ":%s,", av.useattr); - /* av.relation not considered yet */ + if (av.limit != -1) + { + if (av.useattr) + { + wrbuf_printf(w_limit, "%d:%s", av.limit, + av.useattr); + wrbuf_puts(w_limit, ","); + } + else + general_limit = av.limit; + } + if (av.start != -1) + general_start = av.start; + if (av.sortorder != -1) + general_sortorder = av.sortorder; } } - if (wrbuf_len(w) > 0) + if (general_limit != -1) + { + char tmp[32]; + sprintf(tmp, "%d,", general_limit); + wrbuf_insert(w_limit, 0, tmp, strlen(tmp)); + } + if (wrbuf_len(w_limit) > 1) { - wrbuf_cut_right(w, 1); /* remove , */ - *limit = odr_strdup(o, wrbuf_cstr(w)); + wrbuf_cut_right(w_limit, 1); + *limit = odr_strdup(o, wrbuf_cstr(w_limit)); } - wrbuf_destroy(w); + if (general_start != -1) + { + char tmp[32]; + sprintf(tmp, "%d", general_start); + *start = odr_strdup(o, tmp); + } + if (general_sortorder == 1) + { + *sort = odr_strdup(o, "alphanumeric"); + } + wrbuf_destroy(w_limit); } } else if (o->direction == ODR_DECODE) { - const char *cp = *limit; - *facetList = 0; - if (cp) + WRBUF w = wrbuf_alloc(); + int general_limit = -1; + + if (*limit) { + const char *cp = *limit; int nor = 0; - int limit_val = 0; - WRBUF w = wrbuf_alloc(); - while (sscanf(cp, "%d%n", &limit_val, &nor) >= 1 && nor > 0) + int val = 0; + while (sscanf(cp, "%d%n", &val, &nor) >= 1 && nor > 0) { cp += nor; - if (wrbuf_len(w)) - wrbuf_puts(w, ","); if (*cp == ':') /* field name follows */ { - wrbuf_puts(w, "@attr 1="); - while (*++cp && *cp != ',') - wrbuf_putc(w, *cp); - wrbuf_puts(w, " "); + char tmp[40]; + const char *cp0 = ++cp; + while (*cp && *cp != ',') + cp++; + sprintf(tmp, "@attr 3=%d", val); + insert_field(w, cp0, cp - cp0, tmp); + + if (*start && strlen(*start) < 20) + { + sprintf(tmp, "@attr 4=%s", *start); + insert_field(w, cp0, cp - cp0, tmp); + } + if (*sort && !strcmp(*sort, "alphanumeric")) + insert_field(w, cp0, cp - cp0, "@attr 2=1"); + else + insert_field(w, cp0, cp - cp0, "@attr 2=0"); } - if (limit_val != -1) - wrbuf_printf(w, "@attr 3=%d", limit_val); + else + general_limit = val; + if (*cp != ',') break; cp++; } + } + if (*sort || *start || general_limit != -1) + { if (wrbuf_len(w)) - *facetList = yaz_pqf_parse_facet_list(o, wrbuf_cstr(w)); - wrbuf_destroy(w); + wrbuf_puts(w, ","); + if (*sort && !strcmp(*sort, "alphanumeric")) + wrbuf_printf(w, " @attr 2=1"); + else + wrbuf_printf(w, " @attr 2=0"); + if (general_limit != -1) + wrbuf_printf(w, " @attr 3=%d", general_limit); + if (*start) + { + wrbuf_printf(w, " @attr 4=%s", *start); + } } + if (wrbuf_len(w)) + *facetList = yaz_pqf_parse_facet_list(o, wrbuf_cstr(w)); + else + *facetList = 0; + wrbuf_destroy(w); } } @@ -102,11 +198,10 @@ void yaz_sru_facet_response(ODR o, Z_FacetList **facetList, xmlNodePtr n) "http://docs.oasis-open.org/ns/search-ws/facetedResults"; xmlNode *p1 = xmlNewChild(n, 0, BAD_CAST "facetedResults", 0); xmlNsPtr ns_fr = xmlNewNs(p1, BAD_CAST ns, BAD_CAST "fr"); - xmlSetNs(p1, ns_fr); for (i = 0; i < fl->num; i++) { Z_FacetField *ff = fl->elements[i]; - xmlNode *p2 = xmlNewChild(p1, 0, BAD_CAST "facet", 0); + xmlNode *p2 = xmlNewChild(p1, ns_fr, BAD_CAST "facet", 0); int j; xmlNode *p3; struct yaz_facet_attr av; @@ -164,32 +259,8 @@ void yaz_sru_facet_response(ODR o, Z_FacetList **facetList, xmlNodePtr n) p_terms = p2; } if (index_name) - { - Z_AttributeList *al = - (Z_AttributeList*) odr_malloc(o, sizeof(*al)); - Z_ComplexAttribute *ca = - (Z_ComplexAttribute *) odr_malloc(o, sizeof(*ca)); - Z_AttributeElement *ae = - (Z_AttributeElement *) odr_malloc(o, sizeof(*ae)); - al->num_attributes = 1; - al->attributes = (Z_AttributeElement **) - odr_malloc(o, sizeof(*al->attributes)); - al->attributes[0] = ae; - ae->attributeSet = 0; - ae->attributeType = odr_intdup(o, 1); - ae->which = Z_AttributeValue_complex; - ae->value.complex = ca; - ca->num_semanticAction = 0; - ca->semanticAction = 0; - ca->num_list = 1; - ca->list = (Z_StringOrNumeric **) - odr_malloc(o, sizeof(*ca->list)); - ca->list[0] = (Z_StringOrNumeric *) - odr_malloc(o, sizeof(**ca->list)); - ca->list[0]->which = Z_StringOrNumeric_string; - ca->list[0]->u.string = index_name; - ff->attributes = al; - } + ff->attributes = + zget_AttributeList_use_string(o, index_name); if (p_terms) { xmlNode *p; @@ -216,7 +287,9 @@ void yaz_sru_facet_response(ODR o, Z_FacetList **facetList, xmlNodePtr n) &cstr)) ; else if (yaz_match_xsd_integer(p2, "count", o, - &count)) + &count)) + ; + else ; } if (cstr && count)