]> git.notmuchmail.org Git - notmuch/blobdiff - cnotmuch/database.py
Implement Database.upgrade() to get the last bit of API. We are complete now.
[notmuch] / cnotmuch / database.py
index 714290347b38377c5070e92ea2825c0545f2c042..c88c21c549b969e542ff1d3582eef4bd166979b9 100644 (file)
@@ -36,6 +36,10 @@ class Database(object):
     _open = nmlib.notmuch_database_open 
     _open.restype = c_void_p
 
+    """notmuch_database_upgrade"""
+    _upgrade = nmlib.notmuch_database_upgrade
+    _upgrade.argtypes = [c_void_p, c_void_p, c_void_p]
+
     """ notmuch_database_find_message """
     _find_message = nmlib.notmuch_database_find_message
     _find_message.restype = c_void_p
@@ -173,6 +177,27 @@ class Database(object):
 
         return notmuch_database_needs_upgrade(self._db) 
 
+    def upgrade(self):
+        """Upgrades the current database
+
+        After opening a database in read-write mode, the client should
+        check if an upgrade is needed (notmuch_database_needs_upgrade) and
+        if so, upgrade with this function before making any modifications.
+
+        NOT IMPLEMENTED: The optional progress_notify callback can be
+        used by the caller to provide progress indication to the
+        user. If non-NULL it will be called periodically with
+        'progress' as a floating-point value in the range of [0.0
+        .. 1.0] indicating the progress made so far in the upgrade
+        process.
+        """
+        # Raise a NotmuchError if not initialized
+        self._verify_initialized_db()
+
+        status = Database._upgrade (self._db, None, None)
+        #TODO: catch exceptions, document return values and etc
+        return status
+
     def get_directory(self, path):
         """Returns a :class:`Directory` of path, 
         (creating it if it does not exist(?))
@@ -593,6 +618,10 @@ class Directory(object):
     _set_mtime = nmlib.notmuch_directory_set_mtime
     _set_mtime.argtypes = [c_char_p, c_long]
 
+    """notmuch_directory_get_child_files"""
+    _get_child_files = nmlib.notmuch_directory_get_child_files
+    _get_child_files.restype = c_void_p
+
     """notmuch_directory_get_child_directories"""
     _get_child_directories = nmlib.notmuch_directory_get_child_directories
     _get_child_directories.restype = c_void_p
@@ -612,7 +641,6 @@ class Directory(object):
                        this Directory object lives. This keeps the
                        parent object alive.
         """
-        #TODO, sanity checking that the path is really absolute?
         self._path = path
         self._dir_p = dir_p
         self._parent = parent
@@ -688,14 +716,17 @@ class Directory(object):
                      and setting of the Directory *mtime*""")
 
     def get_child_files(self):
-       """Gets a Filenames iterator listing all the filenames of
-       messages in the database within the given directory.
+        """Gets a Filenames iterator listing all the filenames of
+        messages in the database within the given directory.
  
-       The returned filenames will be the basename-entries only (not
-       complete paths.
-       """
-       pass
-       #notmuch_filenames_t * notmuch_directory_get_child_files (notmuch_directory_t *directory);
+        The returned filenames will be the basename-entries only (not
+        complete paths.
+        """
+        #Raise a NotmuchError(STATUS.NOT_INITIALIZED) if self._dir_p is None
+        self._verify_dir_initialized()
+
+        files_p = Directory._get_child_files(self._dir_p)
+        return Filenames(files_p, self)
 
     def get_child_directories(self):
         """Gets a Filenams iterator listing all the filenames of
@@ -704,8 +735,11 @@ class Directory(object):
         The returned filenames will be the basename-entries only (not
         complete paths.
         """
-        #notmuch_filenames_t * notmuch_directory_get_child_directories (notmuch_directory_t *directory);
-        pass
+        #Raise a NotmuchError(STATUS.NOT_INITIALIZED) if self._dir_p is None
+        self._verify_dir_initialized()
+
+        files_p = Directory._get_child_directories(self._dir_p)
+        return Filenames(files_p, self)
 
     @property
     def path(self):
@@ -720,3 +754,67 @@ class Directory(object):
         """Close and free the Directory"""
         if self._dir_p is not None:
             nmlib.notmuch_directory_destroy(self._dir_p)
+
+#------------------------------------------------------------------------------
+class Filenames(object):
+    """An iterator over File- or Directory names that are stored in the notmuch database
+    """
+
+    #notmuch_filenames_get
+    _get = nmlib.notmuch_filenames_get
+    _get.restype = c_char_p
+
+    def __init__(self, files_p, parent):
+        """
+        :param files_p: The pointer to an internal notmuch_filenames_t object.
+        :param parent: The object this Directory is derived from
+                       (usually a Directory()). We do not directly use
+                       this, but store a reference to it as long as
+                       this Directory object lives. This keeps the
+                       parent object alive.
+        """
+        self._files_p = files_p
+        self._parent = parent
+
+    def __iter__(self):
+        """ Make Filenames an iterator """
+        return self
+
+    def next(self):
+        if self._files_p is None:
+            raise NotmuchError(STATUS.NOT_INITIALIZED)
+
+        if not nmlib.notmuch_filenames_valid(self._files_p):
+            self._files_p = None
+            raise StopIteration
+
+        file = Filenames._get (self._files_p)
+        nmlib.notmuch_filenames_move_to_next(self._files_p)
+        return file
+
+    def __len__(self):
+        """len(:class:`Filenames`) returns the number of contained files
+
+        .. note:: As this iterates over the files, we will not be able to 
+               iterate over them again! So this will fail::
+
+                 #THIS FAILS
+                 files = Database().get_directory('').get_child_files()
+                 if len(files) > 0:              #this 'exhausts' msgs
+                     # next line raises NotmuchError(STATUS.NOT_INITIALIZED)!!!
+                     for file in files: print file
+        """
+        if self._files_p is None:
+            raise NotmuchError(STATUS.NOT_INITIALIZED)
+
+        i=0
+        while nmlib.notmuch_filenames_valid(self._files_p):
+            nmlib.notmuch_filenames_move_to_next(self._files_p)
+            i += 1
+        self._files_p = None
+        return i
+
+    def __del__(self):
+        """Close and free Filenames"""
+        if self._files_p is not None:
+            nmlib.notmuch_filenames_destroy(self._files_p)