version 0.3.31
[fms.git] / src / freenet / messagelistrequester.cpp
index c5cb291..e54e0f2 100644 (file)
@@ -1,7 +1,6 @@
 #include "../../include/freenet/messagelistrequester.h"\r
 #include "../../include/freenet/messagelistxml.h"\r
 \r
-#include <Poco/DateTime.h>\r
 #include <Poco/DateTimeFormatter.h>\r
 #include <Poco/DateTimeParser.h>\r
 #include <Poco/Timestamp.h>\r
@@ -73,41 +72,51 @@ const bool MessageListRequester::CheckDateWithinMaxDays(const std::string &dates
        }\r
 }\r
 \r
-void MessageListRequester::GetBoardList(std::map<std::string,bool> &boards)\r
+void MessageListRequester::GetBoardList(std::map<std::string,bool> &boards, const bool forceload)\r
 {\r
-       SQLite3DB::Statement st=m_db->Prepare("SELECT BoardName, SaveReceivedMessages FROM tblBoard;");\r
-       st.Step();\r
-       while(st.RowReturned())\r
+       // only query database when forced, or an 30 minutes have passed since last query\r
+       if(forceload==true || m_boardscacheupdate+Poco::Timespan(0,0,30,0,0)<=Poco::DateTime())\r
        {\r
-               std::string boardname="";\r
-               std::string tempval="";\r
-               st.ResultText(0,boardname);\r
-               st.ResultText(1,tempval);\r
-\r
-               if(tempval=="true")\r
-               {\r
-                       boards[boardname]=true;\r
-               }\r
-               else\r
+               m_boardscache.clear();\r
+               SQLite3DB::Statement st=m_db->Prepare("SELECT BoardName, SaveReceivedMessages FROM tblBoard;");\r
+               st.Step();\r
+               while(st.RowReturned())\r
                {\r
-                       boards[boardname]=false;\r
-               }\r
+                       std::string boardname="";\r
+                       std::string tempval="";\r
+                       st.ResultText(0,boardname);\r
+                       st.ResultText(1,tempval);\r
 \r
-               st.Step();\r
+                       if(tempval=="true")\r
+                       {\r
+                               m_boardscache[boardname]=true;\r
+                       }\r
+                       else\r
+                       {\r
+                               m_boardscache[boardname]=false;\r
+                       }\r
+\r
+                       st.Step();\r
+               }\r
+               m_boardscacheupdate=Poco::DateTime();\r
        }\r
