version 0.3.26
[fms.git] / src / dbsetup.cpp
index bc197cc..e6065f7 100644 (file)
@@ -15,14 +15,8 @@ void SetupDB()
        SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
 \r
        db->Open("fms.db3");\r
-       db->SetBusyTimeout(10000);              // set timeout to 10 seconds\r
-\r
-       tempval="";\r
-       Option::Instance()->Get("VacuumOnStartup",tempval);\r
-       if(tempval=="true")\r
-       {\r
-               db->Execute("VACUUM;");\r
-       }\r
+       db->SetBusyTimeout(20000);              // set timeout to 20 seconds\r
+       db->Execute("PRAGMA synchronous = FULL;");\r
 \r
        db->Execute("CREATE TABLE IF NOT EXISTS tblDBVersion(\\r
                                Major                           INTEGER,\\r
@@ -104,13 +98,37 @@ void SetupDB()
                        major=1;\r
                        minor=12;\r
                }\r
+               if(major==1 && minor==12)\r
+               {\r
+                       ConvertDB0112To0113();\r
+                       major=1;\r
+                       minor=13;\r
+               }\r
+               if(major==1 && minor==13)\r
+               {\r
+                       ConvertDB0113To0114();\r
+                       major=1;\r
+                       minor=14;\r
+               }\r
        }\r
        else\r
        {\r
-               db->Execute("INSERT INTO tblDBVersion(Major,Minor) VALUES(1,12);");\r
+               db->Execute("INSERT INTO tblDBVersion(Major,Minor) VALUES(1,14);");\r
        }\r
 \r
-       db->Execute("UPDATE tblDBVersion SET Major=1, Minor=12;");\r
+       db->Execute("UPDATE tblDBVersion SET Major=1, Minor=14;");\r
+\r
+       db->Execute("CREATE TABLE IF NOT EXISTS tblFMSVersion(\\r
+                               Major                           INTEGER,\\r
+                               Minor                           INTEGER,\\r
+                               Release                         INTEGER,\\r
+                               Notes                           TEXT,\\r
+                               Changes                         TEXT,\\r
+                               PageKey                         TEXT,\\r
+                               SourceKey                       TEXT\\r
+                               );");\r
+\r
+       db->Execute("CREATE UNIQUE INDEX IF NOT EXISTS idxFMSVersion_Version ON tblFMSVersion(Major,Minor,Release);");\r
 \r
        db->Execute("CREATE TABLE IF NOT EXISTS tblOption(\\r
                                Option                          TEXT UNIQUE,\\r
@@ -176,6 +194,9 @@ void SetupDB()
                                FoundSolution           BOOL CHECK(FoundSolution IN('true','false')) DEFAULT 'false'\\r
                                );");\r
 \r
+       /*\r
+               PurgeDate is not used yet\r
+       */\r
        db->Execute("CREATE TABLE IF NOT EXISTS tblIdentity(\\r
                                IdentityID                              INTEGER PRIMARY KEY,\\r
                                PublicKey                               TEXT UNIQUE,\\r
@@ -268,13 +289,14 @@ void SetupDB()
                                BoardDescription                TEXT,\\r
                                DateAdded                               DATETIME,\\r
                                SaveReceivedMessages    BOOL CHECK(SaveReceivedMessages IN('true','false')) DEFAULT 'true',\\r
-                               AddedMethod                             TEXT\\r
+                               AddedMethod                             TEXT,\\r
+                               Forum                                   TEXT CHECK(Forum IN('true','false')) DEFAULT 'false'\\r
                                );");\r
 \r
-       db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded,AddedMethod) VALUES('fms','Freenet Message System','2007-12-01 12:00:00','Initial Board');");\r
-       db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded,AddedMethod) VALUES('freenet','Discussion about Freenet','2007-12-01 12:00:00','Initial Board');");\r
-       db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded,AddedMethod) VALUES('public','Public discussion','2007-12-01 12:00:00','Initial Board');");\r
-       db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded,AddedMethod) VALUES('test','Test board','2007-12-01 12:00:00','Initial Board');");\r
+       db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded,AddedMethod,Forum) VALUES('fms','Freenet Message System','2007-12-01 12:00:00','Initial Board','true');");\r
+       db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded,AddedMethod,Forum) VALUES('freenet','Discussion about Freenet','2007-12-01 12:00:00','Initial Board','true');");\r
+       db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded,AddedMethod,Forum) VALUES('public','Public discussion','2007-12-01 12:00:00','Initial Board','true');");\r
+       db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded,AddedMethod,Forum) VALUES('test','Test board','2007-12-01 12:00:00','Initial Board','true');");\r
 \r
        db->Execute("CREATE TABLE IF NOT EXISTS tblMessage(\\r
                                MessageID                       INTEGER PRIMARY KEY,\\r
@@ -286,7 +308,8 @@ void SetupDB()
                                MessageUUID                     TEXT UNIQUE,\\r
                                ReplyBoardID            INTEGER,\\r
                                Body                            TEXT,\\r
-                               MessageIndex            INTEGER\\r
+                               MessageIndex            INTEGER,\\r
+                               Read                            INTEGER CHECK(Read IN(0,1)) DEFAULT 0\\r
                                );");\r
 \r
        db->Execute("CREATE INDEX IF NOT EXISTS idxMessage_IdentityID ON tblMessage (IdentityID);");\r
