Refactor unlink bits a little bit to simplify the code.

This commit is contained in:
alexhudson
2010-07-11 12:26:19 +00:00
parent e23685f047
commit 0c61366536
3 changed files with 114 additions and 80 deletions
+15 -80
View File
@@ -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;
}
/**
+95
View File
@@ -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;
}
+4
View File
@@ -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