From: skodak Date: Sat, 23 Feb 2008 22:55:15 +0000 (+0000) Subject: MDL-13520, MDL-13604, MDL-13620 stats - better simplified parent context join, admini... X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=67ce5270fb5ab79716d07f43d1728861857f8602;p=moodle.git MDL-13520, MDL-13604, MDL-13620 stats - better simplified parent context join, administrator now counted too, optimised processing when no day logs present; merged from MOODLE_19_STABLE --- diff --git a/lib/statslib.php b/lib/statslib.php index 390e8866d8..6cf571afab 100644 --- a/lib/statslib.php +++ b/lib/statslib.php @@ -110,8 +110,9 @@ function stats_cron_daily($maxdays=1) { $guest = get_guest(); $guestrole = get_guest_role(); - list($enrolfrom, $enrolwhere) = stats_get_enrolled_sql($CFG->statscatdepth); - list($fpfrom, $fpwhere) = stats_get_enrolled_sql(0); + list($enroljoin, $enrolwhere) = stats_get_enrolled_sql($CFG->statscatdepth, true); + list($enroljoin_na, $enrolwhere_na) = stats_get_enrolled_sql($CFG->statscatdepth, false); + list($fpjoin, $fpwhere) = stats_get_enrolled_sql(0, true); mtrace("Running daily statistics gathering, starting at $timestart:"); @@ -133,12 +134,21 @@ function stats_cron_daily($maxdays=1) { set_cron_lock('statsrunning', time() + $timeout, true); } + $daystart = time(); + $timesql = "l.time >= $timestart AND l.time < $nextmidnight"; $timesql1 = "l1.time >= $timestart AND l1.time < $nextmidnight"; $timesql2 = "l2.time >= $timestart AND l2.time < $nextmidnight"; stats_daily_progress('init'); + + /// find out if any logs available for this day + $sql = "SELECT 'x' + FROM {$CFG->prefix}log l + WHERE $timesql"; + $logspresent = get_records_sql($sql, 0, 1); + /// process login info first $sql = "INSERT INTO {$CFG->prefix}stats_user_daily (stattype, timeend, courseid, userid, statsreads) @@ -149,7 +159,7 @@ function stats_cron_daily($maxdays=1) { GROUP BY stattype, timeend, courseid, userid HAVING count(l.id) > 0"; - if (!execute_sql($sql, false)) { + if ($logspresent and !execute_sql($sql, false)) { $failed = true; break; } @@ -165,7 +175,7 @@ function stats_cron_daily($maxdays=1) { FROM {$CFG->prefix}stats_user_daily s2 WHERE s2.stattype = 'logins' AND timeend = $nextmidnight) AS stat2"; - if (!execute_sql($sql, false)) { + if ($logspresent and !execute_sql($sql, false)) { $failed = true; break; } @@ -189,11 +199,9 @@ function stats_cron_daily($maxdays=1) { SELECT 'enrolments' AS stattype, $nextmidnight AS timeend, c.id AS courseid, ra.roleid, COUNT(DISTINCT ra.userid) AS stat1, 0 AS stat2 - FROM {$CFG->prefix}role_assignments ra, {$CFG->prefix}context ctx, - {$CFG->prefix}course c, $enrolfrom - WHERE $enrolwhere - GROUP BY stattype, timeend, c.id, ra.roleid, stat2 - HAVING COUNT(DISTINCT ra.userid) > 0"; + FROM {$CFG->prefix}role_assignments ra $enroljoin_na + WHERE $enrolwhere_na + GROUP BY stattype, timeend, c.id, ra.roleid, stat2"; if (!execute_sql($sql, false)) { $failed = true; @@ -204,11 +212,10 @@ function stats_cron_daily($maxdays=1) { // using table alias in UPDATE does not work in pg < 8.2 $sql = "UPDATE {$CFG->prefix}stats_daily SET stat2 = (SELECT COUNT(DISTINCT ra.userid) - FROM {$CFG->prefix}role_assignments ra, {$CFG->prefix}context ctx, - {$CFG->prefix}course c, $enrolfrom + FROM {$CFG->prefix}role_assignments ra $enroljoin_na WHERE ra.roleid = {$CFG->prefix}stats_daily.roleid AND c.id = {$CFG->prefix}stats_daily.courseid AND - $enrolwhere AND + $enrolwhere_na AND EXISTS (SELECT 'x' FROM {$CFG->prefix}log l WHERE l.course = {$CFG->prefix}stats_daily.courseid AND @@ -220,7 +227,7 @@ function stats_cron_daily($maxdays=1) { FROM {$CFG->prefix}log l WHERE $timesql)"; - if (!execute_sql($sql, false)) { + if ($logspresent and !execute_sql($sql, false)) { $failed = true; break; } @@ -231,13 +238,12 @@ function stats_cron_daily($maxdays=1) { SELECT 'enrolments' AS stattype, $nextmidnight AS timeend, c.id, 0 AS nroleid, COUNT(DISTINCT ra.userid) AS stat1, 0 AS stat2 - FROM {$CFG->prefix}role_assignments ra, {$CFG->prefix}context ctx, - {$CFG->prefix}course c, $enrolfrom - WHERE c.id <> ".SITEID." AND $enrolwhere + FROM {$CFG->prefix}role_assignments ra $enroljoin_na + WHERE c.id <> ".SITEID." AND $enrolwhere_na GROUP BY stattype, timeend, c.id, nroleid, stat2 HAVING COUNT(DISTINCT ra.userid) > 0"; - if (!execute_sql($sql, false)) { + if ($logspresent and !execute_sql($sql, false)) { $failed = true; break; } @@ -245,10 +251,9 @@ function stats_cron_daily($maxdays=1) { $sql = "UPDATE {$CFG->prefix}stats_daily SET stat2 = (SELECT COUNT(DISTINCT ra.userid) - FROM {$CFG->prefix}role_assignments ra, {$CFG->prefix}context ctx, - {$CFG->prefix}course c, $enrolfrom + FROM {$CFG->prefix}role_assignments ra $enroljoin_na WHERE c.id = {$CFG->prefix}stats_daily.courseid AND - $enrolwhere AND + $enrolwhere_na AND EXISTS (SELECT 'x' FROM {$CFG->prefix}log l WHERE l.course = {$CFG->prefix}stats_daily.courseid AND @@ -261,7 +266,7 @@ function stats_cron_daily($maxdays=1) { FROM {$CFG->prefix}log l WHERE $timesql AND l.course <> ".SITEID.")"; - if (!execute_sql($sql, false)) { + if ($logspresent and !execute_sql($sql, false)) { $failed = true; break; } @@ -279,7 +284,7 @@ function stats_cron_daily($maxdays=1) { JOIN {$CFG->prefix}log l ON l.userid = u.id WHERE u.deleted = 0 AND $timesql) AS stat2"; - if (!execute_sql($sql, false)) { + if ($logspresent and !execute_sql($sql, false)) { $failed = true; break; } @@ -298,7 +303,7 @@ function stats_cron_daily($maxdays=1) { FROM {$CFG->prefix}stats_daily WHERE stattype = 'enrolments' AND courseid = ".SITEID." AND roleid = $defaultfproleid AND timeend = $nextmidnight"; - if (!execute_sql($sql, false)) { + if ($logspresent and !execute_sql($sql, false)) { $failed = true; break; } @@ -315,7 +320,7 @@ function stats_cron_daily($maxdays=1) { JOIN {$CFG->prefix}log l ON l.userid = u.id WHERE u.deleted = 0 AND $timesql) AS stat2"; - if (!execute_sql($sql, false)) { + if ($logspresent and !execute_sql($sql, false)) { $failed = true; break; } @@ -349,7 +354,7 @@ function stats_cron_daily($maxdays=1) { SELECT 0 AS userid, ".SITEID." AS courseid) d"; // can not use group by here because pg can not handle it :-( - if (!execute_sql($sql, false)) { + if ($logspresent and !execute_sql($sql, false)) { $failed = true; break; } @@ -373,7 +378,7 @@ function stats_cron_daily($maxdays=1) { FROM {$CFG->prefix}log l WHERE l.course = c.id and $timesql)"; - if (!execute_sql($sql, false)) { + if ($logspresent and !execute_sql($sql, false)) { $failed = true; break; } @@ -387,17 +392,17 @@ function stats_cron_daily($maxdays=1) { SELECT 'activity' AS stattype, $nextmidnight AS timeend, pl.courseid, pl.roleid, SUM(pl.statsreads) AS stat1, SUM(pl.statswrites) AS stat2 FROM (SELECT DISTINCT ra.roleid, c.id AS courseid, sud.statsreads, sud.statswrites - FROM {$CFG->prefix}role_assignments ra, {$CFG->prefix}context ctx, {$CFG->prefix}course c, - {$CFG->prefix}stats_user_daily sud, $enrolfrom + FROM {$CFG->prefix}role_assignments ra $enroljoin + JOIN {$CFG->prefix}stats_user_daily sud + ON (sud.userid = ra.userid AND sud.courseid = c.id) WHERE c.id <> ".SITEID." AND ra.roleid <> $guestrole->id AND ra.userid <> $guest->id AND - sud.timeend = $nextmidnight AND sud.userid = ra.userid AND - sud.courseid = c.id AND $enrolwhere + sud.timeend = $nextmidnight AND $enrolwhere ) pl GROUP BY stattype, timeend, pl.courseid, pl.roleid HAVING SUM(pl.statsreads) > 0 OR SUM(pl.statswrites) > 0"; - if (!execute_sql($sql, false)) { + if ($logspresent and !execute_sql($sql, false)) { $failed = true; break; } @@ -415,14 +420,13 @@ function stats_cron_daily($maxdays=1) { WHERE sud.timeend = $nextmidnight AND sud.courseid <> ".SITEID." AND (sud.userid = $guest->id OR sud.userid NOT IN (SELECT ra.userid - FROM {$CFG->prefix}role_assignments ra, {$CFG->prefix}context ctx, - {$CFG->prefix}course c, $enrolfrom + FROM {$CFG->prefix}role_assignments ra $enroljoin WHERE c.id <> ".SITEID." AND ra.roleid <> $guestrole->id AND $enrolwhere)) GROUP BY stattype, timeend, sud.courseid, nroleid HAVING SUM(sud.statsreads) > 0 OR SUM(sud.statswrites) > 0"; - if (!execute_sql($sql, false)) { + if ($logspresent and !execute_sql($sql, false)) { $failed = true; break; } @@ -435,17 +439,17 @@ function stats_cron_daily($maxdays=1) { SELECT 'activity' AS stattype, $nextmidnight AS timeend, pl.courseid, pl.roleid, SUM(pl.statsreads) AS stat1, SUM(pl.statswrites) AS stat2 FROM (SELECT DISTINCT ra.roleid, c.id AS courseid, sud.statsreads, sud.statswrites - FROM {$CFG->prefix}role_assignments ra, {$CFG->prefix}context ctx, {$CFG->prefix}course c, - {$CFG->prefix}stats_user_daily sud, $fpfrom + FROM {$CFG->prefix}role_assignments ra $fpjoin + JOIN {$CFG->prefix}stats_user_daily sud + ON (sud.userid = ra.userid AND sud.courseid = c.id) WHERE c.id = ".SITEID." AND ra.roleid <> $defaultfproleid AND ra.roleid <> $guestrole->id AND ra.userid <> $guest->id AND - sud.timeend = $nextmidnight AND sud.userid = ra.userid AND - sud.courseid = c.id AND $fpwhere + sud.timeend = $nextmidnight AND $fpwhere ) pl GROUP BY stattype, timeend, pl.courseid, pl.roleid HAVING SUM(pl.statsreads) > 0 OR SUM(pl.statswrites) > 0"; - if (!execute_sql($sql, false)) { + if ($logspresent and !execute_sql($sql, false)) { $failed = true; break; } @@ -461,14 +465,13 @@ function stats_cron_daily($maxdays=1) { WHERE sud.timeend = $nextmidnight AND sud.courseid = ".SITEID." AND sud.userid <> $guest->id AND sud.userid <> 0 AND sud.userid NOT IN (SELECT ra.userid - FROM {$CFG->prefix}role_assignments ra, {$CFG->prefix}context ctx, - {$CFG->prefix}course c, $fpfrom + FROM {$CFG->prefix}role_assignments ra $fpjoin WHERE c.id = ".SITEID." AND ra.roleid <> $guestrole->id AND ra.roleid <> $defaultfproleid AND $fpwhere) GROUP BY stattype, timeend, sud.courseid, nroleid HAVING SUM(sud.statsreads) > 0 OR SUM(sud.statswrites) > 0"; - if (!execute_sql($sql, false)) { + if ($logspresent and !execute_sql($sql, false)) { $failed = true; break; } @@ -487,7 +490,7 @@ function stats_cron_daily($maxdays=1) { GROUP BY stattype, timeend, courseid, nroleid HAVING SUM(pl.statsreads) > 0 OR SUM(pl.statswrites) > 0"; - if (!execute_sql($sql, false)) { + if ($logspresent and !execute_sql($sql, false)) { $failed = true; break; } @@ -495,7 +498,7 @@ function stats_cron_daily($maxdays=1) { // remember processed days set_config('statslastdaily', $nextmidnight); - mtrace(" finished until $nextmidnight: ".userdate($nextmidnight)); + mtrace(" finished until $nextmidnight: ".userdate($nextmidnight)." (in ".(time()-$daystart)." s)"); $timestart = $nextmidnight; $nextmidnight = stats_get_next_day_start($nextmidnight); @@ -758,35 +761,41 @@ function stats_cron_monthly() { /** * Returns simplified enrolment sql join data * @param int $limit number of max parent course categories - * @return array from and where string + * @param bool $includedoanything include also admins + * @return array ra join and where string */ -function stats_get_enrolled_sql($limit) { +function stats_get_enrolled_sql($limit, $includedoanything) { global $CFG; - $from = "{$CFG->prefix}role_capabilities rc"; - for($i=1; $i<=$limit; $i++) { - $from .= ", {$CFG->prefix}course_categories cc$i"; - } + $adm = $includedoanything ? " OR rc.capability = 'moodle/site:doanything'" : ""; - $where = " (rc.capability = 'moodle/course:view' AND - rc.permission = 1 AND rc.contextid = ".SYSCONTEXTID." AND - rc.roleid = ra.roleid AND - ( (ctx.id = ".SYSCONTEXTID." AND ctx.id = ra.contextid) - OR (ctx.contextlevel = ".CONTEXT_COURSE." AND - ctx.instanceid = c.id AND ctx.id = ra.contextid)"; + $join = "JOIN {$CFG->prefix}context ctx + ON ctx.id = ra.contextid + JOIN {$CFG->prefix}course c + ON TRUE + JOIN {$CFG->prefix}role_capabilities rc + ON rc.roleid = ra.roleid"; + $where = "((rc.capability = 'moodle/course:view' $adm) + AND rc.permission = 1 AND rc.contextid = ".SYSCONTEXTID." + AND (ctx.contextlevel = ".CONTEXT_SYSTEM." + OR (c.id = ctx.instanceid AND ctx.contextlevel = ".CONTEXT_COURSE.")"; for($i=1; $i<=$limit; $i++) { - $where .= " OR (ctx.contextlevel = ".CONTEXT_COURSECAT." AND ctx.id = ra.contextid AND ctx.instanceid = cc1.id"; - for($j=2; $j<=$i; $j++) { - $k = $j -1; - $where .= " AND cc$j.parent = cc$k.id"; + if ($i == 1) { + $join .= " LEFT OUTER JOIN {$CFG->prefix}course_categories cc1 + ON cc1.id = c.category"; + $where .= " OR (cc1.id = ctx.instanceid AND ctx.contextlevel = ".CONTEXT_COURSECAT.")"; + } else { + $j = $i-1; + $join .= " LEFT OUTER JOIN {$CFG->prefix}course_categories cc$i + ON cc$i.id = cc$j.parent"; + $where .= " OR (cc$i.id = ctx.instanceid AND ctx.contextlevel = ".CONTEXT_COURSECAT.")"; } - $where .= " AND c.category = cc$i.id)"; } - $where .= ")) "; + $where .= "))"; - return array($from, $where); + return array($join, $where); } /**