diff --git a/src/agents/store/CMakeLists.txt b/src/agents/store/CMakeLists.txt index 983609d..00b9597 100644 --- a/src/agents/store/CMakeLists.txt +++ b/src/agents/store/CMakeLists.txt @@ -19,6 +19,7 @@ add_executable(bongostore main.c mime.c object-model.c + object-queries.c properties.c query-builder.c query-parser.c diff --git a/src/agents/store/command.c b/src/agents/store/command.c index fe9e27f..9516c07 100644 --- a/src/agents/store/command.c +++ b/src/agents/store/command.c @@ -1822,8 +1822,8 @@ StoreCommandDELETE(StoreClient *client, StoreObject *object) switch(object->type) { case STORE_DOCTYPE_MAIL: // check to see if we can remove this document from a conversation - //if (StoreObjectUnlinkFromConversation(client, object)) - // return ConnWriteStr(client->conn, MSG5005DBLIBERR); + if (StoreObjectUnlinkFromConversation(client, object)) + return ConnWriteStr(client->conn, MSG5005DBLIBERR); break; case STORE_DOCTYPE_CALENDAR: // do we want to remove its events also? diff --git a/src/agents/store/object-model.c b/src/agents/store/object-model.c index f5b7995..03eb186 100644 --- a/src/agents/store/object-model.c +++ b/src/agents/store/object-model.c @@ -1,4 +1,15 @@ -/* Create stuff */ +/** + * object-model.c : A set of utility functions for manipulating the store DB + * + * The StoreObject is designed to be allocated on the stack, and these + * functions allow you to find / modify / work with these objects. + * In general, these functions should be relatively safe to call, but + * a higher-level locking mechanism is required to create complete + * atomicity. + * + * object-queries is used to short-hand common SQL queries, and should + * only be used from within this file. + */ #include #include @@ -10,6 +21,7 @@ #include "properties.h" #include "object-model.h" +#include "object-queries.h" #include "query-builder.h" #include "command-parsing.h" #include "messages.h" @@ -585,13 +597,7 @@ abort: int StoreObjectRemove(StoreClient *client, StoreObject *object) { - MsgSQLStatement stmt; - MsgSQLStatement *ret; - char *query; int retcode = -2; - int status; - - memset(&stmt, 0, sizeof(MsgSQLStatement)); // try to remove the file/whatever first if (STORE_IS_FOLDER(object->type)) { @@ -600,32 +606,13 @@ StoreObjectRemove(StoreClient *client, StoreObject *object) // FIXME } - // create a stub entry in the database to get our guid MsgSQLBeginTransaction(client->storedb); - query = "DELETE FROM storeobject WHERE guid=?1;"; - - ret = MsgSQLPrepare(client->storedb, query, &stmt); - if (ret == NULL) goto abort; - - MsgSQLBindInt64(&stmt, 1, object->guid); - - status = MsgSQLExecute(client->storedb, &stmt); - if (status != 0) { - // perhaps the guid doesn't exist... - retcode = -1; - goto abort; + retcode = SOQuery_RemoveSOByGUID(client, object->guid); + if (retcode || MsgSQLCommitTransaction(client->storedb)) { + MsgSQLAbortTransaction(client->storedb); } - MsgSQLFinalize(&stmt); - if (MsgSQLCommitTransaction(client->storedb)) - goto abort; - - return 0; - -abort: - MsgSQLFinalize(&stmt); - MsgSQLAbortTransaction(client->storedb); return retcode; } @@ -1994,9 +1981,8 @@ StoreObjectUnlinkFromConversation(StoreClient *client, StoreObject *mail) if (related == 0) { // conversation now empty, so we can remove it - StoreObject conversation; - StoreObjectFind(client, conversation_guid, &conversation); - StoreObjectRemove(client, &conversation); + status = SOQuery_RemoveSOByGUID(client, conversation_guid); + if (status != 0) goto abort; } } diff --git a/src/agents/store/object-queries.c b/src/agents/store/object-queries.c new file mode 100644 index 0000000..c9217ee --- /dev/null +++ b/src/agents/store/object-queries.c @@ -0,0 +1,49 @@ +/** + * object-queries.c : common SQL queries used in the object model. + * + * This is a set of utility SQL queries that is used to help make the + * object-model.c file a bit more concise. + * + * Functions in here do not setup transactions, so the caller can setup + * a transaction and call many of the functions in a row. These functions + * should not be used outside of object-model.c + */ + +#include +#include +#include +#include "object-model.h" +#include "object-queries.h" + +/** + * Remove an object from the store by its guid + * + * \param client Store client we're operating for + * \param guid GUID of the object we want to remove + * \return 0 on success, -1 is 'no such guid', -2 is other failure + */ +int +SOQuery_RemoveSOByGUID(StoreClient *client, uint64_t guid) +{ + MsgSQLStatement stmt; + MsgSQLStatement *ret; + char *query; + int retcode = -2; + int status; + + memset(&stmt, 0, sizeof(MsgSQLStatement)); + + query = "DELETE FROM storeobject WHERE guid=?1;"; + + ret = MsgSQLPrepare(client->storedb, query, &stmt); + if (ret == NULL) goto end; + + MsgSQLBindInt64(&stmt, 1, guid); + + status = MsgSQLExecute(client->storedb, &stmt); + retcode = (status == 0)? 0 : -1; + +end: + MsgSQLFinalize(&stmt); + return retcode; +} diff --git a/src/agents/store/object-queries.h b/src/agents/store/object-queries.h new file mode 100644 index 0000000..2e7bcf9 --- /dev/null +++ b/src/agents/store/object-queries.h @@ -0,0 +1,6 @@ +#ifndef OBJECT_QUERIES_H +#define OBJECT_QUERIES_H + +int SOQuery_RemoveSOByGUID(StoreClient *client, uint64_t guid); + +#endif // OBJECT_QUERIES_H