? patch.txt
Index: multichoice.install
===================================================================
RCS file: /cvs/drupal/contributions/modules/quiz/multichoice.install,v
retrieving revision 1.4
diff -u -r1.4 multichoice.install
--- multichoice.install	13 Dec 2007 05:03:30 -0000	1.4
+++ multichoice.install	31 Dec 2007 13:24:51 -0000
@@ -35,17 +35,43 @@
           PRIMARY KEY(answer_id)
         ) /*!40100 DEFAULT CHARACTER SET utf8 */;");
 
-      // Default the "Show Author and Date" for this question type to OFF.
-      $temp_array = variable_get('theme_settings', $default);
-      $temp_array['toggle_node_info_multichoice'] = 0;
-      variable_set('theme_settings', $temp_array);
       break;
 
     case 'pgsql':
+  	  /**
+  	   * Stores correct answers for multichoice quiz.
+  	   */
+        // Create the quiz node user answers multichoice table.
+        db_query("CREATE TABLE {quiz_multichoice_user_answers} (
+          question_nid int_unsigned NOT NULL,
+          question_vid int_unsigned NOT NULL,
+          result_id int_unsigned NOT NULL,
+          answer_id int_unsigned NOT NULL,
+          PRIMARY KEY(result_id, question_nid, question_vid, answer_id)
+        );");
+	  
+  	  /**
+  	   * Stores user answers for multichoice quiz.
+  	   */
+        // Create the quiz node answers multichoice table.
+        db_query("CREATE TABLE {quiz_multichoice_answers} (
+          answer_id SERIAL,
+          nid int_unsigned NOT NULL,
+          vid int_unsigned NOT NULL,
+          answer varchar(255) NOT NULL,
+          feedback text,
+          result_option int_unsigned DEFAULT 0,
+          is_correct smallint_unsigned DEFAULT 0,
+          PRIMARY KEY(answer_id)
+        );");
 	
       break;
 	  
   }
