version 0.1.14
[fms.git] / src / freenet / messagelistinserter.cpp
1 #include "../../include/freenet/messagelistinserter.h"\r
2 #include "../../include/freenet/messagexml.h"\r
3 #include "../../include/freenet/messagelistxml.h"\r
4 \r
5 #ifdef XMEM\r
6         #include <xmem.h>\r
7 #endif\r
8 \r
9 MessageListInserter::MessageListInserter()\r
10 {\r
11         Initialize();\r
12 }\r
13 \r
14 MessageListInserter::MessageListInserter(FCPv2 *fcp):IIndexInserter<long>(fcp)\r
15 {\r
16         Initialize();\r
17 }\r
18 \r
19 void MessageListInserter::CheckForNeededInsert()\r
20 {\r
21         // only do 1 insert at a time\r
22         if(m_inserting.size()==0)\r
23         {\r
24                 std::string sql;\r
25                 DateTime now;\r
26                 DateTime previous;\r
27 \r
28                 now.SetToGMTime();\r
29                 previous.SetToGMTime();\r
30 \r
31                 previous.Add(0,0,0,-m_daysbackward);\r
32 \r
33                 // query for identities that have messages in the past X days and (we haven't inserted lists for in the past 30 minutes OR identity has a record in tmpMessageListInsert)\r
34                 sql="SELECT tblLocalIdentity.LocalIdentityID ";\r
35                 sql+="FROM tblLocalIdentity INNER JOIN tblMessageInserts ON tblLocalIdentity.LocalIdentityID=tblMessageInserts.LocalIdentityID ";\r
36                 sql+="WHERE tblMessageInserts.Day>=? AND ((tblLocalIdentity.LastInsertedMessageList<=? OR tblLocalIdentity.LastInsertedMessageList IS NULL OR tblLocalIdentity.LastInsertedMessageList='') OR tblLocalIdentity.LocalIdentityID IN (SELECT LocalIdentityID FROM tmpMessageListInsert)) ";\r
37                 sql+=";";\r
38 \r
39                 SQLite3DB::Statement st=m_db->Prepare(sql);\r
40                 st.Bind(0,previous.Format("%Y-%m-%d"));\r
41                 st.Bind(1,(now-(1.0/48.0)).Format("%Y-%m-%d %H:%M:%S"));\r
42                 st.Step();\r
43 \r
44                 if(st.RowReturned())\r
45                 {\r
46                         int localidentityid;\r
47                         st.ResultInt(0,localidentityid);\r
48                         StartInsert(localidentityid);\r
49                 }\r
50         }\r
51 \r
52 }\r
53 \r
54 const bool MessageListInserter::HandlePutFailed(FCPMessage &message)\r
55 {\r
56         std::vector<std::string> idparts;\r
57         long localidentityid;\r
58         long index;\r
59 \r
60         StringFunctions::Split(message["Identifier"],"|",idparts);\r
61         StringFunctions::Convert(idparts[1],localidentityid);\r
62         StringFunctions::Convert(idparts[2],index);\r
63 \r
64         if(message["Fatal"]=="true" || message["Code"]=="9")\r
65         {\r
66                 SQLite3DB::Statement st=m_db->Prepare("INSERT INTO tblMessageListInserts(LocalIdentityID,Day,InsertIndex,Inserted) VALUES(?,?,?,'false');");\r
67                 st.Bind(0,localidentityid);\r
68                 st.Bind(1,idparts[4]);\r
69                 st.Bind(2,index);\r
70                 st.Step();\r
71         }\r
72 \r
73         RemoveFromInsertList(localidentityid);\r
74 \r
75         return true;\r
76 \r
77 }\r
78 \r
79 const bool MessageListInserter::HandlePutSuccessful(FCPMessage &message)\r
80 {\r
81         DateTime now;\r
82         std::vector<std::string> idparts;\r
83         long localidentityid;\r
84         long index;\r
85 \r
86         StringFunctions::Split(message["Identifier"],"|",idparts);\r
87         StringFunctions::Convert(idparts[1],localidentityid);\r
88         StringFunctions::Convert(idparts[2],index);\r
89 \r
90         SQLite3DB::Statement st=m_db->Prepare("INSERT INTO tblMessageListInserts(LocalIdentityID,Day,InsertIndex,Inserted) VALUES(?,?,?,'true');");\r
91         st.Bind(0,localidentityid);\r
92         st.Bind(1,idparts[4]);\r
93         st.Bind(2,index);\r
94         st.Step();\r
95 \r
96         now.SetToGMTime();\r
97         st=m_db->Prepare("UPDATE tblLocalIdentity SET LastInsertedMessageList=? WHERE LocalIdentityID=?;");\r
98         st.Bind(0,now.Format("%Y-%m-%d %H:%M:%S"));\r
99         st.Bind(1,localidentityid);\r
100         st.Step();\r
101 \r
102         // delete any record from tmpMessageListInsert\r
103         st=m_db->Prepare("DELETE FROM tmpMessageListInsert WHERE LocalIdentityID=?;");\r
104         st.Bind(0,localidentityid);\r
105         st.Step();\r
106 \r
107         RemoveFromInsertList(localidentityid);\r
108 \r
109         m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"MessageListInserter::HandlePutSuccessful successfully inserted MessageList.");\r
110 \r
111         return true;\r
112 }\r
113 \r
114 void MessageListInserter::Initialize()\r
115 {\r
116         std::string tempval;\r
117 \r
118         m_fcpuniquename="MessageListInserter";\r
119         m_daysbackward=0;\r
120         Option::Instance()->Get("MessageListDaysBackward",tempval);\r
121         StringFunctions::Convert(tempval,m_daysbackward);\r
122 }\r
123 \r
124 void MessageListInserter::StartInsert(const long &localidentityid)\r
125 {\r
126         FCPMessage message;\r
127         DateTime date;\r
128         DateTime now;\r
129         std::string privatekey;\r
130         std::string localidentityidstr;\r
131         MessageListXML mlxml;\r
132         MessageXML messxml;\r
133         std::string xmlstr;\r
134         std::string xmlsizestr;\r
135         int index;\r
136         std::string indexstr;\r
137 \r
138         now.SetToGMTime();\r
139         date.SetToGMTime();\r
140         date.Add(0,0,0,-m_daysbackward);\r
141         StringFunctions::Convert(localidentityid,localidentityidstr);\r
142 \r
143         SQLite3DB::Statement st=m_db->Prepare("SELECT Day, InsertIndex, MessageXML, PrivateKey FROM tblMessageInserts INNER JOIN tblLocalIdentity ON tblMessageInserts.LocalIdentityID=tblLocalIdentity.LocalIdentityID WHERE tblLocalIdentity.LocalIdentityID=? AND Day>=?;");\r
144         st.Bind(0,localidentityid);\r
145         st.Bind(1,date.Format("%Y-%m-%d"));\r
146         st.Step();\r
147 \r
148         while(st.RowReturned())\r
149         {\r
150                 std::string day;\r
151                 int index;\r
152                 std::string xmlstr;\r
153                 std::vector<std::string> boards;\r
154 \r
155                 st.ResultText(0,day);\r
156                 st.ResultInt(1,index);\r
157                 st.ResultText(2,xmlstr);\r
158                 st.ResultText(3,privatekey);\r
159 \r
160                 messxml.ParseXML(xmlstr);\r
161 \r
162                 mlxml.AddMessage(day,index,messxml.GetBoards());\r
163 \r
164                 st.Step();\r
165         }\r
166         st.Finalize();\r
167 \r
168 \r
169         st=m_db->Prepare("SELECT MessageDate, MessageIndex, PublicKey, MessageID FROM tblMessage INNER JOIN tblIdentity ON tblMessage.IdentityID=tblIdentity.IdentityID WHERE MessageIndex IS NOT NULL ORDER BY MessageDate DESC, MessageTime DESC LIMIT 100;");\r
170         SQLite3DB::Statement st2=m_db->Prepare("SELECT BoardName FROM tblBoard INNER JOIN tblMessageBoard ON tblBoard.BoardID=tblMessageBoard.BoardID WHERE tblMessageBoard.MessageID=?;");\r
171         st.Step();\r
172         while(st.RowReturned())\r
173         {\r
174                 std::string day;\r
175                 int index;\r
176                 std::string publickey;\r
177                 std::vector<std::string> boardlist;\r
178                 int messageid;\r
179                 \r
180                 st.ResultText(0,day);\r
181                 st.ResultInt(1,index);\r
182                 st.ResultText(2,publickey);\r
183                 st.ResultInt(3,messageid);\r
184 \r
185                 st2.Bind(0,messageid);\r
186                 st2.Step();\r
187                 while(st2.RowReturned())\r
188                 {\r
189                         std::string boardname="";\r
190                         st2.ResultText(0,boardname);\r
191                         StringFunctions::LowerCase(boardname,boardname);\r
192                         boardlist.push_back(boardname);\r
193                         st2.Step();\r
194                 }\r
195                 st2.Reset();\r
196 \r
197                 mlxml.AddExternalMessage(publickey,day,index,boardlist);\r
198 \r
199                 st.Step();\r
200         }\r
201 \r
202         // get last inserted messagelist index for this day\r
203         index=0;\r
204         st=m_db->Prepare("SELECT MAX(InsertIndex) FROM tblMessageListInserts WHERE LocalIdentityID=? AND Day=?;");\r
205         st.Bind(0,localidentityid);\r
206         st.Bind(1,now.Format("%Y-%m-%d"));\r
207         st.Step();\r
208         if(st.ResultNull(0)==false)\r
209         {\r
210                 st.ResultInt(0,index);\r
211                 index++;\r
212         }\r
213         StringFunctions::Convert(index,indexstr);\r
214 \r
215         // actually insert message\r
216         xmlstr=mlxml.GetXML();\r
217         StringFunctions::Convert(xmlstr.size(),xmlsizestr);\r
218 \r
219         message.SetName("ClientPut");\r
220         message["URI"]=privatekey+m_messagebase+"|"+now.Format("%Y-%m-%d")+"|MessageList|"+indexstr+".xml";\r
221         message["Identifier"]=m_fcpuniquename+"|"+localidentityidstr+"|"+indexstr+"|"+message["URI"];\r
222         message["UploadFrom"]="direct";\r
223         message["DataLength"]=xmlsizestr;\r
224         m_fcp->SendMessage(message);\r
225         m_fcp->SendRaw(xmlstr.c_str(),xmlstr.size());\r
226 \r
227         m_inserting.push_back(localidentityid);\r
228 \r
229 }\r