From ea02337e650af536562dab3271759d7280326a77 Mon Sep 17 00:00:00 2001 From: acanas Date: Tue, 20 Jul 2021 13:14:12 +0200 Subject: [PATCH] Version 20.95.3: Jul 20, 2021 Queries moved to module swad_exam_database. --- swad_changelog.h | 3 +- swad_exam.c | 5 +- swad_exam_database.c | 520 ++++++++++++++++++++++++++++++++++++++++++- swad_exam_database.h | 21 ++ swad_exam_session.c | 501 +++-------------------------------------- swad_exam_session.h | 10 - swad_group.c | 16 +- swad_match.c | 4 +- swad_match.h | 4 +- swad_survey.c | 38 ++-- swad_survey.h | 4 +- 11 files changed, 610 insertions(+), 516 deletions(-) diff --git a/swad_changelog.h b/swad_changelog.h index 9f1c3bb2..a860bf01 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -602,13 +602,14 @@ TODO: FIX BUG, URGENT! En las fechas como par TODO: En las encuestas, que los estudiantes no puedan ver los resultados hasta que no finalice el plazo. */ -#define Log_PLATFORM_VERSION "SWAD 20.95.2 (2021-07-16)" +#define Log_PLATFORM_VERSION "SWAD 20.95.3 (2021-07-20)" #define CSS_FILE "swad20.45.css" #define JS_FILE "swad20.69.1.js" /* TODO: Rename CENTRE to CENTER in help wiki. TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams + Version 20.95.3: Jul 20, 2021 Queries moved to module swad_exam_database. (314210 lines) Version 20.95.2: Jul 16, 2021 Queries moved to module swad_exam_database. (314137 lines) Version 20.95.1: Jul 15, 2021 Queries moved to module swad_exam_database. (314082 lines) Version 20.95: Jul 08, 2021 New module swad_exam_database for database queries related to exams. (313981 lines) diff --git a/swad_exam.c b/swad_exam.c index 81cfbf31..082a90c3 100644 --- a/swad_exam.c +++ b/swad_exam.c @@ -37,6 +37,7 @@ #include "swad_database.h" #include "swad_error.h" #include "swad_exam.h" +#include "swad_exam_database.h" #include "swad_exam_print.h" #include "swad_exam_result.h" #include "swad_exam_session.h" @@ -1000,10 +1001,10 @@ void Exa_GetDataOfExamByCod (struct Exa_Exam *Exam) Exam->NumQsts = Exa_DB_GetNumQstsExam (Exam->ExaCod); /* Get number of sessions */ - Exam->NumSess = ExaSes_GetNumSessionsInExam (Exam->ExaCod); + Exam->NumSess = Exa_DB_GetNumSessionsInExam (Exam->ExaCod); /* Get number of open sessions */ - Exam->NumOpenSess = ExaSes_GetNumOpenSessionsInExam (Exam->ExaCod); + Exam->NumOpenSess = Exa_DB_GetNumOpenSessionsInExam (Exam->ExaCod); } else /* Initialize to empty exam */ diff --git a/swad_exam_database.c b/swad_exam_database.c index ba2a83d1..b083e3ae 100644 --- a/swad_exam_database.c +++ b/swad_exam_database.c @@ -27,10 +27,7 @@ #define _GNU_SOURCE // For asprintf #include // For asprintf -//#include // For system, getenv, etc. -//#include // For string functions -//#include "swad_action.h" #include "swad_database.h" #include "swad_error.h" #include "swad_exam_database.h" @@ -60,6 +57,8 @@ extern struct Globals Gbl; /***************************** Private prototypes ****************************/ /*****************************************************************************/ +static void Exa_DB_RemoveUsrSesResultsInCrs (long UsrCod,long CrsCod,const char *TableName); + /*****************************************************************************/ /***************** Get sets of questions in a given exam *********************/ /*****************************************************************************/ @@ -141,6 +140,521 @@ unsigned Exa_DB_GetQstAnswersCorrFromSet (MYSQL_RES **mysql_res,long QstCod) QstCod); } +/*****************************************************************************/ +/************************* Create a new exam session *************************/ +/*****************************************************************************/ + +long Exa_DB_CreateSession (const struct ExaSes_Session *Session) + { + return + DB_QueryINSERTandReturnCode ("can not create exam session", + "INSERT exa_sessions" + " (ExaCod," + "Hidden," + "UsrCod," + "StartTime," + "EndTime," + "Title," + "ShowUsrResults)" + " VALUES" + " (%ld," // ExaCod + "'%c'," // Hidden + "%ld," // UsrCod + "FROM_UNIXTIME(%ld)," // Start time + "FROM_UNIXTIME(%ld)," // End time + "'%s'," // Title + "'N')", // ShowUsrResults: Don't show user results initially + Session->ExaCod, + Session->Hidden ? 'Y' : + 'N', + Gbl.Usrs.Me.UsrDat.UsrCod, // Session creator + Session->TimeUTC[Dat_START_TIME], // Start time + Session->TimeUTC[Dat_END_TIME ], // End time + Session->Title); + } + +/*****************************************************************************/ +/********************** Update an existing exam session **********************/ +/*****************************************************************************/ + +void Exa_DB_UpdateSession (const struct ExaSes_Session *Session) + { + /***** Insert this new exam session into database *****/ + DB_QueryUPDATE ("can not update exam session", + "UPDATE exa_sessions," + "exa_exams" + " SET exa_sessions.Hidden='%c'," + "exa_sessions.StartTime=FROM_UNIXTIME(%ld)," + "exa_sessions.EndTime=FROM_UNIXTIME(%ld)," + "exa_sessions.Title='%s'," + "exa_sessions.ShowUsrResults='%c'" + " WHERE exa_sessions.SesCod=%ld" + " AND exa_sessions.ExaCod=%ld" // Extra check + " AND exa_sessions.ExaCod=exa_exams.ExaCod" + " AND exa_exams.CrsCod=%ld", // Extra check + Session->Hidden ? 'Y' : + 'N', + Session->TimeUTC[Dat_START_TIME], // Start time + Session->TimeUTC[Dat_END_TIME ], // End time + Session->Title, + Session->ShowUsrResults ? 'Y' : + 'N', + Session->SesCod, + Session->ExaCod, + Gbl.Hierarchy.Crs.CrsCod); + } + +/*****************************************************************************/ +/********************* Get number of sessions in an exam *********************/ +/*****************************************************************************/ + +unsigned Exa_DB_GetNumSessionsInExam (long ExaCod) + { + /***** Trivial check *****/ + if (ExaCod < 0) // A non-existing exam... + return 0; // ...has no sessions + + /***** Get number of sessions in an exam from database *****/ + return (unsigned) + DB_QueryCOUNT ("can not get number of sessions of an exam", + "SELECT COUNT(*)" + " FROM exa_sessions" + " WHERE ExaCod=%ld", + ExaCod); + } + +/*****************************************************************************/ +/***************** Get number of open sessions in an exam ********************/ +/*****************************************************************************/ + +unsigned Exa_DB_GetNumOpenSessionsInExam (long ExaCod) + { + /***** Trivial check *****/ + if (ExaCod < 0) // A non-existing exam... + return 0; // ...has no sessions + + /***** Get number of open sessions in an exam from database *****/ + return (unsigned) + DB_QueryCOUNT ("can not get number of open sessions of an exam", + "SELECT COUNT(*)" + " FROM exa_sessions" + " WHERE ExaCod=%ld" + " AND NOW() BETWEEN StartTime AND EndTime", + ExaCod); + } + +/*****************************************************************************/ +/************************ List the sessions of an exam ***********************/ +/*****************************************************************************/ + +unsigned Exa_DB_GetSessions (MYSQL_RES **mysql_res,long ExaCod) + { + char *HiddenSubQuery; + char *GroupsSubQuery; + unsigned NumSessions; + + /***** Subquery: get hidden sessions depending on user's role *****/ + switch (Gbl.Usrs.Me.Role.Logged) + { + case Rol_STD: + if (asprintf (&HiddenSubQuery," AND Hidden='N'") < 0) + Err_NotEnoughMemoryExit (); + break; + case Rol_NET: + case Rol_TCH: + case Rol_DEG_ADM: + case Rol_CTR_ADM: + case Rol_INS_ADM: + case Rol_SYS_ADM: + if (asprintf (&HiddenSubQuery,"%s","") < 0) + Err_NotEnoughMemoryExit (); + break; + default: + Err_WrongRoleExit (); + break; + } + + /***** Subquery: get sessions depending on groups *****/ + if (Gbl.Crs.Grps.WhichGrps == Grp_MY_GROUPS) + { + if (asprintf (&GroupsSubQuery," AND" + "(SesCod NOT IN" + " (SELECT SesCod FROM exa_groups)" + " OR" + " SesCod IN" + " (SELECT exa_groups.SesCod" + " FROM exa_groups," + "grp_users" + " WHERE grp_users.UsrCod=%ld" + " AND exa_groups.GrpCod=grp_users.GrpCod))", + Gbl.Usrs.Me.UsrDat.UsrCod) < 0) + Err_NotEnoughMemoryExit (); + } + else // Gbl.Crs.Grps.WhichGrps == Grp_ALL_GROUPS + if (asprintf (&GroupsSubQuery,"%s","") < 0) + Err_NotEnoughMemoryExit (); + + /***** Get data of sessions from database *****/ + NumSessions = (unsigned) + DB_QuerySELECT (mysql_res,"can not get sessions", + "SELECT SesCod," // row[0] + "ExaCod," // row[1] + "Hidden," // row[2] + "UsrCod," // row[3] + "UNIX_TIMESTAMP(StartTime)," // row[4] + "UNIX_TIMESTAMP(EndTime)," // row[5] + "NOW() BETWEEN StartTime AND EndTime," // row[6] + "Title," // row[7] + "ShowUsrResults" // row[8] + " FROM exa_sessions" + " WHERE ExaCod=%ld%s%s" + " ORDER BY SesCod", + ExaCod, + HiddenSubQuery, + GroupsSubQuery); + + /***** Free allocated memory for subqueries *****/ + free (GroupsSubQuery); + free (HiddenSubQuery); + + return NumSessions; + } + +/*****************************************************************************/ +/******************* Get exam session data using its code ********************/ +/*****************************************************************************/ + +unsigned Exa_DB_GetDataOfSessionByCod (MYSQL_RES **mysql_res,long SesCod) + { + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get sessions", + "SELECT SesCod," // row[0] + "ExaCod," // row[1] + "Hidden," // row[2] + "UsrCod," // row[3] + "UNIX_TIMESTAMP(StartTime)," // row[4] + "UNIX_TIMESTAMP(EndTime)," // row[5] + "NOW() BETWEEN StartTime AND EndTime," // row[6] + "Title," // row[7] + "ShowUsrResults" // row[8] + " FROM exa_sessions" + " WHERE SesCod=%ld" + " AND ExaCod IN" // Extra check + " (SELECT ExaCod" + " FROM exa_exams" + " WHERE CrsCod='%ld')", + SesCod, + Gbl.Hierarchy.Crs.CrsCod); + } + +/*****************************************************************************/ +/***************** Toggle visibility of exam session results *****************/ +/*****************************************************************************/ + +void Exa_DB_ToggleVisResultsSesUsr (const struct ExaSes_Session *Session) + { + /***** Toggle visibility of exam session results *****/ + DB_QueryUPDATE ("can not toggle visibility of session results", + "UPDATE exa_sessions," + "exa_exams" + " SET exa_sessions.ShowUsrResults='%c'" + " WHERE exa_sessions.SesCod=%ld" + " AND exa_sessions.ExaCod=%ld" // Extra check + " AND exa_sessions.ExaCod=exa_exams.ExaCod" + " AND exa_exams.CrsCod=%ld", // Extra check + Session->ShowUsrResults ? 'Y' : + 'N', + Session->SesCod, + Session->ExaCod, + Gbl.Hierarchy.Crs.CrsCod); + } + +/*****************************************************************************/ +/******************************** Hide a session *****************************/ +/*****************************************************************************/ + +void Exa_DB_HideUnhideSession (const struct ExaSes_Session *Session,bool Hide) + { + DB_QueryUPDATE ("can not hide exam sessions", + "UPDATE exa_sessions," + "exa_exams" + " SET exa_sessions.Hidden='Y'" + " WHERE exa_sessions.SesCod=%ld" + " AND exa_sessions.ExaCod=%ld" // Extra check + " AND exa_sessions.ExaCod=exa_exams.ExaCod" + " AND exa_exams.CrsCod=%ld", // Extra check + Hide ? 'Y' : + 'N', + Session->SesCod, + Session->ExaCod, + Gbl.Hierarchy.Crs.CrsCod); + } + +/*****************************************************************************/ +/******************* Remove exam session from all tables *********************/ +/*****************************************************************************/ + +void Exa_DB_RemoveSessionFromAllTables (long SesCod) + { + /* To delete orphan exam prints: + // DELETE FROM exa_print_questions WHERE PrnCod IN (SELECT PrnCod FROM exa_prints WHERE SesCod NOT IN (SELECT SesCod FROM exa_sessions)); + // DELETE FROM exa_prints WHERE SesCod NOT IN (SELECT SesCod FROM exa_sessions); + */ + /***** Remove exam prints in this session *****/ + /* + * TODO: DO NOT REMOVE EXAMS PRINTS. Instead move them to tables of deleted prints + DB_QueryDELETE ("can not remove exam print questions in exam session", + "DELETE FROM exa_print_questions" + " USING exa_print_questions, + "exa_prints" + " WHERE exa_prints.SesCod=%ld" + " AND exa_prints.PrnCod=exa_print_questions.PrnCod", + SesCod); + DB_QueryDELETE ("can not remove exam prints in exam session", + "DELETE FROM exa_prints" + " WHERE exa_prints.SesCod=%ld", + SesCod); + */ + + /***** Remove groups associated to this exam session *****/ + DB_QueryDELETE ("can not remove groups associated to exam session", + "DELETE FROM exa_groups" + " WHERE SesCod=%ld", + SesCod); + + /***** Remove exam session from main table *****/ + DB_QueryDELETE ("can not remove exam session", + "DELETE FROM exa_sessions" + " WHERE SesCod=%ld", + SesCod); + } + +/*****************************************************************************/ +/**************** Remove exam session in exam from all tables ****************/ +/*****************************************************************************/ + +void Exa_DB_RemoveSessionsInExamFromAllTables (long ExaCod) + { + /***** Remove exam prints in this session *****/ + /* + * TODO: DO NOT REMOVE EXAMS PRINTS. Instead move them to tables of deleted prints + DB_QueryDELETE ("can not remove exam print questions in exam", + "DELETE FROM exa_print_questions" + " USING exa_print_questions, + "exa_prints, + "exa_sessions" + " WHERE exa_sessions.ExaCod=%ld" + " AND exa_sessions.SesCod=exa_prints.SesCod" + " AND exa_prints.PrnCod=exa_print_questions.PrnCod", + ExaCod); + DB_QueryDELETE ("can not remove exam prints in exam", + "DELETE FROM exa_prints" + " USING exa_prints, + "exa_sessions" + " WHERE exa_sessions.ExaCod=%ld" + " AND exa_sessions.SesCod=exa_prints.SesCod", + ExaCod); + */ + + /***** Remove groups associated to exam sessions of this exam *****/ + DB_QueryDELETE ("can not remove groups associated to sessions of an exam", + "DELETE FROM exa_groups" + " USING exa_sessions," + "exa_groups" + " WHERE exa_sessions.ExaCod=%ld" + " AND exa_sessions.SesCod=exa_groups.SesCod", + ExaCod); + + /***** Remove sessions from main table *****/ + DB_QueryDELETE ("can not remove sessions of an exam", + "DELETE FROM exa_sessions" + " WHERE ExaCod=%ld", + ExaCod); + } + +/*****************************************************************************/ +/*************** Remove exam session in course from all tables ***************/ +/*****************************************************************************/ + +void Exa_DB_RemoveSessionInCourseFromAllTables (long CrsCod) + { + /***** Remove exam prints in this course *****/ + /* + * TODO: DO NOT REMOVE EXAMS PRINTS. Instead move them to tables of deleted prints + DB_QueryDELETE ("can not remove exam print questions in course", + "DELETE FROM exa_print_questions" + " USING exa_print_questions, + "exa_prints, + "exa_sessions, + "exa_exams" + " WHERE exa_exams.CrsCod=%ld" + " AND exa_exams.ExaCod=exa_sessions" + " AND exa_sessions.SesCod=exa_prints.SesCod" + " AND exa_prints.PrnCod=exa_print_questions.PrnCod", + CrsCod); + DB_QueryDELETE ("can not remove exam print questions in course", + "DELETE FROM exa_prints" + " USING exa_prints, + "exa_sessions, + "exa_exams" + " WHERE exa_exams.CrsCod=%ld" + " AND exa_exams.ExaCod=exa_sessions" + " AND exa_sessions.SesCod=exa_prints.SesCod", + CrsCod); + */ + + /***** Remove sessions from table of sessions groups *****/ + DB_QueryDELETE ("can not remove sessions of a course", + "DELETE FROM exa_groups" + " USING exa_exams," + "exa_sessions," + "exa_groups" + " WHERE exa_exams.CrsCod=%ld" + " AND exa_exams.ExaCod=exa_sessions.ExaCod" + " AND exa_sessions.SesCod=exa_groups.SesCod", + CrsCod); + + /***** Remove sessions from exam sessions table *****/ + DB_QueryDELETE ("can not remove sessions of a course", + "DELETE FROM exa_sessions" + " USING exa_exams," + "exa_sessions" + " WHERE exa_exams.CrsCod=%ld" + " AND exa_exams.ExaCod=exa_sessions.ExaCod", + CrsCod); + } + +/*****************************************************************************/ +/************* Remove user from secondary exam session tables ****************/ +/*****************************************************************************/ + +void Exa_DB_RemoveUsrFromSessionTablesInCrs (long UsrCod,long CrsCod) + { + /***** Remove student from secondary tables *****/ + Exa_DB_RemoveUsrSesResultsInCrs (UsrCod,CrsCod,"exa_prints"); + } + +static void Exa_DB_RemoveUsrSesResultsInCrs (long UsrCod,long CrsCod,const char *TableName) + { + /***** Remove sessions in course from secondary table *****/ + DB_QueryDELETE ("can not remove sessions of a user from table", + "DELETE FROM %s" + " USING exa_exams," + "exa_sessions," + "%s" + " WHERE exa_exams.CrsCod=%ld" + " AND exa_exams.ExaCod=exa_sessions.ExaCod" + " AND exa_sessions.SesCod=%s.SesCod" + " AND %s.UsrCod=%ld", + TableName, + TableName, + CrsCod, + TableName, + TableName, + UsrCod); + } + +/*****************************************************************************/ +/**************** Create group associated to an exam session *****************/ +/*****************************************************************************/ + +void Exa_DB_CreateGrpAssociatedToSession (long SesCod,long GrpCod) + { + DB_QueryINSERT ("can not associate a group to an exam session", + "INSERT INTO exa_groups" + " (SesCod,GrpCod)" + " VALUES" + " (%ld,%ld)", + SesCod, + GrpCod); + } + +/*****************************************************************************/ +/*********** Get groups associated to an exam session from database **********/ +/*****************************************************************************/ + +unsigned Exa_DB_GetGrpsAssociatedToSession (MYSQL_RES **mysql_res,long SesCod) + { + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get groups of an exam session", + "SELECT grp_types.GrpTypName," // row[0] + "grp_groups.GrpName" // row[1] + " FROM exa_groups," + "grp_groups," + "grp_types" + " WHERE exa_groups.SesCod=%ld" + " AND exa_groups.GrpCod=grp_groups.GrpCod" + " AND grp_groups.GrpTypCod=grp_types.GrpTypCod" + " ORDER BY grp_types.GrpTypName," + "grp_groups.GrpName", + SesCod); + } + +/*****************************************************************************/ +/*** Check if I belong to any of the groups associated to the exam session ***/ +/*****************************************************************************/ + +bool Exa_DB_CheckIfICanListThisSessionBasedOnGrps (long SesCod) + { + return (DB_QueryCOUNT ("can not check if I can play an exam session", + "SELECT COUNT(*)" + " FROM exa_sessions" + " WHERE SesCod=%ld" + " AND (SesCod NOT IN" + " (SELECT SesCod FROM exa_groups)" + " OR" + " SesCod IN" + " (SELECT exa_groups.SesCod" + " FROM exa_groups," + "grp_users" + " WHERE grp_users.UsrCod=%ld" + " AND grp_users.GrpCod=exa_groups.GrpCod))", + SesCod, + Gbl.Usrs.Me.UsrDat.UsrCod) != 0); + } + +/*****************************************************************************/ +/******************** Remove all groups from one session *********************/ +/*****************************************************************************/ + +void Exa_DB_RemoveAllGrpsAssociatedToSession (long SesCod) + { + DB_QueryDELETE ("can not remove groups associated to a session", + "DELETE FROM exa_groups" + " WHERE SesCod=%ld", + SesCod); + } + +/*****************************************************************************/ +/**************** Remove groups of one type from all sessions ****************/ +/*****************************************************************************/ + +void Exa_DB_RemoveGroupsOfType (long GrpTypCod) + { + DB_QueryDELETE ("can not remove groups of a type" + " from the associations between sessions and groups", + "DELETE FROM exa_groups" + " USING grp_groups," + "exa_groups" + " WHERE grp_groups.GrpTypCod=%ld" + " AND grp_groups.GrpCod=exa_groups.GrpCod", + GrpTypCod); + } + +/*****************************************************************************/ +/******************** Remove one group from all sessions *********************/ +/*****************************************************************************/ + +void Exa_DB_RemoveGrpAssociatedToExamSessions (long GrpCod) + { + /***** Remove group from all the sessions *****/ + DB_QueryDELETE ("can not remove group" + " from the associations between sessions and groups", + "DELETE FROM exa_groups" + " WHERE GrpCod=%ld", + GrpCod); + } + /*****************************************************************************/ /***************** Create new blank exam print in database *******************/ /*****************************************************************************/ diff --git a/swad_exam_database.h b/swad_exam_database.h index 0a91f01d..2af9bd97 100644 --- a/swad_exam_database.h +++ b/swad_exam_database.h @@ -29,6 +29,7 @@ #include "swad_exam_log.h" #include "swad_exam_print.h" +#include "swad_exam_session.h" #include "swad_test_type.h" /*****************************************************************************/ @@ -46,6 +47,26 @@ unsigned Exa_DB_GetValidityAndTypeOfQuestion (MYSQL_RES **mysql_res,long QstCod) unsigned Exa_DB_GetQstAnswersTextFromSet (MYSQL_RES **mysql_res,long QstCod); unsigned Exa_DB_GetQstAnswersCorrFromSet (MYSQL_RES **mysql_res,long QstCod); +long Exa_DB_CreateSession (const struct ExaSes_Session *Session); +void Exa_DB_UpdateSession (const struct ExaSes_Session *Session); +unsigned Exa_DB_GetNumSessionsInExam (long ExaCod); +unsigned Exa_DB_GetNumOpenSessionsInExam (long ExaCod); +unsigned Exa_DB_GetSessions (MYSQL_RES **mysql_res,long ExaCod); +unsigned Exa_DB_GetDataOfSessionByCod (MYSQL_RES **mysql_res,long SesCod); +void Exa_DB_ToggleVisResultsSesUsr (const struct ExaSes_Session *Session); +void Exa_DB_HideUnhideSession (const struct ExaSes_Session *Session,bool Hide); +void Exa_DB_RemoveSessionFromAllTables (long SesCod); +void Exa_DB_RemoveSessionsInExamFromAllTables (long ExaCod); +void Exa_DB_RemoveSessionInCourseFromAllTables (long CrsCod); +void Exa_DB_RemoveUsrFromSessionTablesInCrs (long UsrCod,long CrsCod); + +void Exa_DB_CreateGrpAssociatedToSession (long SesCod,long GrpCod); +unsigned Exa_DB_GetGrpsAssociatedToSession (MYSQL_RES **mysql_res,long SesCod); +bool Exa_DB_CheckIfICanListThisSessionBasedOnGrps (long SesCod); +void Exa_DB_RemoveAllGrpsAssociatedToSession (long SesCod); +void Exa_DB_RemoveGroupsOfType (long GrpTypCod); +void Exa_DB_RemoveGrpAssociatedToExamSessions (long GrpCod); + long Exa_DB_CreatePrint (const struct ExaPrn_Print *Print); void Exa_DB_UpdatePrint (const struct ExaPrn_Print *Print); unsigned Exa_DB_GetDataOfPrintByPrnCod (MYSQL_RES **mysql_res,long PrnCod); diff --git a/swad_exam_session.c b/swad_exam_session.c index 27bbf46d..e8110c00 100644 --- a/swad_exam_session.c +++ b/swad_exam_session.c @@ -36,6 +36,7 @@ #include "swad_date.h" #include "swad_error.h" #include "swad_exam.h" +#include "swad_exam_database.h" #include "swad_exam_print.h" #include "swad_exam_result.h" #include "swad_exam_session.h" @@ -80,7 +81,7 @@ static void ExaSes_PutIconToCreateNewSession (struct Exa_Exams *Exams); static void ExaSes_ListOneOrMoreSessions (struct Exa_Exams *Exams, const struct Exa_Exam *Exam, - long EvtCodToBeEdited, + long SesCodToBeEdited, unsigned NumSessions, MYSQL_RES *mysql_res); static void ExaSes_ListOneOrMoreSessionsHeading (bool ICanEditSessions); @@ -108,17 +109,14 @@ static void ExaSes_ListOneOrMoreSessionsResultTch (struct Exa_Exams *Exams, static void ExaSes_GetSessionDataFromRow (MYSQL_RES *mysql_res, struct ExaSes_Session *Session); -static void Exa_DB_RemoveSessionFromAllTables (long SesCod); -static void Exa_DB_RemoveUsrSesResultsInCrs (long UsrCod,long CrsCod,const char *TableName); - static void ExaSes_PutFormSession (const struct ExaSes_Session *Session); static void ExaSes_ShowLstGrpsToCreateSession (long SesCod); static void ExaSes_CreateSession (struct ExaSes_Session *Session); static void ExaSes_UpdateSession (struct ExaSes_Session *Session); -static void Exa_DB_CreateGrpsAssociatedToExamSession (long SesCod,const struct ListCodGrps *LstGrpsSel); -static void Exa_DB_RemoveGrpsAssociatedToExamSession (long SesCod); +static void ExaSes_CreateGrpsAssociatedToExamSession (long SesCod, + const struct ListCodGrps *LstGrpsSel); /*****************************************************************************/ /***************************** Reset exam session ****************************/ @@ -153,74 +151,8 @@ void ExaSes_ListSessions (struct Exa_Exams *Exams, { extern const char *Hlp_ASSESSMENT_Exams_sessions; extern const char *Txt_Sessions; - char *HiddenSubQuery; - char *GroupsSubQuery; MYSQL_RES *mysql_res; unsigned NumSessions; - long SesCodToBeEdited; - bool PutFormNewSession; - - /***** Subquery: get hidden sessions depending on user's role *****/ - switch (Gbl.Usrs.Me.Role.Logged) - { - case Rol_STD: - if (asprintf (&HiddenSubQuery," AND Hidden='N'") < 0) - Err_NotEnoughMemoryExit (); - break; - case Rol_NET: - case Rol_TCH: - case Rol_DEG_ADM: - case Rol_CTR_ADM: - case Rol_INS_ADM: - case Rol_SYS_ADM: - if (asprintf (&HiddenSubQuery,"%s","") < 0) - Err_NotEnoughMemoryExit (); - break; - default: - Err_WrongRoleExit (); - break; - } - - /***** Subquery: get sessions depending on groups *****/ - if (Gbl.Crs.Grps.WhichGrps == Grp_MY_GROUPS) - { - if (asprintf (&GroupsSubQuery," AND" - "(SesCod NOT IN" - " (SELECT SesCod FROM exa_groups)" - " OR" - " SesCod IN" - " (SELECT exa_groups.SesCod" - " FROM exa_groups," - "grp_users" - " WHERE grp_users.UsrCod=%ld" - " AND exa_groups.GrpCod=grp_users.GrpCod))", - Gbl.Usrs.Me.UsrDat.UsrCod) < 0) - Err_NotEnoughMemoryExit (); - } - else // Gbl.Crs.Grps.WhichGrps == Grp_ALL_GROUPS - if (asprintf (&GroupsSubQuery,"%s","") < 0) - Err_NotEnoughMemoryExit (); - - /***** Get data of sessions from database *****/ - NumSessions = (unsigned) - DB_QuerySELECT (&mysql_res,"can not get sessions", - "SELECT SesCod," // row[0] - "ExaCod," // row[1] - "Hidden," // row[2] - "UsrCod," // row[3] - "UNIX_TIMESTAMP(StartTime)," // row[4] - "UNIX_TIMESTAMP(EndTime)," // row[5] - "NOW() BETWEEN StartTime AND EndTime," // row[6] - "Title," // row[7] - "ShowUsrResults" // row[8] - " FROM exa_sessions" - " WHERE ExaCod=%ld%s%s" - " ORDER BY SesCod", - Exam->ExaCod,HiddenSubQuery,GroupsSubQuery); - - /***** Free allocated memory for subqueries *****/ - free (GroupsSubQuery); - free (HiddenSubQuery); /***** Begin box *****/ Exams->ExaCod = Exam->ExaCod; @@ -247,12 +179,12 @@ void ExaSes_ListSessions (struct Exa_Exams *Exams, } /***** Show the table with the sessions *****/ - if (NumSessions) - { - SesCodToBeEdited = PutFormSession && Session->SesCod > 0 ? Session->SesCod : - -1L; - ExaSes_ListOneOrMoreSessions (Exams,Exam,SesCodToBeEdited,NumSessions,mysql_res); - } + if ((NumSessions = Exa_DB_GetSessions (&mysql_res,Exam->ExaCod))) + ExaSes_ListOneOrMoreSessions (Exams,Exam, + PutFormSession && + Session->SesCod > 0 ? Session->SesCod : + -1L, + NumSessions,mysql_res); /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); @@ -263,8 +195,7 @@ void ExaSes_ListSessions (struct Exa_Exams *Exams, case Rol_NET: case Rol_TCH: case Rol_SYS_ADM: - PutFormNewSession = PutFormSession && Session->SesCod <= 0; - if (PutFormNewSession) + if (PutFormSession && Session->SesCod <= 0) { /* Reset session */ ExaSes_ResetSession (Session); @@ -304,24 +235,7 @@ void ExaSes_GetDataOfSessionByCod (struct ExaSes_Session *Session) } /***** Get exam data session from database *****/ - if (DB_QuerySELECT (&mysql_res,"can not get sessions", - "SELECT SesCod," // row[0] - "ExaCod," // row[1] - "Hidden," // row[2] - "UsrCod," // row[3] - "UNIX_TIMESTAMP(StartTime)," // row[4] - "UNIX_TIMESTAMP(EndTime)," // row[5] - "NOW() BETWEEN StartTime AND EndTime," // row[6] - "Title," // row[7] - "ShowUsrResults" // row[8] - " FROM exa_sessions" - " WHERE SesCod=%ld" - " AND ExaCod IN" // Extra check - " (SELECT ExaCod" - " FROM exa_exams" - " WHERE CrsCod='%ld')", - Session->SesCod, - Gbl.Hierarchy.Crs.CrsCod)) // Session found... + if (Exa_DB_GetDataOfSessionByCod (&mysql_res,Session->SesCod)) // Session found... /* Get exam session data from row */ ExaSes_GetSessionDataFromRow (mysql_res,Session); else @@ -369,7 +283,7 @@ static void ExaSes_PutIconToCreateNewSession (struct Exa_Exams *Exams) static void ExaSes_ListOneOrMoreSessions (struct Exa_Exams *Exams, const struct Exa_Exam *Exam, - long EvtCodToBeEdited, + long SesCodToBeEdited, unsigned NumSessions, MYSQL_RES *mysql_res) { @@ -432,7 +346,7 @@ static void ExaSes_ListOneOrMoreSessions (struct Exa_Exams *Exams, HTM_TR_End (); /***** For to edit this session ****/ - if (Session.SesCod == EvtCodToBeEdited) + if (Session.SesCod == SesCodToBeEdited) { HTM_TR_Begin (NULL); HTM_TD_Begin ("colspan=\"6\" class=\"CT COLOR%u\"",Gbl.RowEvenOdd); @@ -667,24 +581,13 @@ static void ExaSes_GetAndWriteNamesOfGrpsAssociatedToSession (const struct ExaSe unsigned NumGrps; unsigned NumGrp; - /***** Get groups associated to an exam session from database *****/ - NumGrps = (unsigned) - DB_QuerySELECT (&mysql_res,"can not get groups of an exam session", - "SELECT grp_types.GrpTypName," // row[0] - "grp_groups.GrpName" // row[1] - " FROM exa_groups," - "grp_groups," - "grp_types" - " WHERE exa_groups.SesCod=%ld" - " AND exa_groups.GrpCod=grp_groups.GrpCod" - " AND grp_groups.GrpTypCod=grp_types.GrpTypCod" - " ORDER BY grp_types.GrpTypName," - "grp_groups.GrpName", - Session->SesCod); + /***** Get groups *****/ + NumGrps = Exa_DB_GetGrpsAssociatedToSession (&mysql_res,Session->SesCod); /***** Write heading *****/ HTM_DIV_Begin ("class=\"%s\"",Session->Hidden ? "ASG_GRP_LIGHT": "ASG_GRP"); + HTM_TxtColonNBSP (NumGrps == 1 ? Txt_Group : Txt_Groups); @@ -699,7 +602,7 @@ static void ExaSes_GetAndWriteNamesOfGrpsAssociatedToSession (const struct ExaSe /* Get next group */ row = mysql_fetch_row (mysql_res); - /* Write group type name and group name */ + /* Write group type name (row[0]) and group name (row[1]) */ HTM_TxtF ("%s %s",row[0],row[1]); if (NumGrps >= 2) @@ -829,19 +732,7 @@ void ExaSes_ToggleVisResultsSesUsr (void) /***** Toggle visibility of exam session results *****/ Session.ShowUsrResults = !Session.ShowUsrResults; - DB_QueryUPDATE ("can not toggle visibility of session results", - "UPDATE exa_sessions," - "exa_exams" - " SET exa_sessions.ShowUsrResults='%c'" - " WHERE exa_sessions.SesCod=%ld" - " AND exa_sessions.ExaCod=%ld" // Extra check - " AND exa_sessions.ExaCod=exa_exams.ExaCod" - " AND exa_exams.CrsCod=%ld", // Extra check - Session.ShowUsrResults ? 'Y' : - 'N', - Session.SesCod, - Session.ExaCod, - Gbl.Hierarchy.Crs.CrsCod); + Exa_DB_ToggleVisResultsSesUsr (&Session); /***** Show current exam *****/ Exa_ShowOnlyOneExam (&Exams,&Exam,&Session, @@ -978,171 +869,7 @@ void ExaSes_RemoveSession (void) } /*****************************************************************************/ -/******************* Remove exam session from all tables *********************/ -/*****************************************************************************/ - -static void Exa_DB_RemoveSessionFromAllTables (long SesCod) - { - /* To delete orphan exam prints: - // DELETE FROM exa_print_questions WHERE PrnCod IN (SELECT PrnCod FROM exa_prints WHERE SesCod NOT IN (SELECT SesCod FROM exa_sessions)); - // DELETE FROM exa_prints WHERE SesCod NOT IN (SELECT SesCod FROM exa_sessions); - */ - /***** Remove exam prints in this session *****/ - /* - * TODO: DO NOT REMOVE EXAMS PRINTS. Instead move them to tables of deleted prints - DB_QueryDELETE ("can not remove exam print questions in exam session", - "DELETE FROM exa_print_questions" - " USING exa_print_questions, - "exa_prints" - " WHERE exa_prints.SesCod=%ld" - " AND exa_prints.PrnCod=exa_print_questions.PrnCod", - SesCod); - DB_QueryDELETE ("can not remove exam prints in exam session", - "DELETE FROM exa_prints" - " WHERE exa_prints.SesCod=%ld", - SesCod); - */ - - /***** Remove groups associated to this exam session *****/ - DB_QueryDELETE ("can not remove groups associated to exam session", - "DELETE FROM exa_groups" - " WHERE SesCod=%ld", - SesCod); - - /***** Remove exam session from main table *****/ - DB_QueryDELETE ("can not remove exam session", - "DELETE FROM exa_sessions" - " WHERE SesCod=%ld", - SesCod); - } - -/*****************************************************************************/ -/**************** Remove exam session in exam from all tables ****************/ -/*****************************************************************************/ - -void Exa_DB_RemoveSessionsInExamFromAllTables (long ExaCod) - { - /***** Remove exam prints in this session *****/ - /* - * TODO: DO NOT REMOVE EXAMS PRINTS. Instead move them to tables of deleted prints - DB_QueryDELETE ("can not remove exam print questions in exam", - "DELETE FROM exa_print_questions" - " USING exa_print_questions, - "exa_prints, - "exa_sessions" - " WHERE exa_sessions.ExaCod=%ld" - " AND exa_sessions.SesCod=exa_prints.SesCod" - " AND exa_prints.PrnCod=exa_print_questions.PrnCod", - ExaCod); - DB_QueryDELETE ("can not remove exam prints in exam", - "DELETE FROM exa_prints" - " USING exa_prints, - "exa_sessions" - " WHERE exa_sessions.ExaCod=%ld" - " AND exa_sessions.SesCod=exa_prints.SesCod", - ExaCod); - */ - - /***** Remove groups associated to exam sessions of this exam *****/ - DB_QueryDELETE ("can not remove groups associated to sessions of an exam", - "DELETE FROM exa_groups" - " USING exa_sessions," - "exa_groups" - " WHERE exa_sessions.ExaCod=%ld" - " AND exa_sessions.SesCod=exa_groups.SesCod", - ExaCod); - - /***** Remove sessions from main table *****/ - DB_QueryDELETE ("can not remove sessions of an exam", - "DELETE FROM exa_sessions" - " WHERE ExaCod=%ld", - ExaCod); - } - -/*****************************************************************************/ -/*************** Remove exam session in course from all tables ***************/ -/*****************************************************************************/ - -void Exa_DB_RemoveSessionInCourseFromAllTables (long CrsCod) - { - /***** Remove exam prints in this course *****/ - /* - * TODO: DO NOT REMOVE EXAMS PRINTS. Instead move them to tables of deleted prints - DB_QueryDELETE ("can not remove exam print questions in course", - "DELETE FROM exa_print_questions" - " USING exa_print_questions, - "exa_prints, - "exa_sessions, - "exa_exams" - " WHERE exa_exams.CrsCod=%ld" - " AND exa_exams.ExaCod=exa_sessions" - " AND exa_sessions.SesCod=exa_prints.SesCod" - " AND exa_prints.PrnCod=exa_print_questions.PrnCod", - CrsCod); - DB_QueryDELETE ("can not remove exam print questions in course", - "DELETE FROM exa_prints" - " USING exa_prints, - "exa_sessions, - "exa_exams" - " WHERE exa_exams.CrsCod=%ld" - " AND exa_exams.ExaCod=exa_sessions" - " AND exa_sessions.SesCod=exa_prints.SesCod", - CrsCod); - */ - - /***** Remove sessions from table of sessions groups *****/ - DB_QueryDELETE ("can not remove sessions of a course", - "DELETE FROM exa_groups" - " USING exa_exams," - "exa_sessions," - "exa_groups" - " WHERE exa_exams.CrsCod=%ld" - " AND exa_exams.ExaCod=exa_sessions.ExaCod" - " AND exa_sessions.SesCod=exa_groups.SesCod", - CrsCod); - - /***** Remove sessions from exam sessions table *****/ - DB_QueryDELETE ("can not remove sessions of a course", - "DELETE FROM exa_sessions" - " USING exa_exams," - "exa_sessions" - " WHERE exa_exams.CrsCod=%ld" - " AND exa_exams.ExaCod=exa_sessions.ExaCod", - CrsCod); - } - -/*****************************************************************************/ -/************* Remove user from secondary exam session tables ****************/ -/*****************************************************************************/ - -void Exa_DB_RemoveUsrFromSessionTablesInCrs (long UsrCod,long CrsCod) - { - /***** Remove student from secondary tables *****/ - Exa_DB_RemoveUsrSesResultsInCrs (UsrCod,CrsCod,"exa_prints"); - } - -static void Exa_DB_RemoveUsrSesResultsInCrs (long UsrCod,long CrsCod,const char *TableName) - { - /***** Remove sessions in course from secondary table *****/ - DB_QueryDELETE ("can not remove sessions of a user from table", - "DELETE FROM %s" - " USING exa_exams," - "exa_sessions," - "%s" - " WHERE exa_exams.CrsCod=%ld" - " AND exa_exams.ExaCod=exa_sessions.ExaCod" - " AND exa_sessions.SesCod=%s.SesCod" - " AND %s.UsrCod=%ld", - TableName, - TableName, - CrsCod, - TableName, - TableName, - UsrCod); - } - -/*****************************************************************************/ -/******************************* Hide an session *****************************/ +/******************************** Hide a session *****************************/ /*****************************************************************************/ void ExaSes_HideSession (void) @@ -1164,17 +891,7 @@ void ExaSes_HideSession (void) Err_NoPermissionExit (); /***** Hide session *****/ - DB_QueryUPDATE ("can not hide exam sessions", - "UPDATE exa_sessions," - "exa_exams" - " SET exa_sessions.Hidden='Y'" - " WHERE exa_sessions.SesCod=%ld" - " AND exa_sessions.ExaCod=%ld" // Extra check - " AND exa_sessions.ExaCod=exa_exams.ExaCod" - " AND exa_exams.CrsCod=%ld", // Extra check - Session.SesCod, - Session.ExaCod, - Gbl.Hierarchy.Crs.CrsCod); + Exa_DB_HideUnhideSession (&Session,true); /***** Show current exam *****/ Exa_ShowOnlyOneExam (&Exams,&Exam,&Session, @@ -1204,17 +921,7 @@ void ExaSes_UnhideSession (void) Err_NoPermissionExit (); /***** Unhide session *****/ - DB_QueryUPDATE ("can not unhide exam session", - "UPDATE exa_sessions," - "exa_exams" - " SET exa_sessions.Hidden='N'" - " WHERE exa_sessions.SesCod=%ld" - " AND exa_sessions.ExaCod=%ld" // Extra check - " AND exa_sessions.ExaCod=exa_exams.ExaCod" - " AND exa_exams.CrsCod=%ld", // Extra check - Session.SesCod, - Session.ExaCod, - Gbl.Hierarchy.Crs.CrsCod); + Exa_DB_HideUnhideSession (&Session,false); /***** Show current exam *****/ Exa_ShowOnlyOneExam (&Exams,&Exam,&Session, @@ -1574,35 +1281,11 @@ void ExaSes_ReceiveFormSession (void) static void ExaSes_CreateSession (struct ExaSes_Session *Session) { /***** Insert this new exam session into database *****/ - Session->SesCod = - DB_QueryINSERTandReturnCode ("can not create exam session", - "INSERT exa_sessions" - " (ExaCod," - "Hidden," - "UsrCod," - "StartTime," - "EndTime," - "Title," - "ShowUsrResults)" - " VALUES" - " (%ld," // ExaCod - "'%c'," // Hidden - "%ld," // UsrCod - "FROM_UNIXTIME(%ld)," // Start time - "FROM_UNIXTIME(%ld)," // End time - "'%s'," // Title - "'N')", // ShowUsrResults: Don't show user results initially - Session->ExaCod, - Session->Hidden ? 'Y' : - 'N', - Gbl.Usrs.Me.UsrDat.UsrCod, // Session creator - Session->TimeUTC[Dat_START_TIME], // Start time - Session->TimeUTC[Dat_END_TIME ], // End time - Session->Title); + Session->SesCod = Exa_DB_CreateSession (Session); /***** Create groups associated to the exam session *****/ if (Gbl.Crs.Grps.LstGrpsSel.NumGrps) - Exa_DB_CreateGrpsAssociatedToExamSession (Session->SesCod,&Gbl.Crs.Grps.LstGrpsSel); + ExaSes_CreateGrpsAssociatedToExamSession (Session->SesCod,&Gbl.Crs.Grps.LstGrpsSel); } /*****************************************************************************/ @@ -1612,40 +1295,20 @@ static void ExaSes_CreateSession (struct ExaSes_Session *Session) static void ExaSes_UpdateSession (struct ExaSes_Session *Session) { /***** Insert this new exam session into database *****/ - DB_QueryUPDATE ("can not update exam session", - "UPDATE exa_sessions," - "exa_exams" - " SET exa_sessions.Hidden='%c'," - "exa_sessions.StartTime=FROM_UNIXTIME(%ld)," - "exa_sessions.EndTime=FROM_UNIXTIME(%ld)," - "exa_sessions.Title='%s'," - "exa_sessions.ShowUsrResults='%c'" - " WHERE exa_sessions.SesCod=%ld" - " AND exa_sessions.ExaCod=%ld" // Extra check - " AND exa_sessions.ExaCod=exa_exams.ExaCod" - " AND exa_exams.CrsCod=%ld", // Extra check - Session->Hidden ? 'Y' : - 'N', - Session->TimeUTC[Dat_START_TIME], // Start time - Session->TimeUTC[Dat_END_TIME ], // End time - Session->Title, - Session->ShowUsrResults ? 'Y' : - 'N', - Session->SesCod, - Session->ExaCod, - Gbl.Hierarchy.Crs.CrsCod); + Exa_DB_UpdateSession (Session); /***** Update groups associated to the exam session *****/ - Exa_DB_RemoveGrpsAssociatedToExamSession (Session->SesCod); // Remove all groups associated to this session + Exa_DB_RemoveAllGrpsAssociatedToSession (Session->SesCod); // Remove all groups associated to this session if (Gbl.Crs.Grps.LstGrpsSel.NumGrps) - Exa_DB_CreateGrpsAssociatedToExamSession (Session->SesCod,&Gbl.Crs.Grps.LstGrpsSel); // Associate new groups + ExaSes_CreateGrpsAssociatedToExamSession (Session->SesCod,&Gbl.Crs.Grps.LstGrpsSel); // Associate new groups } /*****************************************************************************/ /*************** Create groups associated to an exam session *****************/ /*****************************************************************************/ -static void Exa_DB_CreateGrpsAssociatedToExamSession (long SesCod,const struct ListCodGrps *LstGrpsSel) +static void ExaSes_CreateGrpsAssociatedToExamSession (long SesCod, + const struct ListCodGrps *LstGrpsSel) { unsigned NumGrpSel; @@ -1654,96 +1317,7 @@ static void Exa_DB_CreateGrpsAssociatedToExamSession (long SesCod,const struct L NumGrpSel < LstGrpsSel->NumGrps; NumGrpSel++) /* Create group */ - DB_QueryINSERT ("can not associate a group to an exam session", - "INSERT INTO exa_groups" - " (SesCod,GrpCod)" - " VALUES" - " (%ld,%ld)", - SesCod, - LstGrpsSel->GrpCods[NumGrpSel]); - } - -/*****************************************************************************/ -/******************** Remove all groups from one session *********************/ -/*****************************************************************************/ - -static void Exa_DB_RemoveGrpsAssociatedToExamSession (long SesCod) - { - /***** Remove all groups from one session *****/ - DB_QueryDELETE ("can not remove groups associated to a session", - "DELETE FROM exa_groups" - " WHERE SesCod=%ld", - SesCod); - } - -/*****************************************************************************/ -/******************** Remove one group from all sessions *********************/ -/*****************************************************************************/ - -void Exa_DB_RemoveGrpAssociatedToExamSessions (long GrpCod) - { - /***** Remove group from all the sessions *****/ - DB_QueryDELETE ("can not remove group" - " from the associations between sessions and groups", - "DELETE FROM exa_groups" - " WHERE GrpCod=%ld", - GrpCod); - } - -/*****************************************************************************/ -/**************** Remove groups of one type from all sessions ****************/ -/*****************************************************************************/ - -void Exa_DB_RemoveGroupsOfTypeAssociatedToExamSessions (long GrpTypCod) - { - /***** Remove group from all the sessions *****/ - DB_QueryDELETE ("can not remove groups of a type" - " from the associations between sessions and groups", - "DELETE FROM exa_groups" - " USING grp_groups," - "exa_groups" - " WHERE grp_groups.GrpTypCod=%ld" - " AND grp_groups.GrpCod=exa_groups.GrpCod", - GrpTypCod); - } - -/*****************************************************************************/ -/********************* Get number of sessions in an exam *********************/ -/*****************************************************************************/ - -unsigned ExaSes_GetNumSessionsInExam (long ExaCod) - { - /***** Trivial check *****/ - if (ExaCod < 0) // A non-existing exam... - return 0; // ...has no sessions - - /***** Get number of sessions in an exam from database *****/ - return (unsigned) - DB_QueryCOUNT ("can not get number of sessions of an exam", - "SELECT COUNT(*)" - " FROM exa_sessions" - " WHERE ExaCod=%ld", - ExaCod); - } - -/*****************************************************************************/ -/***************** Get number of open sessions in an exam ********************/ -/*****************************************************************************/ - -unsigned ExaSes_GetNumOpenSessionsInExam (long ExaCod) - { - /***** Trivial check *****/ - if (ExaCod < 0) // A non-existing exam... - return 0; // ...has no sessions - - /***** Get number of open sessions in an exam from database *****/ - return (unsigned) - DB_QueryCOUNT ("can not get number of open sessions of an exam", - "SELECT COUNT(*)" - " FROM exa_sessions" - " WHERE ExaCod=%ld" - " AND NOW() BETWEEN StartTime AND EndTime", - ExaCod); + Exa_DB_CreateGrpAssociatedToSession (SesCod,LstGrpsSel->GrpCods[NumGrpSel]); } /*****************************************************************************/ @@ -1772,20 +1346,7 @@ bool ExaSes_CheckIfICanListThisSessionBasedOnGrps (long SesCod) case Rol_STD: /***** Check if I belong to any of the groups associated to the exam session *****/ - return (DB_QueryCOUNT ("can not check if I can play an exam session", - "SELECT COUNT(*)" - " FROM exa_sessions" - " WHERE SesCod=%ld" - " AND (SesCod NOT IN" - " (SELECT SesCod FROM exa_groups)" - " OR" - " SesCod IN" - " (SELECT exa_groups.SesCod" - " FROM exa_groups," - "grp_users" - " WHERE grp_users.UsrCod=%ld" - " AND grp_users.GrpCod=exa_groups.GrpCod))", - SesCod,Gbl.Usrs.Me.UsrDat.UsrCod) != 0); + return Exa_DB_CheckIfICanListThisSessionBasedOnGrps (SesCod); break; case Rol_NET: case Rol_TCH: diff --git a/swad_exam_session.h b/swad_exam_session.h index 03e758e9..0d277a29 100644 --- a/swad_exam_session.h +++ b/swad_exam_session.h @@ -61,10 +61,6 @@ void ExaSes_ToggleVisResultsSesUsr (void); void ExaSes_RequestRemoveSession (void); void ExaSes_RemoveSession (void); -void Exa_DB_RemoveSessionsInExamFromAllTables (long ExaCod); -void Exa_DB_RemoveSessionInCourseFromAllTables (long CrsCod); -void Exa_DB_RemoveUsrFromSessionTablesInCrs (long UsrCod,long CrsCod); - void ExaSes_HideSession (void); void ExaSes_UnhideSession (void); @@ -79,12 +75,6 @@ void ExaSes_PutButtonNewSession (struct Exa_Exams *Exams,long ExaCod); void ExaSes_RequestCreatOrEditSession (void); void ExaSes_ReceiveFormSession (void); -void Exa_DB_RemoveGrpAssociatedToExamSessions (long GrpCod); -void Exa_DB_RemoveGroupsOfTypeAssociatedToExamSessions (long GrpTypCod); - -unsigned ExaSes_GetNumSessionsInExam (long ExaCod); -unsigned ExaSes_GetNumOpenSessionsInExam (long ExaCod); - bool ExaSes_CheckIfICanAnswerThisSession (const struct Exa_Exam *Exam, const struct ExaSes_Session *Session); bool ExaSes_CheckIfICanListThisSessionBasedOnGrps (long SesCod); diff --git a/swad_group.c b/swad_group.c index e6299b10..4c24cf54 100644 --- a/swad_group.c +++ b/swad_group.c @@ -37,7 +37,7 @@ #include "swad_box.h" #include "swad_database.h" #include "swad_error.h" -#include "swad_exam_session.h" +#include "swad_exam_database.h" #include "swad_form.h" #include "swad_game.h" #include "swad_global.h" @@ -3506,11 +3506,14 @@ static void Grp_RemoveGroupTypeCompletely (void) /***** Remove the associations of attendance events to groups of this type *****/ Att_DB_RemoveGroupsOfType (Gbl.Crs.Grps.GrpTyp.GrpTypCod); + /***** Remove the associations of exam sessions to groups of this type *****/ + Exa_DB_RemoveGroupsOfType (Gbl.Crs.Grps.GrpTyp.GrpTypCod); + /***** Remove the associations of matches to groups of this type *****/ - Mch_RemoveGroupsOfType (Gbl.Crs.Grps.GrpTyp.GrpTypCod); + Mch_DB_RemoveGroupsOfType (Gbl.Crs.Grps.GrpTyp.GrpTypCod); /***** Remove the associations of surveys to groups of this type *****/ - Svy_RemoveGroupsOfType (Gbl.Crs.Grps.GrpTyp.GrpTypCod); + Svy_DB_RemoveGroupsOfType (Gbl.Crs.Grps.GrpTyp.GrpTypCod); /***** Orphan all groups of this type in course timetable *****/ Tmt_DB_OrphanAllGrpsOfATypeInCrsTimeTable (Gbl.Crs.Grps.GrpTyp.GrpTypCod); @@ -3557,10 +3560,13 @@ static void Grp_RemoveGroupCompletely (void) Att_DB_RemoveGroup (GrpDat.GrpCod); /***** Remove this group from all matches *****/ - Mch_RemoveGroup (GrpDat.GrpCod); + Mch_DB_RemoveGroup (GrpDat.GrpCod); + + /***** Remove this group from all exam sessions *****/ + Exa_DB_RemoveGrpAssociatedToExamSessions (GrpDat.GrpCod); /***** Remove this group from all surveys *****/ - Svy_RemoveGroup (GrpDat.GrpCod); + Svy_DB_RemoveGroup (GrpDat.GrpCod); /***** Orphan this group in course timetable *****/ Tmt_DB_OrphanGrpInCrsTimeTable (GrpDat.GrpCod); diff --git a/swad_match.c b/swad_match.c index 418436b8..0e781808 100644 --- a/swad_match.c +++ b/swad_match.c @@ -1975,7 +1975,7 @@ static void Mch_CreateGrps (long MchCod) /********************* Remove one group from all matches *********************/ /*****************************************************************************/ -void Mch_RemoveGroup (long GrpCod) +void Mch_DB_RemoveGroup (long GrpCod) { /***** Remove group from all the matches *****/ DB_QueryDELETE ("can not remove group" @@ -1989,7 +1989,7 @@ void Mch_RemoveGroup (long GrpCod) /***************** Remove groups of one type from all matches ****************/ /*****************************************************************************/ -void Mch_RemoveGroupsOfType (long GrpTypCod) +void Mch_DB_RemoveGroupsOfType (long GrpTypCod) { /***** Remove group from all the matches *****/ DB_QueryDELETE ("can not remove groups of a type" diff --git a/swad_match.h b/swad_match.h index 9f8b8df2..000966e4 100644 --- a/swad_match.h +++ b/swad_match.h @@ -119,8 +119,8 @@ void Mch_ResumeMatch (void); void Mch_GetIndexes (long MchCod,unsigned QstInd, unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]); -void Mch_RemoveGroup (long GrpCod); -void Mch_RemoveGroupsOfType (long GrpTypCod); +void Mch_DB_RemoveGroup (long GrpCod); +void Mch_DB_RemoveGroupsOfType (long GrpTypCod); void Mch_PlayPauseMatch (void); void Mch_ChangeNumColsMch (void); diff --git a/swad_survey.c b/swad_survey.c index f84bcad0..d0f64b24 100644 --- a/swad_survey.c +++ b/swad_survey.c @@ -135,7 +135,7 @@ static void Svy_UpdateNumUsrsNotifiedByEMailAboutSurvey (long SvyCod, unsigned NumUsrsToBeNotifiedByEMail); static void Svy_CreateSurvey (struct Svy_Survey *Svy,const char *Txt); static void Svy_UpdateSurvey (struct Svy_Survey *Svy,const char *Txt); -static void Svy_RemoveAllTheGrpsAssociatedToAndSurvey (long SvyCod); +static void Svy_DB_RemoveAllGrpsAssociatedToSurvey (long SvyCod); static void Svy_CreateGrps (long SvyCod); static void Svy_GetAndWriteNamesOfGrpsAssociatedToSvy (struct Svy_Survey *Svy); static bool Svy_CheckIfICanDoThisSurveyBasedOnGrps (long SvyCod); @@ -1644,7 +1644,7 @@ void Svy_RemoveSurvey (void) Svy.SvyCod); /***** Remove all the groups of this survey *****/ - Svy_RemoveAllTheGrpsAssociatedToAndSurvey (Svy.SvyCod); + Svy_DB_RemoveAllGrpsAssociatedToSurvey (Svy.SvyCod); /***** Remove survey *****/ DB_QueryDELETE ("can not remove survey", @@ -2416,7 +2416,7 @@ static void Svy_UpdateSurvey (struct Svy_Survey *Svy,const char *Txt) /***** Update groups *****/ /* Remove old groups */ - Svy_RemoveAllTheGrpsAssociatedToAndSurvey (Svy->SvyCod); + Svy_DB_RemoveAllGrpsAssociatedToSurvey (Svy->SvyCod); /* Create new groups */ if (Gbl.Crs.Grps.LstGrpsSel.NumGrps) @@ -2430,7 +2430,7 @@ static void Svy_UpdateSurvey (struct Svy_Survey *Svy,const char *Txt) /************************* Remove groups of a survey *************************/ /*****************************************************************************/ -static void Svy_RemoveAllTheGrpsAssociatedToAndSurvey (long SvyCod) +static void Svy_DB_RemoveAllGrpsAssociatedToSurvey (long SvyCod) { /***** Remove groups of the survey *****/ DB_QueryDELETE ("can not remove the groups associated to a survey", @@ -2439,25 +2439,11 @@ static void Svy_RemoveAllTheGrpsAssociatedToAndSurvey (long SvyCod) SvyCod); } -/*****************************************************************************/ -/******************* Remove one group from all the surveys *******************/ -/*****************************************************************************/ - -void Svy_RemoveGroup (long GrpCod) - { - /***** Remove group from all the surveys *****/ - DB_QueryDELETE ("can not remove group from the associations" - " between surveys and groups", - "DELETE FROM svy_groups" - " WHERE GrpCod=%ld", - GrpCod); - } - /*****************************************************************************/ /*************** Remove groups of one type from all the surveys **************/ /*****************************************************************************/ -void Svy_RemoveGroupsOfType (long GrpTypCod) +void Svy_DB_RemoveGroupsOfType (long GrpTypCod) { /***** Remove group from all the surveys *****/ DB_QueryDELETE ("can not remove groups of a type" @@ -2470,6 +2456,20 @@ void Svy_RemoveGroupsOfType (long GrpTypCod) GrpTypCod); } +/*****************************************************************************/ +/******************* Remove one group from all the surveys *******************/ +/*****************************************************************************/ + +void Svy_DB_RemoveGroup (long GrpCod) + { + /***** Remove group from all the surveys *****/ + DB_QueryDELETE ("can not remove group from the associations" + " between surveys and groups", + "DELETE FROM svy_groups" + " WHERE GrpCod=%ld", + GrpCod); + } + /*****************************************************************************/ /************************ Create groups of a survey **************************/ /*****************************************************************************/ diff --git a/swad_survey.h b/swad_survey.h index 72a667c5..e62d042f 100644 --- a/swad_survey.h +++ b/swad_survey.h @@ -108,8 +108,8 @@ void Svy_ResetSurvey (void); void Svy_HideSurvey (void); void Svy_UnhideSurvey (void); void Svy_ReceiveFormSurvey (void); -void Svy_RemoveGroup (long GrpCod); -void Svy_RemoveGroupsOfType (long GrpTypCod); +void Svy_DB_RemoveGroupsOfType (long GrpTypCod); +void Svy_DB_RemoveGroup (long GrpCod); void Svy_RemoveSurveys (HieLvl_Level_t Scope,long Cod); void Svy_RequestEditQuestion (void);