diff --git a/swad_API.c b/swad_API.c index d628d52a4..da91db013 100644 --- a/swad_API.c +++ b/swad_API.c @@ -1032,7 +1032,7 @@ int swad__loginBySessionKey (struct soap *soap, /***** Get course (row[2]) *****/ Gbl.Hierarchy.Crs.CrsCod = Str_ConvertStrCodToLongCod (row[2]); - Crs_GetDataOfCourseByCod (&Gbl.Hierarchy.Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Gbl.Hierarchy.Crs); loginBySessionKeyOut->courseCode = (int) Gbl.Hierarchy.Crs.CrsCod; Str_Copy (loginBySessionKeyOut->courseName,Gbl.Hierarchy.Crs.FullName, Hie_MAX_BYTES_FULL_NAME); @@ -3013,7 +3013,7 @@ int swad__getNotifications (struct soap *soap, /* Get course (row[7]) */ Crs.CrsCod = Str_ConvertStrCodToLongCod (row[7]); - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); /* Get user's code of the user who caused the event (row[3]) */ Gbl.Usrs.Other.UsrDat.UsrCod = Str_ConvertStrCodToLongCod (row[3]); diff --git a/swad_changelog.h b/swad_changelog.h index b55e63dea..ad3017803 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -492,7 +492,7 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - * En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 19.112.8 (2020-01-05)" +#define Log_PLATFORM_VERSION "SWAD 19.112.9 (2020-01-05)" #define CSS_FILE "swad19.112.css" #define JS_FILE "swad19.91.1.js" /* @@ -501,7 +501,9 @@ ps2pdf source.ps destination.pdf // TODO: No se puede entrar con DNI '1' suponiendo que no tenga password ¿por qué? // TODO: Mapas más estrechos en móvil // TODO: Quitar todos los EXTRA_DATA. +// TODO: ¿ Cachear Usr_GetNumUsrsInCrssOfDeg ? + Version 19.112.9: Jan 05, 2020 Optimization in number of users in a course. (278419 lines) Version 19.112.8: Jan 05, 2020 Optimization in number of courses in a degree. (278396 lines) Version 19.112.7: Jan 05, 2020 Optimization in number of degrees in a centre. (278384 lines) Version 19.112.6: Jan 05, 2020 Optimization in number of courses in a centre. (278374 lines) diff --git a/swad_chat.c b/swad_chat.c index a59a77e1e..44ecd3d3c 100644 --- a/swad_chat.c +++ b/swad_chat.c @@ -206,7 +206,7 @@ void Cht_ShowListOfAvailableChatRooms (void) if ((Crs.CrsCod = Str_ConvertStrCodToLongCod (row[0])) > 0) { /* Get data of this course */ - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); /* Link to the room of this course */ IsLastItemInLevel[2] = (NumRow == NumRows - 1); @@ -557,7 +557,7 @@ void Cht_OpenChatWindow (void) /* Get data of this course */ Crs.CrsCod = Gbl.Usrs.Me.MyCrss.Crss[NumMyCrs].CrsCod; - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); snprintf (ThisRoomShortName,sizeof (ThisRoomShortName), "%s", diff --git a/swad_course.c b/swad_course.c index a55ba9a5f..68d08fa8d 100644 --- a/swad_course.c +++ b/swad_course.c @@ -343,7 +343,7 @@ static void Crs_WriteListMyCoursesToSelectOne (void) /***** Get data of this course *****/ Crs.CrsCod = Str_ConvertStrCodToLongCod (row[0]); - if (!Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA)) + if (!Crs_GetDataOfCourseByCod (&Crs)) Lay_ShowErrorAndExit ("Course not found."); /***** Write link to course *****/ @@ -658,14 +658,6 @@ static void Crs_GetListCrssInCurrentDeg (Crs_WhatCourses_t WhatCourses) /* Get next course */ row = mysql_fetch_row (mysql_res); Crs_GetDataOfCourseFromRow (Crs,row); - - /* Get number of users in this course */ - Crs->NumUsrs[Rol_STD] = Usr_GetNumUsrsInCrs (Rol_STD,Crs->CrsCod); - Crs->NumUsrs[Rol_NET] = Usr_GetNumUsrsInCrs (Rol_NET,Crs->CrsCod); - Crs->NumUsrs[Rol_TCH] = Usr_GetNumUsrsInCrs (Rol_TCH,Crs->CrsCod); - Crs->NumUsrs[Rol_UNK] = Crs->NumUsrs[Rol_STD] + - Crs->NumUsrs[Rol_NET] + - Crs->NumUsrs[Rol_TCH]; } } @@ -865,6 +857,7 @@ static bool Crs_ListCoursesOfAYearForSeeing (unsigned Year) const char *BgColor; Crs_StatusTxt_t StatusTxt; bool ThisYearHasCourses = false; + unsigned NumUsrs[Rol_NUM_ROLES]; /***** Write all the courses of this year *****/ for (NumCrs = 0; @@ -892,13 +885,19 @@ static bool Crs_ListCoursesOfAYearForSeeing (unsigned Year) HTM_TR_Begin (NULL); + /* Get number of users */ + NumUsrs[Rol_UNK] = Usr_GetNumUsrsInCrs (Rol_UNK,Crs->CrsCod); + NumUsrs[Rol_STD] = Usr_GetNumUsrsInCrs (Rol_STD,Crs->CrsCod); + NumUsrs[Rol_NET] = Usr_GetNumUsrsInCrs (Rol_NET,Crs->CrsCod); + NumUsrs[Rol_TCH] = Usr_GetNumUsrsInCrs (Rol_TCH,Crs->CrsCod); + /* Put green tip if course has users */ HTM_TD_Begin ("class=\"%s CM %s\" title=\"%s\"", TxtClassNormal,BgColor, - Crs->NumUsrs[Rol_UNK] ? Txt_COURSE_With_users : - Txt_COURSE_Without_users); - HTM_Txt (Crs->NumUsrs[Rol_UNK] ? "✓" : - " "); + NumUsrs[Rol_UNK] ? Txt_COURSE_With_users : + Txt_COURSE_Without_users); + HTM_Txt (NumUsrs[Rol_UNK] ? "✓" : + " "); HTM_TD_End (); /* Institutional code of the course */ @@ -925,13 +924,13 @@ static bool Crs_ListCoursesOfAYearForSeeing (unsigned Year) /* Current number of teachers in this course */ HTM_TD_Begin ("class=\"%s RM %s\"",TxtClassNormal,BgColor); - HTM_Unsigned (Crs->NumUsrs[Rol_TCH] + - Crs->NumUsrs[Rol_NET]); + HTM_Unsigned (NumUsrs[Rol_TCH] + + NumUsrs[Rol_NET]); HTM_TD_End (); /* Current number of students in this course */ HTM_TD_Begin ("class=\"%s RM %s\"",TxtClassNormal,BgColor); - HTM_Unsigned (Crs->NumUsrs[Rol_STD]); + HTM_Unsigned (NumUsrs[Rol_STD]); HTM_TD_End (); /* Course status */ @@ -1065,6 +1064,7 @@ static void Crs_ListCoursesOfAYearForEdition (unsigned Year) unsigned NumCrs; struct UsrData UsrDat; bool ICanEdit; + unsigned NumUsrs[Rol_NUM_ROLES]; Crs_StatusTxt_t StatusTxt; unsigned StatusUnsigned; @@ -1081,11 +1081,17 @@ static void Crs_ListCoursesOfAYearForEdition (unsigned Year) { ICanEdit = Crs_CheckIfICanEdit (Crs); + /* Get number of users */ + NumUsrs[Rol_UNK] = Usr_GetNumUsrsInCrs (Rol_UNK,Crs->CrsCod); + NumUsrs[Rol_STD] = Usr_GetNumUsrsInCrs (Rol_STD,Crs->CrsCod); + NumUsrs[Rol_NET] = Usr_GetNumUsrsInCrs (Rol_NET,Crs->CrsCod); + NumUsrs[Rol_TCH] = Usr_GetNumUsrsInCrs (Rol_TCH,Crs->CrsCod); + HTM_TR_Begin (NULL); /* Put icon to remove course */ HTM_TD_Begin ("class=\"BM\""); - if (Crs->NumUsrs[Rol_UNK] || // Course has users ==> deletion forbidden + if (NumUsrs[Rol_UNK] || // Course has users ==> deletion forbidden !ICanEdit) Ico_PutIconRemovalNotAllowed (); else // Crs->NumUsrs == 0 && ICanEdit @@ -1168,13 +1174,13 @@ static void Crs_ListCoursesOfAYearForEdition (unsigned Year) /* Current number of teachers in this course */ HTM_TD_Begin ("class=\"DAT RM\""); - HTM_Unsigned (Crs->NumUsrs[Rol_TCH] + - Crs->NumUsrs[Rol_NET]); + HTM_Unsigned (NumUsrs[Rol_TCH] + + NumUsrs[Rol_NET]); HTM_TD_End (); /* Current number of students in this course */ HTM_TD_Begin ("class=\"DAT RM\""); - HTM_Unsigned (Crs->NumUsrs[Rol_STD]); + HTM_Unsigned (NumUsrs[Rol_STD]); HTM_TD_End (); /* Course requester */ @@ -1567,14 +1573,15 @@ void Crs_RemoveCourse (void) Crs_EditingCrs->CrsCod = Crs_GetAndCheckParamOtherCrsCod (1); /***** Get data of the course from database *****/ - Crs_GetDataOfCourseByCod (Crs_EditingCrs,Crs_GET_EXTRA_DATA); + Crs_GetDataOfCourseByCod (Crs_EditingCrs); if (Crs_CheckIfICanEdit (Crs_EditingCrs)) { /***** Check if this course has users *****/ - if (Crs_EditingCrs->NumUsrs[Rol_UNK]) // Course has users ==> don't remove - Ale_ShowAlert (Ale_WARNING,Txt_To_remove_a_course_you_must_first_remove_all_users_in_the_course); - else // Course has no users ==> remove it + if (Usr_GetNumUsrsInCrs (Rol_UNK,Crs_EditingCrs->CrsCod)) // Course has users ==> don't remove + Ale_ShowAlert (Ale_WARNING, + Txt_To_remove_a_course_you_must_first_remove_all_users_in_the_course); + else // Course has no users ==> remove it { /***** Remove course *****/ Crs_RemoveCourseCompletely (Crs_EditingCrs->CrsCod); @@ -1594,8 +1601,7 @@ void Crs_RemoveCourse (void) /********************* Get data of a course from its code ********************/ /*****************************************************************************/ -bool Crs_GetDataOfCourseByCod (struct Course *Crs, - Crs_GetExtraData_t GetExtraData) +bool Crs_GetDataOfCourseByCod (struct Course *Crs) { MYSQL_RES *mysql_res; MYSQL_ROW row; @@ -1608,10 +1614,6 @@ bool Crs_GetDataOfCourseByCod (struct Course *Crs, Crs->RequesterUsrCod = -1L; Crs->ShrtName[0] = '\0'; Crs->FullName[0] = '\0'; - Crs->NumUsrs[Rol_UNK] = - Crs->NumUsrs[Rol_STD] = - Crs->NumUsrs[Rol_NET] = - Crs->NumUsrs[Rol_TCH] = 0; /***** Check if course code is correct *****/ if (Crs->CrsCod > 0) @@ -1633,18 +1635,6 @@ bool Crs_GetDataOfCourseByCod (struct Course *Crs, row = mysql_fetch_row (mysql_res); Crs_GetDataOfCourseFromRow (Crs,row); - /* Get extra data */ - if (GetExtraData == Crs_GET_EXTRA_DATA) - { - /* Get number of users in this course */ - Crs->NumUsrs[Rol_STD] = Usr_GetNumUsrsInCrs (Rol_STD,Crs->CrsCod); - Crs->NumUsrs[Rol_NET] = Usr_GetNumUsrsInCrs (Rol_NET,Crs->CrsCod); - Crs->NumUsrs[Rol_TCH] = Usr_GetNumUsrsInCrs (Rol_TCH,Crs->CrsCod); - Crs->NumUsrs[Rol_UNK] = Crs->NumUsrs[Rol_STD] + - Crs->NumUsrs[Rol_NET] + - Crs->NumUsrs[Rol_TCH]; - } - /* Set return value */ CrsFound = true; } @@ -1749,6 +1739,9 @@ void Crs_RemoveCourseCompletely (long CrsCod) DB_QueryDELETE ("can not remove a course", "DELETE FROM courses WHERE CrsCod=%ld", CrsCod); + + /***** Flush caches *****/ + Usr_FlushCacheNumUsrsInCrs (); } } @@ -1767,7 +1760,7 @@ static void Crs_EmptyCourseCompletely (long CrsCod) { /***** Get course data *****/ Crs.CrsCod = CrsCod; - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_EXTRA_DATA); + Crs_GetDataOfCourseByCod (&Crs); /***** Remove all the students in the course *****/ Enr_RemAllStdsInCrs (&Crs); @@ -1923,7 +1916,7 @@ void Crs_ChangeInsCrsCod (void) Par_GetParToText ("InsCrsCod",NewInstitutionalCrsCod,Crs_MAX_BYTES_INSTITUTIONAL_CRS_COD); /* Get data of the course */ - Crs_GetDataOfCourseByCod (Crs_EditingCrs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (Crs_EditingCrs); if (Crs_CheckIfICanEdit (Crs_EditingCrs)) { @@ -1969,7 +1962,7 @@ void Crs_ChangeCrsYear (void) Par_GetParToText ("OthCrsYear",YearStr,2); NewYear = Deg_ConvStrToYear (YearStr); - Crs_GetDataOfCourseByCod (Crs_EditingCrs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (Crs_EditingCrs); if (Crs_CheckIfICanEdit (Crs_EditingCrs)) { @@ -2100,7 +2093,7 @@ void Crs_RenameCourse (struct Course *Crs,Cns_ShrtOrFullName_t ShrtOrFullName) Par_GetParToText (ParamName,NewCrsName,MaxBytes); /***** Get from the database the data of the degree *****/ - Crs_GetDataOfCourseByCod (Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (Crs); if (Crs_CheckIfICanEdit (Crs)) { @@ -2201,7 +2194,7 @@ void Crs_ChangeCrsStatus (void) Status = Crs_GetStatusBitsFromStatusTxt (StatusTxt); // New status /***** Get data of course *****/ - Crs_GetDataOfCourseByCod (Crs_EditingCrs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (Crs_EditingCrs); /***** Update status in table of courses *****/ DB_QueryUPDATE ("can not update the status of a course", @@ -2838,8 +2831,6 @@ void Crs_RemoveOldCrss (void) static void Crs_EditingCourseConstructor (void) { - Rol_Role_t Role; - /***** Pointer must be NULL *****/ if (Crs_EditingCrs != NULL) Lay_ShowErrorAndExit ("Error initializing course."); @@ -2856,10 +2847,6 @@ static void Crs_EditingCourseConstructor (void) Crs_EditingCrs->Status = 0; Crs_EditingCrs->ShrtName[0] = '\0'; Crs_EditingCrs->FullName[0] = '\0'; - for (Role = (Rol_Role_t) 0; - Role <= (Rol_Role_t) (Rol_NUM_ROLES - 1); - Role++) - Crs_EditingCrs->NumUsrs[Role] = 0; } static void Crs_EditingCourseDestructor (void) diff --git a/swad_course.h b/swad_course.h index 99a2b6b0a..cd6a5f419 100644 --- a/swad_course.h +++ b/swad_course.h @@ -85,15 +85,8 @@ struct Course long RequesterUsrCod; // User code of the person who requested the creation of this course char ShrtName[Hie_MAX_BYTES_SHRT_NAME + 1]; // Short name of course char FullName[Hie_MAX_BYTES_FULL_NAME + 1]; // Full name of course - unsigned NumUsrs[Rol_NUM_ROLES]; // Number of users }; -typedef enum - { - Crs_GET_BASIC_DATA, - Crs_GET_EXTRA_DATA, - } Crs_GetExtraData_t; - /*****************************************************************************/ /***************************** Public prototypes *****************************/ /*****************************************************************************/ @@ -120,8 +113,7 @@ void Crs_RecFormReqCrs (void); void Crs_RecFormNewCrs (void); void Crs_RemoveCourse (void); -bool Crs_GetDataOfCourseByCod (struct Course *Crs, - Crs_GetExtraData_t GetExtraData); +bool Crs_GetDataOfCourseByCod (struct Course *Crs); void Crs_RemoveCourseCompletely (long CrsCod); void Crs_ChangeInsCrsCod (void); void Crs_ChangeCrsYear (void); diff --git a/swad_course_config.c b/swad_course_config.c index 67cd5eb7f..b54cb831e 100644 --- a/swad_course_config.c +++ b/swad_course_config.c @@ -427,7 +427,7 @@ static void CrsCfg_NumUsrsInCrs (Rol_Role_t Role) /* Data */ HTM_TD_Begin ("class=\"DAT LB\""); - HTM_Unsigned (Gbl.Hierarchy.Crs.NumUsrs[Role]); + HTM_Unsigned (Usr_GetNumUsrsInCrs (Role,Gbl.Hierarchy.Crs.CrsCod)); HTM_TD_End (); HTM_TR_End (); diff --git a/swad_enrolment.c b/swad_enrolment.c index ce92058a7..f7b6fa27d 100644 --- a/swad_enrolment.c +++ b/swad_enrolment.c @@ -184,7 +184,7 @@ void Enr_CheckStdsAndPutButtonToRegisterStdsInCurrentCrs (void) { /***** Put link to register students *****/ if (Gbl.Usrs.Me.Role.Logged == Rol_TCH) // Course selected and I am logged as teacher - if (!Gbl.Hierarchy.Crs.NumUsrs[Rol_STD]) // No students in course + if (!Usr_GetNumUsrsInCrs (Rol_STD,Gbl.Hierarchy.Crs.CrsCod)) // No students in course Usr_ShowWarningNoUsersFound (Rol_STD); } @@ -675,7 +675,7 @@ static void Enr_ShowFormRegRemSeveralUsrs (Rol_Role_t Role) Enr_PutLinkToAdminOneUsr (ActReqMdfOneStd); /* Put link to remove all the students in the current course */ - if (Gbl.Hierarchy.Crs.NumUsrs[Rol_STD]) // This course has students + if (Usr_GetNumUsrsInCrs (Rol_STD,Gbl.Hierarchy.Crs.CrsCod)) // This course has students Enr_PutLinkToRemAllStdsThisCrs (); break; case Rol_NET: @@ -1821,17 +1821,18 @@ void Enr_AskRemAllStdsThisCrs (void) extern const char *Hlp_USERS_Administration_remove_all_students; extern const char *Txt_Remove_all_students; extern const char *Txt_Do_you_really_want_to_remove_the_X_students_from_the_course_Y_; + unsigned NumStds = Usr_GetNumUsrsInCrs (Rol_STD,Gbl.Hierarchy.Crs.CrsCod); /***** Begin box *****/ Box_BoxBegin (NULL,Txt_Remove_all_students,NULL, Hlp_USERS_Administration_remove_all_students,Box_NOT_CLOSABLE); - if (Gbl.Hierarchy.Crs.NumUsrs[Rol_STD]) + if (NumStds) { /***** Show question and button to remove students *****/ /* Start alert */ Ale_ShowAlertAndButton1 (Ale_QUESTION,Txt_Do_you_really_want_to_remove_the_X_students_from_the_course_Y_, - Gbl.Hierarchy.Crs.NumUsrs[Rol_STD], + NumStds, Gbl.Hierarchy.Crs.FullName); /* Show form to request confirmation */ @@ -2002,9 +2003,9 @@ void Enr_SignUpInCrs (void) /***** Notify teachers or admins by email about the new enrolment request *****/ // If this course has teachers ==> send notification to teachers // If this course has no teachers and I want to be a teacher ==> send notification to administrators or superusers - if (Gbl.Hierarchy.Crs.NumUsrs[Rol_TCH] || - RoleFromForm == Rol_TCH) - Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_ENROLMENT_REQUEST,ReqCod); + if (RoleFromForm == Rol_TCH) // TODO: What happens in user wants to enrole as a non-editing teacher? + if (Usr_GetNumUsrsInCrs (Rol_TCH,Gbl.Hierarchy.Crs.CrsCod)) + Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_ENROLMENT_REQUEST,ReqCod); } } @@ -2820,7 +2821,7 @@ static void Enr_ShowEnrolmentRequestsGivenRoles (unsigned RolesSelected) HTM_TD_End (); /***** Link to course *****/ - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); Deg.DegCod = Crs.DegCod; Deg_GetDataOfDegreeByCod (&Deg); HTM_TD_Begin ("class=\"DAT LT\""); @@ -2836,7 +2837,7 @@ static void Enr_ShowEnrolmentRequestsGivenRoles (unsigned RolesSelected) /***** Number of teachers in the course *****/ HTM_TD_Begin ("class=\"DAT RT\""); - HTM_Unsigned (Crs.NumUsrs[Rol_TCH]); + HTM_Unsigned (Usr_GetNumUsrsInCrs (Rol_TCH,Crs.CrsCod)); HTM_TD_End (); /***** User photo *****/ diff --git a/swad_exam.c b/swad_exam.c index 90166bad8..be6f0f221 100644 --- a/swad_exam.c +++ b/swad_exam.c @@ -1607,7 +1607,7 @@ static void Exa_GetNotifContentExamAnnouncement (char **ContentStr) /***** Get data of course *****/ Crs.CrsCod = Gbl.ExamAnns.ExaDat.CrsCod; - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); /***** Get data of degree *****/ Deg.DegCod = Crs.DegCod; diff --git a/swad_file_browser.c b/swad_file_browser.c index a8e1d1126..5bb80fc7e 100644 --- a/swad_file_browser.c +++ b/swad_file_browser.c @@ -6898,7 +6898,7 @@ static void Brw_WriteCurrentClipboard (void) break; case Brw_ADMI_DOC_CRS: Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s", Txt_documents_management_area, @@ -6908,7 +6908,7 @@ static void Brw_WriteCurrentClipboard (void) GrpDat.GrpCod = Gbl.FileBrowser.Clipboard.Cod; Grp_GetDataOfGroupByCod (&GrpDat); Crs.CrsCod = GrpDat.CrsCod; - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s, %s %s %s", Txt_documents_management_area, @@ -6917,7 +6917,7 @@ static void Brw_WriteCurrentClipboard (void) break; case Brw_ADMI_TCH_CRS: Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s", Txt_teachers_files_area, @@ -6927,7 +6927,7 @@ static void Brw_WriteCurrentClipboard (void) GrpDat.GrpCod = Gbl.FileBrowser.Clipboard.Cod; Grp_GetDataOfGroupByCod (&GrpDat); Crs.CrsCod = GrpDat.CrsCod; - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s, %s %s %s", Txt_teachers_files_area, @@ -6936,7 +6936,7 @@ static void Brw_WriteCurrentClipboard (void) break; case Brw_ADMI_SHR_CRS: Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s", Txt_shared_files_area, @@ -6946,7 +6946,7 @@ static void Brw_WriteCurrentClipboard (void) GrpDat.GrpCod = Gbl.FileBrowser.Clipboard.Cod; Grp_GetDataOfGroupByCod (&GrpDat); Crs.CrsCod = GrpDat.CrsCod; - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s, %s %s %s", Txt_shared_files_area, @@ -6955,7 +6955,7 @@ static void Brw_WriteCurrentClipboard (void) break; case Brw_ADMI_ASG_USR: Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s, %s %s", Txt_assignments_area, @@ -6964,7 +6964,7 @@ static void Brw_WriteCurrentClipboard (void) break; case Brw_ADMI_WRK_USR: Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s, %s %s", Txt_works_area, @@ -6973,7 +6973,7 @@ static void Brw_WriteCurrentClipboard (void) break; case Brw_ADMI_ASG_CRS: Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); Usr_UsrDataConstructor (&UsrDat); UsrDat.UsrCod = Gbl.FileBrowser.Clipboard.WorksUsrCod; Usr_GetAllUsrDataFromUsrCod (&UsrDat,Usr_DONT_GET_PREFS); @@ -6986,7 +6986,7 @@ static void Brw_WriteCurrentClipboard (void) break; case Brw_ADMI_WRK_CRS: Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); Usr_UsrDataConstructor (&UsrDat); UsrDat.UsrCod = Gbl.FileBrowser.Clipboard.WorksUsrCod; Usr_GetAllUsrDataFromUsrCod (&UsrDat,Usr_DONT_GET_PREFS); @@ -7003,7 +7003,7 @@ static void Brw_WriteCurrentClipboard (void) Prj.PrjCod = Gbl.FileBrowser.Clipboard.Cod; Prj_GetDataOfProjectByCod (&Prj); Crs.CrsCod = Prj.CrsCod; - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s, %s %s", Gbl.FileBrowser.Clipboard.FileBrowser == Brw_ADMI_DOC_PRJ ? Txt_project_documents : @@ -7014,7 +7014,7 @@ static void Brw_WriteCurrentClipboard (void) break; case Brw_ADMI_MRK_CRS: Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s", Txt_marks_management_area, @@ -7024,7 +7024,7 @@ static void Brw_WriteCurrentClipboard (void) GrpDat.GrpCod = Gbl.FileBrowser.Clipboard.Cod; Grp_GetDataOfGroupByCod (&GrpDat); Crs.CrsCod = GrpDat.CrsCod; - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s, %s %s %s", Txt_marks_management_area, @@ -7906,7 +7906,7 @@ static void Brw_PasteClipboard (void) case Brw_ADMI_SHR_CRS: case Brw_ADMI_MRK_CRS: Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; - if (Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA)) + if (Crs_GetDataOfCourseByCod (&Crs)) snprintf (PathOrg,sizeof (PathOrg), "%s/%ld/%s", Cfg_PATH_CRS_PRIVATE,Crs.CrsCod, @@ -7921,7 +7921,7 @@ static void Brw_PasteClipboard (void) GrpDat.GrpCod = Gbl.FileBrowser.Clipboard.Cod; Grp_GetDataOfGroupByCod (&GrpDat); Crs.CrsCod = GrpDat.CrsCod; - if (Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA)) + if (Crs_GetDataOfCourseByCod (&Crs)) snprintf (PathOrg,sizeof (PathOrg), "%s/%ld/%s/%ld/%s", Cfg_PATH_CRS_PRIVATE,Crs.CrsCod,Cfg_FOLDER_GRP, @@ -7933,7 +7933,7 @@ static void Brw_PasteClipboard (void) case Brw_ADMI_ASG_CRS: case Brw_ADMI_WRK_CRS: Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; - if (Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA)) + if (Crs_GetDataOfCourseByCod (&Crs)) { Usr_UsrDataConstructor (&UsrDat); UsrDat.UsrCod = Gbl.FileBrowser.Clipboard.WorksUsrCod; @@ -7952,7 +7952,7 @@ static void Brw_PasteClipboard (void) case Brw_ADMI_ASG_USR: case Brw_ADMI_WRK_USR: Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; - if (Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA)) + if (Crs_GetDataOfCourseByCod (&Crs)) snprintf (PathOrg,sizeof (PathOrg), "%s/%ld/%s/%02u/%ld/%s", Cfg_PATH_CRS_PRIVATE,Crs.CrsCod,Cfg_FOLDER_USR, @@ -7966,7 +7966,7 @@ static void Brw_PasteClipboard (void) case Brw_ADMI_ASS_PRJ: PrjCod = Gbl.FileBrowser.Clipboard.Cod; Crs.CrsCod = Prj_GetCourseOfProject (PrjCod); - if (Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA)) + if (Crs_GetDataOfCourseByCod (&Crs)) snprintf (PathOrg,sizeof (PathOrg), "%s/%ld/%s/%02u/%ld/%s", Cfg_PATH_CRS_PRIVATE,Crs.CrsCod,Cfg_FOLDER_PRJ, @@ -11076,7 +11076,7 @@ void Brw_GetCrsGrpFromFileMetadata (Brw_FileBrowser_t FileBrowser,long Cod, /* Cod stores the course code */ *GrpCod = -1L; *CrsCod = Crs.CrsCod = Cod; - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); *DegCod = Deg.DegCod = Crs.DegCod; Deg_GetDataOfDegreeByCod (&Deg); *CtrCod = Ctr.CtrCod = Deg.CtrCod; @@ -11091,7 +11091,7 @@ void Brw_GetCrsGrpFromFileMetadata (Brw_FileBrowser_t FileBrowser,long Cod, *GrpCod = GrpDat.GrpCod = Cod; Grp_GetDataOfGroupByCod (&GrpDat); *CrsCod = Crs.CrsCod = GrpDat.CrsCod; - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); *DegCod = Deg.DegCod = Crs.DegCod; Deg_GetDataOfDegreeByCod (&Deg); *CtrCod = Ctr.CtrCod = Deg.CtrCod; @@ -11103,7 +11103,7 @@ void Brw_GetCrsGrpFromFileMetadata (Brw_FileBrowser_t FileBrowser,long Cod, /* Cod stores the project code */ *GrpCod = -1L; *CrsCod = Crs.CrsCod = Prj_GetCourseOfProject (Cod); - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); *DegCod = Deg.DegCod = Crs.DegCod; Deg_GetDataOfDegreeByCod (&Deg); *CtrCod = Ctr.CtrCod = Deg.CtrCod; @@ -11711,7 +11711,7 @@ void Brw_RemoveUsrWorksInAllCrss (struct UsrData *UsrDat) row = mysql_fetch_row (mysql_res); Crs.CrsCod = Str_ConvertStrCodToLongCod (row[0]); /* Get data of course */ - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); Brw_RemoveUsrWorksInCrs (UsrDat,&Crs); NumCrssWorksRemoved++; } diff --git a/swad_forum.c b/swad_forum.c index e793df847..2a481bf51 100644 --- a/swad_forum.c +++ b/swad_forum.c @@ -2207,14 +2207,14 @@ void For_SetForumName (struct Forum *Forum, break; case For_FORUM_COURSE_USRS: Crs.CrsCod = Forum->Location; - if (!Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA)) + if (!Crs_GetDataOfCourseByCod (&Crs)) Lay_ShowErrorAndExit ("Course not found."); Str_Copy (ForumName,Crs.ShrtName, For_MAX_BYTES_FORUM_NAME); break; case For_FORUM_COURSE_TCHS: Crs.CrsCod = Forum->Location; - if (!Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA)) + if (!Crs_GetDataOfCourseByCod (&Crs)) Lay_ShowErrorAndExit ("Course not found."); snprintf (ForumName,For_MAX_BYTES_FORUM_NAME + 1, "%s%s",Crs.ShrtName, diff --git a/swad_global.h b/swad_global.h index b261b4ad2..44da33dc0 100644 --- a/swad_global.h +++ b/swad_global.h @@ -794,10 +794,14 @@ struct Globals } NumUsrsWhoClaimToBelongToCtr; struct { - Rol_Role_t Role; long CtrCod; unsigned NumUsrs; - } NumUsrsInCrssOfCtr; + } NumUsrsInCrssOfCtr[Rol_NUM_ROLES]; + struct + { + long CrsCod; + unsigned NumUsrs; + } NumUsrsInCrs[Rol_NUM_ROLES]; struct { long UsrCod; diff --git a/swad_help.c b/swad_help.c index 1dc0d9dbc..7f95eceff 100644 --- a/swad_help.c +++ b/swad_help.c @@ -161,17 +161,17 @@ void Hlp_ShowHelpWhatWouldYouLikeToDo (void) if (Gbl.Usrs.Me.MyCrss.Num) // I am enroled in some courses { - if (Gbl.Hierarchy.Level == Hie_CRS && // Course selected - !Gbl.Hierarchy.Crs.NumUsrs[Rol_STD] && // Current course has no students + if (Gbl.Hierarchy.Level == Hie_CRS && // Course selected Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role == Rol_TCH) // I am a teacher in current course - { - /* Request students enrolment */ - Hlp_ShowRowHelpWhatWouldYouLikeToDo (Str_BuildStringStr (Txt_Register_students_in_COURSE_X, - Gbl.Hierarchy.Crs.ShrtName), - ActReqEnrSevStd, - Btn_CREATE_BUTTON,Txt_Register_students); - Str_FreeString (); - } + if (!Usr_GetNumUsrsInCrs (Rol_STD,Gbl.Hierarchy.Crs.CrsCod))// Current course has no students + { + /* Request students enrolment */ + Hlp_ShowRowHelpWhatWouldYouLikeToDo (Str_BuildStringStr (Txt_Register_students_in_COURSE_X, + Gbl.Hierarchy.Crs.ShrtName), + ActReqEnrSevStd, + Btn_CREATE_BUTTON,Txt_Register_students); + Str_FreeString (); + } if (Gbl.Action.Act != ActMyCrs) // I am not seeing the action to list my courses /* Request list my courses */ diff --git a/swad_hierarchy.c b/swad_hierarchy.c index 240357ff5..ec05292b9 100644 --- a/swad_hierarchy.c +++ b/swad_hierarchy.c @@ -525,8 +525,7 @@ void Hie_InitHierarchy (void) /***** If course code is available, get course data *****/ if (Gbl.Hierarchy.Crs.CrsCod > 0) { - if (Crs_GetDataOfCourseByCod (&Gbl.Hierarchy.Crs, // Course found - Crs_GET_EXTRA_DATA)) // Get extra data because they may be needed later + if (Crs_GetDataOfCourseByCod (&Gbl.Hierarchy.Crs)) // Course found Gbl.Hierarchy.Deg.DegCod = Gbl.Hierarchy.Crs.DegCod; else Hie_ResetHierarchy (); diff --git a/swad_layout.c b/swad_layout.c index 917546868..e0d7755aa 100644 --- a/swad_layout.c +++ b/swad_layout.c @@ -1561,7 +1561,7 @@ void Lay_WriteHeaderClassPhoto (bool PrintView,bool DrawingClassPhoto, /***** Get data of course *****/ Crs.CrsCod = CrsCod; - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); /***** Begin table *****/ HTM_TABLE_BeginWidePadding (10); diff --git a/swad_mark.c b/swad_mark.c index dea75e3b9..bc9fce132 100644 --- a/swad_mark.c +++ b/swad_mark.c @@ -623,8 +623,7 @@ void Mrk_ShowMyMarks (void) } else // Course zone { - // if (Usr_GetNumUsrsInCrs (Rol_STD,Gbl.Hierarchy.Crs.CrsCod)) // If there are students in this course - if (Gbl.Hierarchy.Crs.NumUsrs[Rol_STD]) + if (Usr_GetNumUsrsInCrs (Rol_STD,Gbl.Hierarchy.Crs.CrsCod)) // If there are students in this course { Gbl.Usrs.Other.UsrDat.UsrCod = Usr_GetRamdomStdFromCrs (Gbl.Hierarchy.Crs.CrsCod); UsrDat = &Gbl.Usrs.Other.UsrDat; diff --git a/swad_message.c b/swad_message.c index 6278a5721..ca53a305e 100644 --- a/swad_message.c +++ b/swad_message.c @@ -1030,7 +1030,7 @@ void Msg_GetParamMsgsCrsCod (void) { /* Get data of course */ Crs.CrsCod = Gbl.Msg.FilterCrsCod; - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); Str_Copy (Gbl.Msg.FilterCrsShrtName,Crs.ShrtName, Hie_MAX_BYTES_SHRT_NAME); @@ -2597,7 +2597,7 @@ void Msg_GetDistinctCoursesInMyMessages (void) row = mysql_fetch_row (mysql_res); Crs.CrsCod = Str_ConvertStrCodToLongCod (row[0]); if (Crs.CrsCod >= 0 && Gbl.Msg.NumCourses < Crs_MAX_COURSES_PER_USR) - if (Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA)) + if (Crs_GetDataOfCourseByCod (&Crs)) { Gbl.Msg.Courses[Gbl.Msg.NumCourses].CrsCod = Crs.CrsCod; Str_Copy (Gbl.Msg.Courses[Gbl.Msg.NumCourses].ShrtName,Crs.ShrtName, @@ -3279,7 +3279,7 @@ bool Msg_WriteCrsOrgMsg (long CrsCod) Crs.CrsCod = CrsCod; /* Get data of current degree */ - if (Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA)) + if (Crs_GetDataOfCourseByCod (&Crs)) { ThereIsOrgCrs = true; if ((FromThisCrs = (CrsCod == Gbl.Hierarchy.Crs.CrsCod))) // Message sent from current course diff --git a/swad_notification.c b/swad_notification.c index 45ac87a95..6be3cce5e 100644 --- a/swad_notification.c +++ b/swad_notification.c @@ -415,7 +415,7 @@ void Ntf_ShowMyNotifications (void) /* Get course code (row[5]) */ Crs.CrsCod = Str_ConvertStrCodToLongCod (row[5]); - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); /* Get message/post/... code (row[6]) */ Cod = Str_ConvertStrCodToLongCod (row[6]); @@ -1244,7 +1244,7 @@ unsigned Ntf_StoreNotifyEventsToAllUsrs (Ntf_NotifyEvent_t NotifyEvent,long Cod) case Ntf_EVENT_ENROLMENT_TCH: // This function should not be called in this case return 0; case Ntf_EVENT_ENROLMENT_REQUEST: - if (Gbl.Hierarchy.Crs.NumUsrs[Rol_TCH]) + if (Usr_GetNumUsrsInCrs (Rol_TCH,Gbl.Hierarchy.Crs.CrsCod)) { // If this course has teachers ==> send notification to teachers NumRows = DB_QuerySELECT (&mysql_res,"can not get users" @@ -1662,7 +1662,7 @@ static void Ntf_SendPendingNotifByEMailToOneUsr (struct UsrData *ToUsrDat,unsign /* Get course code (row[5]) */ Crs.CrsCod = Str_ConvertStrCodToLongCod (row[5]); - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); /* Get message/post/... code (row[6]) */ Cod = Str_ConvertStrCodToLongCod (row[6]); diff --git a/swad_report.c b/swad_report.c index 18b9e7806..6578e2045 100644 --- a/swad_report.c +++ b/swad_report.c @@ -1161,7 +1161,7 @@ static void Rep_WriteRowCrsData (long CrsCod,Rol_Role_t Role, /***** Get course data *****/ Crs.CrsCod = CrsCod; - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_EXTRA_DATA); + Crs_GetDataOfCourseByCod (&Crs); /***** Get degree data *****/ Deg.DegCod = Crs.DegCod; diff --git a/swad_statistic.c b/swad_statistic.c index 3fc161cbe..33df701fa 100644 --- a/swad_statistic.c +++ b/swad_statistic.c @@ -3619,7 +3619,7 @@ static void Sta_ShowNumHitsPerCourse (unsigned long NumRows, Crs.CrsCod = Str_ConvertStrCodToLongCod (row[0]); /* Get data of current degree */ - CrsOK = Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + CrsOK = Crs_GetDataOfCourseByCod (&Crs); HTM_TR_Begin (NULL); diff --git a/swad_timeline.c b/swad_timeline.c index d912c140b..0ca7907bf 100644 --- a/swad_timeline.c +++ b/swad_timeline.c @@ -1631,7 +1631,7 @@ static void TL_WriteNote (const struct TL_Note *SocNot, case TL_NOTE_NOTICE: /* Get course data */ Crs.CrsCod = SocNot->HieCod; - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); break; case TL_NOTE_FORUM_POST: /* Get forum type of the post */ diff --git a/swad_timetable.c b/swad_timetable.c index 295de2cbe..5b2d02df0 100644 --- a/swad_timetable.c +++ b/swad_timetable.c @@ -1547,7 +1547,7 @@ static void TT_TimeTableDrawCell (unsigned Weekday,unsigned Interval,unsigned Co if (Gbl.TimeTable.Type == TT_MY_TIMETABLE) { Crs.CrsCod = CrsCod; - Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); + Crs_GetDataOfCourseByCod (&Crs); if (ClassType == TT_LECTURE || ClassType == TT_PRACTICAL) { diff --git a/swad_user.c b/swad_user.c index 6e6e25721..ea8cd4011 100644 --- a/swad_user.c +++ b/swad_user.c @@ -4167,14 +4167,56 @@ static void Usr_WriteUsrData (const char *BgColor, /************* Get number of users with a role in a course *******************/ /*****************************************************************************/ +void Usr_FlushCacheNumUsrsInCrs (void) + { + Gbl.Cache.NumUsrsInCrs[Rol_UNK].CrsCod = + Gbl.Cache.NumUsrsInCrs[Rol_STD].CrsCod = + Gbl.Cache.NumUsrsInCrs[Rol_NET].CrsCod = + Gbl.Cache.NumUsrsInCrs[Rol_TCH].CrsCod = -1L; + + Gbl.Cache.NumUsrsInCrs[Rol_UNK].NumUsrs = + Gbl.Cache.NumUsrsInCrs[Rol_STD].NumUsrs = + Gbl.Cache.NumUsrsInCrs[Rol_NET].NumUsrs = + Gbl.Cache.NumUsrsInCrs[Rol_TCH].NumUsrs = 0; + } + unsigned Usr_GetNumUsrsInCrs (Rol_Role_t Role,long CrsCod) { - /***** Get the number of teachers in a course from database ******/ - return - (unsigned) DB_QueryCOUNT ("can not get the number of users in a course", - "SELECT COUNT(*) FROM crs_usr" - " WHERE CrsCod=%ld AND Role=%u", - CrsCod,(unsigned) Role); + /***** 1. Fast check: Trivial case *****/ + if (CrsCod <= 0) + return 0; + + /***** 2. Fast check: Trivial case *****/ + switch (Role) + { + case Rol_UNK: // Here Rol_UNK means all + case Rol_STD: + case Rol_NET: + case Rol_TCH: + break; + default: + return 0; + } + + /***** 3. Fast check: If cached... *****/ + if (CrsCod == Gbl.Cache.NumUsrsInCrs[Role].CrsCod) + return Gbl.Cache.NumUsrsInCrs[Role].NumUsrs; + + /***** 4. Slow: number of users in a course from database *****/ + Gbl.Cache.NumUsrsInCrs[Role].CrsCod = CrsCod; + if (Role == Rol_UNK) + Gbl.Cache.NumUsrsInCrs[Rol_UNK].NumUsrs = + (unsigned) DB_QueryCOUNT ("can not get the number of users in a course", + "SELECT COUNT(*) FROM crs_usr" + " WHERE CrsCod=%ld", + CrsCod); + else + Gbl.Cache.NumUsrsInCrs[Role].NumUsrs = + (unsigned) DB_QueryCOUNT ("can not get the number of users in a course", + "SELECT COUNT(*) FROM crs_usr" + " WHERE CrsCod=%ld AND Role=%u", + CrsCod,(unsigned) Role); + return Gbl.Cache.NumUsrsInCrs[Role].NumUsrs; } /*****************************************************************************/ @@ -4202,9 +4244,15 @@ unsigned Usr_GetNumUsrsInCrssOfDeg (Rol_Role_t Role,long DegCod) void Usr_FlushCacheNumUsrsInCrssOfCtr (void) { - Gbl.Cache.NumUsrsInCrssOfCtr.Role = Rol_UNK; - Gbl.Cache.NumUsrsInCrssOfCtr.CtrCod = -1L; - Gbl.Cache.NumUsrsInCrssOfCtr.NumUsrs = 0; + Gbl.Cache.NumUsrsInCrssOfCtr[Rol_UNK].CtrCod = + Gbl.Cache.NumUsrsInCrssOfCtr[Rol_STD].CtrCod = + Gbl.Cache.NumUsrsInCrssOfCtr[Rol_NET].CtrCod = + Gbl.Cache.NumUsrsInCrssOfCtr[Rol_TCH].CtrCod = -1L; + + Gbl.Cache.NumUsrsInCrssOfCtr[Rol_UNK].NumUsrs = + Gbl.Cache.NumUsrsInCrssOfCtr[Rol_STD].NumUsrs = + Gbl.Cache.NumUsrsInCrssOfCtr[Rol_NET].NumUsrs = + Gbl.Cache.NumUsrsInCrssOfCtr[Rol_TCH].NumUsrs = 0; } unsigned Usr_GetNumUsrsInCrssOfCtr (Rol_Role_t Role,long CtrCod) @@ -4213,17 +4261,27 @@ unsigned Usr_GetNumUsrsInCrssOfCtr (Rol_Role_t Role,long CtrCod) if (CtrCod <= 0) return 0; - /***** 2. Fast check: If cached... *****/ - if (Role == Gbl.Cache.NumUsrsInCrssOfCtr.Role && - CtrCod == Gbl.Cache.NumUsrsInCrssOfCtr.CtrCod) - return Gbl.Cache.NumUsrsInCrssOfCtr.NumUsrs; + /***** 2. Fast check: Trivial case *****/ + switch (Role) + { + case Rol_UNK: // Here Rol_UNK means all + case Rol_STD: + case Rol_NET: + case Rol_TCH: + break; + default: + return 0; + } - /***** 3. Slow: get number of users in courses of a centre + /***** 3. Fast check: If cached... *****/ + if (CtrCod == Gbl.Cache.NumUsrsInCrssOfCtr[Role].CtrCod) + return Gbl.Cache.NumUsrsInCrssOfCtr[Role].NumUsrs; + + /***** 4. Slow: get number of users in courses of a centre from database *****/ - Gbl.Cache.NumUsrsInCrssOfCtr.Role = Role; - Gbl.Cache.NumUsrsInCrssOfCtr.CtrCod = CtrCod; + Gbl.Cache.NumUsrsInCrssOfCtr[Role].CtrCod = CtrCod; if (Role == Rol_UNK) // Any user - Gbl.Cache.NumUsrsInCrssOfCtr.NumUsrs = + Gbl.Cache.NumUsrsInCrssOfCtr[Rol_UNK].NumUsrs = (unsigned) DB_QueryCOUNT ("can not get the number of users" " in courses of a centre", "SELECT COUNT(DISTINCT crs_usr.UsrCod)" @@ -4235,7 +4293,7 @@ unsigned Usr_GetNumUsrsInCrssOfCtr (Rol_Role_t Role,long CtrCod) else // This query is very slow. // It's a bad idea to get number of teachers or students for a big list of centres - Gbl.Cache.NumUsrsInCrssOfCtr.NumUsrs = + Gbl.Cache.NumUsrsInCrssOfCtr[Role].NumUsrs = (unsigned) DB_QueryCOUNT ("can not get the number of users" " in courses of a centre", "SELECT COUNT(DISTINCT crs_usr.UsrCod)" @@ -4245,7 +4303,7 @@ unsigned Usr_GetNumUsrsInCrssOfCtr (Rol_Role_t Role,long CtrCod) " AND courses.CrsCod=crs_usr.CrsCod" " AND crs_usr.Role=%u", CtrCod,(unsigned) Role); - return Gbl.Cache.NumUsrsInCrssOfCtr.NumUsrs; + return Gbl.Cache.NumUsrsInCrssOfCtr[Role].NumUsrs; } /*****************************************************************************/ @@ -9804,21 +9862,7 @@ double Usr_GetNumUsrsPerCrs (Rol_Role_t Role) (unsigned) Role); break; case Hie_CRS: - switch (Role) - { - case Rol_UNK: - return (double) Gbl.Hierarchy.Crs.NumUsrs[Rol_UNK]; // Any user - case Rol_STD: - return (double) Gbl.Hierarchy.Crs.NumUsrs[Rol_STD]; // Students - case Rol_NET: - return (double) Gbl.Hierarchy.Crs.NumUsrs[Rol_UNK]; // Non-editing teachers - case Rol_TCH: - return (double) Gbl.Hierarchy.Crs.NumUsrs[Rol_UNK]; // Teachers - default: - Rol_WrongRoleExit (); - break; // Not reached - } - break; + return (double) Usr_GetNumUsrsInCrs (Role,Gbl.Hierarchy.Crs.CrsCod); default: Lay_WrongScopeExit (); break; diff --git a/swad_user.h b/swad_user.h index f2035943d..78739f12c 100644 --- a/swad_user.h +++ b/swad_user.h @@ -407,6 +407,7 @@ void Usr_WriteRowUsrMainData (unsigned NumUsr,struct UsrData *UsrDat, bool PutCheckBoxToSelectUsr,Rol_Role_t Role, struct SelectedUsrs *SelectedUsrs); +void Usr_FlushCacheNumUsrsInCrs (void); unsigned Usr_GetNumUsrsInCrs (Rol_Role_t Role,long CrsCod); unsigned Usr_GetNumUsrsInCrssOfDeg (Rol_Role_t Role,long DegCod); void Usr_FlushCacheNumUsrsInCrssOfCtr (void);