mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
seperated content value from retrodb
added local meta changing fucntionality to gxs also added msgrelated info id retrieval to tokeservice git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5452 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
8a7c011c5d
commit
6dd18eea46
@ -120,6 +120,14 @@
|
||||
|
||||
#define RS_DATA_SERVICE_DEBUG
|
||||
|
||||
const std::string RsGeneralDataService::GRP_META_SERV_STRING = KEY_NXS_SERV_STRING;
|
||||
const std::string RsGeneralDataService::GRP_META_STATUS = KEY_GRP_STATUS;
|
||||
const std::string RsGeneralDataService::GRP_META_SUBSCRIBE_FLAG = KEY_GRP_SUBCR_FLAG;
|
||||
|
||||
const std::string RsGeneralDataService::MSG_META_SERV_STRING = KEY_NXS_SERV_STRING;
|
||||
const std::string RsGeneralDataService::MSG_META_STATUS = KEY_MSG_STATUS;
|
||||
|
||||
|
||||
RsDataService::RsDataService(const std::string &serviceDir, const std::string &dbName, uint16_t serviceType,
|
||||
RsGxsSearchModule *mod)
|
||||
: RsGeneralDataService(), mServiceDir(serviceDir), mDbName(mServiceDir + "/" + dbName), mServType(serviceType){
|
||||
@ -910,12 +918,16 @@ int RsDataService::removeGroups(const std::vector<std::string> &grpIds)
|
||||
|
||||
int RsDataService::updateGroupMetaData(GrpLocMetaData &meta)
|
||||
{
|
||||
return 0;
|
||||
RsGxsGroupId& grpId = meta.grpId;
|
||||
return mDb->sqlUpdate(GRP_TABLE_NAME, KEY_GRP_ID+ "='" + grpId + "'", meta.val) ? 1 : 0;
|
||||
}
|
||||
|
||||
int RsDataService::updateMessageMetaData(MsgLocMetaData &metaData)
|
||||
{
|
||||
return 0;
|
||||
RsGxsGroupId& grpId = metaData.msgId.first;
|
||||
RsGxsMessageId& msgId = metaData.msgId.second;
|
||||
return mDb->sqlUpdate(MSG_TABLE_NAME, KEY_GRP_ID+ "='" + grpId
|
||||
+ "' AND " + KEY_MSG_ID + "='" + msgId + "'", metaData.val) ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -55,6 +55,8 @@ public:
|
||||
class MsgLocMetaData {
|
||||
|
||||
public:
|
||||
MsgLocMetaData(const MsgLocMetaData& meta){ msgId = meta.msgId; val = meta.val;}
|
||||
MsgLocMetaData() {}
|
||||
RsGxsGrpMsgIdPair msgId;
|
||||
ContentValue val;
|
||||
};
|
||||
@ -66,6 +68,8 @@ public:
|
||||
class GrpLocMetaData {
|
||||
|
||||
public:
|
||||
GrpLocMetaData(const GrpLocMetaData& meta){ grpId = meta.grpId; val = meta.val;}
|
||||
GrpLocMetaData(){}
|
||||
RsGxsGroupId grpId;
|
||||
ContentValue val;
|
||||
|
||||
@ -98,6 +102,16 @@ typedef std::map<RsGxsGroupId, std::vector<RsNxsMsg*> > GxsMsgResult; // <grpId,
|
||||
class RsGeneralDataService
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
|
||||
static const std::string MSG_META_SERV_STRING;
|
||||
static const std::string MSG_META_STATUS;
|
||||
|
||||
static const std::string GRP_META_SUBSCRIBE_FLAG;
|
||||
static const std::string GRP_META_STATUS;
|
||||
static const std::string GRP_META_SERV_STRING;
|
||||
|
||||
public:
|
||||
|
||||
RsGeneralDataService(){}
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#include "rsgenexchange.h"
|
||||
#include "gxssecurity.h"
|
||||
#include "util/contentvalue.h"
|
||||
|
||||
RsGenExchange::RsGenExchange(RsGeneralDataService *gds,
|
||||
RsNetworkExchangeService *ns, RsSerialType *serviceSerialiser, uint16_t servType)
|
||||
@ -63,26 +64,33 @@ void RsGenExchange::tick()
|
||||
|
||||
publishMsgs();
|
||||
|
||||
processGrpMetaChanges();
|
||||
|
||||
processMsgMetaChanges();
|
||||
|
||||
notifyChanges(mNotifications);
|
||||
mNotifications.clear();
|
||||
|
||||
}
|
||||
|
||||
bool RsGenExchange::acknowledgeTokenMsg(const uint32_t& token,
|
||||
std::pair<RsGxsGroupId, RsGxsMessageId>& msgId)
|
||||
RsGxsGrpMsgIdPair& msgId)
|
||||
{
|
||||
RsStackMutex stack(mGenMtx);
|
||||
|
||||
std::map<uint32_t, std::pair<RsGxsGroupId, RsGxsMessageId> >::iterator mit =
|
||||
mMsgPublished.find(token);
|
||||
std::map<uint32_t, RsGxsGrpMsgIdPair >::iterator mit =
|
||||
mMsgNotify.find(token);
|
||||
|
||||
if(mit == mMsgPublished.end())
|
||||
return false;
|
||||
if(mit == mMsgNotify.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
msgId = mit->second;
|
||||
|
||||
// no dump token as client has ackowledged its completion
|
||||
mDataAccess->disposeOfPublicToken(token);
|
||||
msgId = mit->second;
|
||||
|
||||
// no dump token as client has ackowledged its completion
|
||||
mDataAccess->disposeOfPublicToken(token);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -95,9 +103,9 @@ bool RsGenExchange::acknowledgeTokenGrp(const uint32_t& token,
|
||||
RsStackMutex stack(mGenMtx);
|
||||
|
||||
std::map<uint32_t, RsGxsGroupId >::iterator mit =
|
||||
mGrpPublished.find(token);
|
||||
mGrpNotify.find(token);
|
||||
|
||||
if(mit == mGrpPublished.end())
|
||||
if(mit == mGrpNotify.end())
|
||||
return false;
|
||||
|
||||
grpId = mit->second;
|
||||
@ -395,28 +403,131 @@ void RsGenExchange::notifyNewMessages(std::vector<RsNxsMsg *>& messages)
|
||||
}
|
||||
|
||||
|
||||
bool RsGenExchange::publishGroup(uint32_t& token, RsGxsGrpItem *grpItem)
|
||||
void RsGenExchange::publishGroup(uint32_t& token, RsGxsGrpItem *grpItem)
|
||||
{
|
||||
|
||||
RsStackMutex stack(mGenMtx);
|
||||
|
||||
token = mDataAccess->generatePublicToken();
|
||||
mGrpsToPublish.insert(std::make_pair(token, grpItem));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RsGenExchange::publishMsg(uint32_t& token, RsGxsMsgItem *msgItem)
|
||||
void RsGenExchange::publishMsg(uint32_t& token, RsGxsMsgItem *msgItem)
|
||||
{
|
||||
RsStackMutex stack(mGenMtx);
|
||||
|
||||
token = mDataAccess->generatePublicToken();
|
||||
mMsgsToPublish.insert(std::make_pair(token, msgItem));
|
||||
}
|
||||
|
||||
void RsGenExchange::setGroupSubscribeFlag(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& flag)
|
||||
{
|
||||
RsStackMutex stack(mGenMtx);
|
||||
token = mDataAccess->generatePublicToken();
|
||||
|
||||
GrpLocMetaData g;
|
||||
g.grpId = grpId;
|
||||
g.val.put(RsGeneralDataService::GRP_META_SUBSCRIBE_FLAG, (int32_t)flag);
|
||||
mGrpLocMetaMap.insert(std::make_pair(token, g));
|
||||
}
|
||||
|
||||
void RsGenExchange::setGroupStatusFlag(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status)
|
||||
{
|
||||
RsStackMutex stack(mGenMtx);
|
||||
token = mDataAccess->generatePublicToken();
|
||||
|
||||
GrpLocMetaData g;
|
||||
g.grpId = grpId;
|
||||
g.val.put(RsGeneralDataService::GRP_META_STATUS, (int32_t)status);
|
||||
mGrpLocMetaMap.insert(std::make_pair(token, g));
|
||||
}
|
||||
|
||||
|
||||
void RsGenExchange::setGroupServiceString(uint32_t& token, const RsGxsGroupId& grpId, const std::string& servString)
|
||||
{
|
||||
RsStackMutex stack(mGenMtx);
|
||||
token = mDataAccess->generatePublicToken();
|
||||
|
||||
GrpLocMetaData g;
|
||||
g.grpId = grpId;
|
||||
g.val.put(RsGeneralDataService::GRP_META_SERV_STRING, servString);
|
||||
mGrpLocMetaMap.insert(std::make_pair(token, g));
|
||||
}
|
||||
|
||||
void RsGenExchange::setMsgStatusFlag(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const uint32_t& status)
|
||||
{
|
||||
RsStackMutex stack(mGenMtx);
|
||||
token = mDataAccess->generatePublicToken();
|
||||
|
||||
MsgLocMetaData m;
|
||||
m.val.put(RsGeneralDataService::MSG_META_STATUS, (int32_t)status);
|
||||
m.msgId = msgId;
|
||||
mMsgLocMetaMap.insert(std::make_pair(token, m));
|
||||
}
|
||||
|
||||
void RsGenExchange::setMsgServiceString(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const std::string& servString )
|
||||
{
|
||||
RsStackMutex stack(mGenMtx);
|
||||
token = mDataAccess->generatePublicToken();
|
||||
|
||||
MsgLocMetaData m;
|
||||
m.val.put(RsGeneralDataService::MSG_META_SERV_STRING, servString);
|
||||
m.msgId = msgId;
|
||||
mMsgLocMetaMap.insert(std::make_pair(token, m));
|
||||
}
|
||||
|
||||
void RsGenExchange::processMsgMetaChanges()
|
||||
{
|
||||
|
||||
RsStackMutex stack(mGenMtx);
|
||||
RsStackMutex stack(mGenMtx);
|
||||
|
||||
token = mDataAccess->generatePublicToken();
|
||||
mMsgsToPublish.insert(std::make_pair(token, msgItem));
|
||||
std::map<uint32_t, MsgLocMetaData>::iterator mit = mMsgLocMetaMap.begin(),
|
||||
mit_end = mMsgLocMetaMap.end();
|
||||
|
||||
return true;
|
||||
for(; mit != mit_end; mit++)
|
||||
{
|
||||
MsgLocMetaData& m = mit->second;
|
||||
bool ok = mDataStore->updateMessageMetaData(m) == 1;
|
||||
uint32_t token = mit->first;
|
||||
|
||||
if(ok)
|
||||
{
|
||||
mDataAccess->updatePublicRequestStatus(token, RsTokenServiceV2::GXS_REQUEST_STATUS_COMPLETE);
|
||||
}else
|
||||
{
|
||||
mDataAccess->updatePublicRequestStatus(token, RsTokenServiceV2::GXS_REQUEST_STATUS_FAILED);
|
||||
}
|
||||
mMsgNotify.insert(std::make_pair(token, m.msgId));
|
||||
}
|
||||
|
||||
mMsgLocMetaMap.clear();
|
||||
}
|
||||
|
||||
void RsGenExchange::processGrpMetaChanges()
|
||||
{
|
||||
RsStackMutex stack(mGenMtx);
|
||||
|
||||
std::map<uint32_t, GrpLocMetaData>::iterator mit = mGrpLocMetaMap.begin(),
|
||||
mit_end = mGrpLocMetaMap.end();
|
||||
|
||||
for(; mit != mit_end; mit++)
|
||||
{
|
||||
GrpLocMetaData& g = mit->second;
|
||||
uint32_t token = mit->first;
|
||||
bool ok = mDataStore->updateGroupMetaData(g) == 1;
|
||||
|
||||
if(ok)
|
||||
{
|
||||
mDataAccess->updatePublicRequestStatus(token, RsTokenServiceV2::GXS_REQUEST_STATUS_COMPLETE);
|
||||
}else
|
||||
{
|
||||
mDataAccess->updatePublicRequestStatus(token, RsTokenServiceV2::GXS_REQUEST_STATUS_FAILED);
|
||||
}
|
||||
mGrpNotify.insert(std::make_pair(token, g.grpId));
|
||||
}
|
||||
|
||||
mGrpLocMetaMap.clear();
|
||||
}
|
||||
|
||||
void RsGenExchange::publishMsgs()
|
||||
{
|
||||
@ -453,7 +564,7 @@ void RsGenExchange::publishMsgs()
|
||||
ok = mDataAccess->addMsgData(msg);
|
||||
|
||||
// add to published to allow acknowledgement
|
||||
mMsgPublished.insert(std::make_pair(mit->first, std::make_pair(msg->grpId, msg->msgId)));
|
||||
mMsgNotify.insert(std::make_pair(mit->first, std::make_pair(msg->grpId, msg->msgId)));
|
||||
mDataAccess->updatePublicRequestStatus(mit->first, RsTokenServiceV2::GXS_REQUEST_STATUS_COMPLETE);
|
||||
}
|
||||
|
||||
@ -463,7 +574,7 @@ void RsGenExchange::publishMsgs()
|
||||
#ifdef GEN_EXCH_DEBUG
|
||||
std::cerr << "RsGenExchange::publishMsgs() failed to publish msg " << std::endl;
|
||||
#endif
|
||||
mMsgPublished.insert(std::make_pair(mit->first, std::make_pair(RsGxsGroupId(""), RsGxsMessageId(""))));
|
||||
mMsgNotify.insert(std::make_pair(mit->first, std::make_pair(RsGxsGroupId(""), RsGxsMessageId(""))));
|
||||
delete msg;
|
||||
continue;
|
||||
|
||||
@ -509,7 +620,7 @@ void RsGenExchange::publishGrps()
|
||||
ok = mDataAccess->addGroupData(grp);
|
||||
|
||||
// add to published to allow acknowledgement
|
||||
mGrpPublished.insert(std::make_pair(mit->first, grp->grpId));
|
||||
mGrpNotify.insert(std::make_pair(mit->first, grp->grpId));
|
||||
mDataAccess->updatePublicRequestStatus(mit->first, RsTokenServiceV2::GXS_REQUEST_STATUS_COMPLETE);
|
||||
}
|
||||
|
||||
@ -522,7 +633,7 @@ void RsGenExchange::publishGrps()
|
||||
delete grp;
|
||||
|
||||
// add to published to allow acknowledgement, grpid is empty as grp creation failed
|
||||
mGrpPublished.insert(std::make_pair(mit->first, RsGxsGroupId("")));
|
||||
mGrpNotify.insert(std::make_pair(mit->first, RsGxsGroupId("")));
|
||||
mDataAccess->updatePublicRequestStatus(mit->first, RsTokenServiceV2::GXS_REQUEST_STATUS_FAILED);
|
||||
continue;
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ public:
|
||||
* @param msgIds map of grpid->msgIds of message created/modified
|
||||
* @return true if token exists false otherwise
|
||||
*/
|
||||
bool acknowledgeTokenMsg(const uint32_t& token, std::pair<RsGxsGroupId, RsGxsMessageId>& msgId);
|
||||
bool acknowledgeTokenMsg(const uint32_t& token, RsGxsGrpMsgIdPair& msgId);
|
||||
|
||||
/*!
|
||||
* This allows the client service to acknowledge that their grps has
|
||||
@ -184,7 +184,7 @@ protected:
|
||||
* @param token
|
||||
* @param grpItem
|
||||
*/
|
||||
bool publishGroup(uint32_t& token, RsGxsGrpItem* grpItem);
|
||||
void publishGroup(uint32_t& token, RsGxsGrpItem* grpItem);
|
||||
|
||||
/*!
|
||||
* Enables publication of a message item
|
||||
@ -194,7 +194,23 @@ protected:
|
||||
* @param token
|
||||
* @param msgItem
|
||||
*/
|
||||
bool publishMsg(uint32_t& token, RsGxsMsgItem* msgItem);
|
||||
void publishMsg(uint32_t& token, RsGxsMsgItem* msgItem);
|
||||
|
||||
/*!
|
||||
* sets the group subscribe flag
|
||||
* @param token this is set to token value associated to this request
|
||||
* @param
|
||||
*/
|
||||
void setGroupSubscribeFlag(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status);
|
||||
|
||||
void setGroupStatusFlag(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status);
|
||||
|
||||
void setGroupServiceString(uint32_t& token, const RsGxsGroupId& grpId, const std::string& servString);
|
||||
|
||||
void setMsgStatusFlag(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const uint32_t& status);
|
||||
|
||||
void setMsgServiceString(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const std::string& servString );
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
@ -227,6 +243,16 @@ private:
|
||||
|
||||
void publishMsgs();
|
||||
|
||||
/*!
|
||||
* processes msg local meta changes
|
||||
*/
|
||||
void processMsgMetaChanges();
|
||||
|
||||
/*!
|
||||
* Processes group local meta changes
|
||||
*/
|
||||
void processGrpMetaChanges();
|
||||
|
||||
void createGroup(RsNxsGrp* grp);
|
||||
bool createMessage(RsNxsMsg* msg);
|
||||
|
||||
@ -244,8 +270,12 @@ private:
|
||||
std::map<uint32_t, RsGxsGrpItem*> mGrpsToPublish;
|
||||
std::map<uint32_t, RsGxsMsgItem*> mMsgsToPublish;
|
||||
|
||||
std::map<uint32_t, std::pair<RsGxsGroupId, RsGxsMessageId> > mMsgPublished;
|
||||
std::map<uint32_t, RsGxsGroupId> mGrpPublished;
|
||||
std::map<uint32_t, RsGxsGrpMsgIdPair > mMsgNotify;
|
||||
std::map<uint32_t, RsGxsGroupId> mGrpNotify;
|
||||
|
||||
// for loc meta changes
|
||||
std::map<uint32_t, GrpLocMetaData > mGrpLocMetaMap;
|
||||
std::map<uint32_t, MsgLocMetaData> mMsgLocMetaMap;
|
||||
|
||||
std::vector<RsGxsNotify*> mNotifications;
|
||||
|
||||
|
@ -153,58 +153,22 @@ bool RsGxsDataAccess::requestMsgInfo(uint32_t &token, uint32_t ansType,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RsGxsDataAccess::requestSetGroupSubscribeFlags(uint32_t& token, const RsGxsGroupId &grpId, uint32_t subscribeFlags,
|
||||
uint32_t subscribeMask)
|
||||
|
||||
bool RsGxsDataAccess::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const GxsMsgReq& msgIds)
|
||||
{
|
||||
|
||||
generateToken(token);
|
||||
MsgRelatedInfoReq* req = new MsgRelatedInfoReq();
|
||||
req->mMsgIds = msgIds;
|
||||
|
||||
GroupSetFlagReq* req = new GroupSetFlagReq();
|
||||
generateToken(token);
|
||||
|
||||
req->flag = subscribeFlags;
|
||||
req->flagMask = subscribeMask;
|
||||
req->grpId = grpId;
|
||||
setReq(req, token, ansType, opts);
|
||||
storeRequest(req);
|
||||
|
||||
std::cerr << "RsGxsDataAccess::requestSetGroupSubscribeFlags() gets Token: " << token << std::endl;
|
||||
storeRequest(req);
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RsGxsDataAccess::requestSetGroupStatus(uint32_t& token, const RsGxsGroupId& grpId, uint32_t status, uint32_t statusMask)
|
||||
{
|
||||
|
||||
generateToken(token);
|
||||
|
||||
GroupSetFlagReq* req = new GroupSetFlagReq();
|
||||
|
||||
req->flag = status;
|
||||
req->flagMask = statusMask;
|
||||
req->grpId = grpId;
|
||||
|
||||
std::cerr << "RsGxsDataAccess::requestSetGroupStatus() gets Token: " << token << std::endl;
|
||||
storeRequest(req);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RsGxsDataAccess::requestSetMessageStatus(uint32_t& token, const RsGxsGrpMsgIdPair &msgId, uint32_t status,
|
||||
uint32_t statusMask)
|
||||
{
|
||||
|
||||
generateToken(token);
|
||||
|
||||
MessageSetFlagReq* req = new MessageSetFlagReq();
|
||||
|
||||
req->flag = status;
|
||||
req->flagMask = statusMask;
|
||||
req->msgId = msgId;
|
||||
|
||||
std::cerr << "RsGxsDataAccess::requestSetGroupStatus() gets Token: " << token << std::endl;
|
||||
storeRequest(req);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RsGxsDataAccess::setReq(GxsRequest* req, const uint32_t& token, const uint32_t& ansType, const RsTokReqOptionsV2& opts) const
|
||||
{
|
||||
@ -424,6 +388,37 @@ bool RsGxsDataAccess::getMsgList(const uint32_t& token, GxsMsgIdResult& msgIds)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RsGxsDataAccess::getMsgRelatedInfo(const uint32_t &token, GxsMsgIdResult &msgIds)
|
||||
{
|
||||
RsStackMutex stack(mDataMutex);
|
||||
|
||||
GxsRequest* req = locked_retrieveRequest(token);
|
||||
|
||||
if(req == NULL){
|
||||
|
||||
std::cerr << "RsGxsDataAccess::getMsgRelatedInfo() Unable to retrieve group data" << std::endl;
|
||||
return false;
|
||||
}else if(req->status == GXS_REQUEST_STATUS_COMPLETE){
|
||||
|
||||
MsgRelatedInfoReq* mrireq = dynamic_cast<MsgRelatedInfoReq*>(req);
|
||||
|
||||
if(mrireq)
|
||||
{
|
||||
msgIds = mrireq->mMsgIdResult;
|
||||
locked_updateRequestStatus(token, GXS_REQUEST_STATUS_DONE);
|
||||
|
||||
}else{
|
||||
std::cerr << "RsGxsDataAccess::::getMsgRelatedInfo() Req found, failed caste" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
std::cerr << "RsGxsDataAccess::::getMsgRelatedInfo() Req not ready" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RsGxsDataAccess::getGroupList(const uint32_t& token, std::list<RsGxsGroupId>& groupIds)
|
||||
{
|
||||
RsStackMutex stack(mDataMutex);
|
||||
@ -488,6 +483,7 @@ void RsGxsDataAccess::processRequests()
|
||||
MsgMetaReq* mmr;
|
||||
MsgDataReq* mdr;
|
||||
MsgIdReq* mir;
|
||||
MsgRelatedInfoReq* mri;
|
||||
|
||||
for(it = mRequests.begin(); it != mRequests.end(); it++)
|
||||
{
|
||||
@ -527,6 +523,10 @@ void RsGxsDataAccess::processRequests()
|
||||
{
|
||||
getMsgList(mir);
|
||||
}
|
||||
else if((mri = dynamic_cast<MsgRelatedInfoReq*>(req)) != NULL)
|
||||
{
|
||||
getMsgRelatedInfo(mri);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef GXSDATA_SERVE_DEBUG
|
||||
@ -569,7 +569,6 @@ void RsGxsDataAccess::processRequests()
|
||||
|
||||
bool RsGxsDataAccess::getGroupData(GroupDataReq* req)
|
||||
{
|
||||
|
||||
std::map<RsGxsGroupId, RsNxsGrp*> grpData;
|
||||
|
||||
std::list<RsGxsGroupId>::iterator lit = req->mGroupIds.begin(),
|
||||
@ -650,170 +649,200 @@ bool RsGxsDataAccess::getMsgSummary(MsgMetaReq* req)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool RsGxsDataAccess::getMsgRelatedInfo(MsgRelatedInfoReq* req)
|
||||
{
|
||||
GxsMsgMetaResult result;
|
||||
|
||||
const RsTokReqOptionsV2& opts = req->Options;
|
||||
|
||||
{
|
||||
RsStackMutex stack(mDataMutex);
|
||||
mDataStore->retrieveGxsMsgMetaData(req->mMsgIds, result);
|
||||
}
|
||||
|
||||
|
||||
/* CASEs this handles.
|
||||
* Input is groupList + Flags.
|
||||
* 1) No Flags => All Messages in those Groups.
|
||||
*
|
||||
*/
|
||||
std::cerr << "RsGxsDataAccess::getMsgList()";
|
||||
std::cerr << std::endl;
|
||||
|
||||
|
||||
bool onlyOrigMsgs = false;
|
||||
bool onlyLatestMsgs = false;
|
||||
bool onlyThreadHeadMsgs = false;
|
||||
|
||||
// Can only choose one of these two.
|
||||
if (opts.mOptions & RS_TOKREQOPT_MSG_ORIGMSG)
|
||||
{
|
||||
std::cerr << "RsGxsDataAccess::getMsgList() MSG_ORIGMSG";
|
||||
std::cerr << std::endl;
|
||||
onlyOrigMsgs = true;
|
||||
}
|
||||
else if (opts.mOptions & RS_TOKREQOPT_MSG_LATEST)
|
||||
{
|
||||
std::cerr << "RsGxsDataAccess::getMsgList() MSG_LATEST";
|
||||
std::cerr << std::endl;
|
||||
onlyLatestMsgs = true;
|
||||
}
|
||||
|
||||
if (opts.mOptions & RS_TOKREQOPT_MSG_THREAD)
|
||||
{
|
||||
std::cerr << "RsGxsDataAccess::getMsgList() MSG_THREAD";
|
||||
std::cerr << std::endl;
|
||||
onlyThreadHeadMsgs = true;
|
||||
}
|
||||
|
||||
GxsMsgMetaResult::iterator meta_it;
|
||||
MsgMetaFilter metaFilter;
|
||||
|
||||
for(meta_it = result.begin(); meta_it != result.end(); meta_it++)
|
||||
{
|
||||
const RsGxsGroupId& grpId = meta_it->first;
|
||||
|
||||
metaFilter[grpId] = std::map<RsGxsMessageId, RsGxsMsgMetaData*>();
|
||||
|
||||
const std::vector<RsGxsMsgMetaData*>& metaV = meta_it->second;
|
||||
if (onlyLatestMsgs) // THIS ONE IS HARD -> LOTS OF COMP.
|
||||
{
|
||||
std::vector<RsGxsMsgMetaData*>::const_iterator vit = metaV.begin();
|
||||
|
||||
|
||||
// RUN THROUGH ALL MSGS... in map origId -> TS.
|
||||
std::map<RsGxsGroupId, std::pair<RsGxsMessageId, time_t> > origMsgTs;
|
||||
std::map<RsGxsGroupId, std::pair<RsGxsMessageId, time_t> >::iterator oit;
|
||||
|
||||
for(; vit != metaV.end(); vit++)
|
||||
{
|
||||
RsGxsMsgMetaData* msgMeta = *vit;
|
||||
|
||||
/* if we are grabbing thread Head... then parentId == empty. */
|
||||
if (onlyThreadHeadMsgs)
|
||||
{
|
||||
if (!(msgMeta->mParentId.empty()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
oit = origMsgTs.find(msgMeta->mOrigMsgId);
|
||||
bool addMsg = false;
|
||||
if (oit == origMsgTs.end())
|
||||
{
|
||||
std::cerr << "RsGxsDataAccess::getMsgList() Found New OrigMsgId: ";
|
||||
std::cerr << msgMeta->mOrigMsgId;
|
||||
std::cerr << " MsgId: " << msgMeta->mMsgId;
|
||||
std::cerr << " TS: " << msgMeta->mPublishTs;
|
||||
std::cerr << std::endl;
|
||||
|
||||
addMsg = true;
|
||||
}
|
||||
// check timestamps.
|
||||
else if (oit->second.second < msgMeta->mPublishTs)
|
||||
{
|
||||
std::cerr << "RsGxsDataAccess::getMsgList() Found Later Msg. OrigMsgId: ";
|
||||
std::cerr << msgMeta->mOrigMsgId;
|
||||
std::cerr << " MsgId: " << msgMeta->mMsgId;
|
||||
std::cerr << " TS: " << msgMeta->mPublishTs;
|
||||
|
||||
addMsg = true;
|
||||
}
|
||||
|
||||
if (addMsg)
|
||||
{
|
||||
// add as latest. (overwriting if necessary)
|
||||
origMsgTs[msgMeta->mOrigMsgId] = std::make_pair(msgMeta->mMsgId, msgMeta->mPublishTs);
|
||||
metaFilter[grpId].insert(std::make_pair(msgMeta->mMsgId, msgMeta));
|
||||
}
|
||||
}
|
||||
|
||||
// Add the discovered Latest Msgs.
|
||||
for(oit = origMsgTs.begin(); oit != origMsgTs.end(); oit++)
|
||||
{
|
||||
req->mMsgIdResult[grpId].push_back(oit->second.first);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else // ALL OTHER CASES.
|
||||
{
|
||||
std::vector<RsGxsMsgMetaData*>::const_iterator vit = metaV.begin();
|
||||
|
||||
for(; vit != metaV.end(); vit++)
|
||||
{
|
||||
RsGxsMsgMetaData* msgMeta = *vit;
|
||||
bool add = false;
|
||||
|
||||
/* if we are grabbing thread Head... then parentId == empty. */
|
||||
if (onlyThreadHeadMsgs)
|
||||
{
|
||||
if (!(msgMeta->mParentId.empty()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (onlyOrigMsgs)
|
||||
{
|
||||
if (msgMeta->mMsgId == msgMeta->mOrigMsgId)
|
||||
{
|
||||
add = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
add = true;
|
||||
}
|
||||
|
||||
if (add)
|
||||
{
|
||||
req->mMsgIdResult[grpId].push_back(msgMeta->mMsgId);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
filterMsgList(req->mMsgIdResult, opts, metaFilter);
|
||||
|
||||
// delete the data
|
||||
cleanseMetaFilter(metaFilter);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RsGxsDataAccess::getMsgList(MsgIdReq* req)
|
||||
{
|
||||
GxsMsgMetaResult result;
|
||||
|
||||
const RsTokReqOptionsV2& opts = req->Options;
|
||||
GxsMsgMetaResult result;
|
||||
|
||||
{
|
||||
RsStackMutex stack(mDataMutex);
|
||||
mDataStore->retrieveGxsMsgMetaData(req->mMsgIds, result);
|
||||
}
|
||||
{
|
||||
RsStackMutex stack(mDataMutex);
|
||||
mDataStore->retrieveGxsMsgMetaData(req->mMsgIds, result);
|
||||
}
|
||||
|
||||
GxsMsgMetaResult::iterator mit = result.begin(), mit_end = result.end();
|
||||
|
||||
/* CASEs this handles.
|
||||
* Input is groupList + Flags.
|
||||
* 1) No Flags => All Messages in those Groups.
|
||||
*
|
||||
*/
|
||||
std::cerr << "RsGxsDataAccess::getMsgList()";
|
||||
std::cerr << std::endl;
|
||||
for(; mit != mit_end; mit++)
|
||||
{
|
||||
const RsGxsGroupId grpId = mit->first;
|
||||
std::vector<RsGxsMsgMetaData*>& metaV = mit->second;
|
||||
std::vector<RsGxsMsgMetaData*>::iterator vit = metaV.begin(),
|
||||
vit_end = metaV.end();
|
||||
|
||||
|
||||
bool onlyOrigMsgs = false;
|
||||
bool onlyLatestMsgs = false;
|
||||
bool onlyThreadHeadMsgs = false;
|
||||
|
||||
// Can only choose one of these two.
|
||||
if (opts.mOptions & RS_TOKREQOPT_MSG_ORIGMSG)
|
||||
{
|
||||
std::cerr << "RsGxsDataAccess::getMsgList() MSG_ORIGMSG";
|
||||
std::cerr << std::endl;
|
||||
onlyOrigMsgs = true;
|
||||
}
|
||||
else if (opts.mOptions & RS_TOKREQOPT_MSG_LATEST)
|
||||
{
|
||||
std::cerr << "RsGxsDataAccess::getMsgList() MSG_LATEST";
|
||||
std::cerr << std::endl;
|
||||
onlyLatestMsgs = true;
|
||||
}
|
||||
|
||||
if (opts.mOptions & RS_TOKREQOPT_MSG_THREAD)
|
||||
{
|
||||
std::cerr << "RsGxsDataAccess::getMsgList() MSG_THREAD";
|
||||
std::cerr << std::endl;
|
||||
onlyThreadHeadMsgs = true;
|
||||
}
|
||||
|
||||
GxsMsgMetaResult::iterator meta_it;
|
||||
MsgMetaFilter metaFilter;
|
||||
|
||||
for(meta_it = result.begin(); meta_it != result.end(); meta_it++)
|
||||
{
|
||||
const RsGxsGroupId& grpId = meta_it->first;
|
||||
|
||||
metaFilter[grpId] = std::map<RsGxsMessageId, RsGxsMsgMetaData*>();
|
||||
|
||||
const std::vector<RsGxsMsgMetaData*>& metaV = meta_it->second;
|
||||
if (onlyLatestMsgs) // THIS ONE IS HARD -> LOTS OF COMP.
|
||||
{
|
||||
std::vector<RsGxsMsgMetaData*>::const_iterator vit = metaV.begin();
|
||||
|
||||
|
||||
// RUN THROUGH ALL MSGS... in map origId -> TS.
|
||||
std::map<RsGxsGroupId, std::pair<RsGxsMessageId, time_t> > origMsgTs;
|
||||
std::map<RsGxsGroupId, std::pair<RsGxsMessageId, time_t> >::iterator oit;
|
||||
|
||||
for(; vit != metaV.end(); vit++)
|
||||
{
|
||||
RsGxsMsgMetaData* msgMeta = *vit;
|
||||
|
||||
/* if we are grabbing thread Head... then parentId == empty. */
|
||||
if (onlyThreadHeadMsgs)
|
||||
{
|
||||
if (!(msgMeta->mParentId.empty()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
oit = origMsgTs.find(msgMeta->mOrigMsgId);
|
||||
bool addMsg = false;
|
||||
if (oit == origMsgTs.end())
|
||||
{
|
||||
std::cerr << "RsGxsDataAccess::getMsgList() Found New OrigMsgId: ";
|
||||
std::cerr << msgMeta->mOrigMsgId;
|
||||
std::cerr << " MsgId: " << msgMeta->mMsgId;
|
||||
std::cerr << " TS: " << msgMeta->mPublishTs;
|
||||
std::cerr << std::endl;
|
||||
|
||||
addMsg = true;
|
||||
}
|
||||
// check timestamps.
|
||||
else if (oit->second.second < msgMeta->mPublishTs)
|
||||
{
|
||||
std::cerr << "RsGxsDataAccess::getMsgList() Found Later Msg. OrigMsgId: ";
|
||||
std::cerr << msgMeta->mOrigMsgId;
|
||||
std::cerr << " MsgId: " << msgMeta->mMsgId;
|
||||
std::cerr << " TS: " << msgMeta->mPublishTs;
|
||||
|
||||
addMsg = true;
|
||||
}
|
||||
|
||||
if (addMsg)
|
||||
{
|
||||
// add as latest. (overwriting if necessary)
|
||||
origMsgTs[msgMeta->mOrigMsgId] = std::make_pair(msgMeta->mMsgId, msgMeta->mPublishTs);
|
||||
metaFilter[grpId].insert(std::make_pair(msgMeta->mMsgId, msgMeta));
|
||||
}
|
||||
}
|
||||
|
||||
// Add the discovered Latest Msgs.
|
||||
for(oit = origMsgTs.begin(); oit != origMsgTs.end(); oit++)
|
||||
{
|
||||
req->mMsgIds[grpId].push_back(oit->second.first);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else // ALL OTHER CASES.
|
||||
{
|
||||
std::vector<RsGxsMsgMetaData*>::const_iterator vit = metaV.begin();
|
||||
|
||||
for(; vit != metaV.end(); vit++)
|
||||
{
|
||||
RsGxsMsgMetaData* msgMeta = *vit;
|
||||
bool add = false;
|
||||
|
||||
/* if we are grabbing thread Head... then parentId == empty. */
|
||||
if (onlyThreadHeadMsgs)
|
||||
{
|
||||
if (!(msgMeta->mParentId.empty()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (onlyOrigMsgs)
|
||||
{
|
||||
if (msgMeta->mMsgId == msgMeta->mOrigMsgId)
|
||||
{
|
||||
add = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
add = true;
|
||||
}
|
||||
|
||||
if (add)
|
||||
{
|
||||
req->mMsgIdResult[grpId].push_back(msgMeta->mMsgId);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
filterMsgList(req->mMsgIdResult, opts, metaFilter);
|
||||
|
||||
// delete the data
|
||||
cleanseMetaFilter(metaFilter);
|
||||
|
||||
return true;
|
||||
for(; vit != vit_end; vit++)
|
||||
{
|
||||
RsGxsMsgMetaData* meta = *vit;
|
||||
req->mMsgIdResult[grpId].push_back(meta->mMsgId);
|
||||
delete meta; // discard meta data mem
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void RsGxsDataAccess::cleanseMetaFilter(MsgMetaFilter& filter)
|
||||
|
@ -64,36 +64,14 @@ public:
|
||||
bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const GxsMsgReq&);
|
||||
|
||||
/*!
|
||||
* This sets the status of the message
|
||||
* @param msgId the message id to set status for
|
||||
* @param status status
|
||||
* @param statusMask the mask for the settings targetted
|
||||
* @return true if request made successfully, false otherwise
|
||||
* For requesting msgs related to a given msg id within a group
|
||||
* @param token The token returned for the request
|
||||
* @param ansType The type of result wanted
|
||||
* @param opts Additional option that affect outcome of request. Please see specific services, for valid values
|
||||
* @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs
|
||||
* @return true if request successful false otherwise
|
||||
*/
|
||||
bool requestSetMessageStatus(uint32_t &token, const RsGxsGrpMsgIdPair &msgId,
|
||||
const uint32_t status, const uint32_t statusMask);
|
||||
|
||||
/*!
|
||||
*
|
||||
* @param token
|
||||
* @param grpId
|
||||
* @param status
|
||||
* @param statusMask
|
||||
* @return true if request made successfully, false otherwise
|
||||
*/
|
||||
bool requestSetGroupStatus(uint32_t &token, const RsGxsGroupId &grpId, const uint32_t status,
|
||||
const uint32_t statusMask);
|
||||
|
||||
/*!
|
||||
* Use request status to find out if successfully set
|
||||
* @param groupId
|
||||
* @param subscribeFlags
|
||||
* @param subscribeMask
|
||||
* @return true if request made successfully, false otherwise
|
||||
*/
|
||||
bool requestSetGroupSubscribeFlags(uint32_t& token, const RsGxsGroupId &groupId, uint32_t subscribeFlags,
|
||||
uint32_t subscribeMask);
|
||||
|
||||
bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const GxsMsgReq&);
|
||||
|
||||
/* Poll */
|
||||
uint32_t requestStatus(const uint32_t token);
|
||||
@ -103,8 +81,6 @@ public:
|
||||
|
||||
/** E: RsTokenService **/
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
@ -177,6 +153,14 @@ public:
|
||||
*/
|
||||
bool getMsgData(const uint32_t &token, NxsMsgDataResult& msgData);
|
||||
|
||||
/*!
|
||||
*
|
||||
* @param token request token to be redeemed
|
||||
* @param msgIds
|
||||
* @return false if data cannot be found for token
|
||||
*/
|
||||
bool getMsgRelatedInfo(const uint32_t &token, GxsMsgIdResult &msgIds);
|
||||
|
||||
private:
|
||||
|
||||
/** helper functions to implement token service **/
|
||||
@ -321,6 +305,15 @@ private:
|
||||
*/
|
||||
bool getMsgData(MsgDataReq* req);
|
||||
|
||||
|
||||
/*!
|
||||
* Attempts to retrieve messages related to msgIds of associated equest
|
||||
* @param token request token to be redeemed
|
||||
* @param msgIds
|
||||
* @return false if data cannot be found for token
|
||||
*/
|
||||
bool getMsgRelatedInfo(MsgRelatedInfoReq* req);
|
||||
|
||||
/*!
|
||||
* This filter msgs based of options supplied (at the moment just status masks)
|
||||
* @param msgIds The msgsIds to filter
|
||||
|
@ -95,6 +95,14 @@ public:
|
||||
NxsMsgDataResult mMsgData;
|
||||
};
|
||||
|
||||
class MsgRelatedInfoReq : public GxsRequest
|
||||
{
|
||||
|
||||
public:
|
||||
GxsMsgReq mMsgIds;
|
||||
GxsMsgIdResult mMsgIdResult;
|
||||
};
|
||||
|
||||
class GroupSetFlagReq : public GxsRequest
|
||||
{
|
||||
public:
|
||||
|
@ -132,46 +132,20 @@ public:
|
||||
* @param ansType The type of result wanted
|
||||
* @param opts Additional option that affect outcome of request. Please see specific services, for valid values
|
||||
* @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs
|
||||
* @return
|
||||
* @return true if request successful false otherwise
|
||||
*/
|
||||
virtual bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const GxsMsgReq& msgIds) = 0;
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
* This sets the status of the message
|
||||
* @param msgId the message id to set status for
|
||||
* @param status status
|
||||
* @param statusMask the mask for the settings targetted
|
||||
* @return true if request made successfully, false otherwise
|
||||
* For requesting msgs related to a given msg id within a group
|
||||
* @param token The token returned for the request
|
||||
* @param ansType The type of result wanted
|
||||
* @param opts Additional option that affect outcome of request. Please see specific services, for valid values
|
||||
* @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs
|
||||
* @return true if request successful false otherwise
|
||||
*/
|
||||
virtual bool requestSetMessageStatus(uint32_t &token, const RsGxsGrpMsgIdPair &msgId,
|
||||
const uint32_t status, const uint32_t statusMask) = 0;
|
||||
virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const GxsMsgReq& msgIds) = 0;
|
||||
|
||||
/*!
|
||||
* Set the status of a group given by group Id
|
||||
* @param token The token returned for this request
|
||||
* @param grpId The Id of the group to apply status change to
|
||||
* @param status The status to apply
|
||||
* @param statusMask The status mask (target particular type of status)
|
||||
* @return true if request made successfully, false otherwise
|
||||
*/
|
||||
virtual bool requestSetGroupStatus(uint32_t &token, const RsGxsGroupId &grpId, const uint32_t status,
|
||||
const uint32_t statusMask) = 0;
|
||||
|
||||
/*!
|
||||
* Use request status to find out if successfully set
|
||||
* @param groupId
|
||||
* @param subscribeFlags
|
||||
* @param subscribeMask
|
||||
* @return true if request made successfully, false otherwise
|
||||
*/
|
||||
virtual bool requestSetGroupSubscribeFlags(uint32_t& token, const RsGxsGroupId &groupId, uint32_t subscribeFlags, uint32_t subscribeMask) = 0;
|
||||
|
||||
|
||||
// (FUTURE WORK).
|
||||
//virtual bool groupRestoreKeys(const std::string &groupId) = 0;
|
||||
//virtual bool groupShareKeys(const std::string &groupId, std::list<std::string>& peers) = 0;
|
||||
|
||||
/* Poll */
|
||||
|
||||
|
@ -142,7 +142,8 @@ bool p3PhotoServiceV2::submitAlbumDetails(uint32_t& token, RsPhotoAlbum& album)
|
||||
RsGxsPhotoAlbumItem* albumItem = new RsGxsPhotoAlbumItem();
|
||||
albumItem->album = album;
|
||||
albumItem->meta = album.mMeta;
|
||||
return RsGenExchange::publishGroup(token, albumItem);
|
||||
RsGenExchange::publishGroup(token, albumItem);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -177,7 +178,8 @@ bool p3PhotoServiceV2::submitPhoto(uint32_t& token, RsPhotoPhoto& photo)
|
||||
photoItem->photo = photo;
|
||||
photoItem->meta = photo.mMeta;
|
||||
|
||||
return RsGenExchange::publishMsg(token, photoItem);
|
||||
RsGenExchange::publishMsg(token, photoItem);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3PhotoServiceV2::acknowledgeMsg(const uint32_t& token,
|
||||
|
311
libretroshare/src/util/contentvalue.cc
Normal file
311
libretroshare/src/util/contentvalue.cc
Normal file
@ -0,0 +1,311 @@
|
||||
|
||||
/*
|
||||
* util/contentvalue.cc, key val container
|
||||
*
|
||||
* Copyright 2012 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".
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <memory.h>
|
||||
|
||||
#include "contentvalue.h"
|
||||
|
||||
|
||||
|
||||
|
||||
const uint8_t ContentValue::BOOL_TYPE = 1;
|
||||
const uint8_t ContentValue::DATA_TYPE = 2;
|
||||
const uint8_t ContentValue::STRING_TYPE = 3;
|
||||
const uint8_t ContentValue::DOUBLE_TYPE = 4;
|
||||
const uint8_t ContentValue::INT32_TYPE = 5;
|
||||
const uint8_t ContentValue::INT64_TYPE = 6;
|
||||
|
||||
|
||||
/**************** content value implementation ******************/
|
||||
|
||||
typedef std::pair<std::string, uint8_t> KeyTypePair;
|
||||
|
||||
ContentValue::ContentValue(){
|
||||
|
||||
}
|
||||
|
||||
ContentValue::~ContentValue(){
|
||||
// release resources held in data
|
||||
clearData();
|
||||
}
|
||||
|
||||
ContentValue::ContentValue(ContentValue &from){
|
||||
|
||||
std::map<std::string, uint8_t> keyTypeMap;
|
||||
from.getKeyTypeMap(keyTypeMap);
|
||||
std::map<std::string, uint8_t>::const_iterator cit =
|
||||
keyTypeMap.begin();
|
||||
|
||||
uint8_t type = 0;
|
||||
std::string currKey;
|
||||
std::string val = "";
|
||||
char *src = NULL;
|
||||
uint32_t data_len = 0;
|
||||
|
||||
for(; cit != keyTypeMap.end(); cit++){
|
||||
|
||||
type = cit->second;
|
||||
currKey = cit->first;
|
||||
|
||||
switch(type){
|
||||
|
||||
case INT32_TYPE:
|
||||
{
|
||||
int32_t value;
|
||||
from.getAsInt32(currKey, value);
|
||||
put(currKey, value);
|
||||
break;
|
||||
}
|
||||
case INT64_TYPE:
|
||||
{
|
||||
int64_t value;
|
||||
from.getAsInt64(currKey, value);
|
||||
put(currKey, value);
|
||||
break;
|
||||
}
|
||||
case STRING_TYPE:
|
||||
{
|
||||
from.getAsString(currKey, val);
|
||||
put(currKey, val);
|
||||
break;
|
||||
}
|
||||
case BOOL_TYPE:
|
||||
{
|
||||
bool value;
|
||||
from.getAsBool(currKey, value);
|
||||
put(currKey, value);
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE:
|
||||
{
|
||||
from.getAsData(currKey, data_len, src);
|
||||
put(currKey, data_len, src);
|
||||
break;
|
||||
}
|
||||
case DOUBLE_TYPE:
|
||||
double value;
|
||||
from.getAsDouble(currKey, value);
|
||||
put(currKey, value);
|
||||
break;
|
||||
default:
|
||||
std::cerr << "ContentValue::ContentValue(ContentValue &from):"
|
||||
<< "Error! Unrecognised data type!" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ContentValue::put(const std::string &key, bool value){
|
||||
|
||||
if(mKvSet.find(key) != mKvSet.end())
|
||||
removeKeyValue(key);
|
||||
|
||||
mKvSet.insert(KeyTypePair(key, BOOL_TYPE));
|
||||
mKvBool.insert(std::pair<std::string, bool>(key, value));
|
||||
}
|
||||
|
||||
void ContentValue::put(const std::string &key, const std::string &value){
|
||||
|
||||
if(mKvSet.find(key) != mKvSet.end())
|
||||
removeKeyValue(key);
|
||||
|
||||
mKvSet.insert(KeyTypePair(key, STRING_TYPE));
|
||||
mKvString.insert(std::pair<std::string, std::string>(key, value));
|
||||
}
|
||||
|
||||
void ContentValue::put(const std::string &key, double value){
|
||||
|
||||
if(mKvSet.find(key) != mKvSet.end())
|
||||
removeKeyValue(key);
|
||||
|
||||
mKvSet.insert(KeyTypePair(key,DOUBLE_TYPE));
|
||||
mKvDouble.insert(std::pair<std::string, double>(key, value));
|
||||
}
|
||||
|
||||
void ContentValue::put(const std::string &key, int32_t value){
|
||||
|
||||
if(mKvSet.find(key) != mKvSet.end())
|
||||
removeKeyValue(key);
|
||||
|
||||
mKvSet.insert(KeyTypePair(key, INT32_TYPE));
|
||||
mKvInt32.insert(std::pair<std::string, int32_t>(key, value));
|
||||
}
|
||||
|
||||
void ContentValue::put(const std::string &key, int64_t value){
|
||||
|
||||
if(mKvSet.find(key) != mKvSet.end())
|
||||
removeKeyValue(key);
|
||||
|
||||
mKvSet.insert(KeyTypePair(key, INT64_TYPE));
|
||||
mKvInt64.insert(std::pair<std::string, int64_t>(key, value));
|
||||
}
|
||||
|
||||
void ContentValue::put(const std::string &key, uint32_t len, const char* value){
|
||||
|
||||
|
||||
// release memory from old key value if key
|
||||
// exists
|
||||
if(mKvSet.find(key) != mKvSet.end()) {
|
||||
removeKeyValue(key);
|
||||
}
|
||||
|
||||
mKvSet.insert(KeyTypePair(key, DATA_TYPE));
|
||||
char* dest = NULL;
|
||||
|
||||
// len is zero then just put a NULL entry
|
||||
if(len != 0){
|
||||
dest = new char[len];
|
||||
memcpy(dest, value, len);
|
||||
}
|
||||
|
||||
mKvData.insert(std::pair<std::string, std::pair<uint32_t, char*> >
|
||||
(key, std::pair<uint32_t, char*>(len, dest)));
|
||||
}
|
||||
|
||||
bool ContentValue::getAsBool(const std::string &key, bool& value) const{
|
||||
|
||||
std::map<std::string, bool>::const_iterator it;
|
||||
if((it = mKvBool.find(key)) == mKvBool.end())
|
||||
return false;
|
||||
|
||||
value = it->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ContentValue::getAsInt32(const std::string &key, int32_t& value) const{
|
||||
|
||||
std::map<std::string, int32_t>::const_iterator it;
|
||||
if((it = mKvInt32.find(key)) == mKvInt32.end())
|
||||
return false;
|
||||
|
||||
value = it->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ContentValue::getAsInt64(const std::string &key, int64_t& value) const{
|
||||
|
||||
std::map<std::string, int64_t>::const_iterator it;
|
||||
if((it = mKvInt64.find(key)) == mKvInt64.end())
|
||||
return false;
|
||||
|
||||
value = it->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ContentValue::getAsString(const std::string &key, std::string &value) const{
|
||||
|
||||
std::map<std::string, std::string>::const_iterator it;
|
||||
if((it = mKvString.find(key)) == mKvString.end())
|
||||
return false;
|
||||
|
||||
value = it->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ContentValue::getAsData(const std::string& key, uint32_t &len, char*& value) const{
|
||||
|
||||
std::map<std::string, std::pair<uint32_t, char*> >::const_iterator it;
|
||||
if((it = mKvData.find(key)) == mKvData.end())
|
||||
return false;
|
||||
|
||||
const std::pair<uint32_t, char*> &kvRef = it->second;
|
||||
|
||||
len = kvRef.first;
|
||||
value = kvRef.second;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ContentValue::getAsDouble(const std::string &key, double& value) const{
|
||||
|
||||
std::map<std::string, double>::const_iterator it;
|
||||
if((it = mKvDouble.find(key)) == mKvDouble.end())
|
||||
return false;
|
||||
|
||||
value = it->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ContentValue::removeKeyValue(const std::string &key){
|
||||
|
||||
std::map<std::string, uint8_t>::iterator mit;
|
||||
|
||||
if((mit = mKvSet.find(key)) == mKvSet.end())
|
||||
return false;
|
||||
|
||||
if(mit->second == BOOL_TYPE)
|
||||
mKvBool.erase(key);
|
||||
|
||||
if(mit->second == INT64_TYPE)
|
||||
mKvInt64.erase(key);
|
||||
|
||||
if(mit->second == DATA_TYPE){
|
||||
delete[] (mKvData[key].second);
|
||||
mKvData.erase(key);
|
||||
}
|
||||
|
||||
if(mit->second == DOUBLE_TYPE)
|
||||
mKvDouble.erase(key);
|
||||
|
||||
if(mit->second == STRING_TYPE)
|
||||
mKvString.erase(key);
|
||||
|
||||
if(mit->second == INT32_TYPE)
|
||||
mKvInt32.erase(key);
|
||||
|
||||
|
||||
mKvSet.erase(key);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void ContentValue::getKeyTypeMap(std::map<std::string, uint8_t> &keySet) const {
|
||||
keySet = mKvSet;
|
||||
}
|
||||
|
||||
void ContentValue::clear(){
|
||||
mKvSet.clear();
|
||||
mKvBool.clear();
|
||||
mKvDouble.clear();
|
||||
mKvString.clear();
|
||||
mKvInt32.clear();
|
||||
mKvInt64.clear();
|
||||
clearData();
|
||||
}
|
||||
|
||||
void ContentValue::clearData(){
|
||||
|
||||
std::map<std::string, std::pair<uint32_t, char*> >::iterator
|
||||
mit = mKvData.begin();
|
||||
|
||||
for(; mit != mKvData.end(); mit++){
|
||||
|
||||
if(mit->second.first != 0)
|
||||
delete[] (mit->second.second);
|
||||
}
|
||||
|
||||
mKvData.clear();
|
||||
}
|
||||
|
||||
|
||||
|
183
libretroshare/src/util/contentvalue.h
Normal file
183
libretroshare/src/util/contentvalue.h
Normal file
@ -0,0 +1,183 @@
|
||||
#ifndef CONTENTVALUE_H
|
||||
#define CONTENTVALUE_H
|
||||
|
||||
/*
|
||||
* util/contentvalue.h, key val container
|
||||
*
|
||||
* Copyright 2012 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".
|
||||
*
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
/*!
|
||||
* @brief Convenience container for making additions to databases
|
||||
* This class provides a means of holding column values to insert into a database
|
||||
*/
|
||||
class ContentValue {
|
||||
|
||||
public:
|
||||
|
||||
static const uint8_t INT32_TYPE;
|
||||
static const uint8_t INT64_TYPE;
|
||||
static const uint8_t DOUBLE_TYPE;
|
||||
static const uint8_t STRING_TYPE;
|
||||
static const uint8_t DATA_TYPE;
|
||||
static const uint8_t BOOL_TYPE;
|
||||
|
||||
ContentValue();
|
||||
|
||||
/*!
|
||||
* copy constructor that copys the key value set from another \n
|
||||
* ContentValue object to this one
|
||||
* makes a deep copy of raw data
|
||||
* @param from ContentValue instance to copy key value set from
|
||||
*/
|
||||
ContentValue(ContentValue& from);
|
||||
|
||||
/*!
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
~ContentValue();
|
||||
|
||||
/*!
|
||||
* Adds a value to the set
|
||||
* @param key the name of the value to put
|
||||
* @param value the data for the value to put
|
||||
* @warning cast string literals explicitly as string, observed string literal \n
|
||||
* being casted to bool instead e.g. string("hello") rather than "hello"
|
||||
*/
|
||||
void put(const std::string& key, const std::string& value);
|
||||
|
||||
/*!
|
||||
* Adds a value to the set
|
||||
* @param key the name of the value to put
|
||||
* @param value the data for the value to put
|
||||
*/
|
||||
void put(const std::string& key, bool value);
|
||||
|
||||
/*!
|
||||
* Adds a value to the set
|
||||
* @param key the name of the value to put
|
||||
* @param value the data for the value to put
|
||||
*/
|
||||
void put(const std::string& key, int64_t value);
|
||||
|
||||
/*!
|
||||
* Adds a value to the set
|
||||
* @param key the name of the value to put
|
||||
* @param value the data for the value to put
|
||||
*/
|
||||
void put(const std::string& key, int32_t value);
|
||||
|
||||
/*!
|
||||
* Adds a value to the set
|
||||
* @param key the name of the value to put
|
||||
* @param value the data for the value to put
|
||||
*/
|
||||
void put(const std::string& key, double value);
|
||||
|
||||
/*!
|
||||
* Adds a value to the set
|
||||
* @param key the name of the value to put
|
||||
* @param value the data for the value to put
|
||||
*/
|
||||
void put(const std::string& key, uint32_t len, const char* value);
|
||||
|
||||
|
||||
/*!
|
||||
* get value as 32 bit signed integer
|
||||
* @param key the value to get
|
||||
*/
|
||||
bool getAsInt32(const std::string& key, int32_t& value) const;
|
||||
|
||||
/*!
|
||||
* get value as 64 bit signed integer
|
||||
* @param key the value to get
|
||||
*/
|
||||
bool getAsInt64(const std::string& key, int64_t& value) const;
|
||||
|
||||
/*!
|
||||
* get value as bool
|
||||
* @param key the value to get
|
||||
*/
|
||||
bool getAsBool(const std::string& key, bool& value) const;
|
||||
|
||||
/*!
|
||||
* get as value double
|
||||
* @param key the value to get
|
||||
*/
|
||||
bool getAsDouble(const std::string& key, double& value) const;
|
||||
|
||||
/*!
|
||||
* get as value as string
|
||||
* @param key the value to get
|
||||
* @param value the data retrieved
|
||||
*/
|
||||
bool getAsString(const std::string& key, std::string& value) const;
|
||||
|
||||
/*!
|
||||
* get as value as raw data
|
||||
* @warning Deep copy of data reference should be made, if this instance ContentValue \n
|
||||
* is destroyed pointer returned (value) is pointing to invalid memory
|
||||
* @param key the value to get
|
||||
*/
|
||||
bool getAsData(const std::string&, uint32_t& len, char*& value) const;
|
||||
|
||||
/*!
|
||||
* @param keySet the is set with key to type pairs contained in the ContentValue instance
|
||||
*/
|
||||
void getKeyTypeMap(std::map<std::string, uint8_t>& keySet) const;
|
||||
|
||||
/*!
|
||||
* @param key the key of the key value pair to remove
|
||||
* @return true if key was found and removed, false otherwise
|
||||
*/
|
||||
bool removeKeyValue(const std::string& key);
|
||||
|
||||
/*!
|
||||
* clears this data structure of all its key value pairs held
|
||||
*/
|
||||
void clear();
|
||||
|
||||
private:
|
||||
|
||||
/*!
|
||||
* release memory resource associated with mKvData
|
||||
*/
|
||||
void clearData();
|
||||
|
||||
private:
|
||||
|
||||
std::map<std::string, int32_t> mKvInt32;
|
||||
std::map<std::string, int64_t> mKvInt64;
|
||||
std::map<std::string, double> mKvDouble;
|
||||
std::map<std::string, std::string> mKvString;
|
||||
std::map<std::string, std::pair<uint32_t, char*> > mKvData;
|
||||
std::map<std::string, bool> mKvBool;
|
||||
|
||||
std::map<std::string, uint8_t> mKvSet;
|
||||
|
||||
};
|
||||
|
||||
#endif // CONTENTVALUE_H
|
@ -32,6 +32,8 @@
|
||||
|
||||
//#define RETRODB_DEBUG
|
||||
|
||||
|
||||
|
||||
void free_blob(void* dat){
|
||||
|
||||
char* c = (char*) dat;
|
||||
@ -40,13 +42,6 @@ void free_blob(void* dat){
|
||||
|
||||
}
|
||||
|
||||
const uint8_t ContentValue::BOOL_TYPE = 1;
|
||||
const uint8_t ContentValue::DATA_TYPE = 2;
|
||||
const uint8_t ContentValue::STRING_TYPE = 3;
|
||||
const uint8_t ContentValue::DOUBLE_TYPE = 4;
|
||||
const uint8_t ContentValue::INT32_TYPE = 5;
|
||||
const uint8_t ContentValue::INT64_TYPE = 6;
|
||||
|
||||
const int RetroDb::OPEN_READONLY = SQLITE_OPEN_READONLY;
|
||||
const int RetroDb::OPEN_READWRITE = SQLITE_OPEN_READWRITE;
|
||||
const int RetroDb::OPEN_READWRITE_CREATE = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
|
||||
@ -234,9 +229,9 @@ bool RetroDb::sqlInsert(const std::string &table, const std::string& nullColumnH
|
||||
uint8_t type = mit->second;
|
||||
std::string key = mit->first;
|
||||
|
||||
switch(type){
|
||||
|
||||
case ContentValue::BOOL_TYPE:
|
||||
|
||||
if(ContentValue::BOOL_TYPE == type)
|
||||
{
|
||||
bool value;
|
||||
cv.getAsBool(key, value);
|
||||
@ -244,7 +239,7 @@ bool RetroDb::sqlInsert(const std::string &table, const std::string& nullColumnH
|
||||
qValues += oStrStream.str();
|
||||
break;
|
||||
}
|
||||
case ContentValue::DOUBLE_TYPE:
|
||||
else if( ContentValue::DOUBLE_TYPE == type)
|
||||
{
|
||||
double value;
|
||||
cv.getAsDouble(key, value);
|
||||
@ -252,7 +247,7 @@ bool RetroDb::sqlInsert(const std::string &table, const std::string& nullColumnH
|
||||
qValues += oStrStream.str();
|
||||
break;
|
||||
}
|
||||
case ContentValue::DATA_TYPE:
|
||||
else if( ContentValue::DATA_TYPE == type)
|
||||
{
|
||||
char* value;
|
||||
uint32_t len;
|
||||
@ -265,14 +260,14 @@ bool RetroDb::sqlInsert(const std::string &table, const std::string& nullColumnH
|
||||
qValues += "?"; // parameter
|
||||
break;
|
||||
}
|
||||
case ContentValue::STRING_TYPE:
|
||||
else if ( ContentValue::STRING_TYPE == type)
|
||||
{
|
||||
std::string value;
|
||||
cv.getAsString(key, value);
|
||||
qValues += "'" + value +"'";
|
||||
break;
|
||||
}
|
||||
case ContentValue::INT32_TYPE:
|
||||
else if ( ContentValue::INT32_TYPE == type)
|
||||
{
|
||||
int32_t value;
|
||||
cv.getAsInt32(key, value);
|
||||
@ -280,7 +275,7 @@ bool RetroDb::sqlInsert(const std::string &table, const std::string& nullColumnH
|
||||
qValues += oStrStream.str();
|
||||
break;
|
||||
}
|
||||
case ContentValue::INT64_TYPE:
|
||||
else if( ContentValue::INT64_TYPE == type)
|
||||
{
|
||||
int64_t value;
|
||||
cv.getAsInt64(key, value);
|
||||
@ -288,7 +283,7 @@ bool RetroDb::sqlInsert(const std::string &table, const std::string& nullColumnH
|
||||
qValues += oStrStream.str();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mit++;
|
||||
if(mit != keyTypeMap.end()){ // add comma if more columns left
|
||||
@ -419,9 +414,7 @@ bool RetroDb::sqlUpdate(const std::string &tableName, std::string whereClause, c
|
||||
uint8_t type = mit->second;
|
||||
std::string key = mit->first;
|
||||
|
||||
switch(type){
|
||||
|
||||
case ContentValue::BOOL_TYPE:
|
||||
if( ContentValue::BOOL_TYPE == type)
|
||||
{
|
||||
bool value;
|
||||
cv.getAsBool(key, value);
|
||||
@ -429,7 +422,7 @@ bool RetroDb::sqlUpdate(const std::string &tableName, std::string whereClause, c
|
||||
qValues += key + "='" + oStrStream.str();
|
||||
break;
|
||||
}
|
||||
case ContentValue::DOUBLE_TYPE:
|
||||
else if( ContentValue::DOUBLE_TYPE == type)
|
||||
{
|
||||
double value;
|
||||
cv.getAsDouble(key, value);
|
||||
@ -437,7 +430,7 @@ bool RetroDb::sqlUpdate(const std::string &tableName, std::string whereClause, c
|
||||
qValues += key + "='" + oStrStream.str();
|
||||
break;
|
||||
}
|
||||
case ContentValue::DATA_TYPE:
|
||||
else if( ContentValue::DATA_TYPE == type)
|
||||
{
|
||||
char* value;
|
||||
uint32_t len;
|
||||
@ -446,14 +439,14 @@ bool RetroDb::sqlUpdate(const std::string &tableName, std::string whereClause, c
|
||||
qValues += key + "='" + oStrStream.str() + "' ";
|
||||
break;
|
||||
}
|
||||
case ContentValue::STRING_TYPE:
|
||||
else if( ContentValue::STRING_TYPE == type)
|
||||
{
|
||||
std::string value;
|
||||
cv.getAsString(key, value);
|
||||
qValues += key + "='" + value + "' ";
|
||||
break;
|
||||
}
|
||||
case ContentValue::INT32_TYPE:
|
||||
else if( ContentValue::INT32_TYPE == type)
|
||||
{
|
||||
int32_t value;
|
||||
cv.getAsInt32(key, value);
|
||||
@ -461,7 +454,7 @@ bool RetroDb::sqlUpdate(const std::string &tableName, std::string whereClause, c
|
||||
qValues += key + "='" + oStrStream.str() + "' ";
|
||||
break;
|
||||
}
|
||||
case ContentValue::INT64_TYPE:
|
||||
else if( ContentValue::INT64_TYPE == type)
|
||||
{
|
||||
int64_t value;
|
||||
cv.getAsInt64(key, value);
|
||||
@ -469,7 +462,7 @@ bool RetroDb::sqlUpdate(const std::string &tableName, std::string whereClause, c
|
||||
qValues += key + "='" + oStrStream.str() + "' ";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mit++;
|
||||
if(mit != keyTypeMap.end()){ // add comma if more columns left
|
||||
@ -715,276 +708,3 @@ const void* RetroCursor::getData(int columnIndex, uint32_t &datSize){
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**************** content value implementation ******************/
|
||||
|
||||
typedef std::pair<std::string, uint8_t> KeyTypePair;
|
||||
|
||||
ContentValue::ContentValue(){
|
||||
|
||||
}
|
||||
|
||||
ContentValue::~ContentValue(){
|
||||
// release resources held in data
|
||||
clearData();
|
||||
}
|
||||
|
||||
ContentValue::ContentValue(ContentValue &from){
|
||||
|
||||
std::map<std::string, uint8_t> keyTypeMap;
|
||||
from.getKeyTypeMap(keyTypeMap);
|
||||
std::map<std::string, uint8_t>::const_iterator cit =
|
||||
keyTypeMap.begin();
|
||||
|
||||
uint8_t type = 0;
|
||||
std::string currKey;
|
||||
std::string val = "";
|
||||
char *src = NULL;
|
||||
uint32_t data_len = 0;
|
||||
|
||||
for(; cit != keyTypeMap.end(); cit++){
|
||||
|
||||
type = cit->second;
|
||||
currKey = cit->first;
|
||||
|
||||
switch(type){
|
||||
|
||||
case INT32_TYPE:
|
||||
{
|
||||
int32_t value;
|
||||
from.getAsInt32(currKey, value);
|
||||
put(currKey, value);
|
||||
break;
|
||||
}
|
||||
case INT64_TYPE:
|
||||
{
|
||||
int64_t value;
|
||||
from.getAsInt64(currKey, value);
|
||||
put(currKey, value);
|
||||
break;
|
||||
}
|
||||
case STRING_TYPE:
|
||||
{
|
||||
from.getAsString(currKey, val);
|
||||
put(currKey, val);
|
||||
break;
|
||||
}
|
||||
case BOOL_TYPE:
|
||||
{
|
||||
bool value;
|
||||
from.getAsBool(currKey, value);
|
||||
put(currKey, value);
|
||||
break;
|
||||
}
|
||||
case DATA_TYPE:
|
||||
{
|
||||
from.getAsData(currKey, data_len, src);
|
||||
put(currKey, data_len, src);
|
||||
break;
|
||||
}
|
||||
case DOUBLE_TYPE:
|
||||
double value;
|
||||
from.getAsDouble(currKey, value);
|
||||
put(currKey, value);
|
||||
break;
|
||||
default:
|
||||
std::cerr << "ContentValue::ContentValue(ContentValue &from):"
|
||||
<< "Error! Unrecognised data type!" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ContentValue::put(const std::string &key, bool value){
|
||||
|
||||
if(mKvSet.find(key) != mKvSet.end())
|
||||
removeKeyValue(key);
|
||||
|
||||
mKvSet.insert(KeyTypePair(key, BOOL_TYPE));
|
||||
mKvBool.insert(std::pair<std::string, bool>(key, value));
|
||||
}
|
||||
|
||||
void ContentValue::put(const std::string &key, const std::string &value){
|
||||
|
||||
if(mKvSet.find(key) != mKvSet.end())
|
||||
removeKeyValue(key);
|
||||
|
||||
mKvSet.insert(KeyTypePair(key, STRING_TYPE));
|
||||
mKvString.insert(std::pair<std::string, std::string>(key, value));
|
||||
}
|
||||
|
||||
void ContentValue::put(const std::string &key, double value){
|
||||
|
||||
if(mKvSet.find(key) != mKvSet.end())
|
||||
removeKeyValue(key);
|
||||
|
||||
mKvSet.insert(KeyTypePair(key,DOUBLE_TYPE));
|
||||
mKvDouble.insert(std::pair<std::string, double>(key, value));
|
||||
}
|
||||
|
||||
void ContentValue::put(const std::string &key, int32_t value){
|
||||
|
||||
if(mKvSet.find(key) != mKvSet.end())
|
||||
removeKeyValue(key);
|
||||
|
||||
mKvSet.insert(KeyTypePair(key, INT32_TYPE));
|
||||
mKvInt32.insert(std::pair<std::string, int32_t>(key, value));
|
||||
}
|
||||
|
||||
void ContentValue::put(const std::string &key, int64_t value){
|
||||
|
||||
if(mKvSet.find(key) != mKvSet.end())
|
||||
removeKeyValue(key);
|
||||
|
||||
mKvSet.insert(KeyTypePair(key, INT64_TYPE));
|
||||
mKvInt64.insert(std::pair<std::string, int64_t>(key, value));
|
||||
}
|
||||
|
||||
void ContentValue::put(const std::string &key, uint32_t len, const char* value){
|
||||
|
||||
|
||||
// release memory from old key value if key
|
||||
// exists
|
||||
if(mKvSet.find(key) != mKvSet.end()) {
|
||||
removeKeyValue(key);
|
||||
}
|
||||
|
||||
mKvSet.insert(KeyTypePair(key, DATA_TYPE));
|
||||
char* dest = NULL;
|
||||
|
||||
// len is zero then just put a NULL entry
|
||||
if(len != 0){
|
||||
dest = new char[len];
|
||||
memcpy(dest, value, len);
|
||||
}
|
||||
|
||||
mKvData.insert(std::pair<std::string, std::pair<uint32_t, char*> >
|
||||
(key, std::pair<uint32_t, char*>(len, dest)));
|
||||
}
|
||||
|
||||
bool ContentValue::getAsBool(const std::string &key, bool& value) const{
|
||||
|
||||
std::map<std::string, bool>::const_iterator it;
|
||||
if((it = mKvBool.find(key)) == mKvBool.end())
|
||||
return false;
|
||||
|
||||
value = it->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ContentValue::getAsInt32(const std::string &key, int32_t& value) const{
|
||||
|
||||
std::map<std::string, int32_t>::const_iterator it;
|
||||
if((it = mKvInt32.find(key)) == mKvInt32.end())
|
||||
return false;
|
||||
|
||||
value = it->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ContentValue::getAsInt64(const std::string &key, int64_t& value) const{
|
||||
|
||||
std::map<std::string, int64_t>::const_iterator it;
|
||||
if((it = mKvInt64.find(key)) == mKvInt64.end())
|
||||
return false;
|
||||
|
||||
value = it->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ContentValue::getAsString(const std::string &key, std::string &value) const{
|
||||
|
||||
std::map<std::string, std::string>::const_iterator it;
|
||||
if((it = mKvString.find(key)) == mKvString.end())
|
||||
return false;
|
||||
|
||||
value = it->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ContentValue::getAsData(const std::string& key, uint32_t &len, char*& value) const{
|
||||
|
||||
std::map<std::string, std::pair<uint32_t, char*> >::const_iterator it;
|
||||
if((it = mKvData.find(key)) == mKvData.end())
|
||||
return false;
|
||||
|
||||
const std::pair<uint32_t, char*> &kvRef = it->second;
|
||||
|
||||
len = kvRef.first;
|
||||
value = kvRef.second;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ContentValue::getAsDouble(const std::string &key, double& value) const{
|
||||
|
||||
std::map<std::string, double>::const_iterator it;
|
||||
if((it = mKvDouble.find(key)) == mKvDouble.end())
|
||||
return false;
|
||||
|
||||
value = it->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ContentValue::removeKeyValue(const std::string &key){
|
||||
|
||||
std::map<std::string, uint8_t>::iterator mit;
|
||||
|
||||
if((mit = mKvSet.find(key)) == mKvSet.end())
|
||||
return false;
|
||||
|
||||
if(mit->second == BOOL_TYPE)
|
||||
mKvBool.erase(key);
|
||||
|
||||
if(mit->second == INT64_TYPE)
|
||||
mKvInt64.erase(key);
|
||||
|
||||
if(mit->second == DATA_TYPE){
|
||||
delete[] (mKvData[key].second);
|
||||
mKvData.erase(key);
|
||||
}
|
||||
|
||||
if(mit->second == DOUBLE_TYPE)
|
||||
mKvDouble.erase(key);
|
||||
|
||||
if(mit->second == STRING_TYPE)
|
||||
mKvString.erase(key);
|
||||
|
||||
if(mit->second == INT32_TYPE)
|
||||
mKvInt32.erase(key);
|
||||
|
||||
|
||||
mKvSet.erase(key);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void ContentValue::getKeyTypeMap(std::map<std::string, uint8_t> &keySet) const {
|
||||
keySet = mKvSet;
|
||||
}
|
||||
|
||||
void ContentValue::clear(){
|
||||
mKvSet.clear();
|
||||
mKvBool.clear();
|
||||
mKvDouble.clear();
|
||||
mKvString.clear();
|
||||
mKvInt32.clear();
|
||||
mKvInt64.clear();
|
||||
clearData();
|
||||
}
|
||||
|
||||
void ContentValue::clearData(){
|
||||
|
||||
std::map<std::string, std::pair<uint32_t, char*> >::iterator
|
||||
mit = mKvData.begin();
|
||||
|
||||
for(; mit != mKvData.end(); mit++){
|
||||
|
||||
if(mit->second.first != 0)
|
||||
delete[] (mit->second.second);
|
||||
}
|
||||
|
||||
mKvData.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -31,8 +31,8 @@
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
#include "contentvalue.h"
|
||||
|
||||
class ContentValue;
|
||||
class RetroCursor;
|
||||
|
||||
/*!
|
||||
@ -288,157 +288,7 @@ private:
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Convenience container for making additions to databases
|
||||
* This class provides a means of holding column values to insert into a database
|
||||
*/
|
||||
class ContentValue {
|
||||
|
||||
public:
|
||||
|
||||
static const uint8_t INT32_TYPE;
|
||||
static const uint8_t INT64_TYPE;
|
||||
static const uint8_t DOUBLE_TYPE;
|
||||
static const uint8_t STRING_TYPE;
|
||||
static const uint8_t DATA_TYPE;
|
||||
static const uint8_t BOOL_TYPE;
|
||||
|
||||
ContentValue();
|
||||
|
||||
/*!
|
||||
* copy constructor that copys the key value set from another \n
|
||||
* ContentValue object to this one
|
||||
* makes a deep copy of raw data
|
||||
* @param from ContentValue instance to copy key value set from
|
||||
*/
|
||||
ContentValue(ContentValue& from);
|
||||
|
||||
/*!
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
~ContentValue();
|
||||
|
||||
/*!
|
||||
* Adds a value to the set
|
||||
* @param key the name of the value to put
|
||||
* @param value the data for the value to put
|
||||
* @warning cast string literals explicitly as string, observed string literal \n
|
||||
* being casted to bool instead e.g. string("hello") rather than "hello"
|
||||
*/
|
||||
void put(const std::string& key, const std::string& value);
|
||||
|
||||
/*!
|
||||
* Adds a value to the set
|
||||
* @param key the name of the value to put
|
||||
* @param value the data for the value to put
|
||||
*/
|
||||
void put(const std::string& key, bool value);
|
||||
|
||||
/*!
|
||||
* Adds a value to the set
|
||||
* @param key the name of the value to put
|
||||
* @param value the data for the value to put
|
||||
*/
|
||||
void put(const std::string& key, int64_t value);
|
||||
|
||||
/*!
|
||||
* Adds a value to the set
|
||||
* @param key the name of the value to put
|
||||
* @param value the data for the value to put
|
||||
*/
|
||||
void put(const std::string& key, int32_t value);
|
||||
|
||||
/*!
|
||||
* Adds a value to the set
|
||||
* @param key the name of the value to put
|
||||
* @param value the data for the value to put
|
||||
*/
|
||||
void put(const std::string& key, double value);
|
||||
|
||||
/*!
|
||||
* Adds a value to the set
|
||||
* @param key the name of the value to put
|
||||
* @param value the data for the value to put
|
||||
*/
|
||||
void put(const std::string& key, uint32_t len, const char* value);
|
||||
|
||||
|
||||
/*!
|
||||
* get value as 32 bit signed integer
|
||||
* @param key the value to get
|
||||
*/
|
||||
bool getAsInt32(const std::string& key, int32_t& value) const;
|
||||
|
||||
/*!
|
||||
* get value as 64 bit signed integer
|
||||
* @param key the value to get
|
||||
*/
|
||||
bool getAsInt64(const std::string& key, int64_t& value) const;
|
||||
|
||||
/*!
|
||||
* get value as bool
|
||||
* @param key the value to get
|
||||
*/
|
||||
bool getAsBool(const std::string& key, bool& value) const;
|
||||
|
||||
/*!
|
||||
* get as value double
|
||||
* @param key the value to get
|
||||
*/
|
||||
bool getAsDouble(const std::string& key, double& value) const;
|
||||
|
||||
/*!
|
||||
* get as value as string
|
||||
* @param key the value to get
|
||||
* @param value the data retrieved
|
||||
*/
|
||||
bool getAsString(const std::string& key, std::string& value) const;
|
||||
|
||||
/*!
|
||||
* get as value as raw data
|
||||
* @warning Deep copy of data reference should be made, if this instance ContentValue \n
|
||||
* is destroyed pointer returned (value) is pointing to invalid memory
|
||||
* @param key the value to get
|
||||
*/
|
||||
bool getAsData(const std::string&, uint32_t& len, char*& value) const;
|
||||
|
||||
/*!
|
||||
* @param keySet the is set with key to type pairs contained in the ContentValue instance
|
||||
*/
|
||||
void getKeyTypeMap(std::map<std::string, uint8_t>& keySet) const;
|
||||
|
||||
/*!
|
||||
* @param key the key of the key value pair to remove
|
||||
* @return true if key was found and removed, false otherwise
|
||||
*/
|
||||
bool removeKeyValue(const std::string& key);
|
||||
|
||||
/*!
|
||||
* clears this data structure of all its key value pairs held
|
||||
*/
|
||||
void clear();
|
||||
|
||||
private:
|
||||
|
||||
/*!
|
||||
* release memory resource associated with mKvData
|
||||
*/
|
||||
void clearData();
|
||||
|
||||
private:
|
||||
|
||||
std::map<std::string, int32_t> mKvInt32;
|
||||
std::map<std::string, int64_t> mKvInt64;
|
||||
std::map<std::string, double> mKvDouble;
|
||||
std::map<std::string, std::string> mKvString;
|
||||
std::map<std::string, std::pair<uint32_t, char*> > mKvData;
|
||||
std::map<std::string, bool> mKvBool;
|
||||
|
||||
std::map<std::string, uint8_t> mKvSet;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // RSSQLITE_H
|
||||
|
Loading…
Reference in New Issue
Block a user