Happy new year
[yaz-moved-to-github.git] / include / yaz / cql.h
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) Index Data.
3  * All rights reserved.
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  *     * Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *     * Redistributions in binary form must reproduce the above copyright
10  *       notice, this list of conditions and the following disclaimer in the
11  *       documentation and/or other materials provided with the distribution.
12  *     * Neither the name of Index Data nor the names of its contributors
13  *       may be used to endorse or promote products derived from this
14  *       software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 /** \file cql.h
29     \brief Header with public definitions about CQL.
30 */
31
32 #ifndef CQL_H_INCLUDED
33 #define CQL_H_INCLUDED
34 #include <stdio.h>
35 #include <yaz/nmem.h>
36
37 YAZ_BEGIN_CDECL
38
39 /** \brief CQL parser handle (opaque pointer) */
40 typedef struct cql_parser *CQL_parser;
41
42 /** \brief creates a CQL parser.
43     \returns CCL parser
44
45     Returns CQL parser or NULL if parser could not be created.
46  */
47 YAZ_EXPORT
48 CQL_parser cql_parser_create(void);
49
50 /** \brief destroys a CQL parser.
51     \param cp CQL parser
52
53     This function does nothing if NULL if received.
54  */
55 YAZ_EXPORT
56 void cql_parser_destroy(CQL_parser cp);
57
58 /** \brief parses a CQL query (string)
59     \param cp CQL parser
60     \param str CQL string
61     \retval 0 success
62     \retval !=0 failure
63  */
64 YAZ_EXPORT
65 int cql_parser_string(CQL_parser cp, const char *str);
66
67 /** \brief parses CQL query (query stream)
68     \param cp CQL parser
69     \param getbyte function which reads one character from stream
70     \param ungetbyte function which unreads one character from stream
71     \param client_data data to be passed to stream functions
72     \retval 0 success
73     \retval !=0 failure
74
75     This function is similar to cql_parser_string but takes a
76     functions to read each query character from a stream.
77
78     The functions pointers getbytes, ungetbyte are similar to
79     that known from stdios getc, ungetc.
80 */
81 YAZ_EXPORT
82 int cql_parser_stream(CQL_parser cp,
83                       int (*getbyte)(void *client_data),
84                       void (*ungetbyte)(int b, void *client_data),
85                       void *client_data);
86
87 /** \brief parses CQL query (from FILE)
88     \param cp CQL parser
89     \param f file where query is read from
90     \retval 0 success
91     \retval !=0 failure
92
93     This function is similar to cql_parser_string but reads from
94     stdio FILE handle instead.
95 */
96 YAZ_EXPORT
97 int cql_parser_stdio(CQL_parser cp, FILE *f);
98
99 /** \brief configures strict mode
100     \param cp CQL parser
101     \param mode 1=enable strict mode, 0=disable strict mode
102
103     This function is similar to cql_parser_string but reads from
104     stdio FILE handle instead.
105 */
106 YAZ_EXPORT
107 void cql_parser_strict(CQL_parser cp, int mode);
108
109 /** \brief Node type: search term */
110 #define CQL_NODE_ST 1
111 /** \brief Node type: boolean */
112 #define CQL_NODE_BOOL 2
113 /** \brief Node type: sortby single spec */
114 #define CQL_NODE_SORT 3
115
116 /** \brief CQL parse tree (node)
117  */
118 struct cql_node {
119     /** node type */
120     int which;
121     union {
122         /** which == CQL_NODE_ST */
123         struct {
124             /** CQL index */
125             char *index;
126             /** CQL index URI or NULL if no URI */
127             char *index_uri;
128             /** Search term */
129             char *term;
130             /** relation */
131             char *relation;
132             /** relation URL or NULL if no relation URI) */
133             char *relation_uri;
134             /** relation modifiers */
135             struct cql_node *modifiers;
136             /** term list */
137             struct cql_node *extra_terms;
138         } st;
139         /** which == CQL_NODE_BOOL */
140         struct {
141             /** operator name "and", "or", ... */
142             char *value;
143             /** left operand */
144             struct cql_node *left;
145             /** right operand */
146             struct cql_node *right;
147             /** modifiers (NULL for no list) */
148             struct cql_node *modifiers;
149         } boolean;
150         /** which == CQL_NODE_SORT */
151         struct {
152             char *index;
153             /** next spec */
154             struct cql_node *next;
155             /** modifiers (NULL for no list) */
156             struct cql_node *modifiers;
157             /** search node */
158             struct cql_node *search;
159         } sort;
160     } u;
161 };
162
163 /** \brief Private structure that describes the CQL properties (profile)
164  */
165 struct cql_properties;
166
167 /** \brief Structure used by cql_buf_write_handler
168  */
169 struct cql_buf_write_info {
170     int max;
171     int off;
172     char *buf;
173 };
174
175 /** \brief Handler for cql_buf_write_info
176  */
177 YAZ_EXPORT
178 void cql_buf_write_handler(const char *b, void *client_data);
179
180 /** \brief Prints a CQL node and all sub nodes.
181     Hence this function prints the parse tree which is as returned by
182     cql_parser_result.
183 */
184 YAZ_EXPORT
185 void cql_node_print(struct cql_node *cn);
186
187 /** \brief creates a search clause node (st). */
188 YAZ_EXPORT
189 struct cql_node *cql_node_mk_sc(NMEM nmem, const char *index,
190                                 const char *relation, const char *term);
191
192 /** \brief applies a prefix+uri to "unresolved" index and relation URIs.
193     "unresolved" URIs are those nodes where member index_uri / relation_uri
194     is NULL.
195 */
196 YAZ_EXPORT
197 struct cql_node *cql_apply_prefix(NMEM nmem, struct cql_node *cn,
198                                   const char *prefix, const char *uri);
199
200 /** \brief creates a boolean node. */
201 YAZ_EXPORT
202 struct cql_node *cql_node_mk_boolean(NMEM nmem, const char *op);
203
204 /** \brief creates a sort single spec node. */
205 YAZ_EXPORT
206 struct cql_node *cql_node_mk_sort(NMEM nmem, const char *index,
207     struct cql_node *modifiers);
208
209 /** \brief destroys a node and its children. */
210 YAZ_EXPORT
211 void cql_node_destroy(struct cql_node *cn);
212
213 /** duplicates a node (returns a copy of supplied node) . */
214 YAZ_EXPORT
215 struct cql_node *cql_node_dup (NMEM nmem, struct cql_node *cp);
216
217 /** \brief returns the parse tree of the most recently parsed CQL query.
218     \param cp CQL parser
219     \returns CQL node or NULL for failure
220 */
221 YAZ_EXPORT
222 struct cql_node *cql_parser_result(CQL_parser cp);
223
224 /** \brief returns the sortby tree of the most recently parsed CQL query.
225     \param cp CQL parser
226     \returns CQL node or NULL for failure
227 */
228 YAZ_EXPORT
229 struct cql_node *cql_parser_sort_result(CQL_parser cp);
230
231 /** \brief converts CQL tree to XCQL and writes to user-defined stream
232     \param cn CQL node (tree)
233     \param pr print function
234     \param client_data data to be passed to pr function
235  */
236 YAZ_EXPORT
237 void cql_to_xml(struct cql_node *cn,
238                 void (*pr)(const char *buf, void *client_data),
239                 void *client_data);
240 /** \brief converts CQL tree to XCQL and writes to file
241     \param cn CQL node (tree)
242     \param f file handle
243  */
244 YAZ_EXPORT
245 void cql_to_xml_stdio(struct cql_node *cn, FILE *f);
246
247 /** \brief converts CQL tree to XCQL and writes result to buffer
248     \param cn CQL node (tree)
249     \param out buffer
250     \param max size of buffer (max chars to write)
251     \returns length of resulting buffer
252  */
253 YAZ_EXPORT
254 int cql_to_xml_buf(struct cql_node *cn, char *out, int max);
255
256 /** \brief converts CQL tree to CCL and writes to user-defined stream
257     \param cn CQL node (tree)
258     \param pr print function
259     \param client_data data to be passed to pr function
260  */
261 YAZ_EXPORT
262 int cql_to_ccl(struct cql_node *cn,
263                void (*pr)(const char *buf, void *client_data),
264                void *client_data);
265
266 /** \brief converts CQL tree to CCL and writes to file
267     \param cn CQL node (tree)
268     \param f file handle
269  */
270 YAZ_EXPORT
271 void cql_to_ccl_stdio(struct cql_node *cn, FILE *f);
272
273 /** \brief converts CQL tree to CCL and writes result to buffer
274     \param cn CQL node (tree)
275     \param out buffer
276     \param max size of buffer (max chars to write)
277     \retval 0 OK
278     \retval -1 conversion error
279     \retval -2 buffer too small (truncated)
280  */
281 YAZ_EXPORT
282 int cql_to_ccl_buf(struct cql_node *cn, char *out, int max);
283
284 /** \brief stream handle for file (used by cql_to_xml_stdio) */
285 YAZ_EXPORT
286 void cql_fputs(const char *buf, void *client_data);
287
288 /** \brief CQL transform handle.
289     The transform describes how to convert from CQL to PQF (Type-1 AKA RPN).
290 */
291 typedef struct cql_transform_t_ *cql_transform_t;
292
293 /** \brief creates a CQL transform handle
294     \returns transform handle or NULL for failure
295 */
296 YAZ_EXPORT
297 cql_transform_t cql_transform_create(void);
298
299 /** \brief creates a CQL transform handle from am opened file handle
300     \param f file where transformation spec is read
301     \returns transform handle or NULL for failure
302
303     The transformation spec is read from a FILE handle which is assumed
304     opened for reading.
305 */
306 YAZ_EXPORT
307 cql_transform_t cql_transform_open_FILE (FILE *f);
308
309 /** \brief creates a CQL transform handle from a file
310     \param fname name of where transformation spec is read
311     \returns transform handle or NULL for failure
312 */
313 YAZ_EXPORT
314 cql_transform_t cql_transform_open_fname(const char *fname);
315
316
317 /** \brief defines CQL transform pattern
318     \param ct CQL transform handle
319     \param pattern pattern string
320     \param value pattern value
321     \returns 0 for succes; -1 for failure
322 */
323 YAZ_EXPORT
324 int cql_transform_define_pattern(cql_transform_t ct, const char *pattern,
325                                  const char *value);
326
327
328
329 /** \brief destroys a CQL transform handle
330     \param ct CQL transform handle
331  */
332 YAZ_EXPORT
333 void cql_transform_close(cql_transform_t ct);
334
335 /** \brief tranforms PQF given a CQL tree
336     \param ct CQL transform handle
337     \param cn CQL node tree
338     \param pr print function
339     \param client_data data to be passed to pr
340     \retval 0 success
341     \retval != 0 error
342
343     The result is written to a user-defined stream.
344 */
345 YAZ_EXPORT
346 int cql_transform(cql_transform_t ct,
347                   struct cql_node *cn,
348                   void (*pr)(const char *buf, void *client_data),
349                   void *client_data);
350
351 /** \brief transforms PQF given a CQL tree (from FILE)
352     \param ct CQL transform handle
353     \param cn CQL tree
354     \param f FILE where output is written
355     \retval 0 success
356     \retval !=0 failure (error code)
357
358     The result is written to a file specified by FILE handle (which must
359     be opened for writing.
360 */
361 YAZ_EXPORT
362 int cql_transform_FILE(cql_transform_t ct,
363                        struct cql_node *cn, FILE *f);
364
365 /** \brief transforms PQF given a CQL tree (from FILE)
366     \param ct CQL transform handle
367     \param cn CQL tree
368     \param out buffer for output
369     \param max maximum bytes for output (size of buffer)
370     \retval 0 success
371     \retval !=0 failure (error code)
372  */
373 YAZ_EXPORT
374 int cql_transform_buf(cql_transform_t ct,
375                       struct cql_node *cn, char *out, int max);
376
377 /** \brief returns additional information for last transform
378     \param ct CQL transform handle
379     \param addinfo additional info (result)
380     \returns error code
381  */
382 YAZ_EXPORT
383 int cql_transform_error(cql_transform_t ct, const char **addinfo);
384
385 /** \brief sets error and addinfo for transform
386     \param ct CQL transform handle
387     \param error error code
388     \param addinfo additional info
389  */
390 YAZ_EXPORT
391 void cql_transform_set_error(cql_transform_t ct, int error, const char *addinfo);
392
393 /** \brief returns the CQL message corresponding to a given error code.
394     \param code error code
395     \returns text message
396 */
397 YAZ_EXPORT
398 const char *cql_strerror(int code);
399
400 /** \brief returns the standard CQL context set URI.
401     \returns CQL URI string
402 */
403 YAZ_EXPORT
404 const char *cql_uri(void);
405
406 /** \brief compares two CQL strings (ala strcmp)
407     \param s1 string 1
408     \param s2 string 2
409     \returns comparison value
410     Compares two CQL strings (for relations, operators, etc)
411     (unfortunately defined as case-insensitive unlike XML etc)
412 */
413 YAZ_EXPORT
414 int cql_strcmp(const char *s1, const char *s2);
415
416 /** \brief compares two CQL strings (ala strncmp)
417     \param s1 string 1
418     \param s2 string 2
419     \param n size
420     \returns comparison value
421     Compares two CQL strings at most n bytes
422     (unfortunately defined as case-insensitive unlike XML etc)
423  */
424 YAZ_EXPORT
425 int cql_strncmp(const char *s1, const char *s2, size_t n);
426
427 /** \brief converts CQL sortby to sortkeys (ala versions 1.1)
428     \param cn CQL tree
429     \param pr print function
430     \param client_data data to be passed to pr function
431
432     This will take CQL_NODE_SORT entries and conver them to
433
434     path,schema,ascending,caseSensitive,missingValue
435     items..
436
437     One for each sort keys. Where
438
439     path is string index for sorting
440
441     schema is schema for sort index
442
443     ascending is a boolean (0=false, 1=true). Default is true.
444
445     caseSensitive is a boolean. Default is false.
446
447     missingValue is a string and one of 'abort', 'highValue', 'lowValue',
448     or 'omit'. Default is 'highValue'.
449
450     See also
451     http://www.loc.gov/standards/sru/sru1-1archive/search-retrieve-operation.html#sort
452 */
453 YAZ_EXPORT
454 int cql_sortby_to_sortkeys(struct cql_node *cn,
455                            void (*pr)(const char *buf, void *client_data),
456                            void *client_data);
457
458 /** \brief converts CQL sortby to sortkeys ..
459     \param cn CQL tree
460     \param out result buffer
461     \param max size of buffer (allocated)
462     \retval 0 OK
463     \retval -1 ERROR
464 */
465 YAZ_EXPORT
466 int cql_sortby_to_sortkeys_buf(struct cql_node *cn, char *out, int max);
467
468 YAZ_END_CDECL
469
470 #endif
471 /* CQL_H_INCLUDED */
472 /*
473  * Local variables:
474  * c-basic-offset: 4
475  * c-file-style: "Stroustrup"
476  * indent-tabs-mode: nil
477  * End:
478  * vim: shiftwidth=4 tabstop=8 expandtab
479  */
480