diff options
author | Alex Gorrod <alexg@wiredtiger.com> | 2012-11-28 16:57:04 +1100 |
---|---|---|
committer | Alex Gorrod <alexg@wiredtiger.com> | 2012-11-28 16:57:04 +1100 |
commit | c1bd165f6a22dacfa15c10a7106a0ded6c35f6e1 (patch) | |
tree | 26829887ba6dc86eeb26cd193b835095bd5b6a62 /lang | |
parent | c7491df4da3c5192d49ca4f8706a6750428a305d (diff) | |
parent | 2f4a57ac4b851c18ce3b5bf5e2df391c163e7add (diff) | |
download | mongo-c1bd165f6a22dacfa15c10a7106a0ded6c35f6e1.tar.gz |
Merge remote-tracking branch 'upstream/develop' into develop
Conflicts:
build_posix/Make.subdirs
build_posix/configure.ac.in
Diffstat (limited to 'lang')
-rw-r--r-- | lang/python/Makefile.am | 4 | ||||
-rw-r--r-- | lang/python/setup.py | 6 | ||||
-rw-r--r-- | lang/python/wiredtiger.i | 255 |
3 files changed, 155 insertions, 110 deletions
diff --git a/lang/python/Makefile.am b/lang/python/Makefile.am index fede28ff058..d22234e9f43 100644 --- a/lang/python/Makefile.am +++ b/lang/python/Makefile.am @@ -1,4 +1,4 @@ -INCLUDES = -I$(abs_top_builddir) +AM_CPPFLAGS = -I$(abs_top_builddir) PYSRC = $(top_srcdir)/lang/python if DEBUG @@ -7,7 +7,7 @@ endif all-local: _wiredtiger.so $(PYSRC)/wiredtiger_wrap.c: $(top_srcdir)/src/include/wiredtiger.in $(PYSRC)/wiredtiger.i @(cd $(PYSRC) && \ - $(SWIG) -python -nodefaultctor -nodefaultdtor -threads -I$(abs_top_builddir) wiredtiger.i) + $(SWIG) -python -threads -O -Wall -nodefaultctor -nodefaultdtor -I$(abs_top_builddir) wiredtiger.i) _wiredtiger.so: $(top_builddir)/libwiredtiger.la $(PYSRC)/wiredtiger_wrap.c $(PYTHON) $(PYSRC)/setup.py build_ext -b . -t . -f $(PY_SETUP_DEBUG) diff --git a/lang/python/setup.py b/lang/python/setup.py index fb2e036578b..96cdc50b1de 100644 --- a/lang/python/setup.py +++ b/lang/python/setup.py @@ -19,7 +19,11 @@ if sys.platform == 'darwin': kernel_version = os.uname()[2] # e.g. 12.0.0 is Mountain Lion major_version = int(kernel_version.split('.')[0]) if major_version >= 12: - extra_cflags += ['-Wno-self-assign', '-Qunused-arguments'] + extra_cflags += [ + '-Wno-self-assign', + '-Wno-unused-value', + '-Qunused-arguments' + ] dir = os.path.dirname(__file__) diff --git a/lang/python/wiredtiger.i b/lang/python/wiredtiger.i index 9466ea2ab5c..7372213cb77 100644 --- a/lang/python/wiredtiger.i +++ b/lang/python/wiredtiger.i @@ -55,6 +55,10 @@ from packing import pack, unpack (*$1)->flags |= WT_CURSTD_RAW; PyObject_SetAttrString($result, "is_column", PyBool_FromLong(strcmp((*$1)->key_format, "r") == 0)); + PyObject_SetAttrString($result, "key_format", + PyString_InternFromString((*$1)->key_format)); + PyObject_SetAttrString($result, "value_format", + PyString_InternFromString((*$1)->value_format)); } } @@ -85,6 +89,7 @@ DESTRUCTOR(__wt_session, close) /* Don't require empty config strings. */ %typemap(default) const char *config { $1 = NULL; } +%typemap(default) WT_CURSOR *to_dup { $1 = NULL; } /* * Error returns other than WT_NOTFOUND generate an exception. @@ -153,6 +158,58 @@ SELFHELPER(struct __wt_connection, connection) SELFHELPER(struct __wt_session, session) SELFHELPER(struct __wt_cursor, cursor) +/* Error handling. Default case: a non-zero return is an error. */ +%exception { + $action + if (result != 0) { + /* We could use PyErr_SetObject for more complex reporting. */ + SWIG_SetErrorMsg(wtError, wiredtiger_strerror(result)); + SWIG_fail; + } +} + +/* Cursor positioning methods can also return WT_NOTFOUND. */ +%define NOTFOUND_OK(m) +%exception m { + $action + if (result != 0 && result != WT_NOTFOUND) { + /* We could use PyErr_SetObject for more complex reporting. */ + SWIG_SetErrorMsg(wtError, wiredtiger_strerror(result)); + SWIG_fail; + } +} +%enddef + +/* Cursor compare can return any of -1, 0, 1 or WT_NOTFOUND. */ +%define COMPARE_OK(m) +%exception m { + $action + if ((result < -1 || result > 1) && result != WT_NOTFOUND) { + /* We could use PyErr_SetObject for more complex reporting. */ + SWIG_SetErrorMsg(wtError, wiredtiger_strerror(result)); + SWIG_fail; + } +} +%enddef + +NOTFOUND_OK(__wt_cursor::next) +NOTFOUND_OK(__wt_cursor::prev) +NOTFOUND_OK(__wt_cursor::remove) +NOTFOUND_OK(__wt_cursor::search) +NOTFOUND_OK(__wt_cursor::update) + +COMPARE_OK(__wt_cursor::compare) +COMPARE_OK(__wt_cursor::search_near) + +/* Lastly, some methods need no (additional) error checking. */ +%exception __wt_connection::search_near; +%exception __wt_connection::get_home; +%exception __wt_connection::is_new; +%exception __wt_cursor::_set_key; +%exception __wt_cursor::_set_value; +%exception wiredtiger_strerror; +%exception wiredtiger_version; + /* WT_CURSOR customization. */ /* First, replace the varargs get / set methods with Python equivalents. */ %ignore __wt_cursor::get_key; @@ -161,12 +218,31 @@ SELFHELPER(struct __wt_cursor, cursor) %ignore __wt_cursor::set_value; /* Next, override methods that return integers via arguments. */ -%ignore __wt_cursor::equals(WT_CURSOR *, WT_CURSOR *, int *); +%ignore __wt_cursor::compare(WT_CURSOR *, WT_CURSOR *, int *); %ignore __wt_cursor::search_near(WT_CURSOR *, int *); /* SWIG magic to turn Python byte strings into data / size. */ %apply (char *STRING, int LENGTH) { (char *data, int size) }; +/* Handle binary data returns from get_key/value -- avoid cstring.i: it creates a list of returns. */ +%typemap(in,numinputs=0) (char **datap, int *sizep) (char *data, int size) { $1 = &data; $2 = &size; } +%typemap(frearg) (char **datap, int *sizep) ""; +%typemap(argout) (char **datap, int *sizep) { + if (*$1) + $result = SWIG_FromCharPtrAndSize(*$1, *$2); +} + +/* Handle record number returns from get_recno */ +%typemap(in,numinputs=0) (uint64_t *recnop) (uint64_t recno) { $1 = &recno; } +%typemap(frearg) (uint64_t *recnop) ""; +%typemap(argout) (uint64_t *recnop) { $result = PyLong_FromUnsignedLongLong(*$1); } + +%{ +typedef int int_void; +%} +typedef int int_void; +%typemap(out) int_void { $result = VOID_Object; } + %extend __wt_cursor { /* Get / set keys and values */ void _set_key(char *data, int size) { @@ -176,23 +252,21 @@ SELFHELPER(struct __wt_cursor, cursor) $self->set_key($self, &k); } - void _set_recno(uint64_t recno) { + int_void _set_recno(uint64_t recno) { WT_ITEM k; uint8_t recno_buf[20]; size_t size; - int ret = wiredtiger_struct_pack($self->session, - recno_buf, sizeof (recno_buf), "r", recno); - if (ret == 0) - ret = wiredtiger_struct_size($self->session, - &size, "q", recno); - if (ret != 0) { - SWIG_Python_SetErrorMsg(wtError, - wiredtiger_strerror(ret)); - return; - } + int ret; + if ((ret = wiredtiger_struct_size($self->session, + &size, "r", recno)) != 0 || + (ret = wiredtiger_struct_pack($self->session, + recno_buf, sizeof (recno_buf), "r", recno)) != 0) + return (ret); + k.data = recno_buf; k.size = (uint32_t)size; $self->set_key($self, &k); + return (ret); } void _set_value(char *data, int size) { @@ -202,69 +276,57 @@ SELFHELPER(struct __wt_cursor, cursor) $self->set_value($self, &v); } - PyObject *_get_key() { + /* Don't return values, just throw exceptions on failure. */ + int_void _get_key(char **datap, int *sizep) { WT_ITEM k; int ret = $self->get_key($self, &k); - if (ret != 0) { - SWIG_Python_SetErrorMsg(wtError, - wiredtiger_strerror(ret)); - return (NULL); + if (ret == 0) { + *datap = (char *)k.data; + *sizep = (int)k.size; } - return SWIG_FromCharPtrAndSize(k.data, k.size); + return (ret); } - PyObject *_get_recno() { + int_void _get_recno(uint64_t *recnop) { WT_ITEM k; - uint64_t r; int ret = $self->get_key($self, &k); if (ret == 0) ret = wiredtiger_struct_unpack($self->session, - k.data, k.size, "q", &r); - if (ret != 0) { - SWIG_Python_SetErrorMsg(wtError, - wiredtiger_strerror(ret)); - return (NULL); - } - return PyLong_FromUnsignedLongLong(r); + k.data, k.size, "q", recnop); + return (ret); } - PyObject *_get_value() { + int_void _get_value(char **datap, int *sizep) { WT_ITEM v; int ret = $self->get_value($self, &v); - if (ret != 0) { - SWIG_Python_SetErrorMsg(wtError, - wiredtiger_strerror(ret)); - return (NULL); + if (ret == 0) { + *datap = (char *)v.data; + *sizep = (int)v.size; } - return SWIG_FromCharPtrAndSize(v.data, v.size); + return (ret); } - /* equals and search_near need special handling. */ - PyObject *equals(WT_CURSOR *other) { - int is_equal = 0; - int ret = $self->equals($self, other, &is_equal); - if (ret != 0) { - SWIG_Python_SetErrorMsg(wtError, - wiredtiger_strerror(ret)); - return (NULL); - } - return (SWIG_From_int(is_equal)); + /* compare and search_near need special handling. */ + int compare(WT_CURSOR *other) { + int cmp = 0; + int ret = $self->compare($self, other, &cmp); + /* + * Map less-than-zero to -1 and greater-than-zero to 1 to avoid + * colliding with other errors. + */ + return ((ret != 0) ? ret : + (cmp < 0) ? -1 : (cmp == 0) ? 0 : 1); } - PyObject *search_near() { + int search_near() { int cmp = 0; int ret = $self->search_near($self, &cmp); - if (ret != 0 && ret != WT_NOTFOUND) { - SWIG_Python_SetErrorMsg(wtError, - wiredtiger_strerror(ret)); - return (NULL); - } /* * Map less-than-zero to -1 and greater-than-zero to 1 to avoid * colliding with WT_NOTFOUND. */ - return (SWIG_From_int((ret != 0) ? ret : - (cmp < 0) ? -1 : (cmp == 0) ? 0 : 1)); + return ((ret != 0) ? ret : + (cmp < 0) ? -1 : (cmp == 0) ? 0 : 1); } %pythoncode %{ @@ -273,7 +335,10 @@ SELFHELPER(struct __wt_cursor, cursor) @copydoc WT_CURSOR::get_key Returns only the first column.''' - return self.get_keys()[0] + k = self.get_keys() + if len(k) == 1: + return k[0] + return k def get_keys(self): '''get_keys(self) -> (object, ...) @@ -289,7 +354,10 @@ SELFHELPER(struct __wt_cursor, cursor) @copydoc WT_CURSOR::get_value Returns only the first column.''' - return self.get_values()[0] + v = self.get_values() + if len(v) == 1: + return v[0] + return v def get_values(self): '''get_values(self) -> (object, ...) @@ -301,6 +369,8 @@ SELFHELPER(struct __wt_cursor, cursor) '''set_key(self) -> None @copydoc WT_CURSOR::set_key''' + if len(args) == 1 and type(args[0]) == tuple: + args = args[0] if self.is_column: self._set_recno(long(args[0])) else: @@ -312,6 +382,8 @@ SELFHELPER(struct __wt_cursor, cursor) '''set_value(self) -> None @copydoc WT_CURSOR::set_value''' + if len(args) == 1 and type(args[0]) == tuple: + args = args[0] # Keep the Python string pinned self._value = pack(self.value_format, *args) self._set_value(self._value) @@ -322,14 +394,21 @@ SELFHELPER(struct __wt_cursor, cursor) if not hasattr(self, '_iterable'): self._iterable = IterableCursor(self) return self._iterable + + def __getitem__(self, key): + '''Python convenience for searching''' + self.set_key(key) + if self.search() != 0: + raise KeyError + return self.get_value() %} }; /* Remove / rename parts of the C API that we don't want in Python. */ %immutable __wt_cursor::session; %immutable __wt_cursor::uri; -%immutable __wt_cursor::key_format; -%immutable __wt_cursor::value_format; +%ignore __wt_cursor::key_format; +%ignore __wt_cursor::value_format; %immutable __wt_session::connection; %ignore __wt_buf; @@ -353,47 +432,6 @@ SELFHELPER(struct __wt_cursor, cursor) %ignore wiredtiger_extension_init; -/* - * Error handling. This comes last so it doesn't interfere with the extension - * code above. - * - * Default case: a non-zero return is an error. - */ -%exception { - $action - if (result != 0) { - /* We could use PyErr_SetObject for more complex reporting. */ - SWIG_Python_SetErrorMsg(wtError, wiredtiger_strerror(result)); - SWIG_fail; - } -} - -/* Cursor positioning methods can also return WT_NOTFOUND. */ -%define NOTFOUND_OK(m) -%exception m { - $action - if (result != 0 && result != WT_NOTFOUND) { - /* We could use PyErr_SetObject for more complex reporting. */ - SWIG_Python_SetErrorMsg(wtError, wiredtiger_strerror(result)); - SWIG_fail; - } -} -%enddef - -NOTFOUND_OK(__wt_cursor::next) -NOTFOUND_OK(__wt_cursor::prev) -NOTFOUND_OK(__wt_cursor::remove) -NOTFOUND_OK(__wt_cursor::search) -NOTFOUND_OK(__wt_cursor::update) - -/* Lastly, some methods need no (additional) error checking. */ -%exception __wt_connection::equals; -%exception __wt_connection::search_near; -%exception __wt_connection::get_home; -%exception __wt_connection::is_new; -%exception wiredtiger_strerror; -%exception wiredtiger_version; - /* Convert 'int *' to output args for wiredtiger_version */ %apply int *OUTPUT { int * }; @@ -407,27 +445,30 @@ NOTFOUND_OK(__wt_cursor::update) ## @} class stat: - """ a set of static defines used by statistics cursor """ - pass + '''keys for statistics cursors''' + + class conn: + '''keys for cursors on connection statistics''' + pass -class filestat: - """ a set of static defines used by statistics cursor """ - pass + class dsrc: + '''keys for cursors on data source statistics''' + pass import sys -# All names starting with 'WT_STAT_file_' are renamed to -# the wiredtiger.filestat class, those starting with 'WT_STAT_' are -# renamed to wiredtiger.stat . +# All names starting with 'WT_STAT_DSRC_' are renamed to +# the wiredtiger.stat.dsrc class, those starting with 'WT_STAT_CONN' are +# renamed to wiredtiger.stat.conn class. def _rename_with_prefix(prefix, toclass): curmodule = sys.modules[__name__] for name in dir(curmodule): if name.startswith(prefix): - shortname = name[len(prefix):] + shortname = name[len(prefix):].lower() setattr(toclass, shortname, getattr(curmodule, name)) delattr(curmodule, name) -_rename_with_prefix('WT_STAT_file_', filestat) -_rename_with_prefix('WT_STAT_', stat) +_rename_with_prefix('WT_STAT_CONN_', stat.conn) +_rename_with_prefix('WT_STAT_DSRC_', stat.dsrc) del _rename_with_prefix %} |