1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) 1995-2010 Index Data
3 * See the file LICENSE for details.
7 * \brief Implements ZOOM C query interface.
15 #include <yaz/yaz-util.h>
16 #include <yaz/xmalloc.h>
18 #include <yaz/pquery.h>
21 #include <yaz/sortspec.h>
25 Z_SortKeySpecList *sort_spec;
31 Z_Query *ZOOM_query_get_Z_Query(ZOOM_query s)
37 Z_SortKeySpecList *ZOOM_query_get_sortspec(ZOOM_query s)
42 static void cql2pqf_wrbuf_puts(const char *buf, void *client_data)
44 WRBUF wrbuf = (WRBUF) client_data;
45 wrbuf_puts(wrbuf, buf);
48 char *ZOOM_query_get_query_string(ZOOM_query s)
50 return s->query_string;
54 * Returns an xmalloc()d string containing RPN that corresponds to the
55 * CQL passed in. On error, sets the Connection object's error state
56 * and returns a null pointer.
57 * ### We could cache CQL parser and/or transformer in Connection.
59 static char *cql2pqf(ZOOM_connection c, const char *cql)
64 cql_transform_t trans;
67 parser = cql_parser_create();
68 if ((error = cql_parser_string(parser, cql)) != 0) {
69 cql_parser_destroy(parser);
70 ZOOM_set_error(c, ZOOM_ERROR_CQL_PARSE, cql);
74 cqlfile = ZOOM_connection_option_get(c, "cqlfile");
77 ZOOM_set_error(c, ZOOM_ERROR_CQL_TRANSFORM, "no CQL transform file");
79 else if ((trans = cql_transform_open_fname(cqlfile)) == 0)
82 sprintf(buf, "can't open CQL transform file '%.200s': %.200s",
83 cqlfile, strerror(errno));
84 ZOOM_set_error(c, ZOOM_ERROR_CQL_TRANSFORM, buf);
88 WRBUF wrbuf_result = wrbuf_alloc();
89 error = cql_transform(trans, cql_parser_result(parser),
90 cql2pqf_wrbuf_puts, wrbuf_result);
94 error = cql_transform_error(trans, &addinfo);
95 sprintf(buf, "%.200s (addinfo=%.200s)",
96 cql_strerror(error), addinfo);
97 ZOOM_set_error(c, ZOOM_ERROR_CQL_TRANSFORM, buf);
101 result = xstrdup(wrbuf_cstr(wrbuf_result));
103 cql_transform_close(trans);
104 wrbuf_destroy(wrbuf_result);
106 cql_parser_destroy(parser);
112 ZOOM_query_create(void)
114 ZOOM_query s = (ZOOM_query) xmalloc(sizeof(*s));
119 s->odr = odr_createmem(ODR_ENCODE);
126 ZOOM_query_destroy(ZOOM_query s)
132 if (s->refcount == 0)
140 ZOOM_query_addref(ZOOM_query s)
146 ZOOM_query_prefix(ZOOM_query s, const char *str)
148 s->query_string = odr_strdup(s->odr, str);
149 s->z_query = (Z_Query *) odr_malloc(s->odr, sizeof(*s->z_query));
150 s->z_query->which = Z_Query_type_1;
151 s->z_query->u.type_1 = p_query_rpn(s->odr, str);
152 if (!s->z_query->u.type_1)
161 ZOOM_query_cql(ZOOM_query s, const char *str)
165 s->query_string = odr_strdup(s->odr, str);
167 ext = (Z_External *) odr_malloc(s->odr, sizeof(*ext));
168 ext->direct_reference = odr_oiddup(s->odr, yaz_oid_userinfo_cql);
169 ext->indirect_reference = 0;
171 ext->which = Z_External_CQL;
172 ext->u.cql = s->query_string;
174 s->z_query = (Z_Query *) odr_malloc(s->odr, sizeof(*s->z_query));
175 s->z_query->which = Z_Query_type_104;
176 s->z_query->u.type_104 = ext;
182 * Translate the CQL string client-side into RPN which is passed to
183 * the server. This is useful for server's that don't themselves
184 * support CQL, for which ZOOM_query_cql() is useless. `conn' is used
185 * only as a place to stash diagnostics if compilation fails; if this
186 * information is not needed, a null pointer may be used.
189 ZOOM_query_cql2rpn(ZOOM_query s, const char *str, ZOOM_connection conn)
193 ZOOM_connection freeme = 0;
196 conn = freeme = ZOOM_connection_create(0);
198 rpn = cql2pqf(conn, str);
200 ZOOM_connection_destroy(freeme);
204 ret = ZOOM_query_prefix(s, rpn);
210 * Analogous in every way to ZOOM_query_cql2rpn(), except that there
211 * is no analogous ZOOM_query_ccl() that just sends uninterpreted CCL
212 * to the server, as the YAZ GFS doesn't know how to handle this.
215 ZOOM_query_ccl2rpn(ZOOM_query s, const char *str, const char *config,
216 int *ccl_error, const char **error_string,
220 struct ccl_rpn_node *rpn;
221 CCL_bibset bibset = ccl_qual_mk();
224 ccl_qual_buf(bibset, config);
226 rpn = ccl_find_str(bibset, str, ccl_error, error_pos);
229 *error_string = ccl_err_msg(*ccl_error);
234 WRBUF wr = wrbuf_alloc();
237 ret = ZOOM_query_prefix(s, wrbuf_cstr(wr));
240 ccl_qual_rm(&bibset);
245 ZOOM_query_sortby(ZOOM_query s, const char *criteria)
247 s->sort_spec = yaz_sort_spec(s->odr, criteria);
257 * c-file-style: "Stroustrup"
258 * indent-tabs-mode: nil
260 * vim: shiftwidth=4 tabstop=8 expandtab