+\r
+       boards=m_boardscache;\r
+\r
 }\r
 \r
 const bool MessageListRequester::HandleAllData(FCPv2::Message &message)\r
 {      \r
        SQLite3DB::Statement st;\r
-       SQLite3DB::Statement trustst;\r
        std::vector<std::string> idparts;\r
        long datalength;\r
        std::vector<char> data;\r
        MessageListXML xml;\r
        long identityid;\r
+       long fromidentityid;\r
        long index;\r
        std::map<std::string,bool> boards;      // list of boards and if we will save messages for that board or not\r
+       std::map<std::string,long> identityids; // list of identity public keys and their id in the database\r
        bool addmessage=false;\r
        std::string boardsstr="";\r
        std::string datestr="";\r
@@ -120,6 +129,8 @@ const bool MessageListRequester::HandleAllData(FCPv2::Message &message)
        StringFunctions::Convert(idparts[1],identityid);\r
        StringFunctions::Convert(idparts[2],index);\r
 \r
+       fromidentityid=identityid;\r
+\r
        // wait for all data to be received from connection\r
        m_fcp->WaitForBytes(1000,datalength);\r
 \r
@@ -138,9 +149,10 @@ const bool MessageListRequester::HandleAllData(FCPv2::Message &message)
 \r
                m_db->Execute("BEGIN;");\r
 \r
-               SQLite3DB::Statement st=m_db->Prepare("SELECT IdentityID FROM tblMessageRequests WHERE IdentityID=? AND Day=? AND RequestIndex=?;");\r
                SQLite3DB::Statement spk=m_db->Prepare("SELECT IdentityID FROM tblIdentity WHERE PublicKey=?;");\r
-               SQLite3DB::Statement mst=m_db->Prepare("INSERT INTO tblMessageRequests(IdentityID,Day,RequestIndex,FromMessageList) VALUES(?,?,?,'true');");\r
+               SQLite3DB::Statement mst=m_db->Prepare("INSERT INTO tblMessageRequests(IdentityID,Day,RequestIndex,FromMessageList,FromIdentityID) VALUES(?,?,?,'true',?);");\r
+               SQLite3DB::Statement ust=m_db->Prepare("UPDATE tblMessageRequests SET FromIdentityID=? WHERE IdentityID=? AND Day=? AND RequestIndex=?;");\r
+\r
                for(long i=0; i<xml.MessageCount(); i++)\r
                {\r
 \r
@@ -182,19 +194,25 @@ const bool MessageListRequester::HandleAllData(FCPv2::Message &message)
 \r
                        if(addmessage==true)\r
                        {\r
-                               st.Bind(0,identityid);\r
-                               st.Bind(1,xml.GetDate(i));\r
-                               st.Bind(2,xml.GetIndex(i));\r
-                               st.Step();\r
-                               if(st.RowReturned()==false)\r
-                               {\r
-                                       mst.Bind(0,identityid);\r
-                                       mst.Bind(1,xml.GetDate(i));\r
-                                       mst.Bind(2,xml.GetIndex(i));\r
-                                       mst.Step();\r
-                                       mst.Reset();\r
-                               }\r
-                               st.Reset();\r
+                               mst.Bind(0,identityid);\r
+                               mst.Bind(1,xml.GetDate(i));\r
+                               mst.Bind(2,xml.GetIndex(i));\r
+                               mst.Bind(3,identityid);\r
+                               mst.Step();\r
+                               mst.Reset();\r
+\r
+                               // We need to update ID here, in case this index was already inserted from another\r
+                               // identity's message list.  This doesn't reset try count - maybe we should if the from\r
+                               // identity was another identity\r
+                               ust.Bind(0,identityid);\r
+                               ust.Bind(1,identityid);\r
+                               ust.Bind(2,xml.GetDate(i));\r
+                               ust.Bind(3,xml.GetIndex(i));\r
+                               ust.Step();\r
+                               ust.Reset();\r
+\r
+                               m_requestindexcache[xml.GetDate(i)][identityid].insert(xml.GetIndex(i));\r
+\r
                        }\r
                        else\r
                        {\r
@@ -245,19 +263,36 @@ const bool MessageListRequester::HandleAllData(FCPv2::Message &message)
 \r
                                if(addmessage==true)\r
                                {\r
-                                       spk.Bind(0,xml.GetExternalIdentity(i));\r
-                                       spk.Step();\r
-                                       if(spk.RowReturned())\r
+                                       int thisidentityid=0;\r
+                                       if(identityids.find(xml.GetExternalIdentity(i))!=identityids.end())\r
+                                       {\r
+                                               thisidentityid=identityids[xml.GetExternalIdentity(i)];\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               spk.Bind(0,xml.GetExternalIdentity(i));\r
+                                               spk.Step();\r
+\r
+                                               if(spk.RowReturned())\r
+                                               {\r
+                                                       spk.ResultInt(0,thisidentityid);\r
+                                                       identityids[xml.GetExternalIdentity(i)]=thisidentityid;\r
+                                               }\r
+\r
+                                               spk.Reset();\r
+                                       }\r
+\r
+                                       if(thisidentityid!=0 && m_requestindexcache[xml.GetExternalDate(i)][thisidentityid].find(xml.GetExternalIndex(i))==m_requestindexcache[xml.GetExternalDate(i)][thisidentityid].end())\r
                                        {\r
-                                               int thisidentityid=0;\r
-                                               spk.ResultInt(0,thisidentityid);\r
                                                mst.Bind(0,thisidentityid);\r
                                                mst.Bind(1,xml.GetExternalDate(i));\r
                                                mst.Bind(2,xml.GetExternalIndex(i));\r
+                                               mst.Bind(3,fromidentityid);\r
                                                mst.Step();\r
                                                mst.Reset();\r
+\r
+                                               m_requestindexcache[xml.GetExternalDate(i)][thisidentityid].insert(xml.GetExternalIndex(i));\r
                                        }\r
-                                       spk.Reset();\r
                                }\r
                                else\r
                                {\r
@@ -273,6 +308,10 @@ const bool MessageListRequester::HandleAllData(FCPv2::Message &message)
                st.Step();\r
                st.Finalize();\r
 \r
+               spk.Finalize();\r
+               mst.Finalize();\r
+               ust.Finalize();\r
+\r
                m_db->Execute("COMMIT;");\r
 \r
                m_log->debug(m_fcpuniquename+"::HandleAllData parsed MessageList XML file : "+message["Identifier"]);\r
@@ -293,6 +332,12 @@ const bool MessageListRequester::HandleAllData(FCPv2::Message &message)
        // remove this identityid from request list\r
        RemoveFromRequestList(identityid);\r
 \r
+       // keep 2 days of request indexes in the cache\r
+       while(m_requestindexcache.size()>2)\r
+       {\r
+               m_requestindexcache.erase(m_requestindexcache.begin());\r
+       }\r
+\r
        return true;\r
 \r
 }\r
@@ -383,6 +428,8 @@ void MessageListRequester::Initialize()
        option.Get("MessageDownloadMaxDaysBackward",tempval);\r
        StringFunctions::Convert(tempval,m_messagedownloadmaxdaysbackward);\r
 \r
+       m_boardscacheupdate=Poco::DateTime()-Poco::Timespan(1,0,0,0,0);\r
+\r
 }\r
 \r
 void MessageListRequester::PopulateIDList()\r
@@ -396,11 +443,11 @@ void MessageListRequester::PopulateIDList()
        // select identities we want to query (we've seen them today) - sort by their trust level (descending) with secondary sort on how long ago we saw them (ascending)\r
        if(m_localtrustoverrides==false)\r
        {\r
-               st=m_db->Prepare("SELECT tblIdentity.IdentityID FROM tblIdentity INNER JOIN vwIdentityStats ON tblIdentity.IdentityID=vwIdentityStats.IdentityID WHERE PublicKey IS NOT NULL AND PublicKey <> '' AND LastSeen>='"+Poco::DateTimeFormatter::format(date,"%Y-%m-%d")+"' AND (vwIdentityStats.LastMessageDate>='"+Poco::DateTimeFormatter::format(yesterday,"%Y-%m-%d")+"') AND (LocalMessageTrust IS NULL OR LocalMessageTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinLocalMessageTrust')) AND (PeerMessageTrust IS NULL OR PeerMessageTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinPeerMessageTrust')) ORDER BY LocalMessageTrust+LocalTrustListTrust DESC, LastSeen;");\r
+               st=m_db->Prepare("SELECT tblIdentity.IdentityID FROM tblIdentity INNER JOIN vwIdentityStats ON tblIdentity.IdentityID=vwIdentityStats.IdentityID WHERE PublicKey IS NOT NULL AND PublicKey <> '' AND LastSeen>='"+Poco::DateTimeFormatter::format(date,"%Y-%m-%d")+"' AND (vwIdentityStats.LastMessageDate>='"+Poco::DateTimeFormatter::format(yesterday,"%Y-%m-%d")+"') AND (LocalMessageTrust IS NULL OR LocalMessageTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinLocalMessageTrust')) AND (PeerMessageTrust IS NULL OR PeerMessageTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinPeerMessageTrust')) AND FailureCount<=(SELECT OptionValue FROM tblOption WHERE Option='MaxFailureCount') ORDER BY LocalMessageTrust+LocalTrustListTrust DESC, LastSeen;");\r
        }\r
        else\r
        {\r
-               st=m_db->Prepare("SELECT tblIdentity.IdentityID FROM tblIdentity INNER JOIN vwIdentityStats ON tblIdentity.IdentityID=vwIdentityStats.IdentityID WHERE PublicKey IS NOT NULL AND PublicKey <> '' AND LastSeen>='"+Poco::DateTimeFormatter::format(date,"%Y-%m-%d")+"' AND (vwIdentityStats.LastMessageDate>='"+Poco::DateTimeFormatter::format(yesterday,"%Y-%m-%d")+"') AND (LocalMessageTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinLocalMessageTrust') OR (LocalMessageTrust IS NULL AND (PeerMessageTrust IS NULL OR PeerMessageTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinPeerMessageTrust')))) ORDER BY LocalMessageTrust+LocalTrustListTrust DESC, LastSeen;");\r
+               st=m_db->Prepare("SELECT tblIdentity.IdentityID FROM tblIdentity INNER JOIN vwIdentityStats ON tblIdentity.IdentityID=vwIdentityStats.IdentityID WHERE PublicKey IS NOT NULL AND PublicKey <> '' AND LastSeen>='"+Poco::DateTimeFormatter::format(date,"%Y-%m-%d")+"' AND (vwIdentityStats.LastMessageDate>='"+Poco::DateTimeFormatter::format(yesterday,"%Y-%m-%d")+"') AND (LocalMessageTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinLocalMessageTrust') OR (LocalMessageTrust IS NULL AND (PeerMessageTrust IS NULL OR PeerMessageTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinPeerMessageTrust')))) AND FailureCount<=(SELECT OptionValue FROM tblOption WHERE Option='MaxFailureCount') ORDER BY LocalMessageTrust+LocalTrustListTrust DESC, LastSeen;");\r
        }\r
        st.Step();\r
 \r