8f4289601e4f804fe6f6ba53595dfc498164ea2a
[idzebra-moved-to-github.git] / perl / zebra_perl.c
1 #if 0
2 #include "zebraapi.h"
3 #endif
4
5 #include "EXTERN.h"
6 #include "perl.h"
7 #include "XSUB.h"
8
9 #include <yaz/yaz-util.h>
10 #include <yaz/proto.h>
11 #include <yaz/log.h>
12 #include <yaz/cql.h>
13 #include <yaz/pquery.h>
14
15 #include "zebra_perl.h"
16 #include <data1.h>
17
18 NMEM handles;
19
20 void init (void) {
21   nmem_init ();
22   yaz_log_init_prefix ("ZebraPerl");
23   yaz_log (LOG_DEBUG, "Zebra API initialized");
24 }
25
26 void DESTROY (void) {
27   nmem_exit ();
28   yaz_log (LOG_DEBUG, "Zebra API destroyed");
29 }   
30
31 /* Logging facilities from yaz */
32 void logMsg (int level, const char *message) {
33   logf(level, "%s", message);
34 }
35
36 /* debug tool for data1... maybe should be moved to data1. 
37    perl can't really pass filehandles */
38 void data1_print_tree(data1_handle dh, data1_node *n) {
39   data1_pr_tree(dh, n, stdout);
40 }
41
42 /* ---------------------------------------------------------------------------
43   Record retrieval 
44   2 phase retrieval - I didn't manage to return array of blessed references
45   to wrapped structures... it's feasible, but I'll need some time 
46   / pop - 2002-11-17
47 */
48
49 void record_retrieve(RetrievalObj *ro,
50                      ODR stream,
51                      RetrievalRecord *res,
52                      int pos) 
53 {
54   int i = pos - 1;
55
56
57   RetrievalRecordBuf *buf = 
58     (RetrievalRecordBuf *) odr_malloc(stream, sizeof(*buf));  
59
60   res->errCode    = ro->records[i].errCode;
61   if (ro->records[i].errString) {
62     res->errString  = odr_strdup(stream, ro->records[i].errString);
63   } else {
64     res->errString = "";
65   }
66   res->position   = ro->records[i].position;
67   res->base       = odr_strdup(stream, ro->records[i].base);
68   res->format     = (char *) 
69     yaz_z3950_oid_value_to_str(ro->records[i].format, CLASS_RECSYN); 
70   res->buf        = buf;
71   res->buf->len   = ro->records[i].len;
72   res->buf->buf   = ro->records[i].buf;
73   res->score      = ro->records[i].score;
74   res->sysno      = ro->records[i].sysno;
75
76 }
77
78
79
80 /* most of the code here was copied from yaz-client */
81 void records_retrieve(ZebraHandle zh,
82                       ODR stream,
83                       const char *setname,
84                       const char *a_eset, 
85                       const char *a_schema,
86                       const char *a_format,
87                       int from,
88                       int to,
89                       RetrievalObj *res) 
90 {
91   static enum oid_value recordsyntax = VAL_SUTRS;
92   static enum oid_value schema = VAL_NONE;
93   static Z_ElementSetNames *elementSetNames = 0; 
94   static Z_RecordComposition compo;
95   static Z_ElementSetNames esn;
96   static char what[100];
97   int i;
98   int oid[OID_SIZE];
99
100   compo.which = -1;
101
102   if (from < 1) from = 1;
103   if (from > to) to = from;
104   res->noOfRecords = to - from + 1;
105
106   res->records = odr_malloc (stream, 
107                              sizeof(*res->records) * (res->noOfRecords));  
108
109   for (i = 0; i<res->noOfRecords; i++) res->records[i].position = from+i;
110
111   if (!a_eset || !*a_eset) {
112     elementSetNames = 0;
113   } else {
114     strcpy(what, a_eset);
115     esn.which = Z_ElementSetNames_generic;
116     esn.u.generic = what;
117     elementSetNames = &esn;
118   }
119
120   if (!a_schema || !*a_schema) {
121     schema = VAL_NONE;
122   } else {
123     schema = oid_getvalbyname (a_schema);
124     if (schema == VAL_NONE) {
125       logf(LOG_WARN,"unknown schema '%s'",a_schema);
126     }
127   }
128
129   
130   if (!a_format || !*a_format) {
131     recordsyntax = VAL_SUTRS;
132   } else {
133     recordsyntax = oid_getvalbyname (a_format);
134     if (recordsyntax == VAL_NONE) {
135       logf(LOG_WARN,"unknown record syntax '%s', using SUTRS",a_schema);
136       recordsyntax = VAL_SUTRS;
137     }
138   }
139
140   if (schema != VAL_NONE) {
141     oident prefschema;
142
143     prefschema.proto = PROTO_Z3950;
144     prefschema.oclass = CLASS_SCHEMA;
145     prefschema.value = schema;
146     
147     compo.which = Z_RecordComp_complex;
148     compo.u.complex = (Z_CompSpec *)
149       odr_malloc(stream, sizeof(*compo.u.complex));
150     compo.u.complex->selectAlternativeSyntax = (bool_t *) 
151       odr_malloc(stream, sizeof(bool_t));
152     *compo.u.complex->selectAlternativeSyntax = 0;
153     
154     compo.u.complex->generic = (Z_Specification *)
155       odr_malloc(stream, sizeof(*compo.u.complex->generic));
156     compo.u.complex->generic->which = Z_Schema_oid;
157     compo.u.complex->generic->schema.oid = (Odr_oid *)
158       odr_oiddup(stream, oid_ent_to_oid(&prefschema, oid));
159     if (!compo.u.complex->generic->schema.oid)
160       {
161         /* OID wasn't a schema! Try record syntax instead. */
162         prefschema.oclass = CLASS_RECSYN;
163         compo.u.complex->generic->schema.oid = (Odr_oid *)
164           odr_oiddup(stream, oid_ent_to_oid(&prefschema, oid));
165       }
166     if (!elementSetNames)
167       compo.u.complex->generic->elementSpec = 0;
168     else
169       {
170         compo.u.complex->generic->elementSpec = (Z_ElementSpec *)
171           odr_malloc(stream, sizeof(Z_ElementSpec));
172         compo.u.complex->generic->elementSpec->which =
173           Z_ElementSpec_elementSetName;
174         compo.u.complex->generic->elementSpec->u.elementSetName =
175           elementSetNames->u.generic;
176       }
177     compo.u.complex->num_dbSpecific = 0;
178     compo.u.complex->dbSpecific = 0;
179     compo.u.complex->num_recordSyntax = 0;
180     compo.u.complex->recordSyntax = 0;
181   } 
182   else if (elementSetNames) {
183     compo.which = Z_RecordComp_simple;
184     compo.u.simple = elementSetNames;
185   }
186
187   if (compo.which == -1) {
188     api_records_retrieve (zh, stream, setname, 
189                             NULL, 
190                             recordsyntax,
191                             res->noOfRecords, res->records);
192   } else {
193     api_records_retrieve (zh, stream, setname, 
194                             &compo,
195                             recordsyntax,
196                             res->noOfRecords, res->records);
197   }
198
199 }
200  
201 int zebra_cql2pqf (cql_transform_t ct, 
202                    const char *query, char *res, int len) {
203   
204   int status;
205   const char *addinfo = "";
206   CQL_parser cp = cql_parser_create();
207
208   if (status = cql_parser_string(cp, query)) {
209     cql_parser_destroy(cp);
210     return (status);
211   }
212
213   if (cql_transform_buf(ct, cql_parser_result(cp), res, len)) {
214     status = cql_transform_error(ct, &addinfo);
215     logf (LOG_WARN,"Transform error %d %s\n", status, addinfo ? addinfo : "");
216     cql_parser_destroy(cp);
217     return (status);
218   }
219
220   cql_parser_destroy(cp);
221   return (0);
222 }
223
224 void zebra_scan_PQF (ZebraHandle zh,
225                      ScanObj *so,
226                      ODR stream,
227                      const char *pqf_query)
228 {
229   Z_AttributesPlusTerm *zapt;
230   Odr_oid *attrsetid;
231   const char* oidname;
232   oid_value attributeset;
233   ZebraScanEntry *entries;
234   int i, class;
235
236   logf(LOG_DEBUG,  
237        "scan req: pos:%d, num:%d, partial:%d", 
238        so->position, so->num_entries, so->is_partial);
239
240   zapt = p_query_scan (stream, PROTO_Z3950, &attrsetid, pqf_query);
241
242   oidname = yaz_z3950oid_to_str (attrsetid, &class); 
243   logf (LOG_DEBUG, "Attributreset: %s", oidname);
244   attributeset = oid_getvalbyname(oidname);
245
246   if (!zapt) {
247     logf (LOG_WARN, "bad query %s\n", pqf_query);
248     odr_reset (stream);
249     return;
250   }
251
252   so->entries = (scanEntry *)
253     odr_malloc (stream, sizeof(so->entries) * (so->num_entries));
254
255
256   zebra_scan (zh, stream, zapt, attributeset, 
257               &so->position, &so->num_entries, 
258               (ZebraScanEntry **) &so->entries, &so->is_partial);
259
260   logf(LOG_DEBUG, 
261        "scan res: pos:%d, num:%d, partial:%d", 
262        so->position, so->num_entries, so->is_partial);
263 }
264
265 scanEntry *getScanEntry(ScanObj *so, int pos) {
266   return (&so->entries[pos-1]);
267 }
268