From ad4c7473a9135392cd9c4cfab983758c6c124b67 Mon Sep 17 00:00:00 2001 From: martinlanghoff <martinlanghoff> Date: Wed, 19 Sep 2007 07:29:07 +0000 Subject: [PATCH] accesslib: build_context_path() is now much much cheaper We now populate the context.path only where it's empty, this means that we take 0.15s instead of 0.6s. More importantly, we avoid thrashing the DB's indexes pointlessly. We also support Oracle and its dirty hack here. And the function now has a $force parameter that can be used to actually overwrite the paths/depths in case they've been corrupted. --- lib/accesslib.php | 65 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 19 deletions(-) diff --git a/lib/accesslib.php b/lib/accesslib.php index 86c7b25f39..e428aee4c0 100755 --- a/lib/accesslib.php +++ b/lib/accesslib.php @@ -4403,23 +4403,46 @@ function component_level_changed($cap, $comp, $contextlevel) { } /** - * Populate context.path and context.depth + * Populate context.path and context.depth where missing. + * + * Use $force=true to force a complete rebuild of + * the path and depth fields. + * */ -function build_context_path() { +function build_context_path($force=false) { global $CFG; // Site - $sitectx = get_field('context', 'id','contextlevel', CONTEXT_SYSTEM); - $base = "/$sitectx"; - set_field('context', 'path', $base, 'id', $sitectx); - set_field('context', 'depth', 1, 'id', $sitectx); + $sitectx = get_record('context', 'contextlevel', CONTEXT_SYSTEM); + $base = '/' . $sitectx->id; - // Sitecourse - $ctxid = get_field('context', 'id','contextlevel', CONTEXT_COURSE, - 'instanceid', SITEID); - set_field('context', 'path', "$base/$ctxid", 'id', $ctxid); - set_field('context', 'depth', 2, 'id', $ctxid); + if ($force || $sitectx->path !== $base) { + set_field('context', 'path', $base, 'id', $sitectx->id); + set_field('context', 'depth', 1, 'id', $sitectx->id); + $sitectx = get_record('context', 'contextlevel', CONTEXT_SYSTEM); + } + // Sitecourse + $sitecoursectx = get_record('context', + 'contextlevel', CONTEXT_COURSE, + 'instanceid', SITEID); + if ($force || $sitecoursectx->path !== "$base/{$sitecoursectx->id}") { + set_field('context', 'path', "$base/{$sitecoursectx->id}", + 'id', $sitecoursectx->id); + set_field('context', 'depth', 2, + 'id', $sitecoursectx->id); + $sitecoursectx = get_record('context', + 'contextlevel', CONTEXT_COURSE, + 'instanceid', SITEID); + } + + $emptyclause = " AND path=''"; + if ($CFG->dbtype==='oci8po') { // DIRTYHACK - everybody loves Oracle ;-) + $emptyclause = " AND path=' '"; + } + if ($force) { + $emptyclause = ''; + } // Top level categories $sql = "UPDATE {$CFG->prefix}context SET depth=2, path=" . sql_concat("'$base/'", 'id') . " @@ -4427,7 +4450,7 @@ function build_context_path() { AND instanceid IN (SELECT id FROM {$CFG->prefix}course_categories - WHERE depth=1)"; + WHERE depth=1 $emptyclause )"; execute_sql($sql, false); // Deeper categories - one query per depthlevel @@ -4443,7 +4466,8 @@ function build_context_path() { AND pctx.contextlevel=".CONTEXT_COURSECAT.") WHERE c.depth=$n) it WHERE contextlevel=".CONTEXT_COURSECAT." - AND {$CFG->prefix}context.instanceid=it.instanceid"; + AND {$CFG->prefix}context.instanceid=it.instanceid + $emptyclause "; execute_sql($sql, false); } @@ -4458,7 +4482,8 @@ function build_context_path() { AND pctx.contextlevel=".CONTEXT_COURSECAT.") WHERE c.id != ".SITEID.") it WHERE contextlevel=".CONTEXT_COURSE." - AND {$CFG->prefix}context.instanceid=it.instanceid"; + AND {$CFG->prefix}context.instanceid=it.instanceid + $emptyclause "; execute_sql($sql, false); // Module instances @@ -4472,7 +4497,8 @@ function build_context_path() { AND pctx.contextlevel=".CONTEXT_COURSE.") ) it WHERE contextlevel=".CONTEXT_MODULE." - AND {$CFG->prefix}context.instanceid=it.instanceid"; + AND {$CFG->prefix}context.instanceid=it.instanceid + $emptyclause "; execute_sql($sql, false); // Blocks - non-pinned only @@ -4487,16 +4513,17 @@ function build_context_path() { AND pctx.contextlevel=".CONTEXT_COURSE.") ) it WHERE contextlevel=".CONTEXT_BLOCK." - AND {$CFG->prefix}context.instanceid=it.instanceid"; + AND {$CFG->prefix}context.instanceid=it.instanceid + $emptyclause "; execute_sql($sql, false); // User $sql = "UPDATE {$CFG->prefix}context SET depth=2, path=".sql_concat("'$base/'", 'id')." WHERE contextlevel=".CONTEXT_USER." - AND instanceid IN - (SELECT id - FROM {$CFG->prefix}user)"; + AND instanceid IN (SELECT id + FROM {$CFG->prefix}user) + $emptyclause "; execute_sql($sql, false); // Personal TODO -- 2.39.5