]> git.mjollnir.org Git - moodle.git/commitdiff
accesslib: build_context_path() is now much much cheaper
authormartinlanghoff <martinlanghoff>
Wed, 19 Sep 2007 07:29:07 +0000 (07:29 +0000)
committermartinlanghoff <martinlanghoff>
Wed, 19 Sep 2007 07:29:07 +0000 (07:29 +0000)
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

index 86c7b25f395826881ed8c86610871bb1afa96ac2..e428aee4c0dcbac7220cfc560fa3cf339ec1e979 100755 (executable)
@@ -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