From: Adam Dickmeiss Date: Tue, 3 May 2011 14:04:00 +0000 (+0200) Subject: CQL sortby; conversion to XML done. X-Git-Tag: v4.2.0~37 X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=commitdiff_plain;h=262800f89e3280c5b594faf6eea2c98e988ee2cb CQL sortby; conversion to XML done. The cql_node struct has not changed size but a new type of node CQL_NODE_SORT is new. Strictly speaking this breaks binary compatibility so perhaps this has to be enabled "actively", by API. Bug #608. --- diff --git a/include/yaz/cql.h b/include/yaz/cql.h index 2c92470..c9df2ac 100644 --- a/include/yaz/cql.h +++ b/include/yaz/cql.h @@ -100,6 +100,9 @@ int cql_parser_stdio(CQL_parser cp, FILE *f); #define CQL_NODE_ST 1 /** \brief Node type: boolean */ #define CQL_NODE_BOOL 2 +/** \brief Node type: sortby single spec */ +#define CQL_NODE_SORT 3 + /** \brief CQL parse tree (node) */ struct cql_node { @@ -134,6 +137,16 @@ struct cql_node { /** modifiers (NULL for no list) */ struct cql_node *modifiers; } boolean; + /** which == CQL_NODE_SORT */ + struct { + char *index; + /** next spec */ + struct cql_node *next; + /** modifiers (NULL for no list) */ + struct cql_node *modifiers; + /** search node */ + struct cql_node *search; + } sort; } u; }; @@ -178,6 +191,11 @@ struct cql_node *cql_apply_prefix(NMEM nmem, struct cql_node *cn, YAZ_EXPORT struct cql_node *cql_node_mk_boolean(NMEM nmem, const char *op); +/** \brief creates a sort single spec node. */ +YAZ_EXPORT +struct cql_node *cql_node_mk_sort(NMEM nmem, const char *index, + struct cql_node *modifiers); + /** \brief destroys a node and its children. */ YAZ_EXPORT void cql_node_destroy(struct cql_node *cn); @@ -193,6 +211,13 @@ struct cql_node *cql_node_dup (NMEM nmem, struct cql_node *cp); YAZ_EXPORT struct cql_node *cql_parser_result(CQL_parser cp); +/** \brief returns the sortby tree of the most recently parsed CQL query. + \param cp CQL parser + \returns CQL node or NULL for failure +*/ +YAZ_EXPORT +struct cql_node *cql_parser_sort_result(CQL_parser cp); + /** \brief converts CQL tree to XCQL and writes to user-defined stream \param cn CQL node (tree) \param pr print function diff --git a/src/cql.y b/src/cql.y index 00d806a..4021373 100644 --- a/src/cql.y +++ b/src/cql.y @@ -66,17 +66,35 @@ top: { ((CQL_parser) parm)->top = 0; } cqlQuery1 sortby { cql_node_destroy($$.rel); - ((CQL_parser) parm)->top = $2.cql; + if ($3.cql) + { + $3.cql->u.sort.search = $2.cql; + ((CQL_parser) parm)->top = $3.cql; + } else { + ((CQL_parser) parm)->top = $2.cql; + } } ; sortby: /* empty */ -| SORTBY sortSpec; - -sortSpec: sortSpec singleSpec -| singleSpec; + { $$.cql = 0; } +| SORTBY sortSpec { + $$.cql = $2.cql; + }; + +sortSpec: sortSpec singleSpec { + $$.cql = $1.cql; + $$.cql->u.sort.next = $2.cql; + } +| singleSpec +{ + $$.cql = $1.cql; +}; -singleSpec: index modifiers ; +singleSpec: index modifiers { + $$.cql = cql_node_mk_sort(((CQL_parser) parm)->nmem, $1.buf, $2.cql); + } +; cqlQuery1: cqlQuery | cqlQuery error { @@ -395,8 +413,7 @@ int cql_parser_stream(CQL_parser cp, cp->getbyte = getbyte; cp->ungetbyte = ungetbyte; cp->client_data = client_data; - if (cp->top) - cql_node_destroy(cp->top); + cql_node_destroy(cp->top); cql_parse(cp); if (cp->top) return 0; @@ -428,6 +445,7 @@ struct cql_node *cql_parser_result(CQL_parser cp) { return cp->top; } + /* * Local variables: * c-basic-offset: 4 diff --git a/src/cqlutil.c b/src/cqlutil.c index 8eb25f3..7dba5a7 100644 --- a/src/cqlutil.c +++ b/src/cqlutil.c @@ -83,6 +83,19 @@ struct cql_node *cql_node_mk_boolean(NMEM nmem, const char *op) return p; } +struct cql_node *cql_node_mk_sort(NMEM nmem, const char *index, + struct cql_node *modifiers) +{ + struct cql_node *p = (struct cql_node *) nmem_malloc(nmem, sizeof(*p)); + p->which = CQL_NODE_SORT; + p->u.sort.index = 0; + if (index) + p->u.sort.index = nmem_strdup(nmem, index); + p->u.sort.modifiers = modifiers; + p->u.sort.next = 0; + return p; +} + const char *cql_uri(void) { return "info:srw/cql-context-set/1/cql-v1.2"; @@ -144,6 +157,11 @@ void cql_node_destroy(struct cql_node *cn) cql_node_destroy(cn->u.boolean.left); cql_node_destroy(cn->u.boolean.right); cql_node_destroy(cn->u.boolean.modifiers); + break; + case CQL_NODE_SORT: + cql_node_destroy(cn->u.sort.search); + cql_node_destroy(cn->u.sort.next); + cql_node_destroy(cn->u.sort.modifiers); } } diff --git a/src/xcqlutil.c b/src/xcqlutil.c index 1b15aa2..19b5036 100644 --- a/src/xcqlutil.c +++ b/src/xcqlutil.c @@ -118,9 +118,36 @@ static void cql_to_xml_mod(struct cql_node *m, } } +static void cql_sort_to_xml(struct cql_node *cn, + void (*pr)(const char *buf, void *client_data), + void *client_data, int level) +{ + if (cn) + { + pr_n("\n", pr, client_data, level); + for (; cn; cn = cn->u.sort.next) + { + pr_n("\n", pr, client_data, level+2); + + if (cn->u.sort.index) + { + pr_n("", pr, client_data, level+4); + pr_cdata(cn->u.sort.index, pr, client_data); + pr_n("\n", pr, client_data, 0); + + cql_to_xml_mod(cn->u.sort.modifiers, + pr, client_data, level+6); + } + pr_n("\n", pr, client_data, level+2); + } + pr_n("\n", pr, client_data, level); + } +} + static void cql_to_xml_r(struct cql_node *cn, void (*pr)(const char *buf, void *client_data), - void *client_data, int level) + void *client_data, int level, + struct cql_node *sort_node) { if (!cn) return; @@ -171,6 +198,7 @@ static void cql_to_xml_r(struct cql_node *cn, pr_n("\n", pr, client_data, 0); } } + cql_sort_to_xml(sort_node, pr, client_data, level+2); pr_n("\n", pr, client_data, level); break; case CQL_NODE_BOOL: @@ -191,16 +219,20 @@ static void cql_to_xml_r(struct cql_node *cn, if (cn->u.boolean.left) { printf ("%*s\n", level+2, ""); - cql_to_xml_r(cn->u.boolean.left, pr, client_data, level+4); + cql_to_xml_r(cn->u.boolean.left, pr, client_data, level+4, 0); printf ("%*s\n", level+2, ""); } if (cn->u.boolean.right) { printf ("%*s\n", level+2, ""); - cql_to_xml_r(cn->u.boolean.right, pr, client_data, level+4); + cql_to_xml_r(cn->u.boolean.right, pr, client_data, level+4, 0); printf ("%*s\n", level+2, ""); } + cql_sort_to_xml(sort_node, pr, client_data, level+2); pr_n("\n", pr, client_data, level); + break; + case CQL_NODE_SORT: + cql_to_xml_r(cn->u.sort.search, pr, client_data, level, cn); } } @@ -208,7 +240,7 @@ void cql_to_xml(struct cql_node *cn, void (*pr)(const char *buf, void *client_data), void *client_data) { - cql_to_xml_r(cn, pr, client_data, 0); + cql_to_xml_r(cn, pr, client_data, 0, 0); } void cql_to_xml_stdio(struct cql_node *cn, FILE *f)