Common subdirectories: /tmp/contributions/modules/quiz/CVS and /var/www/contributions/modules/quiz/CVS
Common subdirectories: /tmp/contributions/modules/quiz/images and /var/www/contributions/modules/quiz/images
diff -uN /tmp/contributions/modules/quiz/multichoice.install /var/www/contributions/modules/quiz/multichoice.install
--- /tmp/contributions/modules/quiz/multichoice.install	2007-09-01 04:08:14.000000000 +0300
+++ /var/www/contributions/modules/quiz/multichoice.install	2007-09-25 18:46:37.000000000 +0200
@@ -40,7 +40,41 @@
       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)
+      ) /*!40100 DEFAULT CHARACTER SET utf8 */;");	  
+	  
+	  
+	  /**
+	   * Stores user answers for multichoice quiz.
+	   */
+      // Create the quiz node answers multichoice table
+      db_query("CREATE TABLE {quiz_multichoice_answers} (
+        answer_id INT_UNSIGNED NOT NULL ,
+        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)
+      ) /*!40100 DEFAULT CHARACTER SET utf8 */;");	
+      db_query("CREATE sequence quiz_multichoice_user_answers_question_nid_seq;");
+      db_query("CREATE sequence quiz_multichoice_answers_answer_id_seq;");
+      db_query("create function ifnull (text, text) returns text AS '
+				select coalesce($1, $2) as result
+				' language 'sql';");
+      db_query("create function ifnull (int4, int4) returns int4 as '
+				select coalesce($1, $2) as result
+				' language 'sql';");
       break;
 	  
   }
@@ -52,6 +86,22 @@
 function multichoice_uninstall() {
   db_query('DROP TABLE {quiz_multichoice_user_answers}');
   db_query('DROP TABLE {quiz_multichoice_answers}');
-  // 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':
+		  // 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")');
+ 		break;
+ 	case 'pgsql':
+ 		db_query("DELETE   FROM  node_revisions nr USING node n WHERE n.nid=nr.nid and n.\"type\" IN ('multichoice');");
+ 		db_query("DELETE   FROM  quiz_node_question_properties np USING node n WHERE n.nid=np.nid and n.\"type\" IN ('multichoice');");
+		db_query("DELETE FROM node WHERE \"type\" IN ('multichoice');");
+ 		db_query("DROP sequence quiz_multichoice_user_answers_question_nid_seq;");
+      	db_query("DROP sequence quiz_multichoice_answers_answer_id_seq;");
+      	db_query("drop function ifnull (text, text);");
+      	db_query("drop function ifnull (int4, int4);");
+      		
+ 		break;
+  }	 
 }
diff -uN /tmp/contributions/modules/quiz/quiz.install /var/www/contributions/modules/quiz/quiz.install
--- /tmp/contributions/modules/quiz/quiz.install	2007-09-12 21:09:04.000000000 +0300
+++ /var/www/contributions/modules/quiz/quiz.install	2007-09-25 20:00:27.000000000 +0200
@@ -111,9 +111,109 @@
       break;
 
     case 'pgsql':
-  
+    	
+    	db_query("CREATE sequence quiz_node_properties_property_id_seq;");
+      	db_query("CREATE sequence quiz_node_result_options_option_id_seq;");
+      	db_query("CREATE sequence quiz_node_results_result_id_seq;");
+    	
+  		db_query("CREATE TABLE {quiz_node_properties} (
+        property_id INT_UNSIGNED NOT NULL default nextval('quiz_node_properties_property_id_seq'),
+        vid INT_UNSIGNED NOT NULL,
+        nid INT_UNSIGNED NOT NULL,
+        number_of_random_questions INT 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  DEFAULT 0,
+        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 INT2 NOT NULL default 0,
+        tid INT_UNSIGNED NOT NULL DEFAULT 0,
+        PRIMARY KEY(property_id)
+       ) /*!40100 DEFAULT CHARACTER SET utf8 */;");
+
+    /**
+     * 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)
+      ) /*!40100 DEFAULT CHARACTER SET utf8 */;");
+    
+    /**
+     * 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
+      ) /*!40100 DEFAULT CHARACTER SET utf8 */;");
+    
+    /**
+     * Quiz specific options concerning  availability and access to scores.
+     */
+      // Create the quiz node results table
+      db_query("CREATE TABLE {quiz_node_results} (
+        result_id INT_UNSIGNED NOT NULL ,
+        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 INT2 NOT NULL DEFAULT 0,
+        PRIMARY KEY(result_id)
+      ) /*!40100 DEFAULT CHARACTER SET utf8 */;");    
+    
+    /**
+     * 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 INT2 NOT NULL DEFAULT '0',
+        answer_timestamp INT_UNSIGNED NOT NULL,
+        PRIMARY KEY(result_id, question_nid, question_vid)
+      ) /*!40100 DEFAULT CHARACTER SET utf8 */;");
+    
+    /**
+     * 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 INT_UNSIGNED NOT NULL ,
+        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)
+      ) /*!40100 DEFAULT CHARACTER SET utf8 */;");   
+      
+      
+      db_query("CREATE INDEX vid ON quiz_node_properties (vid, nid);");
       break;
-  }
+  } 
 }
 
 /**
@@ -127,9 +227,24 @@
   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':
+		 
+      db_query("DROP sequence quiz_node_properties_property_id_seq;");
+      db_query("DROP sequence quiz_node_result_options_option_id_seq;");
+      db_query("DROP sequence quiz_node_results_result_id_seq;");
+      
+		db_query("DELETE   FROM  node_revisions nr USING node n WHERE n.nid=nr.nid and n.\"type\" IN ('quiz');");
+		db_query("DELETE FROM node WHERE \"type\" IN ('quiz');");
+	break;
+  }
+	
+	
   variable_del('quiz_name');
   variable_del('quiz_default_close');
   variable_del('quiz_use_passfail');
@@ -156,6 +271,23 @@
         PRIMARY KEY (nid, option_id)
       ) /*!40100 DEFAULT CHARACTER SET utf8 */;");
       break;
+      case 'pgsql':
+      	
+      	// add a result option to the answer table
+      $ret[] = update_sql("ALTER TABLE {quiz_question_answer} ADD result_option INTEGER UNSIGNED NULL");
+
+      // Create the result options table
+      $ret[] = update_sql("CREATE TABLE {quiz_result_options} (
+        nid INT_UNSIGNED NOT NULL,
+        option_id INT_UNSIGNED NOT NULL,
+        option_name VARCHAR(255) character set utf8 NOT NULL,
+        option_summary TEXT character set utf8 NOT NULL,
+        option_start smallint_unsigned NULL,
+        option_end smallint_unsigned NULL,
+        PRIMARY KEY (nid, option_id)
+      ) /*!40100 DEFAULT CHARACTER SET utf8 */;");
+      db_query("CREATE sequence quiz_node_result_options_option_id_seq;");
+      break;
   }
   return $ret;
 }
diff -uN /tmp/contributions/modules/quiz/quiz.module /var/www/contributions/modules/quiz/quiz.module
--- /tmp/contributions/modules/quiz/quiz.module	2007-09-21 02:10:07.000000000 +0200
+++ /var/www/contributions/modules/quiz/quiz.module	2007-09-25 19:38:05.000000000 +0200
@@ -642,7 +642,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 is not null', $quiz_vid, $node->nid);
   while ($question = db_fetch_object($results)) {
     $additions->status[$question->child_nid] = $question->status; 
   }
@@ -816,10 +816,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
@@ -1201,7 +1201,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;
   }
@@ -1250,7 +1250,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;
@@ -1880,10 +1880,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
