Implement cql_transform_cql2rpn
[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 tranforms PQF given a CQL tree
352     \param ct CQL transform handle
353     \param cn CQL node tree
354     \param addinfo additional information (if error)
355     \param pr print function
356     \param client_data data to be passed to pr
357     \retval 0 success
358     \retval != 0 error code
359
360     The result is written to a user-defined stream.
361 */
362 int cql_transform_cql2rpn(cql_transform_t ct, struct cql_node *cn,
363                           char **addinfo,
364                           void (*pr)(const char *buf, void *client_data),
365                           void *client_data);
366
367 /** \brief transforms PQF given a CQL tree (from FILE)
368     \param ct CQL transform handle
369     \param cn CQL tree
370     \param f FILE where output is written
371     \retval 0 success
372     \retval !=0 failure (error code)
373
374     The result is written to a file specified by FILE handle (which must
375     be opened for writing.
376 */
377 YAZ_EXPORT
378 int cql_transform_FILE(cql_transform_t ct,
379                        struct cql_node *cn, FILE *f);
380
381 /** \brief transforms PQF given a CQL tree (from FILE)
382     \param ct CQL transform handle
383     \param cn CQL tree
384     \param out buffer for output
385     \param max maximum bytes for output (size of buffer)
386     \retval 0 success
387     \retval !=0 failure (error code)
388  */
389 YAZ_EXPORT
390 int cql_transform_buf(cql_transform_t ct,
391                       struct cql_node *cn, char *out, int max);
392
393 /** \brief returns additional information for last transform
394     \param ct CQL transform handle
395     \param addinfo additional info (result)
396     \returns error code
397  */
398 YAZ_EXPORT
399 int cql_transform_error(cql_transform_t ct, const char **addinfo);
400
401 /** \brief sets error and addinfo for transform
402     \param ct CQL transform handle
403     \param error error code
404     \param addinfo additional info
405  */
406 YAZ_EXPORT
407 void cql_transform_set_error(cql_transform_t ct, int error, const char *addinfo);
408
409 /** \brief returns the CQL message corresponding to a given error code.
410     \param code error code
411     \returns text message
412 */
413 YAZ_EXPORT
414 const char *cql_strerror(int code);
415
416 /** \brief returns the standard CQL context set URI.
417     \returns CQL URI string
418 */
419 YAZ_EXPORT
420 const char *cql_uri(void);
421
422 /** \brief compares two CQL strings (ala strcmp)
423     \param s1 string 1
424     \param s2 string 2
425     \returns comparison value
426     Compares two CQL strings (for relations, operators, etc)
427     (unfortunately defined as case-insensitive unlike XML etc)
428 */
429 YAZ_EXPORT
430 int cql_strcmp(const char *s1, const char *s2);
431
432 /** \brief compares two CQL strings (ala strncmp)
433     \param s1 string 1
434     \param s2 string 2
435     \param n size
436     \returns comparison value
437     Compares two CQL strings at most n bytes
438     (unfortunately defined as case-insensitive unlike XML etc)
439  */
440 YAZ_EXPORT
441 int cql_strncmp(const char *s1, const char *s2, size_t n);
442
443 /** \brief converts CQL sortby to sortkeys (ala versions 1.1)
444     \param cn CQL tree
445     \param pr print function
446     \param client_data data to be passed to pr function
447
448     This will take CQL_NODE_SORT entries and conver them to
449
450     path,schema,ascending,caseSensitive,missingValue
451     items..
452
453     One for each sort keys. Where
454
455     path is string index for sorting
456
457     schema is schema for sort index
458
459     ascending is a boolean (0=false, 1=true). Default is true.
460
461     caseSensitive is a boolean. Default is false.
462
463     missingValue is a string and one of 'abort', 'highValue', 'lowValue',
464     or 'omit'. Default is 'highValue'.
465
466     See also
467     http://www.loc.gov/standards/sru/sru1-1archive/search-retrieve-operation.html#sort
468 */
469 YAZ_EXPORT
470 int cql_sortby_to_sortkeys(struct cql_node *cn,
471                            void (*pr)(const char *buf, void *client_data),
472                            void *client_data);
473
474 /** \brief converts CQL sortby to sortkeys ..
475     \param cn CQL tree
476     \param out result buffer
477     \param max size of buffer (allocated)
478     \retval 0 OK
479     \retval -1 ERROR
480 */
481 YAZ_EXPORT
482 int cql_sortby_to_sortkeys_buf(struct cql_node *cn, char *out, int max);
483
484 YAZ_END_CDECL
485
486 #endif
487 /* CQL_H_INCLUDED */
488 /*
489  * Local variables:
490  * c-basic-offset: 4
491  * c-file-style: "Stroustrup"
492  * indent-tabs-mode: nil
493  * End:
494  * vim: shiftwidth=4 tabstop=8 expandtab
495  */
496