author | Alberto Bertogli
<albertito@blitiri.com.ar> 2010-04-26 18:22:50 UTC |
committer | Alberto Bertogli
<albertito@blitiri.com.ar> 2010-04-26 19:04:54 UTC |
parent | 69ac3b2861a62b2448cd98f2238ebb4b447cd574 |
.gitignore | +0 | -1 |
LICENSE | +0 | -1 |
Makefile | +3 | -3 |
bindings/python/nmdb.py | +2 | -2 |
bindings/python/nmdb_ll.c | +91 | -36 |
bindings/python/setup.py | +9 | -1 |
bindings/python3/LICENSE | +0 | -30 |
bindings/python3/nmdb.py | +0 | -252 |
bindings/python3/nmdb_ll.c | +0 | -452 |
bindings/python3/setup.py | +0 | -17 |
diff --git a/.gitignore b/.gitignore index ee35c58..1ce400d 100644 --- a/.gitignore +++ b/.gitignore @@ -20,7 +20,6 @@ gmon.out /libnmdb/doxygen/Doxyfile.base /tags /bindings/python/build -/bindings/python3/build /tests/perf/out /tests/perf/ag-data /tests/perf/graph diff --git a/LICENSE b/LICENSE index b857b79..0c8c297 100644 --- a/LICENSE +++ b/LICENSE @@ -15,7 +15,6 @@ As a brief resume, here's how each sub-project is licensed: * bindings/haskell: BOLA (Public domain) * bindings/newlisp: BOLA (Public domain) * bindings/python: BOLA (Public domain) - * bindings/python3: BOLA (Public domain) * bindings/ruby: BOLA (Public domain) diff --git a/Makefile b/Makefile index 5ef8582..7c61c5e 100644 --- a/Makefile +++ b/Makefile @@ -33,13 +33,13 @@ python_clean: cd bindings/python && rm -rf build/ python3: - cd bindings/python3 && python3 setup.py build + cd bindings/python && python3 setup.py build python3_install: - cd bindings/python3 && python3 setup.py install + cd bindings/python && python3 setup.py install python3_clean: - cd bindings/python3 && rm -rf build/ + cd bindings/python && rm -rf build/ .PHONY: default all clean nmdb libnmdb utils \ diff --git a/bindings/python/nmdb.py b/bindings/python/nmdb.py index b5b73c4..fbad7a9 100644 --- a/bindings/python/nmdb.py +++ b/bindings/python/nmdb.py @@ -183,8 +183,8 @@ class GenericDB (object): elif r == 1: # no match, because the value didn't have the right # format - raise TypeError, \ - "The value must be a NULL-terminated string" + raise TypeError( + "The value must be a NULL-terminated string") elif r == 0: # not in raise KeyError diff --git a/bindings/python/nmdb_ll.c b/bindings/python/nmdb_ll.c index 9b51bbb..6c329a3 100644 --- a/bindings/python/nmdb_ll.c +++ b/bindings/python/nmdb_ll.c @@ -1,12 +1,14 @@ /* - * Python bindings for libnmdb + * Python 2 and 3 bindings for libnmdb * Alberto Bertogli (albertito@blitiri.com.ar) * * This is the low-level module, used by the python one to construct * friendlier objects. */ +#define PY_SSIZE_T_CLEAN 1 + #include <Python.h> #include <nmdb.h> @@ -19,7 +21,6 @@ typedef struct { PyObject_HEAD; nmdb_t *db; } nmdbobject; -static PyTypeObject nmdbType; /* * The nmdb object @@ -92,7 +93,7 @@ static PyObject *db_add_udp_server(nmdbobject *db, PyObject *args) static PyObject *db_cache_set(nmdbobject *db, PyObject *args) { unsigned char *key, *val; - int ksize, vsize; + size_t ksize, vsize; int rv; if (!PyArg_ParseTuple(args, "s#s#:cache_set", &key, &ksize, @@ -111,8 +112,8 @@ static PyObject *db_cache_set(nmdbobject *db, PyObject *args) static PyObject *db_cache_get(nmdbobject *db, PyObject *args) { unsigned char *key, *val; - int ksize, vsize; - long rv; + size_t ksize, vsize; + ssize_t rv; PyObject *r; if (!PyArg_ParseTuple(args, "s#:cache_get", &key, &ksize)) { @@ -136,7 +137,11 @@ static PyObject *db_cache_get(nmdbobject *db, PyObject *args) /* Miss, handled in the high-level module. */ r = PyLong_FromLong(-1); } else { +#ifdef PYTHON3 + r = PyBytes_FromStringAndSize((char *) val, rv); +#elif PYTHON2 r = PyString_FromStringAndSize((char *) val, rv); +#endif } free(val); @@ -147,7 +152,7 @@ static PyObject *db_cache_get(nmdbobject *db, PyObject *args) static PyObject *db_cache_delete(nmdbobject *db, PyObject *args) { unsigned char *key; - int ksize; + size_t ksize; int rv; if (!PyArg_ParseTuple(args, "s#:cache_delete", &key, &ksize)) { @@ -165,7 +170,7 @@ static PyObject *db_cache_delete(nmdbobject *db, PyObject *args) static PyObject *db_cache_cas(nmdbobject *db, PyObject *args) { unsigned char *key, *oldval, *newval; - int ksize, ovsize, nvsize; + size_t ksize, ovsize, nvsize; int rv; if (!PyArg_ParseTuple(args, "s#s#s#:cache_cas", &key, &ksize, @@ -186,7 +191,7 @@ static PyObject *db_cache_cas(nmdbobject *db, PyObject *args) static PyObject *db_cache_incr(nmdbobject *db, PyObject *args) { unsigned char *key; - int ksize; + size_t ksize; int rv; long long int increment; int64_t newval; @@ -200,7 +205,7 @@ static PyObject *db_cache_incr(nmdbobject *db, PyObject *args) rv = nmdb_cache_incr(db->db, key, ksize, increment, &newval); Py_END_ALLOW_THREADS - return Py_BuildValue("LL", rv, newval); + return Py_BuildValue("iL", rv, newval); } @@ -208,7 +213,7 @@ static PyObject *db_cache_incr(nmdbobject *db, PyObject *args) static PyObject *db_set(nmdbobject *db, PyObject *args) { unsigned char *key, *val; - int ksize, vsize; + size_t ksize, vsize; int rv; if (!PyArg_ParseTuple(args, "s#s#:set", &key, &ksize, @@ -227,8 +232,8 @@ static PyObject *db_set(nmdbobject *db, PyObject *args) static PyObject *db_get(nmdbobject *db, PyObject *args) { unsigned char *key, *val; - int ksize, vsize; - long rv; + size_t ksize, vsize; + ssize_t rv; PyObject *r; if (!PyArg_ParseTuple(args, "s#:get", &key, &ksize)) { @@ -252,7 +257,11 @@ static PyObject *db_get(nmdbobject *db, PyObject *args) /* Miss, handled in the high-level module. */ r = PyLong_FromLong(-1); } else { +#ifdef PYTHON3 + r = PyBytes_FromStringAndSize((char *) val, rv); +#elif PYTHON2 r = PyString_FromStringAndSize((char *) val, rv); +#endif } free(val); @@ -263,7 +272,7 @@ static PyObject *db_get(nmdbobject *db, PyObject *args) static PyObject *db_delete(nmdbobject *db, PyObject *args) { unsigned char *key; - int ksize; + size_t ksize; int rv; if (!PyArg_ParseTuple(args, "s#:delete", &key, &ksize)) { @@ -281,7 +290,7 @@ static PyObject *db_delete(nmdbobject *db, PyObject *args) static PyObject *db_cas(nmdbobject *db, PyObject *args) { unsigned char *key, *oldval, *newval; - int ksize, ovsize, nvsize; + size_t ksize, ovsize, nvsize; int rv; if (!PyArg_ParseTuple(args, "s#s#s#:cas", &key, &ksize, @@ -301,7 +310,7 @@ static PyObject *db_cas(nmdbobject *db, PyObject *args) static PyObject *db_incr(nmdbobject *db, PyObject *args) { unsigned char *key; - int ksize; + size_t ksize; int rv; long long int increment; int64_t newval; @@ -322,7 +331,7 @@ static PyObject *db_incr(nmdbobject *db, PyObject *args) static PyObject *db_set_sync(nmdbobject *db, PyObject *args) { unsigned char *key, *val; - int ksize, vsize; + size_t ksize, vsize; int rv; if (!PyArg_ParseTuple(args, "s#s#:set_sync", &key, &ksize, @@ -341,7 +350,7 @@ static PyObject *db_set_sync(nmdbobject *db, PyObject *args) static PyObject *db_delete_sync(nmdbobject *db, PyObject *args) { unsigned char *key; - int ksize; + size_t ksize; int rv; if (!PyArg_ParseTuple(args, "s#:delete_sync", &key, &ksize)) { @@ -359,8 +368,8 @@ static PyObject *db_delete_sync(nmdbobject *db, PyObject *args) static PyObject *db_firstkey(nmdbobject *db, PyObject *args) { unsigned char *key; - int ksize; - long rv; + size_t ksize; + ssize_t rv; PyObject *r; if (!PyArg_ParseTuple(args, "")) { @@ -385,7 +394,11 @@ static PyObject *db_firstkey(nmdbobject *db, PyObject *args) * module. */ r = PyLong_FromLong(-1); } else { +#ifdef PYTHON3 + r = PyBytes_FromStringAndSize((char *) key, rv); +#elif PYTHON2 r = PyString_FromStringAndSize((char *) key, rv); +#endif } free(key); @@ -396,8 +409,8 @@ static PyObject *db_firstkey(nmdbobject *db, PyObject *args) static PyObject *db_nextkey(nmdbobject *db, PyObject *args) { unsigned char *key, *newkey; - int ksize, nksize; - long rv; + size_t ksize, nksize; + ssize_t rv; PyObject *r; if (!PyArg_ParseTuple(args, "s#:nextkey", &key, &ksize)) { @@ -421,7 +434,11 @@ static PyObject *db_nextkey(nmdbobject *db, PyObject *args) /* End, handled in the high-level module. */ r = PyLong_FromLong(-1); } else { +#ifdef PYTHON3 + r = PyBytes_FromStringAndSize((char *) newkey, rv); +#elif PYTHON2 r = PyString_FromStringAndSize((char *) newkey, rv); +#endif } free(newkey); @@ -456,21 +473,6 @@ static PyMethodDef nmdb_methods[] = { { NULL } }; -static PyObject *db_getattr(nmdbobject *db, char *name) -{ - return Py_FindMethod(nmdb_methods, (PyObject *)db, name); -} - -static PyTypeObject nmdbType = { - PyObject_HEAD_INIT(NULL) - 0, - "nmdb_ll.nmdb", - sizeof(nmdbobject), - 0, - (destructor) db_dealloc, - 0, - (getattrfunc) db_getattr, -}; /* @@ -478,11 +480,16 @@ static PyTypeObject nmdbType = { */ /* new, returns an nmdb object */ +static PyTypeObject nmdbType; static PyObject *db_new(PyObject *self, PyObject *args) { nmdbobject *db; +#ifdef PYTHON3 + db = (nmdbobject *) nmdbType.tp_alloc(&nmdbType, 0); +#elif PYTHON2 db = PyObject_New(nmdbobject, &nmdbType); +#endif if (db == NULL) return NULL; @@ -509,6 +516,53 @@ static PyMethodDef nmdb_functions[] = { { NULL } }; + +#ifdef PYTHON3 +static PyTypeObject nmdbType = { + PyObject_HEAD_INIT(NULL) + .tp_name = "nmdb_ll.nmdb", + .tp_itemsize = sizeof(nmdbobject), + .tp_dealloc = (destructor) db_dealloc, + .tp_methods = nmdb_methods, +}; + +static PyModuleDef nmdb_module = { + PyModuleDef_HEAD_INIT, + .m_name = "nmdb_ll", + .m_doc = NULL, + .m_size = -1, + .m_methods = nmdb_functions, +}; + +PyMODINIT_FUNC PyInit_nmdb_ll(void) +{ + PyObject *m; + + if (PyType_Ready(&nmdbType) < 0) + return NULL; + + m = PyModule_Create(&nmdb_module); + + return m; +} + +#elif PYTHON2 +static PyObject *db_getattr(nmdbobject *db, char *name) +{ + return Py_FindMethod(nmdb_methods, (PyObject *)db, name); +} + +static PyTypeObject nmdbType = { + PyObject_HEAD_INIT(NULL) + 0, + "nmdb_ll.nmdb", + sizeof(nmdbobject), + 0, + (destructor) db_dealloc, + 0, + (getattrfunc) db_getattr, +}; + PyMODINIT_FUNC initnmdb_ll(void) { PyObject *m; @@ -518,5 +572,6 @@ PyMODINIT_FUNC initnmdb_ll(void) m = Py_InitModule("nmdb_ll", nmdb_functions); } +#endif diff --git a/bindings/python/setup.py b/bindings/python/setup.py index 54c1bcd..dce1df3 100644 --- a/bindings/python/setup.py +++ b/bindings/python/setup.py @@ -1,9 +1,17 @@ +import sys from distutils.core import setup, Extension +if sys.version_info[0] == 2: + ver_define = ('PYTHON2', '1') +elif sys.version_info[0] == 3: + ver_define = ('PYTHON3', '1') + + nmdb_ll = Extension("nmdb_ll", libraries = ['nmdb'], - sources = ['nmdb_ll.c']) + sources = ['nmdb_ll.c'], + define_macros = [ver_define]) setup( name = 'nmdb', diff --git a/bindings/python3/LICENSE b/bindings/python3/LICENSE deleted file mode 100644 index 987d3b9..0000000 --- a/bindings/python3/LICENSE +++ /dev/null @@ -1,30 +0,0 @@ - -I don't like licenses, because I don't like having to worry about all this -legal stuff just for a simple piece of software I don't really mind anyone -using. But I also believe that it's important that people share and give back; -so I'm placing this work under the following license. - - -BOLA - Buena Onda License Agreement (v1.1) ------------------------------------------- - -This work is provided 'as-is', without any express or implied warranty. In no -event will the authors be held liable for any damages arising from the use of -this work. - -To all effects and purposes, this work is to be considered Public Domain. - - -However, if you want to be "buena onda", you should: - -1. Not take credit for it, and give proper recognition to the authors. -2. Share your modifications, so everybody benefits from them. -3. Do something nice for the authors. -4. Help someone who needs it: sign up for some volunteer work or help your - neighbour paint the house. -5. Don't waste. Anything, but specially energy that comes from natural - non-renewable resources. Extra points if you discover or invent something - to replace them. -6. Be tolerant. Everything that's good in nature comes from cooperation. - - diff --git a/bindings/python3/nmdb.py b/bindings/python3/nmdb.py deleted file mode 100644 index 2c0b88c..0000000 --- a/bindings/python3/nmdb.py +++ /dev/null @@ -1,252 +0,0 @@ - -""" -libnmdb python 3 wrapper - -This module is a wrapper for the libnmdb, the C library used to implement -clients to the nmdb server. - -It provides three similar classes: DB, SyncDB and Cache. They all present the -same dictionary-alike interface, but differ in how they interact with the -server. - -The DB class allows you to set, get and delete (key, value) pairs from the -database; the SyncDB class works like DB, but does so in a synchronous way; and -the Cache class affects only the cache and do not impact the backend database. - -Note that mixing cache sets with DB sets can create inconsistencies between -the database and the cache. You shouldn't do that unless you know what you're -doing. - -The classes use pickle to allow you to store and retrieve python objects in a -transparent way. To disable it, set .autopickle to False. - -Here is an example using the DB class: - ->>> import nmdb ->>> db = nmdb.DB() ->>> db.add_tipc_server() ->>> db[1] = { 'english': 'one', 'castellano': 'uno', 'quechua': 'huk' } ->>> print(db[1]) -{'english': 'one', 'castellano': 'uno', 'quechua': 'huk'} ->>> db[(1, 2)] = (True, False) ->>> print(db[(1, 2)]) -(True, False) ->>> del db[(1, 2)] ->>> print(db[(1, 2)]) -Traceback (most recent call last): - File "<stdin>", line 1, in <module> - File "/usr/local/lib/python3.0/dist-packages/nmdb.py", line 206, in __getitem__ - return self.get(key) - File "/usr/local/lib/python3.0/dist-packages/nmdb.py", line 102, in normal_get - return self.generic_get(self._db.get, key) - File "/usr/local/lib/python3.0/dist-packages/nmdb.py", line 93, in generic_get - raise KeyError -KeyError ->>> -""" - -import pickle -import nmdb_ll - - -class NetworkError (Exception): - pass - - -class GenericDB: - def __init__(self): - self._db = nmdb_ll.nmdb() - self.autopickle = True - - def add_tipc_server(self, port = -1): - "Adds a TIPC server to the server pool." - rv = self._db.add_tipc_server(port) - if not rv: - raise NetworkError - return rv - - def add_tcp_server(self, addr, port = -1): - "Adds a TCP server to the server pool." - rv = self._db.add_tcp_server(addr, port) - if not rv: - raise NetworkError - return rv - - def add_udp_server(self, addr, port = -1): - "Adds an UDP server to the server pool." - rv = self._db.add_udp_server(addr, port) - if not rv: - raise NetworkError - return rv - - - def generic_get(self, getf, key): - "d[k] Returns the value associated with the key k." - if self.autopickle: - key = pickle.dumps(key, protocol = -1) - try: - r = getf(key) - except: - raise NetworkError - if r == -1: - # For key errors, get returns -1 instead of a string - # so we know it's a miss. - raise KeyError - if self.autopickle: - r = pickle.loads(r) - return r - - def cache_get(self, key): - return self.generic_get(self._db.cache_get, key) - - def normal_get(self, key): - return self.generic_get(self._db.get, key) - - - def generic_set(self, setf, key, val): - "d[k] = v Associates the value v to the key k." - if self.autopickle: - key = pickle.dumps(key, protocol = -1) - val = pickle.dumps(val, protocol = -1) - r = setf(key, val) - if r <= 0: - raise NetworkError - return 1 - - def cache_set(self, key, val): - return self.generic_set(self._db.cache_set, key, val) - - def normal_set(self, key, val): - return self.generic_set(self._db.set, key, val) - - def set_sync(self, key, val): - return self.generic_set(self._db.set_sync, key, val) - - - def generic_delete(self, delf, key): - "del d[k] Deletes the key k." - if self.autopickle: - key = pickle.dumps(key, protocol = -1) - r = delf(key) - if r < 0: - raise NetworkError - elif r == 0: - raise KeyError - return 1 - - def cache_delete(self, key): - return self.generic_delete(self._db.cache_delete, key) - - def normal_delete(self, key): - return self.generic_delete(self._db.delete, key) - - def delete_sync(self, key): - return self.generic_delete(self._db.delete_sync, key) - - - def generic_cas(self, casf, key, oldval, newval): - "Perform a compare-and-swap." - if self.autopickle: - key = pickle.dumps(key, protocol = -1) - oldval = pickle.dumps(oldval, protocol = -1) - newval = pickle.dumps(newval, protocol = -1) - r = casf(key, oldval, newval) - if r == 2: - # success - return 2 - elif r == 1: - # no match - return 1 - elif r == 0: - # not in - raise KeyError - else: - raise NetworkError - - def cache_cas(self, key, oldv, newv): - return self.generic_cas(self._db.cache_cas, key, - oldval, newval) - - def normal_cas(self, key, oldval, newval): - return self.generic_cas(self._db.cas, key, - oldval, newval) - - - def generic_incr(self, incrf, key, increment): - """Atomically increment the value associated with the given - key by the given increment.""" - if self.autopickle: - key = pickle.dumps(key, protocol = -1) - r, v = incrf(key, increment) - if r == 2: - # success - return v - elif r == 1: - # no match, because the value didn't have the right - # format - raise TypeError("The value must be a " + \ - "NULL-terminated string") - elif r == 0: - # not in - raise KeyError - else: - raise NetworkError - - def cache_incr(self, key, increment = 1): - return self.generic_incr(self._db.cache_incr, key, increment) - - def normal_incr(self, key, increment = 1): - return self.generic_incr(self._db.incr, key, increment) - - - # The following functions will assume the existance of self.set, - # self.get, and self.delete, which are supposed to be set by our - # subclasses. - - def __getitem__(self, key): - return self.get(key) - - def __setitem__(self, key, val): - return self.set(key, val) - - def __delitem__(self, key): - return self.delete(key) - - def __contains__(self, key): - "Returns True if the key is in the database, False otherwise." - try: - r = self.get(key) - except KeyError: - return False - if not r: - return False - return True - - def has_key(self, key): - "Returns True if the key is in the database, False otherwise." - return self.__contains__(key) - - - -class Cache (GenericDB): - get = GenericDB.cache_get - set = GenericDB.cache_set - delete = GenericDB.cache_delete - cas = GenericDB.cache_cas - incr = GenericDB.cache_incr - -class DB (GenericDB): - get = GenericDB.normal_get - set = GenericDB.normal_set - delete = GenericDB.normal_delete - cas = GenericDB.normal_cas - incr = GenericDB.normal_incr - -class SyncDB (GenericDB): - get = GenericDB.normal_get - set = GenericDB.set_sync - delete = GenericDB.delete_sync - cas = GenericDB.normal_cas - incr = GenericDB.normal_incr - - diff --git a/bindings/python3/nmdb_ll.c b/bindings/python3/nmdb_ll.c deleted file mode 100644 index a6a4ab8..0000000 --- a/bindings/python3/nmdb_ll.c +++ /dev/null @@ -1,452 +0,0 @@ - -/* - * Python 3 bindings for libnmdb - * Alberto Bertogli (albertito@blitiri.com.ar) - * - * This is the low-level module, used by the python one to construct - * friendlier objects. - */ - -#include <Python.h> -#include <nmdb.h> - - -/* - * Type definitions - */ - -typedef struct { - PyObject_HEAD; - nmdb_t *db; -} nmdbobject; -static PyTypeObject nmdbType; - -/* - * The nmdb object - */ - -/* delete */ -static void db_dealloc(nmdbobject *db) -{ - if (db->db) { - nmdb_free(db->db); - } - PyObject_Del(db); -} - - -/* add tipc server */ -static PyObject *db_add_tipc_server(nmdbobject *db, PyObject *args) -{ - int port; - int rv; - - if (!PyArg_ParseTuple(args, "i:add_tipc_server", &port)) { - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - rv = nmdb_add_tipc_server(db->db, port); - Py_END_ALLOW_THREADS - - return PyLong_FromLong(rv); -} - -/* add tcp server */ -static PyObject *db_add_tcp_server(nmdbobject *db, PyObject *args) -{ - int port; - char *addr; - int rv; - - if (!PyArg_ParseTuple(args, "si:add_tcp_server", &addr, &port)) { - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - rv = nmdb_add_tcp_server(db->db, addr, port); - Py_END_ALLOW_THREADS - - return PyLong_FromLong(rv); -} - -/* add udp server */ -static PyObject *db_add_udp_server(nmdbobject *db, PyObject *args) -{ - int port; - char *addr; - int rv; - - if (!PyArg_ParseTuple(args, "si:add_udp_server", &addr, &port)) { - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - rv = nmdb_add_udp_server(db->db, addr, port); - Py_END_ALLOW_THREADS - - return PyLong_FromLong(rv); -} - -/* cache set */ -static PyObject *db_cache_set(nmdbobject *db, PyObject *args) -{ - unsigned char *key, *val; - int ksize, vsize; - int rv; - - if (!PyArg_ParseTuple(args, "s#s#:cache_set", &key, &ksize, - &val, &vsize)) { - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - rv = nmdb_cache_set(db->db, key, ksize, val, vsize); - Py_END_ALLOW_THREADS - - return PyLong_FromLong(rv); -} - -/* cache get */ -static PyObject *db_cache_get(nmdbobject *db, PyObject *args) -{ - unsigned char *key, *val; - int ksize, vsize; - long rv; - PyObject *r; - - if (!PyArg_ParseTuple(args, "s#:cache_get", &key, &ksize)) { - return NULL; - } - - /* vsize is enough to hold the any value */ - vsize = 128 * 1024; - val = malloc(vsize); - if (val == NULL) - return PyErr_NoMemory(); - - Py_BEGIN_ALLOW_THREADS - rv = nmdb_cache_get(db->db, key, ksize, val, vsize); - Py_END_ALLOW_THREADS - - if (rv <= -2) { - /* FIXME: define a better exception */ - r = PyErr_SetFromErrno(PyExc_IOError); - } else if (rv == -1) { - /* Miss, handled in the high-level module. */ - r = PyLong_FromLong(-1); - } else { - r = PyBytes_FromStringAndSize((char *) val, rv); - } - - free(val); - return r; -} - -/* cache delete */ -static PyObject *db_cache_delete(nmdbobject *db, PyObject *args) -{ - unsigned char *key; - int ksize; - int rv; - - if (!PyArg_ParseTuple(args, "s#:cache_delete", &key, &ksize)) { - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - rv = nmdb_cache_del(db->db, key, ksize); - Py_END_ALLOW_THREADS - - return PyLong_FromLong(rv); -} - -/* cache cas */ -static PyObject *db_cache_cas(nmdbobject *db, PyObject *args) -{ - unsigned char *key, *oldval, *newval; - int ksize, ovsize, nvsize; - int rv; - - if (!PyArg_ParseTuple(args, "s#s#s#:cache_cas", &key, &ksize, - &oldval, &ovsize, - &newval, &nvsize)) { - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - rv = nmdb_cache_cas(db->db, key, ksize, oldval, ovsize, - newval, nvsize); - Py_END_ALLOW_THREADS - - return PyLong_FromLong(rv); -} - -/* cache increment */ -static PyObject *db_cache_incr(nmdbobject *db, PyObject *args) -{ - unsigned char *key; - int ksize; - int rv; - long long int increment; - int64_t newval; - - if (!PyArg_ParseTuple(args, "s#L:cache_incr", &key, &ksize, - &increment)) { - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - rv = nmdb_cache_incr(db->db, key, ksize, increment, &newval); - Py_END_ALLOW_THREADS - - return Py_BuildValue("LL", rv, newval); -} - - -/* db set */ -static PyObject *db_set(nmdbobject *db, PyObject *args) -{ - unsigned char *key, *val; - int ksize, vsize; - int rv; - - if (!PyArg_ParseTuple(args, "s#s#:set", &key, &ksize, - &val, &vsize)) { - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - rv = nmdb_set(db->db, key, ksize, val, vsize); - Py_END_ALLOW_THREADS - - return PyLong_FromLong(rv); -} - -/* db get */ -static PyObject *db_get(nmdbobject *db, PyObject *args) -{ - unsigned char *key, *val; - int ksize, vsize; - long rv; - PyObject *r; - - if (!PyArg_ParseTuple(args, "s#:get", &key, &ksize)) { - return NULL; - } - - /* vsize is enough to hold the any value */ - vsize = 128 * 1024; - val = malloc(vsize); - if (val == NULL) - return PyErr_NoMemory(); - - Py_BEGIN_ALLOW_THREADS - rv = nmdb_get(db->db, key, ksize, val, vsize); - Py_END_ALLOW_THREADS - - if (rv <= -2) { - /* FIXME: define a better exception */ - r = PyErr_SetFromErrno(PyExc_IOError); - } else if (rv == -1) { - /* Miss, handled in the high-level module. */ - r = PyLong_FromLong(-1); - } else { - r = PyBytes_FromStringAndSize((char *) val, rv); - } - - free(val); - return r; -} - -/* db delete */ -static PyObject *db_delete(nmdbobject *db, PyObject *args) -{ - unsigned char *key; - int ksize; - int rv; - - if (!PyArg_ParseTuple(args, "s#:delete", &key, &ksize)) { - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - rv = nmdb_del(db->db, key, ksize); - Py_END_ALLOW_THREADS - - return PyLong_FromLong(rv); -} - -/* db cas */ -static PyObject *db_cas(nmdbobject *db, PyObject *args) -{ - unsigned char *key, *oldval, *newval; - int ksize, ovsize, nvsize; - int rv; - - if (!PyArg_ParseTuple(args, "s#s#s#:cas", &key, &ksize, - &oldval, &ovsize, - &newval, &nvsize)) { - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - rv = nmdb_cas(db->db, key, ksize, oldval, ovsize, newval, nvsize); - Py_END_ALLOW_THREADS - - return PyLong_FromLong(rv); -} - -/* db increment */ -static PyObject *db_incr(nmdbobject *db, PyObject *args) -{ - unsigned char *key; - int ksize; - int rv; - long long int increment; - int64_t newval; - - if (!PyArg_ParseTuple(args, "s#L:incr", &key, &ksize, &increment)) { - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - rv = nmdb_incr(db->db, key, ksize, increment, &newval); - Py_END_ALLOW_THREADS - - return Py_BuildValue("LL", rv, newval); -} - - -/* db set sync */ -static PyObject *db_set_sync(nmdbobject *db, PyObject *args) -{ - unsigned char *key, *val; - int ksize, vsize; - int rv; - - if (!PyArg_ParseTuple(args, "s#s#:set_sync", &key, &ksize, - &val, &vsize)) { - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - rv = nmdb_set_sync(db->db, key, ksize, val, vsize); - Py_END_ALLOW_THREADS - - return PyLong_FromLong(rv); -} - -/* db delete sync */ -static PyObject *db_delete_sync(nmdbobject *db, PyObject *args) -{ - unsigned char *key; - int ksize; - int rv; - - if (!PyArg_ParseTuple(args, "s#:delete_sync", &key, &ksize)) { - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - rv = nmdb_del_sync(db->db, key, ksize); - Py_END_ALLOW_THREADS - - return PyLong_FromLong(rv); -} - - - -/* nmdb method table */ - -static PyMethodDef nmdb_methods[] = { - { "add_tipc_server", (PyCFunction) db_add_tipc_server, - METH_VARARGS, NULL }, - { "add_tcp_server", (PyCFunction) db_add_tcp_server, - METH_VARARGS, NULL }, - { "add_udp_server", (PyCFunction) db_add_udp_server, - METH_VARARGS, NULL }, - { "cache_set", (PyCFunction) db_cache_set, METH_VARARGS, NULL }, - { "cache_get", (PyCFunction) db_cache_get, METH_VARARGS, NULL }, - { "cache_delete", (PyCFunction) db_cache_delete, METH_VARARGS, NULL }, - { "cache_cas", (PyCFunction) db_cache_cas, METH_VARARGS, NULL }, - { "cache_incr", (PyCFunction) db_cache_incr, METH_VARARGS, NULL }, - { "set", (PyCFunction) db_set, METH_VARARGS, NULL }, - { "get", (PyCFunction) db_get, METH_VARARGS, NULL }, - { "delete", (PyCFunction) db_delete, METH_VARARGS, NULL }, - { "cas", (PyCFunction) db_cas, METH_VARARGS, NULL }, - { "incr", (PyCFunction) db_incr, METH_VARARGS, NULL }, - { "set_sync", (PyCFunction) db_set_sync, METH_VARARGS, NULL }, - { "delete_sync", (PyCFunction) db_delete_sync, METH_VARARGS, NULL }, - - { NULL } -}; - -/* new, returns an nmdb object */ -static PyObject *db_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - nmdbobject *db; - - db = (nmdbobject *) type->tp_alloc(type, 0); - if (db == NULL) - return NULL; - - if (!PyArg_ParseTuple(args, ":new")) { - return NULL; - } - - db->db = nmdb_init(); - if (db->db == NULL) { - return PyErr_NoMemory(); - } - - /* XXX: is this necessary? */ - if (PyErr_Occurred()) { - nmdb_free(db->db); - return NULL; - } - - return (PyObject *) db; -} - - -static PyTypeObject nmdbType = { - PyObject_HEAD_INIT(NULL) - .tp_name = "nmdb_ll.nmdb", - .tp_itemsize = sizeof(nmdbobject), - .tp_dealloc = (destructor) db_dealloc, - .tp_methods = nmdb_methods, - .tp_new = db_new, -}; - - - -/* - * The module - */ - -static PyModuleDef nmdb_module = { - PyModuleDef_HEAD_INIT, - .m_name = "nmdb_ll", - .m_doc = NULL, - .m_size = -1, -}; - - -PyMODINIT_FUNC PyInit_nmdb_ll(void) -{ - PyObject *m; - - if (PyType_Ready(&nmdbType) < 0) - return NULL; - - m = PyModule_Create(&nmdb_module); - - Py_INCREF(&nmdbType); - PyModule_AddObject(m, "nmdb", (PyObject *) &nmdbType); - - return m; -} - - - diff --git a/bindings/python3/setup.py b/bindings/python3/setup.py deleted file mode 100644 index 54c1bcd..0000000 --- a/bindings/python3/setup.py +++ /dev/null @@ -1,17 +0,0 @@ - -from distutils.core import setup, Extension - -nmdb_ll = Extension("nmdb_ll", - libraries = ['nmdb'], - sources = ['nmdb_ll.c']) - -setup( - name = 'nmdb', - description = "libnmdb bindings", - author = "Alberto Bertogli", - author_email = "albertito@blitiri.com.ar", - url = "http://blitiri.com.ar/p/nmdb", - py_modules = ['nmdb'], - ext_modules = [nmdb_ll] -) -