1 #include "../../include/freenet/messageinserter.h"
\r
2 #include "../../include/freenet/messagexml.h"
\r
4 #include <Poco/DateTime.h>
\r
5 #include <Poco/DateTimeFormatter.h>
\r
6 #include <Poco/Timestamp.h>
\r
8 MessageInserter::MessageInserter(SQLite3DB::DB *db):IIndexInserter<std::string>(db)
\r
13 MessageInserter::MessageInserter(SQLite3DB::DB *db, FCPv2::Connection *fcp):IIndexInserter<std::string>(db,fcp)
\r
18 void MessageInserter::CheckForNeededInsert()
\r
21 bool didinsert=false;
\r
22 // only do 1 insert at a time
\r
23 if(m_inserting.size()==0)
\r
25 SQLite3DB::Statement st=m_db->Prepare("SELECT MessageUUID FROM tblMessageInserts INNER JOIN tblLocalIdentity ON tblMessageInserts.LocalIdentityID=tblLocalIdentity.LocalIdentityID WHERE tblLocalIdentity.PrivateKey IS NOT NULL AND tblLocalIdentity.PrivateKey <> '' AND tblMessageInserts.Inserted='false' AND tblMessageInserts.SendDate<=?;");
\r
26 st.Bind(0,Poco::DateTimeFormatter::format(now,"%Y-%m-%d %H:%M:%S"));
\r
29 while(st.RowReturned() && m_inserting.size()==0)
\r
31 std::string messageuuid="";
\r
32 st.ResultText(0,messageuuid);
\r
34 // make sure there are no uninserted files attached to this message
\r
35 SQLite3DB::Statement st2=m_db->Prepare("SELECT FileInsertID FROM tblFileInserts WHERE Key IS NULL AND MessageUUID=?;");
\r
36 st2.Bind(0,messageuuid);
\r
39 if(st2.RowReturned()==false)
\r
41 StartInsert(messageuuid);
\r
49 const bool MessageInserter::HandlePutFailed(FCPv2::Message &message)
\r
52 int localidentityid;
\r
53 std::vector<std::string> idparts;
\r
55 // do check to make sure this is the non-editioned SSK - we ignore failure/success for editioned SSK for now
\r
56 if(message["Identifier"].find(".xml")!=std::string::npos)
\r
59 StringFunctions::Split(message["Identifier"],"|",idparts);
\r
60 StringFunctions::Convert(idparts[2],localidentityid);
\r
61 StringFunctions::Convert(idparts[3],index);
\r
63 // fatal put - or data exists - insert bogus index into database so we'll try to insert this message again
\r
64 if(message["Fatal"]=="true" || message["Code"]=="9")
\r
66 SQLite3DB::Statement st=m_db->Prepare("INSERT INTO tblMessageInserts(LocalIdentityID,Day,InsertIndex,Inserted) VALUES(?,?,?,'true');");
\r
67 st.Bind(0,localidentityid);
\r
68 st.Bind(1,idparts[6]);
\r
73 m_log->trace("MessageInserter::HandlePutFailed error code "+message["Code"]+" fatal="+message["Fatal"]);
\r
75 RemoveFromInsertList(idparts[1]);
\r
80 m_log->trace("MessageInserter::HandlePutFailed for editioned SSK error code "+message["Code"]+ " id "+message["Identifier"]);
\r
86 const bool MessageInserter::HandlePutSuccessful(FCPv2::Message &message)
\r
89 Poco::DateTime date;
\r
90 int localidentityid;
\r
92 std::vector<std::string> idparts;
\r
94 // do check to make sure this is the non-editioned SSK - we ignore failure/success for editioned SSK for now
\r
95 if(message["Identifier"].find(".xml")!=std::string::npos)
\r
98 StringFunctions::Split(message["Identifier"],"|",idparts);
\r
99 StringFunctions::Convert(idparts[3],index);
\r
100 StringFunctions::Convert(idparts[2],localidentityid);
\r
102 SQLite3DB::Statement st=m_db->Prepare("UPDATE tblMessageInserts SET Day=?, InsertIndex=?, Inserted='true' WHERE MessageUUID=?;");
\r
103 st.Bind(0,idparts[6]);
\r
105 st.Bind(2,idparts[1]);
\r
108 // insert record into temp table so MessageList will be inserted ASAP
\r
109 date=Poco::Timestamp();
\r
110 st=m_db->Prepare("INSERT INTO tmpMessageListInsert(LocalIdentityID,Date) VALUES(?,?);");
\r
111 st.Bind(0,localidentityid);
\r
112 st.Bind(1,Poco::DateTimeFormatter::format(date,"%Y-%m-%d"));
\r
115 // update the messageuuid to the real messageuuid
\r
116 st=m_db->Prepare("SELECT MessageXML FROM tblMessageInserts WHERE MessageUUID=?;");
\r
117 st.Bind(0,idparts[1]);
\r
119 if(st.RowReturned())
\r
121 std::string xmldata="";
\r
122 st.ResultText(0,xmldata);
\r
123 xml.ParseXML(xmldata);
\r
124 xml.SetMessageID(idparts[4]);
\r
126 SQLite3DB::Statement st2=m_db->Prepare("UPDATE tblMessageInserts SET MessageUUID=?, MessageXML=? WHERE MessageUUID=?;");
\r
127 st2.Bind(0,idparts[4]);
\r
128 st2.Bind(1,xml.GetXML());
\r
129 st2.Bind(2,idparts[1]);
\r
132 //update file insert MessageUUID as well
\r
133 st2=m_db->Prepare("UPDATE tblFileInserts SET MessageUUID=? WHERE MessageUUID=?;");
\r
134 st2.Bind(0,idparts[4]);
\r
135 st2.Bind(1,idparts[1]);
\r
139 RemoveFromInsertList(idparts[1]);
\r
141 m_log->debug("MessageInserter::HandlePutSuccessful successfully inserted message "+message["Identifier"]);
\r
146 m_log->debug("MessageInserter::HandlePutSuccessful for editioned SSK "+message["Identifier"]);
\r
152 void MessageInserter::Initialize()
\r
154 m_fcpuniquename="MessageInserter";
\r
157 const bool MessageInserter::StartInsert(const std::string &messageuuid)
\r
159 MessageXML xmlfile;
\r
160 Poco::DateTime now;
\r
161 SQLite3DB::Statement st=m_db->Prepare("SELECT MessageXML,PrivateKey,tblLocalIdentity.LocalIdentityID,PublicKey FROM tblMessageInserts INNER JOIN tblLocalIdentity ON tblMessageInserts.LocalIdentityID=tblLocalIdentity.LocalIdentityID WHERE MessageUUID=?;");
\r
162 st.Bind(0,messageuuid);
\r
165 if(st.RowReturned())
\r
167 int localidentityid;
\r
170 std::string xmlsizestr;
\r
171 std::string privatekey;
\r
172 std::string publickey;
\r
173 FCPv2::Message message;
\r
174 std::string indexstr;
\r
177 st.ResultText(0,xml);
\r
178 st.ResultText(1,privatekey);
\r
179 st.ResultInt(2,localidentityid);
\r
180 st.ResultText(3,publickey);
\r
181 StringFunctions::Convert(localidentityid,idstr);
\r
183 st=m_db->Prepare("SELECT MAX(InsertIndex) FROM tblMessageInserts WHERE Day=? AND LocalIdentityID=?;");
\r
184 st.Bind(0,Poco::DateTimeFormatter::format(now,"%Y-%m-%d"));
\r
185 st.Bind(1,localidentityid);
\r
188 if(st.ResultNull(0)==false)
\r
190 st.ResultInt(0,index);
\r
193 StringFunctions::Convert(index,indexstr);
\r
195 xmlfile.ParseXML(xml);
\r
197 // add file attachments to xml - must do this before we change UUID
\r
198 st=m_db->Prepare("SELECT Key, Size FROM tblFileInserts WHERE MessageUUID=?;");
\r
199 st.Bind(0,xmlfile.GetMessageID());
\r
201 while(st.RowReturned())
\r
203 std::string key="";
\r
206 st.ResultText(0,key);
\r
207 st.ResultInt(1,size);
\r
209 xmlfile.AddFileAttachment(key,size);
\r
214 // recreate messageuuid in xml - UUID of message will not match entry in MessageInserts table until we successfully insert it
\r
215 // see HandlePutSuccessful
\r
216 // if we don't already have an @sskpart - add it
\r
217 if(xmlfile.GetMessageID().find("@")==std::string::npos)
\r
219 // remove - and ~ from publickey part
\r
220 std::string publickeypart=StringFunctions::Replace(StringFunctions::Replace(publickey.substr(4,43),"-",""),"~","");
\r
221 xmlfile.SetMessageID(xmlfile.GetMessageID()+"@"+publickeypart);
\r
223 xml=xmlfile.GetXML();
\r
225 StringFunctions::Convert(xml.size(),xmlsizestr);
\r
227 message.SetName("ClientPut");
\r
228 message["URI"]=privatekey+m_messagebase+"|"+Poco::DateTimeFormatter::format(now,"%Y-%m-%d")+"|Message|"+indexstr+".xml";
\r
229 message["Identifier"]=m_fcpuniquename+"|"+messageuuid+"|"+idstr+"|"+indexstr+"|"+xmlfile.GetMessageID()+"|"+message["URI"];
\r
230 message["UploadFrom"]="direct";
\r
231 message["DataLength"]=xmlsizestr;
\r
232 m_fcp->Send(message);
\r
233 m_fcp->Send(std::vector<char>(xml.begin(),xml.end()));
\r
235 // test insert as editioned SSK
\r
237 message.SetName("ClientPut");
\r
238 message["URI"]=privatekey+m_messagebase+"|"+Poco::DateTimeFormatter::format(now,"%Y-%m-%d")+"|Message-"+indexstr;
\r
239 message["Identifier"]=m_fcpuniquename+"|"+message["URI"];
\r
240 message["UploadFrom"]="direct";
\r
241 message["DataLength"]=xmlsizestr;
\r
242 m_fcp->Send(message);
\r
243 m_fcp->Send(std::vector<char>(xml.begin(),xml.end()));
\r
245 m_inserting.push_back(messageuuid);
\r
247 m_log->debug("MessageInserter::StartInsert started message insert "+message["URI"]);
\r