#include <yaz/yaz-ccl.h>
#include <yaz/cql.h>
#include <yaz/log.h>
+#include <yaz/facet.h>
#if HAVE_READLINE_READLINE_H
#include <readline/readline.h>
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)
{
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;
}
facet_field->attributes = attribute_list;
facet_field->num_terms = 0;
facet_field->terms = 0;
+ //debug_add_facet_term(odr, facet_field);
+
return facet_field;
}
return 2;
}
-void display_term(Z_TermInfo *t)
+void display_term_info(Z_TermInfo *t)
{
if (t->displayTerm)
printf("%s", t->displayTerm);
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);
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 \
--- /dev/null
+
+#ifndef YAZ_FACET_H
+#define YAZ_FACET_H
+
+#include <yaz/yconfig.h>
+#include <yaz/z-core.h>
+#include <yaz/log.h>
+
+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
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 \
-- 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 {
--- /dev/null
+
+
+#include <yaz/facet.h>
+#include <yaz/diagbib1.h>
+
+/* 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 */
+
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
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;
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);
{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,