X-Git-Url: http://lists.indexdata.com/cgi-bin?a=blobdiff_plain;f=perl%2Fzebra_api_ext.c;h=49663f47353dbee005a10399bdacaea530f349db;hb=8e1d114f1969b19d12afc6ab0b04031e35ae5c88;hp=90e40c4ad7ea09c809d69409639d5ce5cf03ee2a;hpb=af03c4a4f5320b52c7cc5f47bab7c9ad4b3e384d;p=idzebra-moved-to-github.git diff --git a/perl/zebra_api_ext.c b/perl/zebra_api_ext.c index 90e40c4..49663f4 100644 --- a/perl/zebra_api_ext.c +++ b/perl/zebra_api_ext.c @@ -12,9 +12,12 @@ #include "index.h" #include #include -#include "rg.h" +#include "zebra_perl.h" +#include "zebra_api_ext.h" #include "yaz/log.h" #include +#include +#include void data1_print_tree(data1_handle dh, data1_node *n, FILE *out) { data1_pr_tree(dh, n, stdout); @@ -27,13 +30,6 @@ int zebra_get_shadow_enable (ZebraHandle zh) { void zebra_set_shadow_enable (ZebraHandle zh, int value) { zh->shadow_enable = value; } -/* recordGroup stuff */ -void describe_recordGroup (recordGroup *rg) { - printf ("name:%s\ndatabaseName%s\npath:%s\n", - rg->groupName, - rg->databaseName, - rg->path); -} void init_recordGroup (recordGroup *rg) { rg->groupName = NULL; @@ -42,13 +38,13 @@ void init_recordGroup (recordGroup *rg) { rg->recordId = NULL; rg->recordType = NULL; rg->flagStoreData = -1; - rg->flagStoreKeys = -1; + rg->flagStoreKeys = -1; rg->flagRw = 1; rg->databaseNamePath = 0; - rg->explainDatabase = 0; - rg->fileVerboseLimit = 100000; + rg->explainDatabase = 0; + rg->fileVerboseLimit = 100000; rg->followLinks = -1; -} +} /* This is from extract.c... it seems useful, when extract_rec_in mem is @@ -57,11 +53,11 @@ void res_get_recordGroup (ZebraHandle zh, recordGroup *rGroup, const char *ext) { char gprefix[128]; - char ext_res[128]; + char ext_res[128]; if (!rGroup->groupName || !*rGroup->groupName) *gprefix = '\0'; - else + else sprintf (gprefix, "%s.", rGroup->groupName); /* determine file type - depending on extension */ @@ -73,18 +69,18 @@ void res_get_recordGroup (ZebraHandle zh, } } /* determine match criteria */ - if (!rGroup->recordId) { + if (!rGroup->recordId) { sprintf (ext_res, "%srecordId.%s", gprefix, ext); if (!(rGroup->recordId = res_get (zh->res, ext_res))) { sprintf (ext_res, "%srecordId", gprefix); rGroup->recordId = res_get (zh->res, ext_res); } - } + } /* determine database name */ if (!rGroup->databaseName) { sprintf (ext_res, "%sdatabase.%s", gprefix, ext); - if (!(rGroup->databaseName = res_get (zh->res, ext_res))) { + if (!(rGroup->databaseName = res_get (zh->res, ext_res))) { sprintf (ext_res, "%sdatabase", gprefix); rGroup->databaseName = res_get (zh->res, ext_res); } @@ -125,6 +121,10 @@ void res_get_recordGroup (ZebraHandle zh, } if (rGroup->flagStoreKeys == -1) rGroup->flagStoreKeys = 0; +} + +int zebra_trans_processed(ZebraTransactionStatus s) { + return (s.processed); } /* --------------------------------------------------------------------------- @@ -133,11 +133,11 @@ void res_get_recordGroup (ZebraHandle zh, If sysno is provided, then it's used to identify the reocord. If not, and match_criteria is provided, then sysno is guessed If not, and a record is provided, then sysno is got from there - */ int zebra_update_record (ZebraHandle zh, - struct recordGroup *rGroup, + struct recordGroup *rGroup, + const char *recordType, int sysno, const char *match, const char *fname, const char *buf, int buf_size) @@ -146,17 +146,20 @@ int zebra_update_record (ZebraHandle zh, if (buf_size < 1) buf_size = strlen(buf); + zebra_begin_trans(zh); res=bufferExtractRecord (zh, buf, buf_size, rGroup, - 0, // delete_flag - 0, // test_mode, - &sysno, - match, fname); - - return sysno; + 0, // delete_flag + 0, // test_mode, + recordType, + &sysno, + match, fname); + zebra_end_trans(zh); + return sysno; } int zebra_delete_record (ZebraHandle zh, struct recordGroup *rGroup, + const char *recordType, int sysno, const char *match, const char *fname, const char *buf, int buf_size) { @@ -164,13 +167,24 @@ int zebra_delete_record (ZebraHandle zh, if (buf_size < 1) buf_size = strlen(buf); + zebra_begin_trans(zh); res=bufferExtractRecord (zh, buf, buf_size, rGroup, 1, // delete_flag 0, // test_mode, + recordType, &sysno, match,fname); - return sysno; + zebra_end_trans(zh); + return sysno; } + +/* --------------------------------------------------------------------------- + Searching + + zebra_search_RPN is the same as zebra_search_rpn, except that read locking + is not mandatory. (it's repeatable now, also in zebraapi.c) +*/ + void zebra_search_RPN (ZebraHandle zh, ODR decode, ODR stream, Z_RPNQuery *query, const char *setname, int *hits) { @@ -182,28 +196,9 @@ void zebra_search_RPN (ZebraHandle zh, ODR decode, ODR stream, resultSetAddRPN (zh, decode, stream, query, zh->num_basenames, zh->basenames, setname); - zebra_end_read (zh); - - *hits = zh->hits; -} - -void zebra_retrieve_sysnos (ZebraHandle zh, - const char *setname, - int num_recs) -{ - if (!zh->res) { - zh->errCode = 30; - /* zh->errString = odr_strdup (stream, setname); */ - logf(LOG_FATAL,"No resources open"); - return; - } - - zh->errCode = 0; - if (zebra_begin_read (zh)) - return; - zebra_end_read (zh); + *hits = zh->hits; } int zebra_search_PQF (ZebraHandle zh, @@ -214,9 +209,7 @@ int zebra_search_PQF (ZebraHandle zh, { int hits; Z_RPNQuery *query; - logf (LOG_LOG, "11"); query = p_query_rpn (odr_input, PROTO_Z3950, pqf_query); - logf (LOG_LOG, "22"); if (!query) { logf (LOG_WARN, "bad query %s\n", pqf_query); @@ -230,3 +223,346 @@ int zebra_search_PQF (ZebraHandle zh, return(hits); } + +int zebra_cql2pqf (cql_transform_t ct, + const char *query, char *res, int len) { + + int status; + const char *addinfo = ""; + CQL_parser cp = cql_parser_create(); + + if (status = cql_parser_string(cp, query)) { + cql_parser_destroy(cp); + return (status); + } + + if (cql_transform_buf(ct, cql_parser_result(cp), res, len)) { + status = cql_transform_error(ct, &addinfo); + logf (LOG_WARN,"Transform error %d %s\n", status, addinfo ? addinfo : ""); + cql_parser_destroy(cp); + return (status); + } + + cql_parser_destroy(cp); + return (0); +} + +void zebra_scan_PQF (ZebraHandle zh, + ScanObj *so, + ODR stream, + const char *pqf_query) +{ + Z_AttributesPlusTerm *zapt; + Odr_oid *attrsetid; + const char* oidname; + oid_value attributeset; + ZebraScanEntry *entries; + int i, class; + + logf(LOG_DEBUG, + "scan req: pos:%d, num:%d, partial:%d", + so->position, so->num_entries, so->is_partial); + + zapt = p_query_scan (stream, PROTO_Z3950, &attrsetid, pqf_query); + + oidname = yaz_z3950oid_to_str (attrsetid, &class); + logf (LOG_DEBUG, "Attributreset: %s", oidname); + attributeset = oid_getvalbyname(oidname); + + if (!zapt) { + logf (LOG_WARN, "bad query %s\n", pqf_query); + odr_reset (stream); + return; + } + + so->entries = (ScanEntry *) + odr_malloc (stream, sizeof(so->entries) * (so->num_entries)); + + + zebra_scan (zh, stream, zapt, attributeset, + &so->position, &so->num_entries, + (ZebraScanEntry **) &so->entries, &so->is_partial); + + logf(LOG_DEBUG, + "scan res: pos:%d, num:%d, partial:%d", + so->position, so->num_entries, so->is_partial); +} + +ScanEntry *getScanEntry(ScanObj *so, int pos) { + return (&so->entries[pos-1]); +} + +/* --------------------------------------------------------------------------- + Record retrieval + 2 phase retrieval - I didn't manage to return array of blessed references + to wrapped structures... it's feasible, but I'll need some time + / pop - 2002-11-17 +*/ + +void record_retrieve(RetrievalObj *ro, + ODR stream, + RetrievalRecord *res, + int pos) +{ + int i = pos - 1; + + + RetrievalRecordBuf *buf = + (RetrievalRecordBuf *) odr_malloc(stream, sizeof(*buf)); + + res->errCode = ro->records[i].errCode; + if (ro->records[i].errString) { + res->errString = odr_strdup(stream, ro->records[i].errString); + } else { + res->errString = ""; + } + res->position = ro->records[i].position; + res->base = ro->records[i].base; + res->format = (char *) + yaz_z3950_oid_value_to_str(ro->records[i].format, CLASS_RECSYN); + res->buf = buf; + res->buf->len = ro->records[i].len; + res->buf->buf = ro->records[i].buf; + res->score = ro->records[i].score; + res->sysno = ro->records[i].sysno; + +} + +/* most of the code here was copied from yaz-client */ +void records_retrieve(ZebraHandle zh, + ODR stream, + const char *setname, + const char *a_eset, + const char *a_schema, + const char *a_format, + int from, + int to, + RetrievalObj *res) +{ + static enum oid_value recordsyntax = VAL_SUTRS; + static enum oid_value schema = VAL_NONE; + static Z_ElementSetNames *elementSetNames = 0; + static Z_RecordComposition compo; + static Z_ElementSetNames esn; + static char what[100]; + int i; + int oid[OID_SIZE]; + + compo.which = -1; + + if (from < 1) from = 1; + if (from > to) to = from; + res->noOfRecords = to - from + 1; + + res->records = odr_malloc (stream, + sizeof(*res->records) * (res->noOfRecords)); + + for (i = 0; inoOfRecords; i++) res->records[i].position = from+i; + + if (!a_eset || !*a_eset) { + elementSetNames = 0; + } else { + strcpy(what, a_eset); + esn.which = Z_ElementSetNames_generic; + esn.u.generic = what; + elementSetNames = &esn; + } + + if (!a_schema || !*a_schema) { + schema = VAL_NONE; + } else { + schema = oid_getvalbyname (a_schema); + if (schema == VAL_NONE) { + logf(LOG_WARN,"unknown schema '%s'",a_schema); + } + } + + + if (!a_format || !*a_format) { + recordsyntax = VAL_SUTRS; + } else { + recordsyntax = oid_getvalbyname (a_format); + if (recordsyntax == VAL_NONE) { + logf(LOG_WARN,"unknown record syntax '%s', using SUTRS",a_schema); + recordsyntax = VAL_SUTRS; + } + } + + if (schema != VAL_NONE) { + oident prefschema; + + prefschema.proto = PROTO_Z3950; + prefschema.oclass = CLASS_SCHEMA; + prefschema.value = schema; + + compo.which = Z_RecordComp_complex; + compo.u.complex = (Z_CompSpec *) + odr_malloc(stream, sizeof(*compo.u.complex)); + compo.u.complex->selectAlternativeSyntax = (bool_t *) + odr_malloc(stream, sizeof(bool_t)); + *compo.u.complex->selectAlternativeSyntax = 0; + + compo.u.complex->generic = (Z_Specification *) + odr_malloc(stream, sizeof(*compo.u.complex->generic)); + compo.u.complex->generic->which = Z_Schema_oid; + compo.u.complex->generic->schema.oid = (Odr_oid *) + odr_oiddup(stream, oid_ent_to_oid(&prefschema, oid)); + if (!compo.u.complex->generic->schema.oid) + { + /* OID wasn't a schema! Try record syntax instead. */ + prefschema.oclass = CLASS_RECSYN; + compo.u.complex->generic->schema.oid = (Odr_oid *) + odr_oiddup(stream, oid_ent_to_oid(&prefschema, oid)); + } + if (!elementSetNames) + compo.u.complex->generic->elementSpec = 0; + else + { + compo.u.complex->generic->elementSpec = (Z_ElementSpec *) + odr_malloc(stream, sizeof(Z_ElementSpec)); + compo.u.complex->generic->elementSpec->which = + Z_ElementSpec_elementSetName; + compo.u.complex->generic->elementSpec->u.elementSetName = + elementSetNames->u.generic; + } + compo.u.complex->num_dbSpecific = 0; + compo.u.complex->dbSpecific = 0; + compo.u.complex->num_recordSyntax = 0; + compo.u.complex->recordSyntax = 0; + } + else if (elementSetNames) { + compo.which = Z_RecordComp_simple; + compo.u.simple = elementSetNames; + } + + if (compo.which == -1) { + api_records_retrieve (zh, stream, setname, + NULL, + recordsyntax, + res->noOfRecords, res->records); + } else { + api_records_retrieve (zh, stream, setname, + &compo, + recordsyntax, + res->noOfRecords, res->records); + } + +} + +int zebra_trans_no (ZebraHandle zh) { + return (zh->trans_no); +} + +/* almost the same as zebra_records_retrieve ... but how did it work? + I mean for multiple records ??? CHECK ??? */ +void api_records_retrieve (ZebraHandle zh, ODR stream, + const char *setname, Z_RecordComposition *comp, + oid_value input_format, int num_recs, + ZebraRetrievalRecord *recs) +{ + ZebraPosSet poset; + int i, *pos_array; + + if (!zh->res) + { + zh->errCode = 30; + zh->errString = odr_strdup (stream, setname); + return; + } + + zh->errCode = 0; + + if (zebra_begin_read (zh)) + return; + + pos_array = (int *) xmalloc (num_recs * sizeof(*pos_array)); + for (i = 0; ierrCode = 30; + zh->errString = nmem_strdup (stream->mem, setname); + } + else + { + for (i = 0; ierrCode = 13; + zh->errString = odr_strdup (stream, num_str); + break; + } + + } + zebraPosSetDestroy (zh, poset, num_recs); + } + zebra_end_read (zh); + xfree (pos_array); +} + + +/* --------------------------------------------------------------------------- + Sort - a simplified interface, with optional read locks. +*/ +int sort (ZebraHandle zh, + ODR stream, + const char *sort_spec, + const char *output_setname, + const char **input_setnames + ) +{ + int num_input_setnames = 0; + int sort_status = 0; + Z_SortKeySpecList *sort_sequence = yaz_sort_spec (stream, sort_spec); + if (!sort_sequence) { + logf(LOG_WARN,"invalid sort specs '%s'", sort_spec); + zh->errCode = 207; + return (-1); + } + + /* we can do this, since the typemap code for char** will + put a NULL at the end of list */ + while (input_setnames[num_input_setnames]) num_input_setnames++; + + if (zebra_begin_read (zh)) + return; + + resultSetSort (zh, stream->mem, num_input_setnames, input_setnames, + output_setname, sort_sequence, &sort_status); + + zebra_end_read(zh); + return (sort_status); +}