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