X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=bindings%2Fpython%2Fnotmuch%2Fdatabase.py;h=f30453345e0dabd6a1cb4fa81596c50bdac65143;hp=1db332fe333b0b83b79a3e6c004de8485d29ad63;hb=fa0bc2ef91cf5c5a86ac24cd76383be3b1819cee;hpb=fcfb619b44b0011ac6bc557e6cbe2d516bc58f8a diff --git a/bindings/python/notmuch/database.py b/bindings/python/notmuch/database.py index 1db332fe..f3045334 100644 --- a/bindings/python/notmuch/database.py +++ b/bindings/python/notmuch/database.py @@ -20,7 +20,8 @@ Copyright 2010 Sebastian Spaeth import os import codecs from ctypes import c_char_p, c_void_p, c_uint, byref, POINTER -from notmuch.globals import ( +from .compat import SafeConfigParser +from .globals import ( nmlib, Enum, _str, @@ -35,10 +36,9 @@ from .errors import ( NotmuchError, NullPointerError, NotInitializedError, - ReadOnlyDatabaseError, ) -from notmuch.message import Message -from notmuch.tag import Tags +from .message import Message +from .tag import Tags from .query import Query from .directory import Directory @@ -73,8 +73,8 @@ class Database(object): """notmuch_database_get_directory""" _get_directory = nmlib.notmuch_database_get_directory - _get_directory.argtypes = [NotmuchDatabaseP, c_char_p] - _get_directory.restype = NotmuchDirectoryP + _get_directory.argtypes = [NotmuchDatabaseP, c_char_p, POINTER(NotmuchDirectoryP)] + _get_directory.restype = c_uint """notmuch_database_get_path""" _get_path = nmlib.notmuch_database_get_path @@ -88,8 +88,8 @@ class Database(object): """notmuch_database_open""" _open = nmlib.notmuch_database_open - _open.argtypes = [c_char_p, c_uint] - _open.restype = NotmuchDatabaseP + _open.argtypes = [c_char_p, c_uint, POINTER(NotmuchDatabaseP)] + _open.restype = c_uint """notmuch_database_upgrade""" _upgrade = nmlib.notmuch_database_upgrade @@ -115,8 +115,8 @@ class Database(object): """notmuch_database_create""" _create = nmlib.notmuch_database_create - _create.argtypes = [c_char_p] - _create.restype = NotmuchDatabaseP + _create.argtypes = [c_char_p, POINTER(NotmuchDatabaseP)] + _create.restype = c_uint def __init__(self, path = None, create = False, mode = MODE.READ_ONLY): @@ -156,11 +156,13 @@ class Database(object): _destroy = nmlib.notmuch_database_destroy _destroy.argtypes = [NotmuchDatabaseP] - _destroy.restype = None + _destroy.restype = c_uint def __del__(self): if self._db: - self._destroy(self._db) + status = self._destroy(self._db) + if status != STATUS.SUCCESS: + raise NotmuchError(status) def _assert_db_is_initialized(self): """Raises :exc:`NotInitializedError` if self._db is `None`""" @@ -186,12 +188,13 @@ class Database(object): raise NotmuchError(message="Cannot create db, this Database() " "already has an open one.") - res = Database._create(_str(path), Database.MODE.READ_WRITE) + db = NotmuchDatabaseP() + status = Database._create(_str(path), byref(db)) - if not res: - raise NotmuchError( - message="Could not create the specified database") - self._db = res + if status != STATUS.SUCCESS: + raise NotmuchError(status) + self._db = db + return status def open(self, path, mode=0): """Opens an existing database @@ -205,15 +208,17 @@ class Database(object): :raises: Raises :exc:`NotmuchError` in case of any failure (possibly after printing an error message on stderr). """ - res = Database._open(_str(path), mode) + db = NotmuchDatabaseP() + status = Database._open(_str(path), mode, byref(db)) - if not res: - raise NotmuchError(message="Could not open the specified database") - self._db = res + if status != STATUS.SUCCESS: + raise NotmuchError(status) + self._db = db + return status _close = nmlib.notmuch_database_close _close.argtypes = [NotmuchDatabaseP] - _close.restype = None + _close.restype = c_uint def close(self): ''' @@ -227,7 +232,9 @@ class Database(object): NotmuchError. ''' if self._db: - self._close(self._db) + status = self._close(self._db) + if status != STATUS.SUCCESS: + raise NotmuchError(status) def __enter__(self): ''' @@ -343,7 +350,6 @@ class Database(object): def get_directory(self, path): """Returns a :class:`Directory` of path, - (creating it if it does not exist(?)) :param path: An unicode string containing the path relative to the path of database (see :meth:`get_path`), or else should be an absolute @@ -351,18 +357,9 @@ class Database(object): :returns: :class:`Directory` or raises an exception. :raises: :exc:`FileError` if path is not relative database or absolute with initial components same as database. - :raises: :exc:`ReadOnlyDatabaseError` if the database has not been - opened in read-write mode """ self._assert_db_is_initialized() - # work around libnotmuch calling exit(3), see - # id:20120221002921.8534.57091@thinkbox.jade-hamburg.de - # TODO: remove once this issue is resolved - if self.mode != Database.MODE.READ_WRITE: - raise ReadOnlyDatabaseError('The database has to be opened in ' - 'read-write mode for get_directory') - # sanity checking if path is valid, and make path absolute if path and path[0] == os.sep: # we got an absolute path @@ -375,7 +372,13 @@ class Database(object): #we got a relative path, make it absolute abs_dirpath = os.path.abspath(os.path.join(self.get_path(), path)) - dir_p = Database._get_directory(self._db, _str(path)) + dir_p = NotmuchDirectoryP() + status = Database._get_directory(self._db, _str(path), byref(dir_p)) + + if status != STATUS.SUCCESS: + raise NotmuchError(status) + if not dir_p: + return None # return the Directory, init it with the absolute path return Directory(abs_dirpath, dir_p, self) @@ -480,7 +483,10 @@ class Database(object): removed. """ self._assert_db_is_initialized() - return self._remove_message(self._db, _str(filename)) + status = self._remove_message(self._db, _str(filename)) + if status not in [STATUS.SUCCESS, STATUS.DUPLICATE_MESSAGE_ID]: + raise NotmuchError(status) + return status def find_message(self, msgid): """Returns a :class:`Message` as identified by its message ID @@ -527,19 +533,10 @@ class Database(object): retry. :raises: :exc:`NotInitializedError` if the database was not intitialized. - :raises: :exc:`ReadOnlyDatabaseError` if the database has not been - opened in read-write mode *Added in notmuch 0.9*""" self._assert_db_is_initialized() - # work around libnotmuch calling exit(3), see - # id:20120221002921.8534.57091@thinkbox.jade-hamburg.de - # TODO: remove once this issue is resolved - if self.mode != Database.MODE.READ_WRITE: - raise ReadOnlyDatabaseError('The database has to be opened in ' - 'read-write mode for get_directory') - msg_p = NotmuchMessageP() status = Database._find_message_by_filename(self._db, _str(filename), byref(msg_p)) @@ -556,7 +553,7 @@ class Database(object): """ self._assert_db_is_initialized() tags_p = Database._get_all_tags(self._db) - if tags_p == None: + if not tags_p: raise NullPointerError() return Tags(tags_p, self) @@ -580,6 +577,22 @@ class Database(object): """ return Query(self, querystring) + """notmuch_database_status_string""" + _status_string = nmlib.notmuch_database_status_string + _status_string.argtypes = [NotmuchDatabaseP] + _status_string.restype = c_char_p + + def status_string(self): + """Returns the status string of the database + + This is sometimes used for additional error reporting + """ + self._assert_db_is_initialized() + s = Database._status_string(self._db) + if s: + return s.decode('utf-8', 'ignore') + return s + def __repr__(self): return "'Notmuch DB " + self.get_path() + "'" @@ -587,13 +600,6 @@ class Database(object): """ Reads a user's notmuch config and returns his db location Throws a NotmuchError if it cannot find it""" - try: - # python3.x - from configparser import SafeConfigParser - except ImportError: - # python2.x - from ConfigParser import SafeConfigParser - config = SafeConfigParser() conf_f = os.getenv('NOTMUCH_CONFIG', os.path.expanduser('~/.notmuch-config')) @@ -602,12 +608,3 @@ class Database(object): raise NotmuchError(message="No DB path specified" " and no user default found") return config.get('database', 'path') - - @property - def db_p(self): - """Property returning a pointer to `notmuch_database_t` or `None` - - This should normally not be needed by a user (and is not yet - guaranteed to remain stable in future versions). - """ - return self._db