+  // Default the "Show Author and Date" for this question type to OFF.
+  $temp_array = variable_get('theme_settings', $default);
+  $temp_array['toggle_node_info_multichoice'] = 0;
+  variable_set('theme_settings', $temp_array);
 }
 
 /**
@@ -64,7 +90,17 @@
   db_query("DELETE FROM {variable} WHERE name LIKE '%s%%'", 'multichoice_');
   
   // Delete from nodes and node_revisions.
-  db_query('DELETE FROM node, node_revisions, quiz_node_question_properties USING node LEFT JOIN node_revisions USING (nid) LEFT JOIN {quiz_node_question_properties} USING (nid) WHERE type IN ("multichoice")');
+  switch ($GLOBALS['db_type']) {
+    case 'mysql':
+    case 'mysqli':
+      db_query('DELETE FROM node, node_revisions, quiz_node_question_properties USING node LEFT JOIN node_revisions USING (nid) LEFT JOIN {quiz_node_question_properties} USING (nid) WHERE type IN ("multichoice")');
+      break;
+    case 'pgsql':
+      db_query("DELETE FROM {quiz_node_question_properties} WHERE nid IN (SELECT nid FROM {node} WHERE type IN ('multichoice'))");
+      db_query("DELETE FROM {node_revisions} WHERE nid IN (SELECT nid FROM {node} WHERE type IN ('multichoice'))");
+      db_query("DELETE FROM {node} WHERE type IN ('multichoice')");
+      break;
+  }
 
   // Truncate the cache so users don't run into any unexpected errors.
   cache_clear_all('variables', 'cache');
Index: multichoice.module
===================================================================
RCS file: /cvs/drupal/contributions/modules/quiz/multichoice.module,v
retrieving revision 1.61
diff -u -r1.61 multichoice.module
--- multichoice.module	19 Dec 2007 08:07:49 -0000	1.61
+++ multichoice.module	31 Dec 2007 11:37:01 -0000
@@ -698,7 +698,7 @@
  */
 function multichoice_get_report($nid, $vid, $rid) {
   $result = db_query("SELECT *, " .
-                     "IFNULL((SELECT 1 FROM {quiz_multichoice_user_answers} ua WHERE question_nid = n.nid AND question_vid = n.vid AND result_id = %d AND ua.answer_id = ma.answer_id),0) as user_answer, " .
+                     "COALESCE((SELECT 1 FROM {quiz_multichoice_user_answers} ua WHERE question_nid = n.nid AND question_vid = n.vid AND result_id = %d AND ua.answer_id = ma.answer_id),0) as user_answer, " .
                      "(SELECT is_correct FROM {quiz_node_results_answers} WHERE question_nid = n.nid AND question_vid = n.vid AND result_id = %d) as question_correct " .
                      "FROM {node} n " .
                      "LEFT JOIN {node_revisions} USING (nid, vid) " .
Index: quiz.install
===================================================================
RCS file: /cvs/drupal/contributions/modules/quiz/quiz.install,v
retrieving revision 1.17
diff -u -r1.17 quiz.install
--- quiz.install	13 Dec 2007 05:03:30 -0000	1.17
+++ quiz.install	30 Dec 2007 19:04:40 -0000
@@ -106,16 +106,122 @@
           option_end INTEGER UNSIGNED DEFAULT 0,
           PRIMARY KEY(option_id)
         ) /*!40100 DEFAULT CHARACTER SET utf8 */;");
-
-      // Default the "Show Author and Date" for quiz nodes to OFF.
-      $temp_array = variable_get('theme_settings', $default);
-      $temp_array['toggle_node_info_quiz'] = 0;
-      variable_set('theme_settings', $temp_array);
       break;
 
     case 'pgsql':
+      /**
+       * Connect all the quiz specific properties to the correct version of a quiz.
+       */
+        // Create the quiz node properties table
+        db_query("CREATE TABLE {quiz_node_properties} (
+          property_id SERIAL,
+          vid int_unsigned NOT NULL,
+          nid int_unsigned NOT NULL,
+          number_of_random_questions smallint_unsigned DEFAULT 0 NOT NULL,
+          pass_rate smallint_unsigned NOT NULL,
+          summary_pass TEXT,
+          summary_default TEXT,
+          shuffle smallint_unsigned NOT NULL,
+          backwards_navigation smallint_unsigned NOT NULL,
+          feedback_time smallint_unsigned NOT NULL,
+          quiz_open int_unsigned DEFAULT 0,
+          quiz_close int_unsigned DEFAULT 0,
+          takes smallint_unsigned NOT NULL,
+          time_limit int_unsigned DEFAULT 0 NOT NULL,
+          quiz_always smallint NOT NULL DEFAULT 0,
+          tid int_unsigned NOT NULL DEFAULT 0,
+          PRIMARY KEY(property_id)
+        );");
+        db_query("CREATE INDEX idx_{quiz_node_properties}_vidnid ON {quiz_node_properties}(vid, nid);");
+
+      /**
+       * Both a quiz and a quiz question are nodes with versions.  A quiz is a parent node of a quiz question,
+       * making the quiz question the child.
+       *
+       * The quiz_node_relationship table stores this relationship in a way that allows a quiz question to be
+       * the child of multiple quizzes without losing version history.
+       *
+       * Future functionality will allow a quiz question to be a parent of another quiz question with the same
+       * data model.  This will make adaptive quiz functionality possible without redesign.
+       */
+        // Create the quiz node relationship table
+        db_query("CREATE TABLE {quiz_node_relationship} (
+          parent_nid int_unsigned NOT NULL,
+          parent_vid int_unsigned NOT NULL,
+          child_nid int_unsigned NOT NULL,
+          child_vid int_unsigned NOT NULL,
+          question_status smallint_unsigned DEFAULT 1 NOT NULL,
+          PRIMARY KEY(parent_nid, parent_vid, child_nid, child_vid)
+        );");
+    
+      /**
+       * This connects all the quiz question specific properties to the correct version of a quiz question.
+       */
+        // Create the quiz node question properties table
+        db_query("CREATE TABLE {quiz_node_question_properties} (
+          nid int_unsigned NOT NULL,
+          vid int_unsigned NOT NULL,
+          number_of_answers smallint_unsigned DEFAULT 1 NOT NULL
+        );");
+    
+      /**
+       * Quiz specific options concerning  availability and access to scores.
+       */
+        // Create the quiz node results table
+        db_query("CREATE TABLE {quiz_node_results} (
+          result_id SERIAL,
+          nid int_unsigned NOT NULL,
+          vid int_unsigned NOT NULL,
+          uid int_unsigned NOT NULL,
+          time_start int_unsigned DEFAULT 0,
+          time_end int_unsigned DEFAULT 0,
+          released int_unsigned DEFAULT 0,
+          score smallint NOT NULL DEFAULT 0,
+          PRIMARY KEY(result_id)
+        );");
+    
+      /**
+       * Information about a particular question in a result
+       */
+        db_query("CREATE TABLE {quiz_node_results_answers} (
+          result_id int_unsigned NOT NULL ,
+          question_nid int_unsigned NOT NULL ,
+          question_vid int_unsigned NOT NULL ,
+          is_correct smallint_unsigned NOT NULL DEFAULT '0',
+          points_awarded smallint NOT NULL DEFAULT '0',
+          answer_timestamp int_unsigned NOT NULL,
+          PRIMARY KEY(result_id, question_nid, question_vid)
+        );");
+    
+      /**
+       * Allows custom feedback based on the results of a user completing a quiz.
+       */
+        // Create the quiz node result options table
+        db_query("CREATE TABLE {quiz_node_result_options} (
+          option_id SERIAL,
+          nid int_unsigned NOT NULL,
+          vid int_unsigned NOT NULL,
+          option_name VARCHAR(255) NOT NULL,
+          option_summary TEXT,
+          option_start int_unsigned DEFAULT 0,
+          option_end int_unsigned DEFAULT 0,
+          PRIMARY KEY(option_id)
+        );");
+
+        db_query("CREATE FUNCTION plus_bigint_smallint_unsigned(bigint,smallint_unsigned)
+          RETURNS bigint AS 'select $1 + $2::bigint'
+          LANGUAGE 'sql';");
+
+        db_query("CREATE OPERATOR + ( 
+          PROCEDURE = plus_bigint_smallint_unsigned, 
+          LEFTARG = bigint, 
+          RIGHTARG = smallint_unsigned );");
       break;
   }
+  // Default the "Show Author and Date" for quiz nodes to OFF.
+  $temp_array = variable_get('theme_settings', $default);
+  $temp_array['toggle_node_info_quiz'] = 0;
+  variable_set('theme_settings', $temp_array);
 }
 
 /**
@@ -129,8 +235,20 @@
   db_query('DROP TABLE {quiz_node_result_options}');
   db_query('DROP TABLE {quiz_node_results_answers}');
   
-  // delete from nodes and node_revisions
-  db_query('DELETE FROM node, node_revisions USING node LEFT JOIN node_revisions USING (nid) WHERE type IN ("quiz")');
+  switch ($GLOBALS['db_type']) {
+    case 'mysql':
+    case 'mysqli':
+      // delete from nodes and node_revisions
+      db_query('DELETE FROM {node}, {node_revisions} USING {node} LEFT JOIN {node_revisions} USING (nid) WHERE type IN ("quiz")');
+      break;
+    case 'pgsql':
+      // delete from nodes and node_revisions
+      db_query("DELETE FROM {node_revisions} WHERE nid IN (SELECT nid FROM {node} WHERE type IN ('quiz'))");
+      db_query("DELETE FROM {node} WHERE type IN ('quiz')");
+      db_query("DROP OPERATOR + ( LEFTARG = bigint, RIGHTARG = smallint_unsigned );");
+      db_query("DROP FUNCTION plus_bigint_smallint_unsigned(bigint,smallint_unsigned);");
+      break;
+  }
 
   variable_del('quiz_name');
   variable_del('quiz_default_close');
Index: quiz.module
===================================================================
RCS file: /cvs/drupal/contributions/modules/quiz/quiz.module,v
retrieving revision 1.129
diff -u -r1.129 quiz.module
--- quiz.module	19 Dec 2007 08:07:49 -0000	1.129
+++ quiz.module	31 Dec 2007 12:06:54 -0000
@@ -679,7 +679,7 @@
     SELECT nr.nid, qnr.question_status 
   FROM {quiz_node_relationship} qnr 
   INNER JOIN {node_revisions} nr ON (qnr.parent_vid = nr.vid AND qnr.parent_nid = nr.nid)
-  WHERE qnr.parent_vid = %d AND qnr.parent_nid', $quiz_vid, $node->nid);
+  WHERE qnr.parent_vid = %d AND qnr.parent_nid = %d', $quiz_vid, $node->nid);
   while ($question = db_fetch_object($results)) {
     $additions->status[$question->child_nid] = $question->status;
   }
@@ -853,10 +853,10 @@
   global $user;
   $results = array();
   $dbresult = db_query("SELECT
-                          n.nid nid,
-                          n.title title,
-                          u.name name,
-                          qnrs.result_id result_id,
+                          n.nid as nid,
+                          n.title as title,
+                          u.name as name,
+                          qnrs.result_id as result_id,
                           qnrs.time_start,
                           qnrs.time_end
                         FROM {node} n, {quiz_node_properties} qnp, {quiz_node_results} qnrs, {users} u
@@ -1257,7 +1257,7 @@
   $questions = array();
 
   // Get required questions first.
-  $result = db_query("SELECT child_nid nid, child_vid vid FROM {quiz_node_relationship} WHERE parent_vid = %d AND parent_nid = %d AND question_status = %d", $quiz->vid, $quiz->nid, QUESTION_ALWAYS);
+  $result = db_query("SELECT child_nid as nid, child_vid as vid FROM {quiz_node_relationship} WHERE parent_vid = %d AND parent_nid = %d AND question_status = %d", $quiz->vid, $quiz->nid, QUESTION_ALWAYS);
   while ($question_node = db_fetch_array($result)) {
     $questions[] = $question_node;
   }
@@ -1305,7 +1305,7 @@
     }
     else {
       // Select random question from assigned pool.
-      $result = db_query_range("SELECT child_nid nid, child_vid vid FROM {quiz_node_relationship} WHERE parent_vid = %d AND parent_nid = %d AND question_status = %d ORDER BY RAND()", $quiz->vid, $quiz->nid, QUESTION_RANDOM, 0, $quiz->number_of_random_questions);
+      $result = db_query_range("SELECT child_nid as nid, child_vid as vid FROM {quiz_node_relationship} WHERE parent_vid = %d AND parent_nid = %d AND question_status = %d ORDER BY RAND()", $quiz->vid, $quiz->nid, QUESTION_RANDOM, 0, $quiz->number_of_random_questions);
     }
     while ($question_node = db_fetch_array($result)) {
       $questions[] = $question_node;
@@ -1950,10 +1950,10 @@
 function _quiz_get_results($nid = '', $uid = 0) {
   $results = array();
   $args = array();
-  $sql = "SELECT n.nid nid,
-                 n.title title,
-                 u.name name,
-                 qnrs.result_id result_id,
+  $sql = "SELECT n.nid as nid,
+                 n.title as title,
+                 u.name as name,
+                 qnrs.result_id as result_id,
                  qnrs.time_start,
                  qnrs.time_end
           FROM {node} n, {quiz_node_properties} qnp, {quiz_node_results} qnrs, {users} u
