YAZ 5.37.0
zoom-query.c
Go to the documentation of this file.
1/* This file is part of the YAZ toolkit.
2 * Copyright (C) Index Data
3 * See the file LICENSE for details.
4 */
9#if HAVE_CONFIG_H
10#include <config.h>
11#endif
12
13#include <assert.h>
14#include <string.h>
15#include <errno.h>
16#include "zoom-p.h"
17
18#include <yaz/yaz-util.h>
19#include <yaz/xmalloc.h>
20#include <yaz/log.h>
21#include <yaz/pquery.h>
22#include <yaz/cql.h>
23#include <yaz/ccl.h>
24#include <yaz/sortspec.h>
25#include <yaz/snprintf.h>
26
27#define SORT_STRATEGY_Z3950 0
28#define SORT_STRATEGY_TYPE7 1
29#define SORT_STRATEGY_CQL 2
30#define SORT_STRATEGY_SRU11 3
31#define SORT_STRATEGY_EMBED 4
32#define SORT_STRATEGY_SOLR 5
33
46
47static int generate(ZOOM_query s)
48{
49 if (s->query_string)
50 {
51 Z_External *ext;
52
56
58 {
59 int r = 0;
61
62 switch (s->sort_strategy)
63 {
66 break;
69 break;
70 }
71 if (r)
72 return r;
73 }
74 switch (s->query_type)
75 {
76 case Z_Query_type_1: /* RPN */
77 if (s->sort_spec &&
80 {
82 if (r)
83 return r;
84 }
86 sizeof(*s->z_query));
88 s->z_query->u.type_1 =
90 if (!s->z_query->u.type_1)
91 {
92 s->z_query = 0;
93 return -1;
94 }
95 break;
96 case Z_Query_type_104: /* CQL */
97 if (s->sort_spec &&
100 {
102 if (r)
103 return r;
104 }
105 ext = (Z_External *) odr_malloc(s->odr_query, sizeof(*ext));
108 ext->indirect_reference = 0;
109 ext->descriptor = 0;
110 ext->which = Z_External_CQL;
112
113 s->z_query = (Z_Query *) odr_malloc(s->odr_query, sizeof(*s->z_query));
115 s->z_query->u.type_104 = ext;
116
117 break;
118 }
119 }
120 return 0;
121}
122
124{
126 return wrbuf_cstr(s->sru11_sort_spec);
127 return 0;
128}
129
134
139
141{
142 return wrbuf_cstr(s->full_query);
143}
144
146{
147 wrbuf_printf(w, "%d;", s->query_type);
148 if (s->query_string)
150 wrbuf_printf(w, ";%d;", s->sort_strategy);
151 if (s->sort_spec)
153}
154
155/*
156 * Returns an xmalloc()d string containing RPN that corresponds to the
157 * CQL passed in. On error, sets the Connection object's error state
158 * and returns a null pointer.
159 * ### We could cache CQL parser and/or transformer in Connection.
160 */
161static char *cql2pqf(ZOOM_connection c, const char *cql)
162{
163 CQL_parser parser;
164 int error;
165 const char *cqlfile;
166 cql_transform_t trans;
167 char *result = 0;
168
169 parser = cql_parser_create();
170 if ((error = cql_parser_string(parser, cql)) != 0) {
171 cql_parser_destroy(parser);
173 return 0;
174 }
175
176 cqlfile = ZOOM_connection_option_get(c, "cqlfile");
177 if (cqlfile == 0)
178 {
179 ZOOM_set_error(c, ZOOM_ERROR_CQL_TRANSFORM, "no CQL transform file");
180 }
181 else if ((trans = cql_transform_open_fname(cqlfile)) == 0)
182 {
183 char buf[512];
184 yaz_snprintf(buf, sizeof(buf), "can't open CQL transform file '%s': %s",
185 cqlfile, strerror(errno));
187 }
188 else
189 {
190 WRBUF wrbuf_result = wrbuf_alloc();
191 error = cql_transform(trans, cql_parser_result(parser),
192 wrbuf_vp_puts, wrbuf_result);
193 if (error != 0) {
194 char buf[512];
195 const char *addinfo;
196 error = cql_transform_error(trans, &addinfo);
197 yaz_snprintf(buf, sizeof(buf), "%s (addinfo=%s)",
198 cql_strerror(error), addinfo);
200 }
201 else
202 {
203 result = xstrdup(wrbuf_cstr(wrbuf_result));
204 }
205 cql_transform_close(trans);
206 wrbuf_destroy(wrbuf_result);
207 }
208 cql_parser_destroy(parser);
209 return result;
210}
211
212
215{
216 ZOOM_query s = (ZOOM_query) xmalloc(sizeof(*s));
217
218 s->refcount = 1;
219 s->z_query = 0;
220 s->sort_spec = 0;
223 s->query_string = 0;
224 s->full_query = wrbuf_alloc();
227 return s;
228}
229
230ZOOM_API(void)
232{
233 if (!s)
234 return;
235
236 (s->refcount)--;
237 if (s->refcount == 0)
238 {
239 odr_destroy(s->odr_query);
240 odr_destroy(s->odr_sort_spec);
241 xfree(s->query_string);
242 wrbuf_destroy(s->full_query);
243 wrbuf_destroy(s->sru11_sort_spec);
244 xfree(s);
245 }
246}
247
248ZOOM_API(void)
250{
251 s->refcount++;
252}
253
254
255ZOOM_API(int)
256 ZOOM_query_prefix(ZOOM_query s, const char *str)
257{
258 xfree(s->query_string);
259 s->query_string = xstrdup(str);
260 s->query_type = Z_Query_type_1;
261 return generate(s);
262}
263
264ZOOM_API(int)
265 ZOOM_query_cql(ZOOM_query s, const char *str)
266{
267 xfree(s->query_string);
268 s->query_string = xstrdup(str);
269 s->query_type = Z_Query_type_104;
270 return generate(s);
271}
272
273/*
274 * Translate the CQL string client-side into RPN which is passed to
275 * the server. This is useful for server's that don't themselves
276 * support CQL, for which ZOOM_query_cql() is useless. `conn' is used
277 * only as a place to stash diagnostics if compilation fails; if this
278 * information is not needed, a null pointer may be used.
279 */
280ZOOM_API(int)
282{
283 char *rpn;
284 int ret;
285 ZOOM_connection freeme = 0;
286
287 if (conn == 0)
288 conn = freeme = ZOOM_connection_create(0);
289
290 rpn = cql2pqf(conn, str);
291 if (freeme != 0)
293 if (rpn == 0)
294 return -1;
295
296 ret = ZOOM_query_prefix(s, rpn);
297 xfree(rpn);
298 return ret;
299}
300
301/*
302 * Analogous in every way to ZOOM_query_cql2rpn(), except that there
303 * is no analogous ZOOM_query_ccl() that just sends uninterpreted CCL
304 * to the server, as the YAZ GFS doesn't know how to handle this.
305 */
306ZOOM_API(int)
307 ZOOM_query_ccl2rpn(ZOOM_query s, const char *str, const char *config,
308 int *ccl_error, const char **error_string,
309 int *error_pos)
310{
311 int ret;
312 struct ccl_rpn_node *rpn;
313 CCL_bibset bibset = ccl_qual_mk();
314
315 if (config)
316 ccl_qual_buf(bibset, config);
317
318 rpn = ccl_find_str(bibset, str, ccl_error, error_pos);
319 if (!rpn)
320 {
321 *error_string = ccl_err_msg(*ccl_error);
322 ret = -1;
323 }
324 else
325 {
326 WRBUF wr = wrbuf_alloc();
327 ccl_pquery(wr, rpn);
328 ccl_rpn_delete(rpn);
329 ret = ZOOM_query_prefix(s, wrbuf_cstr(wr));
330 wrbuf_destroy(wr);
331 }
332 ccl_qual_rm(&bibset);
333 return ret;
334}
335
336ZOOM_API(int)
337 ZOOM_query_sortby(ZOOM_query s, const char *criteria)
338{
339 return ZOOM_query_sortby2(s, "z3950", criteria);
340}
341
342ZOOM_API(int)
343ZOOM_query_sortby2(ZOOM_query s, const char *strategy, const char *criteria)
344{
345 if (!strcmp(strategy, "z3950"))
346 {
347 s->sort_strategy = SORT_STRATEGY_Z3950;
348 }
349 else if (!strcmp(strategy, "type7"))
350 {
351 s->sort_strategy = SORT_STRATEGY_TYPE7;
352 }
353 else if (!strcmp(strategy, "cql"))
354 {
355 s->sort_strategy = SORT_STRATEGY_CQL;
356 }
357 else if (!strcmp(strategy, "sru11"))
358 {
359 s->sort_strategy = SORT_STRATEGY_SRU11;
360 }
361 else if (!strcmp(strategy, "solr"))
362 {
363 s->sort_strategy = SORT_STRATEGY_SOLR;
364 }
365 else if (!strcmp(strategy, "embed"))
366 {
367 s->sort_strategy = SORT_STRATEGY_EMBED;
368 }
369 else
370 return -1;
371
372 odr_reset(s->odr_sort_spec);
373 s->sort_spec = yaz_sort_spec(s->odr_sort_spec, criteria);
374 if (!s->sort_spec)
375 return -2;
376 return generate(s);
377}
378
379/*
380 * Local variables:
381 * c-basic-offset: 4
382 * c-file-style: "Stroustrup"
383 * indent-tabs-mode: nil
384 * End:
385 * vim: shiftwidth=4 tabstop=8 expandtab
386 */
387
Header with public definitions for CCL.
struct ccl_qualifiers * CCL_bibset
CCL bibset, AKA profile.
Definition ccl.h:146
const char * ccl_err_msg(int ccl_errno)
Definition cclerrms.c:36
struct ccl_rpn_node * ccl_find_str(CCL_bibset bibset, const char *str, int *error, int *pos)
parse CCL find string using CCL profile return RPN tree
Definition cclfind.c:1310
void ccl_rpn_delete(struct ccl_rpn_node *rpn)
Definition cclfind.c:141
void ccl_pquery(WRBUF w, struct ccl_rpn_node *p)
Definition cclptree.c:132
void ccl_qual_buf(CCL_bibset bibset, const char *buf)
Definition cclqfile.c:261
CCL_bibset ccl_qual_mk(void)
creates Bibset
Definition cclqual.c:210
void ccl_qual_rm(CCL_bibset *b)
destroys Bibset
Definition cclqual.c:224
struct cql_node * cql_parser_result(CQL_parser cp)
returns the parse tree of the most recently parsed CQL query.
Definition cql.c:1902
void cql_parser_destroy(CQL_parser cp)
destroys a CQL parser.
Definition cql.c:1895
CQL_parser cql_parser_create(void)
creates a CQL parser.
Definition cql.c:1880
Header with public definitions about CQL.
struct cql_transform_t_ * cql_transform_t
CQL transform handle. The transform describes how to convert from CQL to PQF (Type-1 AKA RPN).
Definition cql.h:292
struct cql_parser * CQL_parser
CQL parser handle (opaque pointer).
Definition cql.h:41
const char * cql_strerror(int code)
returns the CQL message corresponding to a given error code.
Definition cqlstrer.c:16
int cql_parser_string(CQL_parser cp, const char *str)
parses a CQL query (string)
Definition cqlstring.c:35
int cql_transform(cql_transform_t ct, struct cql_node *cn, void(*pr)(const char *buf, void *client_data), void *client_data)
tranforms PQF given a CQL tree (NOT re-entrant)
cql_transform_t cql_transform_open_fname(const char *fname)
creates a CQL transform handle from a file
void cql_transform_close(cql_transform_t ct)
destroys a CQL transform handle
int cql_transform_error(cql_transform_t ct, const char **addinfo)
returns additional information for last transform
Header for errno utilities.
Logging utility.
ODR odr_createmem(int direction)
Definition odr.c:198
void odr_reset(ODR o)
Definition odr.c:224
struct odr * ODR
Definition odr.h:121
#define ODR_ENCODE
Definition odr.h:96
void * odr_malloc(ODR o, size_t size)
Definition odr_mem.c:31
char * odr_strdup(ODR o, const char *str)
Definition odr_mem.c:36
Odr_oid * odr_oiddup(ODR odr, const Odr_oid *o)
Definition odr_util.c:60
const Odr_oid yaz_oid_userinfo_cql[]
Definition oid_std.c:143
Z_RPNQuery * p_query_rpn(ODR o, const char *qbuf)
Definition pquery.c:699
Header for PQF parsing.
#define Z_External_CQL
Definition prt-ext.h:93
void yaz_snprintf(char *buf, size_t size, const char *fmt,...)
Definition snprintf.c:31
Header for config file reading utilities.
int yaz_sort_spec_to_type7(Z_SortKeySpecList *sksl, WRBUF pqf)
Definition sortspec.c:190
Z_SortKeySpecList * yaz_sort_spec(ODR out, const char *arg)
parse sort spec string
Definition sortspec.c:23
int yaz_sort_spec_to_solr_sortkeys(Z_SortKeySpecList *sksl, WRBUF w)
Definition sortspec.c:297
int yaz_sort_spec_to_srw_sortkeys(Z_SortKeySpecList *sksl, WRBUF w)
Definition sortspec.c:237
int yaz_sort_spec_to_cql(Z_SortKeySpecList *sksl, WRBUF w)
Definition sortspec.c:135
Header for SortSpec parsing.
WRBUF sru11_sort_spec
Definition zoom-query.c:44
WRBUF full_query
Definition zoom-query.c:43
Z_SortKeySpecList * sort_spec
Definition zoom-query.c:37
ODR odr_sort_spec
Definition zoom-query.c:39
int sort_strategy
Definition zoom-query.c:36
Z_Query * z_query
Definition zoom-query.c:35
char * query_string
Definition zoom-query.c:42
structure for all known EXTERNALs
Definition prt-ext.h:59
Odr_int * indirect_reference
Definition prt-ext.h:61
union Z_External::@173112132151266201036013025012152147264102163302 u
Z_InternationalString * cql
Definition prt-ext.h:138
int which
Definition prt-ext.h:63
Odr_oid * direct_reference
Definition prt-ext.h:60
char * descriptor
Definition prt-ext.h:62
union Z_Query::@270220245041066023256025363242165325012357336235 u
Z_External * type_104
Definition z-core.h:477
Z_RPNQuery * type_1
Definition z-core.h:472
int which
Definition z-core.h:469
RPN tree structure node.
Definition ccl.h:128
void wrbuf_destroy(WRBUF b)
destroy WRBUF and its buffer
Definition wrbuf.c:38
const char * wrbuf_cstr(WRBUF b)
returns WRBUF content as C-string
Definition wrbuf.c:299
void wrbuf_rewind(WRBUF b)
empty WRBUF content (length of buffer set to 0)
Definition wrbuf.c:47
WRBUF wrbuf_alloc(void)
construct WRBUF
Definition wrbuf.c:25
void wrbuf_printf(WRBUF b, const char *fmt,...)
writes printf result to WRBUF
Definition wrbuf.c:189
void wrbuf_vp_puts(const char *buf, void *client_data)
appends C-string to WRBUF - void pointer variant
Definition wrbuf.c:94
void wrbuf_puts(WRBUF b, const char *buf)
appends C-string to WRBUF
Definition wrbuf.c:89
#define wrbuf_len(b)
Definition wrbuf.h:269
struct wrbuf * WRBUF
Header for memory handling functions.
#define xstrdup(s)
utility macro which calls xstrdup_f
Definition xmalloc.h:55
#define xfree(x)
utility macro which calls xfree_f
Definition xmalloc.h:53
#define xmalloc(x)
utility macro which calls malloc_f
Definition xmalloc.h:49
Header for common YAZ utilities.
#define Z_Query_type_1
Definition z-core.h:479
#define Z_Query_type_104
Definition z-core.h:484
void ZOOM_set_error(ZOOM_connection c, int error, const char *addinfo)
Definition zoom-c.c:98
Internal header for ZOOM implementation.
#define SORT_STRATEGY_EMBED
Definition zoom-query.c:31
const char * ZOOM_query_get_sru11(ZOOM_query s)
Definition zoom-query.c:123
Z_SortKeySpecList * ZOOM_query_get_sortspec(ZOOM_query s)
Definition zoom-query.c:135
ZOOM_query_prefix(ZOOM_query s, const char *str)
Definition zoom-query.c:256
#define SORT_STRATEGY_SOLR
Definition zoom-query.c:32
static int generate(ZOOM_query s)
Definition zoom-query.c:47
#define SORT_STRATEGY_Z3950
Definition zoom-query.c:27
#define SORT_STRATEGY_TYPE7
Definition zoom-query.c:28
#define SORT_STRATEGY_CQL
Definition zoom-query.c:29
void ZOOM_query_get_hash(ZOOM_query s, WRBUF w)
Definition zoom-query.c:145
static char * cql2pqf(ZOOM_connection c, const char *cql)
Definition zoom-query.c:161
const char * ZOOM_query_get_query_string(ZOOM_query s)
Definition zoom-query.c:140
Z_Query * ZOOM_query_get_Z_Query(ZOOM_query s)
Definition zoom-query.c:130
ZOOM_query_sortby2(ZOOM_query s, const char *strategy, const char *criteria)
Definition zoom-query.c:343
#define SORT_STRATEGY_SRU11
Definition zoom-query.c:30
ZOOM_query_destroy(ZOOM_query s)
Definition zoom-query.c:231
ZOOM_query_cql(ZOOM_query s, const char *str)
Definition zoom-query.c:265
ZOOM_connection_destroy(ZOOM_connection c)
Definition zoom-c.c:605
#define ZOOM_ERROR_CQL_PARSE
Definition zoom.h:139
ZOOM_query_prefix(ZOOM_query s, const char *str)
Definition zoom-query.c:256
#define ZOOM_ERROR_CQL_TRANSFORM
Definition zoom.h:140
ZOOM_connection_option_get(ZOOM_connection c, const char *key)
Definition zoom-c.c:1770
ZOOM_query_cql2rpn(ZOOM_query s, const char *str, ZOOM_connection conn)
Definition zoom-query.c:281
ZOOM_query_create(void)
Definition zoom-query.c:214
ZOOM_connection_create(ZOOM_options options)
Definition zoom-c.c:237
struct ZOOM_query_p * ZOOM_query
Definition zoom.h:51
ZOOM_query_ccl2rpn(ZOOM_query s, const char *query_str, const char *config, int *ccl_error, const char **error_string, int *error_pos)
Definition zoom-query.c:307
struct ZOOM_connection_p * ZOOM_connection
Definition zoom.h:52
#define ZOOM_API(x)
Definition zoom.h:42
ZOOM_query_addref(ZOOM_query s)
Definition zoom-query.c:249
ZOOM_query_sortby(ZOOM_query s, const char *criteria)
Definition zoom-query.c:337
ZOOM_query_sortby2(ZOOM_query s, const char *strategy, const char *criteria)
Definition zoom-query.c:343