Zebra api extension tuned for SWIG
[idzebra-moved-to-github.git] / index / api_swig.c
1 #include <idzebra/api_swig.h>
2 #include <idzebra/res.h>
3 #include <idzebra/api.h>
4 #include <stdarg.h>
5 #include "index.h"
6
7 #define DEFAULT_APPROX_LIMIT 2000000000
8
9 /* == API errors, debug ==================================================== */
10 static Res api_error = 0;
11 const char* api_error_context = 0;
12 void api_add_error(const char *fmt, ...); 
13 void api_clear_error(void);
14 void free_array(const char **args);
15 ZebraHandle zebra_get_handle (ZebraService zs);
16
17
18 /* == API init, destroy  =================================================== */
19 void idzebra_api_init(void) 
20 {
21   yaz_log_init_prefix("API_SWIG");
22   yaz_log(YLOG_LOG, "IDZebra API initialized");
23 }
24
25 /* == Service start/stop =================================================== */
26
27 ZebraService idzebra_start(RES_LIST) 
28 {
29   ZebraService zs = 0;
30
31   ARGS_INIT;
32   API_SET_CONTEXT;
33
34   ARGS_PARSE ("configName", 
35               "chdir", 
36               "modulePath", 
37               "profilePath",
38               "register",
39               "shadow",
40               "isam",
41               "keyTmpDir",
42               "setTmpDir",
43               "lockDir");
44   
45   zs = zebra_start_res(res_get(func_res,"configName"), NULL, func_res);
46
47   /* Function resources are kept for service (zs->global_res); */
48   func_res = 0; 
49   ARGS_DONE;
50
51   return (zs);
52 }
53
54 IDZEBRA_RES idzebra_stop(ZebraService zs) 
55 {
56   /* Global res have an over part here */
57   res_close_over(zs->global_res);
58   return (zebra_stop(zs));
59 }
60
61 /* == Session open/close =================================================== */
62 ZebraHandle idzebra_open (ZebraService zs, RES_LIST)
63 {
64
65   ZebraHandle zh;
66
67   ARGS_INIT;
68   API_SET_CONTEXT;
69
70   ARGS_PARSE  ("tempfiles", 
71                "openRW", 
72                "memmax",
73                "encoding",
74                "estimatehits",
75                "staticrank");
76
77   zh = zebra_open(zs, func_res);
78
79   /* Function resources are kept for session (zh->res->over_res); */
80   func_res = 0; 
81   ARGS_DONE;
82
83   yaz_log (YLOG_DEBUG, "zebra_open zs=%p returns %p", zs, zh);
84
85   return (zh);
86 }
87
88 IDZEBRA_RES idzebra_close(ZebraHandle zh) 
89 {
90   res_close_over(zh->session_res);
91   return (zebra_close(zh));
92 }
93 /* == Sample function == =================================================== */
94 IDZEBRA_RES idzebra_samplefunc(ZebraHandle zh, RES_LIST)
95 {
96   ARGS_INIT;
97   API_SET_CONTEXT;
98   ARGS_PARSE("strucc");
99   ARGS_PROCESS(ARG_MODE_OPTIONAL,"encoding");
100   ARGS_APPLY;
101
102   yaz_log (YLOG_DEBUG, "Got strucc:%s\n",res_get(zh->res,"strucc"));
103   res_dump (zh->res,0);
104
105   ARGS_REVOKE;
106   ARGS_DONE;
107   return (ZEBRA_OK);
108
109
110
111 /* 
112 -------------------------------------------------------------------------------
113  Utility functions for argument handling
114 -------------------------------------------------------------------------------
115 */
116 void arg_parse_res (Res r, 
117                     const char **valid_args, 
118                     Res skip,
119                     char *name, char *value)
120 {
121   if ((name) && (value)) {
122       int i = 0;
123       int gotit = 0;
124       while (valid_args[i]) {
125         if (!strcmp(name, valid_args[i])) {
126           res_set(r, name, value);
127           gotit = 1;
128           break;
129         }
130         i++;
131       }
132       if (!gotit)
133         yaz_log (YLOG_DEBUG, "skip: %s=%s",name, value);
134         res_add (skip, name, value);
135   }
136 }
137
138 void args_parse_res (Res r, 
139                      const char **valid_args, 
140                      Res skip,
141                      char **args)
142 {
143   char *argname;
144   char *argvalue;
145   int i = 0;
146   if (args) {
147     while (args[i] && args[i+1]) {
148       argname = args[i++];
149       argvalue = args[i++];
150       arg_parse_res (r, valid_args, skip, argname, argvalue);
151     }
152   }
153 }
154
155 /* == special resource handlers ============================================ */
156
157 void idzebra_res_encoding (ZebraHandle zh, const char *value) 
158 {
159   if (value)
160     zebra_octet_term_encoding(zh, value);
161   else
162     zebra_octet_term_encoding(zh, "ISO-8859-1");
163   
164 }
165
166 void idzebra_res_estimatehits (ZebraHandle zh, const char *value) 
167 {
168   int val = 0;
169   if (value)
170     if (! (sscanf(value, "%d", &val) == 1)) 
171       api_add_error( "Expected integer value for 'estimatehits'");
172
173   zebra_set_approx_limit(zh, val);
174 }
175
176 void idzebra_res_staticrank (ZebraHandle zh, const char *value) 
177 {
178   int val = 0;
179   if (value)
180     if (! (sscanf(value, "%d", &val) == 1)) 
181       api_add_error( "Expected integer value for 'estimatehits'");
182   
183   zh->m_staticrank = val;
184 }
185
186 /* == applying and revoking call-scope resources =========================== */
187
188 void arg_use (ZebraHandle zh,
189               Res r,
190               Res rr,
191               int mode,
192               const char *name)
193 {
194   if (name) {
195     const char *value = res_get(r, name);
196     int gotit = 0;
197
198     /* in FORCE mode resource is used with default value also */
199     if ((value) || (mode & ARG_MODE_FORCE)) {
200
201       /* encoding */
202       if (!strcmp(name,"encoding")) {
203         idzebra_res_encoding(zh, value);
204         gotit = 1;
205       }
206
207       /* estimatehits */
208       else if (!strcmp(name,"estimatehits")) {
209         idzebra_res_estimatehits(zh, value);
210         gotit = 1;
211       }
212
213       /* staticrank */
214       else if (!strcmp(name,"staticrank")) {
215         idzebra_res_staticrank(zh, value);
216         gotit = 1;
217       }
218       
219       /* collects provided arguments in order to revoke them 
220          at the end of the function */
221       if (gotit) {
222         if (! (mode & ARG_MODE_FORCE)) res_add(r, "_used", name);
223         if ( (rr) && (name) && (value) ) res_add(rr, name, value);
224       }
225   } else {
226       /* value missing */
227       if (mode & ARG_MODE_MANDATORY)
228         api_add_error( "Missing mandatory argument '%s'", name);
229     }
230   }
231 }
232
233 void args_use (ZebraHandle zh,
234                Res r,
235                Res rr,
236                int mode,
237                const char **args)
238 {
239   int i = 0;
240   if (args) {
241     while (args[i]) {
242       arg_use (zh, r, rr, mode, args[i++]);
243     }
244   }
245 }
246
247 /* == API errors =========================================================== */
248
249 void api_add_error(const char *fmt, ...) 
250 {
251
252   va_list ap;
253   char buf[4096];  
254   const char *context;
255   va_start(ap, fmt);
256
257 #ifdef WIN32
258   _vsnprintf(buf, sizeof(buf)-1, fmt, ap);
259 #else
260 /* !WIN32 */
261 #if HAVE_VSNPRINTF
262   vsnprintf(buf, sizeof(buf), fmt, ap);
263 #else
264   vsprintf(buf, fmt, ap);
265 #endif
266 #endif
267
268   va_end (ap);
269
270   if (! api_error)
271     api_error = res_open(0,0);
272
273   if (api_error_context)
274     context = api_error_context;
275   else
276     context = "<unknown>";
277       
278   res_add(api_error, context, buf);
279 }
280
281 char **api_errors(void)
282 {
283   static char **res = 0;
284
285   res = res_2_array(api_error);
286   if (!res) {
287     res = xmalloc(sizeof(char *));
288     res[0] = 0 ;
289   }
290   return (&res[0]);
291
292 }
293
294
295 int api_check_error(void)
296 {
297   if (api_error)
298     return (1);
299   else
300     return (0);
301 }
302
303 void api_clear_error(void) 
304 {
305   if (api_error)
306     res_close(api_error);
307   api_error = 0;
308 }
309
310 void free_array(const char **args)
311 {
312   int i = 0;
313   if (args) {
314     while (args[i]) {
315       xfree((char *) args[i]);
316       i++;
317     }
318     xfree (args);
319   }
320 }