mapistore: implement get_folder_count() in mapistore python bindings
authorBrad Hards <bradh@openchange.org>
Mon, 21 Feb 2011 02:19:57 +0000 (02:19 +0000)
committerBrad Hards <bradh@openchange.org>
Mon, 21 Feb 2011 02:19:57 +0000 (02:19 +0000)
Also convert mapistore_strip_ns_from_uri to use const char**

Also add a test for mapistore rmdir(), which appears to have
some kind of reference count problem - it is causing a python
assert that indicates that something is still reachable.

mapiproxy/libmapistore/backends/mapistore_fsocpf.c
mapiproxy/libmapistore/backends/mapistore_mstoredb.c
mapiproxy/libmapistore/mapistore_backend.h
mapiproxy/libmapistore/mapistore_backend_public.c
pyopenchange/pymapistore.c
pyopenchange/unittest/unittest_mapistoredb.py

index c4bc7d17f035ebd88d87e8c6b3810eb27670db06..af9bc7eff781760f2fab151a57db249e8abc1163 100644 (file)
@@ -153,17 +153,26 @@ static struct fsocpf_folder *fsocpf_find_folder(struct fsocpf_context *fsocpf_ct
                                                const char *uri)
 {
        struct fsocpf_folder_list       *el;
+       const char                      *path = NULL;
 
        /* Sanity checks */
        if (!fsocpf_ctx) return NULL;
        if (!uri) return NULL;
 
+       if (mapistore_strip_ns_from_uri(uri, &path) != MAPISTORE_SUCCESS) {
+               /* assume its already stripped */
+               path = uri;
+       }
+       MSTORE_DEBUG_INFO(MSTORE_LEVEL_DEBUG, "finding %s\n", path);
        for (el = fsocpf_ctx->folders; el; el = el->next) {
-               if (el->folder && el->folder->uri && !strcmp(uri, el->folder->uri)) {
+               MSTORE_DEBUG_INFO(MSTORE_LEVEL_DEBUG, "el->folder->uri: %s\n", el->folder->uri);
+               if (el->folder && el->folder->uri && !strcmp(path, el->folder->uri)) {
                        return el->folder;
                }
        }
 
+       MSTORE_DEBUG_INFO(MSTORE_LEVEL_DEBUG, "%s not found\n", path);
+
        return NULL;
 }
 
@@ -647,7 +656,7 @@ static enum MAPISTORE_ERROR fsocpf_op_mkdir(void *private_data,
        TALLOC_CTX                      *mem_ctx;
        struct fsocpf_context           *fsocpf_ctx = (struct fsocpf_context *)private_data;
        struct fsocpf_folder            *folder;
-       char                            *parent_uri;
+       const char                      *parent_uri;
        char                            *newfolder;
        char                            *dummy_uri;
        struct fsocpf_folder_list       *newel;
@@ -740,45 +749,58 @@ static enum MAPISTORE_ERROR fsocpf_op_mkdir(void *private_data,
 /* FIXME: there's no check to ensure parent_uri is the folder_uri parent ... */
 static enum MAPISTORE_ERROR fsocpf_op_rmdir(void *private_data, const char *parent_uri, const char *folder_uri)
 {
-       struct fsocpf_context   *fsocpf_ctx = (struct fsocpf_context *)private_data;
-       struct fsocpf_folder    *parent;
-       struct fsocpf_folder    *el;
-       char                    *propertiespath;
-       TALLOC_CTX              *mem_ctx;
-       int                     ret;
+       struct fsocpf_context           *fsocpf_ctx = (struct fsocpf_context *)private_data;
+       struct fsocpf_folder            *parent;
+       struct fsocpf_folder            *folder;
+       const char                      *folder_path = NULL;
+       char                            *propertiespath;
+       TALLOC_CTX                      *mem_ctx;
+       int                             ret;
+       struct fsocpf_folder_list       *el;
 
        /* Sanity checks */
        MAPISTORE_RETVAL_IF(!fsocpf_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
        MAPISTORE_RETVAL_IF(!parent_uri, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
        MAPISTORE_RETVAL_IF(!folder_uri, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
-       MSTORE_DEBUG_INFO(MSTORE_LEVEL_LOW, "Deleting %s from %s\n", folder_uri, parent_uri);
+       if (mapistore_strip_ns_from_uri(folder_uri, &folder_path) != MAPISTORE_SUCCESS) {
+               MSTORE_DEBUG_INFO(MSTORE_LEVEL_CRITICAL, "misformed folder_uri: %s\n", folder_uri);
+               return MAPISTORE_ERR_INVALID_PARAMETER;
+       }
+       MSTORE_DEBUG_INFO(MSTORE_LEVEL_LOW, "Deleting %s from %s\n", folder_path, parent_uri);
 
        /* Step 1. Search for the parent fid */
        parent = fsocpf_find_folder(fsocpf_ctx, parent_uri);
        MAPISTORE_RETVAL_IF(!parent, MAPISTORE_ERR_NO_DIRECTORY, NULL);
 
        /* Step 2. Search for the folder element */
-       el = fsocpf_find_folder(fsocpf_ctx, folder_uri);
-       MAPISTORE_RETVAL_IF(!el, MAPISTORE_ERR_NO_DIRECTORY, NULL);
+       folder = fsocpf_find_folder(fsocpf_ctx, folder_path);
+       MAPISTORE_RETVAL_IF(!folder, MAPISTORE_ERR_NO_DIRECTORY, NULL);
 
        mem_ctx = talloc_named(NULL, 0, __FUNCTION__);
 
        /* Step 3. Remove .properties file */
-       propertiespath = talloc_asprintf(mem_ctx, "%s/.properties", folder_uri);
+       propertiespath = talloc_asprintf(mem_ctx, "%s/.properties", folder_path);
        ret = unlink(propertiespath);
        if (ret) {
                MSTORE_DEBUG_ERROR(MSTORE_LEVEL_CRITICAL, "Unlink failed with error '%s'\n", strerror(errno));
        }
 
        /* Step 4. Delete directory */
-       ret = rmdir(folder_uri);
+       ret = rmdir(folder_path);
        if (ret) {
                MSTORE_DEBUG_ERROR(MSTORE_LEVEL_CRITICAL, "rmdir failed with error '%s'\n", strerror(errno));
                talloc_free(mem_ctx);
                return MAPISTORE_ERROR;
        }
-
+       for (el = fsocpf_ctx->folders; el; el = el->next) {
+               MSTORE_DEBUG_INFO(MSTORE_LEVEL_DEBUG, "el->folder->uri: %s\n", el->folder->uri);
+               if (el->folder && el->folder->uri && !strcmp(folder_path, el->folder->uri)) {
+                       MSTORE_DEBUG_INFO(MSTORE_LEVEL_DEBUG, "removing: %s\n", el->folder->uri);
+                       DLIST_REMOVE(fsocpf_ctx->folders, el);
+               }
+       }
+        
        return MAPISTORE_SUCCESS;
 }
 
@@ -802,8 +824,8 @@ static enum MAPISTORE_ERROR fsocpf_op_opendir(void *private_data, const char *pa
        struct fsocpf_folder_list       *newel;
        struct dirent                   *curdir;
        DIR                             *dir;
-       char                            *folder_path = NULL;
-       char                            *parent_folder_path = NULL;
+       const char                      *folder_path = NULL;
+       const char                      *parent_folder_path = NULL;
 
        MSTORE_DEBUG_INFO(MSTORE_LEVEL_DEBUG, MSTORE_SINGLE_MSG, "");
 
@@ -916,6 +938,7 @@ static enum MAPISTORE_ERROR fsocpf_op_readdir_count(void *private_data,
        struct fsocpf_folder            *folder;
        struct fsocpf_folder_list       *el;
        struct dirent                   *curdir;
+       const char                      *folder_path = NULL;
 
        MSTORE_DEBUG_INFO(MSTORE_LEVEL_DEBUG, MSTORE_SINGLE_MSG, "");
 
@@ -924,7 +947,12 @@ static enum MAPISTORE_ERROR fsocpf_op_readdir_count(void *private_data,
        MAPISTORE_RETVAL_IF(!folder_uri, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
        MAPISTORE_RETVAL_IF(!RowCount, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
-       if (!strcmp(fsocpf_ctx->uri, folder_uri)) {
+       if (mapistore_strip_ns_from_uri(folder_uri, &folder_path) != MAPISTORE_SUCCESS) {
+               /* assume its already stripped */
+               folder_path = folder_uri;
+       }
+
+       if (!strcmp(fsocpf_ctx->uri, folder_path)) {
                /* If we access it for the first time, just add an entry to the folder list */
                if (!fsocpf_ctx->folders) {
                        el = fsocpf_folder_list_element_init((TALLOC_CTX *)fsocpf_ctx, fsocpf_ctx->uri, fsocpf_ctx->dir);
@@ -936,7 +964,7 @@ static enum MAPISTORE_ERROR fsocpf_op_readdir_count(void *private_data,
        }
 
        /* Search for the fid fsocpf_folder entry */
-       folder = fsocpf_find_folder(fsocpf_ctx, folder_uri);
+       folder = fsocpf_find_folder(fsocpf_ctx, folder_path);
        MAPISTORE_RETVAL_IF(!folder, MAPISTORE_ERR_NO_DIRECTORY, NULL);
 
        switch (table_type) {
@@ -1462,7 +1490,7 @@ static enum MAPISTORE_ERROR fsocpf_op_setprops(void *private_data,
        struct fsocpf_folder    *folder;
        struct fsocpf_message   *message;
        uint32_t                i;
-       char                    *path;
+       const char              *path;
        enum MAPISTORE_ERROR    retval = MAPISTORE_SUCCESS;
 
        MSTORE_DEBUG_INFO(MSTORE_LEVEL_DEBUG, MSTORE_SINGLE_MSG, "");
index 5988af54e201de791cbb36980394f211b8881d01..777d48ed12421d90d857682d19fb5337785534d3 100644 (file)
@@ -276,10 +276,10 @@ static enum MAPISTORE_ERROR mstoredb_op_mkdir(void *private_data,
 {
        TALLOC_CTX                      *mem_ctx;
        enum MAPISTORE_ERROR            retval = MAPISTORE_SUCCESS;
-       char                            *stripped_uri;
+       const char                      *stripped_uri;
        struct mstoredb_context         *mstoredb_ctx = (struct mstoredb_context *) private_data;
        char                            *ldif;
-       char                            *folder_dn;
+       const char                      *folder_dn;
 
        MSTORE_DEBUG_INFO(MSTORE_LEVEL_DEBUG, MSTORE_SINGLE_MSG, "");
 
index 6bf14a76588731c458c46c9fb0dc5b1ba2d37ed2..3227cc54b065ab26fdaa18beb48d775b815c8567 100644 (file)
@@ -79,7 +79,7 @@ __BEGIN_DECLS
 
 enum MAPISTORE_ERROR   mapistore_backend_register(const struct mapistore_backend *);
 enum MAPISTORE_ERROR   mapistore_backend_init_defaults(struct mapistore_backend *);
-enum MAPISTORE_ERROR   mapistore_strip_ns_from_uri(const char *, char **);
+enum MAPISTORE_ERROR   mapistore_strip_ns_from_uri(const char *, const char **);
 struct ldb_context     *mapistore_public_ldb_connect(struct mapistore_backend_context *, const char *);
 enum MAPISTORE_ERROR   mapistore_exist(struct mapistore_backend_context *, const char *, const char *);
 enum MAPISTORE_ERROR   mapistore_register_folder(struct mapistore_backend_context *, const char *, const char *, 
index c3571e485356cddc956b61f5f075ef6be6f06c0d..253dd8f89ba24d5d5744f5f8b477e96e4b4f3449 100644 (file)
@@ -116,7 +116,7 @@ enum MAPISTORE_ERROR mapistore_exist(struct mapistore_backend_context *ctx,
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-enum MAPISTORE_ERROR mapistore_strip_ns_from_uri(const char *uri, char **stripped_uri)
+enum MAPISTORE_ERROR mapistore_strip_ns_from_uri(const char *uri, const char **stripped_uri)
 {
        char            *tmp;
 
index 099eabf1a8343514d244adee4dd0013da3db7728..d06d6bcf34c48f065a2cb308e686b5fa48d54087 100644 (file)
@@ -370,6 +370,27 @@ static PyObject *py_MAPIStore_setprops(PyMAPIStoreObject *self, PyObject *args)
        return PyInt_FromLong(mapistore_setprops(self->mstore_ctx, context_id, fid, object_type, &aRow));
 }
 
+static PyObject *py_MAPIStore_get_folder_count(PyMAPIStoreObject *self, PyObject *args)
+{
+       uint32_t                context_id;
+       uint64_t                fid;
+       uint32_t                folder_count;
+       enum MAPISTORE_ERROR    retval;
+
+       if (!PyArg_ParseTuple(args, "iK", &context_id, &fid)) {
+               return NULL;
+       }
+
+       retval = mapistore_get_folder_count(self->mstore_ctx, context_id, fid, &folder_count);
+
+       if (retval != MAPISTORE_SUCCESS) {
+               PyErr_SetString(PyExc_RuntimeError, mapistore_errstr(retval));
+               return NULL;
+       }
+       
+       return PyInt_FromLong(folder_count);
+}
+
 static PyObject *py_MAPIStore_errstr(PyMAPIStoreObject *self, PyObject *args)
 {
        enum MAPISTORE_ERROR    retval;
@@ -423,6 +444,7 @@ static PyMethodDef mapistore_methods[] = {
        { "mkdir", (PyCFunction)py_MAPIStore_mkdir, METH_KEYWORDS },
        { "rmdir", (PyCFunction)py_MAPIStore_rmdir, METH_VARARGS },
        { "setprops", (PyCFunction)py_MAPIStore_setprops, METH_VARARGS },
+       { "get_folder_count", (PyCFunction)py_MAPIStore_get_folder_count, METH_VARARGS },
        { "errstr", (PyCFunction)py_MAPIStore_errstr, METH_VARARGS },
        { NULL },
 };
index eecf4190aca5cc99e06c9081cb16a004605192d0..951b7edfdf87d5006eeb538c8972a39507113e3c 100755 (executable)
@@ -108,10 +108,15 @@ class TestMAPIStoreDB(unittest.TestCase):
                (inbox_context_id, inbox_fid) = self.MAPIStore.add_context(self.username, inbox_uri)
                self.assertNotEqual(inbox_context_id, 0)
                self.assertNotEqual(inbox_fid, 0)
+               num_folders = self.MAPIStore.get_folder_count(inbox_context_id, inbox_fid)
+               self.assertEqual(num_folders, 0);
+               self.MAPIStore.debuglevel = 99
                test_subfolder_fid = self.MAPIStore.mkdir(inbox_context_id, inbox_fid, "Test Folder", "This is a test folder", mapistore.FOLDER_GENERIC)
                self.assertNotEqual(test_subfolder_fid, 0)
-               # TODO: remove this 
-               self.debuglevel = 9
+               num_folders = self.MAPIStore.get_folder_count(inbox_context_id, inbox_fid)
+               self.assertEqual(num_folders, 1);
+               num_folders = self.MAPIStore.get_folder_count(inbox_context_id, test_subfolder_fid)
+               self.assertEqual(num_folders, 0);
                retval = self.MAPIStore.opendir(context_id = inbox_context_id, parent_fid = inbox_fid, fid = test_subfolder_fid)
                self.assertEqual(retval, 0)
                # TODO: add getprops support, and check return values.
@@ -131,6 +136,8 @@ class TestMAPIStoreDB(unittest.TestCase):
                self.assertEqual(retval, 0, self.MAPIStoreDB.errstr(retval))
                retval = self.MAPIStore.closedir(inbox_context_id, test_subfolder_fid)
                self.assertEqual(retval, 0, self.MAPIStoreDB.errstr(retval))
+               retval = self.MAPIStore.rmdir(inbox_context_id, inbox_fid, test_subfolder_fid, mapistore.DEL_FOLDERS)
+               self.assertEqual(retval, 0, self.MAPIStoreDB.errstr(retval))
 
        def test_errstr(self):
                self.assertEqual(self.MAPIStoreDB.errstr(0), "Success")