}
static gint
-read_uids_callback (gpointer ref,
+read_uids_callback (gpointer ref_array,
gint ncol,
gchar **cols,
gchar **name)
{
- GPtrArray *array = (GPtrArray *) ref;
+ GPtrArray *array = ref_array;
- #if 0
- gint i;
- for (i = 0; i < ncol; ++i) {
- if (!name[i] || !cols[i])
- continue;
+ g_return_val_if_fail (ncol == 1, 0);
- if (!strcmp (name [i], "uid"))
- g_ptr_array_add (array, (gchar *) (camel_pstring_strdup (cols[i])));
- }
- #else
- if (cols[0])
- g_ptr_array_add (array, (gchar *) (camel_pstring_strdup (cols[0])));
- #endif
+ if (cols[0])
+ g_ptr_array_add (array, (gchar *) (camel_pstring_strdup (cols[0])));
- return 0;
+ return 0;
+}
+
+static gint
+read_uids_to_hash_callback (gpointer ref_hash,
+ gint ncol,
+ gchar **cols,
+ gchar **name)
+{
+ GHashTable *hash = ref_hash;
+
+ g_return_val_if_fail (ncol == 2, 0);
+
+ if (cols[0])
+ g_hash_table_insert (hash, (gchar *) camel_pstring_strdup (cols[0]), GUINT_TO_POINTER (cols[1] ? strtoul (cols[1], NULL, 10) : 0));
+
+ return 0;
}
/**
* camel_db_get_folder_uids:
*
+ * Fills hash with uid->GUINT_TO_POINTER (flag)
+ *
* Since: 2.24
**/
gint
const gchar *folder_name,
const gchar *sort_by,
const gchar *collate,
- GPtrArray *array,
+ GHashTable *hash,
GError **error)
{
gchar *sel_query;
gint ret;
- sel_query = sqlite3_mprintf("SELECT uid FROM %Q%s%s%s%s", folder_name, sort_by ? " order by " : "", sort_by ? sort_by: "", (sort_by && collate) ? " collate " : "", (sort_by && collate) ? collate : "");
+ sel_query = sqlite3_mprintf("SELECT uid,flags FROM %Q%s%s%s%s", folder_name, sort_by ? " order by " : "", sort_by ? sort_by: "", (sort_by && collate) ? " collate " : "", (sort_by && collate) ? collate : "");
- ret = camel_db_select (db, sel_query, read_uids_callback, array, error);
+ ret = camel_db_select (db, sel_query, read_uids_to_hash_callback, hash, error);
sqlite3_free (sel_query);
return ret;
return array;
}
+struct ReadPreviewData
+{
+ GHashTable *columns_hash;
+ GHashTable *hash;
+};
+
static gint
read_preview_callback (gpointer ref,
gint ncol,
gchar **cols,
gchar **name)
{
- GHashTable *hash = (GHashTable *) ref;
+ struct ReadPreviewData *rpd = ref;
const gchar *uid = NULL;
gchar *msg = NULL;
gint i;
if (!name[i] || !cols[i])
continue;
- if (!strcmp (name [i], "uid"))
- uid = camel_pstring_strdup (cols[i]);
- else if (!strcmp (name [i], "preview"))
- msg = g_strdup (cols[i]);
+ switch (camel_db_get_column_ident (&rpd->columns_hash, i, ncol, name)) {
+ case CAMEL_DB_COLUMN_UID:
+ uid = camel_pstring_strdup (cols[i]);
+ break;
+ case CAMEL_DB_COLUMN_PREVIEW:
+ msg = g_strdup (cols[i]);
+ break;
+ default:
+ g_warn_if_reached ();
+ break;
+ }
}
- g_hash_table_insert (hash, (gchar *) uid, msg);
+ g_hash_table_insert (rpd->hash, (gchar *) uid, msg);
return 0;
}
const gchar *folder_name,
GError **error)
{
- gchar *sel_query;
- gint ret;
- GHashTable *hash = g_hash_table_new (g_str_hash, g_str_equal);
+ gchar *sel_query;
+ gint ret;
+ struct ReadPreviewData rpd;
+ GHashTable *hash = g_hash_table_new (g_str_hash, g_str_equal);
- sel_query = sqlite3_mprintf("SELECT uid, preview FROM '%q_preview'", folder_name);
+ sel_query = sqlite3_mprintf ("SELECT uid, preview FROM '%q_preview'", folder_name);
- ret = camel_db_select (db, sel_query, read_preview_callback, hash, error);
- sqlite3_free (sel_query);
+ rpd.columns_hash = NULL;
+ rpd.hash = hash;
- if (!g_hash_table_size (hash) || ret != 0) {
- g_hash_table_destroy (hash);
- hash = NULL;
- }
+ ret = camel_db_select (db, sel_query, read_preview_callback, &rpd, error);
+ sqlite3_free (sel_query);
+
+ if (rpd.columns_hash)
+ g_hash_table_destroy (rpd.columns_hash);
- return hash;
+ if (!g_hash_table_size (hash) || ret != 0) {
+ g_hash_table_destroy (hash);
+ hash = NULL;
+ }
+
+ return hash;
}
/**
{
GPtrArray *array = (GPtrArray *) ref;
- #if 0
- gint i;
-
- for (i = 0; i < ncol; ++i) {
- if (!name[i] || !cols[i] || strlen (cols[i]) <= 8)
- continue;
-
- if (!strcmp (name [i], "vuid"))
- g_ptr_array_add (array, (gchar *) (camel_pstring_strdup (cols[i]+8)));
- }
- #else
- if (cols[0] && strlen (cols[0]) > 8)
- g_ptr_array_add (array, (gchar *) (camel_pstring_strdup (cols[0]+8)));
- #endif
+ if (cols[0] && strlen (cols[0]) > 8)
+ g_ptr_array_add (array, (gchar *) (camel_pstring_strdup (cols[0]+8)));
return 0;
}
return ret;
}
+struct ReadFirData
+{
+ GHashTable *columns_hash;
+ CamelFIRecord *record;
+};
+
static gint
read_fir_callback (gpointer ref,
gint ncol,
gchar **cols,
gchar **name)
{
- CamelFIRecord *record = *(CamelFIRecord **) ref;
+ struct ReadFirData *rfd = ref;
gint i;
d(g_print ("\nread_fir_callback called \n"));
if (!name[i] || !cols[i])
continue;
- if (!strcmp (name [i], "folder_name"))
- record->folder_name = g_strdup (cols[i]);
-
- else if (!strcmp (name [i], "version"))
- record->version = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
-
- else if (!strcmp (name [i], "flags"))
- record->flags = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
-
- else if (!strcmp (name [i], "nextuid"))
- record->nextuid = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
-
- else if (!strcmp (name [i], "time"))
- record->time = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
-
- else if (!strcmp (name [i], "saved_count"))
- record->saved_count = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
-
- else if (!strcmp (name [i], "unread_count"))
- record->unread_count = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
-
- else if (!strcmp (name [i], "deleted_count"))
- record->deleted_count = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
-
- else if (!strcmp (name [i], "junk_count"))
- record->junk_count = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
- else if (!strcmp (name [i], "visible_count"))
- record->visible_count = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
- else if (!strcmp (name [i], "jnd_count"))
- record->jnd_count = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
- else if (!strcmp (name [i], "bdata"))
- record->bdata = g_strdup (cols[i]);
-
+ switch (camel_db_get_column_ident (&rfd->columns_hash, i, ncol, name)) {
+ case CAMEL_DB_COLUMN_FOLDER_NAME:
+ rfd->record->folder_name = g_strdup (cols[i]);
+ break;
+ case CAMEL_DB_COLUMN_VERSION:
+ rfd->record->version = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+ break;
+ case CAMEL_DB_COLUMN_FLAGS:
+ rfd->record->flags = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+ break;
+ case CAMEL_DB_COLUMN_NEXTUID:
+ rfd->record->nextuid = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+ break;
+ case CAMEL_DB_COLUMN_TIME:
+ rfd->record->time = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+ break;
+ case CAMEL_DB_COLUMN_SAVED_COUNT:
+ rfd->record->saved_count = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+ break;
+ case CAMEL_DB_COLUMN_UNREAD_COUNT:
+ rfd->record->unread_count = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+ break;
+ case CAMEL_DB_COLUMN_DELETED_COUNT:
+ rfd->record->deleted_count = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+ break;
+ case CAMEL_DB_COLUMN_JUNK_COUNT:
+ rfd->record->junk_count = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+ break;
+ case CAMEL_DB_COLUMN_VISIBLE_COUNT:
+ rfd->record->visible_count = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+ break;
+ case CAMEL_DB_COLUMN_JND_COUNT:
+ rfd->record->jnd_count = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+ break;
+ case CAMEL_DB_COLUMN_BDATA:
+ rfd->record->bdata = g_strdup (cols[i]);
+ break;
+ default:
+ g_warn_if_reached ();
+ break;
+ }
}
return 0;
gint
camel_db_read_folder_info_record (CamelDB *cdb,
const gchar *folder_name,
- CamelFIRecord **record,
+ CamelFIRecord *record,
GError **error)
{
+ struct ReadFirData rfd;
gchar *query;
gint ret;
- query = sqlite3_mprintf ("SELECT * FROM folders WHERE folder_name = %Q", folder_name);
- ret = camel_db_select (cdb, query, read_fir_callback, record, error);
+ rfd.columns_hash = NULL;
+ rfd.record = record;
+ query = sqlite3_mprintf ("SELECT * FROM folders WHERE folder_name = %Q", folder_name);
+ ret = camel_db_select (cdb, query, read_fir_callback, &rfd, error);
sqlite3_free (query);
- return (ret);
+
+ if (rfd.columns_hash)
+ g_hash_table_destroy (rfd.columns_hash);
+
+ return ret;
}
/**
return ret;
}
+
+static struct _known_column_names {
+ const gchar *name;
+ CamelDBKnownColumnNames ident;
+} known_column_names[] = {
+ { "attachment", CAMEL_DB_COLUMN_ATTACHMENT },
+ { "bdata", CAMEL_DB_COLUMN_BDATA },
+ { "bodystructure", CAMEL_DB_COLUMN_BODYSTRUCTURE },
+ { "cinfo", CAMEL_DB_COLUMN_CINFO },
+ { "deleted", CAMEL_DB_COLUMN_DELETED },
+ { "deleted_count", CAMEL_DB_COLUMN_DELETED_COUNT },
+ { "dreceived", CAMEL_DB_COLUMN_DRECEIVED },
+ { "dsent", CAMEL_DB_COLUMN_DSENT },
+ { "flags", CAMEL_DB_COLUMN_FLAGS },
+ { "folder_name", CAMEL_DB_COLUMN_FOLDER_NAME },
+ { "followup_completed_on", CAMEL_DB_COLUMN_FOLLOWUP_COMPLETED_ON },
+ { "followup_due_by", CAMEL_DB_COLUMN_FOLLOWUP_DUE_BY },
+ { "followup_flag", CAMEL_DB_COLUMN_FOLLOWUP_FLAG },
+ { "important", CAMEL_DB_COLUMN_IMPORTANT },
+ { "jnd_count", CAMEL_DB_COLUMN_JND_COUNT },
+ { "junk", CAMEL_DB_COLUMN_JUNK },
+ { "junk_count", CAMEL_DB_COLUMN_JUNK_COUNT },
+ { "labels", CAMEL_DB_COLUMN_LABELS },
+ { "mail_cc", CAMEL_DB_COLUMN_MAIL_CC },
+ { "mail_from", CAMEL_DB_COLUMN_MAIL_FROM },
+ { "mail_to", CAMEL_DB_COLUMN_MAIL_TO },
+ { "mlist", CAMEL_DB_COLUMN_MLIST },
+ { "nextuid", CAMEL_DB_COLUMN_NEXTUID },
+ { "part", CAMEL_DB_COLUMN_PART },
+ { "preview", CAMEL_DB_COLUMN_PREVIEW },
+ { "read", CAMEL_DB_COLUMN_READ },
+ { "replied", CAMEL_DB_COLUMN_REPLIED },
+ { "saved_count", CAMEL_DB_COLUMN_SAVED_COUNT },
+ { "size", CAMEL_DB_COLUMN_SIZE },
+ { "subject", CAMEL_DB_COLUMN_SUBJECT },
+ { "time", CAMEL_DB_COLUMN_TIME },
+ { "uid", CAMEL_DB_COLUMN_UID },
+ { "unread_count", CAMEL_DB_COLUMN_UNREAD_COUNT },
+ { "usertags", CAMEL_DB_COLUMN_USERTAGS },
+ { "version", CAMEL_DB_COLUMN_VERSION },
+ { "visible_count", CAMEL_DB_COLUMN_VISIBLE_COUNT },
+ { "vuid", CAMEL_DB_COLUMN_VUID }
+};
+
+/**
+ * camel_db_get_column_ident:
+ * Traverses column name from index @index into an enum #CamelDBKnownColumnNames value;
+ * The @col_names contains @ncols columns. First time this is called is created
+ * the @hash from col_names indexes into the enum, and this is reused for every other call.
+ * The function expects that column names are returned always in the same order.
+ * When all rows are read the @hash table can be freed with g_hash_table_destroy().
+ **/
+CamelDBKnownColumnNames
+camel_db_get_column_ident (GHashTable **hash, gint index, gint ncols, gchar **col_names)
+{
+ gpointer value = NULL;
+
+ g_return_val_if_fail (hash != NULL, CAMEL_DB_COLUMN_UNKNOWN);
+ g_return_val_if_fail (col_names != NULL, CAMEL_DB_COLUMN_UNKNOWN);
+ g_return_val_if_fail (ncols > 0, CAMEL_DB_COLUMN_UNKNOWN);
+ g_return_val_if_fail (index >= 0, CAMEL_DB_COLUMN_UNKNOWN);
+ g_return_val_if_fail (index < ncols, CAMEL_DB_COLUMN_UNKNOWN);
+
+ if (!*hash) {
+ gint ii, jj, from, max = G_N_ELEMENTS (known_column_names);
+
+ *hash = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+ for (ii = 0, jj = 0; ii < ncols; ii++) {
+ const gchar *name = col_names[ii];
+ gboolean first = TRUE;
+
+ if (!name)
+ continue;
+
+ for (from = jj; first || jj != from; jj = (jj + 1) % max, first = FALSE) {
+ if (g_str_equal (name, known_column_names[jj].name)) {
+ g_hash_table_insert (*hash, GINT_TO_POINTER (ii), GINT_TO_POINTER (known_column_names[jj].ident));
+ break;
+ }
+ }
+
+ if (from == jj && !first)
+ g_warning ("%s: missing column name '%s' in a list of known columns", G_STRFUNC, name);
+ }
+ }
+
+ g_return_val_if_fail (g_hash_table_lookup_extended (*hash, GINT_TO_POINTER (index), NULL, &value), CAMEL_DB_COLUMN_UNKNOWN);
+
+ return GPOINTER_TO_INT (value);
+}
typedef struct _CamelDB CamelDB;
+typedef enum {
+ CAMEL_DB_COLUMN_UNKNOWN = -1,
+ CAMEL_DB_COLUMN_ATTACHMENT,
+ CAMEL_DB_COLUMN_BDATA,
+ CAMEL_DB_COLUMN_BODYSTRUCTURE,
+ CAMEL_DB_COLUMN_CINFO,
+ CAMEL_DB_COLUMN_DELETED,
+ CAMEL_DB_COLUMN_DELETED_COUNT,
+ CAMEL_DB_COLUMN_DRECEIVED,
+ CAMEL_DB_COLUMN_DSENT,
+ CAMEL_DB_COLUMN_FLAGS,
+ CAMEL_DB_COLUMN_FOLDER_NAME,
+ CAMEL_DB_COLUMN_FOLLOWUP_COMPLETED_ON,
+ CAMEL_DB_COLUMN_FOLLOWUP_DUE_BY,
+ CAMEL_DB_COLUMN_FOLLOWUP_FLAG,
+ CAMEL_DB_COLUMN_IMPORTANT,
+ CAMEL_DB_COLUMN_JND_COUNT,
+ CAMEL_DB_COLUMN_JUNK,
+ CAMEL_DB_COLUMN_JUNK_COUNT,
+ CAMEL_DB_COLUMN_LABELS,
+ CAMEL_DB_COLUMN_MAIL_CC,
+ CAMEL_DB_COLUMN_MAIL_FROM,
+ CAMEL_DB_COLUMN_MAIL_TO,
+ CAMEL_DB_COLUMN_MLIST,
+ CAMEL_DB_COLUMN_NEXTUID,
+ CAMEL_DB_COLUMN_PART,
+ CAMEL_DB_COLUMN_PREVIEW,
+ CAMEL_DB_COLUMN_READ,
+ CAMEL_DB_COLUMN_REPLIED,
+ CAMEL_DB_COLUMN_SAVED_COUNT,
+ CAMEL_DB_COLUMN_SIZE,
+ CAMEL_DB_COLUMN_SUBJECT,
+ CAMEL_DB_COLUMN_TIME,
+ CAMEL_DB_COLUMN_UID,
+ CAMEL_DB_COLUMN_UNREAD_COUNT,
+ CAMEL_DB_COLUMN_USERTAGS,
+ CAMEL_DB_COLUMN_VERSION,
+ CAMEL_DB_COLUMN_VISIBLE_COUNT,
+ CAMEL_DB_COLUMN_VUID
+} CamelDBKnownColumnNames;
+
+CamelDBKnownColumnNames camel_db_get_column_ident (GHashTable **hash, gint index, gint ncols, gchar **col_names);
+
/**
* CamelDBSelectCB:
*
gint camel_db_select (CamelDB *cdb, const gchar * stmt, CamelDBSelectCB callback, gpointer data, GError **error);
gint camel_db_write_folder_info_record (CamelDB *cdb, CamelFIRecord *record, GError **error);
-gint camel_db_read_folder_info_record (CamelDB *cdb, const gchar *folder_name, CamelFIRecord **record, GError **error);
+gint camel_db_read_folder_info_record (CamelDB *cdb, const gchar *folder_name, CamelFIRecord *record, GError **error);
gint camel_db_prepare_message_info_table (CamelDB *cdb, const gchar *folder_name, GError **error);
gint camel_db_add_to_vfolder (CamelDB *db, gchar *folder_name, gchar *vuid, GError **error);
gint camel_db_add_to_vfolder_transaction (CamelDB *db, const gchar *folder_name, const gchar *vuid, GError **error);
-gint camel_db_get_folder_uids (CamelDB *db, const gchar *folder_name, const gchar *sort_by, const gchar *collate, GPtrArray *array, GError **error);
+gint camel_db_get_folder_uids (CamelDB *db, const gchar *folder_name, const gchar *sort_by, const gchar *collate, GHashTable *hash, GError **error);
GPtrArray * camel_db_get_folder_junk_uids (CamelDB *db, gchar *folder_name, GError **error);
GPtrArray * camel_db_get_folder_deleted_uids (CamelDB *db, const gchar *folder_name, GError **error);
gint
camel_db_reset_folder_version (CamelDB *cdb, const gchar *folder_name, gint reset_version, GError **error);
-#endif
+#endif
{
GPtrArray *uids;
gint i;
- guint count;
CamelMessageInfo *info;
gboolean success;
+ GPtrArray *known_uids;
uids = g_ptr_array_new ();
camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
- count = camel_folder_summary_count (folder->summary);
- for (i = 0; i < count; i++) {
- info = camel_folder_summary_index (folder->summary, i);
+ known_uids = camel_folder_summary_get_array (folder->summary);
+ for (i = 0; known_uids && i < known_uids->len; i++) {
+ const gchar *uid = g_ptr_array_index (known_uids, i);
+
+ info = camel_folder_summary_get (folder->summary, uid);
if (camel_message_info_flags (info) & CAMEL_MESSAGE_DELETED)
- g_ptr_array_add (uids, g_strdup (camel_message_info_uid (info)));
+ g_ptr_array_add (uids, (gpointer) uid);
camel_message_info_free (info);
}
success = disco_expunge_uids (folder, uids, cancellable, error);
- for (i = 0; i < uids->len; i++)
- g_free (uids->pdata[i]);
g_ptr_array_free (uids, TRUE);
+ if (known_uids)
+ camel_folder_summary_free_array (known_uids);
return success;
}
for (i = 0; i < v->len; i++) {
const gchar *uid;
- search->current = camel_folder_summary_uid (search->folder->summary, v->pdata[i]);
+ search->current = camel_folder_summary_get (search->folder->summary, v->pdata[i]);
if (!search->current)
continue;
uid = camel_message_info_uid (search->current);
gboolean need_preview;
GHashTable *preview_updates;
+
+ guint32 nextuid; /* next uid? */
+ guint32 saved_count; /* how many were saved/loaded */
+ guint32 unread_count; /* handy totals */
+ guint32 deleted_count;
+ guint32 junk_count;
+ guint32 junk_not_deleted_count;
+ guint32 visible_count;
+
+ gchar *summary_path;
+ gboolean build_content; /* do we try and parse/index the content, or not? */
+
+ GHashTable *uids; /* uids of all known message infos; the 'value' are used flags for the message info */
+ GHashTable *loaded_infos; /* uid->CamelMessageInfo*, those currently in memory */
+
+ struct _CamelFolder *folder; /* parent folder, for events */
+ time_t cache_load_time;
+ guint timeout_handle;
};
static GStaticMutex info_lock = G_STATIC_MUTEX_INIT;
#define CAMEL_FOLDER_SUMMARY_VERSION (14)
-#define META_SUMMARY_SUFFIX_LEN 5 /* strlen("-meta") */
-
/* trivial lists, just because ... */
struct _node {
struct _node *next;
static CamelMessageInfo * message_info_from_uid (CamelFolderSummary *s, const gchar *uid);
+enum {
+ PROP_0,
+ PROP_FOLDER,
+ PROP_SAVED_COUNT,
+ PROP_UNREAD_COUNT,
+ PROP_DELETED_COUNT,
+ PROP_JUNK_COUNT,
+ PROP_JUNK_NOT_DELETED_COUNT,
+ PROP_VISIBLE_COUNT,
+ PROP_BUILD_CONTENT,
+ PROP_NEED_PREVIEW
+};
+
G_DEFINE_TYPE (CamelFolderSummary, camel_folder_summary, CAMEL_TYPE_OBJECT)
static void
folder_summary_finalize (GObject *object)
{
CamelFolderSummary *summary = CAMEL_FOLDER_SUMMARY (object);
+ CamelFolderSummaryPrivate *priv = summary->priv;
- if (summary->timeout_handle)
- g_source_remove (summary->timeout_handle);
- /*camel_folder_summary_clear(s);*/
- g_ptr_array_foreach (summary->uids, (GFunc) camel_pstring_free, NULL);
- g_ptr_array_free (summary->uids, TRUE);
- g_hash_table_destroy (summary->loaded_infos);
+ if (priv->timeout_handle)
+ g_source_remove (priv->timeout_handle);
- g_hash_table_foreach (summary->priv->filter_charset, free_o_name, NULL);
- g_hash_table_destroy (summary->priv->filter_charset);
+ g_hash_table_destroy (priv->uids);
+ g_hash_table_destroy (priv->loaded_infos);
- g_hash_table_destroy (summary->priv->preview_updates);
+ g_hash_table_foreach (priv->filter_charset, free_o_name, NULL);
+ g_hash_table_destroy (priv->filter_charset);
- g_free (summary->summary_path);
+ g_hash_table_destroy (priv->preview_updates);
- /* Freeing memory occupied by meta-summary-header */
- g_free (summary->meta_summary->path);
- g_free (summary->meta_summary);
+ g_free (priv->summary_path);
- g_static_rec_mutex_free (&summary->priv->summary_lock);
- g_static_rec_mutex_free (&summary->priv->io_lock);
- g_static_rec_mutex_free (&summary->priv->filter_lock);
- g_static_rec_mutex_free (&summary->priv->alloc_lock);
- g_static_rec_mutex_free (&summary->priv->ref_lock);
+ g_static_rec_mutex_free (&priv->summary_lock);
+ g_static_rec_mutex_free (&priv->io_lock);
+ g_static_rec_mutex_free (&priv->filter_lock);
+ g_static_rec_mutex_free (&priv->alloc_lock);
+ g_static_rec_mutex_free (&priv->ref_lock);
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (camel_folder_summary_parent_class)->finalize (object);
}
-static gint
+static void
+folder_summary_set_folder (CamelFolderSummary *summary, CamelFolder *folder)
+{
+ g_return_if_fail (summary != NULL);
+ g_return_if_fail (summary->priv != NULL);
+ g_return_if_fail (summary->priv->folder == NULL);
+ /* folder can be NULL in certain cases, see maildir-store */
+
+ summary->priv->folder = folder;
+}
+
+static void
+folder_summary_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_FOLDER:
+ folder_summary_set_folder (
+ CAMEL_FOLDER_SUMMARY (object),
+ CAMEL_FOLDER (g_value_get_object (value)));
+ return;
+
+ case PROP_BUILD_CONTENT:
+ camel_folder_summary_set_build_content (
+ CAMEL_FOLDER_SUMMARY (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_NEED_PREVIEW:
+ camel_folder_summary_set_need_preview (
+ CAMEL_FOLDER_SUMMARY (object),
+ g_value_get_boolean (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+folder_summary_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_FOLDER:
+ g_value_set_object (
+ value, camel_folder_summary_get_folder (
+ CAMEL_FOLDER_SUMMARY (object)));
+ return;
+
+ case PROP_SAVED_COUNT:
+ g_value_set_uint (
+ value, camel_folder_summary_get_saved_count (
+ CAMEL_FOLDER_SUMMARY (object)));
+ return;
+
+ case PROP_UNREAD_COUNT:
+ g_value_set_uint (
+ value, camel_folder_summary_get_unread_count (
+ CAMEL_FOLDER_SUMMARY (object)));
+ return;
+
+ case PROP_DELETED_COUNT:
+ g_value_set_uint (
+ value, camel_folder_summary_get_deleted_count (
+ CAMEL_FOLDER_SUMMARY (object)));
+ return;
+
+ case PROP_JUNK_COUNT:
+ g_value_set_uint (
+ value, camel_folder_summary_get_junk_count (
+ CAMEL_FOLDER_SUMMARY (object)));
+ return;
+
+ case PROP_JUNK_NOT_DELETED_COUNT:
+ g_value_set_uint (
+ value, camel_folder_summary_get_junk_not_deleted_count (
+ CAMEL_FOLDER_SUMMARY (object)));
+ return;
+
+ case PROP_VISIBLE_COUNT:
+ g_value_set_uint (
+ value, camel_folder_summary_get_visible_count (
+ CAMEL_FOLDER_SUMMARY (object)));
+ return;
+
+ case PROP_BUILD_CONTENT:
+ g_value_set_boolean (
+ value, camel_folder_summary_get_build_content (
+ CAMEL_FOLDER_SUMMARY (object)));
+ return;
+
+ case PROP_NEED_PREVIEW:
+ g_value_set_boolean (
+ value, camel_folder_summary_get_need_preview (
+ CAMEL_FOLDER_SUMMARY (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+/**
+ * folder_summary_update_counts_by_flags:
+ *
+ * Since: 3.0
+ **/
+static void
+folder_summary_update_counts_by_flags (CamelFolderSummary *summary,
+ guint32 flags,
+ gboolean subtract)
+{
+ gint unread = 0, deleted = 0, junk = 0;
+ gboolean is_junk_folder = FALSE, is_trash_folder = FALSE;
+ GObject *summary_object;
+
+ g_return_if_fail (summary != NULL);
+ g_return_if_fail (summary->priv != NULL);
+
+ summary_object = G_OBJECT (summary);
+
+ if (summary->priv->folder && CAMEL_IS_VTRASH_FOLDER (summary->priv->folder)) {
+ CamelVTrashFolder *vtrash = CAMEL_VTRASH_FOLDER (summary->priv->folder);
+
+ is_junk_folder = vtrash && vtrash->type == CAMEL_VTRASH_FOLDER_JUNK;
+ is_trash_folder = vtrash && vtrash->type == CAMEL_VTRASH_FOLDER_TRASH;
+ }
+
+ if (!(flags & CAMEL_MESSAGE_SEEN))
+ unread = subtract ? -1 : 1;
+
+ if (flags & CAMEL_MESSAGE_DELETED)
+ deleted = subtract ? -1 : 1;
+
+ if (flags & CAMEL_MESSAGE_JUNK)
+ junk = subtract ? -1 : 1;
+
+ dd(printf("%p: %d %d %d | %d %d %d \n", (gpointer) summary, unread, deleted, junk, summary->priv->unread_count, summary->priv->visible_count, summary->priv->saved_count));
+
+ g_object_freeze_notify (summary_object);
+
+ if (deleted) {
+ summary->priv->deleted_count += deleted;
+ g_object_notify (summary_object, "deleted-count");
+ }
+
+ if (junk) {
+ summary->priv->junk_count += junk;
+ g_object_notify (summary_object, "junk-count");
+ }
+
+ if (junk && !deleted) {
+ summary->priv->junk_not_deleted_count += junk;
+ g_object_notify (summary_object, "junk-not-deleted-count");
+ }
+
+ if (!junk && !deleted) {
+ summary->priv->visible_count += subtract ? -1 : 1;
+ g_object_notify (summary_object, "visible-count");
+ }
+
+ if (junk && !is_junk_folder)
+ unread = 0;
+ if (deleted && !is_trash_folder)
+ unread = 0;
+
+ if (unread) {
+ summary->priv->unread_count += unread;
+ g_object_notify (summary_object, "unread-count");
+ }
+
+ summary->priv->saved_count += subtract ? -1 : 1;
+ g_object_notify (summary_object, "saved-count");
+
+ camel_folder_summary_touch (summary);
+
+ g_object_thaw_notify (summary_object);
+
+ dd(printf("%p: %d %d %d | %d %d %d\n", (gpointer) summary, unread, deleted, junk, summary->priv->unread_count, summary->priv->visible_count, summary->priv->saved_count));
+}
+
+static gboolean
summary_header_from_db (CamelFolderSummary *s,
CamelFIRecord *record)
{
if ((s->version > 0xff) && (s->version & 0xff) < 12) {
io(printf ("Summary header version mismatch"));
errno = EINVAL;
- return -1;
+ return FALSE;
}
if (!(s->version < 0x100 && s->version >= 13))
#endif
s->flags = record->flags;
- s->nextuid = record->nextuid;
+ s->priv->nextuid = record->nextuid;
s->time = record->time;
- s->saved_count = record->saved_count;
+ s->priv->saved_count = record->saved_count;
- s->unread_count = record->unread_count;
- s->deleted_count = record->deleted_count;
- s->junk_count = record->junk_count;
- s->visible_count = record->visible_count;
- s->junk_not_deleted_count = record->jnd_count;
+ s->priv->unread_count = record->unread_count;
+ s->priv->deleted_count = record->deleted_count;
+ s->priv->junk_count = record->junk_count;
+ s->priv->visible_count = record->visible_count;
+ s->priv->junk_not_deleted_count = record->jnd_count;
- return 0;
+ return TRUE;
}
static CamelFIRecord *
/* Though we are going to read, we do this during write,
* so lets use it that way. */
- table_name = camel_folder_get_full_name (s->folder);
- parent_store = camel_folder_get_parent_store (s->folder);
+ table_name = camel_folder_get_full_name (s->priv->folder);
+ parent_store = camel_folder_get_parent_store (s->priv->folder);
db = parent_store->cdb_w;
io(printf("Savining header to db\n"));
/* we always write out the current version */
record->version = CAMEL_FOLDER_SUMMARY_VERSION;
record->flags = s->flags;
- record->nextuid = s->nextuid;
+ record->nextuid = s->priv->nextuid;
record->time = s->time;
/* FIXME: Ever heard of Constructors and initializing ? */
if (camel_db_count_junk_not_deleted_message_info (db, table_name, &(record->jnd_count), NULL))
record->jnd_count = 0;
- s->unread_count = record->unread_count;
- s->deleted_count = record->deleted_count;
- s->junk_count = record->junk_count;
- s->visible_count = record->visible_count;
- s->junk_not_deleted_count = record->jnd_count;
+ s->priv->unread_count = record->unread_count;
+ s->priv->deleted_count = record->deleted_count;
+ s->priv->junk_count = record->junk_count;
+ s->priv->visible_count = record->visible_count;
+ s->priv->junk_not_deleted_count = record->jnd_count;
return record;
}
return ci;
}
-static gint
+static gboolean
content_info_to_db (CamelFolderSummary *s,
CamelMessageContentInfo *ci,
CamelMIRecord *record)
g_string_free (str, FALSE);
}
- return 0;
+ return TRUE;
}
static gint
summary_header_save (CamelFolderSummary *s,
FILE *out)
{
- gint unread = 0, deleted = 0, junk = 0, count, i;
+ gint unread = 0, deleted = 0, junk = 0, i;
+ GPtrArray *known_uids;
fseek (out, 0, SEEK_SET);
/* we always write out the current version */
camel_file_util_encode_fixed_int32 (out, CAMEL_FOLDER_SUMMARY_VERSION);
camel_file_util_encode_fixed_int32 (out, s->flags);
- camel_file_util_encode_fixed_int32 (out, s->nextuid);
+ camel_file_util_encode_fixed_int32 (out, s->priv->nextuid);
camel_file_util_encode_time_t (out, s->time);
- count = camel_folder_summary_count (s);
- for (i = 0; i < count; i++) {
- CamelMessageInfo *info = camel_folder_summary_index (s, i);
+ known_uids = camel_folder_summary_get_array (s);
+ for (i = 0; known_uids && i < known_uids->len; i++) {
+ CamelMessageInfo *info = camel_folder_summary_get (s, g_ptr_array_index (known_uids, i));
guint32 flags;
if (info == NULL)
camel_message_info_free (info);
}
- camel_file_util_encode_fixed_int32 (out, count);
+ camel_folder_summary_free_array (known_uids);
+
+ camel_file_util_encode_fixed_int32 (out, i); /* total count */
camel_file_util_encode_fixed_int32 (out, unread);
camel_file_util_encode_fixed_int32 (out, deleted);
return camel_file_util_encode_fixed_int32 (out, junk);
}
+static gboolean
+folder_summary_replace_flags (CamelFolderSummary *summary, CamelMessageInfo *info)
+{
+ guint32 used_flags;
+ GObject *summary_object;
+ guint32 old_saved_count, old_unread_count, old_deleted_count, old_junk_count;
+ guint32 old_junk_not_deleted_count, old_visible_count;
+
+ g_return_val_if_fail (summary != NULL, FALSE);
+ g_return_val_if_fail (summary->priv != NULL, FALSE);
+ g_return_val_if_fail (info != NULL, FALSE);
+
+ if (!camel_message_info_uid (info) ||
+ !camel_folder_summary_check_uid (summary, camel_message_info_uid (info)))
+ return FALSE;
+
+ summary_object = G_OBJECT (summary);
+
+ camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+ g_object_freeze_notify (summary_object);
+
+ used_flags = GPOINTER_TO_UINT (g_hash_table_lookup (summary->priv->uids, camel_message_info_uid (info)));
+
+ old_saved_count = summary->priv->saved_count;
+ old_unread_count = summary->priv->unread_count;
+ old_deleted_count = summary->priv->deleted_count;
+ old_junk_count = summary->priv->junk_count;
+ old_junk_not_deleted_count = summary->priv->junk_not_deleted_count;
+ old_visible_count = summary->priv->visible_count;
+
+ /* decrement counts with old flags */
+ folder_summary_update_counts_by_flags (summary, used_flags, TRUE);
+
+ /* update current flags on the summary */
+ g_hash_table_insert (summary->priv->uids,
+ (gpointer) camel_pstring_strdup (camel_message_info_uid (info)),
+ GUINT_TO_POINTER (camel_message_info_flags (info)));
+
+ /* increment counts with new flags */
+ folder_summary_update_counts_by_flags (summary, camel_message_info_flags (info), FALSE);
+
+ /* this approach generates false notifications at least for "saved-count",
+ but is it an issue? I suppose not.
+ */
+ g_object_thaw_notify (summary_object);
+ camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
+ return old_saved_count != summary->priv->saved_count ||
+ old_unread_count != summary->priv->unread_count ||
+ old_deleted_count != summary->priv->deleted_count ||
+ old_junk_count != summary->priv->junk_count ||
+ old_junk_not_deleted_count != summary->priv->junk_not_deleted_count ||
+ old_visible_count != summary->priv->visible_count;
+}
+
static CamelMessageInfo *
message_info_clone (CamelFolderSummary *s,
const CamelMessageInfo *mi)
res = camel_flag_set (&mi->user_flags, name, value);
- /* TODO: check this item is still in the summary first */
- if (mi->summary && res && mi->summary->folder && mi->uid) {
+ if (mi->summary && res && mi->summary->priv->folder && mi->uid
+ && camel_folder_summary_check_uid (mi->summary, mi->uid)) {
CamelFolderChangeInfo *changes = camel_folder_change_info_new ();
mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
mi->dirty = TRUE;
camel_folder_summary_touch (mi->summary);
camel_folder_change_info_change_uid (changes, camel_message_info_uid (info));
- camel_folder_changed (mi->summary->folder, changes);
+ camel_folder_changed (mi->summary->priv->folder, changes);
camel_folder_change_info_free (changes);
}
res = camel_tag_set (&mi->user_tags, name, value);
- if (mi->summary && res && mi->summary->folder && mi->uid) {
+ if (mi->summary && res && mi->summary->priv->folder && mi->uid
+ && camel_folder_summary_check_uid (mi->summary, mi->uid)) {
CamelFolderChangeInfo *changes = camel_folder_change_info_new ();
mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
mi->dirty = TRUE;
camel_folder_summary_touch (mi->summary);
camel_folder_change_info_change_uid (changes, camel_message_info_uid (info));
- camel_folder_changed (mi->summary->folder, changes);
+ camel_folder_changed (mi->summary->priv->folder, changes);
camel_folder_change_info_free (changes);
}
{
guint32 old;
CamelMessageInfoBase *mi = (CamelMessageInfoBase *) info;
- gint read = 0, deleted = 0, junk = 0;
- /* TODO: locking? */
-
- if (flags & CAMEL_MESSAGE_SEEN && ((set & CAMEL_MESSAGE_SEEN) != (mi->flags & CAMEL_MESSAGE_SEEN)))
- { read = set & CAMEL_MESSAGE_SEEN ? 1 : -1; d(printf("Setting read as %d\n", set & CAMEL_MESSAGE_SEEN ? 1 : 0));}
-
- if (flags & CAMEL_MESSAGE_DELETED && ((set & CAMEL_MESSAGE_DELETED) != (mi->flags & CAMEL_MESSAGE_DELETED)))
- { deleted = set & CAMEL_MESSAGE_DELETED ? 1 : -1; d(printf("Setting deleted as %d\n", set & CAMEL_MESSAGE_DELETED ? 1 : 0));}
-
- if (flags & CAMEL_MESSAGE_JUNK && ((set & CAMEL_MESSAGE_JUNK) != (mi->flags & CAMEL_MESSAGE_JUNK)))
- { junk = set & CAMEL_MESSAGE_JUNK ? 1 : -1; d(printf("Setting junk as %d\n", set & CAMEL_MESSAGE_JUNK ? 1 : 0));}
+ gboolean counts_changed = FALSE;
- old = mi->flags;
+ old = camel_message_info_flags (info);
mi->flags = (old & ~flags) | (set & flags);
if (old != mi->flags) {
mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
camel_folder_summary_touch (mi->summary);
}
- if (((old & ~CAMEL_MESSAGE_SYSTEM_MASK) == (mi->flags & ~CAMEL_MESSAGE_SYSTEM_MASK)) && !((set & CAMEL_MESSAGE_JUNK_LEARN) && !(set & CAMEL_MESSAGE_JUNK)))
+ if (mi->summary) {
+ camel_folder_summary_lock (mi->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+ g_object_freeze_notify (G_OBJECT (mi->summary));
+ counts_changed = folder_summary_replace_flags (mi->summary, info);
+ }
+
+ if (!counts_changed && ((old & ~CAMEL_MESSAGE_SYSTEM_MASK) == (mi->flags & ~CAMEL_MESSAGE_SYSTEM_MASK)) && !((set & CAMEL_MESSAGE_JUNK_LEARN) && !(set & CAMEL_MESSAGE_JUNK))) {
+ if (mi->summary) {
+ g_object_thaw_notify (G_OBJECT (mi->summary));
+ camel_folder_summary_unlock (mi->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+ }
return FALSE;
+ }
if (mi->summary) {
- if (read && junk == 0 && !(mi->flags & CAMEL_MESSAGE_JUNK))
- mi->summary->unread_count -= read;
- else if (junk > 0)
- mi->summary->unread_count -= (old & CAMEL_MESSAGE_SEEN) ? 0 : 1;
- else if (junk < 0)
- mi->summary->unread_count -= (old & CAMEL_MESSAGE_SEEN) ? 0 : -1;
-
- if (deleted)
- mi->summary->deleted_count += deleted;
- if (junk)
- mi->summary->junk_count += junk;
- if (junk && !deleted)
- mi->summary->junk_not_deleted_count += junk;
- else if ((mi->flags & CAMEL_MESSAGE_JUNK) && deleted)
- mi->summary->junk_not_deleted_count -= deleted;
-
- if (((junk && !(mi->flags & CAMEL_MESSAGE_DELETED))) || (deleted && !(mi->flags & CAMEL_MESSAGE_JUNK)))
- mi->summary->visible_count -= junk ? junk : deleted;
- }
- if (mi->summary && mi->summary->folder && mi->uid) {
+ g_object_thaw_notify (G_OBJECT (mi->summary));
+ camel_folder_summary_unlock (mi->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+ }
+
+ if (mi->summary && mi->summary->priv->folder && mi->uid) {
CamelFolderChangeInfo *changes = camel_folder_change_info_new ();
camel_folder_change_info_change_uid (changes, camel_message_info_uid (info));
- camel_folder_changed (mi->summary->folder, changes);
+ camel_folder_changed (mi->summary->priv->folder, changes);
camel_folder_change_info_free (changes);
}
- d(printf("%d %d %d %d %d\n", mi->summary->unread_count, mi->summary->deleted_count, mi->summary->junk_count, mi->summary->junk_not_deleted_count, mi->summary->visible_count));
return TRUE;
}
g_type_class_add_private (class, sizeof (CamelFolderSummaryPrivate));
object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = folder_summary_set_property;
+ object_class->get_property = folder_summary_get_property;
object_class->dispose = folder_summary_dispose;
object_class->finalize = folder_summary_finalize;
class->info_set_flags = info_set_flags;
+ /**
+ * CamelFolderSummary:folder
+ *
+ * The #CamelFolder to which the folder summary belongs.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_FOLDER,
+ g_param_spec_object (
+ "folder",
+ "Folder",
+ "The folder to which the folder summary belongs",
+ CAMEL_TYPE_FOLDER,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ /**
+ * CamelFolderSummary:saved-count
+ *
+ * How many infos is saved in a summary.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SAVED_COUNT,
+ g_param_spec_uint (
+ "saved-count",
+ "Saved count",
+ "How many infos is savef in a summary",
+ 0, G_MAXUINT32,
+ 0, G_PARAM_READABLE));
+
+ /**
+ * CamelFolderSummary:unread-count
+ *
+ * How many unread infos is saved in a summary.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_UNREAD_COUNT,
+ g_param_spec_uint (
+ "unread-count",
+ "Unread count",
+ "How many unread infos is saved in a summary",
+ 0, G_MAXUINT32,
+ 0, G_PARAM_READABLE));
+
+ /**
+ * CamelFolderSummary:deleted-count
+ *
+ * How many deleted infos is saved in a summary.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_DELETED_COUNT,
+ g_param_spec_uint (
+ "deleted-count",
+ "Deleted count",
+ "How many deleted infos is saved in a summary",
+ 0, G_MAXUINT32,
+ 0, G_PARAM_READABLE));
+
+ /**
+ * CamelFolderSummary:junk-count
+ *
+ * How many junk infos is saved in a summary.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_JUNK_COUNT,
+ g_param_spec_uint (
+ "junk-count",
+ "Junk count",
+ "How many junk infos is saved in a summary",
+ 0, G_MAXUINT32,
+ 0, G_PARAM_READABLE));
+
+ /**
+ * CamelFolderSummary:junk-not-deleted-count
+ *
+ * How many junk and not deleted infos is saved in a summary.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_JUNK_NOT_DELETED_COUNT,
+ g_param_spec_uint (
+ "junk-not-deleted-count",
+ "Junk not deleted count",
+ "How many junk and not deleted infos is saved in a summary",
+ 0, G_MAXUINT32,
+ 0, G_PARAM_READABLE));
+
+ /**
+ * CamelFolderSummary:visible-count
+ *
+ * How many visible (not deleted and not junk) infos is saved in a summary.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_VISIBLE_COUNT,
+ g_param_spec_uint (
+ "visible-count",
+ "Visible count",
+ "How many visible (not deleted and not junk) infos is saved in a summary",
+ 0, G_MAXUINT32,
+ 0, G_PARAM_READABLE));
+
+ /**
+ * CamelFolderSummary:build-content
+ *
+ * Whether to build CamelMessageInfo.content.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_BUILD_CONTENT,
+ g_param_spec_boolean (
+ "build-content",
+ "Build content",
+ "Whether to build CamelMessageInfo.content",
+ FALSE,
+ G_PARAM_READWRITE));
+
+ /**
+ * CamelFolderSummary:need-preview
+ *
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_NEED_PREVIEW,
+ g_param_spec_boolean (
+ "need-preview",
+ "Need preview",
+ "",
+ FALSE,
+ G_PARAM_READWRITE));
}
static void
summary->priv = G_TYPE_INSTANCE_GET_PRIVATE (
summary, CAMEL_TYPE_FOLDER_SUMMARY, CamelFolderSummaryPrivate);
+ summary->version = CAMEL_FOLDER_SUMMARY_VERSION;
+ summary->flags = 0;
+ summary->time = 0;
+
summary->priv->filter_charset = g_hash_table_new (
camel_strcase_hash, camel_strcase_equal);
- summary->message_info_chunks = NULL;
- summary->content_info_chunks = NULL;
summary->priv->need_preview = FALSE;
summary->priv->preview_updates = g_hash_table_new (g_str_hash, g_str_equal);
-#if defined (DOESTRV) || defined (DOEPOOLV)
- summary->message_info_strings = CAMEL_MESSAGE_INFO_LAST;
-#endif
- summary->version = CAMEL_FOLDER_SUMMARY_VERSION;
- summary->flags = 0;
- summary->time = 0;
- summary->nextuid = 1;
-
- summary->uids = g_ptr_array_new ();
- summary->loaded_infos = g_hash_table_new (g_str_hash, g_str_equal);
+ summary->priv->nextuid = 1;
+ summary->priv->uids = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) camel_pstring_free, NULL);
+ summary->priv->loaded_infos = g_hash_table_new (g_str_hash, g_str_equal);
g_static_rec_mutex_init (&summary->priv->summary_lock);
g_static_rec_mutex_init (&summary->priv->io_lock);
g_static_rec_mutex_init (&summary->priv->alloc_lock);
g_static_rec_mutex_init (&summary->priv->ref_lock);
- summary->meta_summary = g_malloc0 (sizeof (CamelFolderMetaSummary));
-
- /* Default is 20, any implementor having UIDs that has length
- * exceeding 20, has to override this value
- */
- summary->meta_summary->uid_len = 20;
- summary->cache_load_time = 0;
- summary->timeout_handle = 0;
+ summary->priv->cache_load_time = 0;
+ summary->priv->timeout_handle = 0;
}
/**
* Returns: a new #CamelFolderSummary object
**/
CamelFolderSummary *
-camel_folder_summary_new (struct _CamelFolder *folder)
+camel_folder_summary_new (CamelFolder *folder)
{
- CamelFolderSummary *new;
-
- new = g_object_new (CAMEL_TYPE_FOLDER_SUMMARY, NULL);
- new->folder = folder;
-
- return new;
+ return g_object_new (CAMEL_TYPE_FOLDER_SUMMARY, "folder", folder, NULL);
}
/**
- * camel_folder_summary_set_filename:
+ * camel_folder_summary_get_index:
* @summary: a #CamelFolderSummary object
- * @filename: a filename
*
- * Set the filename where the summary will be loaded to/saved from.
+ * Returns: a #CamelFolder to which the summary if associated.
+ *
+ * Since: 3.4
**/
-void
-camel_folder_summary_set_filename (CamelFolderSummary *s,
- const gchar *name)
+CamelFolder *
+camel_folder_summary_get_folder (CamelFolderSummary *summary)
{
- camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+ CamelFolderSummaryPrivate *priv;
- g_free (s->summary_path);
- s->summary_path = g_strdup (name);
+ g_return_val_if_fail (summary != NULL, NULL);
+ g_return_val_if_fail (summary->priv != NULL, NULL);
- g_free (s->meta_summary->path);
- s->meta_summary->path = g_strconcat(name, "-meta", NULL);
+ priv = summary->priv;
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+ return priv->folder;
}
/**
- * camel_folder_summary_set_index:
+ * camel_folder_summary_get_saved_count:
* @summary: a #CamelFolderSummary object
- * @index: a #CamelIndex
*
- * Set the index used to index body content. If the index is %NULL, or
- * not set (the default), no indexing of body content will take place.
+ * Returns: Count of saved infos.
*
- * Unlike earlier behaviour, build_content need not be set to perform indexing.
+ * Since: 3.4
**/
-void
-camel_folder_summary_set_index (CamelFolderSummary *s,
- CamelIndex *index)
+guint32
+camel_folder_summary_get_saved_count (CamelFolderSummary *summary)
{
- struct _CamelFolderSummaryPrivate *p = s->priv;
+ CamelFolderSummaryPrivate *priv;
- if (p->index)
- g_object_unref (p->index);
+ g_return_val_if_fail (summary != NULL, 0);
+ g_return_val_if_fail (summary->priv != NULL, 0);
- p->index = index;
- if (index)
- g_object_ref (index);
-}
+ priv = summary->priv;
-/**
- * camel_folder_summary_set_build_content:
- * @summary: a #CamelFolderSummary object
- * @state: to build or not to build the content
- *
- * Set a flag to tell the summary to build the content info summary
- * (#CamelMessageInfo.content). The default is not to build content
- * info summaries.
- **/
-void
-camel_folder_summary_set_build_content (CamelFolderSummary *s,
- gboolean state)
-{
- s->build_content = state;
+ return priv->saved_count;
}
/**
- * camel_folder_summary_count:
+ * camel_folder_summary_get_saved_count:
* @summary: a #CamelFolderSummary object
*
- * Get the number of summary items stored in this summary.
+ * Returns: Count of unread infos.
*
- * Returns: the number of items in the summary
+ * Since: 3.4
**/
-guint
-camel_folder_summary_count (CamelFolderSummary *s)
+guint32
+camel_folder_summary_get_unread_count (CamelFolderSummary *summary)
{
- return s->uids->len;
+ CamelFolderSummaryPrivate *priv;
+
+ g_return_val_if_fail (summary != NULL, 0);
+ g_return_val_if_fail (summary->priv != NULL, 0);
+
+ priv = summary->priv;
+
+ return priv->unread_count;
}
/**
- * camel_folder_summary_index:
+ * camel_folder_summary_get_deleted_count:
* @summary: a #CamelFolderSummary object
- * @index: item index
*
- * Retrieve a summary item by index number.
+ * Returns: Count of deleted infos.
*
- * A referenced to the summary item is returned, which may be
- * ref'd or free'd as appropriate.
- *
- * Returns: the summary item, or %NULL if @index is out of range
+ * Since: 3.4
**/
-CamelMessageInfo *
-camel_folder_summary_index (CamelFolderSummary *s,
- gint i)
+guint32
+camel_folder_summary_get_deleted_count (CamelFolderSummary *summary)
{
- CamelMessageInfo *info = NULL;
-
- camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_REF_LOCK);
-
- if (i < s->uids->len) {
- gchar *uid;
- uid = g_ptr_array_index (s->uids, i);
-
- /* FIXME: Get exception from caller
- and pass it on below */
-
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_REF_LOCK);
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+ CamelFolderSummaryPrivate *priv;
- return camel_folder_summary_uid (s, uid);
- }
+ g_return_val_if_fail (summary != NULL, 0);
+ g_return_val_if_fail (summary->priv != NULL, 0);
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_REF_LOCK);
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+ priv = summary->priv;
- return info;
+ return priv->deleted_count;
}
-/* FIXME[disk-summary] Implement - camel_folder_summary_uid_exist -
- * directly through db than manual strcmp */
-
/**
- * camel_folder_summary_uid_from_index:
- * @s: a #CamelFolderSummary object
- * @i: item index
- *
- * Retrieve a summary item's uid by index number.
- *
- * A newly allocated uid is returned, which must be
- * free'd as appropriate.
+ * camel_folder_summary_get_junk_count:
+ * @summary: a #CamelFolderSummary object
*
- * Returns: the summary item's uid , or %NULL if @index is out of range
+ * Returns: Count of junk infos.
*
- * Since: 2.24
+ * Since: 3.4
**/
-gchar *
-camel_folder_summary_uid_from_index (CamelFolderSummary *s,
- gint i)
+guint32
+camel_folder_summary_get_junk_count (CamelFolderSummary *summary)
{
- gchar *uid = NULL;
- camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-
- if (i < s->uids->len)
- uid = g_strdup (g_ptr_array_index (s->uids, i));
+ CamelFolderSummaryPrivate *priv;
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+ g_return_val_if_fail (summary != NULL, 0);
+ g_return_val_if_fail (summary->priv != NULL, 0);
- return uid;
+ priv = summary->priv;
+ return priv->junk_count;
}
/**
- * camel_folder_summary_check_uid
- * @s: a #CamelFolderSummary object
- * @uid: a uid
- *
- * Check if the uid is valid. This isn't very efficient, so it shouldn't be called iteratively.
- *
+ * camel_folder_summary_get_junk_not_deleted_count:
+ * @summary: a #CamelFolderSummary object
*
- * Returns: if the uid is present in the summary or not (%TRUE or %FALSE)
+ * Returns: Count of junk and not deleted infos.
*
- * Since: 2.24
+ * Since: 3.4
**/
-gboolean
-camel_folder_summary_check_uid (CamelFolderSummary *s,
- const gchar *uid)
+guint32
+camel_folder_summary_get_junk_not_deleted_count (CamelFolderSummary *summary)
{
- gboolean ret = FALSE;
- gint i;
-
- camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+ CamelFolderSummaryPrivate *priv;
- for (i = 0; i < s->uids->len; i++) {
- if (strcmp (s->uids->pdata[i], uid) == 0) {
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- return TRUE;
- }
- }
+ g_return_val_if_fail (summary != NULL, 0);
+ g_return_val_if_fail (summary->priv != NULL, 0);
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+ priv = summary->priv;
- return ret;
+ return priv->junk_not_deleted_count;
}
/**
- * camel_folder_summary_array:
+ * camel_folder_summary_get_visible_count:
* @summary: a #CamelFolderSummary object
*
- * Obtain a copy of the summary array. This is done atomically,
- * so cannot contain empty entries.
- *
- * It must be freed using g_ptr_array_free
+ * Returns: Count of visible (not junk and not deleted) infos.
*
- * Returns: a #GPtrArray of uids
+ * Since: 3.4
**/
-GPtrArray *
-camel_folder_summary_array (CamelFolderSummary *s)
+guint32
+camel_folder_summary_get_visible_count (CamelFolderSummary *summary)
{
- GPtrArray *res = g_ptr_array_new ();
- gint i;
-
- camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+ CamelFolderSummaryPrivate *priv;
- g_ptr_array_set_size (res, s->uids->len);
- for (i = 0; i < s->uids->len; i++)
- res->pdata[i] = (gpointer) camel_pstring_strdup ((gchar *) g_ptr_array_index (s->uids, i));
+ g_return_val_if_fail (summary != NULL, 0);
+ g_return_val_if_fail (summary->priv != NULL, 0);
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+ priv = summary->priv;
- return res;
+ return priv->visible_count;
}
/**
- * camel_folder_summary_get_hashtable:
+ * camel_folder_summary_set_index:
* @summary: a #CamelFolderSummary object
+ * @index: a #CamelIndex
*
- * Obtain a copy of the summary array in the hashtable. This is done atomically,
+ * Set the index used to index body content. If the index is %NULL, or
+ * not set (the default), no indexing of body content will take place.
+ *
+ * Unlike earlier behaviour, build_content need not be set to perform indexing.
+ **/
+void
+camel_folder_summary_set_index (CamelFolderSummary *summary,
+ CamelIndex *index)
+{
+ CamelFolderSummaryPrivate *priv;
+
+ g_return_if_fail (summary != NULL);
+ g_return_if_fail (summary->priv != NULL);
+
+ priv = summary->priv;
+
+ if (index)
+ g_object_ref (index);
+
+ if (priv->index)
+ g_object_unref (priv->index);
+
+ priv->index = index;
+}
+
+/**
+ * camel_folder_summary_get_index:
+ * @summary: a #CamelFolderSummary object
+ *
+ * Returns: a #CamelIndex used to index body content.
+ *
+ * Since: 3.4
+ **/
+CamelIndex *
+camel_folder_summary_get_index (CamelFolderSummary *summary)
+{
+ CamelFolderSummaryPrivate *priv;
+
+ g_return_val_if_fail (summary != NULL, NULL);
+ g_return_val_if_fail (summary->priv != NULL, NULL);
+
+ priv = summary->priv;
+
+ return priv->index;
+}
+
+/**
+ * camel_folder_summary_set_build_content:
+ * @summary: a #CamelFolderSummary object
+ * @state: to build or not to build the content
+ *
+ * Set a flag to tell the summary to build the content info summary
+ * (#CamelMessageInfo.content). The default is not to build content
+ * info summaries.
+ **/
+void
+camel_folder_summary_set_build_content (CamelFolderSummary *summary,
+ gboolean state)
+{
+ CamelFolderSummaryPrivate *priv;
+
+ g_return_if_fail (summary != NULL);
+ g_return_if_fail (summary->priv != NULL);
+
+ priv = summary->priv;
+
+ if ((priv->build_content ? 1 : 0) == (state ? 1 : 0))
+ return;
+
+ priv->build_content = state;
+
+ g_object_notify (G_OBJECT (summary), "build-content");
+}
+
+/**
+ * camel_folder_summary_get_build_content:
+ * @summary: a #CamelFolderSummary object
+ *
+ * Returns: Whether to build #CamelMessageInfo.content.
+ *
+ * Since: 3.4
+ **/
+gboolean
+camel_folder_summary_get_build_content (CamelFolderSummary *summary)
+{
+ CamelFolderSummaryPrivate *priv;
+
+ g_return_val_if_fail (summary != NULL, FALSE);
+ g_return_val_if_fail (summary->priv != NULL, FALSE);
+
+ priv = summary->priv;
+
+ return priv->build_content;
+}
+
+/**
+ * camel_folder_summary_set_need_preview:
+ *
+ * Since: 2.28
+ **/
+void
+camel_folder_summary_set_need_preview (CamelFolderSummary *summary,
+ gboolean preview)
+{
+ CamelFolderSummaryPrivate *priv;
+
+ g_return_if_fail (summary != NULL);
+ g_return_if_fail (summary->priv != NULL);
+
+ priv = summary->priv;
+
+ priv->need_preview = preview;
+}
+
+/**
+ * camel_folder_summary_get_need_preview:
+ *
+ * Since: 2.28
+ **/
+gboolean
+camel_folder_summary_get_need_preview (CamelFolderSummary *summary)
+{
+ CamelFolderSummaryPrivate *priv;
+
+ g_return_val_if_fail (summary != NULL, FALSE);
+ g_return_val_if_fail (summary->priv != NULL, FALSE);
+
+ priv = summary->priv;
+
+ return priv->need_preview;
+}
+
+/**
+ * camel_folder_summary_next_uid:
+ * @summary: a #CamelFolderSummary object
+ *
+ * Generate a new unique uid value as an integer. This
+ * may be used to create a unique sequence of numbers.
+ *
+ * Returns: the next unique uid value
+ **/
+guint32
+camel_folder_summary_next_uid (CamelFolderSummary *s)
+{
+ guint32 uid;
+
+ camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
+ uid = s->priv->nextuid++;
+ camel_folder_summary_touch (s);
+
+ camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
+ return uid;
+}
+
+/**
+ * camel_folder_summary_set_next_uid:
+ * @summary: a #CamelFolderSummary object
+ * @uid: The next minimum uid to assign. To avoid clashing
+ * uid's, set this to the uid of a given messages + 1.
+ *
+ * Set the next minimum uid available. This can be used to
+ * ensure new uid's do not clash with existing uid's.
+ **/
+void
+camel_folder_summary_set_next_uid (CamelFolderSummary *s,
+ guint32 uid)
+{
+ camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
+ s->priv->nextuid = MAX (s->priv->nextuid, uid);
+ camel_folder_summary_touch (s);
+
+ camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+}
+
+/**
+ * camel_folder_summary_get_next_uid:
+ * @summary: a #CamelFolderSummary object
+ *
+ * Returns: Next uid currently awaiting for assignment. The difference from
+ * camel_folder_summary_next_uid() is that this function returns actual
+ * value and doesn't increment it before returning.
+ *
+ * Since: 3.4
+ **/
+guint32
+camel_folder_summary_get_next_uid (CamelFolderSummary *summary)
+{
+ guint32 res;
+
+ g_return_val_if_fail (summary != NULL, 0);
+ g_return_val_if_fail (summary->priv != NULL, 0);
+
+ camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
+ res = summary->priv->nextuid;
+
+ camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
+ return res;
+}
+
+/**
+ * camel_folder_summary_next_uid_string:
+ * @summary: a #CamelFolderSummary object
+ *
+ * Retrieve the next uid, but as a formatted string.
+ *
+ * Returns: the next uid as an unsigned integer string.
+ * This string must be freed by the caller.
+ **/
+gchar *
+camel_folder_summary_next_uid_string (CamelFolderSummary *summary)
+{
+ CamelFolderSummaryClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), NULL);
+
+ class = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary);
+ g_return_val_if_fail (class->next_uid_string != NULL, NULL);
+
+ return class->next_uid_string (summary);
+}
+
+/**
+ * camel_folder_summary_set_filename:
+ * @summary: a #CamelFolderSummary object
+ * @filename: a filename
+ *
+ * Set the filename where the summary will be loaded to/saved from.
+ **/
+void
+camel_folder_summary_set_filename (CamelFolderSummary *s,
+ const gchar *name)
+{
+ camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
+ g_free (s->priv->summary_path);
+ s->priv->summary_path = g_strdup (name);
+
+ camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+}
+
+/**
+ * camel_folder_summary_count:
+ * @summary: a #CamelFolderSummary object
+ *
+ * Get the number of summary items stored in this summary.
+ *
+ * Returns: the number of items in the summary
+ **/
+guint
+camel_folder_summary_count (CamelFolderSummary *summary)
+{
+ g_return_val_if_fail (summary != NULL, 0);
+ g_return_val_if_fail (summary->priv != NULL, 0);
+
+ return g_hash_table_size (summary->priv->uids);
+}
+
+/**
+ * camel_folder_summary_check_uid
+ * @s: a #CamelFolderSummary object
+ * @uid: a uid
+ *
+ * Check if the uid is valid. This isn't very efficient, so it shouldn't be called iteratively.
+ *
+ *
+ * Returns: if the uid is present in the summary or not (%TRUE or %FALSE)
+ *
+ * Since: 2.24
+ **/
+gboolean
+camel_folder_summary_check_uid (CamelFolderSummary *s,
+ const gchar *uid)
+{
+ gboolean ret;
+
+ g_return_val_if_fail (s != NULL, FALSE);
+ g_return_val_if_fail (s->priv != NULL, FALSE);
+ g_return_val_if_fail (uid != NULL, FALSE);
+
+ camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
+ ret = g_hash_table_lookup_extended (s->priv->uids, uid, NULL, NULL);
+
+ camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
+ return ret;
+}
+
+static void
+folder_summary_dupe_uids_to_array (gpointer key_uid, gpointer value_flags, gpointer user_data)
+{
+ g_ptr_array_add (user_data, (gpointer) camel_pstring_strdup (key_uid));
+}
+
+/**
+ * camel_folder_summary_get_array:
+ * @summary: a #CamelFolderSummary object
+ *
+ * Obtain a copy of the summary array. This is done atomically,
* so cannot contain empty entries.
*
- * It must be freed using camel_folder_summary_free_hashtable
+ * Free with camel_folder_summary_free_array()
*
- * Returns: a #GHashTable of uids
+ * Returns: a #GPtrArray of uids
*
- * Since: 2.26
+ * Since: 3.4
**/
-GHashTable *
-camel_folder_summary_get_hashtable (CamelFolderSummary *s)
+GPtrArray *
+camel_folder_summary_get_array (CamelFolderSummary *s)
{
- GHashTable *hash = g_hash_table_new (g_str_hash, g_str_equal);
- gint i;
+ GPtrArray *res;
+
+ g_return_val_if_fail (s != NULL, NULL);
+ g_return_val_if_fail (s->priv != NULL, NULL);
camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- for (i = 0; i < s->uids->len; i++)
- g_hash_table_insert (hash, (gpointer) camel_pstring_strdup ((gchar *) g_ptr_array_index (s->uids, i)), GINT_TO_POINTER (1));
+ res = g_ptr_array_sized_new (g_hash_table_size (s->priv->uids));
+ g_hash_table_foreach (s->priv->uids, folder_summary_dupe_uids_to_array, res);
camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- return hash;
+ return res;
}
/**
- * camel_folder_summary_free_hashtable:
+ * camel_folder_summary_free_array:
+ * @array: a #GPtrArray returned from camel_folder_summary_get_array()
*
- * Since: 2.26
+ * Free's array and its elements returned from camel_folder_summary_get_array().
+ *
+ * Since: 3.4
**/
void
-camel_folder_summary_free_hashtable (GHashTable *ht)
+camel_folder_summary_free_array (GPtrArray *array)
{
- g_hash_table_foreach (ht, (GHFunc) camel_pstring_free, NULL);
- g_hash_table_destroy (ht);
+ if (!array)
+ return;
+
+ g_ptr_array_foreach (array, (GFunc) camel_pstring_free, NULL);
+ g_ptr_array_free (array, TRUE);
}
/**
- * camel_folder_summary_peek_info:
+ * camel_folder_summary_peek_loaded:
*
* Since: 2.26
**/
CamelMessageInfo *
-camel_folder_summary_peek_info (CamelFolderSummary *s,
- const gchar *uid)
+camel_folder_summary_peek_loaded (CamelFolderSummary *s,
+ const gchar *uid)
{
- CamelMessageInfo *info = g_hash_table_lookup (s->loaded_infos, uid);
+ CamelMessageInfo *info;
+
+ g_return_val_if_fail (s != NULL, NULL);
+ g_return_val_if_fail (s->priv != NULL, NULL);
+
+ info = g_hash_table_lookup (s->priv->loaded_infos, uid);
if (info)
camel_message_info_ref (info);
+
return info;
}
struct _db_pass_data {
+ GHashTable *columns_hash;
CamelFolderSummary *summary;
gboolean add; /* or just insert to hashtable */
};
camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- info = g_hash_table_lookup (s->loaded_infos, uid);
+ info = g_hash_table_lookup (s->priv->loaded_infos, uid);
if (!info) {
CamelDB *cdb;
const gchar *folder_name;
struct _db_pass_data data;
- d(printf ("\ncamel_folder_summary_uid called \n"));
-
- folder_name = camel_folder_get_full_name (s->folder);
- parent_store = camel_folder_get_parent_store (s->folder);
+ folder_name = camel_folder_get_full_name (s->priv->folder);
+ parent_store = camel_folder_get_parent_store (s->priv->folder);
cdb = parent_store->cdb_r;
+ data.columns_hash = NULL;
data.summary = s;
data.add = FALSE;
ret = camel_db_read_message_info_record_with_uid (
cdb, folder_name, uid, &data,
camel_read_mir_callback, NULL);
+ if (data.columns_hash)
+ g_hash_table_destroy (data.columns_hash);
+
if (ret != 0) {
camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
return NULL;
}
/* We would have double reffed at camel_read_mir_callback */
- info = g_hash_table_lookup (s->loaded_infos, uid);
+ info = g_hash_table_lookup (s->priv->loaded_infos, uid);
cfs_schedule_info_release_timer (s);
}
}
/**
- * camel_folder_summary_uid:
+ * camel_folder_summary_get:
* @summary: a #CamelFolderSummary object
* @uid: a uid
*
* Returns: the summary item, or %NULL if the uid @uid is not available
**/
CamelMessageInfo *
-camel_folder_summary_uid (CamelFolderSummary *summary,
- const gchar *uid)
+camel_folder_summary_get (CamelFolderSummary *summary,
+ const gchar *uid)
{
CamelFolderSummaryClass *class;
return class->message_info_from_uid (summary, uid);
}
-/**
- * camel_folder_summary_next_uid:
- * @summary: a #CamelFolderSummary object
- *
- * Generate a new unique uid value as an integer. This
- * may be used to create a unique sequence of numbers.
- *
- * Returns: the next unique uid value
- **/
-guint32
-camel_folder_summary_next_uid (CamelFolderSummary *s)
-{
- guint32 uid;
-
- camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-
- uid = s->nextuid++;
-
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-
- /* FIXME: sync this to disk */
-/* summary_header_save(s);*/
- return uid;
-}
-
-/**
- * camel_folder_summary_set_uid:
- * @summary: a #CamelFolderSummary object
- * @uid: The next minimum uid to assign. To avoid clashing
- * uid's, set this to the uid of a given messages + 1.
- *
- * Set the next minimum uid available. This can be used to
- * ensure new uid's do not clash with existing uid's.
- **/
-void
-camel_folder_summary_set_uid (CamelFolderSummary *s,
- guint32 uid)
-{
- /* TODO: sync to disk? */
- camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-
- s->nextuid = MAX (s->nextuid, uid);
-
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-}
-
-/**
- * camel_folder_summary_next_uid_string:
- * @summary: a #CamelFolderSummary object
- *
- * Retrieve the next uid, but as a formatted string.
- *
- * Returns: the next uid as an unsigned integer string.
- * This string must be freed by the caller.
- **/
-gchar *
-camel_folder_summary_next_uid_string (CamelFolderSummary *summary)
-{
- CamelFolderSummaryClass *class;
-
- g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), NULL);
-
- class = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary);
- g_return_val_if_fail (class->next_uid_string != NULL, NULL);
-
- return class->next_uid_string (summary);
-}
-
static CamelMessageContentInfo *
perform_content_info_load_from_db (CamelFolderSummary *s,
CamelMIRecord *mir)
* from DB and merge */
camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- g_hash_table_foreach (s->loaded_infos, (GHFunc) append_changed_uids, res);
+ g_hash_table_foreach (s->priv->loaded_infos, (GHFunc) append_changed_uids, res);
camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
return res;
gint count = 0;
camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- g_hash_table_foreach (s->loaded_infos, (GHFunc) count_changed_uids, &count);
+ g_hash_table_foreach (s->priv->loaded_infos, (GHFunc) count_changed_uids, &count);
camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
return count;
}
-/* FIXME[disk-summary] I should have a better LRU algorithm */
static gboolean
-remove_item (gchar *key,
+remove_item (gchar *uid,
CamelMessageInfoBase *info,
- GList **to_free_list)
+ GSList **to_remove_infos)
{
- d(printf("%d(%d)\t", info->refcount, info->dirty)); /* camel_message_info_dump (info); */
- if (info->refcount == 1 && !info->dirty && !(info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) {
- *to_free_list = g_list_prepend (*to_free_list, info);
+ if (info->refcount == 1 && !info->dirty && (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) == 0) {
+ *to_remove_infos = g_slist_prepend (*to_remove_infos, info);
return TRUE;
}
+
return FALSE;
}
CamelFolderSummary *summary,
GError **error)
{
- GList *to_free_list = NULL, *l;
+ GSList *to_remove_infos = NULL;
CAMEL_DB_RELEASE_SQLITE_MEMORY;
- if (time (NULL) - summary->cache_load_time < SUMMARY_CACHE_DROP)
+ if (time (NULL) - summary->priv->cache_load_time < SUMMARY_CACHE_DROP)
return;
- /* FIXME[disk-summary] hack. fix it */
- camel_folder_summary_lock (
- summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+ camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_REF_LOCK);
- g_hash_table_foreach_remove (
- summary->loaded_infos, (GHRFunc) remove_item, &to_free_list);
+ g_hash_table_foreach_remove (summary->priv->loaded_infos, (GHRFunc) remove_item, &to_remove_infos);
camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_REF_LOCK);
- /* Deferred freeing as _free function will try to remove
- * entries from the hash_table in foreach_remove otherwise */
- for (l = to_free_list; l; l = l->next)
- camel_message_info_free (l->data);
- g_list_free (to_free_list);
+ g_slist_foreach (to_remove_infos, (GFunc) camel_message_info_free, NULL);
+ g_slist_free (to_remove_infos);
- camel_folder_summary_unlock (
- summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+ camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- summary->cache_load_time = time (NULL);
+ summary->priv->cache_load_time = time (NULL);
}
static gboolean
CamelSession *session;
/* If folder is freed or if the cache is nil then clean up */
- if (!summary->folder || !g_hash_table_size (summary->loaded_infos)) {
- summary->cache_load_time = 0;
- summary->timeout_handle = 0;
+ if (!summary->priv->folder || !g_hash_table_size (summary->priv->loaded_infos)) {
+ summary->priv->cache_load_time = 0;
+ summary->priv->timeout_handle = 0;
return FALSE;
}
- parent_store = camel_folder_get_parent_store (summary->folder);
+ parent_store = camel_folder_get_parent_store (summary->priv->folder);
session = camel_service_get_session (CAMEL_SERVICE (parent_store));
- if (time (NULL) - summary->cache_load_time < SUMMARY_CACHE_DROP)
+ if (time (NULL) - summary->priv->cache_load_time < SUMMARY_CACHE_DROP)
return TRUE;
camel_session_submit_job (
{
g_return_if_fail (CAMEL_IS_FOLDER_SUMMARY (s));
- if (!s->timeout_handle) {
+ if (!s->priv->timeout_handle) {
static gboolean know_can_do = FALSE, can_do = TRUE;
if (!know_can_do) {
/* FIXME[disk-summary] LRU please and not timeouts */
if (can_do)
- s->timeout_handle = g_timeout_add_seconds (SUMMARY_CACHE_DROP, (GSourceFunc) cfs_try_release_memory, s);
+ s->priv->timeout_handle = g_timeout_add_seconds (SUMMARY_CACHE_DROP, (GSourceFunc) cfs_try_release_memory, s);
}
/* update also cache load time to the actual, to not release something just loaded */
- s->cache_load_time = time (NULL);
+ s->priv->cache_load_time = time (NULL);
}
static gint
cfs_cache_size (CamelFolderSummary *s)
{
/* FIXME[disk-summary] this is a timely hack. fix it well */
- if (!CAMEL_IS_VEE_FOLDER (s->folder))
- return g_hash_table_size (s->loaded_infos);
+ if (!CAMEL_IS_VEE_FOLDER (s->priv->folder))
+ return g_hash_table_size (s->priv->loaded_infos);
else
- return s->uids->len;
+ return g_hash_table_size (s->priv->uids);
}
/* Update preview of cached messages */
gpointer value,
CamelFolder *folder)
{
- CamelMessageInfoBase *info = (CamelMessageInfoBase *) camel_folder_summary_uid (folder->summary, uid);
+ CamelMessageInfoBase *info = (CamelMessageInfoBase *) camel_folder_summary_get (folder->summary, uid);
CamelMimeMessage *msg;
CamelStore *parent_store;
const gchar *full_name;
g_ptr_array_add (array, (gchar *) camel_pstring_strdup (uid));
}
+static void
+copy_all_uids_to_hash (gpointer uid,
+ gpointer hash)
+{
+ g_return_if_fail (uid != NULL);
+
+ g_hash_table_insert (hash, (gchar *) camel_pstring_strdup (uid), GINT_TO_POINTER (1));
+}
+
static gboolean
fill_mi (const gchar *uid,
const gchar *msg,
{
CamelMessageInfoBase *info;
- info = g_hash_table_lookup (folder->summary->loaded_infos, uid);
+ info = g_hash_table_lookup (folder->summary->priv->loaded_infos, uid);
if (info) /* We re assign the memory of msg */
info->preview = (gchar *) msg;
camel_pstring_free (uid); /* unref the uid */
GError **error)
{
/* FIXME: Either lock & use or copy & use.*/
- GPtrArray *uids_uncached= camel_folder_get_uncached_uids (folder, folder->summary->uids, NULL);
- GHashTable *hash = camel_folder_summary_get_hashtable (folder->summary);
- GHashTable *preview_data;
+ GPtrArray *uids_uncached, *uids_array;
+ GHashTable *preview_data, *uids_hash;
CamelStore *parent_store;
const gchar *full_name;
gint i;
+ uids_array = camel_folder_summary_get_array (folder->summary);
+ uids_hash = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) camel_pstring_free, NULL);
+ g_ptr_array_foreach (uids_array, copy_all_uids_to_hash, uids_hash);
+ uids_uncached = camel_folder_get_uncached_uids (folder, uids_array, NULL);
+ camel_folder_summary_free_array (uids_array);
+ uids_array = NULL;
+
full_name = camel_folder_get_full_name (folder);
parent_store = camel_folder_get_parent_store (folder);
preview_data = camel_db_get_folder_preview (parent_store->cdb_r, full_name, NULL);
}
camel_folder_summary_lock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- g_hash_table_foreach (folder->summary->loaded_infos, (GHFunc) pick_uids, uids_uncached);
+ g_hash_table_foreach (folder->summary->priv->loaded_infos, (GHFunc) pick_uids, uids_uncached);
camel_folder_summary_unlock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
for (i = 0; i < uids_uncached->len; i++) {
- g_hash_table_remove (hash, uids_uncached->pdata[i]);
- camel_pstring_free (uids_uncached->pdata[i]); /* unref the hash table key */
+ g_hash_table_remove (uids_hash, uids_uncached->pdata[i]);
}
camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
camel_db_begin_transaction (parent_store->cdb_w, NULL);
- g_hash_table_foreach (hash, (GHFunc) msg_update_preview, folder);
+ g_hash_table_foreach (uids_hash, (GHFunc) msg_update_preview, folder);
camel_db_end_transaction (parent_store->cdb_w, NULL);
camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
camel_folder_free_uids (folder, uids_uncached);
- camel_folder_summary_free_hashtable (hash);
+ g_hash_table_destroy (uids_hash);
}
/* end */
* load better. */
d(printf ("\ncamel_folder_summary_reload_from_db called \n"));
- folder_name = camel_folder_get_full_name (s->folder);
- parent_store = camel_folder_get_parent_store (s->folder);
+ folder_name = camel_folder_get_full_name (s->priv->folder);
+ parent_store = camel_folder_get_parent_store (s->priv->folder);
session = camel_service_get_session (CAMEL_SERVICE (parent_store));
cdb = parent_store->cdb_r;
- /* FIXME FOR SANKAR: No need to pass the address of summary here. */
+ data.columns_hash = NULL;
data.summary = s;
data.add = FALSE;
+
ret = camel_db_read_message_info_records (
cdb, folder_name, (gpointer) &data,
camel_read_mir_callback, NULL);
+ if (data.columns_hash)
+ g_hash_table_destroy (data.columns_hash);
+
cfs_schedule_info_release_timer (s);
if (s->priv->need_preview)
camel_session_submit_job (
session,
(CamelSessionCallback) preview_update,
- g_object_ref (s->folder),
+ g_object_ref (s->priv->folder),
(GDestroyNotify) g_object_unref);
return ret == 0 ? 0 : -1;
}
/* update also cache load time, even when not loaded anything */
- s->cache_load_time = time (NULL);
+ s->priv->cache_load_time = time (NULL);
}
/**
*
* Since: 2.24
**/
-gint
+gboolean
camel_folder_summary_load_from_db (CamelFolderSummary *s,
GError **error)
{
gint ret = 0;
GError *local_error = NULL;
+ g_return_val_if_fail (s != NULL, FALSE);
+ g_return_val_if_fail (s->priv != NULL, FALSE);
+
camel_folder_summary_save_to_db (s, NULL);
/* struct _db_pass_data data; */
d(printf ("\ncamel_folder_summary_load_from_db called \n"));
- full_name = camel_folder_get_full_name (s->folder);
- parent_store = camel_folder_get_parent_store (s->folder);
- ret = camel_folder_summary_header_load_from_db (s, parent_store, full_name, error);
-
- if (ret)
- return ret;
+ full_name = camel_folder_get_full_name (s->priv->folder);
+ parent_store = camel_folder_get_parent_store (s->priv->folder);
+ if (!camel_folder_summary_header_load_from_db (s, parent_store, full_name, error))
+ return FALSE;
cdb = parent_store->cdb_r;
ret = camel_db_get_folder_uids (
cdb, full_name, s->sort_by, s->collate,
- s->uids, &local_error);
+ s->priv->uids, &local_error);
if (local_error != NULL && local_error->message != NULL &&
strstr (local_error->message, "no such table") != NULL) {
} else if (local_error != NULL)
g_propagate_error (error, local_error);
- return ret == 0 ? 0 : -1;
+ return ret == 0;
}
static void
mir_from_cols (CamelMIRecord *mir,
CamelFolderSummary *s,
+ GHashTable **columns_hash,
gint ncol,
gchar **cols,
gchar **name)
if (!name[i] || !cols[i])
continue;
- if (!strcmp (name [i], "uid"))
- mir->uid = (gchar *) camel_pstring_strdup (cols[i]);
- else if (!strcmp (name [i], "flags"))
- mir->flags = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
- else if (!strcmp (name [i], "read"))
- mir->read = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) : FALSE;
- else if (!strcmp (name [i], "deleted"))
- mir->deleted = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) : FALSE;
- else if (!strcmp (name [i], "replied"))
- mir->replied = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) : FALSE;
- else if (!strcmp (name [i], "important"))
- mir->important = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) : FALSE;
- else if (!strcmp (name [i], "junk"))
- mir->junk = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) : FALSE;
- else if (!strcmp (name [i], "attachment"))
- mir->attachment = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) : FALSE;
- else if (!strcmp (name [i], "size"))
- mir->size = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
- else if (!strcmp (name [i], "dsent"))
- mir->dsent = cols[i] ? strtol (cols[i], NULL, 10) : 0;
- else if (!strcmp (name [i], "dreceived"))
- mir->dreceived = cols[i] ? strtol (cols[i], NULL, 10) : 0;
- else if (!strcmp (name [i], "subject"))
- mir->subject = (gchar *) camel_pstring_strdup (cols[i]);
- else if (!strcmp (name [i], "mail_from"))
- mir->from = (gchar *) camel_pstring_strdup (cols[i]);
- else if (!strcmp (name [i], "mail_to"))
- mir->to = (gchar *) camel_pstring_strdup (cols[i]);
- else if (!strcmp (name [i], "mail_cc"))
- mir->cc = (gchar *) camel_pstring_strdup (cols[i]);
- else if (!strcmp (name [i], "mlist"))
- mir->mlist = (gchar *) camel_pstring_strdup (cols[i]);
- else if (!strcmp (name [i], "followup_flag"))
- mir->followup_flag = (gchar *) camel_pstring_strdup (cols[i]);
- else if (!strcmp (name [i], "followup_completed_on"))
- mir->followup_completed_on = (gchar *) camel_pstring_strdup (cols[i]);
- else if (!strcmp (name [i], "followup_due_by"))
- mir->followup_due_by = (gchar *) camel_pstring_strdup (cols[i]);
- else if (!strcmp (name [i], "part"))
- mir->part = g_strdup (cols[i]);
- else if (!strcmp (name [i], "labels"))
- mir->labels = g_strdup (cols[i]);
- else if (!strcmp (name [i], "usertags"))
- mir->usertags = g_strdup (cols[i]);
- else if (!strcmp (name [i], "cinfo"))
- mir->cinfo = g_strdup (cols[i]);
- else if (!strcmp (name [i], "bdata"))
- mir->bdata = g_strdup (cols[i]);
- /* Evolution itself doesn't yet use this, ignoring
- else if (!strcmp (name [i], "bodystructure"))
- mir->bodystructure = g_strdup (cols[i]); */
-
+ switch (camel_db_get_column_ident (columns_hash, i, ncol, name)) {
+ case CAMEL_DB_COLUMN_UID:
+ mir->uid = (gchar *) camel_pstring_strdup (cols[i]);
+ break;
+ case CAMEL_DB_COLUMN_FLAGS:
+ mir->flags = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+ break;
+ case CAMEL_DB_COLUMN_READ:
+ mir->read = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) : FALSE;
+ break;
+ case CAMEL_DB_COLUMN_DELETED:
+ mir->deleted = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) : FALSE;
+ break;
+ case CAMEL_DB_COLUMN_REPLIED:
+ mir->replied = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) : FALSE;
+ break;
+ case CAMEL_DB_COLUMN_IMPORTANT:
+ mir->important = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) : FALSE;
+ break;
+ case CAMEL_DB_COLUMN_JUNK:
+ mir->junk = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) : FALSE;
+ break;
+ case CAMEL_DB_COLUMN_ATTACHMENT:
+ mir->attachment = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) : FALSE;
+ break;
+ case CAMEL_DB_COLUMN_SIZE:
+ mir->size = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+ break;
+ case CAMEL_DB_COLUMN_DSENT:
+ mir->dsent = cols[i] ? strtol (cols[i], NULL, 10) : 0;
+ break;
+ case CAMEL_DB_COLUMN_DRECEIVED:
+ mir->dreceived = cols[i] ? strtol (cols[i], NULL, 10) : 0;
+ break;
+ case CAMEL_DB_COLUMN_SUBJECT:
+ mir->subject = (gchar *) camel_pstring_strdup (cols[i]);
+ break;
+ case CAMEL_DB_COLUMN_MAIL_FROM:
+ mir->from = (gchar *) camel_pstring_strdup (cols[i]);
+ break;
+ case CAMEL_DB_COLUMN_MAIL_TO:
+ mir->to = (gchar *) camel_pstring_strdup (cols[i]);
+ break;
+ case CAMEL_DB_COLUMN_MAIL_CC:
+ mir->cc = (gchar *) camel_pstring_strdup (cols[i]);
+ break;
+ case CAMEL_DB_COLUMN_MLIST:
+ mir->mlist = (gchar *) camel_pstring_strdup (cols[i]);
+ break;
+ case CAMEL_DB_COLUMN_FOLLOWUP_FLAG:
+ mir->followup_flag = (gchar *) camel_pstring_strdup (cols[i]);
+ break;
+ case CAMEL_DB_COLUMN_FOLLOWUP_COMPLETED_ON:
+ mir->followup_completed_on = (gchar *) camel_pstring_strdup (cols[i]);
+ break;
+ case CAMEL_DB_COLUMN_FOLLOWUP_DUE_BY:
+ mir->followup_due_by = (gchar *) camel_pstring_strdup (cols[i]);
+ break;
+ case CAMEL_DB_COLUMN_PART:
+ mir->part = g_strdup (cols[i]);
+ break;
+ case CAMEL_DB_COLUMN_LABELS:
+ mir->labels = g_strdup (cols[i]);
+ break;
+ case CAMEL_DB_COLUMN_USERTAGS:
+ mir->usertags = g_strdup (cols[i]);
+ break;
+ case CAMEL_DB_COLUMN_CINFO:
+ mir->cinfo = g_strdup (cols[i]);
+ break;
+ case CAMEL_DB_COLUMN_BDATA:
+ mir->bdata = g_strdup (cols[i]);
+ break;
+ case CAMEL_DB_COLUMN_BODYSTRUCTURE:
+ /* Evolution itself doesn't yet use this, ignoring */
+ /* mir->bodystructure = g_strdup (cols[i]); */
+ break;
+ default:
+ g_warn_if_reached ();
+ break;
+ }
}
}
gint ret = 0;
mir = g_new0 (CamelMIRecord , 1);
- mir_from_cols (mir, s, ncol, cols, name);
+ mir_from_cols (mir, s, &data->columns_hash, ncol, cols, name);
camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- if (!mir->uid || g_hash_table_lookup (s->loaded_infos, mir->uid)) {
+ if (!mir->uid || g_hash_table_lookup (s->priv->loaded_infos, mir->uid)) {
/* Unlock and better return */
camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
camel_db_camel_mir_free (mir);
if (info) {
- if (s->build_content) {
+ if (s->priv->build_content) {
gchar *tmp;
tmp = mir->cinfo;
/* FIXME: this should be done differently, how i don't know */
CamelDB *cdb;
CamelFIRecord *record;
- parent_store = camel_folder_get_parent_store (s->folder);
+ parent_store = camel_folder_get_parent_store (s->priv->folder);
cdb = parent_store->cdb_w;
/* Kick off the gc thread cycle. */
- if (s->timeout_handle)
- g_source_remove (s->timeout_handle);
- s->timeout_handle = 0;
+ if (s->priv->timeout_handle)
+ g_source_remove (s->priv->timeout_handle);
+ s->priv->timeout_handle = 0;
d(g_print ("\ncamel_folder_summary_load from FLAT FILE called \n"));
- if (s->summary_path == NULL) {
+ if (s->priv->summary_path == NULL) {
g_warning ("No summary path set. Unable to migrate\n");
return -1;
}
- in = g_fopen(s->summary_path, "rb");
+ in = g_fopen (s->priv->summary_path, "rb");
if (in == NULL)
return -1;
goto error;
/* now read in each message ... */
- for (i = 0; i < s->saved_count; i++) {
+ for (i = 0; i < s->priv->saved_count; i++) {
CamelTag *tag;
mi = CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->message_info_migrate (s, in);
goto error;
/* FIXME: this should be done differently, how i don't know */
- if (s->build_content) {
+ if (s->priv->build_content) {
((CamelMessageInfoBase *) mi)->content = perform_content_info_migrate (s, in);
if (((CamelMessageInfoBase *) mi)->content == NULL) {
camel_message_info_free (mi);
}
mi->dirty = TRUE;
- g_hash_table_insert (s->loaded_infos, (gpointer) mi->uid, mi);
+ g_hash_table_insert (s->priv->loaded_infos, (gpointer) mi->uid, mi);
}
if (fclose (in) != 0)
error:
if (errno != EINVAL)
- g_warning ("Cannot load summary file: '%s': %s", s->summary_path, g_strerror (errno));
+ g_warning ("Cannot load summary file: '%s': %s", s->priv->summary_path, g_strerror (errno));
fclose (in);
}
/* saves the content descriptions, recursively */
-static gint
+static gboolean
perform_content_info_save_to_db (CamelFolderSummary *s,
CamelMessageContentInfo *ci,
CamelMIRecord *record)
CamelMessageContentInfo *part;
gchar *oldr;
- if (CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->content_info_to_db (s, ci, record) == -1)
- return -1;
+ if (!CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->content_info_to_db (s, ci, record))
+ return FALSE;
oldr = record->cinfo;
record->cinfo = g_strdup_printf ("%s %d", oldr, my_list_size ((struct _node **)&ci->childs));
part = ci->childs;
while (part) {
if (perform_content_info_save_to_db (s, part, record) == -1)
- return -1;
+ return FALSE;
part = part->next;
}
- return 0;
+ return TRUE;
}
typedef struct {
CamelDB *cdb;
CamelMIRecord *mir;
- full_name = camel_folder_get_full_name (s->folder);
- parent_store = camel_folder_get_parent_store (s->folder);
+ full_name = camel_folder_get_full_name (s->priv->folder);
+ parent_store = camel_folder_get_parent_store (s->priv->folder);
cdb = parent_store->cdb_w;
if (!args->migration && !mi->dirty)
mir = CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->message_info_to_db (s, (CamelMessageInfo *) mi);
- if (mir && s->build_content) {
- if (perform_content_info_save_to_db (s, ((CamelMessageInfoBase *) mi)->content, mir) == -1) {
+ if (mir && s->priv->build_content) {
+ if (!perform_content_info_save_to_db (s, ((CamelMessageInfoBase *) mi)->content, mir)) {
g_warning ("unable to save mir+cinfo for uid: %s\n", mir->uid);
camel_db_camel_mir_free (mir);
/* FIXME: Add exception here */
}
if (!args->migration) {
- if (camel_db_write_message_info_record (cdb, full_name, mir, error) != 0) {
- camel_db_camel_mir_free (mir);
- return;
- }
+ if (camel_db_write_message_info_record (cdb, full_name, mir, error) != 0) {
+ camel_db_camel_mir_free (mir);
+ return;
+ }
} else {
- if (camel_db_write_fresh_message_info_record (cdb, CAMEL_DB_IN_MEMORY_TABLE, mir, error) != 0) {
- camel_db_camel_mir_free (mir);
- return;
- }
+ if (camel_db_write_fresh_message_info_record (cdb, CAMEL_DB_IN_MEMORY_TABLE, mir, error) != 0) {
+ camel_db_camel_mir_free (mir);
+ return;
+ }
- if (args->progress > CAMEL_DB_IN_MEMORY_TABLE_LIMIT) {
- g_print ("BULK INsert limit reached \n");
- camel_db_flush_in_memory_transactions (cdb, full_name, error);
- camel_db_start_in_memory_transactions (cdb, error);
- args->progress = 0;
- } else {
- args->progress++;
- }
+ if (args->progress > CAMEL_DB_IN_MEMORY_TABLE_LIMIT) {
+ g_print ("BULK INsert limit reached \n");
+ camel_db_flush_in_memory_transactions (cdb, full_name, error);
+ camel_db_start_in_memory_transactions (cdb, error);
+ args->progress = 0;
+ } else {
+ args->progress++;
+ }
}
/* Reset the dirty flag which decides if the changes are synced to the DB or not.
args.migration = fresh_mirs;
args.progress = 0;
- full_name = camel_folder_get_full_name (s->folder);
- parent_store = camel_folder_get_parent_store (s->folder);
+ full_name = camel_folder_get_full_name (s->priv->folder);
+ parent_store = camel_folder_get_parent_store (s->priv->folder);
cdb = parent_store->cdb_w;
if (camel_db_prepare_message_info_table (cdb, full_name, error) != 0)
/* Push MessageInfo-es */
camel_db_begin_transaction (cdb, NULL);
- g_hash_table_foreach (s->loaded_infos, save_to_db_cb, &args);
+ g_hash_table_foreach (s->priv->loaded_infos, save_to_db_cb, &args);
camel_db_end_transaction (cdb, NULL);
camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- /* FIXME[disk-summary] make sure we free the message infos that are loaded
- * are freed if not used anymore or should we leave that to the timer? */
+ cfs_schedule_info_release_timer (s);
return 0;
}
*
* Since: 2.24
**/
-gint
+gboolean
camel_folder_summary_save_to_db (CamelFolderSummary *s,
GError **error)
{
gint ret, count;
if (!(s->flags & CAMEL_SUMMARY_DIRTY))
- return 0;
+ return TRUE;
- parent_store = camel_folder_get_parent_store (s->folder);
+ parent_store = camel_folder_get_parent_store (s->priv->folder);
cdb = parent_store->cdb_w;
d(printf ("\ncamel_folder_summary_save_to_db called \n"));
camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
camel_db_begin_transaction (parent_store->cdb_w, NULL);
- g_hash_table_foreach (s->priv->preview_updates, (GHFunc) msg_save_preview, s->folder);
+ g_hash_table_foreach (s->priv->preview_updates, (GHFunc) msg_save_preview, s->priv->folder);
g_hash_table_remove_all (s->priv->preview_updates);
camel_db_end_transaction (parent_store->cdb_w, NULL);
if (ret != 0) {
/* Failed, so lets reset the flag */
s->flags |= CAMEL_SUMMARY_DIRTY;
- return -1;
+ return FALSE;
}
/* XXX So... if an error is set, how do we even reach this point
strstr ((*error)->message, "26 columns but 28 values") != NULL) {
const gchar *full_name;
- full_name = camel_folder_get_full_name (s->folder);
+ full_name = camel_folder_get_full_name (s->priv->folder);
g_warning ("Fixing up a broken summary migration on %s\n", full_name);
/* Begin everything again. */
ret = save_message_infos_to_db (s, FALSE, error);
if (ret != 0) {
s->flags |= CAMEL_SUMMARY_DIRTY;
- return -1;
+ return FALSE;
}
}
record = CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->summary_header_to_db (s, error);
if (!record) {
s->flags |= CAMEL_SUMMARY_DIRTY;
- return -1;
+ return FALSE;
}
camel_db_begin_transaction (cdb, NULL);
if (ret != 0) {
camel_db_abort_transaction (cdb, NULL);
s->flags |= CAMEL_SUMMARY_DIRTY;
- return -1;
+ return FALSE;
}
camel_db_end_transaction (cdb, NULL);
- return ret;
+ return ret == 0;
}
/**
*
* Since: 2.24
**/
-gint
+gboolean
camel_folder_summary_header_save_to_db (CamelFolderSummary *s,
GError **error)
{
CamelDB *cdb;
gint ret;
- parent_store = camel_folder_get_parent_store (s->folder);
+ parent_store = camel_folder_get_parent_store (s->priv->folder);
cdb = parent_store->cdb_w;
d(printf ("\ncamel_folder_summary_header_save_to_db called \n"));
record = CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->summary_header_to_db (s, error);
if (!record) {
- return -1;
+ return FALSE;
}
camel_db_begin_transaction (cdb, NULL);
if (ret != 0) {
camel_db_abort_transaction (cdb, NULL);
- return -1;
+ return FALSE;
}
camel_db_end_transaction (cdb, NULL);
- return ret;
+ return ret == 0;
}
/**
*
* Since: 2.24
**/
-gint
+gboolean
camel_folder_summary_header_load_from_db (CamelFolderSummary *s,
CamelStore *store,
const gchar *folder_name,
{
CamelDB *cdb;
CamelFIRecord *record;
- gint ret = 0;
+ gboolean ret = FALSE;
- d(printf ("\ncamel_folder_summary_load_from_db called \n"));
+ d(printf ("\ncamel_folder_summary_header_load_from_db called \n"));
camel_folder_summary_save_to_db (s, NULL);
cdb = store->cdb_r;
record = g_new0 (CamelFIRecord, 1);
- camel_db_read_folder_info_record (cdb, folder_name, &record, error);
+ camel_db_read_folder_info_record (cdb, folder_name, record, error);
if (record) {
- if (CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->summary_header_from_db (s, record) == -1)
- ret = -1;
+ ret = CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->summary_header_from_db (s, record);
} else {
- ret = -1;
+ ret = FALSE;
}
g_free (record->folder_name);
return ret;
}
-static gint
+static gboolean
summary_assign_uid (CamelFolderSummary *s,
CamelMessageInfo *info)
{
camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- while ((mi = g_hash_table_lookup (s->loaded_infos, uid))) {
+ while ((mi = g_hash_table_lookup (s->priv->loaded_infos, uid))) {
camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
if (mi == info)
- return 0;
+ return FALSE;
d(printf ("Trying to insert message with clashing uid (%s). new uid re-assigned", camel_message_info_uid (info)));
camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- return 1;
+ return TRUE;
}
/**
camel_folder_summary_add (CamelFolderSummary *s,
CamelMessageInfo *info)
{
+ CamelMessageInfoBase *base_info;
+
+ g_return_if_fail (s != NULL);
+ g_return_if_fail (s->priv != NULL);
+
if (info == NULL)
return;
- if (summary_assign_uid (s, info) == 0)
+ camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+ if (!summary_assign_uid (s, info)) {
+ camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
return;
+ }
- camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+ base_info = (CamelMessageInfoBase *) info;
+ folder_summary_update_counts_by_flags (s, camel_message_info_flags (info), FALSE);
+ base_info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
+ base_info->dirty = TRUE;
+
+ g_hash_table_insert (s->priv->uids,
+ (gpointer) camel_pstring_strdup (camel_message_info_uid (info)),
+ GUINT_TO_POINTER (camel_message_info_flags (info)));
/* Summary always holds a ref for the loaded infos */
- /* camel_message_info_ref(info); FIXME: Check how things are loaded. */
- /* FIXME[disk-summary] SHould we ref it or redesign it later on */
- /* The uid array should have its own memory. We will unload the infos when not reqd.*/
- g_ptr_array_add (s->uids, (gpointer) camel_pstring_strdup ((camel_message_info_uid (info))));
+ g_hash_table_insert (s->priv->loaded_infos, (gpointer) camel_message_info_uid (info), info);
- g_hash_table_insert (s->loaded_infos, (gpointer) camel_message_info_uid (info), info);
s->flags |= CAMEL_SUMMARY_DIRTY;
camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
CamelMessageInfo *info,
gboolean load)
{
+ g_return_if_fail (s != NULL);
+ g_return_if_fail (s->priv != NULL);
+
if (info == NULL)
return;
camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- /* Summary always holds a ref for the loaded infos */
- /* camel_message_info_ref(info); FIXME: Check how things are loaded. */
- /* FIXME[disk-summary] SHould we ref it or redesign it later on */
- /* The uid array should have its own memory. We will unload the infos when not reqd.*/
- if (!load)
- g_ptr_array_add (s->uids, (gchar *) camel_pstring_strdup (camel_message_info_uid (info)));
-
- g_hash_table_insert (s->loaded_infos, (gchar *) camel_message_info_uid (info), info);
-
- if (!load)
- s->flags |= CAMEL_SUMMARY_DIRTY;
-
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-}
-
-/**
- * camel_folder_summary_update_counts_by_flags:
- *
- * Since: 3.0
- **/
-void
-camel_folder_summary_update_counts_by_flags (CamelFolderSummary *summary,
- guint32 flags,
- gboolean subtract)
-{
- gint unread = 0, deleted = 0, junk = 0;
- gboolean is_junk_folder = FALSE, is_trash_folder = FALSE;
+ if (!load) {
+ CamelMessageInfoBase *base_info = (CamelMessageInfoBase *) info;
- g_return_if_fail (summary != NULL);
+ folder_summary_update_counts_by_flags (s, camel_message_info_flags (info), FALSE);
+ base_info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
+ base_info->dirty = TRUE;
- if (summary->folder && CAMEL_IS_VTRASH_FOLDER (summary->folder)) {
- CamelVTrashFolder *vtrash = CAMEL_VTRASH_FOLDER (summary->folder);
+ g_hash_table_insert (s->priv->uids,
+ (gpointer) camel_pstring_strdup (camel_message_info_uid (info)),
+ GUINT_TO_POINTER (camel_message_info_flags (info)));
- is_junk_folder = vtrash && vtrash->type == CAMEL_VTRASH_FOLDER_JUNK;
- is_trash_folder = vtrash && vtrash->type == CAMEL_VTRASH_FOLDER_TRASH;
+ s->flags |= CAMEL_SUMMARY_DIRTY;
}
- if (!(flags & CAMEL_MESSAGE_SEEN))
- unread = subtract ? -1 : 1;
-
- if (flags & CAMEL_MESSAGE_DELETED)
- deleted = subtract ? -1 : 1;
-
- if (flags & CAMEL_MESSAGE_JUNK)
- junk = subtract ? -1 : 1;
-
- dd(printf("%p: %d %d %d | %d %d %d \n", (gpointer) summary, unread, deleted, junk, summary->unread_count, summary->visible_count, summary->saved_count));
-
- if (deleted)
- summary->deleted_count += deleted;
- if (junk)
- summary->junk_count += junk;
- if (junk && !deleted)
- summary->junk_not_deleted_count += junk;
- if (!junk && !deleted)
- summary->visible_count += subtract ? -1 : 1;
-
- if (junk && !is_junk_folder)
- unread = 0;
- if (deleted && !is_trash_folder)
- unread = 0;
-
- if (unread)
- summary->unread_count += unread;
-
- summary->saved_count += subtract ? -1 : 1;
- camel_folder_summary_touch (summary);
-
- dd(printf("%p: %d %d %d | %d %d %d\n", (gpointer) summary, unread, deleted, junk, summary->unread_count, summary->visible_count, summary->saved_count));
-}
-
-static void
-update_summary (CamelFolderSummary *summary,
- CamelMessageInfoBase *info)
-{
- g_return_if_fail (summary != NULL);
- g_return_if_fail (info != NULL);
+ /* Summary always holds a ref for the loaded infos */
+ g_hash_table_insert (s->priv->loaded_infos, (gchar *) camel_message_info_uid (info), info);
- camel_folder_summary_update_counts_by_flags (summary, info->flags, FALSE);
- info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
- info->dirty = TRUE;
+ camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
}
/**
info = camel_folder_summary_info_new_from_header (summary, h);
camel_folder_summary_add (summary, info);
- update_summary (summary, (CamelMessageInfoBase *) info);
return info;
}
info = camel_folder_summary_info_new_from_parser (s, mp);
camel_folder_summary_add (s, info);
- update_summary (s, (CamelMessageInfoBase *) info);
+
return info;
}
CamelMessageInfo *info = camel_folder_summary_info_new_from_message (s, msg, NULL);
camel_folder_summary_add (s, info);
- update_summary (s, (CamelMessageInfoBase *) info);
+
return info;
}
*
* Empty the summary contents.
**/
-void
-camel_folder_summary_clear (CamelFolderSummary *s)
-{
- d(printf ("\ncamel_folder_summary_clearcalled \n"));
- s->flags &= ~CAMEL_SUMMARY_DIRTY;
-
- camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- if (camel_folder_summary_count (s) == 0) {
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- return;
- }
-
- g_ptr_array_foreach (s->uids, (GFunc) camel_pstring_free, NULL);
- g_ptr_array_free (s->uids, TRUE);
- s->uids = g_ptr_array_new ();
- s->saved_count = 0;
- s->unread_count = 0;
- s->deleted_count = 0;
- s->junk_count = 0;
- s->junk_not_deleted_count = 0;
- s->visible_count = 0;
-
- g_hash_table_destroy (s->loaded_infos);
- s->loaded_infos = g_hash_table_new (g_str_hash, g_str_equal);
-
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-}
-
-/**
- * camel_folder_summary_clear_db:
- *
- * Since: 2.24
- **/
-void
-camel_folder_summary_clear_db (CamelFolderSummary *s)
+gboolean
+camel_folder_summary_clear (CamelFolderSummary *s, GError **error)
{
+ GObject *summary_object;
CamelStore *parent_store;
CamelDB *cdb;
const gchar *folder_name;
+ gboolean res;
- /* FIXME: This is non-sense. Neither an exception is passed,
- nor a value returned. How is the caller supposed to know,
- whether the operation is succesful */
-
- d(printf ("\ncamel_folder_summary_load_from_db called \n"));
- s->flags &= ~CAMEL_SUMMARY_DIRTY;
-
- folder_name = camel_folder_get_full_name (s->folder);
- parent_store = camel_folder_get_parent_store (s->folder);
- cdb = parent_store->cdb_w;
+ g_return_val_if_fail (s != NULL, FALSE);
+ g_return_val_if_fail (s->priv != NULL, FALSE);
camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
if (camel_folder_summary_count (s) == 0) {
camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- return;
+ return TRUE;
}
- g_ptr_array_foreach (s->uids, (GFunc) camel_pstring_free, NULL);
- g_ptr_array_free (s->uids, TRUE);
- s->uids = g_ptr_array_new ();
- s->saved_count = 0;
- s->unread_count = 0;
- s->deleted_count = 0;
- s->junk_count = 0;
- s->junk_not_deleted_count = 0;
- s->visible_count = 0;
-
- g_hash_table_destroy (s->loaded_infos);
- s->loaded_infos = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_remove_all (s->priv->uids);
+ g_hash_table_remove_all (s->priv->loaded_infos);
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+ s->priv->saved_count = 0;
+ s->priv->unread_count = 0;
+ s->priv->deleted_count = 0;
+ s->priv->junk_count = 0;
+ s->priv->junk_not_deleted_count = 0;
+ s->priv->visible_count = 0;
- camel_db_clear_folder_summary (cdb, folder_name, NULL);
-}
+ camel_folder_summary_touch (s);
-/* This function returns 0 on success. So the caller should not bother,
- * deleting the uid from db when the return value is non-zero */
-static gint
-summary_remove_uid (CamelFolderSummary *s,
- const gchar *uid)
-{
- gint i;
+ folder_name = camel_folder_get_full_name (s->priv->folder);
+ parent_store = camel_folder_get_parent_store (s->priv->folder);
+ cdb = parent_store->cdb_w;
- d(printf ("\nsummary_remove_uid called \n"));
+ res = camel_db_clear_folder_summary (cdb, folder_name, error) == 0;
- /* This could be slower, but no otherway really. FIXME: Callers have to effective and shouldn't call it recursively. */
- for (i = 0; i < s->uids->len; i++) {
- if (strcmp (s->uids->pdata[i], uid) == 0) {
- /* FIXME: Does using fast remove affect anything ? */
- g_ptr_array_remove_index (s->uids, i);
- camel_pstring_free (uid);
- return 0;
- }
+ summary_object = G_OBJECT (s);
+ g_object_freeze_notify (summary_object);
+ g_object_notify (summary_object, "saved-count");
+ g_object_notify (summary_object, "unread-count");
+ g_object_notify (summary_object, "deleted-count");
+ g_object_notify (summary_object, "junk-count");
+ g_object_notify (summary_object, "junk-not-deleted-count");
+ g_object_notify (summary_object, "visible-count");
+ g_object_thaw_notify (summary_object);
- }
+ camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- return -1;
+ return res;
}
/**
* @info: a #CamelMessageInfo
*
* Remove a specific @info record from the summary.
+ *
+ * Returns: Whether the @info was found and removed from the @summary.
**/
-void
+gboolean
camel_folder_summary_remove (CamelFolderSummary *s,
CamelMessageInfo *info)
{
- CamelStore *parent_store;
- const gchar *full_name;
- gboolean found;
- gint ret;
-
- camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-
- found = g_hash_table_lookup (s->loaded_infos, camel_message_info_uid (info)) != NULL;
- g_hash_table_remove (s->loaded_infos, camel_message_info_uid (info));
- ret = summary_remove_uid (s, camel_message_info_uid (info));
-
- s->flags |= CAMEL_SUMMARY_DIRTY;
- s->meta_summary->msg_expunged = TRUE;
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-
- full_name = camel_folder_get_full_name (s->folder);
- parent_store = camel_folder_get_parent_store (s->folder);
-
- if (!ret && camel_db_delete_uid (parent_store->cdb_w, full_name, camel_message_info_uid (info), NULL) != 0)
- return;
+ g_return_val_if_fail (s != NULL, FALSE);
+ g_return_val_if_fail (s->priv != NULL, FALSE);
+ g_return_val_if_fail (info != NULL, FALSE);
- if (found)
+ if (camel_folder_summary_remove_uid (s, camel_message_info_uid (info))) {
camel_message_info_free (info);
+ return TRUE;
+ }
+
+ return FALSE;
}
/**
* @uid: a uid
*
* Remove a specific info record from the summary, by @uid.
+ *
+ * Returns: Whether the @uid was found and removed from the @summary.
**/
-void
+gboolean
camel_folder_summary_remove_uid (CamelFolderSummary *s,
const gchar *uid)
{
- CamelMessageInfo *oldinfo;
- gchar *olduid;
-
- camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_REF_LOCK);
- if (g_hash_table_lookup_extended (s->loaded_infos, uid, (gpointer) &olduid, (gpointer) &oldinfo)) {
- /* make sure it doesn't vanish while we're removing it */
- camel_message_info_ref (oldinfo);
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_REF_LOCK);
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- camel_folder_summary_remove (s, oldinfo);
- camel_message_info_free (oldinfo);
- } else {
- CamelStore *parent_store;
- const gchar *full_name;
- gchar *tmpid = g_strdup (uid);
- gint ret;
- /* Info isn't loaded into the memory. We must just remove the UID*/
- ret = summary_remove_uid (s, uid);
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_REF_LOCK);
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-
- full_name = camel_folder_get_full_name (s->folder);
- parent_store = camel_folder_get_parent_store (s->folder);
- if (!ret && camel_db_delete_uid (parent_store->cdb_w, full_name, tmpid, NULL) != 0) {
- g_free (tmpid);
- return;
- }
- g_free (tmpid);
- }
-}
-
-/* _fast doesn't deal with db and leaves it to the caller. */
-
-/**
- * camel_folder_summary_remove_uid_fast:
- *
- * Since: 2.24
- **/
-void
-camel_folder_summary_remove_uid_fast (CamelFolderSummary *s,
- const gchar *uid)
-{
- CamelMessageInfo *oldinfo;
- gchar *olduid;
-
- camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_REF_LOCK);
- if (g_hash_table_lookup_extended (s->loaded_infos, uid, (gpointer) &olduid, (gpointer) &oldinfo)) {
- /* make sure it doesn't vanish while we're removing it */
- camel_message_info_ref (oldinfo);
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_REF_LOCK);
- g_hash_table_remove (s->loaded_infos, olduid);
- summary_remove_uid (s, olduid);
- s->flags |= CAMEL_SUMMARY_DIRTY;
- s->meta_summary->msg_expunged = TRUE;
- camel_message_info_free (oldinfo);
- camel_message_info_free (oldinfo);
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- } else {
- gchar *tmpid = g_strdup (uid);
- /* Info isn't loaded into the memory. We must just remove the UID*/
- summary_remove_uid (s, uid);
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_REF_LOCK);
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- g_free (tmpid);
- }
-}
+ gpointer ptr_uid = NULL, ptr_flags = NULL;
+ CamelStore *parent_store;
+ const gchar *full_name;
+ const gchar *uid_copy;
+ gboolean res = TRUE;
-/**
- * camel_folder_summary_remove_index_fast:
- *
- * Since: 2.24
- **/
-void
-camel_folder_summary_remove_index_fast (CamelFolderSummary *s,
- gint index)
-{
- const gchar *uid = s->uids->pdata[index];
- CamelMessageInfo *oldinfo;
- gchar *olduid;
+ g_return_val_if_fail (s != NULL, FALSE);
+ g_return_val_if_fail (s->priv != NULL, FALSE);
+ g_return_val_if_fail (uid != NULL, FALSE);
camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_REF_LOCK);
-
- if (g_hash_table_lookup_extended (s->loaded_infos, uid, (gpointer) &olduid, (gpointer) &oldinfo)) {
- /* make sure it doesn't vanish while we're removing it */
- g_hash_table_remove (s->loaded_infos, uid);
- camel_pstring_free (uid);
- g_ptr_array_remove_index (s->uids, index);
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_REF_LOCK);
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- camel_message_info_free (oldinfo);
- } else {
- /* Info isn't loaded into the memory. We must just remove the UID*/
- g_ptr_array_remove_index (s->uids, index);
- camel_pstring_free (uid);
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_REF_LOCK);
+ if (!g_hash_table_lookup_extended (s->priv->uids, uid, &ptr_uid, &ptr_flags)) {
camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+ return FALSE;
}
-}
-
-/**
- * camel_folder_summary_remove_index:
- * @summary: a #CamelFolderSummary object
- * @index: record index
- *
- * Remove a specific info record from the summary, by index.
- **/
-void
-camel_folder_summary_remove_index (CamelFolderSummary *s,
- gint index)
-{
- const gchar *uid = s->uids->pdata[index];
-
- camel_folder_summary_remove_uid (s, uid);
-}
-
-/**
- * camel_folder_summary_remove_range:
- * @summary: a #CamelFolderSummary object
- * @start: initial index
- * @end: last index to remove
- *
- * Removes an indexed range of info records.
- **/
-void
-camel_folder_summary_remove_range (CamelFolderSummary *s,
- gint start,
- gint end)
-{
- d(g_print ("\ncamel_folder_summary_remove_range called \n"));
- if (end < start)
- return;
-
- camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-
- if (start < s->uids->len) {
-
- gint i;
- CamelDB *cdb;
- CamelStore *parent_store;
- const gchar *folder_name;
- GList *uids = NULL;
-
- end = MIN (end + 1, s->uids->len);
-
- for (i = start; i < end; i++) {
- const gchar *uid = s->uids->pdata[i];
- gpointer olduid, oldinfo;
-
- /* the uid will be freed below and will not be used because of changing size of the s->uids array */
- uids = g_list_prepend (uids, (gpointer) uid);
-
- if (g_hash_table_lookup_extended (s->loaded_infos, uid, &olduid, &oldinfo)) {
- camel_message_info_free (oldinfo);
- g_hash_table_remove (s->loaded_infos, uid);
- }
- }
- folder_name = camel_folder_get_full_name (s->folder);
- parent_store = camel_folder_get_parent_store (s->folder);
- cdb = parent_store->cdb_w;
+ folder_summary_update_counts_by_flags (s, GPOINTER_TO_UINT (ptr_flags), TRUE);
- /* FIXME[disk-summary] lifecycle of infos should be checked.
- * Add should add to db and del should del to db. Sync only
- * the changes at interval and remove those full sync on
- * folder switch */
- camel_db_delete_uids (cdb, folder_name, uids, NULL);
+ uid_copy = camel_pstring_strdup (uid);
+ g_hash_table_remove (s->priv->uids, uid_copy);
+ g_hash_table_remove (s->priv->loaded_infos, uid_copy);
- g_list_foreach (uids, (GFunc) camel_pstring_free, NULL);
- g_list_free (uids);
+ full_name = camel_folder_get_full_name (s->priv->folder);
+ parent_store = camel_folder_get_parent_store (s->priv->folder);
+ if (camel_db_delete_uid (parent_store->cdb_w, full_name, uid_copy, NULL) != 0)
+ res = FALSE;
- memmove (s->uids->pdata + start, s->uids->pdata + end, (s->uids->len - end) * sizeof (s->uids->pdata[0]));
- g_ptr_array_set_size (s->uids, s->uids->len - (end - start));
+ camel_pstring_free (uid_copy);
- s->flags |= CAMEL_SUMMARY_DIRTY;
+ camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- } else {
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- }
+ return res;
}
/* should be sorted, for binary search */
summary_header_load (CamelFolderSummary *s,
FILE *in)
{
- if (!s->summary_path)
+ if (!s->priv->summary_path)
return -1;
fseek (in, 0, SEEK_SET);
/* legacy version */
if (camel_file_util_decode_fixed_int32 (in, (gint32 *) &s->flags) == -1
- || camel_file_util_decode_fixed_int32 (in, (gint32 *) &s->nextuid) == -1
+ || camel_file_util_decode_fixed_int32 (in, (gint32 *) &s->priv->nextuid) == -1
|| camel_file_util_decode_time_t (in, &s->time) == -1
- || camel_file_util_decode_fixed_int32 (in, (gint32 *) &s->saved_count) == -1) {
+ || camel_file_util_decode_fixed_int32 (in, (gint32 *) &s->priv->saved_count) == -1) {
return -1;
}
/* version 13 */
if (s->version < 0x100 && s->version >= 13
- && (camel_file_util_decode_fixed_int32 (in, (gint32 *) &s->unread_count) == -1
- || camel_file_util_decode_fixed_int32 (in, (gint32 *) &s->deleted_count) == -1
- || camel_file_util_decode_fixed_int32 (in, (gint32 *) &s->junk_count) == -1)) {
+ && (camel_file_util_decode_fixed_int32 (in, (gint32 *) &s->priv->unread_count) == -1
+ || camel_file_util_decode_fixed_int32 (in, (gint32 *) &s->priv->deleted_count) == -1
+ || camel_file_util_decode_fixed_int32 (in, (gint32 *) &s->priv->junk_count) == -1)) {
return -1;
}
CamelMessageInfoBase *mi = (CamelMessageInfoBase *) info;
if (mi->uid) {
- if (s && g_hash_table_lookup (s->loaded_infos, mi->uid) == mi) {
- g_hash_table_remove (s->loaded_infos, mi->uid);
+ if (s) {
+ camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+ if (g_hash_table_lookup (s->priv->loaded_infos, mi->uid) == mi) {
+ g_hash_table_remove (s->priv->loaded_infos, mi->uid);
+ }
+ camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
}
camel_pstring_free (mi->uid);
}
/* start of this part */
state = camel_mime_parser_step (mp, &buffer, &len);
- if (s->build_content)
+ if (s->priv->build_content)
info = CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->content_info_new_from_parser (s, mp);
switch (state) {
CamelContentType *ct;
const struct _camel_header_raw *header;
- if (s->build_content)
+ if (s->priv->build_content)
info = CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->content_info_new_from_message (s, object);
containee = camel_medium_get_content (CAMEL_MEDIUM (object));
camel_folder_summary_unlock (mi->summary, CAMEL_FOLDER_SUMMARY_REF_LOCK);
/* FIXME: this is kinda busted, should really be handled by message info free */
- if (mi->summary->build_content
+ if (mi->summary->priv->build_content
&& ((CamelMessageInfoBase *) mi)->content) {
camel_folder_summary_content_info_free (mi->summary, ((CamelMessageInfoBase *) mi)->content);
}
camel_content_info_dump (((CamelMessageInfoBase *) mi)->content, 0);
}
-/**
- * camel_folder_summary_set_need_preview:
- *
- * Since: 2.28
- **/
-void
-camel_folder_summary_set_need_preview (CamelFolderSummary *summary,
- gboolean preview)
-{
- summary->priv->need_preview = preview;
-}
-
-/**
- * camel_folder_summary_get_need_preview:
- *
- * Since: 2.28
- **/
-gboolean
-camel_folder_summary_get_need_preview (CamelFolderSummary *summary)
-{
- return summary->priv->need_preview;
-}
-
static gboolean
compare_strings (const gchar *str1,
const gchar *str2)
return val;
}
-
typedef struct _CamelMessageInfo CamelMessageInfo;
typedef struct _CamelMessageInfoBase CamelMessageInfoBase;
-typedef struct _CamelFolderMetaSummary CamelFolderMetaSummary;
-
typedef struct _CamelMessageContentInfo CamelMessageContentInfo;
/* A tree of message content info structures
/* header info */
guint32 version; /* version of file loaded/loading */
- CamelFolderSummaryFlags flags;
- guint32 nextuid; /* next uid? */
time_t time; /* timestamp for this summary (for implementors to use) */
- guint32 saved_count; /* how many were saved/loaded */
- guint32 unread_count; /* handy totals */
- guint32 deleted_count;
- guint32 junk_count;
- guint32 junk_not_deleted_count;
- guint32 visible_count;
-
- /* memory allocators (setup automatically) */
- CamelMemChunk *message_info_chunks;
- CamelMemChunk *content_info_chunks;
-
- gchar *summary_path;
- gboolean build_content; /* do we try and parse/index the content, or not? */
-
- /* New members to replace the above depreacted members */
- GPtrArray *uids;
- GHashTable *loaded_infos;
-
- struct _CamelFolder *folder; /* parent folder, for events */
- struct _CamelFolderMetaSummary *meta_summary; /* Meta summary */
- time_t cache_load_time;
- guint timeout_handle;
+ CamelFolderSummaryFlags flags;
const gchar *collate;
const gchar *sort_by;
gint (*summary_header_save)(CamelFolderSummary *, FILE *);
/* Load/Save folder summary from DB*/
- gint (*summary_header_from_db)(CamelFolderSummary *, struct _CamelFIRecord *);
+ gboolean (*summary_header_from_db)(CamelFolderSummary *, struct _CamelFIRecord *);
struct _CamelFIRecord * (*summary_header_to_db)(CamelFolderSummary *, GError **error);
CamelMessageInfo * (*message_info_from_db) (CamelFolderSummary *, struct _CamelMIRecord *);
struct _CamelMIRecord * (*message_info_to_db) (CamelFolderSummary *, CamelMessageInfo *);
CamelMessageContentInfo * (*content_info_from_db) (CamelFolderSummary *, struct _CamelMIRecord *);
- gint (*content_info_to_db) (CamelFolderSummary *, CamelMessageContentInfo *, struct _CamelMIRecord *);
+ gboolean (*content_info_to_db) (CamelFolderSummary *, CamelMessageContentInfo *, struct _CamelMIRecord *);
/* create/save/load an individual message info */
CamelMessageInfo * (*message_info_new_from_header)(CamelFolderSummary *, struct _camel_header_raw *);
gboolean (*info_set_flags)(CamelMessageInfo *mi, guint32 mask, guint32 set);
};
-/* Meta-summary info */
-struct _CamelFolderMetaSummary {
- guint32 major; /* Major version of meta-summary */
- guint32 minor; /* Minor version of meta-summary */
- guint32 uid_len; /* Length of UID (for implementors to use) */
- gboolean msg_expunged; /* Whether any message is expunged or not */
- gchar *path; /* Path to meta-summary-file */
-};
-
-GType camel_folder_summary_get_type (void);
-CamelFolderSummary *camel_folder_summary_new (struct _CamelFolder *folder);
-
-/* Deprecated */
-void camel_folder_summary_set_filename (CamelFolderSummary *summary, const gchar *filename);
-
-void camel_folder_summary_set_index (CamelFolderSummary *summary, CamelIndex *index);
-void camel_folder_summary_set_build_content (CamelFolderSummary *summary, gboolean state);
-
-guint32 camel_folder_summary_next_uid (CamelFolderSummary *summary);
-gchar *camel_folder_summary_next_uid_string (CamelFolderSummary *summary);
-void camel_folder_summary_set_uid (CamelFolderSummary *summary, guint32 uid);
+GType camel_folder_summary_get_type (void);
+CamelFolderSummary * camel_folder_summary_new (struct _CamelFolder *folder);
+
+struct _CamelFolder * camel_folder_summary_get_folder (CamelFolderSummary *summary);
+CamelFolderSummaryFlags camel_folder_summary_get_flags (CamelFolderSummary *summary);
+
+guint32 camel_folder_summary_get_saved_count
+ (CamelFolderSummary *summary);
+guint32 camel_folder_summary_get_unread_count
+ (CamelFolderSummary *summary);
+guint32 camel_folder_summary_get_deleted_count
+ (CamelFolderSummary *summary);
+guint32 camel_folder_summary_get_junk_count
+ (CamelFolderSummary *summary);
+guint32 camel_folder_summary_get_junk_not_deleted_count
+ (CamelFolderSummary *summary);
+guint32 camel_folder_summary_get_visible_count
+ (CamelFolderSummary *summary);
+
+void camel_folder_summary_set_index (CamelFolderSummary *summary,
+ CamelIndex *index);
+CamelIndex * camel_folder_summary_get_index (CamelFolderSummary *summary);
+void camel_folder_summary_set_build_content
+ (CamelFolderSummary *summary,
+ gboolean state);
+gboolean camel_folder_summary_get_build_content
+ (CamelFolderSummary *summary);
+void camel_folder_summary_set_need_preview
+ (CamelFolderSummary *summary,
+ gboolean preview);
+gboolean camel_folder_summary_get_need_preview
+ (CamelFolderSummary *summary);
+guint32 camel_folder_summary_next_uid (CamelFolderSummary *summary);
+void camel_folder_summary_set_next_uid
+ (CamelFolderSummary *summary,
+ guint32 uid);
+guint32 camel_folder_summary_get_next_uid
+ (CamelFolderSummary *summary);
+gchar * camel_folder_summary_next_uid_string
+ (CamelFolderSummary *summary);
/* load/save the full summary from/to the db */
-gint camel_folder_summary_save_to_db (CamelFolderSummary *s, GError **error);
-gint camel_folder_summary_load_from_db (CamelFolderSummary *s, GError **error);
+gboolean camel_folder_summary_save_to_db (CamelFolderSummary *s,
+ GError **error);
+gboolean camel_folder_summary_load_from_db
+ (CamelFolderSummary *s,
+ GError **error);
/* only load the header */
-gint camel_folder_summary_header_load_from_db (CamelFolderSummary *s, struct _CamelStore *store, const gchar *folder_name, GError **error);
-gint camel_folder_summary_header_save_to_db (CamelFolderSummary *s, GError **error);
+gboolean camel_folder_summary_header_load_from_db
+ (CamelFolderSummary *s,
+ struct _CamelStore *store,
+ const gchar *folder_name,
+ GError **error);
+gboolean camel_folder_summary_header_save_to_db
+ (CamelFolderSummary *s,
+ GError **error);
/* set the dirty bit on the summary */
-void camel_folder_summary_touch (CamelFolderSummary *summary);
+void camel_folder_summary_touch (CamelFolderSummary *summary);
-/* add a new raw summary item */
-void camel_folder_summary_add (CamelFolderSummary *summary, CamelMessageInfo *info);
+/* Just build raw summary items */
+CamelMessageInfo * camel_folder_summary_info_new_from_header
+ (CamelFolderSummary *summary,
+ struct _camel_header_raw *headers);
+CamelMessageInfo * camel_folder_summary_info_new_from_parser
+ (CamelFolderSummary *summary,
+ CamelMimeParser *parser);
+CamelMessageInfo * camel_folder_summary_info_new_from_message
+ (CamelFolderSummary *summary,
+ CamelMimeMessage *message,
+ const gchar *bodystructure);
+
+CamelMessageContentInfo *camel_folder_summary_content_info_new
+ (CamelFolderSummary *summary);
+void camel_folder_summary_content_info_free
+ (CamelFolderSummary *summary,
+ CamelMessageContentInfo *ci);
+
+void camel_folder_summary_add_preview
+ (CamelFolderSummary *s,
+ CamelMessageInfo *info);
-/* Peek from mem only */
-CamelMessageInfo * camel_folder_summary_peek_info (CamelFolderSummary *s, const gchar *uid);
+/* Migration code */
+gint camel_folder_summary_migrate_infos
+ (CamelFolderSummary *s);
+
+/* build/add raw summary items */
+CamelMessageInfo * camel_folder_summary_add_from_header
+ (CamelFolderSummary *summary,
+ struct _camel_header_raw *headers);
+CamelMessageInfo * camel_folder_summary_add_from_parser
+ (CamelFolderSummary *summary,
+ CamelMimeParser *parser);
+CamelMessageInfo * camel_folder_summary_add_from_message
+ (CamelFolderSummary *summary,
+ CamelMimeMessage *message);
+
+/* add a new raw summary item */
+void camel_folder_summary_add (CamelFolderSummary *summary,
+ CamelMessageInfo *info);
-/* Get only the uids of dirty/changed things to sync to server/db */
-GPtrArray * camel_folder_summary_get_changed (CamelFolderSummary *s);
-/* reload the summary at any required point if required */
-void camel_folder_summary_prepare_fetch_all (CamelFolderSummary *s, GError **error);
/* insert mi to summary */
-void camel_folder_summary_insert (CamelFolderSummary *s, CamelMessageInfo *info, gboolean load);
+void camel_folder_summary_insert (CamelFolderSummary *s,
+ CamelMessageInfo *info,
+ gboolean load);
-void camel_folder_summary_remove_index_fast (CamelFolderSummary *s, gint index);
-void camel_folder_summary_remove_uid_fast (CamelFolderSummary *s, const gchar *uid);
+gboolean camel_folder_summary_remove (CamelFolderSummary *summary,
+ CamelMessageInfo *info);
-/* build/add raw summary items */
-CamelMessageInfo *camel_folder_summary_add_from_header (CamelFolderSummary *summary, struct _camel_header_raw *headers);
-CamelMessageInfo *camel_folder_summary_add_from_parser (CamelFolderSummary *summary, CamelMimeParser *parser);
-CamelMessageInfo *camel_folder_summary_add_from_message (CamelFolderSummary *summary, CamelMimeMessage *message);
+gboolean camel_folder_summary_remove_uid (CamelFolderSummary *summary,
+ const gchar *uid);
-/* Just build raw summary items */
-CamelMessageInfo *camel_folder_summary_info_new_from_header (CamelFolderSummary *summary, struct _camel_header_raw *headers);
-CamelMessageInfo *camel_folder_summary_info_new_from_parser (CamelFolderSummary *summary, CamelMimeParser *parser);
-CamelMessageInfo *camel_folder_summary_info_new_from_message (CamelFolderSummary *summary, CamelMimeMessage *message, const gchar *bodystructure);
+/* remove all items */
+gboolean camel_folder_summary_clear (CamelFolderSummary *summary,
+ GError **error);
-CamelMessageContentInfo *camel_folder_summary_content_info_new (CamelFolderSummary *summary);
-void camel_folder_summary_content_info_free (CamelFolderSummary *summary, CamelMessageContentInfo *ci);
+/* lookup functions */
+guint camel_folder_summary_count (CamelFolderSummary *summary);
-/* removes a summary item, doesn't fix content offsets */
-void camel_folder_summary_remove (CamelFolderSummary *summary, CamelMessageInfo *info);
-void camel_folder_summary_remove_uid (CamelFolderSummary *summary, const gchar *uid);
-void camel_folder_summary_remove_index (CamelFolderSummary *summary, gint index);
-void camel_folder_summary_remove_range (CamelFolderSummary *summary, gint start, gint end);
+gboolean camel_folder_summary_check_uid (CamelFolderSummary *s,
+ const gchar *uid);
+CamelMessageInfo * camel_folder_summary_get (CamelFolderSummary *summary,
+ const gchar *uid);
+GPtrArray * camel_folder_summary_get_array (CamelFolderSummary *summary);
+void camel_folder_summary_free_array (GPtrArray *array);
-/* remove all items */
-void camel_folder_summary_clear (CamelFolderSummary *summary);
-void camel_folder_summary_clear_db (CamelFolderSummary *s);
+/* Peek from mem only */
+CamelMessageInfo * camel_folder_summary_peek_loaded
+ (CamelFolderSummary *s,
+ const gchar *uid);
-/* update visible/unread/... counts based on message flags */
-void camel_folder_summary_update_counts_by_flags (CamelFolderSummary *summary, guint32 flags, gboolean subtract);
+/* Get only the uids of dirty/changed things to sync to server/db */
+GPtrArray * camel_folder_summary_get_changed
+ (CamelFolderSummary *s);
-/* lookup functions */
-guint camel_folder_summary_count (CamelFolderSummary *summary);
-CamelMessageInfo *camel_folder_summary_index (CamelFolderSummary *summary, gint index);
-CamelMessageInfo *camel_folder_summary_uid (CamelFolderSummary *summary, const gchar *uid);
-gchar * camel_folder_summary_uid_from_index (CamelFolderSummary *s, gint i);
-gboolean camel_folder_summary_check_uid (CamelFolderSummary *s, const gchar *uid);
+/* reload the summary at any required point if required */
+void camel_folder_summary_prepare_fetch_all
+ (CamelFolderSummary *s,
+ GError **error);
-GPtrArray *camel_folder_summary_array (CamelFolderSummary *summary);
-GHashTable *camel_folder_summary_get_hashtable (CamelFolderSummary *s);
-void camel_folder_summary_free_hashtable (GHashTable *ht);
+/* summary locking */
+void camel_folder_summary_lock (CamelFolderSummary *summary,
+ CamelFolderSummaryLock lock);
+void camel_folder_summary_unlock (CamelFolderSummary *summary,
+ CamelFolderSummaryLock lock);
/* basically like strings, but certain keywords can be compressed and de-cased */
-gint camel_folder_summary_encode_token (FILE *out, const gchar *str);
-gint camel_folder_summary_decode_token (FILE *in, gchar **str);
+gint camel_folder_summary_encode_token
+ (FILE *out,
+ const gchar *str);
+gint camel_folder_summary_decode_token
+ (FILE *in,
+ gchar **str);
/* message flag operations */
-gboolean camel_flag_get (CamelFlag **list, const gchar *name);
-gboolean camel_flag_set (CamelFlag **list, const gchar *name, gboolean value);
-gboolean camel_flag_list_copy (CamelFlag **to, CamelFlag **from);
-gint camel_flag_list_size (CamelFlag **list);
-void camel_flag_list_free (CamelFlag **list);
-
-CamelMessageFlags
- camel_system_flag (const gchar *name);
-gboolean camel_system_flag_get (CamelMessageFlags flags, const gchar *name);
+gboolean camel_flag_get (CamelFlag **list,
+ const gchar *name);
+gboolean camel_flag_set (CamelFlag **list,
+ const gchar *name,
+ gboolean value);
+gboolean camel_flag_list_copy (CamelFlag **to,
+ CamelFlag **from);
+gint camel_flag_list_size (CamelFlag **list);
+void camel_flag_list_free (CamelFlag **list);
+
+CamelMessageFlags camel_system_flag (const gchar *name);
+gboolean camel_system_flag_get (CamelMessageFlags flags,
+ const gchar *name);
/* message tag operations */
-const gchar *camel_tag_get (CamelTag **list, const gchar *name);
-gboolean camel_tag_set (CamelTag **list, const gchar *name, const gchar *value);
-gboolean camel_tag_list_copy (CamelTag **to, CamelTag **from);
-gint camel_tag_list_size (CamelTag **list);
-void camel_tag_list_free (CamelTag **list);
+const gchar * camel_tag_get (CamelTag **list,
+ const gchar *name);
+gboolean camel_tag_set (CamelTag **list,
+ const gchar *name,
+ const gchar *value);
+gboolean camel_tag_list_copy (CamelTag **to,
+ CamelTag **from);
+gint camel_tag_list_size (CamelTag **list);
+void camel_tag_list_free (CamelTag **list);
/* Summary may be null */
/* Use anonymous pointers to avoid tons of cast crap */
-gpointer camel_message_info_new (CamelFolderSummary *summary);
-gpointer camel_message_info_ref (gpointer info);
-CamelMessageInfo *camel_message_info_new_from_header (CamelFolderSummary *summary, struct _camel_header_raw *header);
-void camel_message_info_free (gpointer info);
-gpointer camel_message_info_clone (gconstpointer info);
+gpointer camel_message_info_new (CamelFolderSummary *summary);
+gpointer camel_message_info_ref (gpointer info);
+CamelMessageInfo * camel_message_info_new_from_header
+ (CamelFolderSummary *summary,
+ struct _camel_header_raw *header);
+void camel_message_info_free (gpointer info);
+gpointer camel_message_info_clone (gconstpointer info);
/* accessors */
-gconstpointer camel_message_info_ptr (const CamelMessageInfo *mi, gint id);
-guint32 camel_message_info_uint32 (const CamelMessageInfo *mi, gint id);
-time_t camel_message_info_time (const CamelMessageInfo *mi, gint id);
+gconstpointer camel_message_info_ptr (const CamelMessageInfo *mi,
+ gint id);
+guint32 camel_message_info_uint32 (const CamelMessageInfo *mi,
+ gint id);
+time_t camel_message_info_time (const CamelMessageInfo *mi,
+ gint id);
#define camel_message_info_uid(mi) ((const gchar *)((const CamelMessageInfo *)mi)->uid)
**/
#define camel_message_info_content(mi) ((const CamelMessageContentInfo *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_CONTENT))
-gboolean camel_message_info_user_flag (const CamelMessageInfo *mi, const gchar *id);
-const gchar *camel_message_info_user_tag (const CamelMessageInfo *mi, const gchar *id);
-
-gboolean camel_message_info_set_flags (CamelMessageInfo *mi, CamelMessageFlags flags, guint32 set);
-gboolean camel_message_info_set_user_flag (CamelMessageInfo *mi, const gchar *id, gboolean state);
-gboolean camel_message_info_set_user_tag (CamelMessageInfo *mi, const gchar *id, const gchar *val);
-
-void camel_folder_summary_set_need_preview (CamelFolderSummary *summary, gboolean preview);
-void camel_folder_summary_add_preview (CamelFolderSummary *s, CamelMessageInfo *info);
-gboolean camel_folder_summary_get_need_preview (CamelFolderSummary *summary);
+gboolean camel_message_info_user_flag (const CamelMessageInfo *mi,
+ const gchar *id);
+const gchar * camel_message_info_user_tag (const CamelMessageInfo *mi,
+ const gchar *id);
+
+gboolean camel_message_info_set_flags (CamelMessageInfo *mi,
+ CamelMessageFlags flags,
+ guint32 set);
+gboolean camel_message_info_set_user_flag
+ (CamelMessageInfo *mi,
+ const gchar *id,
+ gboolean state);
+gboolean camel_message_info_set_user_tag (CamelMessageInfo *mi,
+ const gchar *id,
+ const gchar *val);
const CamelMessageContentInfo * camel_folder_summary_guess_content_info (CamelMessageInfo *mi, CamelContentType *ctype);
-/* debugging functions */
-void camel_content_info_dump (CamelMessageContentInfo *ci, gint depth);
-
-void camel_message_info_dump (CamelMessageInfo *mi);
-
-/* Migration code */
-gint camel_folder_summary_migrate_infos (CamelFolderSummary *s);
+/* Deprecated */
+void camel_folder_summary_set_filename
+ (CamelFolderSummary *summary,
+ const gchar *filename);
-void camel_folder_summary_lock (CamelFolderSummary *summary, CamelFolderSummaryLock lock);
-void camel_folder_summary_unlock (CamelFolderSummary *summary, CamelFolderSummaryLock lock);
+/* debugging functions */
+void camel_content_info_dump (CamelMessageContentInfo *ci,
+ gint depth);
+void camel_message_info_dump (CamelMessageInfo *mi);
/* utility functions for bdata string decomposition */
-gint bdata_extract_digit (/* const */ gchar **part);
-gchar *bdata_extract_string (/* const */ gchar **part);
+gint bdata_extract_digit (/* const */ gchar **part);
+gchar * bdata_extract_string (/* const */ gchar **part);
G_END_DECLS
{
CamelFolderThread *thread;
GPtrArray *summary;
- GPtrArray *fsummary;
+ GPtrArray *fsummary = NULL;
gint i;
thread = g_malloc (sizeof (*thread));
thread->folder = g_object_ref (folder);
camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
- fsummary = camel_folder_summary_array (folder->summary);
thread->summary = summary = g_ptr_array_new ();
/* prefer given order from the summary order */
- if (!uids)
+ if (!uids) {
+ fsummary = camel_folder_summary_get_array (folder->summary);
uids = fsummary;
+ }
for (i = 0; i < uids->len; i++) {
CamelMessageInfo *info;
/* FIXME: Check if the info is leaking */
}
- camel_folder_free_summary (folder, fsummary);
+ if (fsummary)
+ camel_folder_summary_free_array (fsummary);
thread_summary (thread, summary);
}
if (folder->summary) {
- folder->summary->folder = NULL;
g_object_unref (folder->summary);
folder->summary = NULL;
}
g_return_val_if_fail (folder->summary != NULL, 0);
- info = camel_folder_summary_uid (folder->summary, uid);
+ info = camel_folder_summary_get (folder->summary, uid);
if (info == NULL)
return 0;
g_return_val_if_fail (folder->summary != NULL, FALSE);
- info = camel_folder_summary_uid (folder->summary, uid);
+ info = camel_folder_summary_get (folder->summary, uid);
if (info == NULL)
return FALSE;
g_return_val_if_fail (folder->summary != NULL, FALSE);
- info = camel_folder_summary_uid (folder->summary, uid);
+ info = camel_folder_summary_get (folder->summary, uid);
if (info == NULL)
return FALSE;
g_return_if_fail (folder->summary != NULL);
- info = camel_folder_summary_uid (folder->summary, uid);
+ info = camel_folder_summary_get (folder->summary, uid);
if (info == NULL)
return;
g_return_val_if_fail (folder->summary != NULL, NULL);
- info = camel_folder_summary_uid (folder->summary, uid);
+ info = camel_folder_summary_get (folder->summary, uid);
if (info == NULL)
return NULL;
g_return_if_fail (folder->summary != NULL);
- info = camel_folder_summary_uid (folder->summary, uid);
+ info = camel_folder_summary_get (folder->summary, uid);
if (info == NULL)
return;
{
g_return_val_if_fail (folder->summary != NULL, NULL);
- return camel_folder_summary_array (folder->summary);
+ return camel_folder_summary_get_array (folder->summary);
}
static GPtrArray *
folder_free_uids (CamelFolder *folder,
GPtrArray *array)
{
- gint i;
-
- for (i = 0; i < array->len; i++)
- camel_pstring_free (array->pdata[i]);
- g_ptr_array_free (array, TRUE);
+ camel_folder_summary_free_array (array);
}
static gint
{
g_return_val_if_fail (folder->summary != NULL, NULL);
- return camel_folder_summary_array (folder->summary);
+ return camel_folder_summary_get_array (folder->summary);
}
static void
folder_free_summary (CamelFolder *folder,
- GPtrArray *summary)
+ GPtrArray *array)
{
- g_ptr_array_foreach (summary, (GFunc) camel_pstring_free, NULL);
- g_ptr_array_free (summary, TRUE);
+ camel_folder_summary_free_array (array);
}
static void
{
g_return_val_if_fail (folder->summary != NULL, NULL);
- return camel_folder_summary_uid (folder->summary, uid);
+ return camel_folder_summary_get (folder->summary, uid);
}
static void
folder_delete (CamelFolder *folder)
{
if (folder->summary)
- camel_folder_summary_clear (folder->summary);
+ camel_folder_summary_clear (folder->summary, NULL);
}
static void
g_return_val_if_fail (CAMEL_IS_FOLDER (folder), -1);
g_return_val_if_fail (folder->summary != NULL, -1);
- return folder->summary->unread_count;
+ return camel_folder_summary_get_unread_count (folder->summary);
}
/**
g_return_val_if_fail (CAMEL_IS_FOLDER (folder), -1);
g_return_val_if_fail (folder->summary != NULL, -1);
- return folder->summary->deleted_count;
+ return camel_folder_summary_get_deleted_count (folder->summary);
}
/**
#include "camel-file-utils.h"
#include "camel-store-summary.h"
+#include "camel-folder-summary.h"
#include "camel-url.h"
#include "camel-win32.h"
#define CAMEL_STORE_SUMMARY_VERSION (2)
struct _CamelStoreSummaryPrivate {
- GMutex *summary_lock; /* for the summary hashtable/array */
- GMutex *io_lock; /* load/save lock, for access to saved_count, etc */
- GMutex *ref_lock; /* for reffing/unreffing messageinfo's ALWAYS obtain before CAMEL_STORE_SUMMARY_SUMMARY_LOCK */
+ GStaticRecMutex summary_lock; /* for the summary hashtable/array */
+ GStaticRecMutex io_lock; /* load/save lock, for access to saved_count, etc */
+ GStaticRecMutex ref_lock; /* for reffing/unreffing messageinfo's ALWAYS obtain before CAMEL_STORE_SUMMARY_SUMMARY_LOCK */
+
+ GHashTable *folder_summaries; /* CamelFolderSummary->path; doesn't add reference to CamelFolderSummary */
};
G_DEFINE_TYPE (CamelStoreSummary, camel_store_summary, CAMEL_TYPE_OBJECT)
camel_store_summary_clear (summary);
g_ptr_array_free (summary->folders, TRUE);
g_hash_table_destroy (summary->folders_path);
+ g_hash_table_destroy (summary->priv->folder_summaries);
g_free (summary->summary_path);
if (summary->store_info_chunks != NULL)
camel_memchunk_destroy (summary->store_info_chunks);
- g_mutex_free (summary->priv->summary_lock);
- g_mutex_free (summary->priv->io_lock);
- g_mutex_free (summary->priv->ref_lock);
+ g_static_rec_mutex_free (&summary->priv->summary_lock);
+ g_static_rec_mutex_free (&summary->priv->io_lock);
+ g_static_rec_mutex_free (&summary->priv->ref_lock);
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (camel_store_summary_parent_class)->finalize (object);
summary->folders = g_ptr_array_new ();
summary->folders_path = g_hash_table_new (g_str_hash, g_str_equal);
+ summary->priv->folder_summaries = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
- summary->priv->summary_lock = g_mutex_new ();
- summary->priv->io_lock = g_mutex_new ();
- summary->priv->ref_lock = g_mutex_new ();
+ g_static_rec_mutex_init (&summary->priv->summary_lock);
+ g_static_rec_mutex_init (&summary->priv->io_lock);
+ g_static_rec_mutex_init (&summary->priv->ref_lock);
}
/**
switch (lock) {
case CAMEL_STORE_SUMMARY_SUMMARY_LOCK:
- g_mutex_lock (summary->priv->summary_lock);
+ g_static_rec_mutex_lock (&summary->priv->summary_lock);
break;
case CAMEL_STORE_SUMMARY_IO_LOCK:
- g_mutex_lock (summary->priv->io_lock);
+ g_static_rec_mutex_lock (&summary->priv->io_lock);
break;
case CAMEL_STORE_SUMMARY_REF_LOCK:
- g_mutex_lock (summary->priv->ref_lock);
+ g_static_rec_mutex_lock (&summary->priv->ref_lock);
break;
default:
g_return_if_reached ();
switch (lock) {
case CAMEL_STORE_SUMMARY_SUMMARY_LOCK:
- g_mutex_unlock (summary->priv->summary_lock);
+ g_static_rec_mutex_unlock (&summary->priv->summary_lock);
break;
case CAMEL_STORE_SUMMARY_IO_LOCK:
- g_mutex_unlock (summary->priv->io_lock);
+ g_static_rec_mutex_unlock (&summary->priv->io_lock);
break;
case CAMEL_STORE_SUMMARY_REF_LOCK:
- g_mutex_unlock (summary->priv->ref_lock);
+ g_static_rec_mutex_unlock (&summary->priv->ref_lock);
break;
default:
g_return_if_reached ();
}
}
+
+static void
+store_summary_sync_folder_summary_count_cb (CamelFolderSummary *folder_summary, GParamSpec *param, CamelStoreSummary *summary)
+{
+ const gchar *path;
+ CamelStoreInfo *si;
+
+ g_return_if_fail (folder_summary != NULL);
+ g_return_if_fail (param != NULL);
+ g_return_if_fail (summary != NULL);
+ g_return_if_fail (summary->priv != NULL);
+
+ path = g_hash_table_lookup (summary->priv->folder_summaries, folder_summary);
+ g_return_if_fail (path != NULL);
+
+ camel_store_summary_lock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+ si = camel_store_summary_path (summary, path);
+ if (!si) {
+ camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+ g_warning ("%s: Store summary %p doesn't hold path '%s'", G_STRFUNC, summary, path);
+ return;
+ }
+
+ if (g_strcmp0 (g_param_spec_get_name (param), "saved-count") == 0) {
+ si->total = camel_folder_summary_get_saved_count (folder_summary);
+ camel_store_summary_touch (summary);
+ } else if (g_strcmp0 (g_param_spec_get_name (param), "unread-count") == 0) {
+ si->unread = camel_folder_summary_get_unread_count (folder_summary);
+ camel_store_summary_touch (summary);
+ } else {
+ g_warn_if_reached ();
+ }
+
+ camel_store_summary_info_free (summary, si);
+
+ camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+}
+
+/**
+ * camel_store_summary_connect_folder_summary:
+ * @summary: a #CamelStoreSummary object
+ * @path: used path for @folder_summary
+ * @folder_summary: a #CamelFolderSummary object
+ *
+ * Connects listeners for count changes on @folder_summary to keep CamelStoreInfo.total
+ * and CamelStoreInfo.unread in sync transparently. The @folder_summary is stored
+ * in @summary as @path. Use camel_store_summary_disconnect_folder_summary()
+ * to disconnect from listening.
+ *
+ * Returns: Whether successfully connect callbacks for count change notifications.
+ *
+ * Since: 3.4
+ **/
+gboolean
+camel_store_summary_connect_folder_summary (CamelStoreSummary *summary, const gchar *path, CamelFolderSummary *folder_summary)
+{
+ CamelStoreInfo *si;
+
+ g_return_val_if_fail (summary != NULL, FALSE);
+ g_return_val_if_fail (summary->priv != NULL, FALSE);
+ g_return_val_if_fail (path != NULL, FALSE);
+ g_return_val_if_fail (folder_summary != NULL, FALSE);
+
+ camel_store_summary_lock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+
+ si = camel_store_summary_path (summary, path);
+ if (!si) {
+ camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+ g_warning ("%s: Store summary %p doesn't hold path '%s'", G_STRFUNC, summary, path);
+ return FALSE;
+ }
+
+ camel_store_summary_info_free (summary, si);
+
+ if (g_hash_table_lookup (summary->priv->folder_summaries, folder_summary)) {
+ camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+ g_warning ("%s: Store summary %p already listens on folder summary %p", G_STRFUNC, summary, folder_summary);
+ return FALSE;
+ }
+
+ g_hash_table_insert (summary->priv->folder_summaries, folder_summary, g_strdup (path));
+ g_signal_connect (folder_summary, "notify::saved-count", G_CALLBACK (store_summary_sync_folder_summary_count_cb), summary);
+ g_signal_connect (folder_summary, "notify::unread-count", G_CALLBACK (store_summary_sync_folder_summary_count_cb), summary);
+
+ camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+
+ return TRUE;
+}
+
+/**
+ * camel_store_summary_disconnect_folder_summary:
+ * @summary: a #CamelStoreSummary object
+ * @folder_summary: a #CamelFolderSummary object
+ *
+ * Diconnects count change listeners previously connected
+ * by camel_store_summary_connect_folder_summary().
+ *
+ * Returns: Whether such connection existed and whether was successfully removed.
+ *
+ * Since: 3.4
+ **/
+gboolean
+camel_store_summary_disconnect_folder_summary (CamelStoreSummary *summary, CamelFolderSummary *folder_summary)
+{
+ g_return_val_if_fail (summary != NULL, FALSE);
+ g_return_val_if_fail (summary->priv != NULL, FALSE);
+ g_return_val_if_fail (folder_summary != NULL, FALSE);
+
+ camel_store_summary_lock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+
+ if (!g_hash_table_lookup (summary->priv->folder_summaries, folder_summary)) {
+ camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+ g_warning ("%s: Store summary %p is not connected to folder summary %p", G_STRFUNC, summary, folder_summary);
+ return FALSE;
+ }
+
+ g_signal_handlers_disconnect_by_func (folder_summary, G_CALLBACK (store_summary_sync_folder_summary_count_cb), summary);
+ g_hash_table_remove (summary->priv->folder_summaries, folder_summary);
+
+ camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+
+ return TRUE;
+}
void camel_store_summary_lock (CamelStoreSummary *summary, CamelStoreSummaryLock lock);
void camel_store_summary_unlock (CamelStoreSummary *summary, CamelStoreSummaryLock lock);
+struct _CamelFolderSummary;
+gboolean camel_store_summary_connect_folder_summary (CamelStoreSummary *summary, const gchar *path, struct _CamelFolderSummary *folder_summary);
+gboolean camel_store_summary_disconnect_folder_summary (CamelStoreSummary *summary, struct _CamelFolderSummary *folder_summary);
+
G_END_DECLS
#endif /* CAMEL_STORE_SUMMARY_H */
}
vinfo = (CamelVeeMessageInfo *) camel_folder_get_message_info ((CamelFolder *) folder_unmatched, vuid);
if (vinfo) {
- camel_folder_summary_update_counts_by_flags (CAMEL_FOLDER (folder_unmatched)->summary, vinfo->old_flags, TRUE);
camel_folder_change_info_remove_uid (
folder_unmatched->changes, vuid);
*unm_added_l = g_list_prepend (*unm_added_l, (gpointer) camel_pstring_strdup (vuid));
- camel_folder_summary_remove_uid_fast (
+ camel_folder_summary_remove_uid (
CAMEL_FOLDER (folder_unmatched)->summary, vuid);
camel_folder_free_message_info (
CAMEL_FOLDER (folder_unmatched),
memcpy (vuid, hash, 8);
strcpy (vuid + 8, uid);
- vinfo = (CamelVeeMessageInfo *) camel_folder_summary_uid (folder->summary, vuid);
- if (vinfo) {
- camel_folder_summary_update_counts_by_flags (folder->summary, vinfo->old_flags, TRUE);
- camel_message_info_free ((CamelMessageInfo *) vinfo);
- }
-
camel_folder_change_info_remove_uid (vf->changes, vuid);
if (use_db)
*m_removed_l = g_list_prepend (*m_removed_l, (gpointer) camel_pstring_strdup (vuid));
- camel_folder_summary_remove_uid_fast (folder->summary, vuid);
+ camel_folder_summary_remove_uid (folder->summary, vuid);
if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER (sub) && folder_unmatched != NULL) {
if (keep) {
vinfo = (CamelVeeMessageInfo *) camel_folder_get_message_info ((CamelFolder *) folder_unmatched, vuid);
if (vinfo) {
- camel_folder_summary_update_counts_by_flags (CAMEL_FOLDER (folder_unmatched)->summary, vinfo->old_flags, TRUE);
camel_folder_change_info_remove_uid (
folder_unmatched->changes, vuid);
*unm_removed_l = g_list_prepend (*unm_removed_l, (gpointer) camel_pstring_strdup (vuid));
- camel_folder_summary_remove_uid_fast (
+ camel_folder_summary_remove_uid (
CAMEL_FOLDER (folder_unmatched)->summary, vuid);
camel_folder_free_message_info (
CAMEL_FOLDER (folder_unmatched),
}
static void
-update_old_flags (CamelFolderSummary *summary,
- CamelVeeMessageInfo *vinfo)
-{
- g_return_if_fail (summary != NULL);
- g_return_if_fail (vinfo != NULL);
-
- camel_folder_summary_update_counts_by_flags (summary, vinfo->old_flags, TRUE);
- vinfo->old_flags = camel_message_info_flags ((CamelMessageInfo *) vinfo);
- camel_folder_summary_update_counts_by_flags (summary, vinfo->old_flags, FALSE);
-}
-
-static void
folder_changed_change_uid (CamelFolder *sub,
const gchar *uid,
const gchar hash[8],
memcpy (vuid, hash, 8);
strcpy (vuid + 8, uid);
- vinfo = (CamelVeeMessageInfo *) camel_folder_summary_uid (folder->summary, vuid);
+ vinfo = (CamelVeeMessageInfo *) camel_folder_summary_get (folder->summary, vuid);
if (folder_unmatched != NULL)
- uinfo = (CamelVeeMessageInfo *) camel_folder_summary_uid (((CamelFolder *) folder_unmatched)->summary, vuid);
+ uinfo = (CamelVeeMessageInfo *) camel_folder_summary_get (((CamelFolder *) folder_unmatched)->summary, vuid);
if (vinfo || uinfo) {
info = camel_folder_get_message_info (sub, uid);
if (info) {
if (vinfo) {
camel_folder_change_info_change_uid (vf->changes, vuid);
- update_old_flags (folder->summary, vinfo);
+ vinfo->old_flags = camel_message_info_flags ((CamelMessageInfo *) vinfo);
+ vinfo->info.flags |= (vinfo->old_flags & ~CAMEL_MESSAGE_FOLDER_FLAGGED);
camel_message_info_free ((CamelMessageInfo *) vinfo);
}
if (uinfo) {
camel_folder_change_info_change_uid (folder_unmatched->changes, vuid);
- update_old_flags (CAMEL_FOLDER (folder_unmatched)->summary, uinfo);
+ uinfo->old_flags = camel_message_info_flags ((CamelMessageInfo *) uinfo);
+ uinfo->info.flags |= (uinfo->old_flags & ~CAMEL_MESSAGE_FOLDER_FLAGGED);
camel_message_info_free ((CamelMessageInfo *) uinfo);
}
}
memcpy (vuid, hash, 8);
strcpy (vuid + 8, uid);
- vinfo = (CamelVeeMessageInfo *) camel_folder_summary_uid (folder->summary, vuid);
+ vinfo = (CamelVeeMessageInfo *) camel_folder_summary_get (folder->summary, vuid);
if (vinfo == NULL) {
g_ptr_array_add (newchanged, (gchar *) uid);
} else {
}
memcpy (vuid, hash, 8);
strcpy (vuid + 8, uid);
- vinfo = (CamelVeeMessageInfo *) camel_folder_summary_uid (folder->summary, vuid);
+ vinfo = (CamelVeeMessageInfo *) camel_folder_summary_get (folder->summary, vuid);
if (vinfo == NULL) {
if (g_hash_table_lookup (matches_hash, uid)) {
/* A uid we dont have, but now it matches, add it */
CamelFolder *sub,
gchar hash[8])
{
- gint count, i;
+ gint i;
CamelFolderChangeInfo *changes = NULL;
CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
CamelFolderSummary *ssummary = sub->summary;
+ GPtrArray *known_uids;
camel_vee_folder_lock (vf, CAMEL_VEE_FOLDER_SUMMARY_LOCK);
camel_folder_summary_prepare_fetch_all (((CamelFolder *) vf)->summary, NULL);
- count = camel_folder_summary_count (((CamelFolder *) vf)->summary);
- for (i = 0; i < count; i++) {
- CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *) camel_folder_summary_index (((CamelFolder *) vf)->summary, i);
+ known_uids = camel_folder_summary_get_array (((CamelFolder *) vf)->summary);
+ for (i = 0; known_uids && i < known_uids->len; i++) {
+ CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *) camel_folder_summary_get (((CamelFolder *) vf)->summary, g_ptr_array_index (known_uids, i));
CamelVeeMessageInfo *vinfo;
if (mi == NULL)
continue;
- if (mi->summary == ssummary) {
+ if (mi->orig_summary == ssummary) {
gchar *uid = (gchar *) camel_message_info_uid (mi);
gchar *oldkey;
gpointer oldval;
camel_folder_change_info_remove_uid (vf->changes, uid);
- camel_folder_summary_update_counts_by_flags (CAMEL_FOLDER (vf)->summary, mi->old_flags, TRUE);
camel_folder_summary_remove (((CamelFolder *) vf)->summary, (CamelMessageInfo *) mi);
- /* works since we always append on the end */
- i--;
- count--;
-
vinfo = vee_folder_add_uid (vf, sub, uid + 8, hash);
if (vinfo) {
camel_folder_change_info_add_uid (vf->changes, camel_message_info_uid (vinfo));
camel_message_info_free ((CamelMessageInfo *) mi);
}
+ camel_folder_summary_free_array (known_uids);
+
if (camel_folder_change_info_changed (vf->changes)) {
changes = vf->changes;
vf->changes = camel_folder_change_info_new ();
if (vee_folder_add_uid_test (u->folder_unmatched, u->source, uidin, u->hash))
camel_folder_change_info_add_uid (u->folder_unmatched->changes, uid);
} else {
- CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *) camel_folder_summary_uid (((CamelFolder *) u->folder_unmatched)->summary, uid);
+ CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *) camel_folder_summary_get (((CamelFolder *) u->folder_unmatched)->summary, uid);
if (mi) {
- camel_folder_summary_update_counts_by_flags (CAMEL_FOLDER (u->folder_unmatched)->summary, mi->old_flags, TRUE);
-
if (u->message_uids != NULL)
g_queue_push_tail (u->message_uids, g_strdup (uid));
- camel_folder_summary_remove_uid_fast (
+ camel_folder_summary_remove_uid (
((CamelFolder *) u->folder_unmatched)->summary, uid);
camel_folder_change_info_remove_uid (
u->folder_unmatched->changes, uid);
const gchar *full_name;
/* We do this during write, so lets use write handle, though we gonna read */
- full_name = camel_folder_get_full_name (s->folder);
+ full_name = camel_folder_get_full_name (camel_folder_summary_get_folder (s));
record->folder_name = g_strdup (full_name);
/* we always write out the current version */
record->version = 13; /* FIXME: CAMEL_FOLDER_SUMMARY_VERSION; */
record->flags = s->flags;
- record->nextuid = s->nextuid;
+ record->nextuid = camel_folder_summary_get_next_uid (s);
record->time = s->time;
- record->saved_count = s->uids->len;
- record->junk_count = s->junk_count;
- record->deleted_count = s->deleted_count;
- record->unread_count = s->unread_count;
- record->visible_count = s->visible_count;
- record->jnd_count = s->junk_not_deleted_count;
+ record->saved_count = camel_folder_summary_count (s);
+ record->junk_count = camel_folder_summary_get_junk_count (s);
+ record->deleted_count = camel_folder_summary_get_deleted_count (s);
+ record->unread_count = camel_folder_summary_get_unread_count (s);
+ record->visible_count = camel_folder_summary_get_visible_count (s);
+ record->jnd_count = camel_folder_summary_get_junk_not_deleted_count (s);
return record;
}
GHashTable *searched = g_hash_table_new (NULL, NULL);
CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
gboolean is_folder_unmatched = vf == folder_unmatched && folder_unmatched;
- GHashTable *folder_unmatched_hash = NULL;
+ CamelFolderSummary *folder_unmatched_summary = NULL;
vee_folder_propagate_skipped_changes (vf);
if (is_folder_unmatched) {
expr = g_strdup (expression);
- folder_unmatched_hash = camel_folder_summary_get_hashtable (((CamelFolder *) folder_unmatched)->summary);
+ folder_unmatched_summary = ((CamelFolder *) folder_unmatched)->summary;
} else {
expr = g_strdup_printf ("(and %s %s)", vf->expression ? vf->expression : "", expression);
}
memcpy (vuid, hash, 8);
strcpy (vuid + 8, uid);
- if (!is_folder_unmatched || g_hash_table_lookup (folder_unmatched_hash, vuid) != NULL)
+ if (!is_folder_unmatched || camel_folder_summary_check_uid (folder_unmatched_summary, vuid))
g_ptr_array_add (result, (gpointer) camel_pstring_strdup (vuid));
g_free (vuid);
}
node = g_list_next (node);
}
- if (folder_unmatched_hash)
- camel_folder_summary_free_hashtable (folder_unmatched_hash);
g_free (expr);
g_hash_table_destroy (searched);
CamelVeeMessageInfo *mi;
CamelMimeMessage *msg = NULL;
- mi = (CamelVeeMessageInfo *) camel_folder_summary_uid (folder->summary, uid);
+ mi = (CamelVeeMessageInfo *) camel_folder_summary_get (folder->summary, uid);
if (mi) {
msg = camel_folder_get_message_sync (
- mi->summary->folder, camel_message_info_uid (mi) + 8,
+ camel_folder_summary_get_folder (mi->orig_summary), camel_message_info_uid (mi) + 8,
cancellable, error);
camel_message_info_free ((CamelMessageInfo *) mi);
} else {
CamelStore *parent_store;
const gchar *full_name;
GList *del = NULL;
- gint i, count;
+ gint i;
+ GPtrArray *known_uids;
camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
- count = camel_folder_summary_count (folder->summary);
- for (i = 0; i < count; i++) {
- CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *) camel_folder_summary_index (folder->summary, i);
+ known_uids = camel_folder_summary_get_array (folder->summary);
+ for (i = 0; known_uids && i < known_uids->len; i++) {
+ CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *) camel_folder_summary_get (folder->summary, g_ptr_array_index (known_uids, i));
if (mi->old_flags & CAMEL_MESSAGE_DELETED) {
del = g_list_prepend (del, (gpointer) camel_pstring_strdup (((CamelMessageInfo *) mi)->uid));
- camel_folder_summary_update_counts_by_flags (folder->summary, mi->old_flags, TRUE);
- camel_folder_summary_remove_index_fast (folder->summary, i);
- count--;
- i--;
+ camel_folder_summary_remove_uid (folder->summary, ((CamelMessageInfo *) mi)->uid);
}
camel_message_info_free (mi);
}
+ camel_folder_summary_free_array (known_uids);
full_name = camel_folder_get_full_name (folder);
parent_store = camel_folder_get_parent_store (folder);
parent_store = camel_folder_get_parent_store (folder);
summary = folder->summary;
- camel_folder_summary_clear (summary);
+ camel_folder_summary_clear (summary, NULL);
camel_db_recreate_vfolder (parent_store->cdb_w, full_name, NULL);
}
vee_folder_remove_folder_helper (CamelVeeFolder *vf,
CamelFolder *source)
{
- gint i, count, n, still = FALSE, start, last;
+ gint i, n, still = FALSE;
gchar *oldkey;
CamelFolder *folder = (CamelFolder *) vf;
gchar hash[8];
GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
CamelFolderSummary *ssummary = source->summary;
gint killun = FALSE;
+ GPtrArray *known_uids;
if (vf == folder_unmatched)
return;
/* See if we just blow all uid's from this folder away from unmatched, regardless */
if (killun) {
- start = -1;
- last = -1;
camel_folder_summary_prepare_fetch_all (((CamelFolder *) folder_unmatched)->summary, NULL);
- count = camel_folder_summary_count (((CamelFolder *) folder_unmatched)->summary);
- for (i = 0; i < count; i++) {
- CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *) camel_folder_summary_index (((CamelFolder *) folder_unmatched)->summary, i);
+ known_uids = camel_folder_summary_get_array (((CamelFolder *) folder_unmatched)->summary);
+ for (i = 0; known_uids && i < known_uids->len; i++) {
+ CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)
+ camel_folder_summary_get (((CamelFolder *) folder_unmatched)->summary, g_ptr_array_index (known_uids, i));
if (mi) {
- if (mi->summary == ssummary) {
+ if (mi->orig_summary == ssummary) {
camel_folder_change_info_remove_uid (folder_unmatched->changes, camel_message_info_uid (mi));
- camel_folder_summary_update_counts_by_flags (CAMEL_FOLDER (folder_unmatched)->summary, mi->old_flags, TRUE);
- if (last == -1) {
- last = start = i;
- } else if (last + 1 == i) {
- last = i;
- } else {
- camel_folder_summary_remove_range (((CamelFolder *) folder_unmatched)->summary, start, last);
- i -= (last - start) + 1;
- start = last = i;
- }
+ camel_folder_summary_remove_uid (((CamelFolder *) folder_unmatched)->summary, camel_message_info_uid (mi));
}
camel_message_info_free ((CamelMessageInfo *) mi);
}
}
- if (last != -1)
- camel_folder_summary_remove_range (((CamelFolder *) folder_unmatched)->summary, start, last);
+ camel_folder_summary_free_array (known_uids);
}
}
/*FIXME: This can be optimized a lot like, searching for UID in the summary uids */
- start = -1;
- last = -1;
camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
- count = camel_folder_summary_count (folder->summary);
- for (i = 0; i < count; i++) {
- CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *) camel_folder_summary_index (folder->summary, i);
+ known_uids = camel_folder_summary_get_array (folder->summary);
+ for (i = 0; known_uids && i < known_uids->len; i++) {
+ CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *) camel_folder_summary_get (folder->summary, g_ptr_array_index (known_uids, i));
if (mi) {
- if (mi->summary == ssummary) {
+ if (mi->orig_summary == ssummary) {
const gchar *uid = camel_message_info_uid (mi);
camel_folder_change_info_remove_uid (vf->changes, uid);
- camel_folder_summary_update_counts_by_flags (folder->summary, mi->old_flags, TRUE);
+ camel_folder_summary_remove_uid (folder->summary, uid);
- if (last == -1) {
- last = start = i;
- } else if (last + 1 == i) {
- last = i;
- } else {
- camel_folder_summary_remove_range (folder->summary, start, last);
- i -= (last - start) + 1;
- start = last = i;
- }
if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && folder_unmatched != NULL) {
if (still) {
if (g_hash_table_lookup_extended (unmatched_uids, uid, (gpointer *) &oldkey, &oldval)) {
camel_message_info_free ((CamelMessageInfo *) mi);
}
}
-
- if (last != -1)
- camel_folder_summary_remove_range (folder->summary, start, last);
+ camel_folder_summary_free_array (known_uids);
if (folder_unmatched) {
if (camel_folder_change_info_changed (folder_unmatched->changes)) {
GHashTable *allhash, *matchhash, *fullhash;
GList *del_list = NULL;
CamelFolder *folder = (CamelFolder *) vee_folder;
- gint i, n, count, start, last;
+ gint i, n, count;
struct _update_data u;
CamelFolderChangeInfo *vee_folder_changes = NULL, *unmatched_changes = NULL;
CamelVeeFolder *folder_unmatched = vee_folder->parent_vee_store ? vee_folder->parent_vee_store->folder_unmatched : NULL;
CamelFolderSummary *ssummary = source->summary;
gboolean rebuilded = FALSE;
gchar *shash;
+ GPtrArray *known_uids;
/* Since the source of a correlating vfolder has to be requeried in
* full every time it changes, caching the results in the db is not
allhash = g_hash_table_new (g_str_hash, g_str_equal);
fullhash = g_hash_table_new (g_str_hash, g_str_equal);
- all = camel_folder_summary_array (source->summary);
+ all = camel_folder_summary_get_array (source->summary);
for (i = 0; i < all->len; i++) {
if (g_hash_table_lookup (matchhash, all->pdata[i]) == NULL)
g_hash_table_insert (allhash, all->pdata[i], GINT_TO_POINTER (1));
/* scan, looking for "old" uid's to be removed. "old" uid's
* are those that are from previous added sources (not in
* current source) */
- start = -1;
- last = -1;
camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
- count = camel_folder_summary_count (folder->summary);
- for (i = 0; i < count; i++) {
- CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *) camel_folder_summary_index (folder->summary, i);
+ known_uids = camel_folder_summary_get_array (folder->summary);
+ for (i = 0; known_uids && i < known_uids->len; i++) {
+ CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *) camel_folder_summary_get (folder->summary, g_ptr_array_index (known_uids, i));
if (mi) {
- if (mi->summary == ssummary) {
+ if (mi->orig_summary == ssummary) {
gchar *uid = (gchar *) camel_message_info_uid (mi), *oldkey;
gpointer oldval;
if (g_hash_table_lookup (matchhash, uid + 8) == NULL) {
- if (last == -1) {
- last = start = i;
- } else if (last + 1 == i) {
- last = i;
- } else {
- camel_folder_summary_remove_range (folder->summary, start, last);
- i -= (last - start) + 1;
- count -= (last - start) + 1;
- start = last = i;
- }
camel_folder_change_info_remove_uid (vee_folder->changes, camel_message_info_uid (mi));
- camel_folder_summary_update_counts_by_flags (folder->summary, mi->old_flags, TRUE);
+ camel_folder_summary_remove_uid (folder->summary, uid);
+
if (!CAMEL_IS_VEE_FOLDER (source)
&& unmatched_uids != NULL
&& g_hash_table_lookup_extended (unmatched_uids, uid, (gpointer *) &oldkey, &oldval)) {
camel_message_info_free ((CamelMessageInfo *) mi);
}
}
- if (last != -1)
- camel_folder_summary_remove_range (folder->summary, start, last);
+ camel_folder_summary_free_array (known_uids);
if (rebuilded && !correlating)
u.message_uids = g_queue_new ();
if (folder_unmatched != NULL) {
/* scan unmatched, remove any that have vanished, etc */
- count = camel_folder_summary_count (((CamelFolder *) folder_unmatched)->summary);
- for (i = 0; i < count; i++) {
- gchar *uid = camel_folder_summary_uid_from_index (((CamelFolder *) folder_unmatched)->summary, i);
-
- if (uid) {
- if (strncmp (uid, u.hash, 8) == 0) {
- if (g_hash_table_lookup (allhash, uid + 8) == NULL) {
- CamelVeeMessageInfo *vinfo = (CamelVeeMessageInfo *) camel_folder_summary_index (CAMEL_FOLDER (folder_unmatched)->summary, i);
- if (vinfo) {
- camel_folder_summary_update_counts_by_flags (CAMEL_FOLDER (folder_unmatched)->summary, vinfo->old_flags, TRUE);
- camel_message_info_free (vinfo);
+ GPtrArray *known_uids;
+
+ known_uids = camel_folder_summary_get_array (((CamelFolder *) folder_unmatched)->summary);
+ if (known_uids != NULL) {
+ for (i = 0; i < known_uids->len; i++) {
+ const gchar *uid = g_ptr_array_index (known_uids, i);
+
+ if (uid) {
+ if (strncmp (uid, u.hash, 8) == 0) {
+ if (g_hash_table_lookup (allhash, uid + 8) == NULL) {
+ /* no longer exists at all, just remove it entirely */
+ camel_folder_summary_remove_uid (((CamelFolder *) folder_unmatched)->summary, uid);
+ camel_folder_change_info_remove_uid (folder_unmatched->changes, uid);
+ } else {
+ g_hash_table_remove (allhash, uid + 8);
}
- /* no longer exists at all, just remove it entirely */
- camel_folder_summary_remove_index_fast (((CamelFolder *) folder_unmatched)->summary, i);
- camel_folder_change_info_remove_uid (folder_unmatched->changes, uid);
- i--;
- count--;
- } else {
- g_hash_table_remove (allhash, uid + 8);
}
}
- g_free (uid);
}
+ camel_folder_summary_free_array (known_uids);
}
/* now allhash contains all potentially new uid's for the unmatched folder, process */
g_ptr_array_free (match, TRUE);
} else
camel_folder_search_free (source, match);
- camel_folder_free_summary (source, all);
+ camel_folder_summary_free_array (all);
if (unmatched_changes) {
camel_folder_changed (
{
CamelFolder *folder;
- folder = vinfo->summary->folder;
+ folder = camel_folder_summary_get_folder (vinfo->orig_summary);
/* locking? yes? no? although the vfolderinfo is valid when obtained
* the folder in it might not necessarily be so ...? */
CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *) info;
camel_pstring_free (info->uid);
- g_object_unref (mi->summary);
+ g_object_unref (mi->orig_summary);
}
static CamelMessageInfo *
to = (CamelVeeMessageInfo *) camel_message_info_new (s);
- to->summary = g_object_ref (from->summary);
+ to->orig_summary = g_object_ref (from->orig_summary);
to->info.summary = s;
to->info.uid = camel_pstring_strdup (from->info.uid);
CamelMessageInfo *rmi;
gpointer p;
- rmi = camel_folder_summary_uid (vmi->summary, mi->uid + 8);
+ rmi = camel_folder_summary_get (vmi->orig_summary, mi->uid + 8);
HANDLE_NULL_INFO (NULL);
p = (gpointer) camel_message_info_ptr (rmi, id);
camel_message_info_free (rmi);
vee_info_uint32 (const CamelMessageInfo *mi,
gint id)
{
- CamelMessageInfo *rmi = camel_folder_summary_uid (((CamelVeeMessageInfo *) mi)->summary, mi->uid + 8);
+ CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary, mi->uid + 8);
guint32 ret;
HANDLE_NULL_INFO (0);
vee_info_time (const CamelMessageInfo *mi,
gint id)
{
- CamelMessageInfo *rmi = camel_folder_summary_uid (((CamelVeeMessageInfo *) mi)->summary, mi->uid + 8);
+ CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary, mi->uid + 8);
time_t ret;
HANDLE_NULL_INFO (0);
vee_info_user_flag (const CamelMessageInfo *mi,
const gchar *id)
{
- CamelMessageInfo *rmi = camel_folder_summary_uid (((CamelVeeMessageInfo *) mi)->summary, mi->uid + 8);
+ CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary, mi->uid + 8);
gboolean ret;
HANDLE_NULL_INFO (FALSE);
vee_info_user_tag (const CamelMessageInfo *mi,
const gchar *id)
{
- CamelMessageInfo *rmi = camel_folder_summary_uid (((CamelVeeMessageInfo *) mi)->summary, mi->uid + 8);
+ CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary, mi->uid + 8);
const gchar *ret;
HANDLE_NULL_INFO("");
gboolean value)
{
gint res = FALSE;
- CamelVeeFolder *vf = (CamelVeeFolder *) mi->summary->folder;
+ CamelVeeFolder *vf = (CamelVeeFolder *) camel_folder_summary_get_folder (mi->summary);
if (camel_debug("vfolderexp"))
printf (
"Expression for vfolder '%s' is '%s'\n",
- camel_folder_get_full_name (mi->summary->folder),
+ camel_folder_get_full_name (camel_folder_summary_get_folder (mi->summary)),
g_strescape (vf->expression, ""));
if (mi->uid) {
- CamelMessageInfo *rmi = camel_folder_summary_uid (((CamelVeeMessageInfo *) mi)->summary, mi->uid + 8);
+ CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary, mi->uid + 8);
+
HANDLE_NULL_INFO (FALSE);
/* ignore changes done in the folder itself,
* unless it's a vTrash or vJunk folder */
if (!CAMEL_IS_VTRASH_FOLDER (vf))
- camel_vee_folder_ignore_next_changed_event (vf, rmi->summary->folder);
+ camel_vee_folder_ignore_next_changed_event (vf, camel_folder_summary_get_folder (rmi->summary));
res = camel_message_info_set_user_flag (rmi, name, value);
gint res = FALSE;
if (mi->uid) {
- CamelMessageInfo *rmi = camel_folder_summary_uid (((CamelVeeMessageInfo *) mi)->summary, mi->uid + 8);
+ CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary, mi->uid + 8);
+ CamelFolder *folder = camel_folder_summary_get_folder (mi->summary);
+
HANDLE_NULL_INFO (FALSE);
/* ignore changes done in the folder itself,
* unless it's a vTrash or vJunk folder */
- if (!CAMEL_IS_VTRASH_FOLDER (mi->summary->folder))
- camel_vee_folder_ignore_next_changed_event ((CamelVeeFolder *) mi->summary->folder, rmi->summary->folder);
+ if (!CAMEL_IS_VTRASH_FOLDER (folder))
+ camel_vee_folder_ignore_next_changed_event ((CamelVeeFolder *) folder, camel_folder_summary_get_folder (rmi->summary));
res = camel_message_info_set_user_tag (rmi, name, value);
camel_message_info_free (rmi);
guint32 set)
{
gint res = FALSE;
- CamelVeeFolder *vf = (CamelVeeFolder *) mi->summary->folder;
+ CamelVeeFolder *vf = CAMEL_VEE_FOLDER (camel_folder_summary_get_folder (mi->summary));
if (camel_debug("vfolderexp"))
printf (
"Expression for vfolder '%s' is '%s'\n",
- camel_folder_get_full_name (mi->summary->folder),
+ camel_folder_get_full_name (CAMEL_FOLDER (vf)),
g_strescape (vf->expression, ""));
+ /* first update original message info... */
if (mi->uid) {
- CamelMessageInfo *rmi = camel_folder_summary_uid (((CamelVeeMessageInfo *) mi)->summary, mi->uid + 8);
+ CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary, mi->uid + 8);
HANDLE_NULL_INFO (FALSE);
- camel_folder_summary_update_counts_by_flags (mi->summary, camel_message_info_flags (rmi), TRUE);
-
/* ignore changes done in the folder itself,
* unless it's a vTrash or vJunk folder */
if (!CAMEL_IS_VTRASH_FOLDER (vf))
- camel_vee_folder_ignore_next_changed_event (vf, rmi->summary->folder);
+ camel_vee_folder_ignore_next_changed_event (vf, camel_folder_summary_get_folder (rmi->summary));
- camel_folder_freeze (rmi->summary->folder);
+ camel_folder_freeze (camel_folder_summary_get_folder (rmi->summary));
res = camel_message_info_set_flags (rmi, flags, set);
((CamelVeeMessageInfo *) mi)->old_flags = camel_message_info_flags (rmi);
- camel_folder_thaw (rmi->summary->folder);
-
- /* Keep the summary in sync */
- camel_folder_summary_update_counts_by_flags (mi->summary, camel_message_info_flags (rmi), FALSE);
-
- d(printf("VF %d %d %d %d %d\n", mi->summary->unread_count, mi->summary->deleted_count, mi->summary->junk_count, mi->summary->junk_not_deleted_count, mi->summary->visible_count));
-
- if (res && mi->summary && mi->summary->folder) {
- CamelFolderChangeInfo *changes = camel_folder_change_info_new ();
-
- camel_folder_change_info_change_uid (changes, camel_message_info_uid (mi));
- camel_folder_changed (mi->summary->folder, changes);
- camel_folder_change_info_free (changes);
- }
+ camel_folder_thaw (camel_folder_summary_get_folder (rmi->summary));
camel_message_info_free (rmi);
}
+ if (res)
+ CAMEL_FOLDER_SUMMARY_CLASS (camel_vee_summary_parent_class)->info_set_flags (mi, flags, set);
+
return res;
}
{
CamelMessageInfo *info;
- /* FIXME[disk-summary] too bad design. Need to peek it from cfs
- * instead of hacking ugly like this */
- camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-
- info = g_hash_table_lookup (s->loaded_infos, uid);
-
- if (info)
- camel_message_info_ref (info);
-
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-
+ info = camel_folder_summary_peek_loaded (s, uid);
if (!info) {
CamelVeeMessageInfo *vinfo;
gchar tmphash[9];
* Otherwise, the first byte itself would return in strcmp, saving the CPU.
*/
if (!camel_folder_summary_check_uid (s, uid)) {
- d(g_message ("Unable to find %s in the summary of %s", uid, s->folder->full_name));
+ d(g_message ("Unable to find %s in the summary of %s", uid,
+ camel_folder_get_full_name (camel_folder_summary_get_folder (s->folder))));
return NULL;
}
info->uid = camel_pstring_strdup (uid);
strncpy (tmphash, uid, 8);
tmphash[8] = 0;
- vinfo->summary = g_hash_table_lookup (((CamelVeeFolder *) s->folder)->hashes, tmphash);
- g_object_ref (vinfo->summary);
+ vinfo->orig_summary = g_hash_table_lookup (((CamelVeeFolder *) camel_folder_summary_get_folder (s))->hashes, tmphash);
+ g_object_ref (vinfo->orig_summary);
camel_folder_summary_insert (s, info, FALSE);
}
+
return info;
}
CamelStore *parent_store;
const gchar *full_name;
- s = g_object_new (CAMEL_TYPE_VEE_SUMMARY, NULL);
- s->summary.folder = parent;
+ s = g_object_new (CAMEL_TYPE_VEE_SUMMARY, "folder", parent, NULL);
- /* FIXME[disk-summary] fix exceptions and note return values */
- /* FIXME[disk-summary] if Evo's junk/trash vfolders make it VJunk
- * VTrash instead of .#evolution/Junk-or-whatever */
full_name = camel_folder_get_full_name (parent);
parent_store = camel_folder_get_parent_store (parent);
camel_db_create_vfolder (parent_store->cdb_w, full_name, NULL);
- return &s->summary;
+ return (CamelFolderSummary *) s;
}
/**
const gchar *full_name;
/* FIXME[disk-summary] fix exception passing */
- full_name = camel_folder_get_full_name (cfs->folder);
- parent_store = camel_folder_get_parent_store (cfs->folder);
+ full_name = camel_folder_get_full_name (camel_folder_summary_get_folder (cfs));
+ parent_store = camel_folder_get_parent_store (camel_folder_summary_get_folder (cfs));
array = camel_db_get_vuids_from_vfolder (parent_store->cdb_r, full_name, shash, NULL);
g_free (shash);
memcpy (vuid, hash, 8);
strcpy (vuid + 8, uid);
- camel_folder_summary_lock (CAMEL_FOLDER_SUMMARY (s), CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- mi = (CamelVeeMessageInfo *) g_hash_table_lookup (((CamelFolderSummary *) s)->loaded_infos, vuid);
- camel_folder_summary_unlock (CAMEL_FOLDER_SUMMARY (s), CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-
+ mi = (CamelVeeMessageInfo *) camel_folder_summary_peek_loaded (&s->summary, vuid);
if (mi) {
/* Possible that the entry is loaded, see if it has the summary */
d(g_message ("%s - already there\n", vuid));
g_free (vuid);
- if (!mi->summary)
- mi->summary = g_object_ref (summary);
-
- camel_message_info_ref (mi);
+ if (!mi->orig_summary)
+ mi->orig_summary = g_object_ref (summary);
return mi;
}
mi = (CamelVeeMessageInfo *) camel_message_info_new (&s->summary);
- mi->summary = g_object_ref (summary);
+ mi->orig_summary = g_object_ref (summary);
mi->info.uid = (gchar *) camel_pstring_strdup (vuid);
g_free (vuid);
camel_message_info_ref (mi);
/* Get actual flags and store it */
- rmi = camel_folder_summary_uid (summary, uid);
+ rmi = camel_folder_summary_get (summary, uid);
if (rmi) {
mi->old_flags = camel_message_info_flags (rmi);
camel_message_info_free (rmi);
}
camel_folder_summary_insert (&s->summary, (CamelMessageInfo *) mi, FALSE);
- camel_folder_summary_update_counts_by_flags (&s->summary, camel_message_info_flags (mi), FALSE);
return mi;
}
typedef struct _CamelVeeMessageInfo CamelVeeMessageInfo;
struct _CamelVeeMessageInfo {
- CamelMessageInfo info;
- CamelFolderSummary *summary;
+ CamelMessageInfoBase info;
+ CamelFolderSummary *orig_summary;
guint32 old_flags; /* These are just for identifying changed flags */
};
continue;
}
- if (dest == mi->summary->folder) {
+ if (dest == camel_folder_summary_get_folder (mi->orig_summary)) {
/* Just unset the flag on the original message */
camel_folder_set_message_flags (
source, uids->pdata[i], sbit, 0);
} else {
if (batch == NULL)
batch = g_hash_table_new (NULL, NULL);
- md = g_hash_table_lookup (batch, mi->summary->folder);
+ md = g_hash_table_lookup (batch, camel_folder_summary_get_folder (mi->orig_summary));
if (md == NULL) {
md = g_malloc0 (sizeof (*md));
md->cancellable = cancellable;
- md->folder = g_object_ref (mi->summary->folder);
+ md->folder = g_object_ref (camel_folder_summary_get_folder (mi->orig_summary));
md->uids = g_ptr_array_new ();
md->dest = dest;
md->delete = delete_originals;
if (cancellable != NULL)
g_object_ref (cancellable);
camel_folder_freeze (md->folder);
- g_hash_table_insert (batch, mi->summary->folder, md);
+ g_hash_table_insert (batch, camel_folder_summary_get_folder (mi->orig_summary), md);
}
/* unset the bit temporarily */
imap_folder_dispose (GObject *object)
{
CamelImapFolder *imap_folder;
+ CamelStore *parent_store;
imap_folder = CAMEL_IMAP_FOLDER (object);
imap_folder->journal = NULL;
}
+ parent_store = camel_folder_get_parent_store (CAMEL_FOLDER (imap_folder));
+ if (parent_store) {
+ camel_store_summary_disconnect_folder_summary (
+ (CamelStoreSummary *) ((CamelImapStore *) parent_store)->summary,
+ CAMEL_FOLDER (imap_folder)->summary);
+ }
+
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (camel_imap_folder_parent_class)->dispose (object);
}
imap_folder->search = camel_imap_search_new (folder_dir);
+ camel_store_summary_connect_folder_summary (
+ (CamelStoreSummary *) ((CamelImapStore *) parent)->summary,
+ folder_name, folder->summary);
+
return folder;
}
CamelMessageFlags perm_flags = 0;
GData *fetch_data;
gint i, count;
- gchar *resp, *old_uid;
+ gchar *resp;
count = camel_folder_summary_count (folder->summary);
imap_summary->validity = validity;
else if (validity != imap_summary->validity) {
imap_summary->validity = validity;
- camel_folder_summary_clear (folder->summary);
+ camel_folder_summary_clear (folder->summary, NULL);
CAMEL_IMAP_FOLDER_REC_LOCK (imap_folder, cache_lock);
camel_imap_message_cache_clear (imap_folder->cache);
CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
else if (count != 0 && !imap_folder->need_rescan) {
CamelStore *parent_store;
CamelImapStore *store;
+ GPtrArray *known_uids;
+ const gchar *old_uid;
parent_store = camel_folder_get_parent_store (folder);
store = CAMEL_IMAP_STORE (parent_store);
}
camel_imap_response_free_without_processing (store, response);
- old_uid = camel_folder_summary_uid_from_index (folder->summary, count - 1);
+ known_uids = camel_folder_summary_get_array (folder->summary);
+ camel_folder_sort_uids (folder, known_uids);
+ old_uid = NULL;
+ if (known_uids && count - 1 >= 0 && count - 1 < known_uids->len)
+ old_uid = g_ptr_array_index (known_uids, count - 1);
if (old_uid) {
val = strtoul (old_uid, NULL, 10);
- g_free (old_uid);
if (uid == 0 || uid != val)
imap_folder->need_rescan = TRUE;
}
+ camel_folder_summary_free_array (known_uids);
}
/* Now rescan if we need to */
guint32 unread, total;
total = camel_folder_summary_count (folder->summary);
- unread = folder->summary->unread_count;
+ unread = camel_folder_summary_get_unread_count (folder->summary);
if (si->total != total
|| si->unread != unread) {
if (get_folder_status (folder, &server_total, &server_unread, cancellable, &local_error)) {
total = camel_folder_summary_count (folder->summary);
- unread = folder->summary->unread_count;
+ unread = camel_folder_summary_get_unread_count (folder->summary);
if (total != server_total || unread != server_unread)
check_rescan = 1;
gboolean ok;
CamelFolderChangeInfo *changes = NULL;
gboolean success;
+ GPtrArray *known_uids;
parent_store = camel_folder_get_parent_store (folder);
store = CAMEL_IMAP_STORE (parent_store);
imap_folder->need_rescan = FALSE;
- summary_len = camel_folder_summary_count (folder->summary);
+ known_uids = camel_folder_summary_get_array (folder->summary);
+ summary_len = known_uids ? known_uids->len : 0;
if (summary_len == 0) {
+ camel_folder_summary_free_array (known_uids);
if (exists)
return camel_imap_folder_changed (
folder, exists, NULL, cancellable, error);
camel_operation_push_message (
cancellable, _("Scanning for changed messages in %s"),
camel_folder_get_display_name (folder));
- uid = camel_folder_summary_uid_from_index (folder->summary, summary_len - 1);
+ camel_folder_sort_uids (folder, known_uids);
+
+ uid = g_ptr_array_index (known_uids, summary_len - 1);
if (!uid) {
camel_operation_pop_message (cancellable);
+ camel_folder_summary_free_array (known_uids);
return TRUE;
}
ok = camel_imap_command_start (
store, folder, cancellable, error,
"UID FETCH 1:%s (FLAGS)", uid);
- g_free (uid);
if (!ok) {
camel_operation_pop_message (cancellable);
+ camel_folder_summary_free_array (known_uids);
return FALSE;
}
g_free (new);
g_free (resp);
+ camel_folder_summary_free_array (known_uids);
return TRUE;
}
if (type != CAMEL_IMAP_RESPONSE_ERROR && type != CAMEL_IMAP_RESPONSE_TAGGED)
camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+ camel_folder_summary_free_array (known_uids);
return TRUE;
}
for (i = 0, j = 0; i < summary_len && new[j].uid; i++) {
gboolean changed = FALSE;
- uid = camel_folder_summary_uid_from_index (folder->summary, i);
-
+ uid = g_ptr_array_index (known_uids, i);
if (!uid)
continue;
- info = camel_folder_summary_uid (folder->summary, uid);
+ info = camel_folder_summary_get (folder->summary, uid);
if (!info) {
if (g_getenv("CRASH_IMAP")) { /* Debug logs to tackle on hard to get imap crasher */
printf ("CRASH: %s: %s",
iinfo = (CamelImapMessageInfo *) info;
if (strcmp (uid, new[j].uid) != 0) {
- g_free (uid);
-
- /* these will be deleted from db in a moment. So adjust the counts please */
- if (info) {
- CamelMessageInfoBase *dinfo = (CamelMessageInfoBase *) info;
- gint unread = 0, deleted = 0, junk = 0;
- guint32 flags;
-
- flags = dinfo->flags;
- if (!(flags & CAMEL_MESSAGE_SEEN))
- unread = 1;
-
- if (flags & CAMEL_MESSAGE_DELETED)
- deleted = 1;
-
- if (flags & CAMEL_MESSAGE_JUNK)
- junk = 1;
-
- if (unread)
- folder->summary->unread_count--;
-
- if (deleted)
- folder->summary->deleted_count--;
- if (junk)
- folder->summary->junk_count--;
-
- if (junk && !deleted)
- folder->summary->junk_not_deleted_count--;
-
- if (!junk && !deleted)
- folder->summary->visible_count--;
-
- folder->summary->saved_count--;
- }
seq = i + 1 - del;
del++;
g_array_append_val (removed, seq);
continue;
}
- g_free (uid);
-
/* Update summary flags */
if (new[j].flags != iinfo->server_flags) {
guint32 server_set, server_cleared;
- gint read = 0, deleted = 0, junk = 0;
server_set = new[j].flags & ~iinfo->server_flags;
server_cleared = iinfo->server_flags & ~new[j].flags;
- if (server_set & CAMEL_MESSAGE_SEEN)
- read = 1;
- else if (server_cleared & CAMEL_MESSAGE_SEEN)
- read = -1;
-
- if (server_set & CAMEL_MESSAGE_DELETED)
- deleted = 1;
- else if (server_cleared & CAMEL_MESSAGE_DELETED)
- deleted = -1;
-
- if (server_set & CAMEL_MESSAGE_JUNK)
- junk = 1;
- else if (server_cleared & CAMEL_MESSAGE_JUNK)
- junk = -1;
-
- d(printf("%s %s %s %s\n", iinfo->info.uid, read == 1 ? "read" : ( read == -1 ? "unread" : ""),
- deleted == 1 ? "deleted" : ( deleted == -1 ? "undeleted" : ""),
- junk == 1 ? "junk" : ( junk == -1 ? "unjunked" : "")));
-
- if (read)
- folder->summary->unread_count -= read;
- if (deleted)
- folder->summary->deleted_count += deleted;
- if (junk)
- folder->summary->junk_count += junk;
- if (junk && !deleted)
- folder->summary->junk_not_deleted_count += junk;
- if (junk || deleted)
- folder->summary->visible_count -= junk ? junk : deleted;
-
- iinfo->info.flags = (iinfo->info.flags | server_set) & ~server_cleared;
+ camel_message_info_set_flags ((CamelMessageInfo *) iinfo, server_set | server_cleared, (iinfo->info.flags | server_set) & ~server_cleared);
iinfo->server_flags = new[j].flags;
+ /* unset folder_flagged, because these are flags received froma server */
+ iinfo->info.flags = iinfo->info.flags & (~CAMEL_MESSAGE_FOLDER_FLAGGED);
iinfo->info.dirty = TRUE;
if (info->summary)
camel_folder_summary_touch (info->summary);
*/
for (i = seq; i <= summary_len; i++) {
- CamelMessageInfoBase *dinfo;
gint j;
- dinfo = (CamelMessageInfoBase *) camel_folder_summary_index (folder->summary, i - 1);
- if (dinfo) {
- /* these will be deleted from db in a moment. So adjust the counts please */
- gint unread = 0, deleted = 0, junk = 0;
- guint32 flags;
-
- flags = dinfo->flags;
- if (!(flags & CAMEL_MESSAGE_SEEN))
- unread = 1;
- if (flags & CAMEL_MESSAGE_DELETED)
- deleted = 1;
-
- if (flags & CAMEL_MESSAGE_JUNK)
- junk = 1;
-
- if (unread)
- folder->summary->unread_count--;
-
- if (deleted)
- folder->summary->deleted_count--;
- if (junk)
- folder->summary->junk_count--;
-
- if (junk && !deleted)
- folder->summary->junk_not_deleted_count--;
-
- if (!junk && !deleted)
- folder->summary->visible_count--;
-
- folder->summary->saved_count--;
- camel_message_info_free (dinfo);
- }
j = seq - del;
g_array_append_val (removed, j);
}
folder, exists, removed, cancellable, error);
g_array_free (removed, TRUE);
+ camel_folder_summary_free_array (known_uids);
return success;
}
uid = summary->pdata[i];
if (uid) {
- info = (CamelImapMessageInfo *) camel_folder_summary_uid (folder->summary, uid);
+ info = (CamelImapMessageInfo *) camel_folder_summary_get (folder->summary, uid);
} else
continue;
full_name = camel_folder_get_full_name (folder);
si = camel_store_summary_path ((CamelStoreSummary *)((CamelImapStore *) parent_store)->summary, full_name);
if (si) {
- if (si->total != folder->summary->saved_count || si->unread != folder->summary->unread_count) {
- si->total = folder->summary->saved_count;
- si->unread = folder->summary->unread_count;
+ if (si->total != camel_folder_summary_get_saved_count (folder->summary) || si->unread != camel_folder_summary_get_unread_count (folder->summary)) {
+ si->total = camel_folder_summary_get_saved_count (folder->summary);
+ si->unread = camel_folder_summary_get_unread_count (folder->summary);
camel_store_summary_touch ((CamelStoreSummary *)((CamelImapStore *) parent_store)->summary);
}
if (!uid) /* Possibly it was sync by matching flags, which we NULLify */
continue;
- if (!(info = (CamelImapMessageInfo *) camel_folder_summary_uid (folder->summary, uid))) {
+ if (!(info = (CamelImapMessageInfo *) camel_folder_summary_get (folder->summary, uid))) {
continue;
}
changes = camel_folder_change_info_new ();
for (i = 0; i < uids->len; i++) {
- camel_folder_summary_remove_uid_fast (folder->summary, uids->pdata[i]);
+ camel_folder_summary_remove_uid (folder->summary, uids->pdata[i]);
camel_folder_change_info_remove_uid (changes, uids->pdata[i]);
list = g_list_prepend (list, (gpointer) uids->pdata[i]);
/* We intentionally don't remove it from the cache because
changes = camel_folder_change_info_new ();
for (i = 0; i < uids->len; i++) {
- camel_folder_summary_remove_uid_fast (folder->summary, uids->pdata[i]);
+ camel_folder_summary_remove_uid (folder->summary, uids->pdata[i]);
camel_folder_change_info_remove_uid (changes, uids->pdata[i]);
list = g_list_prepend (list, (gpointer) uids->pdata[i]);
/* We intentionally don't remove it from the cache because
CamelStore *parent_store;
GPtrArray *uids = NULL;
const gchar *full_name;
- gboolean success;
+ gboolean success, real_trash = FALSE;
full_name = camel_folder_get_full_name (folder);
parent_store = camel_folder_get_parent_store (folder);
if (local_error == NULL && trash && (folder == trash || g_ascii_strcasecmp (full_name, camel_folder_get_full_name (trash)) == 0)) {
/* it's a real trash folder, thus get all mails from there */
- uids = camel_folder_summary_array (folder->summary);
+ real_trash = TRUE;
+ uids = camel_folder_summary_get_array (folder->summary);
}
if (local_error != NULL)
success = imap_expunge_uids_offline (
folder, uids, cancellable, error);
- g_ptr_array_foreach (uids, (GFunc) camel_pstring_free, NULL);
- g_ptr_array_free (uids, TRUE);
+ if (real_trash) {
+ camel_folder_summary_free_array (uids);
+ } else {
+ g_ptr_array_foreach (uids, (GFunc) camel_pstring_free, NULL);
+ g_ptr_array_free (uids, TRUE);
+ }
return success;
}
destuid = get_temp_uid ();
- mi = camel_folder_summary_uid (source->summary, uid);
+ mi = camel_folder_summary_get (source->summary, uid);
g_return_val_if_fail (mi != NULL, FALSE);
message = camel_folder_get_message_sync (
camel_folder_delete_message (
source, uids->pdata[i]);
if (mark_moved) {
- CamelMessageInfoBase *info = (CamelMessageInfoBase *) camel_folder_summary_uid (source->summary, uids->pdata[i]);
+ CamelMessageInfoBase *info = (CamelMessageInfoBase *) camel_folder_summary_get (source->summary, uids->pdata[i]);
if (info)
info->flags |= CAMEL_MESSAGE_IMAP_MOVED;
GError **error)
{
CamelImapMessageInfo *mi;
- mi = (CamelImapMessageInfo *) camel_folder_summary_uid (summary, uid);
+ mi = (CamelImapMessageInfo *) camel_folder_summary_get (summary, uid);
if (mi == NULL) {
g_set_error (
error, CAMEL_FOLDER_ERROR,
|| store->braindamaged
|| mi->info.size < IMAP_SMALL_BODY_SIZE
|| (!content_info_incomplete (mi->info.content) && !mi->info.content->childs)) {
- CamelMessageInfoBase *info = (CamelMessageInfoBase *) camel_folder_summary_uid (folder->summary, uid);
+ CamelMessageInfoBase *info = (CamelMessageInfoBase *) camel_folder_summary_get (folder->summary, uid);
msg = get_message_simple (imap_folder, uid, NULL, cancellable, &local_error);
if (info && !info->preview && msg && camel_folder_summary_get_need_preview (folder->summary)) {
if (camel_mime_message_build_preview ((CamelMimePart *) msg, (CamelMessageInfo *) info) && info->preview)
else
msg = get_message (imap_folder, uid, mi->info.content, cancellable, &local_error);
if (msg && camel_folder_summary_get_need_preview (folder->summary)) {
- CamelMessageInfoBase *info = (CamelMessageInfoBase *) camel_folder_summary_uid (folder->summary, uid);
+ CamelMessageInfoBase *info = (CamelMessageInfoBase *) camel_folder_summary_get (folder->summary, uid);
if (info && !info->preview) {
if (camel_mime_message_build_preview ((CamelMimePart *) msg, (CamelMessageInfo *) info) && info->preview)
camel_folder_summary_add_preview (folder->summary, (CamelMessageInfo *) info);
}
}
-static void
-update_summary (CamelFolderSummary *summary,
- CamelMessageInfoBase *info)
-{
- gint unread = 0, deleted = 0, junk = 0;
- guint32 flags = info->flags;
-
- if (!(flags & CAMEL_MESSAGE_SEEN))
- unread = 1;
-
- if (flags & CAMEL_MESSAGE_DELETED)
- deleted = 1;
-
- if (flags & CAMEL_MESSAGE_JUNK)
- junk = 1;
-
- if (summary) {
-
- if (unread)
- summary->unread_count += unread;
- if (deleted)
- summary->deleted_count += deleted;
- if (junk)
- summary->junk_count += junk;
- if (junk && !deleted)
- summary->junk_not_deleted_count += junk;
- summary->visible_count++;
- if (junk || deleted)
- summary->visible_count -= junk ? junk : deleted;
-
- summary->saved_count++;
- camel_folder_summary_touch (summary);
- }
-}
-
#define CAMEL_MESSAGE_INFO_HEADERS "DATE FROM TO CC SUBJECT REFERENCES IN-REPLY-TO MESSAGE-ID MIME-VERSION CONTENT-TYPE CONTENT-CLASS X-CALENDAR-ATTACHMENT "
/* FIXME: this needs to be kept in sync with camel-mime-utils.c's list
seq = camel_folder_summary_count (folder->summary);
first = seq + 1;
if (seq > 0) {
- tempuid = camel_folder_summary_uid_from_index (folder->summary, seq -1 );
+ GPtrArray *known_uids;
- if (tempuid) {
- uidval = strtoul (tempuid, NULL, 10);
- g_free (tempuid);
+ known_uids = camel_folder_summary_get_array (folder->summary);
+ if (known_uids) {
+ camel_folder_sort_uids (folder, known_uids);
+
+ tempuid = g_ptr_array_index (known_uids, seq - 1);
+ if (tempuid)
+ uidval = strtoul (tempuid, NULL, 10);
+ else
+ uidval = 0;
+
+ camel_folder_summary_free_array (known_uids);
} else
uidval = 0;
} else
/* FIXME: If it enters if (info) it will always match the exception. So stupid */
/* FIXME[disk-summary] Use a db query to see if the DB exists */
-/* info = (CamelImapMessageInfo *)camel_folder_summary_uid(folder->summary, uid); */
+/* info = (CamelImapMessageInfo *)camel_folder_summary_get (folder->summary, uid); */
/* if (info) { */
/* for (seq = 0; seq < camel_folder_summary_count (folder->summary); seq++) { */
/* if (folder->summary->messages->pdata[seq] == info) */
if (((CamelMessageInfoBase *) mi)->summary)
camel_folder_summary_touch (((CamelMessageInfoBase *) mi)->summary);
camel_folder_summary_add (folder->summary, (CamelMessageInfo *) mi);
- update_summary (folder->summary, (CamelMessageInfoBase *) mi);
camel_folder_change_info_add_uid (changes, camel_message_info_uid (mi));
/* Report all new messages as recent, even without that flag, thus new
CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
CamelFolderChangeInfo *changes;
gint len;
- gchar *uid;
gboolean success = TRUE;
changes = camel_folder_change_info_new ();
gint i, id;
GList *deleted = NULL;
const gchar *full_name;
+ const gchar *uid;
+ GPtrArray *known_uids;
+ known_uids = camel_folder_summary_get_array (folder->summary);
+ camel_folder_sort_uids (folder, known_uids);
for (i = 0; i < expunged->len; i++) {
id = g_array_index (expunged, int, i);
- uid = camel_folder_summary_uid_from_index (folder->summary, id - 1);
+ uid = id - 1 + i >= 0 && id - 1 + i < known_uids->len ? g_ptr_array_index (known_uids, id - 1 + i) : NULL;
if (uid == NULL) {
/* FIXME: danw: does this mean that the summary is corrupt? */
/* I guess a message that we never retrieved got expunged? */
continue;
}
- deleted = g_list_prepend (deleted, uid);
+ deleted = g_list_prepend (deleted, (gpointer) uid);
camel_folder_change_info_remove_uid (changes, uid);
CAMEL_IMAP_FOLDER_REC_LOCK (imap_folder, cache_lock);
camel_imap_message_cache_remove (imap_folder->cache, uid);
CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
- camel_folder_summary_remove_index_fast (folder->summary, id - 1);
+ camel_folder_summary_remove_uid (folder->summary, uid);
}
/* Delete all in one transaction */
full_name = camel_folder_get_full_name (folder);
parent_store = camel_folder_get_parent_store (folder);
camel_db_delete_uids (parent_store->cdb_w, full_name, deleted, NULL);
- g_list_foreach (deleted, (GFunc) g_free, NULL);
g_list_free (deleted);
+
+ camel_folder_summary_free_array (known_uids);
}
len = camel_folder_summary_count (folder->summary);
const gchar *dname;
gchar *uid, *p;
GPtrArray *deletes;
- GHashTable *shash;
dir = g_dir_open (path, 0, error);
if (!dir) {
cache->parts = g_hash_table_new (g_str_hash, g_str_equal);
cache->cached = g_hash_table_new (NULL, NULL);
deletes = g_ptr_array_new ();
- shash = camel_folder_summary_get_hashtable (summary);
while ((dname = g_dir_read_name (dir))) {
if (!isdigit (dname[0]))
else
uid = g_strdup (dname);
- if (g_hash_table_lookup (shash, uid))
+ if (camel_folder_summary_check_uid (summary, uid))
cache_put (cache, uid, dname, NULL);
else
g_ptr_array_add (deletes, g_strdup_printf ("%s/%s", cache->path, dname));
}
g_ptr_array_free (deletes, TRUE);
- camel_folder_summary_free_hashtable (shash);
-
return cache;
}
imap_summary_is_dirty (CamelFolderSummary *summary)
{
CamelImapMessageInfo *info;
- gint max, i;
- gint found = FALSE;
+ gint i;
+ gboolean found = FALSE;
+ GPtrArray *known_uids;
+
+ known_uids = camel_folder_summary_get_array (summary);
+ g_return_val_if_fail (known_uids != NULL, FALSE);
- max = camel_folder_summary_count (summary);
- for (i = 0; i < max && !found; i++) {
- info = (CamelImapMessageInfo *) camel_folder_summary_index (summary, i);
+ for (i = 0; i < known_uids->len && !found; i++) {
+ info = (CamelImapMessageInfo *) camel_folder_summary_get (summary, g_ptr_array_index (known_uids, i));
if (info) {
found = info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED;
camel_message_info_free (info);
}
}
- return FALSE;
+ camel_folder_summary_free_array (known_uids);
+
+ return found;
}
static gboolean
else
ims = (CamelImapSummary *) camel_imap_summary_new (folder, NULL);
- fi->unread = ((CamelFolderSummary *) ims)->unread_count;
- fi->total = ((CamelFolderSummary *) ims)->saved_count;
+ fi->unread = camel_folder_summary_get_unread_count ((CamelFolderSummary *) ims);
+ fi->total = camel_folder_summary_get_saved_count ((CamelFolderSummary *) ims);
if (!folder->summary)
g_object_unref (ims);
return fi;
}
-#if 0
-static gboolean
-folder_flags_have_changed (CamelFolder *folder)
-{
- CamelMessageInfo *info;
- gint i, max;
-
- max = camel_folder_summary_count (folder->summary);
- for (i = 0; i < max; i++) {
- info = camel_folder_summary_index (folder->summary, i);
- if (!info)
- continue;
- if (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-#endif
-
/* Use this whenever you need to ensure you're both connected and
* online. */
gboolean
static gboolean info_set_user_flag (CamelMessageInfo *info, const gchar *id, gboolean state);
static CamelMessageContentInfo *content_info_migrate (CamelFolderSummary *s, FILE *in);
-static gint summary_header_from_db (CamelFolderSummary *s, CamelFIRecord *mir);
+static gboolean summary_header_from_db (CamelFolderSummary *s, CamelFIRecord *mir);
static CamelFIRecord * summary_header_to_db (CamelFolderSummary *s, GError **error);
static CamelMIRecord * message_info_to_db (CamelFolderSummary *s, CamelMessageInfo *info);
static CamelMessageInfo * message_info_from_db (CamelFolderSummary *s, CamelMIRecord *mir);
-static gint content_info_to_db (CamelFolderSummary *s, CamelMessageContentInfo *info, CamelMIRecord *mir);
+static gboolean content_info_to_db (CamelFolderSummary *s, CamelMessageContentInfo *info, CamelMIRecord *mir);
static CamelMessageContentInfo * content_info_from_db (CamelFolderSummary *s, CamelMIRecord *mir);
G_DEFINE_TYPE (CamelImapSummary, camel_imap_summary, CAMEL_TYPE_FOLDER_SUMMARY)
return (a1 < a1) ? -1 : (a1 > a2) ? 1 : 0;
}
-static gint
-uid_compare (gconstpointer va,
- gconstpointer vb)
-{
- const gchar **sa = (const gchar **) va, **sb = (const gchar **) vb;
- gulong a, b;
-
- a = strtoul (*sa, NULL, 10);
- b = strtoul (*sb, NULL, 10);
- if (a < b)
- return -1;
- else if (a == b)
- return 0;
- else
- return 1;
-}
-
/**
* camel_imap_summary_new:
* @folder: Parent folder.
parent_store = camel_folder_get_parent_store (folder);
- summary = g_object_new (CAMEL_TYPE_IMAP_SUMMARY, NULL);
- summary->folder = folder;
+ summary = g_object_new (CAMEL_TYPE_IMAP_SUMMARY, "folder", folder, NULL);
+
/* Don't do DB sort. Its pretty slow to load */
if (folder && 0) {
camel_db_set_collate (
camel_folder_summary_set_build_content (summary, TRUE);
camel_folder_summary_set_filename (summary, filename);
- if (camel_folder_summary_load_from_db (summary, NULL) == -1) {
+ if (!camel_folder_summary_load_from_db (summary, NULL)) {
/* FIXME: Isn't this dangerous ? We clear the summary
if it cannot be loaded, for some random reason.
We need to pass the ex and find out why it is not loaded etc. ? */
- camel_folder_summary_clear_db (summary);
+ camel_folder_summary_clear (summary, NULL);
}
- g_ptr_array_sort (summary->uids, (GCompareFunc) uid_compare);
-
return summary;
}
-static gint
+static gboolean
summary_header_from_db (CamelFolderSummary *s,
CamelFIRecord *mir)
{
CamelImapSummary *ims = CAMEL_IMAP_SUMMARY (s);
gchar *part;
- if (CAMEL_FOLDER_SUMMARY_CLASS (camel_imap_summary_parent_class)->summary_header_from_db (s, mir) == -1)
- return -1;
+ if (!CAMEL_FOLDER_SUMMARY_CLASS (camel_imap_summary_parent_class)->summary_header_from_db (s, mir))
+ return FALSE;
part = mir->bdata;
if (ims->version > CAMEL_IMAP_SUMMARY_VERSION) {
g_warning("Unkown summary version\n");
errno = EINVAL;
- return -1;
+ return FALSE;
}
- return 0;
+ return TRUE;
}
static gint
return camel_folder_summary_content_info_new (s);
}
-static gint
+static gboolean
content_info_to_db (CamelFolderSummary *s,
CamelMessageContentInfo *info,
CamelMIRecord *mir)
oldr = mir->cinfo;
mir->cinfo = oldr ? g_strdup_printf("%s 0", oldr) : g_strdup ("0");
g_free (oldr);
- return 0;
+ return TRUE;
}
}
}
static inline gulong
-get_summary_uid_numeric (CamelFolderSummary *summary,
+get_summary_uid_numeric (GPtrArray *known_uids,
gint index)
{
gulong uid;
- gchar *suid;
+ const gchar *suid;
- suid = camel_folder_summary_uid_from_index (summary, index);
+ g_return_val_if_fail (known_uids != NULL, 0);
+ g_return_val_if_fail (index >= 0, 0);
+ g_return_val_if_fail (index < known_uids->len, 0);
+
+ suid = g_ptr_array_index (known_uids, index);
uid = strtoul (suid, NULL, 10);
- g_free (suid);
return uid;
}
gint si, scount;
GString *gset;
gchar *set;
+ GPtrArray *known_uids;
g_return_val_if_fail (uids->len > uid, NULL);
+ known_uids = camel_folder_summary_get_array (summary);
+ g_return_val_if_fail (known_uids != NULL, NULL);
+
+ camel_folder_sort_uids (camel_folder_summary_get_folder (summary), known_uids);
+
gset = g_string_new (uids->pdata[uid]);
last_uid = strtoul (uids->pdata[uid], NULL, 10);
next_summary_uid = 0;
- scount = camel_folder_summary_count (summary);
+ scount = known_uids->len;
for (uid++, si = 0; uid < uids->len && !UID_SET_FULL (gset->len, maxlen); uid++) {
/* Find the next UID in the summary after the one we
* just wrote out.
*/
for (; last_uid >= next_summary_uid && si < scount; si++)
- next_summary_uid = get_summary_uid_numeric (summary, si);
+ next_summary_uid = get_summary_uid_numeric (known_uids, si);
if (last_uid >= next_summary_uid)
next_summary_uid = (gulong) -1;
set = gset->str;
g_string_free (gset, FALSE);
+ camel_folder_summary_free_array (known_uids);
return set;
}
const gchar *uids)
{
GPtrArray *arr;
+ GPtrArray *known_uids;
gchar *p, *q;
gulong uid, suid;
gint si, scount;
+ known_uids = camel_folder_summary_get_array (summary);
+ g_return_val_if_fail (known_uids != NULL, NULL);
+
+ camel_folder_sort_uids (camel_folder_summary_get_folder (summary), known_uids);
arr = g_ptr_array_new ();
scount = camel_folder_summary_count (summary);
* we just saw.
*/
while (++si < scount) {
- suid = get_summary_uid_numeric (summary, si);
+ suid = get_summary_uid_numeric (known_uids, si);
if (suid > uid)
break;
}
while (suid <= uid) {
g_ptr_array_add (arr, g_strdup_printf ("%lu", suid));
if (++si < scount)
- suid = get_summary_uid_numeric (summary, si);
+ suid = get_summary_uid_numeric (known_uids, si);
else
suid++;
}
p = q;
} while (*p++ == ',');
+ camel_folder_summary_free_array (known_uids);
return arr;
lose:
g_warning ("Invalid uid set %s", uids);
+ camel_folder_summary_free_array (known_uids);
imap_uid_array_free (arr);
return NULL;
}
g_free (summary_file);
+ camel_store_summary_connect_folder_summary (
+ (CamelStoreSummary *) ((CamelIMAPXStore *) store)->summary,
+ folder_name, folder->summary);
+
return folder;
}
imapx_folder_dispose (GObject *object)
{
CamelIMAPXFolder *folder = CAMEL_IMAPX_FOLDER (object);
+ CamelStore *parent_store;
if (folder->cache != NULL) {
g_object_unref (folder->cache);
folder->search = NULL;
}
+ parent_store = camel_folder_get_parent_store (CAMEL_FOLDER (folder));
+ if (parent_store) {
+ camel_store_summary_disconnect_folder_summary (
+ (CamelStoreSummary *) ((CamelIMAPXStore *) parent_store)->summary,
+ CAMEL_FOLDER (folder)->summary);
+ }
+
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (camel_imapx_folder_parent_class)->dispose (object);
}
gchar *uid,
gboolean unsolicited)
{
- CamelMessageInfo *mi;
CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) imap->select_folder;
if (unsolicited && ifolder->exists_on_server)
if (imap->changes == NULL)
imap->changes = camel_folder_change_info_new ();
- mi = camel_folder_summary_uid (imap->select_folder->summary, uid);
- if (mi) {
- imapx_update_summary_for_removed_message (mi, imap->select_folder, unsolicited);
- camel_message_info_free (mi);
- }
-
- camel_folder_summary_remove_uid_fast (imap->select_folder->summary, uid);
+ camel_folder_summary_remove_uid (imap->select_folder->summary, uid);
imap->expunged = g_list_prepend (imap->expunged, uid);
camel_folder_change_info_remove_uid (imap->changes, uid);
}
}
+static gchar *
+imapx_get_uid_from_index (CamelFolderSummary *summary, guint id)
+{
+ GPtrArray *array;
+ gchar *uid;
+
+ g_return_val_if_fail (summary != NULL, NULL);
+
+ array = camel_folder_summary_get_array (summary);
+ g_return_val_if_fail (array != NULL, NULL);
+
+ if (id < array->len) {
+ camel_folder_sort_uids (camel_folder_summary_get_folder (summary), array);
+ uid = g_strdup (g_ptr_array_index (array, id));
+ }
+
+ camel_folder_summary_free_array (array);
+
+ return uid;
+}
+
static void
invalidate_local_cache (CamelIMAPXFolder *ifolder,
guint64 new_uidvalidity)
changes = camel_folder_change_info_new ();
- uids = camel_folder_summary_array (cfolder->summary);
+ uids = camel_folder_summary_get_array (cfolder->summary);
for (ii = 0; uids && ii < uids->len; ii++) {
const gchar *uid = uids->pdata[ii];
camel_folder_change_info_change_uid (changes, uid);
}
- g_ptr_array_foreach (uids, (GFunc) camel_pstring_free, NULL);
- g_ptr_array_free (uids, TRUE);
+ camel_folder_summary_free_array (uids);
CAMEL_IMAPX_SUMMARY (cfolder->summary)->validity = new_uidvalidity;
camel_folder_summary_touch (cfolder->summary);
if (imap->select_folder) {
gchar *uid = NULL;
- uid = camel_folder_summary_uid_from_index (imap->select_folder->summary, expunge - 1);
+ uid = imapx_get_uid_from_index (imap->select_folder->summary, expunge - 1);
if (!uid)
break;
imapx_expunge_uid_from_summary (imap, uid, TRUE);
+ g_free (uid);
}
break;
uid = finfo->uid;
finfo->uid = NULL;
} else {
- uid = camel_folder_summary_uid_from_index (folder->summary, id - 1);
+ uid = imapx_get_uid_from_index (folder->summary, id - 1);
}
if (uid) {
- mi = camel_folder_summary_uid (folder->summary, uid);
+ mi = camel_folder_summary_get (folder->summary, uid);
if (mi) {
/* It's unsolicited _unless_ imap->select_pending (i.e. during
* a QRESYNC SELECT */
if (total && isum->modseq && ifolder->uidvalidity_on_server) {
- firstuid = camel_folder_summary_uid_from_index (folder->summary, 0);
- lastuid = camel_folder_summary_uid_from_index (folder->summary, total - 1);
+ firstuid = imapx_get_uid_from_index (folder->summary, 0);
+ lastuid = imapx_get_uid_from_index (folder->summary, total - 1);
c(is->tagprefix, "SELECT QRESYNC %" G_GUINT64_FORMAT
" %" G_GUINT64_FORMAT "\n",
* the summary starts from zero. */
sprintf(buf, "%d", total - i + 1);
g_string_prepend (seqs, buf);
- uid = camel_folder_summary_uid_from_index (folder->summary, total - i);
+ uid = imapx_get_uid_from_index (folder->summary, total - i);
g_string_prepend (uids, uid);
g_free (uid);
} while (i < total);
if (index >= uids->len)
break;
- info = camel_folder_summary_uid (s, g_ptr_array_index (uids, index));
+ info = camel_folder_summary_get (s, g_ptr_array_index (uids, index));
if (!info)
continue;
}
if (camel_folder_summary_count (job->folder->summary)) {
- gchar *uid = camel_folder_summary_uid_from_index (job->folder->summary,
- camel_folder_summary_count (job->folder->summary) - 1);
+ gchar *uid = imapx_get_uid_from_index (job->folder->summary,
+ camel_folder_summary_count (job->folder->summary) - 1);
guint64 uidl = strtoull (uid, NULL, 10);
g_free (uid);
* for all outstanding messages to be uploaded */
/* obtain a copy to be thread safe */
- uids = camel_folder_summary_array (s);
+ uids = camel_folder_summary_get_array (s);
qsort (infos->data, infos->len, sizeof (struct _refresh_info), imapx_refresh_info_cmp);
g_ptr_array_sort (uids, (GCompareFunc) imapx_uids_array_cmp);
if (uids->len)
- s_minfo = camel_folder_summary_uid (s, g_ptr_array_index (uids, 0));
+ s_minfo = camel_folder_summary_get (s, g_ptr_array_index (uids, 0));
for (i = 0; i < infos->len; i++) {
struct _refresh_info *r = &g_array_index (infos, struct _refresh_info, i);
j = imapx_index_next (uids, s, j);
if (j < uids->len)
- s_minfo = camel_folder_summary_uid (s, g_ptr_array_index (uids, j));
+ s_minfo = camel_folder_summary_get (s, g_ptr_array_index (uids, j));
}
info = NULL;
j = imapx_index_next (uids, s, j);
if (j < uids->len)
- s_minfo = camel_folder_summary_uid (s, g_ptr_array_index (uids, j));
+ s_minfo = camel_folder_summary_get (s, g_ptr_array_index (uids, j));
}
if (s_minfo)
camel_message_info_free (s_minfo);
while (j < uids->len) {
- s_minfo = camel_folder_summary_uid (s, g_ptr_array_index (uids, j));
+ s_minfo = camel_folder_summary_get (s, g_ptr_array_index (uids, j));
if (!s_minfo) {
j++;
for (l = removed; l != NULL; l = g_list_next (l)) {
gchar *uid = (gchar *) l->data;
- CamelMessageInfo *mi;
-
- mi = camel_folder_summary_uid (job->folder->summary, uid);
- if (mi) {
- imapx_update_summary_for_removed_message (mi, job->folder, FALSE);
- camel_message_info_free (mi);
- }
camel_folder_change_info_remove_uid (job->u.refresh_info.changes, uid);
- camel_folder_summary_remove_uid_fast (s, uid);
+ camel_folder_summary_remove_uid (s, uid);
}
if (removed) {
const gchar *full_name;
- full_name = camel_folder_get_full_name (s->folder);
+ full_name = camel_folder_get_full_name (camel_folder_summary_get_folder (s));
camel_db_delete_uids (is->store->cdb_w, full_name, removed, NULL);
g_list_foreach (removed, (GFunc) g_free, NULL);
g_list_free (removed);
camel_folder_changed (job->folder, job->u.refresh_info.changes);
camel_folder_change_info_clear (job->u.refresh_info.changes);
- camel_folder_free_uids (job->folder, uids);
+ camel_folder_summary_free_array (uids);
/* If we have any new messages, download their headers, but only a few (100?) at a time */
if (fetch_new) {
/* There's no sane way to get the server-side unseen count on the
* select mailbox. So just work it out from the flags */
- ((CamelIMAPXFolder *) job->folder)->unread_on_server = job->folder->summary->unread_count;
+ ((CamelIMAPXFolder *) job->folder)->unread_on_server = camel_folder_summary_get_unread_count (job->folder->summary);
g_array_free (job->u.refresh_info.infos, TRUE);
imapx_job_done (is, job);
}
if (camel_folder_summary_count (ic->job->folder->summary)) {
- gchar *uid = camel_folder_summary_uid_from_index (ic->job->folder->summary,
- camel_folder_summary_count (ic->job->folder->summary) - 1);
+ gchar *uid = imapx_get_uid_from_index (ic->job->folder->summary,
+ camel_folder_summary_count (ic->job->folder->summary) - 1);
guint64 uidl = strtoull (uid, NULL, 10);
g_free (uid);
if (total > 0) {
guint64 uidl;
- uid = camel_folder_summary_uid_from_index (folder->summary, total - 1);
+ uid = imapx_get_uid_from_index (folder->summary, total - 1);
uidl = strtoull (uid, NULL, 10);
g_free (uid);
uid = g_strdup_printf ("%" G_GUINT64_FORMAT, uidl+1);
* message flags, but don't depend on modseq for the selected folder */
if (total != ifolder->exists_on_server ||
isum->uidnext != ifolder->uidnext_on_server ||
- folder->summary->unread_count != ifolder->unread_on_server ||
+ camel_folder_summary_get_unread_count (folder->summary) != ifolder->unread_on_server ||
(!is_selected && isum->modseq != ifolder->modseq_on_server))
need_rescan = TRUE;
/* Recalulate need_rescan */
if (total != ifolder->exists_on_server ||
isum->uidnext != ifolder->uidnext_on_server ||
- folder->summary->unread_count != ifolder->unread_on_server ||
+ camel_folder_summary_get_unread_count (folder->summary) != ifolder->unread_on_server ||
(!is_selected && isum->modseq != ifolder->modseq_on_server))
need_rescan = TRUE;
e(is->tagprefix, "folder %s is %sselected, total %u / %u, unread %u / %u, modseq %" G_GUINT64_FORMAT " / %" G_GUINT64_FORMAT ", uidnext %u / %u: will %srescan\n",
full_name, is_selected?"": "not ", total, ifolder->exists_on_server,
- folder->summary->unread_count, ifolder->unread_on_server,
+ camel_folder_summary_get_unread_count (folder->summary), ifolder->unread_on_server,
(guint64) isum->modseq, (guint64) ifolder->modseq_on_server,
isum->uidnext, ifolder->uidnext_on_server,
need_rescan?"":"not ");
isum->modseq = ifolder->modseq_on_server;
total = camel_folder_summary_count (job->folder->summary);
if (total != ifolder->exists_on_server ||
- folder->summary->unread_count != ifolder->unread_on_server ||
+ camel_folder_summary_get_unread_count (folder->summary) != ifolder->unread_on_server ||
(isum->modseq != ifolder->modseq_on_server)) {
c(is->tagprefix, "Eep, after QRESYNC we're out of sync. total %u / %u, unread %u / %u, modseq %" G_GUINT64_FORMAT " / %" G_GUINT64_FORMAT "\n",
total, ifolder->exists_on_server,
- folder->summary->unread_count, ifolder->unread_on_server,
+ camel_folder_summary_get_unread_count (folder->summary), ifolder->unread_on_server,
isum->modseq, ifolder->modseq_on_server);
} else {
c(is->tagprefix, "OK, after QRESYNC we're still in sync. total %u / %u, unread %u / %u, modseq %" G_GUINT64_FORMAT " / %" G_GUINT64_FORMAT "\n",
total, ifolder->exists_on_server,
- folder->summary->unread_count, ifolder->unread_on_server,
+ camel_folder_summary_get_unread_count (folder->summary), ifolder->unread_on_server,
isum->modseq, ifolder->modseq_on_server);
goto done;
}
changes = camel_folder_change_info_new ();
for (i = 0; i < uids->len; i++) {
gchar *uid = uids->pdata[i];
- CamelMessageInfo *mi = camel_folder_summary_uid (folder->summary, uid);
-
- if (mi) {
- imapx_update_summary_for_removed_message (mi, folder, FALSE);
- camel_message_info_free (mi);
- }
- camel_folder_summary_remove_uid_fast (folder->summary, uid);
+ camel_folder_summary_remove_uid (folder->summary, uid);
camel_folder_change_info_remove_uid (changes, uids->pdata[i]);
removed = g_list_prepend (removed, (gpointer) uids->pdata[i]);
}
gint i;
for (i = 0; i < job->u.sync_changes.changed_uids->len; i++) {
- CamelIMAPXMessageInfo *xinfo = (CamelIMAPXMessageInfo *) camel_folder_summary_uid (job->folder->summary,
+ CamelIMAPXMessageInfo *xinfo = (CamelIMAPXMessageInfo *) camel_folder_summary_get (job->folder->summary,
job->u.sync_changes.changed_uids->pdata[i]);
if (!xinfo)
/* ... and store's summary when folder's summary is dirty */
si = camel_store_summary_path ((CamelStoreSummary *)((CamelIMAPXStore *) parent_store)->summary, full_name);
if (si) {
- if (si->total != job->folder->summary->saved_count || si->unread != job->folder->summary->unread_count) {
- si->total = job->folder->summary->saved_count;
- si->unread = job->folder->summary->unread_count;
+ if (si->total != camel_folder_summary_get_saved_count (job->folder->summary) ||
+ si->unread != camel_folder_summary_get_unread_count (job->folder->summary)) {
+ si->total = camel_folder_summary_get_saved_count (job->folder->summary);
+ si->unread = camel_folder_summary_get_unread_count (job->folder->summary);
camel_store_summary_touch ((CamelStoreSummary *)((CamelIMAPXStore *) parent_store)->summary);
}
c(is->tagprefix, "checking/storing %s flags '%s'\n", on?"on":"off", flags_table[j].name);
imapx_uidset_init (&ss, 0, 100);
for (i = 0; i < uids->len; i++) {
- CamelIMAPXMessageInfo *info = (CamelIMAPXMessageInfo *) camel_folder_summary_uid
+ CamelIMAPXMessageInfo *info = (CamelIMAPXMessageInfo *) camel_folder_summary_get
(job->folder->summary, uids->pdata[i]);
guint32 flags;
guint32 sflags;
return stream;
}
- mi = camel_folder_summary_uid (folder->summary, uid);
+ mi = camel_folder_summary_get (folder->summary, uid);
if (!mi) {
g_set_error (
error, CAMEL_FOLDER_ERROR,
CamelFlag *uflags, *suflags;
guint j = 0;
- info = (CamelIMAPXMessageInfo *) camel_folder_summary_uid (folder->summary, uids->pdata[i]);
+ info = (CamelIMAPXMessageInfo *) camel_folder_summary_get (folder->summary, uids->pdata[i]);
if (!info)
continue;
else
ims = (CamelIMAPXSummary *) camel_imapx_summary_new (folder, NULL);
- fi->unread = ((CamelFolderSummary *) ims)->unread_count;
- fi->total = ((CamelFolderSummary *) ims)->saved_count;
+ fi->unread = camel_folder_summary_get_unread_count ((CamelFolderSummary *) ims);
+ fi->total = camel_folder_summary_get_saved_count ((CamelFolderSummary *) ims);
if (!folder->summary)
g_object_unref (ims);
static gboolean info_set_user_flag (CamelMessageInfo *info, const gchar *id, gboolean state);
static CamelMessageContentInfo *content_info_migrate (CamelFolderSummary *s, FILE *in);
-static gint summary_header_from_db (CamelFolderSummary *s, CamelFIRecord *mir);
+static gboolean summary_header_from_db (CamelFolderSummary *s, CamelFIRecord *mir);
static CamelFIRecord * summary_header_to_db (CamelFolderSummary *s, GError **error);
static CamelMIRecord * message_info_to_db (CamelFolderSummary *s, CamelMessageInfo *info);
static CamelMessageInfo * message_info_from_db (CamelFolderSummary *s, CamelMIRecord *mir);
-static gint content_info_to_db (CamelFolderSummary *s, CamelMessageContentInfo *info, CamelMIRecord *mir);
+static gboolean content_info_to_db (CamelFolderSummary *s, CamelMessageContentInfo *info, CamelMIRecord *mir);
static CamelMessageContentInfo * content_info_from_db (CamelFolderSummary *s, CamelMIRecord *mir);
G_DEFINE_TYPE (CamelIMAPXSummary, camel_imapx_summary, CAMEL_TYPE_FOLDER_SUMMARY)
return (a1 < a1) ? -1 : (a1 > a2) ? 1 : 0;
}
-static gint
-uid_compare (gconstpointer va,
- gconstpointer vb)
-{
- const gchar **sa = (const gchar **) va, **sb = (const gchar **) vb;
- gulong a, b;
-
- a = strtoul (*sa, NULL, 10);
- b = strtoul (*sb, NULL, 10);
- if (a < b)
- return -1;
- else if (a == b)
- return 0;
- else
- return 1;
-}
-
/**
* camel_imapx_summary_new:
* @folder: Parent folder.
parent_store = camel_folder_get_parent_store (folder);
- summary = g_object_new (CAMEL_TYPE_IMAPX_SUMMARY, NULL);
+ summary = g_object_new (CAMEL_TYPE_IMAPX_SUMMARY, "folder", folder, NULL);
- summary->folder = folder;
/* Don't do DB sort. Its pretty slow to load */
if (folder && 0) {
camel_db_set_collate (parent_store->cdb_r, "uid", "imapx_uid_sort", (CamelDBCollate)sort_uid_cmp);
camel_folder_summary_set_build_content (summary, TRUE);
camel_folder_summary_set_filename (summary, filename);
- if (camel_folder_summary_load_from_db (summary, &local_error) == -1) {
+ if (!camel_folder_summary_load_from_db (summary, &local_error)) {
/* FIXME: Isn't this dangerous ? We clear the summary
if it cannot be loaded, for some random reason.
We need to pass the error and find out why it is not loaded etc. ? */
- camel_folder_summary_clear_db (summary);
+ camel_folder_summary_clear (summary, NULL);
g_message ("Unable to load summary: %s\n", local_error->message);
g_clear_error (&local_error);
}
- g_ptr_array_sort (summary->uids, (GCompareFunc) uid_compare);
-
return summary;
}
-static gint
+static gboolean
summary_header_from_db (CamelFolderSummary *s,
CamelFIRecord *mir)
{
folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (
camel_imapx_summary_parent_class);
- if (folder_summary_class->summary_header_from_db (s, mir) == -1)
- return -1;
+ if (!folder_summary_class->summary_header_from_db (s, mir))
+ return FALSE;
part = mir->bdata;
if (ims->version > CAMEL_IMAPX_SUMMARY_VERSION) {
g_warning("Unknown summary version\n");
errno = EINVAL;
- return -1;
+ return FALSE;
}
- return 0;
+ return TRUE;
}
static gint
return camel_folder_summary_content_info_new (s);
}
-static gint
+static gboolean
content_info_to_db (CamelFolderSummary *s,
CamelMessageContentInfo *info,
CamelMIRecord *mir)
oldr = mir->cinfo;
mir->cinfo = oldr ? g_strdup_printf("%s 0", oldr) : g_strdup ("0");
g_free (oldr);
- return 0;
+ return TRUE;
}
}
gboolean unsolicited)
{
gboolean changed = FALSE;
- CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) folder;
CamelIMAPXMessageInfo *xinfo = (CamelIMAPXMessageInfo *) info;
- if (server_flags != xinfo->server_flags)
- {
+ if (server_flags != xinfo->server_flags) {
guint32 server_set, server_cleared;
- gint read = 0, deleted = 0, junk = 0;
server_set = server_flags & ~xinfo->server_flags;
server_cleared = xinfo->server_flags & ~server_flags;
if (permanent_flags > 0)
server_cleared &= permanent_flags;
- if (server_set & CAMEL_MESSAGE_SEEN)
- read = 1;
- else if (server_cleared & CAMEL_MESSAGE_SEEN)
- read = -1;
-
- if (server_set & CAMEL_MESSAGE_DELETED)
- deleted = 1;
- else if (server_cleared & CAMEL_MESSAGE_DELETED)
- deleted = -1;
-
- if (server_set & CAMEL_MESSAGE_JUNK)
- junk = 1;
- else if (server_cleared & CAMEL_MESSAGE_JUNK)
- junk = -1;
-
- d('?', "%s %s %s %s\n", xinfo->info.uid, read == 1 ? "read" : ( read == -1 ? "unread" : ""),
- deleted == 1 ? "deleted" : ( deleted == -1 ? "undeleted" : ""),
- junk == 1 ? "junk" : ( junk == -1 ? "unjunked" : ""));
-
- if (read) {
- folder->summary->unread_count -= read;
- if (unsolicited)
- ifolder->unread_on_server -= read;
- }
- if (deleted)
- folder->summary->deleted_count += deleted;
- if (junk)
- folder->summary->junk_count += junk;
- if (junk && !deleted)
- folder->summary->junk_not_deleted_count += junk;
- if (junk || deleted)
- folder->summary->visible_count -= junk ? junk : deleted;
-
- xinfo->info.flags = (xinfo->info.flags | server_set) & ~server_cleared;
+ camel_message_info_set_flags ((CamelMessageInfo *) xinfo, server_set | server_cleared, (xinfo->info.flags | server_set) & ~server_cleared);
+
xinfo->server_flags = server_flags;
+ xinfo->info.flags = xinfo->info.flags & ~CAMEL_MESSAGE_FOLDER_FLAGGED;
xinfo->info.dirty = TRUE;
- if (info->summary)
- camel_folder_summary_touch (info->summary);
+
changed = TRUE;
}
{
CamelMessageInfoBase *binfo = (CamelMessageInfoBase *) info;
CamelIMAPXMessageInfo *xinfo = (CamelIMAPXMessageInfo *) info;
- gint unread = 0, deleted = 0, junk = 0;
- guint32 flags;
binfo->flags |= server_flags;
+ camel_message_info_set_flags (info, server_flags, binfo->flags | server_flags);
+
xinfo->server_flags = server_flags;
if (folder->permanent_flags & CAMEL_MESSAGE_USER)
imapx_update_user_flags (info, server_user_flags);
- /* update the summary count */
- flags = binfo->flags;
-
- if (!(flags & CAMEL_MESSAGE_SEEN))
- unread = 1;
-
- if (flags & CAMEL_MESSAGE_DELETED)
- deleted = 1;
-
- if (flags & CAMEL_MESSAGE_JUNK)
- junk = 1;
-
- if (folder->summary) {
-
- if (unread)
- folder->summary->unread_count += unread;
- if (deleted)
- folder->summary->deleted_count += deleted;
- if (junk)
- folder->summary->junk_count += junk;
- if (junk && !deleted)
- folder->summary->junk_not_deleted_count += junk;
- folder->summary->visible_count++;
- if (junk || deleted)
- folder->summary->visible_count -= junk ? junk : deleted;
-
- folder->summary->saved_count++;
- camel_folder_summary_touch (folder->summary);
- }
-
binfo->flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
-}
-
-void
-imapx_update_summary_for_removed_message (CamelMessageInfo *info,
- CamelFolder *folder,
- gboolean unsolicited)
-{
- CamelMessageInfoBase *dinfo = (CamelMessageInfoBase *) info;
- CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) folder;
- gint unread = 0, deleted = 0, junk = 0;
- guint32 flags;
-
- flags = dinfo->flags;
- if (!(flags & CAMEL_MESSAGE_SEEN))
- unread = 1;
-
- if (flags & CAMEL_MESSAGE_DELETED)
- deleted = 1;
-
- if (flags & CAMEL_MESSAGE_JUNK)
- junk = 1;
-
- if (unread) {
- folder->summary->unread_count--;
- if (unsolicited)
- ifolder->unread_on_server--;
- }
- if (deleted)
- folder->summary->deleted_count--;
- if (junk)
- folder->summary->junk_count--;
-
- if (junk && !deleted)
- folder->summary->junk_not_deleted_count--;
-
- if (!junk && !deleted)
- folder->summary->visible_count--;
-
- folder->summary->saved_count--;
+ binfo->dirty = TRUE;
}
void
guint32 unread, total;
total = camel_folder_summary_count (folder->summary);
- unread = folder->summary->unread_count;
+ unread = camel_folder_summary_get_unread_count (folder->summary);
if (si->unread != unread || si->total != total) {
si->unread = unread;
gboolean imapx_update_message_info_flags (CamelMessageInfo *info, guint32 server_flags, CamelFlag *server_user_flags, guint32 permanent_flags, CamelFolder *folder, gboolean unsolicited);
void imapx_set_message_info_flags_for_new_message (CamelMessageInfo *info, guint32 server_flags, CamelFlag *server_user_flags,
CamelFolder *folder);
-void imapx_update_summary_for_removed_message (CamelMessageInfo *info, CamelFolder *folder, gboolean unsolicited);
void imapx_update_store_summary (CamelFolder *folder);
/* ********************************************************************** */
}
folder->summary = (CamelFolderSummary *) CAMEL_LOCAL_FOLDER_GET_CLASS (lf)->create_summary (lf, lf->summary_path, lf->folder_path, lf->index);
- if (!(flags & CAMEL_STORE_IS_MIGRATING) && camel_local_summary_load ((CamelLocalSummary *) folder->summary, forceindex, NULL) == -1) {
+ if (!(flags & CAMEL_STORE_IS_MIGRATING) && !camel_local_summary_load ((CamelLocalSummary *) folder->summary, forceindex, NULL)) {
/* ? */
if (need_summary_check &&
camel_local_summary_check ((CamelLocalSummary *) folder->summary, lf->changes, cancellable, error) == 0) {
#define EXTRACT_FIRST_DIGIT(val) val=strtoul (part, &part, 10);
static CamelFIRecord * summary_header_to_db (CamelFolderSummary *, GError **error);
-static gint summary_header_from_db (CamelFolderSummary *, CamelFIRecord *);
+static gboolean summary_header_from_db (CamelFolderSummary *, CamelFIRecord *);
static gint summary_header_load (CamelFolderSummary *, FILE *);
static gint summary_header_save (CamelFolderSummary *, FILE *);
g_object_ref (index);
}
-static gint
+static gboolean
local_summary_load (CamelLocalSummary *cls,
gint forceindex,
GError **error)
}
/* load/check the summary */
-gint
+gboolean
camel_local_summary_load (CamelLocalSummary *cls,
gint forceindex,
GError **error)
class = CAMEL_LOCAL_SUMMARY_GET_CLASS (cls);
if ((forceindex && class->need_index ())
- || class->load (cls, forceindex, error) == -1) {
+ || !class->load (cls, forceindex, error)) {
w(g_warning("Could not load summary: flags may be reset"));
- camel_folder_summary_clear ((CamelFolderSummary *) cls);
- return -1;
+ camel_folder_summary_clear ((CamelFolderSummary *) cls, NULL);
+ return FALSE;
}
- return 0;
+ return TRUE;
}
void camel_local_summary_check_force (CamelLocalSummary *cls)
if (ret != -1) {
gint i;
CamelFolderSummary *s = (CamelFolderSummary *) cls;
+ GPtrArray *known_uids;
struct _stat_info stats = { 0 };
+ known_uids = camel_folder_summary_get_array (s);
for (i = 0; i < camel_folder_summary_count (s); i++) {
- CamelMessageInfo *info = camel_folder_summary_index (s, i);
+ CamelMessageInfo *info = camel_folder_summary_get (s, g_ptr_array_index (known_uids, i));
do_stat_mi (cls, &stats, info);
camel_message_info_free (info);
}
+ camel_folder_summary_free_array (known_uids);
printf("\nMemory used by summary:\n\n");
printf("Total of %d messages\n", camel_folder_summary_count(s));
folder_summary = CAMEL_FOLDER_SUMMARY (cls);
- if (camel_folder_summary_save_to_db (folder_summary, error) == -1) {
+ if (!camel_folder_summary_save_to_db (folder_summary, error)) {
g_warning ("Could not save summary for local providers");
return -1;
}
return 1;
}
-static void
-update_summary (CamelFolderSummary *summary,
- CamelMessageInfoBase *info,
- CamelMessageInfoBase *old)
-{
- gint unread = 0, deleted = 0, junk = 0;
- guint32 flags = info->flags;
- guint32 oldflags = old->flags;
-
- if ((flags & CAMEL_MESSAGE_SEEN) != (oldflags & CAMEL_MESSAGE_SEEN))
- unread = (oldflags & CAMEL_MESSAGE_SEEN) ? 1 : -1;
-
- if ((flags & CAMEL_MESSAGE_DELETED) != (oldflags & CAMEL_MESSAGE_DELETED))
- deleted = (oldflags & CAMEL_MESSAGE_DELETED) ? 1 : -1;
-
- if ((flags & CAMEL_MESSAGE_JUNK) != (oldflags & CAMEL_MESSAGE_JUNK))
- junk = (oldflags & CAMEL_MESSAGE_JUNK) ? 1 : -1;
-
- /* Things would already be flagged */
-
- if (summary) {
-
- if (unread)
- summary->unread_count -= unread;
- if (deleted)
- summary->deleted_count += deleted;
- if (junk)
- summary->junk_count += junk;
- if (junk && !deleted)
- summary->junk_not_deleted_count += junk;
- if (junk || deleted)
- summary->visible_count -= junk ? junk : deleted;
- }
-
-}
-
static CamelMessageInfo *
local_summary_add (CamelLocalSummary *cls,
CamelMimeMessage *msg,
GError **error)
{
CamelLocalMessageInfo *mi;
- CamelFolderSummary *s = (CamelFolderSummary *) cls;
gchar *xev;
d(printf("Adding message to summary\n"));
tag = tag->next;
}
- update_summary (s, (CamelMessageInfoBase *) mi, (CamelMessageInfoBase *) info);
- mi->info.flags |= (camel_message_info_flags (info) & 0xffff);
+ camel_message_info_set_flags ((CamelMessageInfo *) mi, 0xffff, camel_message_info_flags (info));
mi->info.size = camel_message_info_size (info);
}
return 0;
}
-static gint
+static gboolean
summary_header_from_db (CamelFolderSummary *s,
CamelFIRecord *fir)
{
/* We dont actually add our own headers, but version that we don't anyway */
- if (CAMEL_FOLDER_SUMMARY_CLASS (camel_local_summary_parent_class)->summary_header_from_db (s, fir) == -1)
- return -1;
+ if (!CAMEL_FOLDER_SUMMARY_CLASS (camel_local_summary_parent_class)->summary_header_from_db (s, fir))
+ return FALSE;
part = fir->bdata;
if (part) {
g_free (fir->bdata);
fir->bdata = tmp;
- return 0;
+ return TRUE;
}
static gint
struct _CamelLocalSummaryClass {
CamelFolderSummaryClass parent_class;
- gint (*load)(CamelLocalSummary *cls, gint forceindex, GError **error);
+ gboolean (*load)(CamelLocalSummary *cls, gint forceindex, GError **error);
gint (*check)(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error);
gint (*sync)(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error);
CamelMessageInfo *(*add)(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, GError **error);
void camel_local_summary_construct (CamelLocalSummary *new, const gchar *filename, const gchar *local_name, CamelIndex *index);
/* load/check the summary */
-gint camel_local_summary_load (CamelLocalSummary *cls, gint forceindex, GError **error);
+gboolean camel_local_summary_load (CamelLocalSummary *cls, gint forceindex, GError **error);
/* check for new/removed messages */
gint camel_local_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *, GCancellable *cancellable, GError **error);
/* perform a folder sync or expunge, if needed */
g_return_val_if_fail (folder != NULL, 0);
g_return_val_if_fail (folder->summary != NULL, 0);
- a = camel_folder_summary_uid (folder->summary, uid1);
- b = camel_folder_summary_uid (folder->summary, uid2);
+ a = camel_folder_summary_get (folder->summary, uid1);
+ b = camel_folder_summary_get (folder->summary, uid2);
g_return_val_if_fail (a != NULL, 0);
g_return_val_if_fail (b != NULL, 0);
gchar *res;
/* get the message summary info */
- if ((info = camel_folder_summary_uid (folder->summary, uid)) == NULL) {
+ if ((info = camel_folder_summary_get (folder->summary, uid)) == NULL) {
set_cannot_get_message_ex (
error, CAMEL_FOLDER_ERROR_INVALID_UID,
uid, lf->folder_path, _("No such message"));
CamelMaildirMessageInfo *mdi;
CamelMessageInfo *info;
- if ((info = camel_folder_summary_uid (source->summary, uid)) == NULL) {
+ if ((info = camel_folder_summary_get (source->summary, uid)) == NULL) {
set_cannot_get_message_ex (
error, CAMEL_FOLDER_ERROR_INVALID_UID,
uid, lf->folder_path, _("No such message"));
}
s = (CamelFolderSummary *) camel_maildir_summary_new (NULL, path, folderpath, NULL);
- if (camel_folder_summary_header_load_from_db (s, store, fi->full_name, NULL) != -1) {
- fi->unread = s->unread_count;
- fi->total = s->saved_count;
+ if (camel_folder_summary_header_load_from_db (s, store, fi->full_name, NULL)) {
+ fi->unread = camel_folder_summary_get_unread_count (s);
+ fi->total = camel_folder_summary_get_saved_count (s);
}
g_object_unref (s);
g_free (folderpath);
{
CamelMaildirSummary *o;
- o = g_object_new (CAMEL_TYPE_MAILDIR_SUMMARY, NULL);
- ((CamelFolderSummary *) o)->folder = folder;
+ o = g_object_new (CAMEL_TYPE_MAILDIR_SUMMARY, "folder", folder, NULL);
if (folder) {
CamelStore *parent_store;
mdi->info.info.uid = camel_pstring_add (camel_folder_summary_next_uid_string (s), TRUE);
/* handle 'duplicates' */
- info = camel_folder_summary_peek_info (s, uid);
+ info = camel_folder_summary_peek_loaded (s, uid);
if (info) {
d(printf("already seen uid '%s', just summarising instead\n", uid));
camel_message_info_free (mi);
gchar *new, *cur;
gchar *uid;
struct _remove_data rd = { cls, changes };
+ GPtrArray *known_uids;
g_mutex_lock (((CamelMaildirSummary *) cls)->priv->summary_lock);
/* keeps track of all uid's that have not been processed */
left = g_hash_table_new (g_str_hash, g_str_equal);
camel_folder_summary_prepare_fetch_all (s, error);
- count = camel_folder_summary_count (s);
- forceindex = count == 0;
- for (i = 0; i < count; i++) {
- info = camel_folder_summary_index ((CamelFolderSummary *) cls, i);
+ known_uids = camel_folder_summary_get_array (s);
+ forceindex = !known_uids || known_uids->len == 0;
+ for (i = 0; known_uids && i < known_uids->len; i++) {
+ info = camel_folder_summary_get ((CamelFolderSummary *) cls, g_ptr_array_index (known_uids, i));
if (info) {
g_hash_table_insert (left, (gchar *) camel_message_info_uid (info), info);
}
g_hash_table_remove (left, uid);
}
- info = camel_folder_summary_uid ((CamelFolderSummary *) cls, uid);
+ info = camel_folder_summary_get ((CamelFolderSummary *) cls, uid);
if (info == NULL) {
/* must be a message incorporated by another client, this is not a 'recent' uid */
if (camel_maildir_summary_add (cls, d->d_name, forceindex, cancellable) == 0)
continue;
/* already in summary? shouldn't happen, but just incase ... */
- if ((info = camel_folder_summary_uid ((CamelFolderSummary *) cls, name))) {
+ if ((info = camel_folder_summary_get ((CamelFolderSummary *) cls, name))) {
camel_message_info_free (info);
newname = destname = camel_folder_summary_next_uid_string (s);
} else {
g_free (new);
g_free (cur);
+ camel_folder_summary_free_array (known_uids);
g_mutex_unlock (((CamelMaildirSummary *) cls)->priv->summary_lock);
return 0;
GError **error)
{
CamelLocalSummaryClass *local_summary_class;
- gint count, i;
+ gint i;
CamelMessageInfo *info;
CamelMaildirMessageInfo *mdi;
gchar *name;
struct stat st;
+ GPtrArray *known_uids;
d(printf("summary_sync(expunge=%s)\n", expunge?"true":"false"));
camel_operation_push_message (cancellable, _("Storing folder"));
camel_folder_summary_prepare_fetch_all ((CamelFolderSummary *) cls, error);
- count = camel_folder_summary_count ((CamelFolderSummary *) cls);
- for (i = count - 1; i >= 0; i--) {
- camel_operation_progress (cancellable, (count - i) * 100 / count);
+ known_uids = camel_folder_summary_get_array ((CamelFolderSummary *) cls);
+ for (i = (known_uids ? known_uids->len : 0) - 1; i >= 0; i--) {
+ camel_operation_progress (cancellable, (known_uids->len - i) * 100 / known_uids->len);
- info = camel_folder_summary_index ((CamelFolderSummary *) cls, i);
+ info = camel_folder_summary_get ((CamelFolderSummary *) cls, g_ptr_array_index (known_uids, i));
mdi = (CamelMaildirMessageInfo *) info;
if (mdi && (mdi->info.info.flags & CAMEL_MESSAGE_DELETED) && expunge) {
name = g_strdup_printf("%s/cur/%s", cls->folder_path, camel_maildir_info_filename(mdi));
camel_message_info_free (info);
}
+ camel_folder_summary_free_array (known_uids);
camel_operation_pop_message (cancellable);
/* Chain up to parent's sync() method. */
g_return_val_if_fail (folder != NULL, 0);
g_return_val_if_fail (folder->summary != NULL, 0);
- a = (CamelMboxMessageInfo *) camel_folder_summary_uid (folder->summary, uid1);
- b = (CamelMboxMessageInfo *) camel_folder_summary_uid (folder->summary, uid2);
+ a = (CamelMboxMessageInfo *) camel_folder_summary_get (folder->summary, uid1);
+ b = (CamelMboxMessageInfo *) camel_folder_summary_get (folder->summary, uid2);
g_return_val_if_fail (a != NULL, 0);
g_return_val_if_fail (b != NULL, 0);
}
/* get the message summary info */
- info = (CamelMboxMessageInfo *) camel_folder_summary_uid (folder->summary, uid);
+ info = (CamelMboxMessageInfo *) camel_folder_summary_get (folder->summary, uid);
if (info == NULL) {
set_cannot_get_message_ex (
retry:
/* get the message summary info */
- info = (CamelMboxMessageInfo *) camel_folder_summary_uid (folder->summary, uid);
+ info = (CamelMboxMessageInfo *) camel_folder_summary_get (folder->summary, uid);
if (info == NULL) {
set_cannot_get_message_ex (
mbs = (CamelMboxSummary *) camel_mbox_summary_new (NULL, path, folderpath, NULL);
/* FIXME[disk-summary] track exception */
- if (camel_folder_summary_header_load_from_db ((CamelFolderSummary *) mbs, store, fi->full_name, NULL) != -1) {
- fi->unread = ((CamelFolderSummary *) mbs)->unread_count;
- fi->total = ((CamelFolderSummary *) mbs)->saved_count;
+ if (camel_folder_summary_header_load_from_db ((CamelFolderSummary *) mbs, store, fi->full_name, NULL)) {
+ fi->unread = camel_folder_summary_get_unread_count ((CamelFolderSummary *) mbs);
+ fi->total = camel_folder_summary_get_saved_count ((CamelFolderSummary *) mbs);
}
g_object_unref (mbs);
#define CAMEL_MBOX_SUMMARY_VERSION (1)
static CamelFIRecord * summary_header_to_db (CamelFolderSummary *, GError **error);
-static gint summary_header_from_db (CamelFolderSummary *, CamelFIRecord *);
+static gboolean summary_header_from_db (CamelFolderSummary *, CamelFIRecord *);
static CamelMessageInfo * message_info_from_db (CamelFolderSummary *s, CamelMIRecord *record);
static CamelMIRecord * message_info_to_db (CamelFolderSummary *s, CamelMessageInfo *info);
{
CamelMboxSummary *new;
- new = g_object_new (CAMEL_TYPE_MBOX_SUMMARY, NULL);
- ((CamelFolderSummary *) new)->folder = folder;
+ new = g_object_new (CAMEL_TYPE_MBOX_SUMMARY, "folder", folder, NULL);
if (folder) {
CamelFolderSummary *summary = (CamelFolderSummary *) new;
CamelStore *parent_store;
}
}
-static gint
+static gboolean
summary_header_from_db (CamelFolderSummary *s,
struct _CamelFIRecord *fir)
{
CamelMboxSummary *mbs = CAMEL_MBOX_SUMMARY (s);
gchar *part;
- CAMEL_FOLDER_SUMMARY_CLASS (camel_mbox_summary_parent_class)->summary_header_from_db (s, fir);
+ if (!CAMEL_FOLDER_SUMMARY_CLASS (camel_mbox_summary_parent_class)->summary_header_from_db (s, fir))
+ return FALSE;
part = fir->bdata;
if (part) {
mbs->folder_size = bdata_extract_digit (&part);
}
- return 0;
+ return TRUE;
}
static gint
uid = camel_message_info_uid (mi);
d(printf("found valid x-evolution: %s\n", uid));
/* If one is there, it should be there already */
- info = (CamelMboxMessageInfo *) camel_folder_summary_peek_info (s, uid);
+ info = (CamelMboxMessageInfo *) camel_folder_summary_peek_loaded (s, uid);
if (info) {
if ((info->info.info.flags & CAMEL_MESSAGE_FOLDER_NOTSEEN)) {
info->info.info.flags &= ~CAMEL_MESSAGE_FOLDER_NOTSEEN;
camel_pstring_free (mi->info.info.uid);
mi->info.info.uid = camel_pstring_add (camel_folder_summary_next_uid_string (s), TRUE);
} else {
- camel_folder_summary_set_uid (s, strtoul (camel_message_info_uid (mi), NULL, 10));
+ camel_folder_summary_set_next_uid (s, strtoul (camel_message_info_uid (mi), NULL, 10));
}
#ifdef STATUS_PINE
if (mbs->xstatus && add&2) {
GCancellable *cancellable,
GError **error)
{
- gint i, count;
+ gint i;
CamelFolderSummary *s = (CamelFolderSummary *) cls;
CamelMboxSummary *mbs = (CamelMboxSummary *) cls;
CamelMimeParser *mp;
struct stat st;
goffset size = 0;
GList *del = NULL;
+ GPtrArray *known_uids;
d(printf("Calling summary update, from pos %d\n", (gint)offset));
* If we're not starting from the start, we must be starting
* from the old end, so everything must be treated as new */
camel_folder_summary_prepare_fetch_all (s, NULL);
- count = camel_folder_summary_count (s);
- for (i = 0; i < count; i++) {
- mi = (CamelMboxMessageInfo *) camel_folder_summary_index (s, i);
+ known_uids = camel_folder_summary_get_array (s);
+ for (i = 0; known_uids && i < known_uids->len; i++) {
+ mi = (CamelMboxMessageInfo *) camel_folder_summary_get (s, g_ptr_array_index (known_uids, i));
if (offset == 0)
mi->info.info.flags |= CAMEL_MESSAGE_FOLDER_NOTSEEN;
else
mi->info.info.flags &= ~CAMEL_MESSAGE_FOLDER_NOTSEEN;
camel_message_info_free (mi);
}
+ camel_folder_summary_free_array (known_uids);
mbs->changes = changeinfo;
while (camel_mime_parser_step (mp, NULL, NULL) == CAMEL_MIME_PARSER_STATE_FROM) {
g_object_unref (mp);
- count = camel_folder_summary_count (s);
- for (i = 0; i < count; i++) {
- mi = (CamelMboxMessageInfo *) camel_folder_summary_index (s, i);
- /* must've dissapeared from the file? */
- if (!mi || mi->info.info.flags & CAMEL_MESSAGE_FOLDER_NOTSEEN) {
- gchar *uid;
-
- if (mi)
- uid = g_strdup (camel_message_info_uid (mi));
- else
- uid = camel_folder_summary_uid_from_index (s, i);
+ known_uids = camel_folder_summary_get_array (s);
+ for (i = 0; known_uids && i < known_uids->len; i++) {
+ const gchar *uid;
- if (!uid) {
- g_debug ("%s: didn't get uid at %d of %d (%d)", G_STRFUNC, i, count, camel_folder_summary_count (s));
- continue;
- }
+ uid = g_ptr_array_index (known_uids, i);
+ if (!uid)
+ continue;
+ mi = (CamelMboxMessageInfo *) camel_folder_summary_get (s, uid);
+ /* must've dissapeared from the file? */
+ if (!mi || mi->info.info.flags & CAMEL_MESSAGE_FOLDER_NOTSEEN) {
d(printf("uid '%s' vanished, removing", uid));
if (changeinfo)
camel_folder_change_info_remove_uid (changeinfo, uid);
del = g_list_prepend (del, (gpointer) camel_pstring_strdup (uid));
- camel_folder_summary_remove_index_fast (s, i);
- count--;
- i--;
- g_free (uid);
+ camel_folder_summary_remove_uid (s, uid);
}
+
if (mi)
camel_message_info_free (mi);
}
+ if (known_uids)
+ camel_folder_summary_free_array (known_uids);
+
/* Delete all in one transaction */
- full_name = camel_folder_get_full_name (s->folder);
- parent_store = camel_folder_get_parent_store (s->folder);
+ full_name = camel_folder_get_full_name (camel_folder_summary_get_folder (s));
+ parent_store = camel_folder_get_parent_store (camel_folder_summary_get_folder (s));
camel_db_delete_uids (parent_store->cdb_w, full_name, del, NULL);
g_list_foreach (del, (GFunc) camel_pstring_free, NULL);
g_list_free (del);
CamelFolderSummary *s = (CamelFolderSummary *) cls;
struct stat st;
gint ret = 0;
- gint i, count;
+ gint i;
d(printf("Checking summary\n"));
/* check if the summary is up-to-date */
if (g_stat (cls->folder_path, &st) == -1) {
- camel_folder_summary_clear (s);
+ camel_folder_summary_clear (s, NULL);
camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
g_set_error (
error, G_IO_ERROR,
cls->check_force = 0;
if (st.st_size == 0) {
+ GPtrArray *known_uids;
+
/* empty? No need to scan at all */
d(printf("Empty mbox, clearing summary\n"));
camel_folder_summary_prepare_fetch_all (s, NULL);
- count= camel_folder_summary_count (s);
- for (i = 0; i < count; i++) {
- CamelMessageInfo *info = camel_folder_summary_index (s, i);
+ known_uids = camel_folder_summary_get_array (s);
+ for (i = 0; known_uids && i < known_uids->len; i++) {
+ CamelMessageInfo *info = camel_folder_summary_get (s, g_ptr_array_index (known_uids, i));
if (info) {
camel_folder_change_info_remove_uid (changes, camel_message_info_uid (info));
camel_message_info_free (info);
}
}
- camel_folder_summary_clear (s);
+ camel_folder_summary_free_array (known_uids);
+ camel_folder_summary_clear (s, NULL);
ret = 0;
} else {
/* is the summary uptodate? */
gint ret = 0;
/* Things are in memory already. Sorting speeds up syncing, if things are sorted by from pos. */
- info1 = (CamelMboxMessageInfo *) camel_folder_summary_uid (summary, *(gchar **) a);
- info2 = (CamelMboxMessageInfo *) camel_folder_summary_uid (summary, *(gchar **) b);
+ info1 = (CamelMboxMessageInfo *) camel_folder_summary_get (summary, *(gchar **) a);
+ info2 = (CamelMboxMessageInfo *) camel_folder_summary_get (summary, *(gchar **) b);
if (info1->frompos > info2->frompos)
ret = 1;
camel_operation_progress (cancellable, pc);
- info = (CamelMboxMessageInfo *) camel_folder_summary_uid (s, summary->pdata[i]);
+ info = (CamelMboxMessageInfo *) camel_folder_summary_get (s, summary->pdata[i]);
d(printf("Checking message %s %08x\n", camel_message_info_uid(info), ((CamelMessageInfoBase *)info)->flags));
return -1;
}
- full_name = camel_folder_get_full_name (s->folder);
- parent_store = camel_folder_get_parent_store (s->folder);
+ full_name = camel_folder_get_full_name (camel_folder_summary_get_folder (s));
+ parent_store = camel_folder_get_parent_store (camel_folder_summary_get_folder (s));
/* Sync only the changes */
summary = camel_folder_summary_get_changed ((CamelFolderSummary *) mbs);
for (i = 0; i < summary->len; i++) {
- CamelMboxMessageInfo *info = (CamelMboxMessageInfo *) camel_folder_summary_uid (s, summary->pdata[i]);
+ CamelMboxMessageInfo *info = (CamelMboxMessageInfo *) camel_folder_summary_get (s, summary->pdata[i]);
if ((expunge && (info->info.info.flags & CAMEL_MESSAGE_DELETED)) ||
(info->info.info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV | CAMEL_MESSAGE_FOLDER_XEVCHANGE)))
CamelMimeParser *mp = NULL;
CamelStore *parent_store;
const gchar *full_name;
- gint i, count;
+ gint i;
CamelMboxMessageInfo *info = NULL;
gchar *buffer, *xevnew = NULL;
gsize len;
gint lastdel = FALSE;
gboolean touched = FALSE;
GList *del = NULL;
+ GPtrArray *known_uids = NULL;
#ifdef STATUS_PINE
gchar statnew[8], xstatnew[8];
#endif
camel_mime_parser_init_with_fd (mp, fd);
camel_folder_summary_prepare_fetch_all (s, NULL);
- count = camel_folder_summary_count (s);
- for (i = 0; i < count; i++) {
- gint pc = (i + 1) * 100 / count;
+ known_uids = camel_folder_summary_get_array (s);
+ for (i = 0; known_uids && i < known_uids->len; i++) {
+ gint pc = (i + 1) * 100 / known_uids->len;
camel_operation_progress (cancellable, pc);
- info = (CamelMboxMessageInfo *) camel_folder_summary_index (s, i);
+ info = (CamelMboxMessageInfo *) camel_folder_summary_get (s, g_ptr_array_index (known_uids, i));
if (!info)
continue;
lastdel = FALSE;
if ((flags&1) && info->info.info.flags & CAMEL_MESSAGE_DELETED) {
const gchar *uid = camel_message_info_uid (info);
- guint32 flags = camel_message_info_flags (info);
- gint read, junk;
d(printf("Deleting %s\n", uid));
if (((CamelLocalSummary *) cls)->index)
camel_index_delete_name (((CamelLocalSummary *) cls)->index, uid);
/* remove it from the change list */
- junk = flags & CAMEL_MESSAGE_JUNK;
- read = flags & CAMEL_MESSAGE_SEEN;
- s->saved_count--;
- if (junk)
- s->junk_count--;
- if (!read)
- s->unread_count--;
- s->deleted_count--;
camel_folder_change_info_remove_uid (changeinfo, uid);
- camel_folder_summary_remove_index_fast (s, i);
+ camel_folder_summary_remove_uid (s, uid);
del = g_list_prepend (del, (gpointer) camel_pstring_strdup (uid));
camel_message_info_free ((CamelMessageInfo *) info);
- count--;
- i--;
info = NULL;
lastdel = TRUE;
touched = TRUE;
}
}
- full_name = camel_folder_get_full_name (s->folder);
- parent_store = camel_folder_get_parent_store (s->folder);
+ full_name = camel_folder_get_full_name (camel_folder_summary_get_folder (s));
+ parent_store = camel_folder_get_parent_store (camel_folder_summary_get_folder (s));
camel_db_delete_uids (parent_store->cdb_w, full_name, del, NULL);
g_list_foreach (del, (GFunc) camel_pstring_free, NULL);
g_list_free (del);
g_object_unref (mp);
/* clear working flags */
- for (i = 0; i < count; i++) {
- info = (CamelMboxMessageInfo *) camel_folder_summary_index (s, i);
+ for (i = 0; known_uids && i < known_uids->len; i++) {
+ info = (CamelMboxMessageInfo *) camel_folder_summary_get (s, g_ptr_array_index (known_uids, i));
if (info) {
if (info->info.info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV | CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_XEVCHANGE)) {
info->info.info.flags &= ~(CAMEL_MESSAGE_FOLDER_NOXEV
}
}
+ camel_folder_summary_free_array (known_uids);
+
if (touched)
camel_folder_summary_header_save_to_db (s, NULL);
if (info)
camel_message_info_free ((CamelMessageInfo *) info);
+ camel_folder_summary_free_array (known_uids);
camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
return -1;
return NULL;
/* get the message summary info */
- if ((info = camel_folder_summary_uid (folder->summary, uid)) == NULL) {
+ if ((info = camel_folder_summary_get (folder->summary, uid)) == NULL) {
set_cannot_get_message_ex (
error, CAMEL_FOLDER_ERROR_INVALID_UID,
uid, lf->folder_path, _("No such message"));
s = (CamelFolderSummary *) camel_mh_summary_new (
NULL, path, folderpath, NULL);
if (camel_folder_summary_header_load_from_db (
- s, store, fi->full_name, NULL) != -1) {
- fi->unread = s->unread_count;
- fi->total = s->saved_count;
+ s, store, fi->full_name, NULL)) {
+ fi->unread = camel_folder_summary_get_unread_count (s);
+ fi->total = camel_folder_summary_get_saved_count (s);
}
g_object_unref (s);
g_free (folderpath);
{
CamelMhSummary *o;
- o = g_object_new (CAMEL_TYPE_MH_SUMMARY, NULL);
- ((CamelFolderSummary *) o)->folder = folder;
+ o = g_object_new (CAMEL_TYPE_MH_SUMMARY, "folder", folder, NULL);
if (folder) {
CamelStore *parent_store;
if (mhs->priv->current_uid) {
uidstr = g_strdup (mhs->priv->current_uid);
/* tell the summary of this, so we always append numbers to the end */
- camel_folder_summary_set_uid (s, strtoul (uidstr, NULL, 10) + 1);
+ camel_folder_summary_set_next_uid (s, strtoul (uidstr, NULL, 10) + 1);
} else {
/* else scan for one - and create it too, to make sure */
do {
CamelMessageInfo *info;
CamelFolderSummary *s = (CamelFolderSummary *) cls;
GHashTable *left;
- gint i, count;
- gint forceindex;
+ gint i;
+ gboolean forceindex;
+ GPtrArray *known_uids;
/* FIXME: Handle changeinfo */
/* keeps track of all uid's that have not been processed */
left = g_hash_table_new (g_str_hash, g_str_equal);
camel_folder_summary_prepare_fetch_all ((CamelFolderSummary *) cls, error);
- count = camel_folder_summary_count ((CamelFolderSummary *) cls);
- forceindex = count == 0;
- for (i = 0; i < count; i++) {
- info = camel_folder_summary_index ((CamelFolderSummary *) cls, i);
+ known_uids = camel_folder_summary_get_array ((CamelFolderSummary *) cls);
+ forceindex = !known_uids || known_uids->len == 0;
+ for (i = 0; known_uids && i < known_uids->len; i++) {
+ info = camel_folder_summary_get ((CamelFolderSummary *) cls, g_ptr_array_index (known_uids, i));
if (info) {
g_hash_table_insert (left, (gchar *) camel_message_info_uid (info), info);
}
}
+ camel_folder_summary_free_array (known_uids);
while ((d = readdir (dir))) {
/* FIXME: also run stat to check for regular file */
break;
}
if (c == 0) {
- info = camel_folder_summary_uid ((CamelFolderSummary *) cls, d->d_name);
+ info = camel_folder_summary_get ((CamelFolderSummary *) cls, d->d_name);
if (info == NULL || (cls->index && (!camel_index_has_name (cls->index, d->d_name)))) {
/* need to add this file to the summary */
if (info != NULL) {
GError **error)
{
CamelLocalSummaryClass *local_summary_class;
- gint count, i;
+ gint i;
+ GPtrArray *known_uids;
CamelLocalMessageInfo *info;
gchar *name;
const gchar *uid;
/* FIXME: need to update/honour .mh_sequences or whatever it is */
camel_folder_summary_prepare_fetch_all ((CamelFolderSummary *) cls, error);
- count = camel_folder_summary_count ((CamelFolderSummary *) cls);
- for (i = count - 1; i >= 0; i--) {
- info = (CamelLocalMessageInfo *) camel_folder_summary_index ((CamelFolderSummary *) cls, i);
+ known_uids = camel_folder_summary_get_array ((CamelFolderSummary *) cls);
+ for (i = (known_uids ? known_uids->len : 0) - 1; i >= 0; i--) {
+ info = (CamelLocalMessageInfo *) camel_folder_summary_get ((CamelFolderSummary *) cls, g_ptr_array_index (known_uids, i));
g_assert (info);
if (expunge && (info->info.flags & CAMEL_MESSAGE_DELETED)) {
uid = camel_message_info_uid (info);
{
CamelSpoolSummary *new;
- new = g_object_new (CAMEL_TYPE_SPOOL_SUMMARY, NULL);
- ((CamelFolderSummary *) new)->folder = folder;
+ new = g_object_new (CAMEL_TYPE_SPOOL_SUMMARY, "folder", folder, NULL);
if (folder) {
CamelStore *parent_store;
GCancellable *cancellable,
GError **error)
{
- gint i, work, count;
+ gint i;
+ gboolean work;
struct stat st;
CamelFolderSummary *s = (CamelFolderSummary *) cls;
+ GPtrArray *known_uids;
if (CAMEL_LOCAL_SUMMARY_CLASS (camel_spool_summary_parent_class)->check (cls, changeinfo, cancellable, error) == -1)
return -1;
/* check to see if we need to copy/update the file; missing xev headers prompt this */
work = FALSE;
camel_folder_summary_prepare_fetch_all (s, error);
- count = camel_folder_summary_count (s);
- for (i = 0; !work && i < count; i++) {
- CamelMboxMessageInfo *info = (CamelMboxMessageInfo *) camel_folder_summary_index (s, i);
+ known_uids = camel_folder_summary_get_array (s);
+ for (i = 0; !work && known_uids && i < known_uids->len; i++) {
+ CamelMboxMessageInfo *info = (CamelMboxMessageInfo *) camel_folder_summary_get (s, g_ptr_array_index (known_uids, i));
g_assert (info);
work = (info->info.info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV)) != 0;
camel_message_info_free ((CamelMessageInfo *) info);
}
+ camel_folder_summary_free_array (known_uids);
/* if we do, then write out the headers using sync_full, etc */
if (work) {
static void
nntp_folder_dispose (GObject *object)
{
+ CamelStore *parent_store;
CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (object);
camel_folder_summary_save_to_db (
CAMEL_FOLDER (nntp_folder)->summary, NULL);
+ parent_store = camel_folder_get_parent_store (CAMEL_FOLDER (nntp_folder));
+ if (parent_store) {
+ camel_store_summary_disconnect_folder_summary (
+ (CamelStoreSummary *) ((CamelNNTPStore *) parent_store)->summary,
+ CAMEL_FOLDER (nntp_folder)->summary);
+ }
+
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (camel_nntp_folder_parent_class)->dispose (object);
}
{
CamelMessageInfo *info;
- info = camel_folder_summary_uid (summary, uid);
+ info = camel_folder_summary_get (summary, uid);
if (info) {
CamelMessageInfoBase *base = (CamelMessageInfoBase *) info;
folder = NULL;
}
+ camel_store_summary_connect_folder_summary (
+ (CamelStoreSummary *) ((CamelNNTPStore *) parent)->summary,
+ folder_name, folder->summary);
+
return folder;
}
static CamelMessageInfo * message_info_new_from_header (CamelFolderSummary *, struct _camel_header_raw *);
static gint summary_header_load (CamelFolderSummary *, FILE *);
static gint summary_header_save (CamelFolderSummary *, FILE *);
-static gint summary_header_from_db (CamelFolderSummary *s, CamelFIRecord *mir);
+static gboolean summary_header_from_db (CamelFolderSummary *s, CamelFIRecord *mir);
static CamelFIRecord * summary_header_to_db (CamelFolderSummary *s, GError **error);
G_DEFINE_TYPE (CamelNNTPSummary, camel_nntp_summary, CAMEL_TYPE_FOLDER_SUMMARY)
{
CamelNNTPSummary *cns;
- cns = g_object_new (CAMEL_TYPE_NNTP_SUMMARY, NULL);
- ((CamelFolderSummary *) cns)->folder = folder;
+ cns = g_object_new (CAMEL_TYPE_NNTP_SUMMARY, "folder", folder, NULL);
camel_folder_summary_set_filename ((CamelFolderSummary *) cns, path);
camel_folder_summary_set_build_content ((CamelFolderSummary *) cns, FALSE);
return (CamelMessageInfo *) mi;
}
-static gint
+static gboolean
summary_header_from_db (CamelFolderSummary *s,
CamelFIRecord *mir)
{
CamelNNTPSummary *cns = CAMEL_NNTP_SUMMARY (s);
gchar *part;
- if (CAMEL_FOLDER_SUMMARY_CLASS (camel_nntp_summary_parent_class)->summary_header_from_db (s, mir) == -1)
- return -1;
+ if (!CAMEL_FOLDER_SUMMARY_CLASS (camel_nntp_summary_parent_class)->summary_header_from_db (s, mir))
+ return FALSE;
part = mir->bdata;
cns->high = bdata_extract_digit (&part);
cns->low = bdata_extract_digit (&part);
- return 0;
+ return TRUE;
}
static gint
gint ret;
guint n, count, total, size;
struct _xover_header *xover;
- GHashTable *summary_table;
s = (CamelFolderSummary *) cns;
- summary_table = camel_folder_summary_get_hashtable (s);
url = camel_service_get_camel_url (CAMEL_SERVICE (store));
/* truncated line? ignore? */
if (xover == NULL) {
- if (!GPOINTER_TO_INT (g_hash_table_lookup (summary_table, cns->priv->uid))) {
+ if (!camel_folder_summary_check_uid (s, cns->priv->uid)) {
mi = (CamelMessageInfoBase *)
camel_folder_summary_add_from_header (s, headers);
if (mi) {
camel_operation_pop_message (cancellable);
- camel_folder_summary_free_hashtable (summary_table);
-
return ret;
}
guint i, n, count, total;
CamelMessageInfo *mi;
CamelMimeParser *mp;
- GHashTable *summary_table;
s = (CamelFolderSummary *) cns;
- summary_table = camel_folder_summary_get_hashtable (s);
-
mp = camel_mime_parser_new ();
url = camel_service_get_camel_url (CAMEL_SERVICE (store));
if ((msgid = strchr (line, '<')) && (line = strchr (msgid + 1, '>'))) {
line[1] = 0;
cns->priv->uid = g_strdup_printf ("%u,%s\n", n, msgid);
- if (!GPOINTER_TO_INT (g_hash_table_lookup (summary_table, cns->priv->uid))) {
+ if (!camel_folder_summary_check_uid (s, cns->priv->uid)) {
if (camel_mime_parser_init_with_stream (mp, (CamelStream *) store->stream, error) == -1)
goto error;
mi = camel_folder_summary_add_from_parser (s, mp);
camel_operation_pop_message (cancellable);
- camel_folder_summary_free_hashtable (summary_table);
-
return ret;
}
s = (CamelFolderSummary *) cns;
- full_name = camel_folder_get_full_name (s->folder);
- parent_store = camel_folder_get_parent_store (s->folder);
+ full_name = camel_folder_get_full_name (camel_folder_summary_get_folder (s));
+ parent_store = camel_folder_get_parent_store (camel_folder_summary_get_folder (s));
line +=3;
n = strtoul (line, &line, 10);
/* Check for messages no longer on the server */
if (cns->low != f) {
- count = camel_folder_summary_count (s);
- for (i = 0; i < count; i++) {
- gchar *uid;
- const gchar *msgid;
-
- uid = camel_folder_summary_uid_from_index (s, i);
- n = strtoul (uid, NULL, 10);
-
- if (n < f || n > l) {
- dd (printf ("nntp_summary: %u is lower/higher than lowest/highest article, removed\n", n));
- /* Since we use a global cache this could prematurely remove
- * a cached message that might be in another folder - not that important as
- * it is a true cache */
- msgid = strchr (uid, ',');
- if (msgid)
- camel_data_cache_remove (store->cache, "cache", msgid+1, NULL);
- camel_folder_change_info_remove_uid (changes, uid);
- del = g_list_prepend (del, uid);
- camel_folder_summary_remove_uid_fast (s, uid);
- uid = NULL; /*Lets not free it */
- count--;
- i--;
+ GPtrArray *known_uids;
+
+ known_uids = camel_folder_summary_get_array (s);
+ if (known_uids) {
+ for (i = 0; i < known_uids->len; i++) {
+ const gchar *uid;
+ const gchar *msgid;
+
+ uid = g_ptr_array_index (known_uids, i);
+ n = strtoul (uid, NULL, 10);
+
+ if (n < f || n > l) {
+ dd (printf ("nntp_summary: %u is lower/higher than lowest/highest article, removed\n", n));
+ /* Since we use a global cache this could prematurely remove
+ * a cached message that might be in another folder - not that important as
+ * it is a true cache */
+ msgid = strchr (uid, ',');
+ if (msgid)
+ camel_data_cache_remove (store->cache, "cache", msgid + 1, NULL);
+ camel_folder_change_info_remove_uid (changes, uid);
+ del = g_list_prepend (del, (gpointer) camel_pstring_strdup (uid));
+ camel_folder_summary_remove_uid (s, uid);
+ }
}
- g_free (uid);
+ camel_folder_summary_free_array (known_uids);
}
cns->low = f;
}
camel_db_delete_uids (parent_store->cdb_w, full_name, del, NULL);
- g_list_foreach (del, (GFunc) g_free, NULL);
+ g_list_foreach (del, (GFunc) camel_pstring_free, NULL);
g_list_free (del);
if (cns->high < l) {