#include <yaz/ccl.h>
#include <yaz/sortspec.h>
+#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)
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);
}
/*
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;
}
(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);
}
}
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);
}
/*
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
#include <yaz/xmalloc.h>
#include <yaz/zoom.h>
-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;
}
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<no; i++)
+ for (i = 0; i < no; i++)
{
- z[i] = ZOOM_connection_create (o);
- ZOOM_connection_connect (z[i], argv[i+1], 0);
- r[i] = ZOOM_connection_search (z[i], q);
+ z[i] = ZOOM_connection_create(o);
+ ZOOM_connection_connect(z[i], argv[i+1], 0);
+ r[i] = ZOOM_connection_search(z[i], q);
}
/* network I/O */
- while (ZOOM_event (no, z))
+ while (ZOOM_event(no, z))
;
/* handle errors */
- for (i = 0; i<no; i++)
+ for (i = 0; i < no; i++)
{
int error;
const char *errmsg, *addinfo;
if ((error = ZOOM_connection_error(z[i], &errmsg, &addinfo)))
- fprintf (stderr, "%s error: %s (%d) %s\n",
- ZOOM_connection_option_get(z[i], "host"),
- errmsg, error, addinfo);
+ fprintf(stderr, "%s error: %s (%d) %s\n",
+ ZOOM_connection_option_get(z[i], "host"),
+ errmsg, error, addinfo);
else
{
/* OK, no major errors. Look at the result count */
int pos;
- printf ("%s: %ld hits\n", ZOOM_connection_option_get(z[i], "host"),
- (long) ZOOM_resultset_size(r[i]));
+ printf("%s: %ld hits\n", ZOOM_connection_option_get(z[i], "host"),
+ (long) ZOOM_resultset_size(r[i]));
/* go through first 20 records at target */
for (pos = 0; pos < 20; pos++)
{
ZOOM_record rec;
const char *db, *syntax, *str;
- int len;
+ int record_len, syntax_len;
- rec = ZOOM_resultset_record (r[i], pos);
+ rec = ZOOM_resultset_record(r[i], pos);
/* get database for record and record itself at pos */
- db = ZOOM_record_get (rec, "database", 0);
- str = ZOOM_record_get (rec, "xml", &len);
- syntax = ZOOM_record_get (rec, "syntax", &len);
+ db = ZOOM_record_get(rec, "database", 0);
+ str = ZOOM_record_get(rec, "xml", &record_len);
+ syntax = ZOOM_record_get(rec, "syntax", &syntax_len);
/* if rec is non-null, we got a record for display */
if (str)
{
- printf ("%d %s %s\n", pos+1, syntax,
- (db ? db : "unknown"));
+ printf("%d %s %s\n", pos+1, syntax,
+ (db ? db : "unknown"));
if (rec)
{
- if (fwrite (str, 1, len, stdout) != (size_t) len)
+ if (fwrite(str, 1, record_len, stdout) !=
+ (size_t) record_len)
printf("write to stdout failed\n");
}
- printf ("\n");
+ printf("\n");
}
}
}
}
/* destroy stuff and exit */
- ZOOM_query_destroy (q);
- for (i = 0; i<no; i++)
+ ZOOM_query_destroy(q);
+ for (i = 0; i < no; i++)
{
- ZOOM_resultset_destroy (r[i]);
- ZOOM_connection_destroy (z[i]);
+ ZOOM_resultset_destroy(r[i]);
+ ZOOM_connection_destroy(z[i]);
}
ZOOM_options_destroy(o);
exit(0);