Added ZEBRA_CHECK_HANDLE(zh) which returns ZEBRA_FAIL if handle is
[idzebra-moved-to-github.git] / index / apitest.c
1 /* $Id: apitest.c,v 1.24 2006-03-31 15:58:04 adam Exp $
2    Copyright (C) 1995-2005
3    Index Data ApS
4
5 This file is part of the Zebra server.
6
7 Zebra is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Zebra; see the file LICENSE.zebra.  If not, write to the
19 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.
21 */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25
26 #include <yaz/log.h>
27 #include <yaz/pquery.h>
28 #include <idzebra/api.h>
29
30 /* Small routine to display GRS-1 record variants ... */
31 /* Copied verbatim from yaz/client/client.c */
32 static void display_variant(Z_Variant *v, int level)
33 {
34     int i;
35
36     for (i = 0; i < v->num_triples; i++)
37     {
38         printf("%*sclass=%d,type=%d", level * 4, "", *v->triples[i]->zclass,
39             *v->triples[i]->type);
40         if (v->triples[i]->which == Z_Triple_internationalString)
41             printf(",value=%s\n", v->triples[i]->value.internationalString);
42         else
43             printf("\n");
44     }
45 }
46  
47 /* Small routine to display a GRS-1 record ... */
48 /* Copied verbatim from yaz/client/client.c */
49 static void display_grs1(Z_GenericRecord *r, int level)
50 {
51     int i;
52
53     if (!r)
54         return;
55     for (i = 0; i < r->num_elements; i++)
56     {
57         Z_TaggedElement *t;
58
59         printf("%*s", level * 4, "");
60         t = r->elements[i];
61         printf("(");
62         if (t->tagType)
63             printf("%d,", *t->tagType);
64         else
65             printf("?,");
66         if (t->tagValue->which == Z_StringOrNumeric_numeric)
67             printf("%d) ", *t->tagValue->u.numeric);
68         else
69             printf("%s) ", t->tagValue->u.string);
70         if (t->content->which == Z_ElementData_subtree)
71         {
72             printf("\n");
73             display_grs1(t->content->u.subtree, level+1);
74         }
75         else if (t->content->which == Z_ElementData_string)
76             printf("%s\n", t->content->u.string);
77         else if (t->content->which == Z_ElementData_numeric)
78             printf("%d\n", *t->content->u.numeric);
79         else if (t->content->which == Z_ElementData_oid)
80         {
81             int *ip = t->content->u.oid;
82             oident *oent;
83
84             if ((oent = oid_getentbyoid(t->content->u.oid)))
85                 printf("OID: %s\n", oent->desc);
86             else
87             {
88                 printf("{");
89                 while (ip && *ip >= 0)
90                     printf(" %d", *(ip++));
91                 printf(" }\n");
92             }
93         }
94         else if (t->content->which == Z_ElementData_noDataRequested)
95             printf("[No data requested]\n");
96         else if (t->content->which == Z_ElementData_elementEmpty)
97             printf("[Element empty]\n");
98         else if (t->content->which == Z_ElementData_elementNotThere)
99             printf("[Element not there]\n");
100         else
101             printf("??????\n");
102         if (t->appliedVariant)
103             display_variant(t->appliedVariant, level+1);
104         if (t->metaData && t->metaData->supportedVariants)
105         {
106             int c;
107
108             printf("%*s---- variant list\n", (level+1)*4, "");
109             for (c = 0; c < t->metaData->num_supportedVariants; c++)
110             {
111                 printf("%*svariant #%d\n", (level+1)*4, "", c);
112                 display_variant(t->metaData->supportedVariants[c], level + 2);
113             }
114         }
115     }
116 }
117
118 /* Small test main to illustrate the use of the C api */
119 int main (int argc, char **argv)
120 {
121     /* odr is a handle to memory assocated with RETURNED data from
122        various functions */
123     ODR odr_input, odr_output;
124     
125     /* zs is our Zebra Service - decribes whole server */
126     ZebraService zs;
127
128     /* zh is our Zebra Handle - describes database session */
129     ZebraHandle zh;
130     
131     /* the database we specify in our example */
132     const char *base = "Default";
133     int argno;
134
135     nmem_init ();
136
137     yaz_log_init_file("apitest.log");
138
139     odr_input = odr_createmem (ODR_DECODE);    
140     odr_output = odr_createmem (ODR_ENCODE);    
141     
142     zs = zebra_start ("zebra.cfg");
143     if (!zs)
144     {
145         printf ("zebra_start failed; missing zebra.cfg?\n");
146         exit (1);
147     }
148     /* open Zebra */
149     zh = zebra_open (zs, 0);
150     if (!zh)
151     {
152         printf ("zebras_open failed\n");
153         exit (1);
154     }
155     if (zebra_select_databases (zh, 1, &base) != ZEBRA_OK)
156     {
157         printf ("zebra_select_databases failed\n");
158         exit (1);
159     }
160     /* Each argument to main will be a query */
161     for (argno = 1; argno < argc; argno++)
162     {
163         /* parse the query and generate an RPN structure */
164         Z_RPNQuery *query = p_query_rpn (odr_input, PROTO_Z3950, argv[argno]);
165         char setname[64];
166         int errCode;
167         int i;
168         zint hits;
169         char *errString;
170         ZebraRetrievalRecord *records;
171         int noOfRecordsToFetch;
172
173         /* bad query? */
174         if (!query)
175         {
176             yaz_log (YLOG_WARN, "bad query %s\n", argv[argno]);
177             odr_reset (odr_input);
178             continue;
179         }
180         else
181         {
182             char out_str[100];
183             int r;
184 #if 1
185             r = zebra_string_norm (zh, 'w',
186                                    argv[argno], strlen(argv[argno]),
187                                    out_str, sizeof(out_str));
188             if (r >= 0)
189             {
190                 printf ("norm: '%s'\n", out_str);
191             }
192             else
193             {
194                 printf ("norm fail: %d\n", r);
195             }
196 #endif
197
198         }
199         /* result set name will be called 1,2, etc */
200         sprintf (setname, "%d", argno);
201
202         /* fire up the search */
203         zebra_search_RPN (zh, odr_input, query, setname, &hits);
204         
205         /* status ... */
206         zebra_result (zh, &errCode, &errString);
207         
208         /* error? */
209         if (errCode)
210         {
211             printf ("Zebra Search Error %d %s\n",
212                     errCode, errString);
213             continue;
214         }
215         /* ok ... */
216         printf ("Zebra Search gave " ZINT_FORMAT " hits\n", hits);
217         
218         /* Deterimine number of records to fetch ... */
219         if (hits > 10)
220             noOfRecordsToFetch = 10;
221         else
222             noOfRecordsToFetch = hits;
223
224         /* reset our memory - we've finished dealing with search */
225         odr_reset (odr_input);
226         odr_reset (odr_output);
227
228         /* prepare to fetch ... */
229         records = odr_malloc (odr_input, sizeof(*records) * noOfRecordsToFetch);
230         /* specify position of each record to fetch */
231         /* first one is numbered 1 and NOT 0 */
232         for (i = 0; i<noOfRecordsToFetch; i++)
233             records[i].position = i+1;
234         /* fetch them and request for GRS-1 records */
235         zebra_records_retrieve (zh, odr_input, setname, NULL, VAL_SUTRS,
236                                 noOfRecordsToFetch, records);
237
238         /* status ... */
239
240         zebra_result (zh, &errCode, &errString);
241
242         /* error ? */
243         if (errCode)
244         {
245             printf ("Zebra Search Error %d %s\n",
246                     errCode, errString);
247         }
248         else
249         {
250             /* inspect each record in result */
251             for (i = 0; i<noOfRecordsToFetch; i++)
252             {
253                 printf ("Record %d\n", i+1);
254                 /* error when fetching this record? */
255                 if (records[i].errCode)
256                 {
257                     printf ("  Error %d\n", records[i].errCode);
258                     continue;
259                 }
260                 /* GRS-1 record ? */
261                 if (records[i].format == VAL_GRS1)
262                 {
263                     Z_GenericRecord *grs_record =
264                         (Z_GenericRecord *) records[i].buf;
265                     printf ("  GRS-1\n");
266                     display_grs1(grs_record, 0);
267                 }
268                 else if (records[i].format == VAL_SUTRS)
269                 {
270                     printf ("  SUTRS\n");
271                     printf ("%.*s", records[i].len, records[i].buf);
272                 }
273                 /* some other record we don't handle yet... */
274                 else
275                 {
276                     printf ("  Other record (ignored)\n");
277                 }
278             }
279         }
280         /* reset our memory - we've finished dealing with present */
281         odr_reset (odr_input); 
282         odr_reset (odr_output);
283     }
284     odr_destroy (odr_input);
285     odr_destroy (odr_output);
286     zebra_close (zh);
287     zebra_stop (zs);
288     return 0;
289 }