nmdb: Add an option to save the pidfile
[nmdb.git] / bindings / python / nmdb_ll.c
blob6c329a384d41ab551f6efb701db356739809b3a8
2 /*
3 * Python 2 and 3 bindings for libnmdb
4 * Alberto Bertogli (albertito@blitiri.com.ar)
6 * This is the low-level module, used by the python one to construct
7 * friendlier objects.
8 */
10 #define PY_SSIZE_T_CLEAN 1
12 #include <Python.h>
13 #include <nmdb.h>
17 * Type definitions
20 typedef struct {
21 PyObject_HEAD;
22 nmdb_t *db;
23 } nmdbobject;
26 * The nmdb object
29 /* delete */
30 static void db_dealloc(nmdbobject *db)
32 if (db->db) {
33 nmdb_free(db->db);
35 PyObject_Del(db);
39 /* add tipc server */
40 static PyObject *db_add_tipc_server(nmdbobject *db, PyObject *args)
42 int port;
43 int rv;
45 if (!PyArg_ParseTuple(args, "i:add_tipc_server", &port)) {
46 return NULL;
49 Py_BEGIN_ALLOW_THREADS
50 rv = nmdb_add_tipc_server(db->db, port);
51 Py_END_ALLOW_THREADS
53 return PyLong_FromLong(rv);
56 /* add tcp server */
57 static PyObject *db_add_tcp_server(nmdbobject *db, PyObject *args)
59 int port;
60 char *addr;
61 int rv;
63 if (!PyArg_ParseTuple(args, "si:add_tcp_server", &addr, &port)) {
64 return NULL;
67 Py_BEGIN_ALLOW_THREADS
68 rv = nmdb_add_tcp_server(db->db, addr, port);
69 Py_END_ALLOW_THREADS
71 return PyLong_FromLong(rv);
74 /* add udp server */
75 static PyObject *db_add_udp_server(nmdbobject *db, PyObject *args)
77 int port;
78 char *addr;
79 int rv;
81 if (!PyArg_ParseTuple(args, "si:add_udp_server", &addr, &port)) {
82 return NULL;
85 Py_BEGIN_ALLOW_THREADS
86 rv = nmdb_add_udp_server(db->db, addr, port);
87 Py_END_ALLOW_THREADS
89 return PyLong_FromLong(rv);
92 /* cache set */
93 static PyObject *db_cache_set(nmdbobject *db, PyObject *args)
95 unsigned char *key, *val;
96 size_t ksize, vsize;
97 int rv;
99 if (!PyArg_ParseTuple(args, "s#s#:cache_set", &key, &ksize,
100 &val, &vsize)) {
101 return NULL;
104 Py_BEGIN_ALLOW_THREADS
105 rv = nmdb_cache_set(db->db, key, ksize, val, vsize);
106 Py_END_ALLOW_THREADS
108 return PyLong_FromLong(rv);
111 /* cache get */
112 static PyObject *db_cache_get(nmdbobject *db, PyObject *args)
114 unsigned char *key, *val;
115 size_t ksize, vsize;
116 ssize_t rv;
117 PyObject *r;
119 if (!PyArg_ParseTuple(args, "s#:cache_get", &key, &ksize)) {
120 return NULL;
123 /* vsize is enough to hold the any value */
124 vsize = 128 * 1024;
125 val = malloc(vsize);
126 if (val == NULL)
127 return PyErr_NoMemory();
129 Py_BEGIN_ALLOW_THREADS
130 rv = nmdb_cache_get(db->db, key, ksize, val, vsize);
131 Py_END_ALLOW_THREADS
133 if (rv <= -2) {
134 /* FIXME: define a better exception */
135 r = PyErr_SetFromErrno(PyExc_IOError);
136 } else if (rv == -1) {
137 /* Miss, handled in the high-level module. */
138 r = PyLong_FromLong(-1);
139 } else {
140 #ifdef PYTHON3
141 r = PyBytes_FromStringAndSize((char *) val, rv);
142 #elif PYTHON2
143 r = PyString_FromStringAndSize((char *) val, rv);
144 #endif
147 free(val);
148 return r;
151 /* cache delete */
152 static PyObject *db_cache_delete(nmdbobject *db, PyObject *args)
154 unsigned char *key;
155 size_t ksize;
156 int rv;
158 if (!PyArg_ParseTuple(args, "s#:cache_delete", &key, &ksize)) {
159 return NULL;
162 Py_BEGIN_ALLOW_THREADS
163 rv = nmdb_cache_del(db->db, key, ksize);
164 Py_END_ALLOW_THREADS
166 return PyLong_FromLong(rv);
169 /* cache cas */
170 static PyObject *db_cache_cas(nmdbobject *db, PyObject *args)
172 unsigned char *key, *oldval, *newval;
173 size_t ksize, ovsize, nvsize;
174 int rv;
176 if (!PyArg_ParseTuple(args, "s#s#s#:cache_cas", &key, &ksize,
177 &oldval, &ovsize,
178 &newval, &nvsize)) {
179 return NULL;
182 Py_BEGIN_ALLOW_THREADS
183 rv = nmdb_cache_cas(db->db, key, ksize, oldval, ovsize,
184 newval, nvsize);
185 Py_END_ALLOW_THREADS
187 return PyLong_FromLong(rv);
190 /* cache increment */
191 static PyObject *db_cache_incr(nmdbobject *db, PyObject *args)
193 unsigned char *key;
194 size_t ksize;
195 int rv;
196 long long int increment;
197 int64_t newval;
199 if (!PyArg_ParseTuple(args, "s#L:cache_incr", &key, &ksize,
200 &increment)) {
201 return NULL;
204 Py_BEGIN_ALLOW_THREADS
205 rv = nmdb_cache_incr(db->db, key, ksize, increment, &newval);
206 Py_END_ALLOW_THREADS
208 return Py_BuildValue("iL", rv, newval);
212 /* db set */
213 static PyObject *db_set(nmdbobject *db, PyObject *args)
215 unsigned char *key, *val;
216 size_t ksize, vsize;
217 int rv;
219 if (!PyArg_ParseTuple(args, "s#s#:set", &key, &ksize,
220 &val, &vsize)) {
221 return NULL;
224 Py_BEGIN_ALLOW_THREADS
225 rv = nmdb_set(db->db, key, ksize, val, vsize);
226 Py_END_ALLOW_THREADS
228 return PyLong_FromLong(rv);
231 /* db get */
232 static PyObject *db_get(nmdbobject *db, PyObject *args)
234 unsigned char *key, *val;
235 size_t ksize, vsize;
236 ssize_t rv;
237 PyObject *r;
239 if (!PyArg_ParseTuple(args, "s#:get", &key, &ksize)) {
240 return NULL;
243 /* vsize is enough to hold the any value */
244 vsize = 128 * 1024;
245 val = malloc(vsize);
246 if (val == NULL)
247 return PyErr_NoMemory();
249 Py_BEGIN_ALLOW_THREADS
250 rv = nmdb_get(db->db, key, ksize, val, vsize);
251 Py_END_ALLOW_THREADS
253 if (rv <= -2) {
254 /* FIXME: define a better exception */
255 r = PyErr_SetFromErrno(PyExc_IOError);
256 } else if (rv == -1) {
257 /* Miss, handled in the high-level module. */
258 r = PyLong_FromLong(-1);
259 } else {
260 #ifdef PYTHON3
261 r = PyBytes_FromStringAndSize((char *) val, rv);
262 #elif PYTHON2
263 r = PyString_FromStringAndSize((char *) val, rv);
264 #endif
267 free(val);
268 return r;
271 /* db delete */
272 static PyObject *db_delete(nmdbobject *db, PyObject *args)
274 unsigned char *key;
275 size_t ksize;
276 int rv;
278 if (!PyArg_ParseTuple(args, "s#:delete", &key, &ksize)) {
279 return NULL;
282 Py_BEGIN_ALLOW_THREADS
283 rv = nmdb_del(db->db, key, ksize);
284 Py_END_ALLOW_THREADS
286 return PyLong_FromLong(rv);
289 /* db cas */
290 static PyObject *db_cas(nmdbobject *db, PyObject *args)
292 unsigned char *key, *oldval, *newval;
293 size_t ksize, ovsize, nvsize;
294 int rv;
296 if (!PyArg_ParseTuple(args, "s#s#s#:cas", &key, &ksize,
297 &oldval, &ovsize,
298 &newval, &nvsize)) {
299 return NULL;
302 Py_BEGIN_ALLOW_THREADS
303 rv = nmdb_cas(db->db, key, ksize, oldval, ovsize, newval, nvsize);
304 Py_END_ALLOW_THREADS
306 return PyLong_FromLong(rv);
309 /* db increment */
310 static PyObject *db_incr(nmdbobject *db, PyObject *args)
312 unsigned char *key;
313 size_t ksize;
314 int rv;
315 long long int increment;
316 int64_t newval;
318 if (!PyArg_ParseTuple(args, "s#L:incr", &key, &ksize, &increment)) {
319 return NULL;
322 Py_BEGIN_ALLOW_THREADS
323 rv = nmdb_incr(db->db, key, ksize, increment, &newval);
324 Py_END_ALLOW_THREADS
326 return Py_BuildValue("LL", rv, newval);
330 /* db set sync */
331 static PyObject *db_set_sync(nmdbobject *db, PyObject *args)
333 unsigned char *key, *val;
334 size_t ksize, vsize;
335 int rv;
337 if (!PyArg_ParseTuple(args, "s#s#:set_sync", &key, &ksize,
338 &val, &vsize)) {
339 return NULL;
342 Py_BEGIN_ALLOW_THREADS
343 rv = nmdb_set_sync(db->db, key, ksize, val, vsize);
344 Py_END_ALLOW_THREADS
346 return PyLong_FromLong(rv);
349 /* db delete sync */
350 static PyObject *db_delete_sync(nmdbobject *db, PyObject *args)
352 unsigned char *key;
353 size_t ksize;
354 int rv;
356 if (!PyArg_ParseTuple(args, "s#:delete_sync", &key, &ksize)) {
357 return NULL;
360 Py_BEGIN_ALLOW_THREADS
361 rv = nmdb_del_sync(db->db, key, ksize);
362 Py_END_ALLOW_THREADS
364 return PyLong_FromLong(rv);
367 /* firstkey */
368 static PyObject *db_firstkey(nmdbobject *db, PyObject *args)
370 unsigned char *key;
371 size_t ksize;
372 ssize_t rv;
373 PyObject *r;
375 if (!PyArg_ParseTuple(args, "")) {
376 return NULL;
379 /* ksize is enough to hold the any value */
380 ksize = 128 * 1024;
381 key = malloc(ksize);
382 if (key== NULL)
383 return PyErr_NoMemory();
385 Py_BEGIN_ALLOW_THREADS
386 rv = nmdb_firstkey(db->db, key, ksize);
387 Py_END_ALLOW_THREADS
389 if (rv <= -2) {
390 /* FIXME: define a better exception */
391 r = PyErr_SetFromErrno(PyExc_IOError);
392 } else if (rv == -1) {
393 /* No first key or unsupported, handled in the high-level
394 * module. */
395 r = PyLong_FromLong(-1);
396 } else {
397 #ifdef PYTHON3
398 r = PyBytes_FromStringAndSize((char *) key, rv);
399 #elif PYTHON2
400 r = PyString_FromStringAndSize((char *) key, rv);
401 #endif
404 free(key);
405 return r;
408 /* nextkey */
409 static PyObject *db_nextkey(nmdbobject *db, PyObject *args)
411 unsigned char *key, *newkey;
412 size_t ksize, nksize;
413 ssize_t rv;
414 PyObject *r;
416 if (!PyArg_ParseTuple(args, "s#:nextkey", &key, &ksize)) {
417 return NULL;
420 /* nksize is enough to hold the any value */
421 nksize = 128 * 1024;
422 newkey = malloc(nksize);
423 if (newkey == NULL)
424 return PyErr_NoMemory();
426 Py_BEGIN_ALLOW_THREADS
427 rv = nmdb_nextkey(db->db, key, ksize, newkey, nksize);
428 Py_END_ALLOW_THREADS
430 if (rv <= -2) {
431 /* FIXME: define a better exception */
432 r = PyErr_SetFromErrno(PyExc_IOError);
433 } else if (rv == -1) {
434 /* End, handled in the high-level module. */
435 r = PyLong_FromLong(-1);
436 } else {
437 #ifdef PYTHON3
438 r = PyBytes_FromStringAndSize((char *) newkey, rv);
439 #elif PYTHON2
440 r = PyString_FromStringAndSize((char *) newkey, rv);
441 #endif
444 free(newkey);
445 return r;
449 /* nmdb method table */
451 static PyMethodDef nmdb_methods[] = {
452 { "add_tipc_server", (PyCFunction) db_add_tipc_server,
453 METH_VARARGS, NULL },
454 { "add_tcp_server", (PyCFunction) db_add_tcp_server,
455 METH_VARARGS, NULL },
456 { "add_udp_server", (PyCFunction) db_add_udp_server,
457 METH_VARARGS, NULL },
458 { "cache_set", (PyCFunction) db_cache_set, METH_VARARGS, NULL },
459 { "cache_get", (PyCFunction) db_cache_get, METH_VARARGS, NULL },
460 { "cache_delete", (PyCFunction) db_cache_delete, METH_VARARGS, NULL },
461 { "cache_cas", (PyCFunction) db_cache_cas, METH_VARARGS, NULL },
462 { "cache_incr", (PyCFunction) db_cache_incr, METH_VARARGS, NULL },
463 { "set", (PyCFunction) db_set, METH_VARARGS, NULL },
464 { "get", (PyCFunction) db_get, METH_VARARGS, NULL },
465 { "delete", (PyCFunction) db_delete, METH_VARARGS, NULL },
466 { "cas", (PyCFunction) db_cas, METH_VARARGS, NULL },
467 { "incr", (PyCFunction) db_incr, METH_VARARGS, NULL },
468 { "set_sync", (PyCFunction) db_set_sync, METH_VARARGS, NULL },
469 { "delete_sync", (PyCFunction) db_delete_sync, METH_VARARGS, NULL },
470 { "firstkey", (PyCFunction) db_firstkey, METH_VARARGS, NULL },
471 { "nextkey", (PyCFunction) db_nextkey, METH_VARARGS, NULL },
473 { NULL }
479 * The module
482 /* new, returns an nmdb object */
483 static PyTypeObject nmdbType;
484 static PyObject *db_new(PyObject *self, PyObject *args)
486 nmdbobject *db;
488 #ifdef PYTHON3
489 db = (nmdbobject *) nmdbType.tp_alloc(&nmdbType, 0);
490 #elif PYTHON2
491 db = PyObject_New(nmdbobject, &nmdbType);
492 #endif
493 if (db == NULL)
494 return NULL;
496 if (!PyArg_ParseTuple(args, ":new")) {
497 return NULL;
500 db->db = nmdb_init();
501 if (db->db == NULL) {
502 return PyErr_NoMemory();
505 /* XXX: is this necessary? */
506 if (PyErr_Occurred()) {
507 nmdb_free(db->db);
508 return NULL;
511 return (PyObject *) db;
514 static PyMethodDef nmdb_functions[] = {
515 { "new", (PyCFunction) db_new, METH_VARARGS, NULL },
516 { NULL }
520 #ifdef PYTHON3
521 static PyTypeObject nmdbType = {
522 PyObject_HEAD_INIT(NULL)
523 .tp_name = "nmdb_ll.nmdb",
524 .tp_itemsize = sizeof(nmdbobject),
525 .tp_dealloc = (destructor) db_dealloc,
526 .tp_methods = nmdb_methods,
529 static PyModuleDef nmdb_module = {
530 PyModuleDef_HEAD_INIT,
531 .m_name = "nmdb_ll",
532 .m_doc = NULL,
533 .m_size = -1,
534 .m_methods = nmdb_functions,
537 PyMODINIT_FUNC PyInit_nmdb_ll(void)
539 PyObject *m;
541 if (PyType_Ready(&nmdbType) < 0)
542 return NULL;
544 m = PyModule_Create(&nmdb_module);
546 return m;
549 #elif PYTHON2
550 static PyObject *db_getattr(nmdbobject *db, char *name)
552 return Py_FindMethod(nmdb_methods, (PyObject *)db, name);
555 static PyTypeObject nmdbType = {
556 PyObject_HEAD_INIT(NULL)
558 "nmdb_ll.nmdb",
559 sizeof(nmdbobject),
561 (destructor) db_dealloc,
563 (getattrfunc) db_getattr,
566 PyMODINIT_FUNC initnmdb_ll(void)
568 PyObject *m;
570 nmdbType.ob_type = &PyType_Type;
572 m = Py_InitModule("nmdb_ll", nmdb_functions);
575 #endif