diff --git a/mod/quiz/doc/databasetables.html b/mod/quiz/doc/databasetables.html new file mode 100644 index 00000000000..65a413f3d21 --- /dev/null +++ b/mod/quiz/doc/databasetables.html @@ -0,0 +1,35 @@ + + + Database tables + + + + + +

Database tables

+ +

quiz_newest_states

+ +This table exists only for efficiency reasons: + +
    +
  1. Via its 'newest' and 'newgraded' fields it gives attempt.php + a way to quickly find the newest state + and the newest graded state for an attempt. It allows the + construction of SQL to select all the states that need to be loaded + on attempt.php or review.php.
  2. +
  3. Via its 'sumpenalty' field it gives quiz_apply_penalty() a quick + way for getting at the accummulated penalty that needs to be applied. + Without this field the penalties from all previous graded states + would have to be added up each time. Not a big deal actually because + this could be achieved with a single SQL query (using SUM) but this + field was introduced when we still had the multiplicative penalty + scheme around which would have been more difficult to recompute.
  4. +
+ +This table was introduced in Moodle 1.5 and is not populated for all +states during the upgrade because on sites with a lot of existing +states that could take too long. Rather it is done whenever needed +by quiz_upgrade_states(). + + diff --git a/mod/quiz/locallib.php b/mod/quiz/locallib.php index 199e7a13ac9..d8781091312 100644 --- a/mod/quiz/locallib.php +++ b/mod/quiz/locallib.php @@ -2525,13 +2525,28 @@ function quiz_get_reviewoptions($quiz, $attempt, $isteacher=false) { /** * Upgrade states for an attempt to Moodle 1.5 model * +* Any state that does not yet have its timestamp set to nonzero has not yet been upgraded from Moodle 1.4 +* The reason these are still around is that for large sites it would have taken too long to +* upgrade all states at once. This function sets the timestamp field and creates an entry in the +* quiz_newest_states table. * @param object $attempt The attempt whose states need upgrading */ function quiz_upgrade_states($attempt) { global $CFG; + // The old quiz model only allowed a single response per quiz attempt so that there will be + // only one state record per question for this attempt. + + // We set the timestamp of all states to the timemodified field of the attempt. execute_sql("UPDATE {$CFG->prefix}quiz_states SET timestamp = '$attempt->timemodified' WHERE attempt = '$attempt->id'", false); + + // For each state we create an entry in the quiz_newest_states table, with both newest and + // newgraded pointing to this state. + // Actually we only do this for states whose question is actually listed in $attempt->layout. + // We do not do it for states associated to wrapped questions like for example the questions + // used by a RANDOM question $newest->attemptid = $attempt->id; - if ($states = get_records('quiz_states', 'attempt', $attempt->id)) { + $questionlist = quiz_questions_in_quiz($attempt->layout); + if ($states = get_records_select('quiz_states', "attempt = '$attempt->id' AND question IN ($questionlist)")) { foreach ($states as $state) { $newest->newgraded = $state->id; $newest->newest = $state->id;