From 3731bdaf94aeba2550fc553aebe34831c203dc36 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Fri, 30 Nov 2007 12:19:08 +0000 Subject: [PATCH] Allow record retrieval for record types using custom record IDs. A filter may specify its own record_id by assigning a non-zero to record_id member in RecWord. However, until this commit, the original record was not retrievable . Updating only occured with a custom match ID. With this patch the record can be retrieved . The allrecords index (_ALLRECORDS) is used as a map between custom record IDs and Zebras internal record store which is identified by the system-number (storeData and storeKeys). --- include/idzebra/recctrl.h | 4 +- index/extract.c | 41 ++++++++++++++-- index/index.h | 15 ++++-- index/reckeys.c | 14 +++++- index/reckeys.h | 3 +- index/retrieve.c | 24 ++++------ index/rpnsearch.c | 10 ++-- index/zebraapi.c | 3 +- index/zsets.c | 117 ++++++++++++++++++++++++++++++++++++++++++++- test/api/safari1.c | 18 +++---- test/api/t16.c | 4 +- test/api/testlib.c | 31 ++++++------ test/api/testlib.h | 12 +++-- 13 files changed, 229 insertions(+), 67 deletions(-) diff --git a/include/idzebra/recctrl.h b/include/idzebra/recctrl.h index e4d3604..b74e831 100644 --- a/include/idzebra/recctrl.h +++ b/include/idzebra/recctrl.h @@ -1,4 +1,4 @@ -/* $Id: recctrl.h,v 1.38 2007-10-31 16:56:14 adam Exp $ +/* $Id: recctrl.h,v 1.39 2007-11-30 12:19:08 adam Exp $ Copyright (C) 1995-2007 Index Data ApS @@ -123,8 +123,6 @@ struct recRetrieveCtrl { int recordSize; /* size of record in bytes */ char *fname; /* name of file (or NULL if internal) */ data1_handle dh; - zebra_snippets *hit_snippet; - zebra_snippets *doc_snippet; /* response */ const Odr_oid * output_format; /* output format OID */ diff --git a/index/extract.c b/index/extract.c index 167793a..5be1488 100644 --- a/index/extract.c +++ b/index/extract.c @@ -1,4 +1,4 @@ -/* $Id: extract.c,v 1.269 2007-11-08 21:21:58 adam Exp $ +/* $Id: extract.c,v 1.270 2007-11-30 12:19:08 adam Exp $ Copyright (C) 1995-2007 Index Data ApS @@ -520,13 +520,29 @@ struct recordLogInfo { struct recordGroup *rGroup; }; -static void all_matches_add(struct recExtractCtrl *ctrl) +/** \brief add the always-matches index entry and map to real record ID + \param ctrl record control + \param record_id custom record ID + \param sysno system record ID + + This function serves two purposes.. It adds the always matches + entry and makes a pointer from the custom record ID (if defined) + back to the system record ID (sysno) + See zebra_recid_to_sysno . + */ +static void all_matches_add(struct recExtractCtrl *ctrl, zint record_id, + zint sysno) { RecWord word; extract_init(ctrl, &word); + word.record_id = record_id; + /* we use the seqno as placeholder for a way to get back to + record database from _ALLRECORDS.. This is used if a custom + RECORD was defined */ + word.seqno = sysno; word.index_name = "_ALLRECORDS"; word.index_type = "w"; - word.seqno = 1; + extract_add_index_string(&word, zinfo_index_category_alwaysmatches, "", 0); } @@ -874,8 +890,6 @@ ZEBRA_RES zebra_extract_record_stream(ZebraHandle zh, else end_offset = stream->tellf(stream); - all_matches_add(&extractCtrl); - if (extractCtrl.match_criteria[0]) match_criteria = extractCtrl.match_criteria; } @@ -919,6 +933,7 @@ ZEBRA_RES zebra_extract_record_stream(ZebraHandle zh, } } } + if (zebra_rec_keys_empty(zh->reg->keys)) { /* the extraction process returned no information - the record @@ -951,6 +966,15 @@ ZEBRA_RES zebra_extract_record_stream(ZebraHandle zh, *sysno = rec->sysno; + + if (stream) + { + all_matches_add(&extractCtrl, + zebra_rec_keys_get_custom_record_id(zh->reg->keys), + *sysno); + } + + recordAttr = rec_init_attr(zh->reg->zei, rec); if (extractCtrl.staticrank < 0) { @@ -992,6 +1016,13 @@ ZEBRA_RES zebra_extract_record_stream(ZebraHandle zh, rec = rec_get(zh->reg->records, *sysno); assert(rec); + + if (stream) + { + all_matches_add(&extractCtrl, + zebra_rec_keys_get_custom_record_id(zh->reg->keys), + *sysno); + } recordAttr = rec_init_attr(zh->reg->zei, rec); diff --git a/index/index.h b/index/index.h index 64d2745..2bbb61a 100644 --- a/index/index.h +++ b/index/index.h @@ -1,4 +1,4 @@ -/* $Id: index.h,v 1.209 2007-11-06 10:29:59 adam Exp $ +/* $Id: index.h,v 1.210 2007-11-30 12:19:08 adam Exp $ Copyright (C) 1995-2007 Index Data ApS @@ -263,7 +263,7 @@ ZEBRA_RES rpn_search_top(ZebraHandle zh, Z_RPNStructure *zs, const Odr_oid *attributeSet, NMEM stream, NMEM rset_nmem, Z_SortKeySpecList *sort_sequence, - int num_bases, char **basenames, + int num_bases, const char **basenames, RSET *result_set); ZEBRA_RES rpn_get_top_approx_limit(ZebraHandle zh, Z_RPNStructure *zs, @@ -282,6 +282,9 @@ RSET rset_trunc(ZebraHandle zh, ISAM_P *isam_p, int no, struct ord_list *ol, const char *index_type, zint hits_limit, const char *term_ref_id); +ZEBRA_RES resultSetGetBaseNames(ZebraHandle zh, const char *setname, + const char ***basenames, int *num_bases); + void resultSetAddTerm(ZebraHandle zh, ZebraSet s, int reg_type, const char *db, const char *index_name, const char *term); @@ -308,7 +311,7 @@ void resultSetInvalidate(ZebraHandle zh); int zebra_record_fetch(ZebraHandle zh, const char *setname, zint sysno, int score, - zebra_snippets *hit_snippet, ODR stream, + ODR stream, const Odr_oid *input_format, Z_RecordComposition *comp, const Odr_oid **output_format, char **rec_bufp, int *rec_lenp, char **basenamep, @@ -440,6 +443,12 @@ ZEBRA_RES rpn_facet(ZebraHandle zh, ODR stream, int *position, int *num_entries, ZebraScanEntry **list, int *is_partial, const char *set_name); + +ZEBRA_RES zebra_result_recid_to_sysno(ZebraHandle zh, + const char *setname, + zint recid, + zint *sysnos, int *no_sysnos); + YAZ_END_CDECL #endif diff --git a/index/reckeys.c b/index/reckeys.c index 002e1fc..5858267 100644 --- a/index/reckeys.c +++ b/index/reckeys.c @@ -1,4 +1,4 @@ -/* $Id: reckeys.c,v 1.12 2007-01-15 15:10:17 adam Exp $ +/* $Id: reckeys.c,v 1.13 2007-11-30 12:19:08 adam Exp $ Copyright (C) 1995-2007 Index Data ApS @@ -64,6 +64,7 @@ struct zebra_rec_keys_t_ { void *encode_handle; void *decode_handle; char owner_of_buffer; + zint custom_record_id; NMEM nmem; size_t hash_size; @@ -133,6 +134,7 @@ zebra_rec_keys_t zebra_rec_keys_open(void) p->encode_handle = iscz1_start(); p->decode_handle = iscz1_start(); + p->custom_record_id = 0; p->nmem = nmem_create(); p->hash_size = 32767; p->entries = 0; @@ -289,6 +291,10 @@ void zebra_rec_keys_write(zebra_rec_keys_t keys, assert(keys->owner_of_buffer); + if (key->mem[1]) /* record_id custom */ + { + keys->custom_record_id = key->mem[1]; + } #if 1 if (!zebra_rec_keys_add_hash(keys, str, slen, key)) { @@ -410,6 +416,12 @@ int zebra_rec_keys_read(zebra_rec_keys_t keys, } return 1; } + +zint zebra_rec_keys_get_custom_record_id(zebra_rec_keys_t keys) +{ + return keys->custom_record_id; +} + /* * Local variables: * c-basic-offset: 4 diff --git a/index/reckeys.h b/index/reckeys.h index 403c16a..3b33b72 100644 --- a/index/reckeys.h +++ b/index/reckeys.h @@ -1,4 +1,4 @@ -/* $Id: reckeys.h,v 1.9 2007-01-15 20:08:25 adam Exp $ +/* $Id: reckeys.h,v 1.10 2007-11-30 12:19:08 adam Exp $ Copyright (C) 1995-2007 Index Data ApS @@ -51,6 +51,7 @@ void zebra_rec_keys_get_buf(zebra_rec_keys_t p, char **buf, size_t *sz); void zebra_rec_keys_set_buf(zebra_rec_keys_t p, char *buf, size_t sz, int copy_buf); +zint zebra_rec_keys_get_custom_record_id(zebra_rec_keys_t keys); YAZ_END_CDECL #endif diff --git a/index/retrieve.c b/index/retrieve.c index 6a56d61..364bd23 100644 --- a/index/retrieve.c +++ b/index/retrieve.c @@ -1,4 +1,4 @@ -/* $Id: retrieve.c,v 1.75 2007-10-31 16:56:14 adam Exp $ +/* $Id: retrieve.c,v 1.76 2007-11-30 12:19:08 adam Exp $ Copyright (C) 1995-2007 Index Data ApS @@ -703,7 +703,7 @@ int zebra_special_fetch(ZebraHandle zh, const char *setname, int zebra_record_fetch(ZebraHandle zh, const char *setname, zint sysno, int score, - zebra_snippets *hit_snippet, ODR odr, + ODR odr, const Odr_oid *input_format, Z_RecordComposition *comp, const Odr_oid **output_format, char **rec_bufp, int *rec_lenp, char **basenamep, @@ -716,7 +716,15 @@ int zebra_record_fetch(ZebraHandle zh, const char *setname, RecordAttr *recordAttr; void *clientData; int return_code = 0; + zint sysnos[10]; + int no_sysnos = 10; + ZEBRA_RES res; + res = zebra_result_recid_to_sysno(zh, setname, sysno, sysnos, &no_sysnos); + if (res != ZEBRA_OK) + return ZEBRA_FAIL; + + sysno = sysnos[0]; *basenamep = 0; *addinfo = 0; elemsetname = yaz_get_esn(comp); @@ -754,7 +762,6 @@ int zebra_record_fetch(ZebraHandle zh, const char *setname, if (rec) { - zebra_rec_keys_t reckeys = zebra_rec_keys_open(); RecType rt; struct recRetrieveCtrl retrieveCtrl; @@ -774,15 +781,6 @@ int zebra_record_fetch(ZebraHandle zh, const char *setname, retrieveCtrl.res = zh->res; retrieveCtrl.rec_buf = 0; retrieveCtrl.rec_len = -1; - retrieveCtrl.hit_snippet = hit_snippet; - retrieveCtrl.doc_snippet = zebra_snippets_create(); - - zebra_rec_keys_set_buf(reckeys, - rec->info[recInfo_delKeys], - rec->size[recInfo_delKeys], - 0); - zebra_rec_keys_to_snippets(zh, reckeys, retrieveCtrl.doc_snippet); - zebra_rec_keys_close(reckeys); if (!(rt = recType_byName(zh->reg->recTypes, zh->res, file_type, &clientData))) @@ -806,8 +804,6 @@ int zebra_record_fetch(ZebraHandle zh, const char *setname, *addinfo = retrieveCtrl.addinfo; } - zebra_snippets_destroy(retrieveCtrl.doc_snippet); - stream.destroy(&stream); rec_free(&rec); } diff --git a/index/rpnsearch.c b/index/rpnsearch.c index 7858cfd..c3d0544 100644 --- a/index/rpnsearch.c +++ b/index/rpnsearch.c @@ -1,4 +1,4 @@ -/* $Id: rpnsearch.c,v 1.23 2007-11-15 08:53:25 adam Exp $ +/* $Id: rpnsearch.c,v 1.24 2007-11-30 12:19:08 adam Exp $ Copyright (C) 1995-2007 Index Data ApS @@ -2143,7 +2143,7 @@ static ZEBRA_RES rpn_search_database(ZebraHandle zh, static ZEBRA_RES rpn_search_APT(ZebraHandle zh, Z_AttributesPlusTerm *zapt, const Odr_oid *attributeSet, NMEM stream, Z_SortKeySpecList *sort_sequence, - int num_bases, char **basenames, + int num_bases, const char **basenames, NMEM rset_nmem, RSET *rset, struct rset_key_control *kc) @@ -2313,7 +2313,7 @@ static ZEBRA_RES rpn_search_structure(ZebraHandle zh, Z_RPNStructure *zs, const Odr_oid *attributeSet, NMEM stream, NMEM rset_nmem, Z_SortKeySpecList *sort_sequence, - int num_bases, char **basenames, + int num_bases, const char **basenames, RSET **result_sets, int *num_result_sets, Z_Operator *parent_op, struct rset_key_control *kc); @@ -2353,7 +2353,7 @@ ZEBRA_RES rpn_search_top(ZebraHandle zh, Z_RPNStructure *zs, const Odr_oid *attributeSet, NMEM stream, NMEM rset_nmem, Z_SortKeySpecList *sort_sequence, - int num_bases, char **basenames, + int num_bases, const char **basenames, RSET *result_set) { RSET *result_sets = 0; @@ -2390,7 +2390,7 @@ ZEBRA_RES rpn_search_structure(ZebraHandle zh, Z_RPNStructure *zs, const Odr_oid *attributeSet, NMEM stream, NMEM rset_nmem, Z_SortKeySpecList *sort_sequence, - int num_bases, char **basenames, + int num_bases, const char **basenames, RSET **result_sets, int *num_result_sets, Z_Operator *parent_op, struct rset_key_control *kc) diff --git a/index/zebraapi.c b/index/zebraapi.c index 676846f..d06dfe1 100644 --- a/index/zebraapi.c +++ b/index/zebraapi.c @@ -1,4 +1,4 @@ -/* $Id: zebraapi.c,v 1.264 2007-11-06 10:29:59 adam Exp $ +/* $Id: zebraapi.c,v 1.265 2007-11-30 12:19:08 adam Exp $ Copyright (C) 1995-2007 Index Data ApS @@ -1149,7 +1149,6 @@ ZEBRA_RES zebra_records_retrieve(ZebraHandle zh, ODR stream, recs[i].errCode = zebra_record_fetch(zh, setname, poset[i].sysno, poset[i].score, - hit_snippet, stream, input_format, comp, &recs[i].format, &buf, &len, &recs[i].base, &recs[i].errString); diff --git a/index/zsets.c b/index/zsets.c index 9eee590..19a6cf8 100644 --- a/index/zsets.c +++ b/index/zsets.c @@ -1,4 +1,4 @@ -/* $Id: zsets.c,v 1.125 2007-11-01 15:59:47 adam Exp $ +/* $Id: zsets.c,v 1.126 2007-11-30 12:19:09 adam Exp $ Copyright (C) 1995-2007 Index Data ApS @@ -50,7 +50,7 @@ struct zebra_set { NMEM rset_nmem; /* for creating the rsets in */ zint hits; int num_bases; - char **basenames; + const char **basenames; Z_RPNQuery *rpn; Z_SortKeySpecList *sortSpec; struct zset_sort_info *sort_info; @@ -305,6 +305,18 @@ ZebraSet resultSetGet(ZebraHandle zh, const char *name) return NULL; } +ZEBRA_RES resultSetGetBaseNames(ZebraHandle zh, const char *setname, + const char ***basenames, int *num_bases) +{ + ZebraSet sset = resultSetGet(zh, setname); + if (!sset) + return ZEBRA_FAIL; + *basenames = sset->basenames; + *num_bases = sset->num_bases; + return ZEBRA_OK; + +} + void resultSetInvalidate(ZebraHandle zh) { ZebraSet s = zh->sets; @@ -1286,6 +1298,107 @@ ZEBRA_RES zebra_snippets_hit_vector(ZebraHandle zh, const char *setname, return ZEBRA_OK; } +static ZEBRA_RES zebra_recid_to_sysno(ZebraHandle zh, + const char **basenames, int num_bases, + zint recid, + zint *sysnos, int *no_sysnos) +{ + ZEBRA_RES res = ZEBRA_OK; + int sysnos_offset = 0; + int i; + + if (zh->reg->isamb) + { + for (i = 0; res == ZEBRA_OK && i < num_bases; i++) + { + const char *database = basenames[i]; + if (zebraExplain_curDatabase(zh->reg->zei, database) == 0) + { + const char *index_type = "w"; + const char *use_string = "_ALLRECORDS"; + int ord; + zinfo_index_category_t cat = zinfo_index_category_alwaysmatches; + ord = zebraExplain_lookup_attr_str(zh->reg->zei, cat, + index_type, use_string); + if (ord != -1) + { + char ord_buf[32]; + int ord_len = key_SU_encode(ord, ord_buf); + char *info; + + ord_buf[ord_len] = '\0'; + + info = dict_lookup(zh->reg->dict, ord_buf); + if (info) + { + if (*info != sizeof(ISAM_P)) + { + res = ZEBRA_FAIL; + } + else + { + ISAM_P isam_p; + ISAMB_PP pt; + struct it_key key_until, key_found; + int i = 0; + int r; + + memcpy(&isam_p, info+1, sizeof(ISAM_P)); + + pt = isamb_pp_open(zh->reg->isamb, isam_p, 2); + if (!pt) + res = ZEBRA_FAIL; + else + { + key_until.mem[i++] = recid; + key_until.mem[i++] = 0; /* section_id */ + if (zh->m_segment_indexing) + key_until.mem[i++] = 0; /* segment */ + key_until.mem[i++] = 0; + key_until.len = i; + + r = isamb_pp_forward(pt, &key_found, &key_until); + while (r && key_found.mem[0] == recid) + { + if (sysnos_offset < *no_sysnos) + sysnos[sysnos_offset] = + key_found.mem[key_found.len-1]; + + yaz_log(YLOG_LOG, "Found " ZINT_FORMAT, + key_found.mem[key_found.len-1]); + r = isamb_pp_read(pt, &key_found); + sysnos_offset++; + } + isamb_pp_close(pt); + } + } + } + } + } + } + } + *no_sysnos = sysnos_offset; + return res; +} + +ZEBRA_RES zebra_result_recid_to_sysno(ZebraHandle zh, + const char *setname, + zint recid, + zint *sysnos, int *no_sysnos) +{ + const char **basenames; + int num_bases; + ZEBRA_RES res; + + res = resultSetGetBaseNames(zh, setname, &basenames, &num_bases); + if (res != ZEBRA_OK) + return ZEBRA_FAIL; + + return zebra_recid_to_sysno(zh, basenames, num_bases, + recid, sysnos, no_sysnos); +} + + /* * Local variables: * c-basic-offset: 4 diff --git a/test/api/safari1.c b/test/api/safari1.c index 1ffd12a..0b311c5 100644 --- a/test/api/safari1.c +++ b/test/api/safari1.c @@ -1,4 +1,4 @@ -/* $Id: safari1.c,v 1.18 2007-11-30 10:08:01 adam Exp $ +/* $Id: safari1.c,v 1.19 2007-11-30 12:19:09 adam Exp $ Copyright (C) 1995-2007 Index Data ApS @@ -95,17 +95,13 @@ static void tst(int argc, char **argv) ids[1] = 24339; ids[2] = 24340; YAZ_CHECK(tl_meta_query(zh, "@attr 4=3 @attr 1=any mand", 3, ids)); - -#if 0 - { - zint sysnos[10]; - int no_sysnos = 10; - YAZ_CHECK_EQ(zebra_recid_to_sysno(zh, "Default", 24338, sysnos, - &no_sysnos), ZEBRA_OK); - YAZ_CHECK_EQ(no_sysnos, 1); - } -#endif + YAZ_CHECK_EQ(tl_fetch_compare(zh, 1, "R", yaz_oid_recsyn_sutrs, + myrec[0]), ZEBRA_OK); + YAZ_CHECK_EQ(tl_fetch_compare(zh, 2, "R", yaz_oid_recsyn_sutrs, + myrec[2]), ZEBRA_OK); + YAZ_CHECK_EQ(tl_fetch_compare(zh, 3, "R", yaz_oid_recsyn_sutrs, + myrec[4]), ZEBRA_OK); /* limit to 125061 */ limits[0] = 125061; limits[1] = 0; diff --git a/test/api/t16.c b/test/api/t16.c index aa2cc65..59b4807 100644 --- a/test/api/t16.c +++ b/test/api/t16.c @@ -1,4 +1,4 @@ -/* $Id: t16.c,v 1.13 2007-11-30 10:08:01 adam Exp $ +/* $Id: t16.c,v 1.14 2007-11-30 12:19:09 adam Exp $ Copyright (C) 1995-2007 Index Data ApS @@ -50,7 +50,7 @@ static void tst(int argc, char **argv) YAZ_CHECK(tl_init_data(zh, myrec)); - res = zebra_search_PQF(zh, "@attr 1=4 my", "default", &hits); + res = zebra_search_PQF(zh, "@attr 1=4 my", "rsetname", &hits); YAZ_CHECK_EQ(res, ZEBRA_OK); YAZ_CHECK_EQ(hits, 1); diff --git a/test/api/testlib.c b/test/api/testlib.c index 7773351..2be2920 100644 --- a/test/api/testlib.c +++ b/test/api/testlib.c @@ -1,4 +1,4 @@ -/* $Id: testlib.c,v 1.46 2007-11-30 10:08:01 adam Exp $ +/* $Id: testlib.c,v 1.47 2007-11-30 12:19:09 adam Exp $ Copyright (C) 1995-2007 Index Data ApS @@ -450,19 +450,19 @@ void tl_check_filter(ZebraService zs, const char *name) } } -ZEBRA_RES tl_fetch_first(ZebraHandle zh, const char *element_set, - const Odr_oid * format, ODR odr, - const char **rec_buf, size_t *rec_len) +ZEBRA_RES tl_fetch(ZebraHandle zh, int position, const char *element_set, + const Odr_oid * format, ODR odr, + const char **rec_buf, size_t *rec_len) { ZebraRetrievalRecord retrievalRecord[1]; Z_RecordComposition *comp; ZEBRA_RES res; - retrievalRecord[0].position = 1; /* get from this position */ + retrievalRecord[0].position = position; yaz_set_esn(&comp, element_set, odr->mem); - res = zebra_records_retrieve(zh, odr, "default", comp, format, 1, + res = zebra_records_retrieve(zh, odr, "rsetname", comp, format, 1, retrievalRecord); if (res != ZEBRA_OK) { @@ -478,15 +478,15 @@ ZEBRA_RES tl_fetch_first(ZebraHandle zh, const char *element_set, return res; } -ZEBRA_RES tl_fetch_first_compare(ZebraHandle zh, - const char *element_set, - const Odr_oid *format, const char *cmp_rec) +ZEBRA_RES tl_fetch_compare(ZebraHandle zh, + int position, const char *element_set, + const Odr_oid *format, const char *cmp_rec) { const char *rec_buf = 0; size_t rec_len = 0; ODR odr = odr_createmem(ODR_ENCODE); - ZEBRA_RES res = tl_fetch_first(zh, element_set, format, odr, - &rec_buf, &rec_len); + ZEBRA_RES res = tl_fetch(zh, position, element_set, format, odr, + &rec_buf, &rec_len); if (res == ZEBRA_OK) { if (strlen(cmp_rec) != rec_len) @@ -498,9 +498,12 @@ ZEBRA_RES tl_fetch_first_compare(ZebraHandle zh, return res; } - - - +ZEBRA_RES tl_fetch_first_compare(ZebraHandle zh, + const char *element_set, + const Odr_oid *format, const char *cmp_rec) +{ + return tl_fetch_compare(zh, 1, element_set, format, cmp_rec); +} /* * Local variables: diff --git a/test/api/testlib.h b/test/api/testlib.h index b433436..09773a5 100644 --- a/test/api/testlib.h +++ b/test/api/testlib.h @@ -1,4 +1,4 @@ -/* $Id: testlib.h,v 1.26 2007-11-30 10:08:01 adam Exp $ +/* $Id: testlib.h,v 1.27 2007-11-30 12:19:09 adam Exp $ Copyright (C) 1995-2007 Index Data ApS @@ -127,9 +127,13 @@ ZEBRA_RES tl_fetch_first_compare(ZebraHandle zh, const char *element_set, const Odr_oid *format, const char *cmp_rec); -ZEBRA_RES tl_fetch_first(ZebraHandle zh, const char *element_set, - const Odr_oid * format, ODR odr, - const char **rec_buf, size_t *rec_len); +ZEBRA_RES tl_fetch(ZebraHandle zh, + int position, const char *element_set, + const Odr_oid * format, ODR odr, + const char **rec_buf, size_t *rec_len); +ZEBRA_RES tl_fetch_compare(ZebraHandle zh, + int position, const char *element_set, + const Odr_oid *format, const char *cmp_rec); #define TL_MAIN int main(int argc, char **argv) { \ YAZ_CHECK_INIT(argc, argv); YAZ_CHECK_LOG(); tst(argc, argv); YAZ_CHECK_TERM; } -- 1.7.10.4