1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) 1995-2011 Index Data
3 * See the file LICENSE for details.
7 * \brief Implements SortSpec parsing.
17 #include <yaz/z-core.h>
18 #include <yaz/sortspec.h>
19 #include <yaz/oid_db.h>
20 #include <yaz/wrbuf.h>
22 Z_SortKeySpecList *yaz_sort_spec(ODR out, const char *arg)
24 char sort_string_buf[64], sort_flags[64];
25 Z_SortKeySpecList *sksl = (Z_SortKeySpecList *)
26 odr_malloc (out, sizeof(*sksl));
30 sksl->specs = (Z_SortKeySpec **)odr_malloc(out, sizeof(sksl->specs) * 20);
32 while ((sscanf(arg, "%63s %63s%n", sort_string_buf,
33 sort_flags, &off)) == 2 && off > 1)
36 char *sort_string_sep;
37 char *sort_string = sort_string_buf;
38 Z_SortKeySpec *sks = (Z_SortKeySpec *) odr_malloc(out, sizeof(*sks));
39 Z_SortKey *sk = (Z_SortKey *) odr_malloc(out, sizeof(*sk));
42 sksl->specs[sksl->num_specs++] = sks;
43 sks->sortElement = (Z_SortElement *)
44 odr_malloc (out, sizeof(*sks->sortElement));
45 sks->sortElement->which = Z_SortElement_generic;
46 sks->sortElement->u.generic = sk;
48 if ((sort_string_sep = strchr(sort_string, '=')))
51 sk->which = Z_SortKey_sortAttributes;
52 sk->u.sortAttributes = (Z_SortAttributes *)
53 odr_malloc(out, sizeof(*sk->u.sortAttributes));
54 sk->u.sortAttributes->id = odr_oiddup(out, yaz_oid_attset_bib_1);
55 sk->u.sortAttributes->list = (Z_AttributeList *)
56 odr_malloc(out, sizeof(*sk->u.sortAttributes->list));
57 sk->u.sortAttributes->list->attributes = (Z_AttributeElement **)
59 sizeof(*sk->u.sortAttributes->list->attributes));
60 while (i < 10 && sort_string && sort_string_sep)
62 Z_AttributeElement *el = (Z_AttributeElement *)
63 odr_malloc (out, sizeof(*el));
64 sk->u.sortAttributes->list->attributes[i] = el;
66 el->attributeType = odr_intdup(out, atoi(sort_string));
67 el->which = Z_AttributeValue_numeric;
69 odr_intdup(out, odr_atoi(sort_string_sep + 1));
71 sort_string = strchr(sort_string, ',');
75 sort_string_sep = strchr(sort_string, '=');
78 sk->u.sortAttributes->list->num_attributes = i;
82 sk->which = Z_SortKey_sortField;
83 sk->u.sortField = odr_strdup (out, sort_string);
85 sks->sortRelation = odr_intdup(out, Z_SortKeySpec_ascending);
86 sks->caseSensitivity = odr_intdup(out, Z_SortKeySpec_caseInsensitive);
88 sks->which = Z_SortKeySpec_null;
89 sks->u.null = odr_nullval ();
91 for (i = 0; sort_flags[i]; i++)
93 switch (sort_flags[i])
98 *sks->sortRelation = Z_SortKeySpec_descending;
103 *sks->sortRelation = Z_SortKeySpec_ascending;
107 *sks->caseSensitivity = Z_SortKeySpec_caseInsensitive;
111 *sks->caseSensitivity = Z_SortKeySpec_caseSensitive;
114 sks->which = Z_SortKeySpec_abort;
115 sks->u.abort = odr_nullval();
118 sks->which = Z_SortKeySpec_missingValueData;
119 sks->u.missingValueData = (Odr_oct*)
120 odr_malloc(out, sizeof(Odr_oct));
122 sks->u.missingValueData->len = strlen(sort_flags+i);
123 sks->u.missingValueData->size = sks->u.missingValueData->len;
124 sks->u.missingValueData->buf = (unsigned char*)
125 odr_strdup(out, sort_flags+i);
126 i += strlen(sort_flags+i);
130 if (!sksl->num_specs)
135 int yaz_sort_spec_to_cql(Z_SortKeySpecList *sksl, WRBUF w)
138 for (i = 0; i < sksl->num_specs; i++)
140 Z_SortKeySpec *sks = sksl->specs[i];
143 if (sks->sortElement->which != Z_SortElement_generic)
146 sk = sks->sortElement->u.generic;
150 wrbuf_puts(w, " SORTBY ");
151 if (sk->which == Z_SortKey_sortAttributes)
153 else if (sk->which == Z_SortKey_sortField)
154 wrbuf_puts(w, sk->u.sortField);
155 switch (*sks->sortRelation)
157 case Z_SortKeySpec_ascending:
158 wrbuf_puts(w, "/ascending");
160 case Z_SortKeySpec_descending:
161 wrbuf_puts(w, "/descending");
164 switch (*sks->caseSensitivity)
166 case Z_SortKeySpec_caseSensitive:
167 wrbuf_puts(w, "/respectCase");
169 case Z_SortKeySpec_caseInsensitive:
170 wrbuf_puts(w, "/ignoreCase");
175 case Z_SortKeySpec_null:
177 case Z_SortKeySpec_abort:
178 wrbuf_puts(w, "/missingFail");
180 case Z_SortKeySpec_missingValueData:
181 wrbuf_puts(w, "/missingValue=");
182 wrbuf_write(w, (const char *) sks->u.missingValueData->buf,
183 sks->u.missingValueData->len);
189 int yaz_sort_spec_to_type7(Z_SortKeySpecList *sksl, WRBUF pqf)
192 for (i = 0; i < sksl->num_specs; i++)
194 Z_SortKeySpec *sks = sksl->specs[i];
197 if (sks->sortElement->which != Z_SortElement_generic)
200 sk = sks->sortElement->u.generic;
202 wrbuf_insert(pqf, 0, "@or ", 4);
204 if (sk->which == Z_SortKey_sortAttributes)
207 for (j = 0; j < sk->u.sortAttributes->list->num_attributes; j++)
209 Z_AttributeElement *el =
210 sk->u.sortAttributes->list->attributes[j];
211 if (el->which != Z_AttributeValue_numeric)
213 wrbuf_printf(pqf, " @attr " ODR_INT_PRINTF "=" ODR_INT_PRINTF,
214 *el->attributeType, *el->value.numeric);
217 else if (sk->which == Z_SortKey_sortField)
219 wrbuf_puts(pqf, " @attr 1=");
220 wrbuf_puts(pqf, sk->u.sortField);
222 switch (*sks->sortRelation)
224 case Z_SortKeySpec_ascending:
225 wrbuf_puts(pqf, " @attr 7=1 ");
227 case Z_SortKeySpec_descending:
228 wrbuf_puts(pqf, " @attr 7=2 ");
231 wrbuf_printf(pqf, "%d", i);
236 int yaz_sort_spec_to_srw_sortkeys(Z_SortKeySpecList *sksl, WRBUF w)
239 for (i = 0; i < sksl->num_specs; i++)
241 Z_SortKeySpec *sks = sksl->specs[i];
244 if (sks->sortElement->which != Z_SortElement_generic)
247 sk = sks->sortElement->u.generic;
252 if (sk->which == Z_SortKey_sortAttributes)
254 else if (sk->which == Z_SortKey_sortField)
256 wrbuf_puts(w, sk->u.sortField);
258 wrbuf_puts(w, ",,"); /* path is absent */
259 switch (*sks->sortRelation)
261 case Z_SortKeySpec_ascending:
264 case Z_SortKeySpec_descending:
269 switch (*sks->caseSensitivity)
271 case Z_SortKeySpec_caseSensitive:
274 case Z_SortKeySpec_caseInsensitive:
281 case Z_SortKeySpec_null:
282 wrbuf_puts(w, "highValue");
284 case Z_SortKeySpec_abort:
285 wrbuf_puts(w, "abort");
287 case Z_SortKeySpec_missingValueData:
288 wrbuf_write(w, (const char *) sks->u.missingValueData->buf,
289 sks->u.missingValueData->len);
295 int yaz_srw_sortkeys_to_sort_spec(const char *srw_sortkeys, WRBUF w)
297 /* sru sortkey layout: path,schema,ascending,caseSensitive,missingValue */
298 /* see cql_sortby_to_sortkeys of YAZ. */
300 int num_sortspec = 0;
302 NMEM nmem = nmem_create();
305 nmem_strsplit_blank(nmem, srw_sortkeys, &sortspec, &num_sortspec);
306 if (num_sortspec > 0)
308 for (i = 0; i < num_sortspec; i++)
313 int case_sensitive = 0;
314 const char *missing = 0;
315 nmem_strsplitx(nmem, ",", sortspec[i], &arg, &num_arg, 0);
317 if (num_arg > 2 && arg[2][0])
318 ascending = atoi(arg[2]);
319 if (num_arg > 3 && arg[3][0])
320 case_sensitive = atoi(arg[3]);
321 if (num_arg > 4 && arg[4][0])
327 wrbuf_puts(w, arg[0]); /* field */
330 wrbuf_puts(w, ascending ? "a" : "d");
331 wrbuf_puts(w, case_sensitive ? "s" : "i");
334 if (!strcmp(missing, "omit"))
336 else if (!strcmp(missing, "abort"))
338 else if (!strcmp(missing, "lowValue"))
340 else if (!strcmp(missing, "highValue"))
345 wrbuf_puts(w, missing);
357 * c-file-style: "Stroustrup"
358 * indent-tabs-mode: nil
360 * vim: shiftwidth=4 tabstop=8 expandtab