From 963919bc82501e0e2699694c54b48202249e82c7 Mon Sep 17 00:00:00 2001 From: acanas Date: Sun, 26 Apr 2020 03:07:55 +0200 Subject: [PATCH] Version19.198 --- sql/swad.sql | 4 +- swad_changelog.h | 8 ++- swad_database.c | 8 +-- swad_exam.c | 135 ++++++++++++++++++++++++++++++++++++++-------- swad_exam.h | 6 +-- swad_exam_event.c | 2 +- swad_text.c | 21 ++++++++ 7 files changed, 151 insertions(+), 33 deletions(-) diff --git a/sql/swad.sql b/sql/swad.sql index 5f53e6d3b..222ed9c0b 100644 --- a/sql/swad.sql +++ b/sql/swad.sql @@ -515,10 +515,10 @@ CREATE TABLE IF NOT EXISTS exa_participants ( -- Table exa_questions: stores the questions in the exams -- CREATE TABLE IF NOT EXISTS exa_questions ( - ExaCod INT NOT NULL, + SetCod INT NOT NULL, QstCod INT NOT NULL, QstInd INT NOT NULL DEFAULT 0, - INDEX(ExaCod), + INDEX(SetCod), INDEX(QstCod)); -- -- Table exa_results: stores exam results diff --git a/swad_changelog.h b/swad_changelog.h index c4e03bb79..b627b433f 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -544,10 +544,16 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - * En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 19.197 (2020-04-26)" +#define Log_PLATFORM_VERSION "SWAD 19.198 (2020-04-26)" #define CSS_FILE "swad19.193.1.css" #define JS_FILE "swad19.193.1.js" /* + Version 19.198: Apr 26, 2020 Remove set of questions. (299054 lines) + 3 changes necessary in database: +ALTER TABLE exa_questions DROP INDEX ExaCod; +ALTER TABLE exa_questions CHANGE COLUMN ExaCod SetCod INT NOT NULL; +ALTER TABLE exa_questions ADD INDEX(SetCod); + Version 19.197: Apr 26, 2020 Ask user to remove set of questions. (298954 lines) Version 19.196.1: Apr 25, 2020 Changes in edition of exams. (298857 lines) Version 19.196: Apr 25, 2020 Changes in edition of sets of questions. (298866 lines) diff --git a/swad_database.c b/swad_database.c index 82a940c99..49caee07d 100644 --- a/swad_database.c +++ b/swad_database.c @@ -1143,17 +1143,17 @@ mysql> DESCRIBE exa_questions; +--------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+---------+------+-----+---------+-------+ -| ExaCod | int(11) | NO | MUL | NULL | | +| SetCod | int(11) | NO | MUL | NULL | | | QstCod | int(11) | NO | MUL | NULL | | | QstInd | int(11) | NO | | 0 | | +--------+---------+------+-----+---------+-------+ -3 rows in set (0.01 sec) +3 rows in set (0.00 sec) */ DB_CreateTable ("CREATE TABLE IF NOT EXISTS exa_questions (" - "ExaCod INT NOT NULL," + "SetCod INT NOT NULL," "QstCod INT NOT NULL," "QstInd INT NOT NULL DEFAULT 0," - "INDEX(ExaCod)," + "INDEX(SetCod)," "INDEX(QstCod))"); /***** Table exa_results *****/ diff --git a/swad_exam.c b/swad_exam.c index 05a984a62..0e2de98e4 100644 --- a/swad_exam.c +++ b/swad_exam.c @@ -241,6 +241,7 @@ void Exa_ResetExam (struct Exa_Exam *Exam) Exam->TimeUTC[Dat_START_TIME] = (time_t) 0; Exam->TimeUTC[Dat_END_TIME ] = (time_t) 0; Exam->Title[0] = '\0'; + Exam->NumSets = 0; Exam->NumQsts = 0; Exam->NumEvts = 0; Exam->NumUnfinishedEvts = 0; @@ -545,7 +546,7 @@ static void Exa_ShowOneExam (struct Exa_Exams *Exams, struct Exa_Exam *Exam,bool ShowOnlyThisExam) { extern const char *Txt_View_exam; - extern const char *Txt_No_of_questions; + extern const char *Txt_Set_of_questions; extern const char *Txt_Maximum_grade; extern const char *Txt_Result_visibility; extern const char *Txt_Events; @@ -629,8 +630,8 @@ static void Exa_ShowOneExam (struct Exa_Exams *Exams, /* Number of questions, maximum grade, visibility of results */ HTM_DIV_Begin ("class=\"%s\"",Exam->Hidden ? "ASG_GRP_LIGHT" : "ASG_GRP"); - HTM_TxtColonNBSP (Txt_No_of_questions); - HTM_Unsigned (Exam->NumQsts); + HTM_TxtColonNBSP (Txt_Set_of_questions); + HTM_Unsigned (Exam->NumSets); HTM_BR (); HTM_TxtColonNBSP (Txt_Maximum_grade); HTM_Double (Exam->MaxGrade); @@ -1044,20 +1045,18 @@ void ExaSet_GetDataOfSetByCod (struct ExaSet_Set *Set) { MYSQL_RES *mysql_res; MYSQL_ROW row; - unsigned long NumRows; char StrSetInd[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; /***** Get data of set of questions from database *****/ - NumRows = DB_QuerySELECT (&mysql_res,"can not get set data", - "SELECT SetCod," // row[0] - "SetInd," // row[1] - "NumQstsToExam," // row[2] - "Title" // row[3] - " FROM exa_sets" - " WHERE SetCod=%ld" - " AND ExaCod=%ld", // Extra check - Set->SetCod,Set->ExaCod); - if (NumRows) // Set found... + if (DB_QuerySELECT (&mysql_res,"can not get set data", + "SELECT SetCod," // row[0] + "SetInd," // row[1] + "NumQstsToExam," // row[2] + "Title" // row[3] + " FROM exa_sets" + " WHERE SetCod=%ld" + " AND ExaCod=%ld", // Extra check + Set->SetCod,Set->ExaCod)) // Set found... { /* Get row */ row = mysql_fetch_row (mysql_res); @@ -1144,8 +1143,11 @@ void Exa_GetDataOfExamByCod (struct Exa_Exam *Exam) Str_Copy (Exam->Title,row[6], Exa_MAX_BYTES_TITLE); + /* Get number of sets */ + Exam->NumSets = ExaSet_GetNumSetsExam (Exam->ExaCod); + /* Get number of questions */ - Exam->NumQsts = Exa_GetNumQstsExam (Exam->ExaCod); + Exam->NumQsts = ExaSet_GetNumQstsExam (Exam->ExaCod); /* Get number of events */ Exam->NumEvts = ExaEvt_GetNumEventsInExam (Exam->ExaCod); @@ -1640,7 +1642,7 @@ void ExaSet_RecFormSet (void) if (Exams.ExaCod <= 0) Lay_WrongExamExit (); Set.ExaCod = Exam.ExaCod = Exams.ExaCod; - Set.SetCod = ExaSet_GetParamSetCod (); + Exams.SetCod = Set.SetCod = ExaSet_GetParamSetCod (); ItsANewSet = (Set.SetCod <= 0); /***** Get exam data from database *****/ @@ -2023,16 +2025,44 @@ static void Exa_UpdateExam (struct Exa_Exam *Exam,const char *Txt) /******************* Get number of questions of an exam *********************/ /*****************************************************************************/ -unsigned Exa_GetNumQstsExam (long ExaCod) +unsigned ExaSet_GetNumSetsExam (long ExaCod) { - /***** Get nuumber of questions in an exam from database *****/ + /***** Get number of sets in an exam from database *****/ return - (unsigned) DB_QueryCOUNT ("can not get number of questions of an exam", - "SELECT COUNT(*) FROM exa_questions" + (unsigned) DB_QueryCOUNT ("can not get number of sets in an exam", + "SELECT COUNT(*) FROM exa_sets" " WHERE ExaCod=%ld", ExaCod); } +/*****************************************************************************/ +/******************* Get number of questions of an exam *********************/ +/*****************************************************************************/ + +unsigned ExaSet_GetNumQstsExam (long ExaCod) + { + MYSQL_RES *mysql_res; + MYSQL_ROW row; + unsigned NumQsts = 0; + + /***** Get total number of questions to appear in exam *****/ + if (!DB_QuerySELECT (&mysql_res,"can not get number of questions in an exam", + "SELECT SUM(NumQstsToExam) FROM exa_sets" + " WHERE ExaCod=%ld", + ExaCod)) + Lay_ShowErrorAndExit ("Error: wrong question index."); + + /***** Get number of questions (row[0]) *****/ + row = mysql_fetch_row (mysql_res); + if (row[0]) + NumQsts = Str_ConvertStrToUnsigned (row[0]); + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); + + return NumQsts; + } + /*****************************************************************************/ /********** Request the creation or edition of an set of questions ***********/ /*****************************************************************************/ @@ -2061,7 +2091,8 @@ void ExaSet_RequestCreatOrEditSet (void) if (Exams.ExaCod <= 0) Lay_WrongExamExit (); Exam.ExaCod = Exams.ExaCod; - ItsANewSet = ((Set.SetCod = ExaSet_GetParamSetCod ()) <= 0); + Exams.SetCod = Set.SetCod = ExaSet_GetParamSetCod (); + ItsANewSet = (Set.SetCod <= 0); /***** Get exam data from database *****/ Exa_GetDataOfExamByCod (&Exam); @@ -3025,7 +3056,7 @@ void ExaSet_RequestRemoveSet (void) if (Exams.ExaCod <= 0) Lay_WrongExamExit (); Set.ExaCod = Exam.ExaCod = Exams.ExaCod; - Set.SetCod = ExaSet_GetParamSetCod (); + Exams.SetCod = Set.SetCod = ExaSet_GetParamSetCod (); if (Set.SetCod <= 0) Lay_WrongSetExit (); @@ -3055,6 +3086,66 @@ void ExaSet_RequestRemoveSet (void) void ExaSet_RemoveSet (void) { + extern const char *Txt_Set_of_questions_removed; + struct Exa_Exams Exams; + struct Exa_Exam Exam; + struct ExaSet_Set Set; + + /***** Reset exams context *****/ + Exa_ResetExams (&Exams); + + /***** Reset exam and set *****/ + Exa_ResetExam (&Exam); + ExaSet_ResetSet (&Set); + + /***** Get parameters *****/ + Exa_GetParams (&Exams); + if (Exams.ExaCod <= 0) + Lay_WrongExamExit (); + Set.ExaCod = Exam.ExaCod = Exams.ExaCod; + Set.SetCod = ExaSet_GetParamSetCod (); + if (Set.SetCod <= 0) + Lay_WrongSetExit (); + + /***** Get exam data from database *****/ + Exa_GetDataOfExamByCod (&Exam); + if (!Exa_CheckIfEditable (&Exam)) + Lay_NoPermissionExit (); + + /***** Get set data from database *****/ + ExaSet_GetDataOfSetByCod (&Set); + + /***** Remove the set from all the tables *****/ + /* Remove questions associated to set */ + DB_QueryDELETE ("can not remove questions associated to set", + "DELETE FROM exa_questions" + " USING exa_questions,exa_sets" + " WHERE exa_questions.SetCod=%ld" + " AND exa_questions.SetCod=exa_sets.SetCod" + " AND exa_sets.ExaCod=%ld", // Extra check + Set.SetCod,Set.ExaCod); + + /* Remove the set itself */ + DB_QueryDELETE ("can not remove set", + "DELETE FROM exa_sets" + " WHERE SetCod=%ld" + " AND ExaCod=%ld", // Extra check + Set.SetCod,Set.ExaCod); + if (!mysql_affected_rows (&Gbl.mysql)) + Lay_ShowErrorAndExit ("The set to be removed does not exist."); + + /* Change index of sets greater than this */ + DB_QueryUPDATE ("can not update indexes of sets", + "UPDATE exa_sets SET SetInd=SetInd-1" + " WHERE ExaCod=%ld AND SetInd>%u", + Set.ExaCod,Set.SetInd); + + /***** Write message *****/ + Ale_ShowAlert (Ale_SUCCESS,Txt_Set_of_questions_removed); + + /***** Show current exam and its sets *****/ + Exa_PutFormsOneExam (&Exams,&Exam,&Set, + false); // It's not a new exam } /*****************************************************************************/ diff --git a/swad_exam.h b/swad_exam.h index ecd1e9a1b..1221fbbbc 100644 --- a/swad_exam.h +++ b/swad_exam.h @@ -95,6 +95,7 @@ struct Exa_Exam char Title[Exa_MAX_BYTES_TITLE + 1]; time_t TimeUTC[Dat_NUM_START_END_TIME]; bool Hidden; // Exam is hidden + unsigned NumSets; // Number of sets in the exam unsigned NumQsts; // Number of questions in the exam unsigned NumEvts; // Number of events in the exam unsigned NumUnfinishedEvts; // Number of unfinished events in the exam @@ -154,9 +155,8 @@ void ExaSet_RecFormSet (void); void Exa_RecFormExam (void); bool Mch_CheckIfMatchIsAssociatedToGrp (long EvtCod,long GrpCod); -unsigned Exa_GetNumQstsExam (long ExaCod); - -void Exa_RequestNewSet (void); +unsigned ExaSet_GetNumSetsExam (long ExaCod); +unsigned ExaSet_GetNumQstsExam (long ExaCod); void ExaSet_RequestCreatOrEditSet (void); void Exa_RequestNewQuestion (void); diff --git a/swad_exam_event.c b/swad_exam_event.c index 2bf3125dc..a3089f026 100644 --- a/swad_exam_event.c +++ b/swad_exam_event.c @@ -2705,7 +2705,7 @@ static void ExaEvt_ShowNumQstInEvt (const struct ExaEvt_Event *Event) { extern const char *Txt_MATCH_Start; extern const char *Txt_MATCH_End; - unsigned NumQsts = Exa_GetNumQstsExam (Event->ExaCod); + unsigned NumQsts = ExaSet_GetNumQstsExam (Event->ExaCod); HTM_DIV_Begin ("class=\"EXA_NUM_QST\""); switch (Event->Status.Showing) diff --git a/swad_text.c b/swad_text.c index 790e28ea6..5c104049d 100644 --- a/swad_text.c +++ b/swad_text.c @@ -41046,6 +41046,27 @@ const char *Txt_Set_of_questions = "Conjunto de perguntas"; #endif +const char *Txt_Set_of_questions_removed = +#if L==1 // ca + "Conjunt de preguntes eliminat."; +#elif L==2 // de + "Satz von Fragen entfernt."; +#elif L==3 // en + "Set of questions removed."; +#elif L==4 // es + "Conjunto de preguntas eliminado."; +#elif L==5 // fr + "Ensemble de questions supprimé."; +#elif L==6 // gn + "Conjunto de preguntas eliminado."; // Okoteve traducción +#elif L==7 // it + "Set di domande rimosso."; +#elif L==8 // pl + "Zestaw pytań usuniete."; +#elif L==9 // pt + "Conjunto de perguntas removido."; +#endif + const char *Txt_Set_password = #if L==1 // ca "Establir contrasenya";