Release 1.6.4
[yazpp-moved-to-github.git] / src / yaz-cql2rpn.cpp
1 /* This file is part of the yazpp toolkit.
2  * Copyright (C) Index Data 
3  * See the file LICENSE for details.
4  */
5
6 #if HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9 #include <yaz/log.h>
10 #include <yaz/diagsrw.h>
11 #include <yaz/pquery.h>
12 #include <yaz/sortspec.h>
13 #include <yazpp/cql2rpn.h>
14 #include <yaz/rpn2cql.h>
15
16 using namespace yazpp_1;
17
18 Yaz_cql2rpn::Yaz_cql2rpn()
19 {
20     m_transform = 0;
21 }
22
23 Yaz_cql2rpn::~Yaz_cql2rpn()
24 {
25     if (m_transform)
26         cql_transform_close(m_transform);
27 }
28
29 void Yaz_cql2rpn::set_pqf_file(const char *fname)
30 {
31     if (!m_transform)
32         m_transform = cql_transform_open_fname(fname);
33 }
34
35
36 bool Yaz_cql2rpn::parse_spec_file(const char *fname, int *error)
37 {
38     *error = 0;
39     cql_transform_close(m_transform);
40     m_transform = cql_transform_open_fname(fname);
41     return m_transform ? true : false;
42 }
43
44 int Yaz_cql2rpn::rpn2cql_transform(Z_RPNQuery *q, WRBUF cql, ODR o,
45                                    char **addinfop)
46 {
47     WRBUF addinfo = wrbuf_alloc();
48     int r = cql_transform_rpn2cql_stream_r(m_transform, addinfo,
49                                            wrbuf_vp_puts, cql, q);
50     if (r && wrbuf_len(addinfo))
51         *addinfop = odr_strdup_null(o, wrbuf_cstr(addinfo));
52     else
53         *addinfop = 0;
54     wrbuf_destroy(addinfo);
55     return r;
56 }
57
58 int Yaz_cql2rpn::query_transform(const char *cql_query,
59                                  Z_RPNQuery **rpnquery, ODR o,
60                                  char **addinfop)
61 {
62     if (!m_transform)
63         return -3;
64     CQL_parser cp = cql_parser_create();
65     WRBUF addinfo = wrbuf_alloc();
66     const char *lead = "query_transform::query_transform";
67
68     int r = cql_parser_string(cp, cql_query);
69     if (r)
70     {
71         wrbuf_printf(addinfo, "%s:cql_parser_string failed: %s",
72                      lead, cql_query);
73         r = YAZ_SRW_QUERY_SYNTAX_ERROR;
74     }
75     else
76     {
77         WRBUF pqf = wrbuf_alloc();
78         r = cql_transform_r(m_transform, cql_parser_result(cp), addinfo,
79                             wrbuf_vp_puts, pqf);
80         if (!r)
81         {
82             WRBUF sortkeys = wrbuf_alloc();
83             WRBUF sortspec = wrbuf_alloc();
84             if (cql_sortby_to_sortkeys(cql_parser_result(cp),
85                                        wrbuf_vp_puts, sortkeys))
86             {
87                 wrbuf_printf(addinfo, "%s: cql_parser_string failed: %s",
88                              lead, cql_query);
89                 r = YAZ_SRW_UNSUPP_SORT_TYPE;
90             }
91             else
92             {
93                 yaz_srw_sortkeys_to_sort_spec(wrbuf_cstr(sortkeys), sortspec);
94                 Z_SortKeySpecList *sksl =
95                     yaz_sort_spec(o, wrbuf_cstr(sortspec));
96                 if (sksl)
97                     yaz_sort_spec_to_type7(sksl, pqf);
98             }
99             wrbuf_destroy(sortspec);
100             wrbuf_destroy(sortkeys);
101
102             YAZ_PQF_Parser pp = yaz_pqf_create();
103
104             *rpnquery = yaz_pqf_parse(pp, o, wrbuf_cstr(pqf));
105             if (!*rpnquery)
106             {
107                 size_t off;
108                 const char *pqf_msg;
109                 yaz_pqf_error(pp, &pqf_msg, &off);
110                 wrbuf_printf(addinfo, "%s: yaz_pqf_parse failed: %s",
111                              lead, wrbuf_cstr(pqf));
112                 r = YAZ_SRW_SYSTEM_TEMPORARILY_UNAVAILABLE;
113             }
114             yaz_pqf_destroy(pp);
115         }
116         wrbuf_destroy(pqf);
117     }
118     cql_parser_destroy(cp);
119     if (r && wrbuf_len(addinfo))
120         *addinfop = odr_strdup_null(o, wrbuf_cstr(addinfo));
121     else
122         *addinfop = 0;
123     wrbuf_destroy(addinfo);
124     return r;
125 }
126 /*
127  * Local variables:
128  * c-basic-offset: 4
129  * c-file-style: "Stroustrup"
130  * indent-tabs-mode: nil
131  * End:
132  * vim: shiftwidth=4 tabstop=8 expandtab
133  */
134