From: Dennis Schafroth Date: Thu, 15 Jul 2010 12:41:09 +0000 (+0200) Subject: Merge branch 'master' of ssh://git.indexdata.com/home/git/pub/yaz X-Git-Tag: v4.0.12~50 X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=commitdiff_plain;h=fe68107992cae293f6c2a3e2058ebfb5b09052a9;hp=c2d4d247b3fe28f7c191fbc3644c8e011e1a4fea Merge branch 'master' of ssh://git.indexdata.com/home/git/pub/yaz --- diff --git a/client/client.c b/client/client.c index 01ae6e2..d2ab870 100644 --- a/client/client.c +++ b/client/client.c @@ -62,6 +62,7 @@ #include #include #include +#include #if HAVE_READLINE_READLINE_H #include @@ -1611,6 +1612,24 @@ static int send_searchRequest(const char *arg) return 2; } +static void display_term(Z_Term *term) { + switch (term->which) + { + case Z_Term_general: + printf("%.*s", term->u.general->len, term->u.general->buf); + break; + case Z_Term_characterString: + printf("%s", term->u.characterString); + break; + case Z_Term_numeric: + printf(ODR_INT_PRINTF, *term->u.numeric); + break; + case Z_Term_null: + printf("null"); + break; + } +} + /* display Query Expression as part of searchResult-1 */ static void display_queryExpression(const char *lead, Z_QueryExpression *qe) { @@ -1622,46 +1641,43 @@ static void display_queryExpression(const char *lead, Z_QueryExpression *qe) if (qe->u.term->queryTerm) { Z_Term *term = qe->u.term->queryTerm; - switch (term->which) - { - case Z_Term_general: - printf("%.*s", term->u.general->len, term->u.general->buf); - break; - case Z_Term_characterString: - printf("%s", term->u.characterString); - break; - case Z_Term_numeric: - printf(ODR_INT_PRINTF, *term->u.numeric); - break; - case Z_Term_null: - printf("null"); - break; + display_term(term); + } + } +} + +static void display_facet(Z_FacetField *facet) { + if (facet->attributes) { + Z_AttributeList *al = facet->attributes; + struct attrvalues attr_values; + attr_values.errcode = 0; + attr_values.limit = -1; + attr_values.useattr = 0; + attr_values.relation = "default"; + + facetattrs(al, &attr_values); + if (!attr_values.errcode) { + int term_index; + printf("Facet: %s (%d): \n", attr_values.useattr, /* attr_values.relation, attr_values.limit, */ facet->num_terms); + for (term_index = 0 ; term_index < facet->num_terms; term_index++) { + Z_FacetTerm *facetTerm = facet->terms[term_index]; + display_term(facetTerm->term); +s printf(" (" NMEM_INT_PRINTF ")\n", *facetTerm->count); } } + } } static void* display_facets(Z_FacetList *fl) { - int index, attribute_index; - printf("UserFacets-1:"); + int index; + printf("Facets (%d): \n", fl->num); + for (index = 0; index < fl->num ; index++) { if (index) printf(","); - if (!fl->elements[index]->attributes) { - Z_AttributeList *al = fl->elements[index]->attributes; - for (attribute_index = 0; attribute_index < al->num_attributes; attribute_index++) { - switch (al->attributes[attribute_index]->which) { - case Z_AttributeValue_complex: - break; - case Z_AttributeValue_numeric: - break; - default: - break; - }; - } - } - + display_facet(fl->elements[index]); } return 0; } @@ -2863,6 +2879,8 @@ static Z_FacetField* parse_facet(ODR odr, const char *facet, int length) facet_field->attributes = attribute_list; facet_field->num_terms = 0; facet_field->terms = 0; + //debug_add_facet_term(odr, facet_field); + return facet_field; } @@ -3406,7 +3424,7 @@ int send_sortrequest(const char *arg, int newset) return 2; } -void display_term(Z_TermInfo *t) +void display_term_info(Z_TermInfo *t) { if (t->displayTerm) printf("%s", t->displayTerm); @@ -3448,7 +3466,7 @@ void process_scanResponse(Z_ScanResponse *res) if (entries[i]->which == Z_Entry_termInfo) { printf("%c ", i + 1 == pos_term ? '*' : ' '); - display_term(entries[i]->u.termInfo); + display_term_info(entries[i]->u.termInfo); } else display_diagrecs(&entries[i]->u.surrogateDiagnostic, 1); diff --git a/include/yaz/Makefile.am b/include/yaz/Makefile.am index 1ee66ac..f4e6548 100644 --- a/include/yaz/Makefile.am +++ b/include/yaz/Makefile.am @@ -5,7 +5,7 @@ noinst_HEADERS = icu_I18N.h pkginclude_HEADERS= backend.h ccl.h ccl_xml.h cql.h rpn2cql.h comstack.h \ diagbib1.h diagsrw.h diagsru_update.h sortspec.h log.h logrpn.h marcdisp.h \ - nmem.h nmem_xml.h odr.h errno.h \ + nmem.h nmem_xml.h odr.h errno.h facet.h \ options.h otherinfo.h pquery.h prt-ext.h querytowrbuf.h \ readconf.h record_conv.h retrieval.h statserv.h \ tcpip.h test.h timing.h unix.h tpath.h wrbuf.h xmalloc.h \ diff --git a/include/yaz/facet.h b/include/yaz/facet.h new file mode 100644 index 0000000..687ce54 --- /dev/null +++ b/include/yaz/facet.h @@ -0,0 +1,51 @@ + +#ifndef YAZ_FACET_H +#define YAZ_FACET_H + +#include +#include +#include + +YAZ_BEGIN_CDECL + + +/* + * Helper function for extracting facet values from the ASN structures. + * + */ + +/* A helper structure to extract all the attribute stuff + from one Z_AttributesList. The pointers will all be to + the Z-structures, or to constants, so there is no need to + worry about freeing them */ +struct attrvalues { + int errcode; /* set in case of errors */ + char *errstring; /* opt */ + const char *useattr; /* @attr 1, from a string attr */ + /* or number converted to a string */ + /* defaults to 'any' */ + char useattrbuff[30]; /* for converting numbers to strings */ + char *relation; /* @attr 2, defaults to '=' */ + int limit; /* for facet attributes */ +}; + + +/* Use attribute, @attr1, can be numeric or string */ +YAZ_EXPORT +void useattr ( Z_AttributeElement *ae, struct attrvalues *av ); + +YAZ_EXPORT +void relationattr ( Z_AttributeElement *ae, struct attrvalues *av ); + +YAZ_EXPORT +void limitattr ( Z_AttributeElement *ae, struct attrvalues *av ); + +YAZ_EXPORT +void limitattr ( Z_AttributeElement *ae, struct attrvalues *av ); + +YAZ_EXPORT +void facetattrs( Z_AttributeList *attributes, struct attrvalues *av ); + + + +#endif diff --git a/src/Makefile.am b/src/Makefile.am index 2e5cec2..e79d237 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -77,7 +77,7 @@ libyaz_la_SOURCES=version.c options.c log.c \ wrbuf.c oid_db.c errno.c \ nmemsdup.c xmalloc.c readconf.c tpath.c nmem.c matchstr.c atoin.c \ siconv.c iconv-p.h utf8.c ucs4.c iso5428.c advancegreek.c \ - odr_bool.c ber_bool.c ber_len.c ber_tag.c odr_util.c \ + odr_bool.c ber_bool.c ber_len.c ber_tag.c odr_util.c facet.c \ odr_null.c ber_null.c odr_int.c ber_int.c odr_tag.c odr_cons.c \ odr_seq.c odr_oct.c ber_oct.c odr_bit.c ber_bit.c odr_oid.c \ ber_oid.c odr_use.c odr_choice.c odr_any.c ber_any.c odr.c odr_mem.c \ diff --git a/src/facet.asn b/src/facet.asn index 7a32e71..f22eedf 100644 --- a/src/facet.asn +++ b/src/facet.asn @@ -10,7 +10,7 @@ FacetField ::= SEQUENCE { -- 2=sortorder 0=most frequent, 1=least frequent, .. -- 3=limit (integer) attributes [1] IMPLICIT AttributeList, - terms [2] IMPLICIT SEQUENCE OF FacetTerm OPTIONAL + terms [2] IMPLICIT SEQUENCE OF FacetTerm OPTIONAL } FacetTerm ::= SEQUENCE { diff --git a/src/facet.c b/src/facet.c new file mode 100644 index 0000000..7baee6b --- /dev/null +++ b/src/facet.c @@ -0,0 +1,120 @@ + + +#include +#include + +/* Little helper to extract a string attribute */ +/* Gets the first string, there is usually only one */ +/* in case of errors, returns null */ +const char *stringattr( Z_ComplexAttribute *c ) { + int i; + Z_StringOrNumeric *son; + for ( i = 0; i < c->num_list; i++ ) { + son = c->list[i]; + if ( son->which == Z_StringOrNumeric_string ) + return son->u.string; + } + return 0; +} + +/* Use attribute, @attr1, can be numeric or string */ +void useattr ( Z_AttributeElement *ae, + struct attrvalues *av ) +{ + const char *s; + if ( ae->which == Z_AttributeValue_complex ) { + s = stringattr( ae->value.complex ); + if (s) { + if (!av->useattr) + av->useattr = s; + else { /* already seen one, can't have duplicates */ + av->errcode = YAZ_BIB1_UNSUPP_ATTRIBUTE_COMBI; + av->errstring = "multiple use attributes"; + } + } else { /* complex that did not return a string */ + av->errcode = YAZ_BIB1_UNSUPP_ATTRIBUTE_COMBI; + av->errstring = "non-string complex attribute"; + } + } else { /* numeric - could translate 4 to 'title' etc */ + sprintf(av->useattrbuff, ODR_INT_PRINTF, *ae->value.numeric ); + av->useattr = av->useattrbuff; + } +} /* useattr */ + + +/* TODO rename to sortorder attr */ +void relationattr ( Z_AttributeElement *ae, + struct attrvalues *av ) +{ + if ( ae->which == Z_AttributeValue_numeric ) { + if ( *ae->value.numeric == 0 ) + av->relation = "desc"; + else if ( *ae->value.numeric == 1 ) + av->relation = "asc"; + else + if ( *ae->value.numeric == 3 ) { + av->relation = "unknown/unordered"; + } else { + av->errcode = YAZ_BIB1_UNSUPP_RELATION_ATTRIBUTE; + sprintf(av->useattrbuff, ODR_INT_PRINTF, + *ae-> attributeType); + av->errstring = av->useattrbuff; + } + } else { + av->errcode = YAZ_BIB1_UNSUPP_RELATION_ATTRIBUTE; + av->errstring = "non-numeric relation attribute"; + } +} /* relationattr */ + +void limitattr ( Z_AttributeElement *ae, + struct attrvalues *av ) +{ + /* TODO - check numeric first, then value! */ + if ( ae->which == Z_AttributeValue_numeric ) { + av->limit = *ae->value.numeric; + } else { + av->errcode = YAZ_BIB1_UNSUPP_ATTRIBUTE; + av->errstring = "non-numeric limit attribute"; + } +} /* relationattr */ + +/* Get the index to be searched from the attributes. + @attr 1 + can be either "string", or some well-known value like + 4 for title + Returns a null and sets errors in rr, + emtpy string if no attr found, + or the string itself - always a pointer to the Z-structs, + so no need to free that string! +*/ + +void facetattrs( Z_AttributeList *attributes, + struct attrvalues *av ) +{ + int i; + Z_AttributeElement *ae; + for ( i=0; i < attributes->num_attributes; i++ ) { + ae = attributes->attributes[i]; + /* ignoring the attributeSet here */ + if ( *ae->attributeType == 1 ) { /* use attribute */ + useattr(ae, av); + } else if ( *ae->attributeType == 2 ) { /* sortorder */ + relationattr(ae, av); + } else if ( *ae->attributeType == 3 ) { /* limit */ + limitattr(ae, av); + } else { /* unknown attribute */ + av->errcode = YAZ_BIB1_UNSUPP_ATTRIBUTE_TYPE; + sprintf(av->useattrbuff, ODR_INT_PRINTF, + *ae-> attributeType); + av->errstring = av->useattrbuff; + yaz_log(YLOG_DEBUG,"Unsupported attribute type %s", + av->useattrbuff); + /* would like to give a better message, but the standard */ + /* tells me to return the attribute type */ + } + if ( av->errcode ) + return; /* no need to dig deeper, return on first error */ + } + return; +} /* facetattrs */ + diff --git a/src/otherinfo.c b/src/otherinfo.c index 9d7e083..7fa2635 100644 --- a/src/otherinfo.c +++ b/src/otherinfo.c @@ -197,6 +197,24 @@ void yaz_oi_set_facetlist_oid ( oi->information.externallyDefinedInfo = z_external; } +Z_FacetList *yaz_oi_get_facetlist_oid ( + Z_OtherInformation **otherInformation, ODR odr, + const Odr_oid *oid, int categoryValue, int delete_flag) +{ + Z_External *z_external = 0; + Z_OtherInformationUnit *oi = + yaz_oi_update(otherInformation, odr, oid, categoryValue, delete_flag); + if (!oi) + return 0; + z_external = oi->information.externallyDefinedInfo; + + if (z_external && z_external->which == Z_External_userFacets) { + return z_external->u.facetList; + } + return 0; +} + + /* * Local variables: * c-basic-offset: 4 diff --git a/src/pquery.c b/src/pquery.c index 63aa7b9..3b416bb 100644 --- a/src/pquery.c +++ b/src/pquery.c @@ -119,7 +119,7 @@ static int lex(struct yaz_pqf_parser *li) return li->query_look = query_token(li); } -static int escape_string(char *out_buf, const char *in, int len) +int escape_string(char *out_buf, const char *in, int len) { char *out = out_buf; @@ -307,11 +307,11 @@ static Z_AttributesPlusTerm *rpn_term_attributes(struct yaz_pqf_parser *li, ODR Z_Term *term; zapt = (Z_AttributesPlusTerm *)odr_malloc(o, sizeof(*zapt)); - term_octet = (Odr_oct *)odr_malloc(o, sizeof(*term_octet)); term = (Z_Term *)odr_malloc(o, sizeof(*term)); zapt->term = term; zapt->attributes = attributes; + term_octet = (Odr_oct *)odr_malloc(o, sizeof(*term_octet)); term_octet->buf = (unsigned char *)odr_malloc(o, 1 + li->lex_len); term_octet->size = term_octet->len = escape_string((char *) (term_octet->buf), li->lex_buf, li->lex_len); diff --git a/src/prt-ext.c b/src/prt-ext.c index fc760f7..ccd2999 100644 --- a/src/prt-ext.c +++ b/src/prt-ext.c @@ -144,7 +144,7 @@ int z_External(ODR o, Z_External **p, int opt, const char *name) {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_userInfo1, (Odr_fun)z_OtherInformation, 0}, {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_userFacets, - (Odr_fun)z_FacetList, 0}, + (Odr_fun)z_FacetList, "FacetList" }, {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_charSetandLanguageNegotiation, (Odr_fun)z_CharSetandLanguageNegotiation, 0}, {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_acfPrompt1,