Zebra uses string attributes for indexing internally. Using set+numeric
[idzebra-moved-to-github.git] / index / attribute.c
1 /* $Id: attribute.c,v 1.23 2006-05-19 13:49:34 adam Exp $
2    Copyright (C) 1995-2006
3    Index Data ApS
4
5 This file is part of the Zebra server.
6
7 Zebra is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Zebra; see the file LICENSE.zebra.  If not, write to the
19 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.
21 */
22
23 #include <stdio.h>
24
25 #include <yaz/log.h>
26 #include <yaz/diagbib1.h>
27 #include <idzebra/res.h>
28 #include <idzebra/util.h>
29 #include <attrfind.h>
30 #include "index.h"
31
32 static data1_att *getatt(data1_attset *p, int att)
33 {
34     data1_att *a;
35     data1_attset_child *c;
36
37     /* scan local set */
38     for (a = p->atts; a; a = a->next)
39         if (a->value == att)
40             return a;
41     /* scan included sets */
42     for (c = p->children; c; c = c->next)
43         if ((a = getatt(c->child, att)))
44             return a;
45     return 0;
46 }
47
48 static int att_getentbyatt(ZebraHandle zi, oid_value set, int att,
49                            const char **name)
50 {
51     data1_att *r;
52     data1_attset *p;
53
54     if (!(p = data1_attset_search_id (zi->reg->dh, set)))
55     {
56         zebraExplain_loadAttsets (zi->reg->dh, zi->res);
57         p = data1_attset_search_id (zi->reg->dh, set);
58     }
59     if (!p)   /* set undefined */
60         return -2;
61     if (!(r = getatt(p, att)))
62         return -1;
63     *name = r->name;
64     return 0;
65 }
66
67
68 ZEBRA_RES zebra_attr_list_get_ord(ZebraHandle zh,
69                                   Z_AttributeList *attr_list,
70                                   int index_type,
71                                   oid_value curAttributeSet,
72                                   int *ord)
73 {
74     int use_value = -1;
75     const char *use_string = 0;
76     AttrType use;
77
78     attr_init_AttrList(&use, attr_list, 1);
79     use_value = attr_find_ex(&use, &curAttributeSet, &use_string);
80
81     if (use_value < 0)
82     {
83         if (!use_string)
84             use_string = "any";
85     }
86     else
87     {
88         /* we have a use attribute and attribute set */
89         int r;
90         
91         r = att_getentbyatt(zh, curAttributeSet, use_value, &use_string);
92         if (r == -2)
93         {
94             zebra_setError_zint(zh,  YAZ_BIB1_UNSUPP_ATTRIBUTE_SET, 0);
95             return ZEBRA_FAIL;
96         }
97         if (r == -1)
98         {
99             zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,  use_value);
100             return ZEBRA_FAIL;
101         }
102     }
103     if (!use_string)
104     {
105         zebra_setError(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE, 0);
106         return ZEBRA_FAIL;
107     }
108     *ord = zebraExplain_lookup_attr_str(zh->reg->zei, index_type, use_string);
109     if (*ord == -1)
110     {
111         if (use_value < 0)
112             zebra_setError(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE, use_string);
113         else
114             zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE, use_value);
115         return ZEBRA_FAIL;
116     }
117     return ZEBRA_OK;
118 }
119
120 ZEBRA_RES zebra_apt_get_ord(ZebraHandle zh,
121                             Z_AttributesPlusTerm *zapt,
122                             int index_type,
123                             const char *xpath_use,
124                             oid_value curAttributeSet,
125                             int *ord)
126 {
127     if (!xpath_use)
128         return zebra_attr_list_get_ord(zh, zapt->attributes,
129                                        index_type, curAttributeSet, ord);
130     else
131     {
132         *ord = zebraExplain_lookup_attr_str(zh->reg->zei, index_type,
133                                             xpath_use);
134         if (*ord == -1)
135         {
136             yaz_log(YLOG_LOG, "zebra_apt_get_ord FAILED xpath=%s index_type=%c",
137                     xpath_use, index_type);
138             zebra_setError(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE, 0);
139             return ZEBRA_FAIL;
140         }
141         else
142         {
143             yaz_log(YLOG_LOG, "zebra_apt_get_ord OK xpath=%s index_type=%c",
144                     xpath_use, index_type);
145         }
146         return ZEBRA_OK;
147     }
148 }
149
150 ZEBRA_RES zebra_sort_get_ord(ZebraHandle zh,
151                              Z_SortAttributes *sortAttributes,
152                              int *ord,
153                              int *numerical)
154 {
155     AttrType structure;
156     int structure_value;
157     attr_init_AttrList(&structure, sortAttributes->list, 4);
158
159     *numerical = 0;
160     structure_value = attr_find(&structure, 0);
161     if (structure_value == 109)
162         *numerical = 1;
163     
164     if (zebra_attr_list_get_ord(zh, sortAttributes->list,
165                                 's', VAL_BIB1, ord)== ZEBRA_OK)
166         return ZEBRA_OK;
167     if (zebra_attr_list_get_ord(zh, sortAttributes->list,
168                                 'S', VAL_BIB1, ord)== ZEBRA_OK)
169         return ZEBRA_OK;
170     return ZEBRA_FAIL;
171 }
172
173
174 /*
175  * Local variables:
176  * c-basic-offset: 4
177  * indent-tabs-mode: nil
178  * End:
179  * vim: shiftwidth=4 tabstop=8 expandtab
180  */
181