YAZ 5.35.1
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
26#define SORT_STRATEGY_Z3950 0
27#define SORT_STRATEGY_TYPE7 1
28#define SORT_STRATEGY_CQL 2
29#define SORT_STRATEGY_SRU11 3
30#define SORT_STRATEGY_EMBED 4
31#define SORT_STRATEGY_SOLR 5
32
45
46static int generate(ZOOM_query s)
47{
48 if (s->query_string)
49 {
50 Z_External *ext;
51
55
57 {
58 int r = 0;
60
61 switch (s->sort_strategy)
62 {
65 break;
68 break;
69 }
70 if (r)
71 return r;
72 }
73 switch (s->query_type)
74 {
75 case Z_Query_type_1: /* RPN */
76 if (s->sort_spec &&
79 {
81 if (r)
82 return r;
83 }
85 sizeof(*s->z_query));
87 s->z_query->u.type_1 =
89 if (!s->z_query->u.type_1)
90 {
91 s->z_query = 0;
92 return -1;
93 }
94 break;
95 case Z_Query_type_104: /* CQL */
96 if (s->sort_spec &&
99 {
101 if (r)
102 return r;
103 }
104 ext = (Z_External *) odr_malloc(s->odr_query, sizeof(*ext));
107 ext->indirect_reference = 0;
108 ext->descriptor = 0;
109 ext->which = Z_External_CQL;
111
112 s->z_query = (Z_Query *) odr_malloc(s->odr_query, sizeof(*s->z_query));
114 s->z_query->u.type_104 = ext;
115
116 break;
117 }
118 }
119 return 0;
120}
121
123{
125 return wrbuf_cstr(s->sru11_sort_spec);
126 return 0;
127}
128
133
138
140{
141 return wrbuf_cstr(s->full_query);
142}
143
145{
146 wrbuf_printf(w, "%d;", s->query_type);
147 if (s->query_string)
149 wrbuf_printf(w, ";%d;", s->sort_strategy);
150 if (s->sort_spec)
152}
153
154/*
155 * Returns an xmalloc()d string containing RPN that corresponds to the
156 * CQL passed in. On error, sets the Connection object's error state
157 * and returns a null pointer.
158 * ### We could cache CQL parser and/or transformer in Connection.
159 */
160static char *cql2pqf(ZOOM_connection c, const char *cql)
161{
162 CQL_parser parser;
163 int error;
164 const char *cqlfile;
165 cql_transform_t trans;
166 char *result = 0;
167
168 parser = cql_parser_create();
169 if ((error = cql_parser_string(parser, cql)) != 0) {
170 cql_parser_destroy(parser);
172 return 0;
173 }
174
175 cqlfile = ZOOM_connection_option_get(c, "cqlfile");
176 if (cqlfile == 0)
177 {
178 ZOOM_set_error(c, ZOOM_ERROR_CQL_TRANSFORM, "no CQL transform file");
179 }
180 else if ((trans = cql_transform_open_fname(cqlfile)) == 0)
181 {
182 char buf[512];
183 sprintf(buf, "can't open CQL transform file '%.200s': %.200s",
184 cqlfile, strerror(errno));
186 }
187 else
188 {
189 WRBUF wrbuf_result = wrbuf_alloc();
190 error = cql_transform(trans, cql_parser_result(parser),
191 wrbuf_vp_puts, wrbuf_result);
192 if (error != 0) {
193 char buf[512];
194 const char *addinfo;
195 error = cql_transform_error(trans, &addinfo);
196 sprintf(buf, "%.200s (addinfo=%.200s)",
197 cql_strerror(error), addinfo);
199 }
200 else
201 {
202 result = xstrdup(wrbuf_cstr(wrbuf_result));
203 }
204 cql_transform_close(trans);
205 wrbuf_destroy(wrbuf_result);
206 }
207 cql_parser_destroy(parser);
208 return result;
209}
210
211
214{
215 ZOOM_query s = (ZOOM_query) xmalloc(sizeof(*s));
216
217 s->refcount = 1;
218 s->z_query = 0;
219 s->sort_spec = 0;
222 s->query_string = 0;
223 s->full_query = wrbuf_alloc();
226 return s;
227}
228
229ZOOM_API(void)
231{
232 if (!s)
233 return;
234
235 (s->refcount)--;
236 if (s->refcount == 0)
237 {
238 odr_destroy(s->odr_query);
239 odr_destroy(s->odr_sort_spec);
240 xfree(s->query_string);
241 wrbuf_destroy(s->full_query);
242 wrbuf_destroy(s->sru11_sort_spec);
243 xfree(s);
244 }
245}
246
247ZOOM_API(void)
249{
250 s->refcount++;
251}
252
253
254ZOOM_API(int)
255 ZOOM_query_prefix(ZOOM_query s, const char *str)
256{
257 xfree(s->query_string);
258 s->query_string = xstrdup(str);
259 s->query_type = Z_Query_type_1;
260 return generate(s);
261}
262
263ZOOM_API(int)
264 ZOOM_query_cql(ZOOM_query s, const char *str)
265{
266 xfree(s->query_string);
267 s->query_string = xstrdup(str);
268 s->query_type = Z_Query_type_104;
269 return generate(s);
270}
271
272/*
273 * Translate the CQL string client-side into RPN which is passed to
274 * the server. This is useful for server's that don't themselves
275 * support CQL, for which ZOOM_query_cql() is useless. `conn' is used
276 * only as a place to stash diagnostics if compilation fails; if this
277 * information is not needed, a null pointer may be used.
278 */
279ZOOM_API(int)
281{
282 char *rpn;
283 int ret;
284 ZOOM_connection freeme = 0;
285
286 if (conn == 0)
287 conn = freeme = ZOOM_connection_create(0);
288
289 rpn = cql2pqf(conn, str);
290 if (freeme != 0)
292 if (rpn == 0)
293 return -1;
294
295 ret = ZOOM_query_prefix(s, rpn);
296 xfree(rpn);
297 return ret;
298}
299
300/*
301 * Analogous in every way to ZOOM_query_cql2rpn(), except that there
302 * is no analogous ZOOM_query_ccl() that just sends uninterpreted CCL
303 * to the server, as the YAZ GFS doesn't know how to handle this.
304 */
305ZOOM_API(int)
306 ZOOM_query_ccl2rpn(ZOOM_query s, const char *str, const char *config,
307 int *ccl_error, const char **error_string,
308 int *error_pos)
309{
310 int ret;
311 struct ccl_rpn_node *rpn;
312 CCL_bibset bibset = ccl_qual_mk();
313
314 if (config)
315 ccl_qual_buf(bibset, config);
316
317 rpn = ccl_find_str(bibset, str, ccl_error, error_pos);
318 if (!rpn)
319 {
320 *error_string = ccl_err_msg(*ccl_error);
321 ret = -1;
322 }
323 else
324 {
325 WRBUF wr = wrbuf_alloc();
326 ccl_pquery(wr, rpn);
327 ccl_rpn_delete(rpn);
328 ret = ZOOM_query_prefix(s, wrbuf_cstr(wr));
329 wrbuf_destroy(wr);
330 }
331 ccl_qual_rm(&bibset);
332 return ret;
333}
334
335ZOOM_API(int)
336 ZOOM_query_sortby(ZOOM_query s, const char *criteria)
337{
338 return ZOOM_query_sortby2(s, "z3950", criteria);
339}
340
341ZOOM_API(int)
342ZOOM_query_sortby2(ZOOM_query s, const char *strategy, const char *criteria)
343{
344 if (!strcmp(strategy, "z3950"))
345 {
346 s->sort_strategy = SORT_STRATEGY_Z3950;
347 }
348 else if (!strcmp(strategy, "type7"))
349 {
350 s->sort_strategy = SORT_STRATEGY_TYPE7;
351 }
352 else if (!strcmp(strategy, "cql"))
353 {
354 s->sort_strategy = SORT_STRATEGY_CQL;
355 }
356 else if (!strcmp(strategy, "sru11"))
357 {
358 s->sort_strategy = SORT_STRATEGY_SRU11;
359 }
360 else if (!strcmp(strategy, "solr"))
361 {
362 s->sort_strategy = SORT_STRATEGY_SOLR;
363 }
364 else if (!strcmp(strategy, "embed"))
365 {
366 s->sort_strategy = SORT_STRATEGY_EMBED;
367 }
368 else
369 return -1;
370
371 odr_reset(s->odr_sort_spec);
372 s->sort_spec = yaz_sort_spec(s->odr_sort_spec, criteria);
373 if (!s->sort_spec)
374 return -2;
375 return generate(s);
376}
377
378/*
379 * Local variables:
380 * c-basic-offset: 4
381 * c-file-style: "Stroustrup"
382 * indent-tabs-mode: nil
383 * End:
384 * vim: shiftwidth=4 tabstop=8 expandtab
385 */
386
Header with public definitions for CCL.
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:135
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.
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:200
void odr_destroy(ODR o)
Definition odr.c:253
void odr_reset(ODR o)
Definition odr.c:226
#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
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:43
WRBUF full_query
Definition zoom-query.c:42
Z_SortKeySpecList * sort_spec
Definition zoom-query.c:36
ODR odr_sort_spec
Definition zoom-query.c:38
int sort_strategy
Definition zoom-query.c:35
Z_Query * z_query
Definition zoom-query.c:34
char * query_string
Definition zoom-query.c:41
structure for all known EXTERNALs
Definition prt-ext.h:59
Odr_int * indirect_reference
Definition prt-ext.h:61
Z_InternationalString * cql
Definition prt-ext.h:138
int which
Definition prt-ext.h:63
union Z_External::@27 u
Odr_oid * direct_reference
Definition prt-ext.h:60
char * descriptor
Definition prt-ext.h:62
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
union Z_Query::@45 u
RPN tree structure node.
Definition ccl.h:128
Definition odr.h:125
string buffer
Definition wrbuf.h:43
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
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.
ZOOM_query_destroy(ZOOM_query s)
Definition zoom-query.c:230
#define SORT_STRATEGY_EMBED
Definition zoom-query.c:30
ZOOM_query_cql(ZOOM_query s, const char *str)
Definition zoom-query.c:264
const char * ZOOM_query_get_sru11(ZOOM_query s)
Definition zoom-query.c:122
Z_SortKeySpecList * ZOOM_query_get_sortspec(ZOOM_query s)
Definition zoom-query.c:134
ZOOM_query_prefix(ZOOM_query s, const char *str)
Definition zoom-query.c:255
#define SORT_STRATEGY_SOLR
Definition zoom-query.c:31
static int generate(ZOOM_query s)
Definition zoom-query.c:46
#define SORT_STRATEGY_Z3950
Definition zoom-query.c:26
#define SORT_STRATEGY_TYPE7
Definition zoom-query.c:27
#define SORT_STRATEGY_CQL
Definition zoom-query.c:28
ZOOM_query_cql2rpn(ZOOM_query s, const char *str, ZOOM_connection conn)
Definition zoom-query.c:280
ZOOM_query_create(void)
Definition zoom-query.c:213
ZOOM_query_ccl2rpn(ZOOM_query s, const char *str, const char *config, int *ccl_error, const char **error_string, int *error_pos)
Definition zoom-query.c:306
void ZOOM_query_get_hash(ZOOM_query s, WRBUF w)
Definition zoom-query.c:144
static char * cql2pqf(ZOOM_connection c, const char *cql)
Definition zoom-query.c:160
const char * ZOOM_query_get_query_string(ZOOM_query s)
Definition zoom-query.c:139
ZOOM_query_addref(ZOOM_query s)
Definition zoom-query.c:248
Z_Query * ZOOM_query_get_Z_Query(ZOOM_query s)
Definition zoom-query.c:129
ZOOM_query_sortby(ZOOM_query s, const char *criteria)
Definition zoom-query.c:336
ZOOM_query_sortby2(ZOOM_query s, const char *strategy, const char *criteria)
Definition zoom-query.c:342
#define SORT_STRATEGY_SRU11
Definition zoom-query.c:29
ZOOM_connection_destroy(ZOOM_connection c)
Definition zoom-c.c:605
#define ZOOM_ERROR_CQL_PARSE
Definition zoom.h:139
#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_connection_create(ZOOM_options options)
Definition zoom-c.c:237
struct ZOOM_query_p * ZOOM_query
Definition zoom.h:51
#define ZOOM_API(x)
Definition zoom.h:42