summaryrefslogtreecommitdiff
path: root/camel/camel-db.c
diff options
context:
space:
mode:
Diffstat (limited to 'camel/camel-db.c')
-rw-r--r--camel/camel-db.c146
1 files changed, 102 insertions, 44 deletions
diff --git a/camel/camel-db.c b/camel/camel-db.c
index 89cf06c15..7bc019c33 100644
--- a/camel/camel-db.c
+++ b/camel/camel-db.c
@@ -28,6 +28,7 @@
#include <config.h>
+#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
@@ -49,6 +50,7 @@
#endif
static GStaticRecMutex trans_lock = G_STATIC_REC_MUTEX_INIT;
+static char *db_path = NULL;
static int
cdb_sql_exec (sqlite3 *db, const char* stmt, CamelException *ex)
@@ -116,8 +118,6 @@ camel_db_open (const char *path, CamelException *ex)
cdb->db = db;
cdb->lock = g_mutex_new ();
/* These will be written once the Summary takes control of the CDB. */
- cdb->sort_by = NULL;
- cdb->collate = NULL;
d(g_print ("\nDatabase succesfully opened \n"));
/* Which is big / costlier ? A Stack frame or a pointer */
@@ -155,9 +155,6 @@ camel_db_set_collate (CamelDB *cdb, const char *col, const char *collate, CamelD
return 0;
g_mutex_lock (cdb->lock);
- cdb->sort_by = col;
- cdb->collate = collate;
- cdb->collate_cb = func;
d(g_print("Creating Collation %s on %s with %p\n", collate, col, func));
if (collate && func)
ret = sqlite3_create_collation(cdb->db, collate, SQLITE_UTF8, NULL, func);
@@ -338,7 +335,7 @@ camel_db_count_junk_message_info (CamelDB *cdb, const char *table_name, guint32
if (!cdb)
return -1;
- query = sqlite3_mprintf ("SELECT COUNT (*) FROM %Q WHERE junk = 1", table_name);
+ query = sqlite3_mprintf ("SELECT COUNT (*) FROM messages WHERE folder_key = %Q AND junk = 1", table_name);
ret = camel_db_count_message_info (cdb, query, count, ex);
sqlite3_free (query);
@@ -355,7 +352,7 @@ camel_db_count_unread_message_info (CamelDB *cdb, const char *table_name, guint3
if (!cdb)
return -1;
- query = sqlite3_mprintf ("SELECT COUNT (*) FROM %Q WHERE read = 0", table_name);
+ query = sqlite3_mprintf ("SELECT COUNT (*) FROM messages WHERE folder_key = %Q AND read = 0", table_name);
ret = camel_db_count_message_info (cdb, query, count, ex);
sqlite3_free (query);
@@ -372,7 +369,7 @@ camel_db_count_visible_unread_message_info (CamelDB *cdb, const char *table_name
if (!cdb)
return -1;
- query = sqlite3_mprintf ("SELECT COUNT (*) FROM %Q WHERE read = 0 AND junk = 0 AND deleted = 0", table_name);
+ query = sqlite3_mprintf ("SELECT COUNT (*) FROM messages WHERE folder_key = %Q AND read = 0 AND junk = 0 AND deleted = 0", table_name);
ret = camel_db_count_message_info (cdb, query, count, ex);
sqlite3_free (query);
@@ -389,7 +386,7 @@ camel_db_count_visible_message_info (CamelDB *cdb, const char *table_name, guint
if (!cdb)
return -1;
- query = sqlite3_mprintf ("SELECT COUNT (*) FROM %Q WHERE junk = 0 AND deleted = 0", table_name);
+ query = sqlite3_mprintf ("SELECT COUNT (*) FROM messages WHERE folder_key = %Q AND junk = 0 AND deleted = 0", table_name);
ret = camel_db_count_message_info (cdb, query, count, ex);
sqlite3_free (query);
@@ -406,7 +403,7 @@ camel_db_count_junk_not_deleted_message_info (CamelDB *cdb, const char *table_na
if (!cdb)
return -1;
- query = sqlite3_mprintf ("SELECT COUNT (*) FROM %Q WHERE junk = 1 AND deleted = 0", table_name);
+ query = sqlite3_mprintf ("SELECT COUNT (*) FROM messages WHERE folder_key = %Q AND junk = 1 AND deleted = 0", table_name);
ret = camel_db_count_message_info (cdb, query, count, ex);
sqlite3_free (query);
@@ -423,7 +420,7 @@ camel_db_count_deleted_message_info (CamelDB *cdb, const char *table_name, guint
if (!cdb)
return -1;
- query = sqlite3_mprintf ("SELECT COUNT (*) FROM %Q WHERE deleted = 1", table_name);
+ query = sqlite3_mprintf ("SELECT COUNT (*) FROM messages WHERE folder_key = %Q AND deleted = 1", table_name);
ret = camel_db_count_message_info (cdb, query, count, ex);
sqlite3_free (query);
@@ -442,7 +439,7 @@ camel_db_count_total_message_info (CamelDB *cdb, const char *table_name, guint32
if (!cdb)
return -1;
- query = sqlite3_mprintf ("SELECT COUNT (*) FROM %Q", table_name);
+ query = sqlite3_mprintf ("SELECT COUNT (*) FROM messages where folder_key = %Q", table_name);
ret = camel_db_count_message_info (cdb, query, count, ex);
sqlite3_free (query);
@@ -583,14 +580,15 @@ read_uids_callback (void *ref, int ncol, char ** cols, char ** name)
}
int
-camel_db_get_folder_uids (CamelDB *db, char *folder_name, GPtrArray *array, CamelException *ex)
+camel_db_get_folder_uids (CamelDB *db, char *folder_name, char *sort_by, char *collate, GPtrArray *array, CamelException *ex)
{
char *sel_query;
int ret;
-
- sel_query = sqlite3_mprintf("SELECT uid FROM %Q%s%s%s%s", folder_name, db->sort_by ? " order by " : "", db->sort_by ? db->sort_by: "", (db->sort_by && db->collate) ? " collate " : "", (db->sort_by && db->collate) ? db->collate : "");
+ printf("start %s: %d\n", folder_name, time(NULL));
+ sel_query = sqlite3_mprintf("SELECT uid FROM messages WHERE folder_key=%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, ex);
+ printf("end %s: %d\n", folder_name, time(NULL));
sqlite3_free (sel_query);
return ret;
@@ -603,7 +601,7 @@ camel_db_get_folder_junk_uids (CamelDB *db, char *folder_name, CamelException *e
int ret;
GPtrArray *array = g_ptr_array_new();
- sel_query = sqlite3_mprintf("SELECT uid FROM %Q where junk=1", folder_name);
+ sel_query = sqlite3_mprintf("SELECT uid FROM messages where folder_key=%Q AND junk=1", folder_name);
ret = camel_db_select (db, sel_query, read_uids_callback, array, ex);
@@ -623,7 +621,7 @@ camel_db_get_folder_deleted_uids (CamelDB *db, char *folder_name, CamelException
int ret;
GPtrArray *array = g_ptr_array_new();
- sel_query = sqlite3_mprintf("SELECT uid FROM %Q where deleted=1", folder_name);
+ sel_query = sqlite3_mprintf("SELECT uid FROM messages where folder_key=%Q AND deleted=1", folder_name);
ret = camel_db_select (db, sel_query, read_uids_callback, array, ex);
sqlite3_free (sel_query);
@@ -720,7 +718,10 @@ int
camel_db_create_folders_table (CamelDB *cdb, CamelException *ex)
{
char *query = "CREATE TABLE IF NOT EXISTS folders ( folder_name TEXT PRIMARY KEY, version REAL, flags INTEGER, nextuid INTEGER, time NUMERIC, saved_count INTEGER, unread_count INTEGER, deleted_count INTEGER, junk_count INTEGER, visible_count INTEGER, jnd_count INTEGER, bdata TEXT )";
+
+ return 0;
CAMEL_DB_RELEASE_SQLITE_MEMORY;
+
return ((camel_db_command (cdb, query, ex)));
}
@@ -729,7 +730,8 @@ camel_db_prepare_message_info_table (CamelDB *cdb, const char *folder_name, Came
{
int ret;
char *table_creation_query, *safe_index;
-
+
+ return 0;
/* README: It is possible to compress all system flags into a single column and use just as userflags but that makes querying for other applications difficult an d bloats the parsing code. Instead, it is better to bloat the tables. Sqlite should have some optimizations for sparse columns etc. */
table_creation_query = sqlite3_mprintf ("CREATE TABLE IF NOT EXISTS %Q ( uid TEXT PRIMARY KEY , flags INTEGER , msg_type INTEGER , read INTEGER , deleted INTEGER , replied INTEGER , important INTEGER , junk INTEGER , attachment INTEGER , msg_security INTEGER , size INTEGER , dsent NUMERIC , dreceived NUMERIC , subject TEXT , mail_from TEXT , mail_to TEXT , mail_cc TEXT , mlist TEXT , followup_flag TEXT , followup_completed_on TEXT , followup_due_by TEXT , part TEXT , labels TEXT , usertags TEXT , cinfo TEXT , bdata TEXT )", folder_name);
@@ -755,10 +757,10 @@ camel_db_write_message_info_record (CamelDB *cdb, const char *folder_name, Camel
char *del_query;
char *ins_query;
- ins_query = sqlite3_mprintf ("INSERT INTO %Q VALUES (%Q, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %ld, %ld, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q )",
- folder_name, record->uid, record->flags,
+ ins_query = sqlite3_mprintf ("INSERT INTO messages VALUES (%Q, %Q, '%s%s', %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %ld, %ld, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q )",
+ folder_name, record->uid, folder_name, record->uid, record->flags,
record->msg_type, record->read, record->deleted, record->replied,
- record->important, record->junk, record->attachment, record->msg_security,
+ record->important, record->junk, record->attachment, record->dirty,
record->size, record->dsent, record->dreceived,
record->subject, record->from, record->to,
record->cc, record->mlist, record->followup_flag,
@@ -766,7 +768,7 @@ camel_db_write_message_info_record (CamelDB *cdb, const char *folder_name, Camel
record->part, record->labels, record->usertags,
record->cinfo, record->bdata);
- del_query = sqlite3_mprintf ("DELETE FROM %Q WHERE uid = %Q", folder_name, record->uid);
+ del_query = sqlite3_mprintf ("DELETE FROM messages WHERE folder_key = %Q AND uid = %Q", folder_name, record->uid);
#if 0
char *upd_query;
@@ -795,13 +797,13 @@ camel_db_write_folder_info_record (CamelDB *cdb, CamelFIRecord *record, CamelExc
char *del_query;
char *ins_query;
- ins_query = sqlite3_mprintf ("INSERT INTO folders VALUES ( %Q, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %Q ) ",
- record->folder_name, record->version,
+ ins_query = sqlite3_mprintf ("INSERT INTO folders VALUES ( %Q, %Q, %Q, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %Q ) ",
+ record->account_url, record->folder_name, record->folder_key, record->version,
record->flags, record->nextuid, record->time,
record->saved_count, record->unread_count,
record->deleted_count, record->junk_count, record->visible_count, record->jnd_count, record->bdata);
- del_query = sqlite3_mprintf ("DELETE FROM folders WHERE folder_name = %Q", record->folder_name);
+ del_query = sqlite3_mprintf ("DELETE FROM folders WHERE account_url = %Q AND folder_name = %Q", record->account_url, record->folder_name);
#if 0
@@ -870,19 +872,23 @@ read_fir_callback (void * ref, int ncol, char ** cols, char ** name)
record->jnd_count = cols [i] ? strtoul (cols [i], NULL, 10) : 0;
else if (!strcmp (name [i], "bdata"))
record->bdata = g_strdup (cols [i]);
-
+ else if (!strcmp (name [i], "account_url"))
+ record->account_url = g_strdup (cols [i]);
+ else if (!strcmp (name [i], "folder_key"))
+ record->folder_key = g_strdup (cols [i]);
+
}
#endif
return 0;
}
int
-camel_db_read_folder_info_record (CamelDB *cdb, const char *folder_name, CamelFIRecord **record, CamelException *ex)
+camel_db_read_folder_info_record (CamelDB *cdb, const char *url, const char *folder_name, CamelFIRecord **record, CamelException *ex)
{
char *query;
int ret;
- query = sqlite3_mprintf ("SELECT * FROM folders WHERE folder_name = %Q", folder_name);
+ query = sqlite3_mprintf ("SELECT * FROM folders WHERE account_url = %Q AND folder_name = %Q", url, folder_name);
ret = camel_db_select (cdb, query, read_fir_callback, record, ex);
sqlite3_free (query);
@@ -890,12 +896,12 @@ camel_db_read_folder_info_record (CamelDB *cdb, const char *folder_name, CamelFI
}
int
-camel_db_read_message_info_record_with_uid (CamelDB *cdb, const char *folder_name, const char *uid, gpointer p, CamelDBSelectCB read_mir_callback, CamelException *ex)
+camel_db_read_message_info_record_with_uid (CamelDB *cdb, const char *folder_name, const char *uid, gpointer p, CamelDBSelectCB read_mir_callback, gboolean vuid, CamelException *ex)
{
char *query;
int ret;
- query = sqlite3_mprintf ("SELECT uid, flags, size, dsent, dreceived, subject, mail_from, mail_to, mail_cc, mlist, part, labels, usertags, cinfo, bdata FROM %Q WHERE uid = %Q", folder_name, uid);
+ query = sqlite3_mprintf ("SELECT folder_key, %s, flags, size, dsent, dreceived, subject, mail_from, mail_to, mail_cc, mlist, part, labels, usertags, cinfo, bdata FROM messages WHERE folder_key = %Q AND %s = %Q", vuid ? "vuid" : "uid", folder_name, vuid ? "vuid" : "uid", uid);
ret = camel_db_select (cdb, query, read_mir_callback, p, ex);
sqlite3_free (query);
@@ -903,13 +909,14 @@ camel_db_read_message_info_record_with_uid (CamelDB *cdb, const char *folder_nam
}
int
-camel_db_read_message_info_records (CamelDB *cdb, const char *folder_name, gpointer p, CamelDBSelectCB read_mir_callback, CamelException *ex)
+camel_db_read_message_info_records (CamelDB *cdb, const char *folder_name, gpointer p, CamelDBSelectCB read_mir_callback, char *v_query, CamelException *ex)
{
char *query;
int ret;
-
- query = sqlite3_mprintf ("SELECT uid, flags, size, dsent, dreceived, subject, mail_from, mail_to, mail_cc, mlist, part, labels, usertags, cinfo, bdata FROM %Q ", folder_name);
+ char *tmp = sqlite3_mprintf ("%Q", folder_name);
+ query = sqlite3_mprintf ("SELECT folder_key, %s, flags, size, dsent, dreceived, subject, mail_from, mail_to, mail_cc, mlist, part, labels, usertags, cinfo, bdata FROM messages where %s%s", v_query ? "vuid" : "uid", v_query ? v_query : "folder_key = ", v_query ? "" : tmp);
ret = camel_db_select (cdb, query, read_mir_callback, p, ex);
+ sqlite3_free (tmp);
sqlite3_free (query);
return (ret);
@@ -918,7 +925,7 @@ camel_db_read_message_info_records (CamelDB *cdb, const char *folder_name, gpoin
int
camel_db_delete_uid (CamelDB *cdb, const char *folder, const char *uid, CamelException *ex)
{
- char *tab = sqlite3_mprintf ("DELETE FROM %Q WHERE uid = %Q", folder, uid);
+ char *tab = sqlite3_mprintf ("DELETE FROM messages WHERE folder_key = %Q AND uid = %Q", folder, uid);
int ret;
ret = camel_db_command (cdb, tab, ex);
@@ -936,7 +943,7 @@ camel_db_delete_uids (CamelDB *cdb, const char * folder_name, GSList *uids, Came
GString *str = g_string_new ("DELETE FROM ");
GSList *iterator;
- tmp = sqlite3_mprintf ("%Q WHERE uid IN (", folder_name);
+ tmp = sqlite3_mprintf ("messages WHERE folder_KEY = %Q AND uid IN (", folder_name);
g_string_append_printf (str, "%s ", tmp);
sqlite3_free (tmp);
@@ -965,15 +972,15 @@ camel_db_delete_uids (CamelDB *cdb, const char * folder_name, GSList *uids, Came
}
int
-camel_db_clear_folder_summary (CamelDB *cdb, char *folder, CamelException *ex)
+camel_db_clear_folder_summary (CamelDB *cdb, char *url, char *folder, char *key, CamelException *ex)
{
int ret;
char *folders_del;
char *msginfo_del;
- folders_del = sqlite3_mprintf ("DELETE FROM folders WHERE folder_name = %Q", folder);
- msginfo_del = sqlite3_mprintf ("DELETE FROM %Q ", folder);
+ folders_del = sqlite3_mprintf ("DELETE FROM folders WHERE account_url = %Q AND folder_name = %Q", folder);
+ msginfo_del = sqlite3_mprintf ("DELETE FROM messages WHERE folder_key= %Q ", key);
camel_db_begin_transaction (cdb, ex);
camel_db_add_to_transaction (cdb, msginfo_del, ex);
@@ -986,6 +993,7 @@ camel_db_clear_folder_summary (CamelDB *cdb, char *folder, CamelException *ex)
return ret;
}
+/* Obsolete */
int
camel_db_delete_folder (CamelDB *cdb, const char *folder, CamelException *ex)
{
@@ -1005,16 +1013,12 @@ camel_db_delete_folder (CamelDB *cdb, const char *folder, CamelException *ex)
}
int
-camel_db_rename_folder (CamelDB *cdb, const char *old_folder, const char *new_folder, CamelException *ex)
+camel_db_rename_folder (CamelDB *cdb, char *url, const char *old_folder, const char *new_folder, CamelException *ex)
{
int ret;
char *cmd;
- cmd = sqlite3_mprintf ("ALTER TABLE %Q RENAME TO %Q", old_folder, new_folder);
- ret = camel_db_command (cdb, cmd, ex);
- sqlite3_free (cmd);
-
- cmd = sqlite3_mprintf ("UPDATE folders SET folder_name = %Q WHERE folder_name = %Q", new_folder, old_folder);
+ cmd = sqlite3_mprintf ("UPDATE folders SET folder_name = %Q WHERE account_url = %Q AND folder_name = %Q", new_folder, url, old_folder);
ret = camel_db_command (cdb, cmd, ex);
sqlite3_free (cmd);
@@ -1026,7 +1030,9 @@ void
camel_db_camel_mir_free (CamelMIRecord *record)
{
if (record) {
+ camel_pstring_free (record->folder_key);
camel_pstring_free (record->uid);
+ camel_pstring_free (record->vuid);
camel_pstring_free (record->subject);
camel_pstring_free (record->from);
camel_pstring_free (record->to);
@@ -1118,3 +1124,55 @@ camel_db_migrate_vfolders_to_14 (CamelDB *cdb, const char *folder, CamelExceptio
CAMEL_DB_RELEASE_SQLITE_MEMORY;
return ret;
}
+
+static int
+cdb_setup_tables (CamelDB *db, CamelException *ex)
+{
+ int ret = 0;
+ const char *query;
+
+ query = "CREATE TABLE IF NOT EXISTS folders ( account_url TEXT , folder_name TEXT , folder_key TEXT, version REAL, flags INTEGER, nextuid INTEGER, time NUMERIC, saved_count INTEGER, unread_count INTEGER, deleted_count INTEGER, junk_count INTEGER, visible_count INTEGER, jnd_count INTEGER, bdata TEXT, PRIMARY KEY(account_url, folder_name))";
+ ret = camel_db_command (db, query, ex);
+ if (ret == -1)
+ return ret;
+
+ query = "CREATE TABLE IF NOT EXISTS messages ( folder_key TEXT , uid TEXT , vuid TEXT, flags INTEGER , msg_type INTEGER , read INTEGER , deleted INTEGER , replied INTEGER , important INTEGER , junk INTEGER , attachment INTEGER , dirty INTEGER , size INTEGER , dsent NUMERIC , dreceived NUMERIC , subject TEXT , mail_from TEXT , mail_to TEXT , mail_cc TEXT , mlist TEXT , followup_flag TEXT , followup_completed_on TEXT , followup_due_by TEXT , part TEXT , labels TEXT , usertags TEXT , cinfo TEXT , bdata TEXT, PRIMARY KEY (folder_key, uid) )";
+
+ ret = camel_db_command (db, query, ex);
+ if (ret == -1)
+ return ret;
+
+ /* Create index for searches */
+ ret = camel_db_command (db, "CREATE INDEX 'messages-junk' on messages (junk)", ex);
+ ret = camel_db_command (db, "CREATE INDEX 'messages-deleted' on messages (deleted)", ex);
+ ret = camel_db_command (db, "CREATE INDEX 'messages-read' on messages (read)", ex);
+
+ return ret;
+}
+
+/* A func that just creates tables and closes everything */
+int
+camel_db_setup (const char *path, CamelException *ex)
+{
+ CamelDB *db;
+
+ db_path = g_build_filename (path, CAMEL_DB_V2_FILE, NULL);
+ if (!g_file_test(db_path, G_FILE_TEST_EXISTS)) {
+ if (!g_file_test(path, G_FILE_TEST_EXISTS)) {
+ g_mkdir_with_parents (path, S_IRWXU);
+ }
+ db = camel_db_open (db_path, ex);
+ if (!db)
+ return -1;
+ cdb_setup_tables (db, ex);
+ camel_db_close(db);
+ }
+
+ return 0;
+}
+
+CamelDB *
+camel_db_get_handle (CamelException *ex)
+{
+ return camel_db_open (db_path, ex);
+}