[evolution-kolab/ek-wip-porting: 7/8] KolabMailAccess: relax folder type checking, adapt to synchronizer API changes
- From: Christian Hilberg <chilberg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-kolab/ek-wip-porting: 7/8] KolabMailAccess: relax folder type checking, adapt to synchronizer API changes
- Date: Fri, 31 Aug 2012 16:11:19 +0000 (UTC)
commit 7c671c2209cbd6a7122a55f6529d6b1b801f24b1
Author: Christian Hilberg <hilberg kernelconcepts de>
Date: Fri Aug 31 17:47:53 2012 +0200
KolabMailAccess: relax folder type checking, adapt to synchronizer API changes
* when creating sources, we need to pass in folder type
information to make the folder creation operation
agnostic to the currently-configured folder context
and creation type
* when creating folders, we need to by-pass the existence
checks, since the new folder will not yet be listed in
the KolabMailInfoDb (work in progress)
src/libekolab/kolab-mail-access.c | 155 ++++++++++++++++++++++++++-----------
src/libekolab/kolab-mail-access.h | 1 +
2 files changed, 109 insertions(+), 47 deletions(-)
---
diff --git a/src/libekolab/kolab-mail-access.c b/src/libekolab/kolab-mail-access.c
index fa86a74..973f4a4 100644
--- a/src/libekolab/kolab-mail-access.c
+++ b/src/libekolab/kolab-mail-access.c
@@ -203,6 +203,7 @@ kolab_mail_access_class_init (KolabMailAccessClass *klass)
static gchar*
mail_access_foldername_new_from_sourcename (KolabMailAccess *self,
const gchar *sourcename,
+ gboolean check_exists,
GError **err)
{
KolabMailAccessPrivate *priv = NULL;
@@ -218,6 +219,9 @@ mail_access_foldername_new_from_sourcename (KolabMailAccess *self,
if (sourcename == NULL)
return NULL;
+ if (! check_exists)
+ goto done;
+
/* foldername may exist in KolabMailSideCache only */
exists = kolab_mail_info_db_exists_foldername (priv->infodb,
sourcename,
@@ -236,6 +240,8 @@ mail_access_foldername_new_from_sourcename (KolabMailAccess *self,
return NULL;
}
+ done:
+
return g_strdup (sourcename);
}
@@ -485,6 +491,7 @@ static gboolean
mail_access_local_store (KolabMailAccess *self,
KolabMailHandle *kmailhandle,
const gchar *foldername,
+ KolabFolderTypeID foldertype,
GCancellable *cancellable,
GError **err)
{
@@ -511,11 +518,8 @@ mail_access_local_store (KolabMailAccess *self,
priv = KOLAB_MAIL_ACCESS_PRIVATE (self);
/* check whether we should create a new folder instead of storing a handle */
- if (kmailhandle == NULL) {
- g_warning ("%s: creating new folders not yet implemented",
- __func__);
- g_assert_not_reached ();
- }
+ if (kmailhandle == NULL)
+ goto handle_skip;
/* get (and replace) local handle */
local_handle = mail_access_local_handle_get (self,
@@ -563,11 +567,15 @@ mail_access_local_store (KolabMailAccess *self,
g_propagate_error (err, tmp_err);
return FALSE;
}
+
+ handle_skip:
+
do_store = kolab_mail_synchronizer_transaction_prepare (priv->synchronizer,
priv->state->opmode,
KOLAB_MAIL_SYNCHRONIZER_TRANSACTION_TYPE_STORE,
local_handle,
foldername,
+ foldertype,
imap_summaries,
&record,
cancellable,
@@ -587,6 +595,7 @@ mail_access_local_store (KolabMailAccess *self,
KOLAB_MAIL_SYNCHRONIZER_TRANSACTION_TYPE_STORE,
local_handle,
foldername,
+ foldertype,
record,
&tmp_err);
if (! ok) {
@@ -595,6 +604,9 @@ mail_access_local_store (KolabMailAccess *self,
return FALSE;
}
+ if (kmailhandle == NULL)
+ goto offline_skip;
+
/* offline store operation (also done in online mode, serves as a
* data loss failsafe guard in case online operation fails. If online
* operation completes successfully, this item is removed from side
@@ -618,19 +630,35 @@ mail_access_local_store (KolabMailAccess *self,
}
}
+ offline_skip:
+
/* online store operation */
if (do_store && (! offline_fail) && (priv->state->opmode == KOLAB_MAIL_ACCESS_OPMODE_ONLINE)) {
- ok = kolab_mail_imap_client_store (priv->client,
- local_handle,
- foldername,
- FALSE, /* folder already updated */
- cancellable,
- &tmp_err);
- if (ok) {
- sync_opmode = KOLAB_MAIL_ACCESS_OPMODE_ONLINE;
- kolab_mail_handle_set_cache_location (local_handle,
- KOLAB_OBJECT_CACHE_LOCATION_IMAP);
+
+ if (kmailhandle != NULL) {
+ /* store PIM object */
+ ok = kolab_mail_imap_client_store (priv->client,
+ local_handle,
+ foldername,
+ FALSE, /* folder already updated */
+ cancellable,
+ &tmp_err);
+ if (ok) {
+ sync_opmode = KOLAB_MAIL_ACCESS_OPMODE_ONLINE;
+ kolab_mail_handle_set_cache_location (local_handle,
+ KOLAB_OBJECT_CACHE_LOCATION_IMAP);
+ }
} else {
+ /* create folder (online operation required) */
+ ok = kolab_mail_imap_client_create_folder (priv->client,
+ foldername,
+ foldertype,
+ cancellable,
+ &tmp_err);
+ /* TODO check whether we need to update DBs and friends */
+ }
+
+ if (tmp_err != NULL) {
g_warning ("%s online mode failure: %s",
__func__, tmp_err->message);
g_error_free (tmp_err);
@@ -641,11 +669,13 @@ mail_access_local_store (KolabMailAccess *self,
/* set handle incomplete */
/* TODO check whether this is the right place */
- summary = kolab_mail_handle_get_summary_nonconst (local_handle);
- g_assert (summary != NULL);
- kolab_mail_summary_set_bool_field (summary,
- KOLAB_MAIL_SUMMARY_BOOL_FIELD_COMPLETE,
- FALSE);
+ if (kmailhandle != NULL) {
+ summary = kolab_mail_handle_get_summary_nonconst (local_handle);
+ g_assert (summary != NULL);
+ kolab_mail_summary_set_bool_field (summary,
+ KOLAB_MAIL_SUMMARY_BOOL_FIELD_COMPLETE,
+ FALSE);
+ }
/* transaction finalization */
if (offline_fail || online_fail) {
@@ -654,6 +684,7 @@ mail_access_local_store (KolabMailAccess *self,
KOLAB_MAIL_SYNCHRONIZER_TRANSACTION_TYPE_STORE,
local_handle,
foldername,
+ foldertype,
record,
&tmp_err);
} else {
@@ -662,6 +693,7 @@ mail_access_local_store (KolabMailAccess *self,
KOLAB_MAIL_SYNCHRONIZER_TRANSACTION_TYPE_STORE,
local_handle,
foldername,
+ foldertype,
record,
&tmp_err);
}
@@ -738,40 +770,51 @@ mail_access_local_delete (KolabMailAccess *self,
g_free (foldername_del);
return FALSE;
}
+ /* TODO can we switch from full summaries table to simple UID list here ? */
+ imap_summaries = kolab_mail_imap_client_query_summaries (priv->client,
+ foldername,
+ NULL,
+ TRUE, /* update folder */
+ cancellable,
+ &tmp_err);
+ if (tmp_err != NULL) {
+ g_propagate_error (err, tmp_err);
+ return FALSE;
+ }
} else {
/* get folder location bits */
KolabFolderSummary *summary = NULL;
summary = kolab_mail_info_db_query_folder_summary (priv->infodb,
foldername,
&tmp_err);
- if (summary == NULL) {
+ if (tmp_err != NULL) {
g_propagate_error (err, tmp_err);
return FALSE;
}
+ if (summary != NULL) {
+ location =
+ kolab_folder_summary_get_uint_field (summary,
+ KOLAB_FOLDER_SUMMARY_UINT_FIELD_CACHE_LOCATION);
+ kolab_folder_summary_free (summary);
+ } else {
+ /* location bits will now not be set - we can still
+ * try server side folder delete, if the folder does
+ * not exist there, the server will tell us
+ */
+ g_warning ("%s()[%u] Got no folder summary for (%s)",
+ __func__, __LINE__, foldername);
+ }
- location = kolab_folder_summary_get_uint_field (summary,
- KOLAB_FOLDER_SUMMARY_UINT_FIELD_CACHE_LOCATION);
- kolab_folder_summary_free (summary);
foldername_del = g_strdup (foldername);
}
-
- /* TODO can we switch from full summaries table to simple UID list here ? */
- imap_summaries = kolab_mail_imap_client_query_summaries (priv->client,
- foldername,
- NULL,
- TRUE, /* need to update folder here */
- cancellable,
- &tmp_err);
- if (tmp_err != NULL) {
- g_propagate_error (err, tmp_err);
- return FALSE;
- }
+
/* delete transaction preparation */
do_del = kolab_mail_synchronizer_transaction_prepare (priv->synchronizer,
priv->state->opmode,
KOLAB_MAIL_SYNCHRONIZER_TRANSACTION_TYPE_DELETE,
kmailhandle,
foldername_del,
+ KOLAB_FOLDER_TYPE_AUTO,
imap_summaries,
&record,
cancellable,
@@ -791,6 +834,7 @@ mail_access_local_delete (KolabMailAccess *self,
KOLAB_MAIL_SYNCHRONIZER_TRANSACTION_TYPE_DELETE,
kmailhandle,
foldername_del,
+ KOLAB_FOLDER_TYPE_AUTO,
record,
&tmp_err);
if (! ok) {
@@ -879,6 +923,7 @@ mail_access_local_delete (KolabMailAccess *self,
KOLAB_MAIL_SYNCHRONIZER_TRANSACTION_TYPE_DELETE,
kmailhandle,
foldername_del,
+ KOLAB_FOLDER_TYPE_AUTO,
record,
&tmp_err);
else
@@ -887,6 +932,7 @@ mail_access_local_delete (KolabMailAccess *self,
KOLAB_MAIL_SYNCHRONIZER_TRANSACTION_TYPE_DELETE,
kmailhandle,
foldername_del,
+ KOLAB_FOLDER_TYPE_AUTO,
record,
&tmp_err);
kolab_mail_info_db_record_free (record);
@@ -1976,6 +2022,7 @@ kolab_mail_access_query_uids (KolabMailAccess *self,
foldername = mail_access_foldername_new_from_sourcename (self,
sourcename,
+ TRUE,
&tmp_err);
if (foldername == NULL)
goto exit;
@@ -2058,6 +2105,7 @@ kolab_mail_access_query_changed_uids (KolabMailAccess *self,
foldername = mail_access_foldername_new_from_sourcename (self,
sourcename,
+ TRUE,
&tmp_err);
if (tmp_err != NULL)
goto exit;
@@ -2158,6 +2206,7 @@ kolab_mail_access_get_handle (KolabMailAccess *self,
/* map Evo calendar name to Kolab folder name */
foldername = mail_access_foldername_new_from_sourcename (self,
sourcename,
+ TRUE,
&tmp_err);
if (tmp_err != NULL)
goto exit;
@@ -2311,6 +2360,7 @@ kolab_mail_access_store_handle (KolabMailAccess *self,
/* sourcename data */
sourcename_fn = mail_access_foldername_new_from_sourcename (self,
sourcename,
+ TRUE,
&tmp_err);
if (sourcename_fn == NULL)
goto exit;
@@ -2350,6 +2400,7 @@ kolab_mail_access_store_handle (KolabMailAccess *self,
ok = mail_access_local_store (self,
kmailhandle,
sourcename_fn,
+ KOLAB_FOLDER_TYPE_AUTO, /* use the preconfigured type */
cancellable,
&tmp_err);
if (! ok)
@@ -2702,6 +2753,7 @@ kolab_mail_access_delete_by_uid (KolabMailAccess *self,
foldername = mail_access_foldername_new_from_sourcename (self,
sourcename,
+ TRUE,
&tmp_err);
if (tmp_err != NULL)
goto exit;
@@ -2908,27 +2960,26 @@ kolab_mail_access_query_folder_info_online (KolabMailAccess *self,
* kolab_mail_access_create_source:
* @self: a #KolabMailAccess instance
* @sourcename: the name of the source to create
+ * @sourcetype: the Kolab type of the source to create
* @cancellable: A cancellation stack
* @err: a #GError object (or NULL)
*
- * Creates a source (address book or calendar) of the given name. A source
+ * Creates a source (email, address book or calendar) of the given name and type. A source
* needs to be created using this function prior to storing a #KolabMailHandle
* into this source. If the @sourcename supplied already exists, the function
* simply returns successfully.
*
- * If #KolabMailAccess is in online operational mode, the source gets created on
- * the Kolab server right away. If that fails or if #KolabMailAccess is in offline
- * operational mode, the source gets created in the local cache only and is
- * synchronized with the server at the next synchronization point. If the source
- * was created locally only, you can nonetheless store #KolabMailHandle objects
- * in it.
+ * #KolabMailAccess is required to be in online operational mode for this function.
+ * This is to ensure the source could actually be created on the server before storing
+ * PIM objects in it. This is to minimize chances that PIM objects are stored
+ * locally in a source for which no folder can be created on the server.
*
- * Returns: TRUE on success,
- * FALSE if offline creation failed (with @err set)
+ * Returns: TRUE on success, FALSE otherwise
*/
gboolean
kolab_mail_access_create_source (KolabMailAccess *self,
const gchar *sourcename,
+ KolabFolderTypeID sourcetype,
GCancellable *cancellable,
GError **err)
{
@@ -2946,8 +2997,14 @@ kolab_mail_access_create_source (KolabMailAccess *self,
g_mutex_lock (&(priv->big_lock));
- if (priv->state->opmode <= KOLAB_MAIL_ACCESS_OPMODE_CONFIGURED)
+ if (priv->state->opmode <= KOLAB_MAIL_ACCESS_OPMODE_OFFLINE) {
+ g_set_error (&tmp_err,
+ KOLAB_BACKEND_ERROR,
+ KOLAB_BACKEND_ERROR_STATE_WRONG_FOR_OP,
+ _("You must be working online to complete this operation"));
+ ok = FALSE;
goto exit;
+ }
/* check whether folder exists */
exists = kolab_mail_info_db_exists_foldername (priv->infodb,
@@ -2965,6 +3022,7 @@ kolab_mail_access_create_source (KolabMailAccess *self,
ok = mail_access_local_store (self,
NULL,
sourcename,
+ sourcetype,
cancellable,
&tmp_err);
exit:
@@ -3013,7 +3071,7 @@ kolab_mail_access_delete_source (KolabMailAccess *self,
GError **err)
{
KolabMailAccessPrivate *priv = NULL;
- gboolean exists = FALSE;
+ /* gboolean exists = FALSE; */
gboolean ok = TRUE;
GError *tmp_err = NULL;
@@ -3028,6 +3086,7 @@ kolab_mail_access_delete_source (KolabMailAccess *self,
if (priv->state->opmode <= KOLAB_MAIL_ACCESS_OPMODE_CONFIGURED)
goto exit;
+#if 0
/* check whether folder exists */
exists = kolab_mail_info_db_exists_foldername (priv->infodb,
@@ -3040,6 +3099,7 @@ kolab_mail_access_delete_source (KolabMailAccess *self,
if (! exists)
goto exit;
+#endif
/* delete folder */
ok = mail_access_local_delete (self,
@@ -3186,6 +3246,7 @@ kolab_mail_access_synchronize (KolabMailAccess *self,
/* foldername will be NULL if sourcename is NULL */
foldername = mail_access_foldername_new_from_sourcename (self,
sourcename,
+ TRUE,
&tmp_err);
if (tmp_err != NULL) {
ok = FALSE;
diff --git a/src/libekolab/kolab-mail-access.h b/src/libekolab/kolab-mail-access.h
index 49b7382..163d399 100644
--- a/src/libekolab/kolab-mail-access.h
+++ b/src/libekolab/kolab-mail-access.h
@@ -177,6 +177,7 @@ kolab_mail_access_query_folder_info_online (KolabMailAccess *self,
gboolean
kolab_mail_access_create_source (KolabMailAccess *self,
const gchar *sourcename,
+ KolabFolderTypeID sourcetype,
GCancellable *cancellable,
GError **err);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]