aboutsummaryrefslogtreecommitdiff
path: root/bindings/python-cffi/notdb/_query.py
diff options
context:
space:
mode:
authorFloris Bruynooghe <flub@google.com>2019-10-08 23:03:12 +0200
committerDavid Bremner <david@tethera.net>2019-12-03 08:12:30 -0400
commit83c2d158983875bf77a9b7662894df585b61741c (patch)
tree8443e3ab530a9cbf00b17c395f03e19138d3bae0 /bindings/python-cffi/notdb/_query.py
parent5f9ea4d2908a597acaf0b809b6f27fa74b70520b (diff)
Introduce CFFI-based python bindings
This introduces CFFI-based Python3-only bindings. The bindings aim at: - Better performance on pypy - Easier to use Python-C interface - More "pythonic" - The API should not allow invalid operations - Use native object protocol where possible - Memory safety; whatever you do from python, it should not coredump.
Diffstat (limited to 'bindings/python-cffi/notdb/_query.py')
-rw-r--r--bindings/python-cffi/notdb/_query.py83
1 files changed, 83 insertions, 0 deletions
diff --git a/bindings/python-cffi/notdb/_query.py b/bindings/python-cffi/notdb/_query.py
new file mode 100644
index 00000000..613aaf12
--- /dev/null
+++ b/bindings/python-cffi/notdb/_query.py
@@ -0,0 +1,83 @@
+from notdb import _base as base
+from notdb import _capi as capi
+from notdb import _errors as errors
+from notdb import _message as message
+from notdb import _thread as thread
+
+
+__all__ = []
+
+
+class Query(base.NotmuchObject):
+ """Private, minimal query object.
+
+ This is not meant for users and is not a full implementation of
+ the query API. It is only an intermediate used internally to
+ match libnotmuch's memory management.
+ """
+ _query_p = base.MemoryPointer()
+
+ def __init__(self, db, query_p):
+ self._db = db
+ self._query_p = query_p
+
+ @property
+ def alive(self):
+ if not self._db.alive:
+ return False
+ try:
+ self._query_p
+ except errors.ObjectDestroyedError:
+ return False
+ else:
+ return True
+
+ def __del__(self):
+ self._destroy()
+
+ def _destroy(self):
+ if self.alive:
+ capi.lib.notmuch_query_destroy(self._query_p)
+ self._query_p = None
+
+ @property
+ def query(self):
+ """The query string as seen by libnotmuch."""
+ q = capi.lib.notmuch_query_get_query_string(self._query_p)
+ return base.BinString.from_cffi(q)
+
+ def messages(self):
+ """Return an iterator over all the messages found by the query.
+
+ This executes the query and returns an iterator over the
+ :class:`Message` objects found.
+ """
+ msgs_pp = capi.ffi.new('notmuch_messages_t**')
+ ret = capi.lib.notmuch_query_search_messages(self._query_p, msgs_pp)
+ if ret != capi.lib.NOTMUCH_STATUS_SUCCESS:
+ raise errors.NotmuchError(ret)
+ return message.MessageIter(self, msgs_pp[0], db=self._db)
+
+ def count_messages(self):
+ """Return the number of messages matching this query."""
+ count_p = capi.ffi.new('unsigned int *')
+ ret = capi.lib.notmuch_query_count_messages(self._query_p, count_p)
+ if ret != capi.lib.NOTMUCH_STATUS_SUCCESS:
+ raise errors.NotmuchError(ret)
+ return count_p[0]
+
+ def threads(self):
+ """Return an iterator over all the threads found by the query."""
+ threads_pp = capi.ffi.new('notmuch_threads_t **')
+ ret = capi.lib.notmuch_query_search_threads(self._query_p, threads_pp)
+ if ret != capi.lib.NOTMUCH_STATUS_SUCCESS:
+ raise errors.NotmuchError(ret)
+ return thread.ThreadIter(self, threads_pp[0], db=self._db)
+
+ def count_threads(self):
+ """Return the number of threads matching this query."""
+ count_p = capi.ffi.new('unsigned int *')
+ ret = capi.lib.notmuch_query_count_threads(self._query_p, count_p)
+ if ret != capi.lib.NOTMUCH_STATUS_SUCCESS:
+ raise errors.NotmuchError(ret)
+ return count_p[0]