]> git.notmuchmail.org Git - notmuch/blobdiff - cnotmuch/database.py
docs: Improve documentations
[notmuch] / cnotmuch / database.py
index 714290347b38377c5070e92ea2825c0545f2c042..44fd31548f7583801827ac9470211332c83f2848 100644 (file)
@@ -24,7 +24,7 @@ class Database(object):
     _get_directory = nmlib.notmuch_database_get_directory
     _get_directory.restype = c_void_p
 
-    """notmuch_database_get_path (notmuch_database_t *database)"""
+    """notmuch_database_get_path"""
     _get_path = nmlib.notmuch_database_get_path
     _get_path.restype = c_char_p
 
@@ -32,24 +32,28 @@ class Database(object):
     _get_version = nmlib.notmuch_database_get_version
     _get_version.restype = c_uint
 
-    """notmuch_database_open (const char *path, notmuch_database_mode_t mode)"""
+    """notmuch_database_open"""
     _open = nmlib.notmuch_database_open 
     _open.restype = c_void_p
 
-    """ notmuch_database_find_message """
+    """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
 
-    """notmuch_database_get_all_tags (notmuch_database_t *database)"""
+    """notmuch_database_get_all_tags"""
     _get_all_tags = nmlib.notmuch_database_get_all_tags
     _get_all_tags.restype = c_void_p
 
-    """ notmuch_database_create(const char *path):"""
+    """notmuch_database_create"""
     _create = nmlib.notmuch_database_create
     _create.restype = c_void_p
 
     def __init__(self, path=None, create=False, mode= 0):
-        """If *path* is *None*, we will try to read a users notmuch 
+        """If *path* is `None`, we will try to read a users notmuch 
         configuration and use his configured database. The location of the 
         configuration file can be specified through the environment variable
         *NOTMUCH_CONFIG*, falling back to the default `~/.notmuch-config`.
@@ -93,8 +97,8 @@ class Database(object):
         This function is used by __init__() and usually does not need
         to be called directly. It wraps the underlying
         *notmuch_database_create* function and creates a new notmuch
-        database at *path*. It will always return a database in
-        :attr:`MODE`.READ_WRITE mode as creating an empty database for
+        database at *path*. It will always return a database in :attr:`MODE`
+        .READ_WRITE mode as creating an empty database for
         reading only does not make a great deal of sense.
 
         :param path: A directory in which we should create the database.
@@ -138,7 +142,7 @@ class Database(object):
     def get_path(self):
         """Returns the file path of an open database
 
-        Wraps notmuch_database_get_path"""
+        Wraps *notmuch_database_get_path*."""
         # Raise a NotmuchError if not initialized
         self._verify_initialized_db()
 
@@ -159,10 +163,10 @@ class Database(object):
     def needs_upgrade(self):
         """Does this database need to be upgraded before writing to it?
 
-        If this function returns True then no functions that modify the
-        database (:meth:`add_message`, :meth:`add_tag`,
-        :meth:`Directory.set_mtime`, etc.) will work unless :meth:`upgrade` 
-        is called successfully first.
+        If this function returns `True` then no functions that modify the
+        database (:meth:`add_message`,
+        :meth:`Message.add_tag`, :meth:`Directory.set_mtime`,
+        etc.) will work unless :meth:`upgrade` is called successfully first.
 
         :returns: `True` or `False`
         :exception: :exc:`NotmuchError` with STATUS.NOT_INITIALIZED if
@@ -173,6 +177,28 @@ 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.
+
+        :TODO: catch exceptions, document return values and etc...
+        """
+        # 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(?))
@@ -182,9 +208,8 @@ class Database(object):
            program if this method is used on a read-only database!
 
         :param path: A str containing the path relative to the path of database
-        (see :meth:`get_path`), or else should be an absolute path
-        with initial components that match the path of 'database'.
-
+              (see :meth:`get_path`), or else should be an absolute path
+              with initial components that match the path of 'database'.
         :returns: :class:`Directory` or raises an exception.
         :exception: :exc:`NotmuchError`
 
@@ -283,7 +308,7 @@ class Database(object):
         is removed for a particular message, the database content for that
         message will be entirely removed.
 
-        :returns: A STATUS.* value with the following meaning:
+        :returns: A STATUS value with the following meaning:
 
              STATUS.SUCCESS
                The last filename was removed and the message was removed 
@@ -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
@@ -607,12 +636,11 @@ class Directory(object):
         :param path:   The absolute path of the directory object.
         :param dir_p:  The pointer to an internal notmuch_directory_t object.
         :param parent: The object this Directory is derived from
-                       (usually a Database()). We do not directly use
+                       (usually a :class:`Database`). 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.
         """
-        #TODO, sanity checking that the path is really absolute?
         self._path = path
         self._dir_p = dir_p
         self._parent = parent
@@ -682,34 +710,42 @@ class Directory(object):
 
         return Directory._get_mtime (self._dir_p)
 
-
     # Make mtime attribute a property of Directory()
     mtime = property(get_mtime, set_mtime, doc="""Property that allows getting
-                     and setting of the Directory *mtime*""")
+                     and setting of the Directory *mtime* (read-write)
+
+                     See :meth:`get_mtime` and :meth:`set_mtime` for usage and 
+                     possible exceptions.""")
 
     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
+        """Gets a :class:`Filenames` iterator listing all the filenames of
         sub-directories in the database within the given directory
         
         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):
-        """Returns the absolute path of this Directory"""
+        """Returns the absolute path of this Directory (read-only)"""
         return self._path
 
     def __repr__(self):
@@ -720,3 +756,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 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)