#include <yaz/pquery.h>
#include <yaz/facet.h>
-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_limit, 1);
+ *limit = odr_strdup(o, wrbuf_cstr(w_limit));
+ }
+ if (general_start != -1)
+ {
+ char tmp[32];
+ sprintf(tmp, "%d", general_start);
+ *start = odr_strdup(o, tmp);
+ }
+ if (general_sortorder == 1)
{
- wrbuf_cut_right(w, 1); /* remove , */
- *limit = odr_strdup(o, wrbuf_cstr(w));
+ *sort = odr_strdup(o, "alphanumeric");
}
- wrbuf_destroy(w);
+ 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);
}
}
"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;
}
}
}
+ else if (o->direction == ODR_DECODE)
+ {
+ Z_FacetList *fl = (Z_FacetList *) odr_malloc(o, sizeof(*fl));
+ xmlNode *p1;
+
+ fl->num = 0;
+ for (p1 = n->children; p1; p1 = p1->next)
+ if (yaz_match_xsd_element(p1, "facet"))
+ fl->num++;
+ if (fl->num > 0)
+ {
+ int i = 0;
+ *facetList = fl;
+ fl->elements = (Z_FacetField **)
+ odr_malloc(o, sizeof(*fl->elements) * fl->num);
+ for (p1 = n->children; p1; p1 = p1->next)
+ if (yaz_match_xsd_element(p1, "facet"))
+ {
+ char *index_name = 0;
+ xmlNode *p_terms = 0;
+ xmlNode *p2 = p1->children;
+ Z_FacetField *ff = (Z_FacetField *)
+ odr_malloc(o, sizeof(*ff));
+ fl->elements[i++] = ff;
+ ff->attributes = 0;
+ ff->num_terms = 0;
+ ff->terms = 0;
+ for (; p2; p2 = p2->next)
+ {
+ if (yaz_match_xsd_string(p2, "index", o, &index_name))
+ ;
+ else if (yaz_match_xsd_element(p2, "terms"))
+ 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;
+ }
+ if (p_terms)
+ {
+ xmlNode *p;
+ int i = 0;
+ for (p = p_terms->children; p; p = p->next)
+ {
+ if (yaz_match_xsd_element(p, "term"))
+ ff->num_terms++;
+ }
+ if (ff->num_terms)
+ ff->terms = (Z_FacetTerm **)
+ odr_malloc(o,
+ sizeof(*ff->terms) * ff->num_terms);
+ for (p = p_terms->children; p; p = p->next)
+ {
+ if (yaz_match_xsd_element(p, "term"))
+ {
+ char *cstr = 0;
+ Odr_int *count = 0;
+ xmlNode *p2 = p->children;
+ for (; p2; p2 = p2->next)
+ {
+ if (yaz_match_xsd_string(p2, "actualTerm", o,
+ &cstr))
+ ;
+ else if (yaz_match_xsd_integer(p2, "count", o,
+ &count))
+ ;
+ }
+ if (cstr && count)
+ {
+ ff->terms[i++] =
+ facet_term_create_cstr(o, cstr, *count);
+ }
+ }
+ }
+ ff->num_terms = i;
+ if (ff->num_terms == 0)
+ ff->terms = 0;
+ }
+ }
+
+ }
+ }
}
#endif