]> jfr.im git - irc/quakenet/newserv.git/blobdiff - chanserv/chanserv_cleanupdb.c
A4STATS: remove E style escapes and switch to createtable for indices
[irc/quakenet/newserv.git] / chanserv / chanserv_cleanupdb.c
index 4ce3670354261fcd1dff976f80d25a9d21d597d2..92a921cc2860513c92377a0158f17dc017432f2e 100644 (file)
@@ -1,8 +1,11 @@
 #include "chanserv.h"
 #include "../lib/irc_string.h"
+#include "../lib/version.h"
 #include <stdio.h>
 #include <string.h>
 
+MODULE_VERSION(QVERSION);
+
 static void cleanupdb(void *arg);
 static void schedulecleanup(int hooknum, void *arg);
 
@@ -24,15 +27,14 @@ void _fini() {
 }
 
 static void schedulecleanup(int hooknum, void *arg) {
-  /* run at midnight but only if we're more than 1h away from it, otherwise run tomorrow */
+  /* run at 1am but only if we're more than 15m away from it, otherwise run tomorrow */
 
   time_t t = time(NULL);
-  time_t next_midnight = (t / 86400) * 86400 + 86400;
-  if(next_midnight - t < 3600)
-    next_midnight+=86400;
-
-//  schedulerecurring(next_midnight,0,86400,cleanupdb,NULL);
-//  scheduleoneshot(time(NULL)+5,cleanupdb,NULL);
+  time_t next_run = ((t / 86400) * 86400 + 86400) + 3600;
+  if(next_run - t < 900)
+    next_run+=86400;
+  
+  schedulerecurring(next_run,0,86400,cleanupdb,NULL);
 }
 
 __attribute__ ((format (printf, 1, 2)))
@@ -54,7 +56,7 @@ static void cleanupdb_real(DBConn *dbconn, void *arg) {
   authname *anp;
   int i,j;
   time_t t, to_age, unused_age, maxchan_age, authhistory_age;
-  int expired = 0, unauthed = 0, chansvaped = 0;
+  int expired = 0, unauthed = 0, chansvaped = 0, chansempty = 0;
   chanindex *cip, *ncip;
   regchan *rcp;
   DBResult *pgres;
@@ -103,6 +105,10 @@ static void cleanupdb_real(DBConn *dbconn, void *arg) {
       if (anp->marker == themarker)
         continue;
 
+      /* HACK: don't ever delete the last user -- prevents userids being reused */
+      if (vrup->ID == lastuserID)
+        continue;
+
       if(!anp->nicks && !UHasStaffPriv(vrup) && !UIsCleanupExempt(vrup)) {
         if(vrup->lastauth && (vrup->lastauth < to_age)) {
           expired++;
@@ -127,6 +133,10 @@ static void cleanupdb_real(DBConn *dbconn, void *arg) {
       if (!(rcp=cip->exts[chanservext]))
         continue;
 
+      /* HACK: don't ever delete the last channel -- prevents channelids being reused */
+      if (rcp->ID == lastchannelID)
+        continue;
+
       /* there's a bug here... if no joins or modes are done within the threshold
        * and someone leaves just before the cleanup then the channel will be nuked.
        */
@@ -134,6 +144,8 @@ static void cleanupdb_real(DBConn *dbconn, void *arg) {
       /* this is one possible soln but relies on cleanupdb being run more frequently than
        * the threshold:
        */ 
+      /* slug: no longer required as we scan the entire network every 1h (cs_hourlyfunc) */
+/*
       if(cip->channel && cs_ischannelactive(cip->channel, rcp)) {
         rcp->lastactive = t;
         if (rcp->lastcountersync < (t - COUNTERSYNCINTERVAL)) {
@@ -141,6 +153,7 @@ static void cleanupdb_real(DBConn *dbconn, void *arg) {
           rcp->lastcountersync=t;
         }
       }
+*/
 
       if(rcp->lastactive < maxchan_age) {
         /* don't remove channels with the original founder as an oper */
@@ -151,6 +164,7 @@ static void cleanupdb_real(DBConn *dbconn, void *arg) {
         cs_log(NULL, "CLEANUPDB inactive channel %s", cip->name?cip->name->content:"??");
         cs_removechannel(rcp, "Channel deleted due to lack of activity.");
         chansvaped++;
+        continue;
       }
       
       /* Get rid of any dead chanlev entries */
@@ -162,9 +176,16 @@ static void cleanupdb_real(DBConn *dbconn, void *arg) {
             cs_log(NULL, "Removing user %s from channel %s (no flags)",rcup->user->username,rcp->index->name->content);
             csdb_deletechanuser(rcup);
             delreguserfromchannel(rcp, rcup->user);
+            freeregchanuser(rcup);
           }
         }
       }
+
+      if (cs_removechannelifempty(NULL, rcp)) {
+        /* logged+parted by cs_removechannelifempty */
+        chansempty++;
+        continue;
+      }
     }
   }
   
@@ -172,7 +193,7 @@ static void cleanupdb_real(DBConn *dbconn, void *arg) {
     
   csdb_cleanuphistories(authhistory_age);
   
-  cleanuplog("Stats: %d accounts inactive for %d days, %d accounts weren't used within %d days, %d channels were inactive for %d days.", expired, CLEANUP_ACCOUNT_INACTIVE, unauthed, CLEANUP_ACCOUNT_UNUSED, chansvaped, CLEANUP_CHANNEL_INACTIVE);
+  cleanuplog("Stats: %d accounts inactive for %d days, %d accounts weren't used within %d days, %d channels were inactive for %d days, %d channels empty.", expired, CLEANUP_ACCOUNT_INACTIVE, unauthed, CLEANUP_ACCOUNT_UNUSED, chansvaped, CLEANUP_CHANNEL_INACTIVE, chansempty);
 
 out:
   cleanupdb_active=0;
@@ -204,8 +225,14 @@ static void cleanupdb(void *arg) {
   /* This query returns a single column containing the userids of all users
    * who have active sessions now, or sessions which ended in the last
    * CLEANUP_ACCOUNT_INACTIVE days.  */
+
+  dbquery("BEGIN TRANSACTION;");
+
+  /* increase memory for aggregate (GROUP BY) -- query can take hours if this spills to disk */
+  dbquery("SET LOCAL work_mem = '512MB';");
   q9cleanup_asyncquery(cleanupdb_real, NULL,
-    "SELECT userID from chanserv.authhistory WHERE disconnecttime=0 OR disconnecttime > %d GROUP BY userID", to_age);
-  
+    "SELECT userID from chanserv.authhistory WHERE disconnecttime=0 OR disconnecttime > %d GROUP BY userID;", to_age);
+  dbquery("COMMIT;");
+
   cleanupdb_active=1;
 }