1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) 1995-2010 Index Data
3 * See the file LICENSE for details.
8 * \brief Facet utilities
15 #include <yaz/facet.h>
16 #include <yaz/diagbib1.h>
17 #include <yaz/oid_db.h>
18 #include <yaz/oid_std.h>
19 #include <yaz/otherinfo.h>
22 /* Little helper to extract a string attribute */
23 /* Gets the first string, there is usually only one */
24 /* in case of errors, returns null */
26 void facet_struct_init(struct attrvalues *attr_values) {
27 attr_values->errcode = 0;
28 attr_values->errstring = 0;
29 attr_values->relation = 0;
30 attr_values->useattr = 0;
31 attr_values->useattrbuff[0] = 0;
32 attr_values->limit = 0;
35 const char *stringattr( Z_ComplexAttribute *c ) {
37 Z_StringOrNumeric *son;
38 for ( i = 0; i < c->num_list; i++ ) {
40 if ( son->which == Z_StringOrNumeric_string )
46 /* Use attribute, @attr1, can be numeric or string */
47 void useattr ( Z_AttributeElement *ae,
48 struct attrvalues *av )
51 if ( ae->which == Z_AttributeValue_complex ) {
52 s = stringattr( ae->value.complex );
53 yaz_log(YLOG_DEBUG, "useattr %s %s", s, av->useattr);
57 else { /* already seen one, can't have duplicates */
58 av->errcode = YAZ_BIB1_UNSUPP_ATTRIBUTE_COMBI;
59 av->errstring = "multiple use attributes";
61 } else { /* complex that did not return a string */
62 av->errcode = YAZ_BIB1_UNSUPP_ATTRIBUTE_COMBI;
63 av->errstring = "non-string complex attribute";
65 } else { /* numeric - could translate 4 to 'title' etc */
66 sprintf(av->useattrbuff, ODR_INT_PRINTF, *ae->value.numeric );
67 av->useattr = av->useattrbuff;
72 /* TODO rename to sortorder attr */
73 void relationattr ( Z_AttributeElement *ae,
74 struct attrvalues *av )
76 if ( ae->which == Z_AttributeValue_numeric ) {
77 if ( *ae->value.numeric == 0 )
78 av->relation = "desc";
79 else if ( *ae->value.numeric == 1 )
82 if ( *ae->value.numeric == 3 ) {
83 av->relation = "unknown/unordered";
85 av->errcode = YAZ_BIB1_UNSUPP_RELATION_ATTRIBUTE;
86 sprintf(av->useattrbuff, ODR_INT_PRINTF,
88 av->errstring = av->useattrbuff;
91 av->errcode = YAZ_BIB1_UNSUPP_RELATION_ATTRIBUTE;
92 av->errstring = "non-numeric relation attribute";
96 void limitattr ( Z_AttributeElement *ae,
97 struct attrvalues *av )
99 /* TODO - check numeric first, then value! */
100 if ( ae->which == Z_AttributeValue_numeric ) {
101 av->limit = *ae->value.numeric;
102 yaz_log(YLOG_DEBUG, "limitattr %d ", av->limit);
104 av->errcode = YAZ_BIB1_UNSUPP_ATTRIBUTE;
105 av->errstring = "non-numeric limit attribute";
109 /* Get the index to be searched from the attributes.
111 can be either "string", or some well-known value like
113 Returns a null and sets errors in rr,
114 emtpy string if no attr found,
115 or the string itself - always a pointer to the Z-structs,
116 so no need to free that string!
119 void facetattrs( Z_AttributeList *attributes,
120 struct attrvalues *av )
123 Z_AttributeElement *ae;
124 yaz_log(YLOG_DEBUG, "Attribute num attributes: %d", attributes->num_attributes);
125 for ( i=0; i < attributes->num_attributes; i++ ) {
126 ae = attributes->attributes[i];
127 /* ignoring the attributeSet here */
128 yaz_log(YLOG_DEBUG, "Attribute type %d", (int) *ae->attributeType);
129 if ( *ae->attributeType == 1 ) { /* use attribute */
131 } else if ( *ae->attributeType == 2 ) { /* sortorder */
132 relationattr(ae, av);
133 } else if ( *ae->attributeType == 3 ) { /* limit */
135 } else { /* unknown attribute */
136 av->errcode = YAZ_BIB1_UNSUPP_ATTRIBUTE_TYPE;
137 sprintf(av->useattrbuff, ODR_INT_PRINTF,
138 *ae-> attributeType);
139 av->errstring = av->useattrbuff;
140 yaz_log(YLOG_DEBUG, "Unsupported attribute type %s", av->useattrbuff);
141 /* would like to give a better message, but the standard */
142 /* tells me to return the attribute type */
145 return; /* no need to dig deeper, return on first error */
151 Z_FacetList *extract_facet_request(ODR odr, Z_OtherInformation *search_input) {
152 Z_FacetList *facet_list = yaz_oi_get_facetlist_oid(&search_input, odr, yaz_oid_userinfo_facet_1, 1, 0);
156 Z_Term *term_create(ODR odr, const char *cstr) {
157 Z_Term *term = odr_malloc(odr, sizeof(*term));
158 term->which = Z_Term_characterString;
159 term->u.characterString = odr_strdup(odr, cstr);
163 Z_FacetTerm* facet_term_create(ODR odr, Z_Term *term, int freq) {
164 Z_FacetTerm *facet_term = odr_malloc(odr, sizeof(*facet_term));
165 facet_term->count = odr_malloc(odr, sizeof(*facet_term->count));
166 facet_term->term = term;
167 *facet_term->count = freq;
171 Z_FacetField* facet_field_create(ODR odr, Z_AttributeList *attributes, int num_terms) {
172 Z_FacetField *facet_field = odr_malloc(odr, sizeof(*facet_field));
173 facet_field->attributes = attributes;
174 facet_field->num_terms = num_terms;
175 facet_field->terms = odr_malloc(odr, num_terms * sizeof(*facet_field->terms));
179 void facet_field_term_set(ODR odr, Z_FacetField *field, Z_FacetTerm *facet_term, int index) {
180 assert(0 <= index && index < field->num_terms);
181 field->terms[index] = facet_term;
184 Z_FacetList* facet_list_create(ODR odr, int num_facets) {
185 Z_FacetList *facet_list = odr_malloc(odr, sizeof(*facet_list));
186 facet_list->num = num_facets;
187 facet_list->elements = odr_malloc(odr, facet_list->num * sizeof(*facet_list->elements));
191 void facet_list_field_set(ODR odr, Z_FacetList *list, Z_FacetField *field, int index) {
192 assert(0 <= index && index < list->num);
193 list->elements[index] = field;
199 * c-file-style: "Stroustrup"
200 * indent-tabs-mode: nil
202 * vim: shiftwidth=4 tabstop=8 expandtab