From d86341924569cccac106c4d269af017757cb6a2d Mon Sep 17 00:00:00 2001 From: martinlanghoff Date: Wed, 12 Sep 2007 02:56:36 +0000 Subject: [PATCH] course/index: move orphan fixups to an optimised fix_coursecategory_orphans() Move the fixups for orphan courses to the newly minted fix_coursecategory_orphans() -- and optimise it to take only 1 dbquery for the common case. If we do find lots of orphans, we issue 2 updates per orphan. This cuts down dbqueries drastically - we used to have 2x the number of courses in the site. --- course/index.php | 18 ++---------------- lib/datalib.php | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/course/index.php b/course/index.php index 9efa48513e..9dad679ac9 100644 --- a/course/index.php +++ b/course/index.php @@ -268,24 +268,10 @@ } } -/// Find the default category (the one with the lowest ID) - $categories = get_categories(); - $default = 99999; - foreach ($categories as $category) { - if ($category->id < $default) { - $default = $category->id; - } - } - /// Find any orphan courses that don't yet have a valid category and set to default - if ($courses = get_courses(NULL,NULL,'c.id, c.category, c.sortorder, c.visible')) { - foreach ($courses as $course) { - if ($course->category and !isset($categories[$course->category])) { - set_field('course', 'category', $default, 'id', $course->id); - } - } - } + fix_coursecategory_orphans(); +/// Should be a no-op 99% of the cases fix_course_sortorder(); /// Print form for creating new categories diff --git a/lib/datalib.php b/lib/datalib.php index f473cb5842..67d85f943d 100644 --- a/lib/datalib.php +++ b/lib/datalib.php @@ -1019,6 +1019,49 @@ function fix_course_sortorder($categoryid=0, $n=0, $safe=0, $depth=0, $path='') return $n+1; } +/** + * Ensure all courses have a valid course category + * useful if a category has been removed manually + **/ +function fix_coursecategory_orphans() { + + global $CFG; + + // Note: the handling of sortorder here is arguably + // open to race conditions. Hard to fix here, unlikely + // to hit anyone in production. + + $sql = "SELECT c.id, c.category, c.shortname + FROM {$CFG->prefix}course c + LEFT OUTER JOIN {$CFG->prefix}course_categories cc ON c.category=cc.id + WHERE cc.id IS NULL AND c.id != " . SITEID; + + $rs = get_recordset_sql($sql); + + if ($rs->RecordCount()){ // we have some orphans + + // the "default" category is the lowest numbered... + $default = get_field_sql("SELECT MIN(id) + FROM {$CFG->prefix}course_categories"); + $sortorder = get_field_sql("SELECT MAX(sortorder) + FROM {$CFG->prefix}course + WHERE category=$default"); + + + begin_sql(); + $tx = true; + while ($tx && $course = rs_fetch_next_record($rs)) { + $tx = $tx && set_field('course', 'category', $default, 'id', $course->id); + $tx = $tx && set_field('course', 'sortorder', ++$sortorder, 'id', $course->id); + } + if ($tx) { + commit_sql(); + } else { + rollback_sql(); + } + } +} + /** * List of remote courses that a user has access to via MNET. * Works only on the IDP -- 2.39.5