version 0.1.12
[fms.git] / src / freenet / messageinserter.cpp
1 #include "../../include/freenet/messageinserter.h"\r
2 #include "../../include/freenet/messagexml.h"\r
3 \r
4 MessageInserter::MessageInserter()\r
5 {\r
6         Initialize();\r
7 }\r
8 \r
9 MessageInserter::MessageInserter(FCPv2 *fcp):IIndexInserter<std::string>(fcp)\r
10 {\r
11         Initialize();\r
12 }\r
13 \r
14 void MessageInserter::CheckForNeededInsert()\r
15 {\r
16         // only do 1 insert at a time\r
17         if(m_inserting.size()==0)\r
18         {\r
19                 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';");\r
20                 st.Step();\r
21 \r
22                 if(st.RowReturned())\r
23                 {\r
24                         std::string messageuuid;\r
25                         st.ResultText(0,messageuuid);\r
26                         StartInsert(messageuuid);\r
27                 }\r
28         }\r
29 }\r
30 \r
31 const bool MessageInserter::HandlePutFailed(FCPMessage &message)\r
32 {\r
33         int index;\r
34         int localidentityid;\r
35         std::vector<std::string> idparts;\r
36         StringFunctions::Split(message["Identifier"],"|",idparts);\r
37         StringFunctions::Convert(idparts[2],localidentityid);\r
38         StringFunctions::Convert(idparts[3],index);\r
39 \r
40         // fatal put - or data exists - insert bogus index into database so we'll try to insert this message again\r
41         if(message["Fatal"]=="true" || message["Code"]=="9")\r
42         {\r
43                 SQLite3DB::Statement st=m_db->Prepare("INSERT INTO tblMessageInserts(LocalIdentityID,Day,InsertIndex,Inserted) VALUES(?,?,?,'true');");\r
44                 st.Bind(0,localidentityid);\r
45                 st.Bind(1,idparts[6]);\r
46                 st.Bind(2,index);\r
47                 st.Step();\r
48         }\r
49 \r
50         RemoveFromInsertList(idparts[1]);\r
51 \r
52         return true;\r
53 }\r
54 \r
55 const bool MessageInserter::HandlePutSuccessful(FCPMessage &message)\r
56 {\r
57         MessageXML xml;\r
58         DateTime date;\r
59         int localidentityid;\r
60         int index;\r
61         std::vector<std::string> idparts;\r
62         StringFunctions::Split(message["Identifier"],"|",idparts);\r
63         StringFunctions::Convert(idparts[3],index);\r
64         StringFunctions::Convert(idparts[2],localidentityid);\r
65 \r
66         SQLite3DB::Statement st=m_db->Prepare("UPDATE tblMessageInserts SET Day=?, InsertIndex=?, Inserted='true' WHERE MessageUUID=?;");\r
67         st.Bind(0,idparts[6]);\r
68         st.Bind(1,index);\r
69         st.Bind(2,idparts[1]);\r
70         st.Step();\r
71 \r
72         // insert record into temp table so MessageList will be inserted ASAP\r
73         date.SetToGMTime();\r
74         st=m_db->Prepare("INSERT INTO tmpMessageListInsert(LocalIdentityID,Date) VALUES(?,?);");\r
75         st.Bind(0,localidentityid);\r
76         st.Bind(1,date.Format("%Y-%m-%d"));\r
77         st.Step();\r
78 \r
79         // update the messageuuid to the real messageuuid\r
80         st=m_db->Prepare("SELECT MessageXML FROM tblMessageInserts WHERE MessageUUID=?;");\r
81         st.Bind(0,idparts[1]);\r
82         st.Step();\r
83         if(st.RowReturned())\r
84         {\r
85                 std::string xmldata="";\r
86                 st.ResultText(0,xmldata);\r
87                 xml.ParseXML(xmldata);\r
88                 xml.SetMessageID(idparts[4]);\r
89 \r
90                 SQLite3DB::Statement st2=m_db->Prepare("UPDATE tblMessageInserts SET MessageUUID=?, MessageXML=? WHERE MessageUUID=?;");\r
91                 st2.Bind(0,idparts[4]);\r
92                 st2.Bind(1,xml.GetXML());\r
93                 st2.Bind(2,idparts[1]);\r
94                 st2.Step();\r
95         }\r
96 \r
97         RemoveFromInsertList(idparts[1]);\r
98 \r
99         m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"MessageInserter::HandlePutSuccessful successfully inserted message "+message["Identifier"]);\r
100 \r
101         return true;\r
102 }\r
103 \r
104 void MessageInserter::Initialize()\r
105 {\r
106         m_fcpuniquename="MessageInserter";\r
107 }\r
108 \r
109 void MessageInserter::StartInsert(const std::string &messageuuid)\r
110 {\r
111         MessageXML xmlfile;\r
112         DateTime now;\r
113         now.SetToGMTime();\r
114         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
115         st.Bind(0,messageuuid);\r
116         st.Step();\r
117 \r
118         if(st.RowReturned())\r
119         {\r
120                 int localidentityid;\r
121                 std::string idstr;\r
122                 std::string xml;\r
123                 std::string xmlsizestr;\r
124                 std::string privatekey;\r
125                 std::string publickey;\r
126                 FCPMessage message;\r
127                 std::string indexstr;\r
128                 int index=0;\r
129                 \r
130                 st.ResultText(0,xml);\r
131                 st.ResultText(1,privatekey);\r
132                 st.ResultInt(2,localidentityid);\r
133                 st.ResultText(3,publickey);\r
134                 StringFunctions::Convert(localidentityid,idstr);\r
135 \r
136                 st=m_db->Prepare("SELECT MAX(InsertIndex) FROM tblMessageInserts WHERE Day=? AND LocalIdentityID=?;");\r
137                 st.Bind(0,now.Format("%Y-%m-%d"));\r
138                 st.Bind(1,localidentityid);\r
139                 st.Step();\r
140 \r
141                 if(st.ResultNull(0)==false)\r
142                 {\r
143                         st.ResultInt(0,index);\r
144                         index++;\r
145                 }\r
146                 StringFunctions::Convert(index,indexstr);\r
147 \r
148                 // recreate messageuuid in xml - UUID of message will not match entry in MessageInserts table until we successfully insert it\r
149                 // see HandlePutSuccessful\r
150                 xmlfile.ParseXML(xml);\r
151                 // if we don't already have an @sskpart - add it\r
152                 if(xmlfile.GetMessageID().find("@")==std::string::npos)\r
153                 {\r
154                         // remove - and ~ from publickey part\r
155                         std::string publickeypart=StringFunctions::Replace(StringFunctions::Replace(publickey.substr(4,43),"-",""),"~","");\r
156                         xmlfile.SetMessageID(xmlfile.GetMessageID()+"@"+publickeypart);\r
157                 }\r
158                 xml=xmlfile.GetXML();\r
159 \r
160                 StringFunctions::Convert(xml.size(),xmlsizestr);\r
161 \r
162                 message.SetName("ClientPut");\r
163                 message["URI"]=privatekey+m_messagebase+"|"+now.Format("%Y-%m-%d")+"|Message|"+indexstr+".xml";\r
164                 message["Identifier"]=m_fcpuniquename+"|"+messageuuid+"|"+idstr+"|"+indexstr+"|"+xmlfile.GetMessageID()+"|"+message["URI"];\r
165                 message["UploadFrom"]="direct";\r
166                 message["DataLength"]=xmlsizestr;\r
167                 m_fcp->SendMessage(message);\r
168                 m_fcp->SendRaw(xml.c_str(),xml.size());\r
169 \r
170                 m_inserting.push_back(messageuuid);\r
171 \r
172                 m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"MessageInserter::StartInsert started message insert "+message["URI"]);\r
173         }\r
174 \r
175 }\r