generated from karsten.jeppesen/KAJE-Template
Quizzer: Redesigned journal
Will now handle infinite size quizzes
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Quizzer.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// This is the database model for the journal, which is used to store the quiz results and other related information. It is used to display the quiz results in the journal page and to store the quiz results in the database.
|
||||
/// </summary>
|
||||
public class Journal
|
||||
{
|
||||
public string PID { get; set; }
|
||||
@@ -11,6 +14,26 @@ namespace Quizzer.Models
|
||||
public bool Anonymous { get; set; }
|
||||
public int Score { get; set; }
|
||||
public int ScoreAcc { get; set; }
|
||||
// This is the JSON string that contains the quiz results, which is used to display the quiz results in the journal page. It is also used to store the quiz results in the database.
|
||||
// The JSON string is in the following format:
|
||||
// {
|
||||
// "items": [
|
||||
// {
|
||||
// "itemID": "1",
|
||||
// "isOpen": 1,
|
||||
// "score": 1,
|
||||
// "maxScore": 1,
|
||||
// "replyMC": [true, false, false, false]
|
||||
// },
|
||||
// {
|
||||
// "itemID": "2",
|
||||
// "isOpen": 0,
|
||||
// "score": 0,
|
||||
// "maxScore": 1,
|
||||
// "replyMC": [false, false, false, false]
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
public string JournalJson { get; set; }
|
||||
}
|
||||
|
||||
@@ -23,9 +46,44 @@ namespace Quizzer.Models
|
||||
public List<bool> ReplyMC { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used for web page building
|
||||
/// </summary>
|
||||
public class JournalHtml
|
||||
{
|
||||
public Journal Journal { get; set; }
|
||||
public Journal2 Journal { get; set; }
|
||||
public string Text { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Table for the journal. One is created for each test available to the PID.
|
||||
/// </summary>
|
||||
[Table("Journal2")]
|
||||
public class Journal2
|
||||
{
|
||||
public string PID { get; set; } // VARCHAR 256 Primary key
|
||||
public string QuizzID { get; set; } // VARCHAR 50 Primary key
|
||||
public string Category { get; set; } // VARCHAR 50
|
||||
public int IsOpen { get; set; } // INT 11
|
||||
public bool Anonymous { get; set; } // INT 11
|
||||
public int Score { get; set; } // INT 11
|
||||
public int ScoreAcc { get; set; } // INT 11
|
||||
public List<Journal2Item> Items { get; set; } // This field does not store in the DB, but is serialized to JSON and stored in the JournalJson field of the JournalHead table. The JSON string is in the following format: {"items": [{"itemID": "1", "isOpen": 1, "score": 1, "maxScore": 1, "replyMC": [true, false, false, false]}, {"itemID": "2", "isOpen": 0, "score": 0, "maxScore": 1, "replyMC": [false, false, false, false]}]}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// One is created for each question in the test, and linked to the JournalHead by the QuizzID and PID. The ItemID is used to identify the question in the test, and the IsOpen, Score, MaxScore, and ReplyMCJson are used to store the quiz results for that question.
|
||||
/// </summary>
|
||||
[Table("Journal2Item")]
|
||||
public class Journal2Item
|
||||
{
|
||||
public string PID { get; set; } // VARCHAR 256, Foreign key to the JournalHead table. Primary key
|
||||
public string QuizzID { get; set; } // VARCHAR 50, Foreign key to the JournalHead table. Primary key
|
||||
public required string QuestionID { get; set; } // VARCHAR 50, used to identify the question in the test. Primary key
|
||||
public int IsOpen { get; set; } // INT 11, used to indicate whether the question is open or not.
|
||||
public int Score { get; set; } // INT 11, used to store the score for the question.
|
||||
public int MaxScore { get; set; } // INT 11, used to store the maximum score for the question.
|
||||
public List<bool> ReplyMC { get; set; } // This field does not store in the DB, but is serialized to JSON and stored in the JournalJson field of the JournalHead table. The JSON string is in the following format: [true, false, false, false]
|
||||
public string ReplyMCJson { get; set; } // VARCHAR 512, used to store the JSON string for the ReplyMC field. The JSON string is in the following format: [true, false, false, false]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,11 +133,11 @@ namespace Quizzer.Pages
|
||||
foreach (Quizz theQuizz in dbManager.GetQuizzesClass(theClass))
|
||||
{
|
||||
// Make sure that for a quizz is generated for this individual
|
||||
Journal theJournal = dbManager.GetJournal(UserID, theQuizz.QuizzId);
|
||||
Journal2 theJournal = dbManager.GetJournal2(UserID, theQuizz.QuizzId);
|
||||
if (theJournal == null)
|
||||
{
|
||||
// Make up a new journal
|
||||
Journal newJournal = new()
|
||||
Journal2 newJournal = new()
|
||||
{
|
||||
PID = UserID,
|
||||
QuizzID = theQuizz.QuizzId,
|
||||
@@ -148,7 +148,7 @@ namespace Quizzer.Pages
|
||||
ScoreAcc = 0,
|
||||
};
|
||||
//List<Item>items = JsonConvert.DeserializeObject<List<Item>>(theJournal.JournalJson);
|
||||
List<Item> myItemList = new();
|
||||
newJournal.Items = new();
|
||||
List<Question> myQuestions = PopulateQList(theQuizz.Category);
|
||||
//List<Question> myQuestions = dbManager.GetQuestions(theQuizz.Category);
|
||||
int theSize = (myQuestions.Count < theQuizz.QSize) ? myQuestions.Count : theQuizz.QSize;
|
||||
@@ -168,16 +168,15 @@ namespace Quizzer.Pages
|
||||
foreach (Question question in myQuestions)
|
||||
{
|
||||
newJournal.ScoreAcc++;
|
||||
myItemList.Add(new Item
|
||||
newJournal.Items.Add(new Journal2Item
|
||||
{
|
||||
ItemID = question.QuestionID,
|
||||
QuestionID = question.QuestionID,
|
||||
IsOpen = 1,
|
||||
Score = 0,
|
||||
MaxScore = 1,
|
||||
});
|
||||
}
|
||||
newJournal.JournalJson = JsonConvert.SerializeObject(myItemList);
|
||||
dbManager.PostJournal(newJournal);
|
||||
dbManager.PostJournal2(newJournal);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -185,8 +184,8 @@ namespace Quizzer.Pages
|
||||
private void BuildTestSelection()
|
||||
{
|
||||
List<JournalHtml> myTests = new();
|
||||
List<Journal> myJournals = dbManager.GetJournal(UserID);
|
||||
foreach (Journal myJournal in myJournals)
|
||||
List<Journal2> myJournals = dbManager.GetJournal2(UserID);
|
||||
foreach (Journal2 myJournal in myJournals)
|
||||
{
|
||||
Quizz theQuizz = dbManager.GetQuizz(myJournal.QuizzID);
|
||||
if (theQuizz == null) continue;
|
||||
@@ -202,20 +201,20 @@ namespace Quizzer.Pages
|
||||
|
||||
private bool PresentQuestion()
|
||||
{
|
||||
Journal myJournal = dbManager.GetJournal(UserID, PageQuizzID);
|
||||
Journal2 myJournal = dbManager.GetJournal2(UserID, PageQuizzID);
|
||||
if (myJournal == null)
|
||||
{
|
||||
Response.Cookies.Delete("PageQuizzID");
|
||||
return false;
|
||||
}
|
||||
List<Item> myItems = JsonConvert.DeserializeObject<List<Item>>(myJournal.JournalJson);
|
||||
//List<Item> myItems = JsonConvert.DeserializeObject<List<Item>>(myJournal.JournalJson);
|
||||
Random rnd = new Random();
|
||||
foreach (var item in myItems)
|
||||
foreach (var item in myJournal.Items)
|
||||
{
|
||||
if (item.IsOpen == 1)
|
||||
{
|
||||
// Get the question
|
||||
MCQuestion myMCQuestion = dbManager.GetMCQuestion(item.ItemID);
|
||||
MCQuestion myMCQuestion = dbManager.GetMCQuestion(item.QuestionID);
|
||||
List<int> myRndSeq = new List<int>();
|
||||
for (int indx = 0; indx < myMCQuestion.AList.Count(); indx++)
|
||||
{
|
||||
@@ -239,23 +238,21 @@ namespace Quizzer.Pages
|
||||
|
||||
private void FinalizeTest()
|
||||
{
|
||||
Journal myJournal = dbManager.GetJournal(UserID, PageQuizzID);
|
||||
List<Item> myItems = JsonConvert.DeserializeObject<List<Item>>(myJournal.JournalJson);
|
||||
Journal2 myJournal = dbManager.GetJournal2(UserID, PageQuizzID);
|
||||
myJournal.IsOpen = 0;
|
||||
dbManager.UpdateJournal(myJournal);
|
||||
dbManager.UpdateJournal2(myJournal);
|
||||
Response.Cookies.Delete("PageQuizzID");
|
||||
}
|
||||
|
||||
private void RegisterAnswer()
|
||||
{
|
||||
Journal myJournal = dbManager.GetJournal(UserID, PageQuizzID);
|
||||
List<Item> myItems = JsonConvert.DeserializeObject<List<Item>>(myJournal.JournalJson);
|
||||
foreach (var item in myItems)
|
||||
Journal2 myJournal = dbManager.GetJournal2(UserID, PageQuizzID);
|
||||
foreach (var item in myJournal.Items)
|
||||
{
|
||||
if (item.IsOpen == 1)
|
||||
{
|
||||
// Get the question
|
||||
MCQuestion myMCQuestion = dbManager.GetMCQuestion(item.ItemID);
|
||||
MCQuestion myMCQuestion = dbManager.GetMCQuestion(item.QuestionID);
|
||||
if (myMCQuestion != null)
|
||||
{
|
||||
int theScore = item.MaxScore;
|
||||
@@ -271,15 +268,14 @@ namespace Quizzer.Pages
|
||||
item.Score = theScore;
|
||||
myJournal.Score += theScore;
|
||||
item.IsOpen = 0;
|
||||
myJournal.JournalJson = JsonConvert.SerializeObject(myItems);
|
||||
dbManager.UpdateJournal(myJournal);
|
||||
dbManager.UpdateJournal2(myJournal);
|
||||
// Now register statistics
|
||||
List<int> counter = new List<int>();
|
||||
for (int indx = 0; indx < myMCQuestion.AList.Count(); indx++)
|
||||
{
|
||||
if (PageMCQuestion.AList[indx].Aok) { counter.Add(1); } else { counter.Add(0); }
|
||||
}
|
||||
dbManager.UpdateStats(PageQuizzID, item.ItemID, counter);
|
||||
dbManager.UpdateStats(PageQuizzID, item.QuestionID, counter);
|
||||
PageMCQuestion.AList.Clear();
|
||||
}
|
||||
return;
|
||||
@@ -293,20 +289,19 @@ namespace Quizzer.Pages
|
||||
PageMCQuestionReview = new();
|
||||
PageMCResponseReview = new();
|
||||
List<StatisticsStudentByCategory> StatStudent = new();
|
||||
Journal myJournal = dbManager.GetJournal(UserID, PageQuizzID);
|
||||
Journal2 myJournal = dbManager.GetJournal2(UserID, PageQuizzID);
|
||||
if (myJournal == null)
|
||||
{
|
||||
Response.Cookies.Delete("PageQuizzID");
|
||||
return;
|
||||
}
|
||||
List<Item> myItems = JsonConvert.DeserializeObject<List<Item>>(myJournal.JournalJson);
|
||||
|
||||
for (int index = 0; index < myItems.Count; index++)
|
||||
for (int index = 0; index < myJournal.Items.Count; index++)
|
||||
{
|
||||
string background;
|
||||
MCQuestion question = dbManager.GetMCQuestion(myItems[index].ItemID);
|
||||
MCQuestion question = dbManager.GetMCQuestion(myJournal.Items[index].QuestionID);
|
||||
PageMCQuestionReview.Add(question);
|
||||
PageMCResponseReview.Add(myItems[index].ReplyMC);
|
||||
PageMCResponseReview.Add(myJournal.Items[index].ReplyMC);
|
||||
// create statistics
|
||||
StatisticsStudentByCategory theStat = StatStudent.Find(x => x.CategoryID == question.Category);
|
||||
if (theStat == null)
|
||||
@@ -315,7 +310,7 @@ namespace Quizzer.Pages
|
||||
StatStudent.Add(new StatisticsStudentByCategory { CategoryID = cat.CId, CategoryName = cat.Txt });
|
||||
theStat = StatStudent[StatStudent.Count - 1];
|
||||
}
|
||||
theStat.Update(myItems[index].Score, myItems[index].MaxScore);
|
||||
theStat.Update(myJournal.Items[index].Score, myJournal.Items[index].MaxScore);
|
||||
// https://social.msdn.microsoft.com/Forums/en-US/7f96525d-7253-4f08-87f8-88ae526834f9/razor-pages-with-chartjs?forum=aspdotnetcore
|
||||
PageChartConnectors = new List<ChartConnector>();
|
||||
//background = "getRandomColor()";
|
||||
@@ -439,7 +434,7 @@ namespace Quizzer.Pages
|
||||
RegisterAnswer();
|
||||
break;
|
||||
case "deleteMyTest": //Student should not be able to delete journal as this resets the journal
|
||||
dbManager.DeleteJournal(UserID, target);
|
||||
dbManager.DeleteJournal2(UserID, target);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -47,6 +47,8 @@ namespace Quizzer.Persistens
|
||||
myDbConnection.Execute("CREATE TABLE IF NOT EXISTS `TheClasss` ( `Name` varchar(50) DEFAULT NULL ) ENGINE=InnoDB COLLATE='utf8mb4_general_ci'");
|
||||
myDbConnection.Execute("CREATE TABLE IF NOT EXISTS `Coverage` ( `Email` VARCHAR(50) NOT NULL DEFAULT 'ERR' COLLATE 'utf8mb4_general_ci', `Name` VARCHAR(50) NOT NULL DEFAULT 'ERR' COLLATE 'utf8mb4_general_ci', `Date` VARCHAR(50) NOT NULL DEFAULT 'ERR' COLLATE 'utf8mb4_general_ci', `TheClass` VARCHAR(50) NOT NULL DEFAULT 'ERR' COLLATE 'utf8mb4_general_ci', PRIMARY KEY (`Email`, `Name`, `Date`) USING BTREE ) COLLATE='utf8mb4_general_ci' ENGINE=InnoDB");
|
||||
myDbConnection.Execute("CREATE TABLE IF NOT EXISTS `Images` ( `MD5` VARCHAR(36) NOT NULL DEFAULT 'ERR', `UID` VARCHAR(50) NOT NULL DEFAULT 'ERR', `Encoding` VARCHAR(16) NULL DEFAULT NULL, `Txt` VARCHAR(256) NULL DEFAULT NULL, PRIMARY KEY (`MD5`, `UID`) ) COLLATE='utf8mb4_general_ci'");
|
||||
myDbConnection.Execute("CREATE TABLE IF NOT EXISTS `Journal2s` (`PID` VARCHAR(256) NOT NULL DEFAULT 'ERROR' COLLATE 'utf8mb4_general_ci',`QuizzID` VARCHAR(50) NOT NULL DEFAULT 'ERROR' COLLATE 'utf8mb4_general_ci',`Category` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',`IsOpen` INT(11) NULL DEFAULT NULL,`Anonymous` INT(11) NULL DEFAULT NULL,`Score` INT(11) NULL DEFAULT NULL,`ScoreAcc` INT(11) NULL DEFAULT NULL,PRIMARY KEY (`PID`, `QuizzID`) USING BTREE) COLLATE='utf8mb4_general_ci'");
|
||||
myDbConnection.Execute("CREATE TABLE IF NOT EXISTS `Journal2Items` (`PID` VARCHAR(256) NOT NULL DEFAULT 'ERROR' COLLATE 'utf8mb4_general_ci',`QuizzID` VARCHAR(50) NOT NULL DEFAULT 'ERROR' COLLATE 'utf8mb4_general_ci',`QuestionID` VARCHAR(50) NOT NULL DEFAULT 'ERROR' COLLATE 'utf8mb4_general_ci',`IsOpen` INT(11) NULL DEFAULT NULL,`Score` INT(11) NULL DEFAULT NULL,`MaxScore` INT(11) NULL DEFAULT NULL,`ReplyMCJson` VARCHAR(512) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',PRIMARY KEY (`PID`, `QuizzID`, `QuestionID`) USING BTREE ) COLLATE='utf8mb4_general_ci'");
|
||||
}
|
||||
|
||||
private string GetGuid()
|
||||
@@ -54,6 +56,62 @@ namespace Quizzer.Persistens
|
||||
return System.Guid.NewGuid().ToString();
|
||||
}
|
||||
|
||||
#endregion General
|
||||
|
||||
|
||||
#region Question
|
||||
|
||||
public List<Question> GetQuestions()
|
||||
{
|
||||
using var myDbConnection = new MySqlConnection(GetConnectionString());
|
||||
try
|
||||
{
|
||||
myDbConnection.Open();
|
||||
return myDbConnection.GetAll<Question>().AsList();
|
||||
}
|
||||
catch (MySqlException ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Question GetQuestion(string questionID)
|
||||
{
|
||||
using var myDbConnection = new MySqlConnection(GetConnectionString());
|
||||
try
|
||||
{
|
||||
myDbConnection.Open();
|
||||
return myDbConnection.QueryFirstOrDefault<Question>("SELECT * FROM Questions WHERE QuestionID = @questionID", new
|
||||
{
|
||||
questionID
|
||||
});
|
||||
}
|
||||
catch (MySqlException ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<Question> GetQuestions(string category)
|
||||
{
|
||||
using var myDbConnection = new MySqlConnection(GetConnectionString());
|
||||
try
|
||||
{
|
||||
myDbConnection.Open();
|
||||
return myDbConnection.Query<Question>("SELECT * FROM Questions WHERE Category = @theCat ORDER BY QuestionText ASC", new
|
||||
{
|
||||
theCat = category
|
||||
}).AsList();
|
||||
}
|
||||
catch (MySqlException ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Question> GetQuestionList()
|
||||
{
|
||||
List<Question> myList = new List<Question>();
|
||||
@@ -114,154 +172,6 @@ namespace Quizzer.Persistens
|
||||
return null;
|
||||
}
|
||||
|
||||
private string indentString = " ";
|
||||
|
||||
public string MakeCSubList(string asForm, string indent, string curSelect, ref List<Cat> cats, string theParent)
|
||||
{
|
||||
string myList = string.Empty;
|
||||
string selTxt;
|
||||
foreach (var item in cats)
|
||||
{
|
||||
if (item.CParentId == theParent)
|
||||
{
|
||||
string subList = MakeCSubList(asForm, indent + indentString, curSelect, ref cats, item.CId);
|
||||
switch (asForm)
|
||||
{
|
||||
case "radioBtn":
|
||||
if (item.CId == curSelect)
|
||||
selTxt = " checked";
|
||||
else
|
||||
selTxt = "";
|
||||
myList += "<div class=\"form - check\">\n" +
|
||||
" <input class=\"form - check - input\" type =\"radio\" name =\"categoryParent\" id =\"" +
|
||||
item.CId +
|
||||
"\" value =\"" +
|
||||
item.CId +
|
||||
"\" onclick=\"javascript: this.form.submit()\"" + selTxt + " > \n" +
|
||||
" <label class=\"form - check - label\" for=\"" + item.CId + "\" > \n" + indent + item.Txt + " </label>\n" +
|
||||
"</div>\n";
|
||||
if (subList != string.Empty)
|
||||
myList += subList;
|
||||
break;
|
||||
case "DropDown":
|
||||
case "DropDownIndented":
|
||||
if (item.CId == curSelect)
|
||||
selTxt = " selected";
|
||||
else
|
||||
selTxt = "";
|
||||
myList = myList + "<option value=\"" + item.CId + "\"" + selTxt + " >" + indent + item.Txt + " </option >";
|
||||
if (subList != string.Empty)
|
||||
myList += subList;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return myList;
|
||||
}
|
||||
public string MakeCList(string uid, string asForm, string curSelect)
|
||||
{
|
||||
DbOps qManager = new();
|
||||
List<Cat> cats = qManager.GetCats(uid);
|
||||
switch (asForm)
|
||||
{
|
||||
case "radioBtn":
|
||||
//return "<ul>" + MakeCSubList(asForm, "  ", curSelect, ref cats, "/") + "</ul>";
|
||||
return "<ul>" + MakeCSubList(asForm, "", curSelect, ref cats, "/") + "</ul>";
|
||||
case "DropDown":
|
||||
return "<select name=\"newCategory\" onchange=\"javascript: this.form.submit()\">" +
|
||||
"<option value=\"\">Please select</option>" +
|
||||
MakeCSubList(asForm, "  ", curSelect, ref cats, "/") +
|
||||
"</select>";
|
||||
case "DropDownIndented":
|
||||
return "<select name=\"newCategory\" onchange=\"javascript: this.form.submit()\">" +
|
||||
"<option value=\"\">Please select</option>" +
|
||||
MakeCSubList(asForm, " ", curSelect, ref cats, "/") +
|
||||
"</select>";
|
||||
default:
|
||||
return "<p>MakeCList form error: " + asForm + "</p>";
|
||||
}
|
||||
}
|
||||
public Cat SetCat(string uid, string parentTagID, string newTagName)
|
||||
{
|
||||
Cat myCat = new();
|
||||
myCat.CParentId = parentTagID;
|
||||
myCat.UID = uid;
|
||||
myCat.Txt = newTagName;
|
||||
myCat.CId = GetGuid();
|
||||
// doesn't map TId fild // myDbConnection.Insert<Tag>(myTag);
|
||||
using var myDbConnection = new MySqlConnection(GetConnectionString());
|
||||
try
|
||||
{
|
||||
myDbConnection.Open();
|
||||
int rowsAffected = myDbConnection.Execute("INSERT INTO Cats (CId, UID, CParentID, Txt) VALUES(@CId, @UID, @CParentID, @Txt)", myCat);
|
||||
return myCat;
|
||||
}
|
||||
catch (MySqlException ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion General
|
||||
|
||||
|
||||
#region Question
|
||||
|
||||
public List<Question> GetQuestions()
|
||||
{
|
||||
using var myDbConnection = new MySqlConnection(GetConnectionString());
|
||||
try
|
||||
{
|
||||
myDbConnection.Open();
|
||||
return myDbConnection.GetAll<Question>().AsList();
|
||||
}
|
||||
catch (MySqlException ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Question GetQuestion(string questionID)
|
||||
{
|
||||
using var myDbConnection = new MySqlConnection(GetConnectionString());
|
||||
try
|
||||
{
|
||||
myDbConnection.Open();
|
||||
return myDbConnection.QueryFirstOrDefault<Question>("SELECT * FROM Questions WHERE QuestionID = @questionID", new
|
||||
{
|
||||
questionID
|
||||
});
|
||||
}
|
||||
catch (MySqlException ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<Question> GetQuestions(string category)
|
||||
{
|
||||
using var myDbConnection = new MySqlConnection(GetConnectionString());
|
||||
try
|
||||
{
|
||||
myDbConnection.Open();
|
||||
return myDbConnection.Query<Question>("SELECT * FROM Questions WHERE Category = @theCat ORDER BY QuestionText ASC", new
|
||||
{
|
||||
theCat = category
|
||||
}).AsList();
|
||||
}
|
||||
catch (MySqlException ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void DeleteQuestion(string questionID)
|
||||
{
|
||||
using var myDbConnection = new MySqlConnection(GetConnectionString());
|
||||
@@ -391,6 +301,99 @@ namespace Quizzer.Persistens
|
||||
|
||||
#region Category
|
||||
|
||||
private string indentString = " ";
|
||||
|
||||
public string MakeCSubList(string asForm, string indent, string curSelect, ref List<Cat> cats, string theParent)
|
||||
{
|
||||
string myList = string.Empty;
|
||||
string selTxt;
|
||||
foreach (var item in cats)
|
||||
{
|
||||
if (item.CParentId == theParent)
|
||||
{
|
||||
string subList = MakeCSubList(asForm, indent + indentString, curSelect, ref cats, item.CId);
|
||||
switch (asForm)
|
||||
{
|
||||
case "radioBtn":
|
||||
if (item.CId == curSelect)
|
||||
selTxt = " checked";
|
||||
else
|
||||
selTxt = "";
|
||||
myList += "<div class=\"form - check\">\n" +
|
||||
" <input class=\"form - check - input\" type =\"radio\" name =\"categoryParent\" id =\"" +
|
||||
item.CId +
|
||||
"\" value =\"" +
|
||||
item.CId +
|
||||
"\" onclick=\"javascript: this.form.submit()\"" + selTxt + " > \n" +
|
||||
" <label class=\"form - check - label\" for=\"" + item.CId + "\" > \n" + indent + item.Txt + " </label>\n" +
|
||||
"</div>\n";
|
||||
if (subList != string.Empty)
|
||||
myList += subList;
|
||||
break;
|
||||
case "DropDown":
|
||||
case "DropDownIndented":
|
||||
if (item.CId == curSelect)
|
||||
selTxt = " selected";
|
||||
else
|
||||
selTxt = "";
|
||||
myList = myList + "<option value=\"" + item.CId + "\"" + selTxt + " >" + indent + item.Txt + " </option >";
|
||||
if (subList != string.Empty)
|
||||
myList += subList;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return myList;
|
||||
}
|
||||
public string MakeCList(string uid, string asForm, string curSelect)
|
||||
{
|
||||
DbOps qManager = new();
|
||||
List<Cat> cats = qManager.GetCats(uid);
|
||||
switch (asForm)
|
||||
{
|
||||
case "radioBtn":
|
||||
//return "<ul>" + MakeCSubList(asForm, "  ", curSelect, ref cats, "/") + "</ul>";
|
||||
return "<ul>" + MakeCSubList(asForm, "", curSelect, ref cats, "/") + "</ul>";
|
||||
case "DropDown":
|
||||
return "<select name=\"newCategory\" onchange=\"javascript: this.form.submit()\">" +
|
||||
"<option value=\"\">Please select</option>" +
|
||||
MakeCSubList(asForm, "  ", curSelect, ref cats, "/") +
|
||||
"</select>";
|
||||
case "DropDownIndented":
|
||||
return "<select name=\"newCategory\" onchange=\"javascript: this.form.submit()\">" +
|
||||
"<option value=\"\">Please select</option>" +
|
||||
MakeCSubList(asForm, " ", curSelect, ref cats, "/") +
|
||||
"</select>";
|
||||
default:
|
||||
return "<p>MakeCList form error: " + asForm + "</p>";
|
||||
}
|
||||
}
|
||||
|
||||
public Cat SetCat(string uid, string parentTagID, string newTagName)
|
||||
{
|
||||
Cat myCat = new();
|
||||
myCat.CParentId = parentTagID;
|
||||
myCat.UID = uid;
|
||||
myCat.Txt = newTagName;
|
||||
myCat.CId = GetGuid();
|
||||
// doesn't map TId fild // myDbConnection.Insert<Tag>(myTag);
|
||||
using var myDbConnection = new MySqlConnection(GetConnectionString());
|
||||
try
|
||||
{
|
||||
myDbConnection.Open();
|
||||
int rowsAffected = myDbConnection.Execute("INSERT INTO Cats (CId, UID, CParentID, Txt) VALUES(@CId, @UID, @CParentID, @Txt)", myCat);
|
||||
return myCat;
|
||||
}
|
||||
catch (MySqlException ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<Cat> GetCats(string uid)
|
||||
{
|
||||
using var myDbConnection = new MySqlConnection(GetConnectionString());
|
||||
@@ -659,6 +662,12 @@ namespace Quizzer.Persistens
|
||||
|
||||
#region Journal
|
||||
|
||||
/// <summary>
|
||||
/// Get the journal for a specific quiz and a specific user. Returns null if no journal exists for that quiz and user.
|
||||
/// </summary>
|
||||
/// <param name="thePID"></param>
|
||||
/// <param name="theQuizzID"></param>
|
||||
/// <returns></returns>
|
||||
public Journal GetJournal(string thePID, string theQuizzID)
|
||||
{
|
||||
string sql = "SELECT * FROM Journals WHERE PID = '" + thePID + "' AND QuizzID = '" + theQuizzID + "'";
|
||||
@@ -680,6 +689,11 @@ namespace Quizzer.Persistens
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get all journals for a specific user. Returns null if no journal exists for that user.
|
||||
/// </summary>
|
||||
/// <param name="thePID"></param>
|
||||
/// <returns></returns>
|
||||
public List<Journal> GetJournal(string thePID)
|
||||
{
|
||||
string sql = "SELECT * FROM Journals WHERE PID = '" + thePID + "'";
|
||||
@@ -697,6 +711,10 @@ namespace Quizzer.Persistens
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update journal. Journal is identified by PID and QuizzID. If no journal exists for that PID and QuizzID, nothing happens.
|
||||
/// </summary>
|
||||
/// <param name="theJournal"></param>
|
||||
public void UpdateJournal(Journal theJournal)
|
||||
{
|
||||
using var myDbConnection = new MySqlConnection(GetConnectionString());
|
||||
@@ -720,6 +738,10 @@ namespace Quizzer.Persistens
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Insert journal. If a journal already exists for that PID and QuizzID, nothing happens.
|
||||
/// </summary>
|
||||
/// <param name="theJournal"></param>
|
||||
public void PostJournal(Journal theJournal)
|
||||
{
|
||||
using var myDbConnection = new MySqlConnection(GetConnectionString());
|
||||
@@ -745,6 +767,11 @@ namespace Quizzer.Persistens
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get all journals for a specific quiz. Returns null if no journal exists for that quiz.
|
||||
/// </summary>
|
||||
/// <param name="quizzID"></param>
|
||||
/// <returns></returns>
|
||||
public List<Journal> GetJournals(string quizzID)
|
||||
{
|
||||
using var myDbConnection = new MySqlConnection(GetConnectionString());
|
||||
@@ -760,6 +787,10 @@ namespace Quizzer.Persistens
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the journal entry associated with the specified quiz identifier.
|
||||
/// </summary>
|
||||
/// <param name="quizzID">The unique identifier of the quiz whose journal entry is to be deleted.</param>
|
||||
public void DeleteJournalByQuizz(string quizzID)
|
||||
{
|
||||
using var myDbConnection = new MySqlConnection(GetConnectionString());
|
||||
@@ -773,6 +804,12 @@ namespace Quizzer.Persistens
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the journal entry associated with the specified participant identifier and quiz identifier.
|
||||
/// </summary>
|
||||
/// <param name="pID"></param>
|
||||
/// <param name="quizzID"></param>
|
||||
public void DeleteJournal(string pID, string quizzID)
|
||||
{
|
||||
using var myDbConnection = new MySqlConnection(GetConnectionString());
|
||||
@@ -787,6 +824,171 @@ namespace Quizzer.Persistens
|
||||
|
||||
#endregion Journal
|
||||
|
||||
#region Journal2
|
||||
|
||||
// JOURNAL2 is an alternative journal table with same structure as Journal, but with different name. This is used for testing purposes, to avoid conflicts with the original Journal table. It is not used in production.
|
||||
|
||||
/// <summary>
|
||||
/// Get the journal for a specific quiz and a specific user. Returns null if no journal exists for that quiz and user.
|
||||
/// </summary>
|
||||
/// <param name="thePID"></param>
|
||||
/// <param name="theQuizzID"></param>
|
||||
/// <returns></returns>
|
||||
public Journal2 GetJournal2(string thePID, string theQuizzID)
|
||||
{
|
||||
string sqlJ = $"SELECT * FROM Journal2s WHERE PID = '{thePID}' AND QuizzID = '{theQuizzID}'";
|
||||
string sqlI = $"SELECT * FROM Journal2Items WHERE PID = '{thePID}' AND QuizzID = '{theQuizzID}'";
|
||||
using var myDbConnection = new MySqlConnection(GetConnectionString());
|
||||
try
|
||||
{
|
||||
myDbConnection.Open();
|
||||
// Get the journal entry, general part.
|
||||
var theJournal = myDbConnection.QueryFirstOrDefault<Journal2>(sqlJ);
|
||||
if (theJournal == null) return null;
|
||||
// Get the journal items.
|
||||
theJournal.Items = myDbConnection.Query<Journal2Item>(sqlI).AsList();
|
||||
//theJournal.Items.Sort((x, y) => x.QuestionID.CompareTo(y.QuestionID));
|
||||
if (theJournal.Items != null)
|
||||
{
|
||||
foreach (var item in theJournal.Items)
|
||||
{
|
||||
item.ReplyMC = JsonConvert.DeserializeObject<List<bool>>(item.ReplyMCJson);
|
||||
}
|
||||
}
|
||||
return theJournal;
|
||||
}
|
||||
catch
|
||||
{
|
||||
myDbConnection.Close();
|
||||
CreateIfNotExist(myDbConnection); // must be in cosed state
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get all journals for a specific user. Returns null if no journal exists for that user.
|
||||
/// </summary>
|
||||
/// <param name="thePID"></param>
|
||||
/// <returns></returns>
|
||||
public List<Journal2> GetJournal2(string thePID)
|
||||
{
|
||||
string sqlJ = $"SELECT * FROM Journal2s WHERE PID = '{thePID}'";
|
||||
using var myDbConnection = new MySqlConnection(GetConnectionString());
|
||||
try
|
||||
{
|
||||
myDbConnection.Open();
|
||||
List<Journal2> result = myDbConnection.Query<Journal2>(sqlJ).AsList();
|
||||
return result;
|
||||
}
|
||||
catch (MySqlException ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update journal. Journal is identified by PID and QuizzID. If no journal exists for that PID and QuizzID, nothing happens.
|
||||
/// </summary>
|
||||
/// <param name="theJournal"></param>
|
||||
public void UpdateJournal2(Journal2 theJournal)
|
||||
{
|
||||
using var myDbConnection = new MySqlConnection(GetConnectionString());
|
||||
try
|
||||
{
|
||||
myDbConnection.Open();
|
||||
myDbConnection.Execute("UPDATE Journal2s SET IsOpen = @IsOpen, Score = @Score WHERE PID=@PID AND QuizzID = @QuizzID", theJournal);
|
||||
foreach (var item in theJournal.Items)
|
||||
{
|
||||
item.ReplyMCJson = JsonConvert.SerializeObject(item.ReplyMC);
|
||||
myDbConnection.Execute("UPDATE Journal2Items SET IsOpen = @IsOpen, Score = @Score, MaxScore = @MaxScore, ReplyMCJson = @ReplyMCJson WHERE PID = @PID AND QuizzID = @QuizzID AND QuestionID = @QuestionID", item);
|
||||
}
|
||||
}
|
||||
catch (MySqlException ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Insert journal. If a journal already exists for that PID and QuizzID, nothing happens.
|
||||
/// </summary>
|
||||
/// <param name="theJournal"></param>
|
||||
public void PostJournal2(Journal2 theJournal)
|
||||
{
|
||||
using var myDbConnection = new MySqlConnection(GetConnectionString());
|
||||
try
|
||||
{
|
||||
myDbConnection.Open();
|
||||
myDbConnection.Execute("INSERT INTO Journal2s (PID, QuizzID, Category, Anonymous, IsOpen, Score, ScoreAcc) VALUES(@PID,@QuizzID,@Category,@Anonymous,@IsOpen,@Score,@ScoreAcc)", new
|
||||
{
|
||||
PID = theJournal.PID,
|
||||
QuizzID = theJournal.QuizzID,
|
||||
Category = theJournal.Category,
|
||||
Anonymous = theJournal.Anonymous,
|
||||
IsOpen = theJournal.IsOpen,
|
||||
Score = theJournal.Score,
|
||||
ScoreAcc = theJournal.ScoreAcc,
|
||||
});
|
||||
|
||||
// Must populate the Journal2Items table with the items of the journal
|
||||
if (theJournal.Items != null)
|
||||
{
|
||||
foreach (var item in theJournal.Items)
|
||||
{
|
||||
item.PID = theJournal.PID;
|
||||
item.QuizzID = theJournal.QuizzID;
|
||||
item.ReplyMCJson = JsonConvert.SerializeObject(item.ReplyMC);
|
||||
myDbConnection.Execute("INSERT INTO Journal2Items (PID, QuizzID, QuestionID, IsOpen, Score, MaxScore, ReplyMCJson) VALUES(@PID, @QuizzID, @QuestionID, @IsOpen, @Score, @MaxScore, @ReplyMCJson)", item);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (MySqlException ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the journal entry associated with the specified quiz identifier.
|
||||
/// </summary>
|
||||
/// <param name="quizzID">The unique identifier of the quiz whose journal entry is to be deleted.</param>
|
||||
public void DeleteJournalByQuizz2(string quizzID)
|
||||
{
|
||||
using var myDbConnection = new MySqlConnection(GetConnectionString());
|
||||
try
|
||||
{
|
||||
myDbConnection.Open();
|
||||
myDbConnection.Delete(quizzID);
|
||||
}
|
||||
catch (MySqlException ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the journal entry associated with the specified participant identifier and quiz identifier.
|
||||
/// </summary>
|
||||
/// <param name="pID"></param>
|
||||
/// <param name="quizzID"></param>
|
||||
public void DeleteJournal2(string pID, string quizzID)
|
||||
{
|
||||
using var myDbConnection = new MySqlConnection(GetConnectionString());
|
||||
try { myDbConnection.Open(); }
|
||||
catch (MySqlException ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
return;
|
||||
}
|
||||
myDbConnection.Execute("DELETE FROM Journal2s WHERE PID = @PID AND QuizzID = @QuizzID", new { PID = pID, QuizzID = quizzID });
|
||||
myDbConnection.Execute("DELETE FROM Journal2Items WHERE PID = @PID AND QuizzID = @QuizzID", new { PID = pID, QuizzID = quizzID });
|
||||
}
|
||||
|
||||
#endregion Journal2
|
||||
|
||||
|
||||
#region Statistic
|
||||
|
||||
|
||||
Reference in New Issue
Block a user