@@ -298,6 +321,7 @@ void SetupDB()
                                );");\r
 \r
        db->Execute("CREATE INDEX IF NOT EXISTS idxMessageReplyTo_MessageID ON tblMessageReplyTo (MessageID);");\r
+       db->Execute("CREATE INDEX IF NOT EXISTS idxMessageReplyTo_ReplyToMessageUUID ON tblMessageReplyTo (ReplyToMessageUUID);");\r
 \r
        db->Execute("CREATE TABLE IF NOT EXISTS tblMessageBoard(\\r
                                MessageID                       INTEGER,\\r
@@ -314,12 +338,17 @@ void SetupDB()
                                Found                           BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\\r
                                );");\r
 \r
+       /*\r
+               Key is for anonymous messages (future)\r
+       */\r
        db->Execute("CREATE TABLE IF NOT EXISTS tblMessageRequests(\\r
                                IdentityID                      INTEGER,\\r
                                Day                                     DATE,\\r
                                RequestIndex            INTEGER,\\r
                                FromMessageList         BOOL CHECK(FromMessageList IN('true','false')) DEFAULT 'false',\\r
-                               Found                           BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\\r
+                               Found                           BOOL CHECK(Found IN('true','false')) DEFAULT 'false',\\r
+                               Tries                           INTEGER DEFAULT 0,\\r
+                               Key                                     TEXT\\r
                                );");\r
 \r
        db->Execute("CREATE UNIQUE INDEX IF NOT EXISTS idxMessageRequest ON tblMessageRequests(IdentityID,Day,RequestIndex);");\r
@@ -369,7 +398,35 @@ void SetupDB()
                                Day                                     DATE,\\r
                                RequestIndex            INTEGER,\\r
                                Found                           BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\\r
-                               );");   \r
+                               );");\r
+\r
+       // begin thread db schema\r
+       db->Execute("CREATE TABLE IF NOT EXISTS tblThread(\\r
+                               ThreadID                INTEGER PRIMARY KEY,\\r
+                               BoardID                 INTEGER,\\r
+                               FirstMessageID  INTEGER,\\r
+                               LastMessageID   INTEGER\\r
+                               );");\r
+\r
+       db->Execute("CREATE INDEX IF NOT EXISTS idxThread_BoardID ON tblThread(BoardID);");\r
+       db->Execute("CREATE INDEX IF NOT EXISTS idxThread_FirstMessageID ON tblThread(FirstMessageID);");\r
+       db->Execute("CREATE INDEX IF NOT EXISTS idxThread_LastMessageID ON tblThread(LastMessageID);");\r
+\r
+       db->Execute("CREATE TABLE IF NOT EXISTS tblThreadPost(\\r
+                               ThreadID                INTEGER,\\r
+                               MessageID               INTEGER,\\r
+                               PostOrder               INTEGER\\r
+                               );");\r
+\r
+       db->Execute("CREATE INDEX IF NOT EXISTS idxThreadPost_ThreadID ON tblThreadPost(ThreadID);");\r
+       db->Execute("CREATE INDEX IF NOT EXISTS idxThreadPost_MessageID ON tblThreadPost(MessageID);");\r
+\r
+       db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteOnThread AFTER DELETE ON tblThread\\r
+                               FOR EACH ROW\\r
+                               BEGIN\\r
+                                       DELETE FROM tblThreadPost WHERE ThreadID=old.ThreadID;\\r
+                               END;");\r
+       // end thread db schema\r
 \r
        // MessageInserter will insert a record into this temp table which the MessageListInserter will query for and insert a MessageList when needed\r
        db->Execute("CREATE TEMPORARY TABLE IF NOT EXISTS tmpMessageListInsert(\\r
@@ -382,6 +439,12 @@ void SetupDB()
                                LocalIdentityID         INTEGER\\r
                                );");\r
 \r
