f83037128b4218463fa55394436dce3ecf927082
[idzebra-moved-to-github.git] / index / api_swig.c
1 /* This file is part of the Zebra server.
2    Copyright (C) 1995-2008 Index Data
3
4 Zebra is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
7 version.
8
9 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
18 */
19
20 struct idzebra_swig_service {
21   ZebraService zs;
22   Res res;
23 };
24
25 struct idzebra_swig_session {
26   ZebraHandle zh;
27   Res res;
28 };
29
30 /* == API errors, debug ==================================================== */
31 static Res api_error = 0;
32 const char* api_error_context = 0;
33 void api_add_error(const char *fmt, ...); 
34 void api_clear_error(void); 
35 void free_array(const char **args);
36
37
38 /* == API init, destroy  =================================================== */
39 void idzebra_api_init(void) 
40 {
41   yaz_log_init_prefix("API_SWIG");
42   yaz_log(YLOG_LOG, "IDZebra API initialized");
43 }
44
45 /* == Service start/stop =================================================== */
46
47 IDZebraService idzebra_start (RES_LIST)
48 {
49   IDZebraService srv = xmalloc(sizeof(*srv));
50
51   ARGS_INIT;
52   API_SET_CONTEXT;
53
54   ARGS_PARSE ("configName", 
55               "chdir", 
56               "modulePath", 
57               "profilePath",
58               "register",
59               "shadow",
60               "isam",
61               "keyTmpDir",
62               "setTmpDir",
63               "lockDir");
64   
65   srv->res = func_res;
66   srv->zs = zebra_start_res(res_get(func_res,"configName"), NULL, srv->res);
67
68   func_res = 0; 
69   ARGS_DONE;
70
71   return (srv);
72 }
73
74 IDZEBRA_RES idzebra_stop(IDZebraService srv) 
75 {
76   ZEBRA_RES rv = zebra_stop(srv->zs);
77   res_close (srv->res);
78   xfree (srv);
79   return (rv);
80 }
81
82 /* == Session open/close =================================================== */
83 IDZebraSession idzebra_open (IDZebraService srv, RES_LIST)
84 {
85   IDZebraSession sess = xmalloc(sizeof(*sess));
86
87   ARGS_INIT;
88   API_SET_CONTEXT;
89
90   ARGS_PARSE  ("tempfiles", 
91                "openRW", 
92                "memmax",
93                "encoding",
94                "estimatehits",
95                "staticrank");
96
97   sess->res = func_res;
98   sess->zh = zebra_open(srv->zs, sess->res);
99
100   /* Function resources are kept for session (zh->res->over_res); */
101   func_res = 0; 
102   ARGS_DONE;
103
104   return (sess);
105 }
106
107 IDZEBRA_RES idzebra_close(IDZebraSession sess) 
108 {
109   ZEBRA_RES rv = zebra_close (sess->zh);
110   res_close (sess->res);
111   xfree (sess);
112   return (rv);
113 }
114 /* == Sample function == =================================================== */
115 IDZEBRA_RES idzebra_samplefunc(IDZebraSession sess, RES_LIST)
116 {
117   ARGS_INIT;
118   API_SET_CONTEXT;
119   ARGS_PARSE("strucc");
120   ARGS_PROCESS(ARG_MODE_OPTIONAL,"encoding");
121   ARGS_APPLY;
122
123   res_dump (sess->res,0);
124
125   //  ARGS_REVOKE;
126   {                                                              
127   const char **used;                                             
128   res_remove_over(temp_res);                                     
129   used = (const char **) res_get_array(local, "_used");                          args_use(sess, sess->res, 0, ARG_MODE_FORCE, used);            
130   free_array(used);                                              
131   }                                                              
132   ARGS_DONE;
133   return (ZEBRA_OK);
134
135
136
137 /* 
138 -------------------------------------------------------------------------------
139  Utility functions for argument handling
140 -------------------------------------------------------------------------------
141 */
142 void arg_parse_res (Res r, 
143                     const char **valid_args, 
144                     Res skip,
145                     char *name, char *value)
146 {
147   if ((name) && (value)) {
148       int i = 0;
149       int gotit = 0;
150       while (valid_args[i]) {
151         if (!strcmp(name, valid_args[i])) {
152           res_set(r, name, value);
153           gotit = 1;
154           break;
155         }
156         i++;
157       }
158       if (!gotit)
159         yaz_log (YLOG_DEBUG, "skip: %s=%s",name, value);
160         res_add (skip, name, value);
161   }
162 }
163
164 void args_parse_res (Res r, 
165                      const char **valid_args, 
166                      Res skip,
167                      char **args)
168 {
169   char *argname;
170   char *argvalue;
171   int i = 0;
172   if (args) {
173     while (args[i] && args[i+1]) {
174       argname = args[i++];
175       argvalue = args[i++];
176       arg_parse_res (r, valid_args, skip, argname, argvalue);
177     }
178   }
179 }
180
181 /* == special resource handlers ============================================ */
182
183 void idzebra_res_encoding (ZebraHandle zh, const char *value) 
184 {
185   if (value)
186     zebra_octet_term_encoding(zh, value);
187   else
188     zebra_octet_term_encoding(zh, "ISO-8859-1");
189   
190 }
191
192 void idzebra_res_estimatehits (ZebraHandle zh, const char *value) 
193 {
194   int val = 0;
195   if (value)
196     if (! (sscanf(value, "%d", &val) == 1)) 
197       api_add_error( "Expected integer value for 'estimatehits'");
198
199   zebra_set_approx_limit(zh, val);
200 }
201
202 /*
203 void idzebra_res_staticrank (ZebraHandle zh, const char *value) 
204 {
205   int val = 0;
206   if (value)
207     if (! (sscanf(value, "%d", &val) == 1)) 
208       api_add_error( "Expected integer value for 'estimatehits'");
209   
210   sess->zh->m_staticrank = val;
211 }
212 */
213
214 /* == applying and revoking call-scope resources =========================== */
215
216 void arg_use (ZebraHandle zh,
217               Res r,
218               Res rr,
219               int mode,
220               const char *name)
221 {
222   if (name) {
223     const char *value = res_get(r, name);
224     int gotit = 0;
225
226     /* in FORCE mode resource is used with default value also */
227     if ((value) || (mode & ARG_MODE_FORCE)) {
228
229       /* encoding */
230       if (!strcmp(name,"encoding")) {
231         idzebra_res_encoding(zh, value);
232         gotit = 1;
233       }
234
235       /* estimatehits */
236       else if (!strcmp(name,"estimatehits")) {
237         idzebra_res_estimatehits(zh, value);
238         gotit = 1;
239       }
240
241       /* staticrank */
242       /*
243       else if (!strcmp(name,"staticrank")) {
244         idzebra_res_staticrank(zh, value);
245         gotit = 1;
246       }
247       */
248       
249       /* collects provided arguments in order to revoke them 
250          at the end of the function */
251       if (gotit) {
252         if (! (mode & ARG_MODE_FORCE)) res_add(r, "_used", name);
253         if ( (rr) && (name) && (value) ) res_add(rr, name, value);
254       }
255   } else {
256       /* value missing */
257       if (mode & ARG_MODE_MANDATORY)
258         api_add_error( "Missing mandatory argument '%s'", name);
259     }
260   }
261 }
262
263 void args_use (IDZebraSession sess,
264                Res r,
265                Res rr,
266                int mode,
267                const char **args)
268 {
269   int i = 0;
270   if (args) {
271     while (args[i]) {
272       arg_use (sess->zh, r, rr, mode, args[i++]);
273     }
274   }
275 }
276
277 /* == API errors =========================================================== */
278
279 void api_add_error(const char *fmt, ...) 
280 {
281
282   va_list ap;
283   char buf[4096];  
284   const char *context;
285   va_start(ap, fmt);
286
287 #ifdef WIN32
288   _vsnprintf(buf, sizeof(buf)-1, fmt, ap);
289 #else
290 /* !WIN32 */
291 #if HAVE_VSNPRINTF
292   vsnprintf(buf, sizeof(buf), fmt, ap);
293 #else
294   vsprintf(buf, fmt, ap);
295 #endif
296 #endif
297
298   va_end (ap);
299
300   if (! api_error)
301     api_error = res_open(0,0);
302
303   if (api_error_context)
304     context = api_error_context;
305   else
306     context = "<unknown>";
307       
308   res_add(api_error, context, buf);
309 }
310
311 char **api_errors(void)
312 {
313   static char **res = 0;
314
315   res = res_2_array(api_error);
316   if (!res) {
317     res = xmalloc(sizeof(char *));
318     res[0] = 0 ;
319   }
320   return (&res[0]);
321
322 }
323
324
325 int api_check_error(void)
326 {
327   if (api_error)
328     return (1);
329   else
330     return (0);
331 }
332
333 void api_clear_error(void) 
334 {
335   if (api_error)
336     res_close(api_error);
337   api_error = 0;
338 }
339
340 void free_array(const char **args)
341 {
342   int i = 0;
343   if (args) {
344     while (args[i]) {
345       xfree((char *) args[i]);
346       i++;
347     }
348     xfree (args);
349   }
350 }
351 /*
352  * Local variables:
353  * c-basic-offset: 4
354  * indent-tabs-mode: nil
355  * End:
356  * vim: shiftwidth=4 tabstop=8 expandtab
357  */
358