X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fsortspec.c;h=7f272f5f9b32f7aab05291127e413e7870bd8c46;hp=8d99a6738f01f7f6a573e8a2ad4d78f1c14c1fcc;hb=b161284b288325f5eb5557152d4da21d18dc8ded;hpb=05c274ef315384faafcc5900c17468f0ea2474e6 diff --git a/src/sortspec.c b/src/sortspec.c index 8d99a67..7f272f5 100644 --- a/src/sortspec.c +++ b/src/sortspec.c @@ -1,79 +1,81 @@ -/* - * Copyright (c) 1995-2004, Index Data. +/* This file is part of the YAZ toolkit. + * Copyright (C) 1995-2012 Index Data * See the file LICENSE for details. - * - * $Id: sortspec.c,v 1.3 2004-10-15 00:19:00 adam Exp $ */ /** * \file sortspec.c * \brief Implements SortSpec parsing. */ +#if HAVE_CONFIG_H +#include +#endif #include #include #include +#include -#include -#include +#include #include +#include +#include -Z_SortKeySpecList *yaz_sort_spec (ODR out, const char *arg) +Z_SortKeySpecList *yaz_sort_spec(ODR out, const char *arg) { - char sort_string_buf[32], sort_flags[32]; + char sort_string_buf[64], sort_flags[64]; Z_SortKeySpecList *sksl = (Z_SortKeySpecList *) - odr_malloc (out, sizeof(*sksl)); + odr_malloc(out, sizeof(*sksl)); int off; - + sksl->num_specs = 0; - sksl->specs = (Z_SortKeySpec **)odr_malloc (out, sizeof(sksl->specs) * 20); - - while ((sscanf (arg, "%31s %31s%n", sort_string_buf, - sort_flags, &off)) == 2 && off > 1) + sksl->specs = (Z_SortKeySpec **)odr_malloc(out, sizeof(sksl->specs) * 20); + + while ((sscanf(arg, "%63s %63s%n", sort_string_buf, + sort_flags, &off)) == 2 && off > 1) { int i; char *sort_string_sep; - char *sort_string = sort_string_buf; - Z_SortKeySpec *sks = (Z_SortKeySpec *)odr_malloc (out, sizeof(*sks)); - Z_SortKey *sk = (Z_SortKey *)odr_malloc (out, sizeof(*sk)); - + char *sort_string = sort_string_buf; + Z_SortKeySpec *sks = (Z_SortKeySpec *) odr_malloc(out, sizeof(*sks)); + Z_SortKey *sk = (Z_SortKey *) odr_malloc(out, sizeof(*sk)); + arg += off; sksl->specs[sksl->num_specs++] = sks; sks->sortElement = (Z_SortElement *) - odr_malloc (out, sizeof(*sks->sortElement)); + odr_malloc(out, sizeof(*sks->sortElement)); sks->sortElement->which = Z_SortElement_generic; sks->sortElement->u.generic = sk; - - if ((sort_string_sep = strchr (sort_string, '='))) + + if ((sort_string_sep = strchr(sort_string, '='))) { - int i = 0; + int i = 0; sk->which = Z_SortKey_sortAttributes; sk->u.sortAttributes = (Z_SortAttributes *) - odr_malloc (out, sizeof(*sk->u.sortAttributes)); - sk->u.sortAttributes->id = - yaz_oidval_to_z3950oid(out, CLASS_ATTSET, VAL_BIB1); + odr_malloc(out, sizeof(*sk->u.sortAttributes)); + sk->u.sortAttributes->id = odr_oiddup(out, yaz_oid_attset_bib_1); sk->u.sortAttributes->list = (Z_AttributeList *) - odr_malloc (out, sizeof(*sk->u.sortAttributes->list)); + odr_malloc(out, sizeof(*sk->u.sortAttributes->list)); sk->u.sortAttributes->list->attributes = (Z_AttributeElement **) - odr_malloc (out, 10 * - sizeof(*sk->u.sortAttributes->list->attributes)); - while (i < 10 && sort_string && sort_string_sep) - { - Z_AttributeElement *el = (Z_AttributeElement *) - odr_malloc (out, sizeof(*el)); - sk->u.sortAttributes->list->attributes[i] = el; - el->attributeSet = 0; - el->attributeType = odr_intdup (out, atoi (sort_string)); - el->which = Z_AttributeValue_numeric; - el->value.numeric = - odr_intdup (out, atoi (sort_string_sep + 1)); - i++; - sort_string = strchr(sort_string, ','); - if (sort_string) - { - sort_string++; - sort_string_sep = strchr (sort_string, '='); - } - } + odr_malloc(out, 10 * + sizeof(*sk->u.sortAttributes->list->attributes)); + while (i < 10 && sort_string && sort_string_sep) + { + Z_AttributeElement *el = (Z_AttributeElement *) + odr_malloc(out, sizeof(*el)); + sk->u.sortAttributes->list->attributes[i] = el; + el->attributeSet = 0; + el->attributeType = odr_intdup(out, atoi(sort_string)); + el->which = Z_AttributeValue_numeric; + el->value.numeric = + odr_intdup(out, odr_atoi(sort_string_sep + 1)); + i++; + sort_string = strchr(sort_string, ','); + if (sort_string) + { + sort_string++; + sort_string_sep = strchr(sort_string, '='); + } + } sk->u.sortAttributes->list->num_attributes = i; } else @@ -81,12 +83,12 @@ Z_SortKeySpecList *yaz_sort_spec (ODR out, const char *arg) sk->which = Z_SortKey_sortField; sk->u.sortField = odr_strdup (out, sort_string); } - sks->sortRelation = odr_intdup (out, Z_SortKeySpec_ascending); - sks->caseSensitivity = odr_intdup (out, Z_SortKeySpec_caseSensitive); + sks->sortRelation = odr_intdup(out, Z_SortKeySpec_ascending); + sks->caseSensitivity = odr_intdup(out, Z_SortKeySpec_caseInsensitive); sks->which = Z_SortKeySpec_null; sks->u.null = odr_nullval (); - + for (i = 0; sort_flags[i]; i++) { switch (sort_flags[i]) @@ -109,10 +111,342 @@ Z_SortKeySpecList *yaz_sort_spec (ODR out, const char *arg) case 's': *sks->caseSensitivity = Z_SortKeySpec_caseSensitive; break; + case '!': + sks->which = Z_SortKeySpec_abort; + sks->u.abort = odr_nullval(); + break; + case '=': + sks->which = Z_SortKeySpec_missingValueData; + sks->u.missingValueData = (Odr_oct*) + odr_malloc(out, sizeof(Odr_oct)); + i++; + sks->u.missingValueData->len = strlen(sort_flags+i); + sks->u.missingValueData->size = sks->u.missingValueData->len; + sks->u.missingValueData->buf = (unsigned char*) + odr_strdup(out, sort_flags+i); + i += strlen(sort_flags+i) - 1; + break; } } } if (!sksl->num_specs) - return 0; + return 0; return sksl; } + +int yaz_sort_spec_to_cql(Z_SortKeySpecList *sksl, WRBUF w) +{ + int i; + for (i = 0; i < sksl->num_specs; i++) + { + Z_SortKeySpec *sks = sksl->specs[i]; + Z_SortKey *sk; + + if (sks->sortElement->which != Z_SortElement_generic) + return -1; + + sk = sks->sortElement->u.generic; + if (i) + wrbuf_puts(w, " "); + else + wrbuf_puts(w, " SORTBY "); + if (sk->which == Z_SortKey_sortAttributes) + return -1; + else if (sk->which == Z_SortKey_sortField) + wrbuf_puts(w, sk->u.sortField); + switch (*sks->sortRelation) + { + case Z_SortKeySpec_ascending: + wrbuf_puts(w, "/ascending"); + break; + case Z_SortKeySpec_descending: + wrbuf_puts(w, "/descending"); + break; + } + switch (*sks->caseSensitivity) + { + case Z_SortKeySpec_caseSensitive: + wrbuf_puts(w, "/respectCase"); + break; + case Z_SortKeySpec_caseInsensitive: + wrbuf_puts(w, "/ignoreCase"); + break; + } + switch (sks->which) + { + case Z_SortKeySpec_null: + break; + case Z_SortKeySpec_abort: + wrbuf_puts(w, "/missingFail"); + break; + case Z_SortKeySpec_missingValueData: + wrbuf_puts(w, "/missingValue="); + wrbuf_write(w, (const char *) sks->u.missingValueData->buf, + sks->u.missingValueData->len); + break; + } + } + return 0; +} + +int yaz_sort_spec_to_type7(Z_SortKeySpecList *sksl, WRBUF pqf) +{ + int i; + for (i = 0; i < sksl->num_specs; i++) + { + Z_SortKeySpec *sks = sksl->specs[i]; + Z_SortKey *sk; + + if (sks->sortElement->which != Z_SortElement_generic) + return -1; + + sk = sks->sortElement->u.generic; + + wrbuf_insert(pqf, 0, "@or ", 4); + + if (sk->which == Z_SortKey_sortAttributes) + { + int j; + for (j = 0; j < sk->u.sortAttributes->list->num_attributes; j++) + { + Z_AttributeElement *el = + sk->u.sortAttributes->list->attributes[j]; + if (el->which != Z_AttributeValue_numeric) + return -1; + wrbuf_printf(pqf, " @attr " ODR_INT_PRINTF "=" ODR_INT_PRINTF, + *el->attributeType, *el->value.numeric); + } + } + else if (sk->which == Z_SortKey_sortField) + { + wrbuf_puts(pqf, " @attr 1="); + wrbuf_puts(pqf, sk->u.sortField); + } + switch (*sks->sortRelation) + { + case Z_SortKeySpec_ascending: + wrbuf_puts(pqf, " @attr 7=1 "); + break; + case Z_SortKeySpec_descending: + wrbuf_puts(pqf, " @attr 7=2 "); + break; + } + wrbuf_printf(pqf, "%d", i); + } + return 0; +} + +int yaz_sort_spec_to_srw_sortkeys(Z_SortKeySpecList *sksl, WRBUF w) +{ + int i; + for (i = 0; i < sksl->num_specs; i++) + { + Z_SortKeySpec *sks = sksl->specs[i]; + Z_SortKey *sk; + + if (sks->sortElement->which != Z_SortElement_generic) + return -1; + + sk = sks->sortElement->u.generic; + + if (i) + wrbuf_puts(w, " "); + + if (sk->which == Z_SortKey_sortAttributes) + return -1; + else if (sk->which == Z_SortKey_sortField) + { + wrbuf_puts(w, sk->u.sortField); + } + wrbuf_puts(w, ",,"); /* path is absent */ + switch (*sks->sortRelation) + { + case Z_SortKeySpec_ascending: + wrbuf_puts(w, "1"); + break; + case Z_SortKeySpec_descending: + wrbuf_puts(w, "0"); + break; + } + wrbuf_puts(w, ","); + switch (*sks->caseSensitivity) + { + case Z_SortKeySpec_caseSensitive: + wrbuf_puts(w, "1"); + break; + case Z_SortKeySpec_caseInsensitive: + wrbuf_puts(w, "0"); + break; + } + wrbuf_puts(w, ","); + switch (sks->which) + { + case Z_SortKeySpec_null: + wrbuf_puts(w, "highValue"); + break; + case Z_SortKeySpec_abort: + wrbuf_puts(w, "abort"); + break; + case Z_SortKeySpec_missingValueData: + wrbuf_write(w, (const char *) sks->u.missingValueData->buf, + sks->u.missingValueData->len); + break; + } + } + return 0; +} + +int yaz_sort_spec_to_solr_sortkeys(Z_SortKeySpecList *sksl, WRBUF w) +{ + int i; + for (i = 0; i < sksl->num_specs; i++) + { + Z_SortKeySpec *sks = sksl->specs[i]; + Z_SortKey *sk; + + if (sks->sortElement->which != Z_SortElement_generic) + return -1; + + sk = sks->sortElement->u.generic; + + if (i) + wrbuf_puts(w, ","); + + if (sk->which == Z_SortKey_sortAttributes) + return -1; + else if (sk->which == Z_SortKey_sortField) + { + wrbuf_puts(w, sk->u.sortField); + } + switch (*sks->sortRelation) + { + case Z_SortKeySpec_ascending: + wrbuf_puts(w, " asc"); + break; + case Z_SortKeySpec_descending: + wrbuf_puts(w, " desc"); + break; + } + } + return 0; +} + + +int yaz_srw_sortkeys_to_sort_spec(const char *srw_sortkeys, WRBUF w) +{ + /* sru sortkey layout: path,schema,ascending,caseSensitive,missingValue */ + /* see cql_sortby_to_sortkeys of YAZ. */ + char **sortspec; + int num_sortspec = 0; + int i; + NMEM nmem = nmem_create(); + + if (srw_sortkeys) + nmem_strsplit_blank(nmem, srw_sortkeys, &sortspec, &num_sortspec); + if (num_sortspec > 0) + { + for (i = 0; i < num_sortspec; i++) + { + char **arg; + int num_arg; + int ascending = 1; + int case_sensitive = 0; + const char *missing = 0; + nmem_strsplitx(nmem, ",", sortspec[i], &arg, &num_arg, 0); + + if (num_arg > 2 && arg[2][0]) + ascending = atoi(arg[2]); + if (num_arg > 3 && arg[3][0]) + case_sensitive = atoi(arg[3]); + if (num_arg > 4 && arg[4][0]) + missing = arg[4]; + + if (i) + wrbuf_puts(w, " "); + + wrbuf_puts(w, arg[0]); /* field */ + wrbuf_puts(w, " "); + + wrbuf_puts(w, ascending ? "a" : "d"); + wrbuf_puts(w, case_sensitive ? "s" : "i"); + if (missing) + { + if (!strcmp(missing, "omit")) { + ; + } + else if (!strcmp(missing, "abort")) + wrbuf_puts(w, "!"); + else if (!strcmp(missing, "lowValue")) { + ; + } + else if (!strcmp(missing, "highValue")) { + ; + } + else + { + wrbuf_puts(w, "="); + wrbuf_puts(w, missing); + } + } + } + } + nmem_destroy(nmem); + return 0; +} + +int yaz_solr_sortkeys_to_sort_spec(const char *solr_sortkeys, WRBUF w) +{ + /* Solr sortkey layout: field order[, field order] */ + /* see cql_sortby_to_sortkeys of YAZ. */ + char **sortspec; + int num_sortspec = 0; + int i; + NMEM nmem = nmem_create(); + + if (solr_sortkeys) + nmem_strsplit(nmem, ",", solr_sortkeys, &sortspec, &num_sortspec); + if (num_sortspec > 0) + { + for (i = 0; i < num_sortspec; i++) + { + char **arg; + int num_arg; + char order = 'a'; + int case_sensitive = 0; + nmem_strsplitx(nmem, " ", sortspec[i], &arg, &num_arg, 0); + + if (num_arg != 2) + return -1; + + if (yaz_matchstr(arg[1], "asc") && + yaz_matchstr(arg[1], "desc")) + return -1; + + if (arg[1][0]) { + order = tolower(arg[1][0]); + } + if (i) + wrbuf_puts(w, " "); + + wrbuf_puts(w, arg[0]); /* field */ + wrbuf_puts(w, " "); + + wrbuf_putc(w, order); + // Always in-sensitive + wrbuf_puts(w, case_sensitive ? "s" : "i"); + } + } + nmem_destroy(nmem); + return 0; +} + + +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ +