From 0c61366536f83bcecbf74a4c0f433886bd7f4e2d Mon Sep 17 00:00:00 2001 From: alexhudson Date: Sun, 11 Jul 2010 12:26:19 +0000 Subject: [PATCH] Refactor unlink bits a little bit to simplify the code. --- src/agents/store/object-model.c | 95 +++++-------------------------- src/agents/store/object-queries.c | 95 +++++++++++++++++++++++++++++++ src/agents/store/object-queries.h | 4 ++ 3 files changed, 114 insertions(+), 80 deletions(-) diff --git a/src/agents/store/object-model.c b/src/agents/store/object-model.c index 03eb186..7d53451 100644 --- a/src/agents/store/object-model.c +++ b/src/agents/store/object-model.c @@ -1878,36 +1878,16 @@ StoreObjectUnlink(StoreClient *client, StoreObject *document, StoreObject *relat int StoreObjectUnlinkAll(StoreClient *client, StoreObject *object) { - MsgSQLStatement stmt; - MsgSQLStatement *ret; - char *query; - int status; - - memset(&stmt, 0, sizeof(MsgSQLStatement)); - MsgSQLBeginTransaction(client->storedb); - query = "DELETE FROM links WHERE doc_guid=?1 OR related_guid=?1;"; + int status = SOQuery_Unlink(client, object->guid, object->guid, TRUE); - ret = MsgSQLPrepare(client->storedb, query, &stmt); - if (ret == NULL) goto abort; - - MsgSQLBindInt64(&stmt, 1, object->guid); - - status = MsgSQLExecute(client->storedb, &stmt); - if (status != 0) - goto abort; - - MsgSQLFinalize(&stmt); - if (MsgSQLCommitTransaction(client->storedb)) - goto abort; + if (status || MsgSQLCommitTransaction(client->storedb)) { + MsgSQLAbortTransaction(client->storedb); + return -1; + } return 0; - -abort: - MsgSQLFinalize(&stmt); - MsgSQLAbortTransaction(client->storedb); - return -1; } @@ -1928,43 +1908,20 @@ StoreObjectUnlinkFromConversation(StoreClient *client, StoreObject *mail) MsgSQLStatement stmt; MsgSQLStatement *ret; char *query; - int status; - uint64_t conversation_guid = 0; memset(&stmt, 0, sizeof(MsgSQLStatement)); MsgSQLBeginTransaction(client->storedb); - // find the mail conversation for this object - query = "SELECT so.guid FROM links l LEFT JOIN storeobject so ON l.doc_guid = so.guid WHERE l.related_guid = ?1 AND so.collection_guid = ?2 AND so.type = 5;"; - ret = MsgSQLPrepare(client->storedb, query, &stmt); - if (ret == NULL) goto abort; - - MsgSQLBindInt64(&stmt, 1, mail->guid); - MsgSQLBindInt64(&stmt, 2, STORE_CONVERSATIONS_GUID); - - // this assumes only one convo per mail. Should be ok.. - status = MsgSQLResults(client->storedb, &stmt); - if (status > 0) { - conversation_guid = MsgSQLResultInt64(&stmt, 0); - } - MsgSQLFinalize(&stmt); + // find the conversation for the email + uint64_t conversation_guid = SOQuery_ConversationGUIDForEmail(client, mail->guid); // unlink the mail from the conversation - // FIXME - refactor this code and StoreObjectUnlinkByGuids() - // We can't use the latter directly atm because of transactions. - query = "DELETE FROM links WHERE doc_guid=?1 AND related_guid=?2;"; - - ret = MsgSQLPrepare(client->storedb, query, &stmt); - if (ret == NULL) goto abort; - - MsgSQLBindInt64(&stmt, 1, conversation_guid); - MsgSQLBindInt64(&stmt, 2, mail->guid); - - status = MsgSQLExecute(client->storedb, &stmt); + int status = SOQuery_Unlink(client, conversation_guid, mail->guid, FALSE); if (status != 0) goto abort; - // find the number of other mails attached to this conversation + // find the number of other mails attached to this conversation - if + // the conversation is 'empty', we want to now remove it. if (conversation_guid) { query = "SELECT count(l.related_guid) FROM links l WHERE l.doc_guid = ?1;"; ret = MsgSQLPrepare(client->storedb, query, &stmt); @@ -2009,38 +1966,16 @@ abort: int StoreObjectUnlinkByGuids(StoreClient *client, uint64_t document, uint64_t related) { - // FIXME: want to check that an existing link isn't in place somehow. - MsgSQLStatement stmt; - MsgSQLStatement *ret; - char *query; - int status; - - memset(&stmt, 0, sizeof(MsgSQLStatement)); - MsgSQLBeginTransaction(client->storedb); - query = "DELETE FROM links WHERE doc_guid=?1 AND related_guid=?2;"; + int status = SOQuery_Unlink(client, document, related, FALSE); - ret = MsgSQLPrepare(client->storedb, query, &stmt); - if (ret == NULL) goto abort; - - MsgSQLBindInt64(&stmt, 1, document); - MsgSQLBindInt64(&stmt, 2, related); - - status = MsgSQLExecute(client->storedb, &stmt); - if (status != 0) - goto abort; - - MsgSQLFinalize(&stmt); - if (MsgSQLCommitTransaction(client->storedb)) - goto abort; + if (status || MsgSQLCommitTransaction(client->storedb)) { + MsgSQLAbortTransaction(client->storedb); + return -1; + } return 0; - -abort: - MsgSQLFinalize(&stmt); - MsgSQLAbortTransaction(client->storedb); - return -1; } /** diff --git a/src/agents/store/object-queries.c b/src/agents/store/object-queries.c index c9217ee..a8cdc7f 100644 --- a/src/agents/store/object-queries.c +++ b/src/agents/store/object-queries.c @@ -47,3 +47,98 @@ end: MsgSQLFinalize(&stmt); return retcode; } + +/** + * Find the related conversation GUID for a given document. + * Only really makes sense if the GUID passed is for an email document. + * + * \param client Store client we're operating for + * \param guid GUID of the object we want to find the conversation for + * \return 0 on failure, the GUID otherwise. + */ +uint64_t +SOQuery_ConversationGUIDForEmail(StoreClient *client, uint64_t guid) +{ + MsgSQLStatement stmt; + MsgSQLStatement *ret; + char *query; + int status; + uint64_t conversation_guid = 0; + + memset(&stmt, 0, sizeof(MsgSQLStatement)); + + query = "SELECT so.guid FROM links l LEFT JOIN storeobject so ON l.doc_guid = so.guid WHERE l.related_guid = ?1 AND so.collection_guid = ?2 AND so.type = 5;"; + ret = MsgSQLPrepare(client->storedb, query, &stmt); + if (ret == NULL) goto end; + + MsgSQLBindInt64(&stmt, 1, guid); + MsgSQLBindInt64(&stmt, 2, STORE_CONVERSATIONS_GUID); + + // this assumes only one convo per mail. Should be ok.. + status = MsgSQLResults(client->storedb, &stmt); + if (status > 0) { + conversation_guid = MsgSQLResultInt64(&stmt, 0); + } +end: + MsgSQLFinalize(&stmt); + + return conversation_guid; +} + +/** + * Unlink store objects. Supply the document and the related document, and the + * link between the two is removed. If either the document or related + * document is 0, it means "any document". + * + * \param client Store client we're operating for + * \param document GUID of document we want to relate to + * \param related GUID of relative we want to unlink from + * \param any If true, we remove anything linked to the document or related GUID + * (only has an effect when document and related are supplied) + * \return 0 if successful, -1 otherwise + */ +int +SOQuery_Unlink(StoreClient *client, uint64_t document, uint64_t related, BOOL any) +{ + MsgSQLStatement stmt; + MsgSQLStatement *ret; + char *query; + int status; + + if ((document == 0) || (related == 0)) return -1; + + memset(&stmt, 0, sizeof(MsgSQLStatement)); + + if (document && related) { + if (any == TRUE) { + query = "DELETE FROM links WHERE doc_guid=?1 OR related_guid=?2;"; + } else { + query = "DELETE FROM links WHERE doc_guid=?1 AND related_guid=?2;"; + } + } else if (document) { + query = "DELETE FROM links WHERE doc_guid=?1"; + } else { + query = "DELETE FROM links WHERE related_guid=?2"; + } + + ret = MsgSQLPrepare(client->storedb, query, &stmt); + if (ret == NULL) goto abort; + + if (document != 0) { + MsgSQLBindInt64(&stmt, 1, document); + } else { + MsgSQLBindInt64(&stmt, 1, related); + } + if (document && related) MsgSQLBindInt64(&stmt, 2, related); + + status = MsgSQLExecute(client->storedb, &stmt); + if (status != 0) goto abort; + + MsgSQLFinalize(&stmt); + + return 0; + +abort: + MsgSQLFinalize(&stmt); + return -1; +} diff --git a/src/agents/store/object-queries.h b/src/agents/store/object-queries.h index 2e7bcf9..36a0201 100644 --- a/src/agents/store/object-queries.h +++ b/src/agents/store/object-queries.h @@ -3,4 +3,8 @@ int SOQuery_RemoveSOByGUID(StoreClient *client, uint64_t guid); +int SOQuery_Unlink(StoreClient *client, uint64_t document, uint64_t related, BOOL any); + +uint64_t SOQuery_ConversationGUIDForEmail(StoreClient *client, uint64_t guid); + #endif // OBJECT_QUERIES_H