+       // Temporary table for form passwords\r
+       db->Execute("CREATE TEMPORARY TABLE IF NOT EXISTS tmpFormPassword(\\r
+                               Date                    DATETIME,\\r
+                               Password                TEXT\\r
+                               );");\r
+\r
        // low / high / message count for each board\r
        db->Execute("CREATE VIEW IF NOT EXISTS vwBoardStats AS \\r
                                SELECT tblBoard.BoardID AS 'BoardID', IFNULL(MIN(MessageID),0) AS 'LowMessageID', IFNULL(MAX(MessageID),0) AS 'HighMessageID', COUNT(MessageID) AS 'MessageCount' \\r
@@ -499,10 +562,10 @@ void SetupDB()
        db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded,LocalTrustListTrust,AddedMethod) VALUES('SSK@NuBL7aaJ6Cn4fB7GXFb9Zfi8w1FhPyW3oKgU9TweZMw,iXez4j3qCpd596TxXiJgZyTq9o-CElEuJxm~jNNZAuA,AQACAAE/','"+Poco::DateTimeFormatter::format(date,"%Y-%m-%d %H:%M:%S")+"',50,'Initial Identity');");\r
        // insert Shadow Panther's public key - haven't seen in a while - disabling for now\r
        //db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded,AddedMethod) VALUES('SSK@~mimyB1kmH4f7Cgsd2wM2Qv2NxrZHRMM6IY8~7EWRVQ,fxTKkR0TYhgMYb-vEGAv55sMOxCGD2xhE4ZxWHxdPz4,AQACAAE/','"+Poco::DateTimeFormatter::format(date,"%Y-%m-%d %H:%M:%S")+"','Initial Identity');");\r
-       // insert garfield's public key\r
-       db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded,AddedMethod) VALUES('SSK@T8l1IEGU4-PoASFzgc2GYhIgRzUvZsKdoQWeuLHuTmM,QLxAPfkGis8l5NafNpSCdbxzXhBlu9WL8svcqJw9Mpo,AQACAAE/','"+Poco::DateTimeFormatter::format(date,"%Y-%m-%d %H:%M:%S")+"','Initial Identity');");\r
-       // insert alek's public key\r
-       db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded,AddedMethod) VALUES('SSK@lTjeI6V0lQsktXqaqJ6Iwk4TdsHduQI54rdUpHfhGbg,0oTYfrxxx8OmdU1~60gqpf3781qzEicM4Sz97mJsBM4,AQACAAE/','"+Poco::DateTimeFormatter::format(date,"%Y-%m-%d %H:%M:%S")+"','Initial Identity');");\r
+       // insert garfield's public key -haven't seen in a while - disabling for now\r
+       //db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded,AddedMethod) VALUES('SSK@T8l1IEGU4-PoASFzgc2GYhIgRzUvZsKdoQWeuLHuTmM,QLxAPfkGis8l5NafNpSCdbxzXhBlu9WL8svcqJw9Mpo,AQACAAE/','"+Poco::DateTimeFormatter::format(date,"%Y-%m-%d %H:%M:%S")+"','Initial Identity');");\r
+       // insert alek's public key - haven't seen in a while - disabling for now\r
+       //db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded,AddedMethod) VALUES('SSK@lTjeI6V0lQsktXqaqJ6Iwk4TdsHduQI54rdUpHfhGbg,0oTYfrxxx8OmdU1~60gqpf3781qzEicM4Sz97mJsBM4,AQACAAE/','"+Poco::DateTimeFormatter::format(date,"%Y-%m-%d %H:%M:%S")+"','Initial Identity');");\r
        // insert Luke771's public key\r
        db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded,AddedMethod) VALUES('SSK@mdXK~ZVlfTZhF1SLBrvZ--i0vOsOpa~w9wv~~psQ-04,gXonsXKc7aexKSO8Gt8Fwre4Qgmmbt2WueO7VzxNKkk,AQACAAE/','"+Poco::DateTimeFormatter::format(date,"%Y-%m-%d %H:%M:%S")+"','Initial Identity');");\r
        // insert falafel's public key\r
@@ -523,3 +586,61 @@ void SetupDB()
        db->Execute("ANALYZE;");\r
 \r
 }\r
+\r
+const bool VerifyDB()\r
+{\r
+       SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
+       SQLite3DB::Statement st=db->Prepare("PRAGMA integrity_check;");\r
+       st.Step();\r
+       if(st.RowReturned())\r
+       {\r
+               std::string res="";\r
+               st.ResultText(0,res);\r
+               if(res=="ok")\r
+               {\r
+                       return true;\r
+               }\r
+               else\r
+               {\r
+                       // try to reindex and vacuum database in case of index corruption\r
+                       st=db->Prepare("REINDEX;");\r
+                       st.Step();\r
+                       st=db->Prepare("VACUUM;");\r
+                       st.Step();\r
+\r
+                       // check integrity again\r
+                       st=db->Prepare("PRAGMA integrity_check;");\r
+                       st.Step();\r
+                       st.ResultText(0,res);\r
+                       if(res=="ok")\r
+                       {\r
+                               return true;\r
+                       }\r
+                       else\r
+                       {\r
+                               return false;\r
+                       }\r
+               }\r
+       }\r
+       else\r
+       {\r
+               return false;\r
+       }\r
+}\r
+\r
+const std::string TestDBIntegrity()\r
+{\r
+       std::string result="";\r
+\r
+       SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
+       SQLite3DB::Statement st=db->Prepare("PRAGMA integrity_check;");\r
+       st.Step();\r
+       while(st.RowReturned())\r
+       {\r
+               std::string text="";\r
+               st.ResultText(0,text);\r
+               result+=text;\r
+               st.Step();\r
+       }\r
+       return result;\r
+}\r