From 57cae124c6a1c7cdd8c70090db636b227887fc19 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Tue, 6 Sep 2011 13:14:44 +0200 Subject: [PATCH] New ZOOM utility ZOOM_query_sortby2 That takes a strategy parameter: one of "z3950", "type7", "cql", "sru11" or "embed". The "embed" chooses type-7 or CQL sortby depending on whether Type-1 or CQL is actually sent to the target. "sru11" not implemented yet. --- include/yaz/zoom.h | 2 + src/zoom-p.h | 2 +- src/zoom-query.c | 159 ++++++++++++++++++++++++++++++++++++++++------------ src/zoom-sru.c | 7 ++- test/.gitignore | 1 + zoom/zoomtst5.c | 97 +++++++++++++++++--------------- 6 files changed, 183 insertions(+), 85 deletions(-) diff --git a/include/yaz/zoom.h b/include/yaz/zoom.h index a505e12..63ebc14 100644 --- a/include/yaz/zoom.h +++ b/include/yaz/zoom.h @@ -295,6 +295,8 @@ ZOOM_query_prefix(ZOOM_query s, const char *str); /* specify sort criteria for search */ ZOOM_API(int) ZOOM_query_sortby(ZOOM_query s, const char *criteria); +ZOOM_API(int) +ZOOM_query_sortby2(ZOOM_query s, const char *strategy, const char *criteria); ZOOM_API(void) ZOOM_query_addref(ZOOM_query s); diff --git a/src/zoom-p.h b/src/zoom-p.h index fd2a04c..b62ad3b 100644 --- a/src/zoom-p.h +++ b/src/zoom-p.h @@ -263,7 +263,7 @@ void ZOOM_record_cache_add(ZOOM_resultset r, Z_NamePlusRecord *npr, Z_Query *ZOOM_query_get_Z_Query(ZOOM_query s); Z_SortKeySpecList *ZOOM_query_get_sortspec(ZOOM_query s); -char *ZOOM_query_get_query_string(ZOOM_query s); +const char *ZOOM_query_get_query_string(ZOOM_query s); int ZOOM_uri_to_code(const char *uri); diff --git a/src/zoom-query.c b/src/zoom-query.c index c0e4312..e80b235 100644 --- a/src/zoom-query.c +++ b/src/zoom-query.c @@ -23,23 +23,91 @@ #include #include +#define SORT_STRATEGY_Z3950 0 +#define SORT_STRATEGY_TYPE7 1 +#define SORT_STRATEGY_CQL 2 +#define SORT_STRATEGY_SRU11 3 +#define SORT_STRATEGY_EMBED 4 + struct ZOOM_query_p { Z_Query *z_query; + int sort_strategy; Z_SortKeySpecList *sort_spec; int refcount; - ODR odr; + ODR odr_sort_spec; + ODR odr_query; + int query_type; char *query_string; + WRBUF full_query; }; +static int generate(ZOOM_query s) +{ + if (s->query_string) + { + Z_External *ext; + + wrbuf_rewind(s->full_query); + wrbuf_puts(s->full_query, s->query_string); + odr_reset(s->odr_query); + + switch (s->query_type) + { + case Z_Query_type_1: /* RPN */ + if (s->sort_spec && + (s->sort_strategy == SORT_STRATEGY_TYPE7 || + s->sort_strategy == SORT_STRATEGY_EMBED)) + { + int r = yaz_sort_spec_to_type7(s->sort_spec, s->full_query); + if (r) + return r; + } + s->z_query = (Z_Query *) odr_malloc(s->odr_query, + sizeof(*s->z_query)); + s->z_query->which = Z_Query_type_1; + s->z_query->u.type_1 = + p_query_rpn(s->odr_query, wrbuf_cstr(s->full_query)); + if (!s->z_query->u.type_1) + { + s->z_query = 0; + return -1; + } + break; + case Z_Query_type_104: /* CQL */ + if (s->sort_spec && + (s->sort_strategy == SORT_STRATEGY_CQL || + s->sort_strategy == SORT_STRATEGY_EMBED)) + { + int r = yaz_sort_spec_to_cql(s->sort_spec, s->full_query); + if (r) + return r; + } + ext = (Z_External *) odr_malloc(s->odr_query, sizeof(*ext)); + ext->direct_reference = odr_oiddup(s->odr_query, + yaz_oid_userinfo_cql); + ext->indirect_reference = 0; + ext->descriptor = 0; + ext->which = Z_External_CQL; + ext->u.cql = odr_strdup(s->odr_query, wrbuf_cstr(s->full_query)); + + s->z_query = (Z_Query *) odr_malloc(s->odr_query, sizeof(*s->z_query)); + s->z_query->which = Z_Query_type_104; + s->z_query->u.type_104 = ext; + + break; + } + } + return 0; +} + Z_Query *ZOOM_query_get_Z_Query(ZOOM_query s) { return s->z_query; } - Z_SortKeySpecList *ZOOM_query_get_sortspec(ZOOM_query s) { - return s->sort_spec; + return s->sort_strategy == SORT_STRATEGY_Z3950 ? s->sort_spec : 0; } static void cql2pqf_wrbuf_puts(const char *buf, void *client_data) @@ -48,9 +116,9 @@ static void cql2pqf_wrbuf_puts(const char *buf, void *client_data) wrbuf_puts(wrbuf, buf); } -char *ZOOM_query_get_query_string(ZOOM_query s) +const char *ZOOM_query_get_query_string(ZOOM_query s) { - return s->query_string; + return wrbuf_cstr(s->full_query); } /* @@ -119,9 +187,11 @@ ZOOM_API(ZOOM_query) s->refcount = 1; s->z_query = 0; s->sort_spec = 0; - s->odr = odr_createmem(ODR_ENCODE); + s->odr_query = odr_createmem(ODR_ENCODE); + s->odr_sort_spec = odr_createmem(ODR_ENCODE); s->query_string = 0; - + s->full_query = wrbuf_alloc(); + s->sort_strategy = SORT_STRATEGY_Z3950; return s; } @@ -134,7 +204,10 @@ ZOOM_API(void) (s->refcount)--; if (s->refcount == 0) { - odr_destroy(s->odr); + odr_destroy(s->odr_query); + odr_destroy(s->odr_sort_spec); + xfree(s->query_string); + wrbuf_destroy(s->full_query); xfree(s); } } @@ -145,40 +218,23 @@ ZOOM_API(void) s->refcount++; } + ZOOM_API(int) ZOOM_query_prefix(ZOOM_query s, const char *str) { - s->query_string = odr_strdup(s->odr, str); - s->z_query = (Z_Query *) odr_malloc(s->odr, sizeof(*s->z_query)); - s->z_query->which = Z_Query_type_1; - s->z_query->u.type_1 = p_query_rpn(s->odr, str); - if (!s->z_query->u.type_1) - { - s->z_query = 0; - return -1; - } - return 0; + xfree(s->query_string); + s->query_string = xstrdup(str); + s->query_type = Z_Query_type_1; + return generate(s); } ZOOM_API(int) ZOOM_query_cql(ZOOM_query s, const char *str) { - Z_External *ext; - - s->query_string = odr_strdup(s->odr, str); - - ext = (Z_External *) odr_malloc(s->odr, sizeof(*ext)); - ext->direct_reference = odr_oiddup(s->odr, yaz_oid_userinfo_cql); - ext->indirect_reference = 0; - ext->descriptor = 0; - ext->which = Z_External_CQL; - ext->u.cql = s->query_string; - - s->z_query = (Z_Query *) odr_malloc(s->odr, sizeof(*s->z_query)); - s->z_query->which = Z_Query_type_104; - s->z_query->u.type_104 = ext; - - return 0; + xfree(s->query_string); + s->query_string = xstrdup(str); + s->query_type = Z_Query_type_104; + return generate(s); } /* @@ -247,13 +303,42 @@ ZOOM_API(int) ZOOM_API(int) ZOOM_query_sortby(ZOOM_query s, const char *criteria) { - s->sort_spec = yaz_sort_spec(s->odr, criteria); + return ZOOM_query_sortby2(s, "z3950", criteria); +} + +ZOOM_API(int) +ZOOM_query_sortby2(ZOOM_query s, const char *strategy, const char *criteria) +{ + if (!strcmp(strategy, "z3950")) + { + s->sort_strategy = SORT_STRATEGY_Z3950; + } + else if (!strcmp(strategy, "type7")) + { + s->sort_strategy = SORT_STRATEGY_TYPE7; + } + else if (!strcmp(strategy, "cql")) + { + s->sort_strategy = SORT_STRATEGY_CQL; + } + else if (!strcmp(strategy, "sru11")) + { + s->sort_strategy = SORT_STRATEGY_SRU11; + } + else if (!strcmp(strategy, "embed")) + { + s->sort_strategy = SORT_STRATEGY_EMBED; + } + else + return -1; + + odr_reset(s->odr_sort_spec); + s->sort_spec = yaz_sort_spec(s->odr_sort_spec, criteria); if (!s->sort_spec) return -1; - return 0; + return generate(s); } - /* * Local variables: * c-basic-offset: 4 diff --git a/src/zoom-sru.c b/src/zoom-sru.c index f9baf44..d52372f 100644 --- a/src/zoom-sru.c +++ b/src/zoom-sru.c @@ -101,14 +101,14 @@ zoom_ret ZOOM_connection_srw_send_scan(ZOOM_connection c) { sr->u.scan_request->query_type = Z_SRW_query_type_cql; sr->u.scan_request->scanClause.cql = - ZOOM_query_get_query_string(scan->query); + odr_strdup(c->odr_out, ZOOM_query_get_query_string(scan->query)); } else if (z_query->which == Z_Query_type_1 || z_query->which == Z_Query_type_101) { sr->u.scan_request->query_type = Z_SRW_query_type_pqf; sr->u.scan_request->scanClause.pqf = - ZOOM_query_get_query_string(scan->query); + odr_strdup(c->odr_out, ZOOM_query_get_query_string(scan->query)); } else { @@ -209,7 +209,8 @@ zoom_ret ZOOM_connection_srw_send_search(ZOOM_connection c) { sr->u.request->query_type = Z_SRW_query_type_pqf; sr->u.request->query.pqf = - ZOOM_query_get_query_string(resultset->query); + odr_strdup(c->odr_out, + ZOOM_query_get_query_string(resultset->query)); } else { diff --git a/test/.gitignore b/test/.gitignore index 4b086b2..b05f748 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -23,6 +23,7 @@ test_filepath test_record_conv test_retrieval test_tpath +test_sortspec test_timing test_comstack test_query_charset diff --git a/zoom/zoomtst5.c b/zoom/zoomtst5.c index 24bcac7..495a101 100644 --- a/zoom/zoomtst5.c +++ b/zoom/zoomtst5.c @@ -10,9 +10,9 @@ #include #include -const char *my_callback (void *handle, const char *name) +const char *my_callback(void *handle, const char *name) { - if (!strcmp (name, "async")) + if (!strcmp(name, "async")) return "1"; return 0; } @@ -20,106 +20,115 @@ const char *my_callback (void *handle, const char *name) int main(int argc, char **argv) { int i; - int no = argc-3; + int no = argc - 4; ZOOM_connection z[500]; /* allow at most 500 connections */ ZOOM_resultset r[500]; /* and result sets .. */ ZOOM_query q; ZOOM_options o; - o = ZOOM_options_create (); - if (argc < 4) + o = ZOOM_options_create(); + if (argc < 5) { - fprintf (stderr, "usage:\n%s target1 .. targetN query sort\n", - *argv); - exit (2); + fprintf(stderr, "usage:\n%s target1 .. targetN query strategy sort\n", + *argv); + exit(2); } if (no > 500) no = 500; /* function my_callback called when reading options .. */ - ZOOM_options_set_callback (o, my_callback, 0); + ZOOM_options_set_callback(o, my_callback, 0); /* get 20 (at most) records from beginning */ - ZOOM_options_set (o, "count", "20"); + ZOOM_options_set(o, "count", "20"); - ZOOM_options_set (o, "implementationName", "sortapp"); - ZOOM_options_set (o, "preferredRecordSyntax", "usmarc"); - ZOOM_options_set (o, "elementSetName", "B"); + ZOOM_options_set(o, "implementationName", "sortapp"); + ZOOM_options_set(o, "preferredRecordSyntax", "usmarc"); + ZOOM_options_set(o, "elementSetName", "B"); /* create query */ - q = ZOOM_query_create (); - if (ZOOM_query_prefix (q, argv[argc-2])) + q = ZOOM_query_create(); + if (strncmp("cql:", argv[argc-3], 4) == 0) { - printf ("bad PQF: %s\n", argv[argc-2]); - exit (1); + if (ZOOM_query_cql(q, argv[argc-3] + 4)) + { + printf("bad CQL: %s\n", argv[argc-3] + 4); + exit(1); + } + } + else if (ZOOM_query_prefix(q, argv[argc-3])) + { + printf("bad PQF: %s\n", argv[argc-3]); + exit(1); } - if (ZOOM_query_sortby (q, argv[argc-1])) + if (ZOOM_query_sortby2(q, argv[argc-2], argv[argc-1])) { - printf ("bad sort spec: %s\n", argv[argc-1]); - exit (1); + printf("bad sort spec: %s\n", argv[argc-1]); + exit(1); } /* connect - and search all */ - for (i = 0; i