OSDN Git Service

Initial commit of senna-1.1.2-fast.
[ludiafuncs/senna-1.1.2-fast.git] / bindings / python / context / sennactx.c
1 /* Copyright(C) 2007 Brazil
2
3   This library is free software; you can redistribute it and/or
4   modify it under the terms of the GNU Lesser General Public
5   License as published by the Free Software Foundation; either
6   version 2.1 of the License, or (at your option) any later version.
7
8   This library is distributed in the hope that it will be useful,
9   but WITHOUT ANY WARRANTY; without even the implied warranty of
10   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11   Lesser General Public License for more details.
12
13   You should have received a copy of the GNU Lesser General Public
14   License along with this library; if not, write to the Free Software
15   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16 */
17 #include <Python.h>
18 #include <senna/senna.h>
19
20 /* TODO: use exception */
21
22 typedef struct {
23   PyObject_HEAD
24   sen_db *db;
25 } sennactx_DbObject;
26
27 typedef struct {
28   PyObject_HEAD
29   sen_ctx *ctx;
30 } sennactx_ContextObject;
31
32 static PyTypeObject sennactx_DbType;
33 static PyTypeObject sennactx_ContextType;
34
35 /* Object methods */
36
37 static PyObject *
38 sennactx_DbObject_new(PyTypeObject *type, PyObject *args, PyObject *keywds)
39 {
40   sennactx_DbObject *self;
41   if ((self = (sennactx_DbObject *)type->tp_alloc(type, 0))) {
42     self->db = NULL;
43   }
44   return (PyObject *)self;
45 }
46
47 static void
48 sennactx_DbObject_dealloc(sennactx_DbObject *self)
49 {
50   if (self->db) {
51     Py_BEGIN_ALLOW_THREADS
52     sen_db_close(self->db);
53     Py_END_ALLOW_THREADS
54   }
55   self->ob_type->tp_free(self);
56 }
57
58 static PyObject *
59 sennactx_ContextObject_new(PyTypeObject *type, PyObject *args, PyObject *keywds)
60 {
61   sennactx_ContextObject *self;
62   if ((self = (sennactx_ContextObject *)type->tp_alloc(type, 0))) {
63     self->ctx = NULL;
64   }
65   return (PyObject *)self;
66 }
67
68 static void
69 sennactx_ContextObject_dealloc(sennactx_ContextObject *self)
70 {
71   if (self->ctx) {
72     Py_BEGIN_ALLOW_THREADS
73     sen_ctx_close(self->ctx);
74     Py_END_ALLOW_THREADS
75   }
76   self->ob_type->tp_free(self);
77 }
78
79 /* Class methods */
80
81 static PyObject *
82 sennactx_DbClass_create(PyTypeObject *type, PyObject *args, PyObject *keywds)
83 {
84   int flags, enc;
85   const char *path;
86   sennactx_DbObject *self;
87   static char *kwlist[] = {"path", "flags", "encodings", NULL};
88
89   if (!PyArg_ParseTupleAndKeywords(args, keywds, "sii", kwlist,
90                                    &path, &flags, &enc)) {
91     return NULL;
92   }
93   if ((self = (sennactx_DbObject *)sennactx_DbObject_new(type, NULL, NULL))) {
94     Py_BEGIN_ALLOW_THREADS
95     self->db = sen_db_create(path, flags, enc);
96     Py_END_ALLOW_THREADS
97     if (self->db) {
98       return (PyObject *)self;
99     }
100     sennactx_DbObject_dealloc(self);
101   }
102   return NULL;
103 }
104
105 static PyObject *
106 sennactx_DbClass_open(PyTypeObject *type, PyObject *args, PyObject *keywds)
107 {
108   const char *path;
109   sennactx_DbObject *self;
110   static char *kwlist[] = {"path", NULL};
111
112   if (!PyArg_ParseTupleAndKeywords(args, keywds, "s", kwlist,
113                                    &path)) {
114     return NULL;
115   }
116   if ((self = (sennactx_DbObject *)sennactx_DbObject_new(type, NULL, NULL))) {
117     Py_BEGIN_ALLOW_THREADS
118     self->db = sen_db_open(path);
119     Py_END_ALLOW_THREADS
120     if (self->db) {
121       return (PyObject *)self;
122     }
123     sennactx_DbObject_dealloc(self);
124   }
125   return NULL;
126 }
127
128 static PyObject *
129 sennactx_ContextClass_connect(PyTypeObject *type, PyObject *args, PyObject *keywds)
130 {
131   int port, flags;
132   const char *host;
133   sennactx_ContextObject *self;
134   static char *kwlist[] = {"host", "port", "flags", NULL};
135
136   if (!PyArg_ParseTupleAndKeywords(args, keywds, "sii", kwlist,
137                                    &host, &port, &flags)) {
138     return NULL;
139   }
140   if ((self = (sennactx_ContextObject *)sennactx_ContextObject_new(type, NULL, NULL))) {
141     Py_BEGIN_ALLOW_THREADS
142     self->ctx = sen_ctx_connect(host, port, flags);
143     Py_END_ALLOW_THREADS
144     if (self->ctx) {
145       return (PyObject *)self;
146     }
147     sennactx_ContextObject_dealloc(self);
148   }
149   return NULL;
150 }
151
152 /* instance methods */
153
154 static PyObject *
155 sennactx_Db_close(sennactx_DbObject *self)
156 {
157   sen_rc rc;
158
159   if (!self->db) { return NULL; }
160   Py_BEGIN_ALLOW_THREADS
161   rc = sen_db_close(self->db);
162   Py_END_ALLOW_THREADS
163   if (!rc) {
164     self->db = NULL;
165   }
166   return Py_BuildValue("i", rc);
167 }
168
169 static PyObject *
170 sennactx_Db_ctx_open(sennactx_DbObject *self, PyObject *args, PyObject *keywds)
171 {
172   int flags;
173   sennactx_ContextObject *ctx;
174   static char *kwlist[] = {"flags", NULL};
175
176   if (!PyArg_ParseTupleAndKeywords(args, keywds, "i", kwlist,
177                                    &flags)) {
178     return NULL;
179   }
180   if ((ctx = (sennactx_ContextObject *)sennactx_ContextObject_new(
181                &sennactx_ContextType, NULL, NULL))) {
182     Py_BEGIN_ALLOW_THREADS
183     ctx->ctx = sen_ctx_open(self->db, flags);
184     Py_END_ALLOW_THREADS
185     if (ctx->ctx) {
186       return (PyObject *)ctx;
187     }
188     sennactx_ContextObject_dealloc(ctx);
189   }
190   return NULL;
191 }
192
193 static PyObject *
194 sennactx_Context_load(sennactx_ContextObject *self, PyObject *args, PyObject *keywds)
195 {
196   sen_rc rc;
197   const char *path;
198   static char *kwlist[] = {"path", NULL};
199
200   if (!PyArg_ParseTupleAndKeywords(args, keywds, "s", kwlist,
201                                    &path)) {
202     return NULL;
203   }
204   if (!self->ctx) { return NULL; }
205   Py_BEGIN_ALLOW_THREADS
206   rc = sen_ctx_load(self->ctx, path);
207   Py_END_ALLOW_THREADS
208   return Py_BuildValue("i", rc);
209 }
210
211 static PyObject *
212 sennactx_Context_send(sennactx_ContextObject *self, PyObject *args, PyObject *keywds)
213 {
214   sen_rc rc;
215   char *str;
216   int str_len, flags;
217   static char *kwlist[] = {"str", "flags", NULL};
218
219   if (!PyArg_ParseTupleAndKeywords(args, keywds, "s#i", kwlist,
220                                    &str,
221                                    &str_len,
222                                    &flags)) {
223     return NULL;
224   }
225   if (!self->ctx) { return NULL; }
226   Py_BEGIN_ALLOW_THREADS
227   rc = sen_ctx_send(self->ctx, str, str_len, flags);
228   Py_END_ALLOW_THREADS
229   return Py_BuildValue("i", rc);
230 }
231
232 static PyObject *
233 sennactx_Context_recv(sennactx_ContextObject *self)
234 {
235   sen_rc rc;
236   int flags;
237   char *str;
238   unsigned int str_len;
239
240   if (!self->ctx) { return NULL; }
241   Py_BEGIN_ALLOW_THREADS
242   rc = sen_ctx_recv(self->ctx, &str, &str_len, &flags);
243   Py_END_ALLOW_THREADS
244   return Py_BuildValue("(is#i)", rc, str, str_len, flags);
245 }
246
247 static PyObject *
248 sennactx_Context_close(sennactx_ContextObject *self)
249 {
250   sen_rc rc;
251
252   if (!self->ctx) { return NULL; }
253   Py_BEGIN_ALLOW_THREADS
254   rc = sen_ctx_close(self->ctx);
255   Py_END_ALLOW_THREADS
256   if (!rc) {
257     self->ctx = NULL;
258   }
259   return Py_BuildValue("i", rc);
260 }
261
262 static PyObject *
263 sennactx_Context_info_get(sennactx_ContextObject *self)
264 {
265   sen_rc rc;
266   sen_ctx_info info;
267
268   if (!self->ctx) { return NULL; }
269   rc = sen_ctx_info_get(self->ctx, &info);
270   /* TODO: handling unsigned int properlly */
271   /* TODO: get outbuf */
272   return Py_BuildValue("{s:i,s:i,s:i}",
273                        "rc", rc,
274                        "com_status", info.com_status,
275                        "com_info", info.com_info
276                        /* "outbuf", info.outbuf */
277                       );
278 }
279
280 /* methods of classes */
281
282 static PyMethodDef sennactx_Db_methods[] = {
283   {"create", (PyCFunction)sennactx_DbClass_create,
284    METH_VARARGS | METH_KEYWORDS | METH_CLASS,
285    "Create a Senna DB and Open an instance of it."},
286   {"open", (PyCFunction)sennactx_DbClass_open,
287    METH_VARARGS | METH_KEYWORDS | METH_CLASS,
288    "Open a Senna DB instance."},
289   {"close", (PyCFunction)sennactx_Db_close,
290    METH_NOARGS,
291    "Release Senna DB instance."},
292   {"ctx_open", (PyCFunction)sennactx_Db_ctx_open,
293    METH_VARARGS | METH_KEYWORDS,
294    "Open a local senna context."},
295   {NULL, NULL, 0, NULL}
296 };
297
298 static PyMethodDef sennactx_Context_methods[] = {
299 /*  {"open", (PyCFunction)sennactx_ContextClass_open,
300    METH_VARARGS | METH_KEYWORDS | METH_CLASS,
301    "Create a local Senna context."}, */
302   {"connect", (PyCFunction)sennactx_ContextClass_connect,
303    METH_VARARGS | METH_KEYWORDS | METH_CLASS,
304    "Create a remote Senna context."},
305   {"load", (PyCFunction)sennactx_Context_load,
306    METH_VARARGS | METH_KEYWORDS,
307    "Load a file into context."},
308   {"send", (PyCFunction)sennactx_Context_send,
309    METH_VARARGS | METH_KEYWORDS,
310    "Send message to context."},
311   {"recv", (PyCFunction)sennactx_Context_recv,
312    METH_NOARGS,
313    "Receive message from context."},
314   {"close", (PyCFunction)sennactx_Context_close,
315    METH_NOARGS,
316    "Release Senna context."},
317   {"info_get", (PyCFunction)sennactx_Context_info_get,
318    METH_NOARGS,
319    "Get context information."},
320   {NULL, NULL, 0, NULL}
321 };
322
323 static PyMethodDef module_methods[] = {
324   {NULL, NULL, 0, NULL}
325 };
326
327 /* type objects */
328
329 static PyTypeObject sennactx_DbType = {
330   PyObject_HEAD_INIT(NULL)
331   0,                                           /* ob_size */
332   "sennactx.Db",                               /* tp_name */
333   sizeof(sennactx_DbObject),                   /* tp_basicsize */
334   0,                                           /* tp_itemsize */
335   (destructor)sennactx_DbObject_dealloc,       /* tp_dealloc */
336   0,                                           /* tp_print */
337   0,                                           /* tp_getattr */
338   0,                                           /* tp_setattr */
339   0,                                           /* tp_compare */
340   0,                                           /* tp_repr */
341   0,                                           /* tp_as_number */
342   0,                                           /* tp_as_sequence */
343   0,                                           /* tp_as_mapping */
344   0,                                           /* tp_hash  */
345   0,                                           /* tp_call */
346   0,                                           /* tp_str */
347   0,                                           /* tp_getattro */
348   0,                                           /* tp_setattro */
349   0,                                           /* tp_as_buffer */
350   Py_TPFLAGS_DEFAULT,                          /* tp_flags */
351   "Senna Db objects",                          /* tp_doc */
352   0,                                           /* tp_traverse */
353   0,                                           /* tp_clear */
354   0,                                           /* tp_richcompare */
355   0,                                           /* tp_weaklistoffset */
356   0,                                           /* tp_iter */
357   0,                                           /* tp_iternext */
358   sennactx_Db_methods,                         /* tp_methods */
359   0,                                           /* tp_members */
360   0,                                           /* tp_getset */
361   0,                                           /* tp_base */
362   0,                                           /* tp_dict */
363   0,                                           /* tp_descr_get */
364   0,                                           /* tp_descr_set */
365   0,                                           /* tp_dictoffset */
366   0,                                           /* tp_init */
367   0,                                           /* tp_alloc */
368   sennactx_DbObject_new,                       /* tp_new */
369 };
370
371 static PyTypeObject sennactx_ContextType = {
372   PyObject_HEAD_INIT(NULL)
373   0,                                           /* ob_size */
374   "sennactx.Context",                          /* tp_name */
375   sizeof(sennactx_ContextObject),              /* tp_basicsize */
376   0,                                           /* tp_itemsize */
377   (destructor)sennactx_ContextObject_dealloc,  /* tp_dealloc */
378   0,                                           /* tp_print */
379   0,                                           /* tp_getattr */
380   0,                                           /* tp_setattr */
381   0,                                           /* tp_compare */
382   0,                                           /* tp_repr */
383   0,                                           /* tp_as_number */
384   0,                                           /* tp_as_sequence */
385   0,                                           /* tp_as_mapping */
386   0,                                           /* tp_hash  */
387   0,                                           /* tp_call */
388   0,                                           /* tp_str */
389   0,                                           /* tp_getattro */
390   0,                                           /* tp_setattro */
391   0,                                           /* tp_as_buffer */
392   Py_TPFLAGS_DEFAULT,                          /* tp_flags */
393   "Senna Context objects",                     /* tp_doc */
394   0,                                           /* tp_traverse */
395   0,                                           /* tp_clear */
396   0,                                           /* tp_richcompare */
397   0,                                           /* tp_weaklistoffset */
398   0,                                           /* tp_iter */
399   0,                                           /* tp_iternext */
400   sennactx_Context_methods,                    /* tp_methods */
401   0,                                           /* tp_members */
402   0,                                           /* tp_getset */
403   0,                                           /* tp_base */
404   0,                                           /* tp_dict */
405   0,                                           /* tp_descr_get */
406   0,                                           /* tp_descr_set */
407   0,                                           /* tp_dictoffset */
408   0,                                           /* tp_init */
409   0,                                           /* tp_alloc */
410   sennactx_ContextObject_new,                  /* tp_new */
411 };
412
413 /* consts */
414
415 typedef struct _ConstPair {
416   const char *name;
417   int value;
418 } ConstPair;
419
420 static ConstPair consts[] = {
421   /* sen_rc */
422   {"RC_SUCCESS", sen_success},
423   {"RC_MEMORY_EXHAUSTED", sen_memory_exhausted},
424   {"RC_INVALID_FORMAT", sen_invalid_format},
425   {"RC_FILE_OPERATION_ERROR", sen_file_operation_error},
426   {"RC_OTHER_ERROR", sen_other_error},
427   /* sen_encoding */
428   {"ENC_DEFAULT", sen_enc_default},
429   {"ENC_NONE", sen_enc_none},
430   {"ENC_EUC_JP", sen_enc_euc_jp},
431   {"ENC_UTF8", sen_enc_utf8},
432   {"ENC_SJIS", sen_enc_sjis},
433   {"ENC_LATIN1", sen_enc_latin1},
434   {"ENC_KOI8R", sen_enc_koi8r},
435   /* sen_ctx flags */
436   {"CTX_MORE", SEN_CTX_MORE},
437   {"CTX_USEQL", SEN_CTX_USEQL},
438   {"CTX_BATCHMODE", SEN_CTX_BATCHMODE},
439   /* end */
440   {NULL, 0}
441 };
442
443 #ifndef PyMODINIT_FUNC
444 #define PyMODINIT_FUNC void
445 #endif
446 PyMODINIT_FUNC
447 initsennactx(void)
448 {
449   unsigned int i;
450   PyObject *m, *dict;
451
452   if (!(m = Py_InitModule3("sennactx", module_methods,
453                            "Senna context module."))) {
454     goto exit;
455   }
456   sen_init();
457
458   /* register classes */
459
460   if (PyType_Ready(&sennactx_DbType) < 0) { goto exit; }
461   if (PyType_Ready(&sennactx_ContextType) < 0) { goto exit; }
462   Py_INCREF(&sennactx_DbType);
463   PyModule_AddObject(m, "Db", (PyObject *)&sennactx_DbType);
464   Py_INCREF(&sennactx_ContextType);
465   PyModule_AddObject(m, "Context", (PyObject *)&sennactx_ContextType);
466
467   /* register consts */
468
469   if (!(dict = PyModule_GetDict(m))) { goto exit; }
470
471   for (i = 0; consts[i].name; i++) {
472     PyObject *v;
473     if (!(v = PyInt_FromLong(consts[i].value))) {
474       goto exit;
475     }
476     PyDict_SetItemString(dict, consts[i].name, v);
477     Py_DECREF(v);
478   }
479   if (Py_AtExit((void (*)(void))sen_fin)) { goto exit; }
480 exit:
481   if (PyErr_Occurred()) {
482     PyErr_SetString(PyExc_ImportError, "sennactx: init failed");
483   }
484 }