diff --git a/libretroshare/src/gxs/rsdataservice.cc b/libretroshare/src/gxs/rsdataservice.cc index a14c4306d..09191f658 100644 --- a/libretroshare/src/gxs/rsdataservice.cc +++ b/libretroshare/src/gxs/rsdataservice.cc @@ -621,10 +621,10 @@ int RsDataService::retrieveNxsMsgs(const GxsMsgReq &reqIds, GxsMsgResult &msg, b const std::string& grpId = mit->first; // if vector empty then request all messages - const std::set& msgIdSet = mit->second; + const std::vector& msgIdV = mit->second; std::vector msgSet; - if(msgIdSet.empty()){ + if(msgIdV.empty()){ RetroCursor* c = mDb->sqlQuery(MSG_TABLE_NAME, msgColumns, KEY_GRP_ID+ "='" + grpId + "'", ""); if(c) @@ -634,9 +634,9 @@ int RsDataService::retrieveNxsMsgs(const GxsMsgReq &reqIds, GxsMsgResult &msg, b }else{ // request each grp - std::set::const_iterator sit = msgIdSet.begin(); + std::vector::const_iterator sit = msgIdV.begin(); - for(; sit!=msgIdSet.end();sit++){ + for(; sit!=msgIdV.end();sit++){ const std::string& msgId = *sit; RetroCursor* c = mDb->sqlQuery(MSG_TABLE_NAME, msgColumns, KEY_GRP_ID+ "='" + grpId + "' AND " + KEY_MSG_ID + "='" + msgId + "'", ""); diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 74df9da0b..b86768efb 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -5,7 +5,7 @@ RsGenExchange::RsGenExchange(RsGeneralDataService *gds, : mReqMtx("GenExchange"), mDataStore(gds), mNetService(ns), mSerialiser(serviceSerialiser) { - mDataAccess = new RsGxsDataAccess(gds, mSerialiser); + mDataAccess = new RsGxsDataAccess(gds); } @@ -26,13 +26,14 @@ RsGenExchange::~RsGenExchange() void RsGenExchange::tick() { - + mDataAccess->processRequests(); } bool RsGenExchange::getGroupList(const uint32_t &token, std::list &groupIds) { + return false; } diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index fe814f8c4..a3c867111 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -170,6 +170,14 @@ protected: */ virtual void notifyChanges(std::vector& changes) = 0; +private: + + void processRecvdData(); + + void processRecvdMessages(); + + void processRecvdGroups(); + private: RsMutex mReqMtx; diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index afea2e55d..b92010a5b 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -1,5 +1,55 @@ #include "rsgxsdataaccess.h" -#include "retroshare/rsidentity.h" + +/* + * libretroshare/src/retroshare: rsgxsdataaccess.cc + * + * RetroShare C++ Interface. + * + * Copyright 2012-2012 by Robert Fernie, Christopher Evi-Parker + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +// This bit will be filled out over time. +#define RS_TOKREQOPT_MSG_VERSIONS 0x0001 // MSGRELATED: Returns All MsgIds with OrigMsgId = MsgId. +#define RS_TOKREQOPT_MSG_ORIGMSG 0x0002 // MSGLIST: All Unique OrigMsgIds in a Group. +#define RS_TOKREQOPT_MSG_LATEST 0x0004 // MSGLIST: All Latest MsgIds in Group. MSGRELATED: Latest MsgIds for Input Msgs. + +#define RS_TOKREQOPT_MSG_THREAD 0x0010 // MSGRELATED: All Msgs in Thread. MSGLIST: All Unique Thread Ids in Group. +#define RS_TOKREQOPT_MSG_PARENT 0x0020 // MSGRELATED: All Children Msgs. + +#define RS_TOKREQOPT_MSG_AUTHOR 0x0040 // MSGLIST: Messages from this AuthorId + + +// Status Filtering... should it be a different Option Field. +#define RS_TOKREQOPT_GROUP_UPDATED 0x0100 // GROUPLIST: Groups that have been updated. +#define RS_TOKREQOPT_MSG_UPDATED 0x0200 // MSGLIST: Msg that have been updated from specified groups. +#define RS_TOKREQOPT_MSG_UPDATED 0x0200 // MSGLIST: Msg that have been updated from specified groups. + + + +// Read Status. +#define RS_TOKREQOPT_READ 0x0001 +#define RS_TOKREQOPT_UNREAD 0x0002 + +#define RS_TOKREQ_ANSTYPE_LIST 0x0001 +#define RS_TOKREQ_ANSTYPE_SUMMARY 0x0002 +#define RS_TOKREQ_ANSTYPE_DATA 0x0003 RsGxsDataAccess::RsGxsDataAccess(RsGeneralDataService* ds) : mDataStore(ds) @@ -10,28 +60,91 @@ RsGxsDataAccess::RsGxsDataAccess(RsGeneralDataService* ds) bool RsGxsDataAccess::requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) { + GxsRequest* req = NULL; + uint32_t reqType = opts.mReqType; + + if(reqType & GXS_REQUEST_TYPE_GROUP_META) + { + GroupMetaReq* gmr = new GroupMetaReq(); + gmr->mGroupIds = groupIds; + req = gmr; + } + else if(reqType & GXS_REQUEST_TYPE_GROUP_DATA) + { + GroupDataReq* gdr = new GroupDataReq(); + gdr->mGroupIds = groupIds; + req = gdr; + } + else if(reqType & GXS_REQUEST_TYPE_GROUP_IDS) + { + GroupIdReq* gir = new GroupIdReq(); + gir->mGroupIds = groupIds; + req = gir; + } + + if(req == NULL) + { + std::cerr << "RsGxsDataAccess::requestMsgInfo() request type not recognised, type " + << reqType << std::endl; + return false; + }else + { + generateToken(token); + std::cerr << "RsGxsDataAccess::requestMsgInfo() gets Token: " << token << std::endl; + } + + setReq(req, token, ansType, opts); + storeRequest(req); return true; } +void RsGxsDataAccess::generateToken(uint32_t &token) +{ + RsStackMutex stack(mDataMutex); /****** LOCKED *****/ + + token = mNextToken++; + + return; +} + bool RsGxsDataAccess::requestMsgInfo(uint32_t &token, uint32_t ansType, - const RsTokReqOptions &opts, const std::list &groupIds) + const RsTokReqOptions &opts, const GxsMsgReq &msgIds) { - generateToken(token); - std::cerr << "RsGxsDataAccess::requestMsgInfo() gets Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGS, groupIds); - return true; -} + GxsRequest* req = NULL; + uint32_t reqType = opts.mReqType; -bool RsGxsDataAccess::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions& opts, - const GxsMsgReq &msgIds) -{ - generateToken(token); - std::cerr << "RsGxsDataAccess::requestMsgRelatedInfo() gets Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); + if(reqType & GXS_REQUEST_TYPE_MSG_META) + { + MsgMetaReq* mmr = new MsgMetaReq(); + mmr->mMsgIds = msgIds; + req = mmr; + }else if(reqType & GXS_REQUEST_TYPE_MSG_DATA) + { + MsgDataReq* mdr = new MsgDataReq(); + mdr->mMsgIds = msgIds; + req = mdr; + }else if(reqType & GXS_REQUEST_TYPE_MSG_IDS) + { + MsgIdReq* mir = new MsgIdReq(); + req = mir; + } + if(req == NULL) + { + std::cerr << "RsGxsDataAccess::requestMsgInfo() request type not recognised, type " + << reqType << std::endl; + return false; + }else + { + generateToken(token); + std::cerr << "RsGxsDataAccess::requestMsgInfo() gets Token: " << token << std::endl; + } + + setReq(req, token, ansType, opts); + storeRequest(req); return true; } @@ -39,28 +152,32 @@ bool RsGxsDataAccess::requestGroupSubscribe(uint32_t &token, uint32_t ansType, c { generateToken(token); + + GroupMetaReq* req = new GroupDataReq(); + req->mGroupIds.push_back(grpId); + std::cerr << "RsGxsDataAccess::requestGroupSubscribe() gets Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, grpId); + + setReq(req, token, ansType, opts); + storeRequest(req); return false; } -bool RsGxsDataAccess::storeRequest(const uint32_t &token, const uint32_t &ansType, const RsTokReqOptions &opts, const uint32_t &type, const std::list &ids) +void RsGxsDataAccess::setReq(GxsRequest* req, const uint32_t& token, const uint32_t& ansType, const RsTokReqOptions& opts) const +{ + req->token = token; + req->ansType = ansType; + req->Options = opts; + return; +} +void RsGxsDataAccess::storeRequest(GxsRequest* req) { RsStackMutex stack(mDataMutex); /****** LOCKED *****/ - GxsRequest* req; - req.token = token; - req.reqTime = time(NULL); - req.reqType = type; - req.ansType = ansType; - req.Options = opts; - req.status = GXS_REQUEST_STATUS_PENDING; - req.inList = ids; + mRequests[req->token] = req; - mRequests[token] = req; - - return true; + return; } uint32_t RsGxsDataAccess::requestStatus(uint32_t token) @@ -93,7 +210,8 @@ bool RsGxsDataAccess::clearRequest(const uint32_t& token) return false; } - mRequests.erase(it); + delete it->second; + mRequests.erase(it->first); return true; } @@ -250,31 +368,8 @@ bool RsGxsDataAccess::getGroupList(const uint32_t& token, std::list GxsRequest* RsGxsDataAccess::retrieveRequest(const uint32_t& token) { - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - if(checkRequestStatus(token, status, reqtype, anstype, ts)) - return NULL; - - if (anstype != RS_TOKREQ_ANSTYPE_SUMMARY) - { - std::cerr << "RsGxsDataAccess::retrieveRequest() ERROR AnsType Wrong" << std::endl; - return false; - } - - if (reqtype != GXS_REQUEST_TYPE_GROUPS) - { - std::cerr << "RsGxsDataAccess::retrieveRequest() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "RsGxsDataAccess::retrieveRequest() ERROR Status Incomplete" << std::endl; - return false; - } + RsStackMutex stack(mDataMutex); if(mRequests.find(token) == mRequests.end()) return NULL; @@ -386,10 +481,114 @@ void RsGxsDataAccess::processRequests() bool RsGxsDataAccess::getGroupData(GroupDataReq* req) { + std::map grpData; + mDataStore->retrieveNxsGrps(grpData, true); - std::map grpMeta; - mDataStore->retrieveGxsGrpMetaData(grpMeta); + std::map::iterator mit = grpData.begin(); + for(; mit != grpData.end(); mit++) + req->mGroupData.push_back(mit->second); return true; } +bool RsGxsDataAccess::getGroupSummary(GroupMetaReq* req) +{ + + std::map grpMeta; + + std::list::const_iterator lit = req->mGroupIds.begin(); + + for(; lit != req->mGroupIds.end(); lit++) + grpMeta[*lit] = NULL; + + mDataStore->retrieveGxsGrpMetaData(grpMeta); + + std::map::iterator mit = grpMeta.begin(); + + for(; mit != grpMeta.end(); mit++) + req->mGroupMetaData.push_back(mit->second); + + return true; +} + +bool RsGxsDataAccess::getGroupList(GroupIdReq* req) +{ + std::map grpMeta; + + std::list::const_iterator lit = req->mGroupIds.begin(); + + for(; lit != req->mGroupIds.end(); lit++) + grpMeta[*lit] = NULL; + + mDataStore->retrieveGxsGrpMetaData(grpMeta); + + std::map::iterator mit = grpMeta.begin(); + + for(; mit != grpMeta.end(); mit++) + { + req->mGroupIdResult.push_back(mit->first); + delete mit->second; // so wasteful!! + } + + return true; +} + +bool RsGxsDataAccess::getMsgData(MsgDataReq* req) +{ + + + GxsMsgResult result; + mDataStore->retrieveNxsMsgs(req->mMsgIds, result, true); + + req->mMsgData = result; + + return true; +} + + +bool RsGxsDataAccess::getMsgSummary(MsgMetaReq* req) +{ + GxsMsgMetaResult result; + std::vector groupIds; + GxsMsgReq::iterator mit = req->mMsgIds.begin(); + for(; mit != req->mMsgIds.end(); mit++) + groupIds.push_back(mit->first); + + mDataStore->retrieveGxsMsgMetaData(groupIds, result); + + req->mMsgMetaData = result; + + return true; +} + +bool RsGxsDataAccess::getMsgList(MsgIdReq* req) +{ + GxsMsgMetaResult result; + std::vector groupIds; + GxsMsgReq::iterator mit = req->mMsgIds.begin(); + + for(; mit != req->mMsgIds.end(); mit++) + groupIds.push_back(mit->first); + + mDataStore->retrieveGxsMsgMetaData(groupIds, result); + + GxsMsgMetaResult::iterator mit2 = result.begin(); + + for(; mit2 != result.end(); mit2++) + { + std::vector& msgIdV = mit2->second; + std::vector::iterator vit = mit2->second.begin(); + std::vector msgIds; + for(; vit != mit2->second.end(); vit++) + { + msgIds.push_back((*vit)->mMsgId); + delete *vit; + } + + req->mMsgIdResult.insert(std::pair >(mit2->first, msgIds)); + + } + + return true; +} diff --git a/libretroshare/src/gxs/rsgxsdataaccess.h b/libretroshare/src/gxs/rsgxsdataaccess.h index cc6532bfb..48f6a3ce8 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.h +++ b/libretroshare/src/gxs/rsgxsdataaccess.h @@ -5,11 +5,6 @@ #include "rsgds.h" -typedef std::map > GxsMsgReq; -typedef std::map > GxsMsgIdResult; -typedef std::map > GxsMsgMetaResult; -typedef std::map > GxsMsgDataResult; - class GxsRequest { @@ -28,6 +23,7 @@ class GroupMetaReq : public GxsRequest { public: + std::list mGroupIds; std::list mGroupMetaData; }; @@ -35,13 +31,25 @@ class GroupIdReq : public GxsRequest { public: + std::list mGroupIds; std::list mGroupIdResult; }; +class GroupDataReq : public GxsRequest +{ + +public: + std::list mGroupIds; + std::list mGroupData; +}; + + class MsgIdReq : public GxsRequest { public: + + GxsMsgReq mMsgIds; GxsMsgIdResult mMsgIdResult; }; @@ -49,22 +57,19 @@ class MsgMetaReq : public GxsRequest { public: - std::map > mMsgMetaData; + GxsMsgReq mMsgIds; + GxsMsgMetaResult mMsgMetaData; }; class MsgDataReq : public GxsRequest { public: + + GxsMsgReq mMsgIds; GxsMsgDataResult mMsgData; }; -class GroupDataReq : public GxsRequest -{ - -public: - std::list mGroupData; -}; class RsGxsDataAccess : public RsTokenService @@ -95,7 +100,7 @@ public: * @param groupIds * @return */ - bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds); + bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const GxsMsgReq&); /*! * More involved for request of particular information for msg @@ -171,20 +176,39 @@ private: /** helper functions to implement token service **/ - bool generateToken(uint32_t &token); + /*! + * Assigns a token value to passed integer + * @param token is assigned a unique token value + */ + void generateToken(uint32_t &token); GxsRequest* retrieveRequest(const uint32_t& token); - bool storeRequest(const uint32_t &token, const uint32_t &ansType, const RsTokReqOptions &opts, - const uint32_t &type, const std::list &ids); - bool storeRequest(const uint32_t &token, const uint32_t &ansType, const RsTokReqOptions &opts, - const uint32_t &type, const GxsMsgReq& msgIds); - bool storeRequest(const uint32_t &token, const uint32_t &ansType, const RsTokReqOptions &opts, - const uint32_t &type, const std::string& grpId); + /*! + * Add a gxs request to queue + * @param req gxs request to add + */ + void storeRequest(GxsRequest* req); + + /*! + * convenience function to setting members of request + * @param req + * @param token + * @param ansType + * @param opts + */ + void setReq(GxsRequest* req,const uint32_t &token, const uint32_t& ansType, const RsTokReqOptions &opts) const; + + /*! + * Remove request for request queue + * Request is deleted + * @param token the token associated to the request + * @return true if token successfully cleared, false if token does not exist + */ bool clearRequest(const uint32_t &token); + bool updateRequestStatus(const uint32_t &token, const uint32_t &status); - bool updateRequestInList(const uint32_t &token, std::list ids); - bool updateRequestOutList(const uint32_t &token, std::list ids); + bool checkRequestStatus(const uint32_t &token, uint32_t &status, uint32_t &reqtype, uint32_t &anstype, time_t &ts); // special ones for testing (not in final design) diff --git a/libretroshare/src/gxs/rstokenservice.h b/libretroshare/src/gxs/rstokenservice.h index 5b7a6ce87..fc4df7648 100644 --- a/libretroshare/src/gxs/rstokenservice.h +++ b/libretroshare/src/gxs/rstokenservice.h @@ -2,7 +2,7 @@ #define RSTOKENSERVICE_H /* - * libretroshare/src/retroshare: rsidentity.h + * libretroshare/src/retroshare: rstokenservice.h * * RetroShare C++ Interface. * @@ -32,6 +32,10 @@ #include "serialiser/rsgxsitems.h" +typedef std::map > GxsMsgReq; +typedef std::map > GxsMsgIdResult; +typedef std::map > GxsMsgMetaResult; +typedef std::map > GxsMsgDataResult; #define GXS_REQUEST_STATUS_FAILED 0 #define GXS_REQUEST_STATUS_PENDING 1 @@ -40,14 +44,16 @@ #define GXS_REQUEST_STATUS_COMPLETE 4 #define GXS_REQUEST_STATUS_DONE 5 // ONCE ALL DATA RETRIEVED. -#define GXS_REQUEST_TYPE_GROUPS 0x00010000 -#define GXS_REQUEST_TYPE_MSGS 0x00020000 -#define GXS_REQUEST_TYPE_MSGRELATED 0x00040000 +#define GXS_REQUEST_TYPE_GROUP_DATA 0x00010000 +#define GXS_REQUEST_TYPE_GROUP_META 0x00020000 +#define GXS_REQUEST_TYPE_GROUP_IDS 0x00040000 +#define GXS_REQUEST_TYPE_MSG_DATA 0x00080000 +#define GXS_REQUEST_TYPE_MSG_META 0x00100000 +#define GXS_REQUEST_TYPE_MSG_IDS 0x00200000 /*! * This class provides useful generic support for GXS style services. * I expect much of this will be incorporated into the base GXS. - * */ class RsTokReqOptions { @@ -55,6 +61,7 @@ public: RsTokReqOptions() { mOptions = 0; mBefore = 0; mAfter = 0; } uint32_t mOptions; + uint32_t mReqType; time_t mBefore; time_t mAfter; }; @@ -94,16 +101,6 @@ public: */ virtual bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) = 0; - /*! - * - * @param token - * @param ansType - * @param opts - * @param msgIds - * @return - */ - virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &msgIds) = 0; - /*! * * @param token