Chapter 3 ~ Under The Hood

Last modified: December 10, 2007 - 18:06

Quiz 2.0 Architecture Information

DATABASE TABLES: The quiz <-> node relationship.

A Quiz is a Drupal node, and thus the node table contains a row for each Quiz. Similarly, a Question is also a Drupal node, so it too has an entry in the node table. Additional properties for Quizzes can be found in the rows of the quiz_node_properties table. Similarly, all question-types have a table called quiz_node_question_properties to store additional data. Each question-type also makes it's own set of tables to hold answers and user feedback. That means the multichoice.module question-type gets a quiz_multichoice_answers and a quiz_multichoice_user_answers.

The resulting quiz.module tableset looks a little bit like this:

  • quiz_node_properties stores all additional fields of a Quiz node, such as the start/stop date, the number of times a user can take the test, time limit, and how many of the questions are randomized.
  • quiz_node_relationship tracks the arrangement between each quiz and it's parents, children, and whether or not the quiz has questions (question_status).
  • quiz_node_question_properties remembers the number of times each question was answered.
  • quiz_node_results is pretty self explanatory.
  • quiz_node_results_answers is, again, a self-fulfilling title.
  • quiz_node_result_options is an unused table, built for expansion.

And the multichoice.module's question tables:

  • quiz_multichoice_answers
  • quiz_multichoice_user_answers

The quiz_node_relationship table is the ‘glue’ between Quizzes and Questions. In the quiz_node_relationship can be found three fields - parentvid, childvid, and status. Together, the parentvid and childvid represent a two-field primary key.

When a Question is added to a Quiz, the status must be set to ‘always’ or ‘random’. If that status is ever changed, then the version (vid) of the Quiz it has been added to will be incremented, thus creating a new revision of that Quiz.

When the vid of a Quiz is incremented, the following node tables are updated: node, node_example, and node_revisions. In addition, for each row in the quiz_node_relationship table that contains a parent_vid corresponding to the Quiz vid (before incrementing), a duplicate will be made. In the newly duplicated rows, each parent_vid will be set to the newly incremented value of the Quiz node vid.

The following pseudo-code details the quiz_node_relationship for any given Quiz and its corresponding Questions. CNR == ‘Create new revision’:

<?php
if (Quiz == edited) { if (Quiz != CNR) { - No changes. }

if (
Quiz == CNR) {
  -
The Quiz vid is incremented.

  -
All rows in the Quiz_node_relationship table containing the vid of
    the Quiz
(parent_vid), before it was incremented, are duplicated.
   
Each parent_vid of the newly duplicated rows are set to the newly
    incremented Quiz vid
.
}

}

if (
question is edited) { if (question != CNR) { - No changes. }

if (
question == CNR) {
  -
The question vid is incremented.

        -
In the Quiz_node_relationship table, for each question vid (child_vid),
           
before it was incremented, the associated Quiz vids (parent_vid) are

            In the Quiz_node_relationship table
, Quiz vids (parent_vid) are
            gathered
for each question vid (child_vid), before the question vid
            was incremented
. Note that if the status is set to 'never', then the
            parent_vid is not included
. These Quiz vids represent revision ids for
           
Quizzes that the edited question belongs to.

            foreach
of the gathered Quiz vids above {
                -
The Quiz vid is incremented.

                -
All rows in the Quiz_node_relationship table containing the vid of
                    the Quiz
(parent_vid), before it was incremented, are duplicated.
                   
Each parent_vid of the newly duplicated rows are set to the newly
                    incremented Quiz vid
.

                -
Set child_vid (Question vid) to newly incremented Question vid,
                   
where parent_vid = newly incremented Quiz vid, and where
                    child_vid
= Question vid (prior to increment).
            }

Q } }

if (
question status is changed) {
    -
The Quiz vid is incremented.

    -
All rows in the Quiz_node_relationship table containing the vid of
        the Quiz
(parent_vid), before it was incremented, are duplicated.
       
Each parent_vid of the newly duplicated rows are set to the newly
        incremented Quiz vid
.
}
?>

EDITING QUIZZES

If a question is edited, and ‘Create new revision’ is checked, then a new revision of the Quiz (node) is created. The new vid of the Quiz will be used to update the following Quiznode* tables:

Quiznodeproperties - new row created

Quiznodequestion_properties - no change

quiz_node_relationship - new row(s) created (see DATABASE: TABLES: quiz_node_relationship)

Quiznoderesults - no changes

Quiznoderesult_options - new row created (currently not implemented)

* Quiznodeanswer_multichoice - no change

* Quiznodeuseanswermultichoice - no changes

* (Multichoice Module)

EDITING QUESTIONS

If a question is edited, and ‘Create new revision’ is checked, then a new revision of the question (node) is created. Additionally, if the question was previously added to a Quiz, then a new revision of the Quiz (node) is created. The new vid of the question will be used to update the following Quiznode* tables:

Quiznodeproperties - new row created

Quiznodequestion_properties - new row(s) created

quiz_node_relationship - new row(s) created (see DATABASE: TABLES: quiz_node_relationship)

Quiznoderesults - no changes

Quiznoderesult_options - new row created (currently not implemented)

* Quiznodeanswer_multichoice - new row(s) created

* Quiznodeuseanswermultichoice - no changes

* (Multichoice Module)

The Quiz Update Script

Converting Quiz 1.x to 2.0

The update function in the Quiz module (update_2) handles the data migration of Quiz.module and multichoice.module.

This is necessarily unique because of the normalization of that db tables that needed to occur during the upgrade. Normally this would have been handled via 2 separate install files, however, there was too much dependency and overlap between the two modules to allow this to be broken up in any other manner.

To that effect, the update script depends on the new module to load information during the data migration. To some, this may seem a little backwards to depend on the new module to handle the data migration, however, it does make sense in a few ways.

The new Quiz module code would always be available when running update.php for the module as long as the proper upgrade process is used, so there is no risk of this functioning improperly.

fixed table names

dvdrtrgn - August 6, 2008 - 14:41

EDITING QUIZZES
If a question is edited, and ‘Create new revision’ is checked, then a new revision of the Quiz (node) is created. The new vid of the Quiz will be used to update the following quiz_node* tables:
quiz_node_properties - new row created
quiz_node_question_properties - no change
quiz_node_relationship - new row(s) created (see DATABASE: TABLES: quiz_node_relationship)
quiz_node_results - no changes
quiz_node_result_options - new row created (currently not implemented)
* quiz_multichoice_answers - no change
* quiz_multichoice_user_answers - no changes
* (Multichoice Module)

EDITING QUESTIONS
If a question is edited, and ‘Create new revision’ is checked, then a new revision of the question (node) is created. Additionally, if the question was previously added to a Quiz, then a new revision of the Quiz (node) is created. The new vid of the question will be used to update the following Quiznode* tables:
quiz_node_properties - new row created
quiz_node_question_properties - new row(s) created
quiz_node_relationship - new row(s) created (see DATABASE: TABLES: quiz_node_relationship)
quiz_node_results - no changes
quiz_node_result_options - new row created (currently not implemented)
* quiz_multichoice_answers - new row(s) created
* quiz_multichoice_user_answers - no changes
* (Multichoice Module)

 
 

Drupal is a registered trademark of Dries Buytaert.