5 #include <yaz/yaz-util.h>
9 #include <yaz/pquery.h>
11 #include "zebra_perl.h"
12 #include "../recctrl/perlread.h"
13 #include <idzebra/data1.h>
19 yaz_log_init_prefix ("ZebraPerl");
20 yaz_log (YLOG_LOG, "Zebra API initialized");
25 yaz_log (YLOG_LOG, "Zebra API destroyed");
28 /* Logging facilities from yaz */
29 void logMsg (int level, const char *message) {
30 yaz_log(level, "%s", message);
33 /* debug tool for data1... maybe should be moved to data1.
34 perl can't really pass filehandles */
35 void data1_print_tree(data1_handle dh, data1_node *n) {
36 data1_pr_tree(dh, n, stdout);
39 /* ---------------------------------------------------------------------------
41 2 phase retrieval - I didn't manage to return array of blessed references
42 to wrapped structures... it's feasible, but I'll need some time
46 void record_retrieve(RetrievalObj *ro,
54 RetrievalRecordBuf *buf =
55 (RetrievalRecordBuf *) odr_malloc(stream, sizeof(*buf));
57 res->errCode = ro->records[i].errCode;
58 if (ro->records[i].errString) {
59 res->errString = odr_strdup(stream, ro->records[i].errString);
63 res->position = ro->records[i].position;
64 res->base = odr_strdup(stream, ro->records[i].base);
65 res->format = (char *)
66 yaz_z3950_oid_value_to_str(ro->records[i].format, CLASS_RECSYN);
68 res->buf->len = ro->records[i].len;
69 res->buf->buf = ro->records[i].buf;
70 res->score = ro->records[i].score;
71 res->sysno = ro->records[i].sysno;
77 /* most of the code here was copied from yaz-client */
78 void records_retrieve(ZebraHandle zh,
88 static enum oid_value recordsyntax = VAL_SUTRS;
89 static enum oid_value schema = VAL_NONE;
90 static Z_ElementSetNames *elementSetNames = 0;
91 static Z_RecordComposition compo;
92 static Z_ElementSetNames esn;
93 static char what[100];
99 if (from < 1) from = 1;
100 if (from > to) to = from;
101 res->noOfRecords = to - from + 1;
103 res->records = odr_malloc (stream,
104 sizeof(*res->records) * (res->noOfRecords));
106 for (i = 0; i<res->noOfRecords; i++) res->records[i].position = from+i;
108 if (!a_eset || !*a_eset) {
111 strcpy(what, a_eset);
112 esn.which = Z_ElementSetNames_generic;
113 esn.u.generic = what;
114 elementSetNames = &esn;
117 if (!a_schema || !*a_schema) {
120 schema = oid_getvalbyname (a_schema);
121 if (schema == VAL_NONE) {
122 yaz_log(YLOG_WARN,"unknown schema '%s'",a_schema);
127 if (!a_format || !*a_format) {
128 recordsyntax = VAL_SUTRS;
130 recordsyntax = oid_getvalbyname (a_format);
131 if (recordsyntax == VAL_NONE) {
132 yaz_log(YLOG_WARN,"unknown record syntax '%s', using SUTRS",a_schema);
133 recordsyntax = VAL_SUTRS;
137 if (schema != VAL_NONE) {
140 prefschema.proto = PROTO_Z3950;
141 prefschema.oclass = CLASS_SCHEMA;
142 prefschema.value = schema;
144 compo.which = Z_RecordComp_complex;
145 compo.u.complex = (Z_CompSpec *)
146 odr_malloc(stream, sizeof(*compo.u.complex));
147 compo.u.complex->selectAlternativeSyntax = (bool_t *)
148 odr_malloc(stream, sizeof(bool_t));
149 *compo.u.complex->selectAlternativeSyntax = 0;
151 compo.u.complex->generic = (Z_Specification *)
152 odr_malloc(stream, sizeof(*compo.u.complex->generic));
153 compo.u.complex->generic->which = Z_Schema_oid;
154 compo.u.complex->generic->schema.oid = (Odr_oid *)
155 odr_oiddup(stream, oid_ent_to_oid(&prefschema, oid));
156 if (!compo.u.complex->generic->schema.oid)
158 /* OID wasn't a schema! Try record syntax instead. */
159 prefschema.oclass = CLASS_RECSYN;
160 compo.u.complex->generic->schema.oid = (Odr_oid *)
161 odr_oiddup(stream, oid_ent_to_oid(&prefschema, oid));
163 if (!elementSetNames)
164 compo.u.complex->generic->elementSpec = 0;
167 compo.u.complex->generic->elementSpec = (Z_ElementSpec *)
168 odr_malloc(stream, sizeof(Z_ElementSpec));
169 compo.u.complex->generic->elementSpec->which =
170 Z_ElementSpec_elementSetName;
171 compo.u.complex->generic->elementSpec->u.elementSetName =
172 elementSetNames->u.generic;
174 compo.u.complex->num_dbSpecific = 0;
175 compo.u.complex->dbSpecific = 0;
176 compo.u.complex->num_recordSyntax = 0;
177 compo.u.complex->recordSyntax = 0;
179 else if (elementSetNames) {
180 compo.which = Z_RecordComp_simple;
181 compo.u.simple = elementSetNames;
184 if (compo.which == -1) {
185 api_records_retrieve (zh, stream, setname,
188 res->noOfRecords, res->records);
190 api_records_retrieve (zh, stream, setname,
193 res->noOfRecords, res->records);
198 int zebra_cql2pqf (cql_transform_t ct,
199 const char *query, char *res, int len) {
202 const char *addinfo = "";
203 CQL_parser cp = cql_parser_create();
205 if (status = cql_parser_string(cp, query)) {
206 cql_parser_destroy(cp);
210 if (cql_transform_buf(ct, cql_parser_result(cp), res, len)) {
211 status = cql_transform_error(ct, &addinfo);
212 yaz_log (YLOG_WARN,"Transform error %d %s\n", status, addinfo ? addinfo : "");
213 cql_parser_destroy(cp);
217 cql_parser_destroy(cp);
221 void zebra_scan_PQF (ZebraHandle zh,
224 const char *pqf_query)
226 Z_AttributesPlusTerm *zapt;
229 oid_value attributeset;
230 ZebraScanEntry *entries;
234 "scan req: pos:%d, num:%d, partial:%d",
235 so->position, so->num_entries, so->is_partial);
237 zapt = p_query_scan (stream, PROTO_Z3950, &attrsetid, pqf_query);
239 oidname = yaz_z3950oid_to_str (attrsetid, &class);
240 yaz_log (YLOG_DEBUG, "Attributreset: %s", oidname);
241 attributeset = oid_getvalbyname(oidname);
244 yaz_log (YLOG_WARN, "bad query %s\n", pqf_query);
249 so->entries = (scanEntry *)
250 odr_malloc (stream, sizeof(so->entries) * (so->num_entries));
253 zebra_scan (zh, stream, zapt, attributeset,
254 &so->position, &so->num_entries,
255 (ZebraScanEntry **) &so->entries, &so->is_partial);
258 "scan res: pos:%d, num:%d, partial:%d",
259 so->position, so->num_entries, so->is_partial);
262 scanEntry *getScanEntry(ScanObj *so, int pos) {
263 return (&so->entries[pos-1]);
267 void Filter_store_buff (struct perl_context *context, char *buff, size_t len)
275 XPUSHs(context->filterRef);
276 XPUSHs(sv_2mortal(newSVpv(buff, len)));
278 call_method("_store_buff", 0);
286 /* The "file" manipulation function wrappers */
287 int grs_perl_readf(struct perl_context *context, size_t len)
290 char *buf = (char *) xmalloc (len+1);
291 r = (*context->readf)(context->fh, buf, len);
292 if (r > 0) Filter_store_buff (context, buf, r);
297 int grs_perl_readline(struct perl_context *context)
300 char *buf = (char *) xmalloc (4096);
303 while ((r = (*context->readf)(context->fh,p,1)) && (p-buf < 4095)) {
305 if (*(p-1) == 10) break;
310 if (p != buf) Filter_store_buff (context, buf, p - buf);
315 char grs_perl_getc(struct perl_context *context)
319 if ((r = (*context->readf)(context->fh,p,1))) {
326 off_t grs_perl_seekf(struct perl_context *context, off_t offset)
328 return ((*context->seekf)(context->fh, offset));
331 off_t grs_perl_tellf(struct perl_context *context)
333 return ((*context->tellf)(context->fh));
336 void grs_perl_endf(struct perl_context *context, off_t offset)
338 (*context->endf)(context->fh, offset);
341 /* Get pointers from the context. Easyer to wrap this by SWIG */
342 data1_handle *grs_perl_get_dh(struct perl_context *context)
344 return(&context->dh);
347 NMEM *grs_perl_get_mem(struct perl_context *context)
349 return(&context->mem);
352 /* Set the result in the context */
353 void grs_perl_set_res(struct perl_context *context, data1_node *n)