diff --git a/swad_centre.c b/swad_centre.c index 19513108b..03b75ec19 100644 --- a/swad_centre.c +++ b/swad_centre.c @@ -416,7 +416,8 @@ static void Ctr_ListOneCentreForSeeing (struct Centre *Ctr,unsigned NumCtr) /***** Number of users in courses of this centre *****/ HTM_TD_Begin ("class=\"%s RM %s\"",TxtClassNormal,BgColor); - HTM_Unsigned (Ctr->NumUsrs); + HTM_Unsigned (Usr_GetNumUsrsInCrssOfCtr (Rol_UNK, // Here Rol_UNK means "all users" + Ctr->CtrCod)); HTM_TD_End (); /***** Centre status *****/ @@ -612,9 +613,6 @@ void Ctr_GetListCentres (long InsCod) /* Get number of courses in this centre */ Ctr->NumCrss = Crs_GetNumCrssInCtr (Ctr->CtrCod); - - /* Get number of users in courses of this centre */ - Ctr->NumUsrs = Usr_GetNumUsrsInCrssOfCtr (Rol_UNK,Ctr->CtrCod); // Here Rol_UNK means "all users" } } else @@ -647,7 +645,6 @@ bool Ctr_GetDataOfCentreByCod (struct Centre *Ctr, Ctr->NumUsrsWhoClaimToBelongToCtr = 0; Ctr->Degs.Num = Ctr->NumCrss = 0; - Ctr->NumUsrs = 0; /***** Check if centre code is correct *****/ if (Ctr->CtrCod > 0) @@ -704,9 +701,6 @@ bool Ctr_GetDataOfCentreByCod (struct Centre *Ctr, /* Get number of courses in this centre */ Ctr->NumCrss = Crs_GetNumCrssInCtr (Ctr->CtrCod); - - /* Get number of users in courses of this centre */ - Ctr->NumUsrs = Usr_GetNumUsrsInCrssOfCtr (Rol_UNK,Ctr->CtrCod); // Here Rol_UNK means "all users" } /* Set return value */ @@ -944,12 +938,16 @@ static void Ctr_ListCentresForEdition (void) /* Put icon to remove centre */ HTM_TR_Begin (NULL); HTM_TD_Begin ("class=\"BM\""); - if (Ctr->Degs.Num || - Ctr->NumUsrsWhoClaimToBelongToCtr || - Ctr->NumUsrs || // Centre has degrees or users ==> deletion forbidden - !ICanEdit) + if (!ICanEdit) Ico_PutIconRemovalNotAllowed (); - else + else if (Ctr->Degs.Num) // Centre has degrees + Ico_PutIconRemovalNotAllowed (); + else if (Ctr->NumUsrsWhoClaimToBelongToCtr) // Centre has users who claim to belong to it + Ico_PutIconRemovalNotAllowed (); + else if (Usr_GetNumUsrsInCrssOfCtr (Rol_UNK, // Here Rol_UNK means "all users" + Ctr->CtrCod)) // Centre has users + Ico_PutIconRemovalNotAllowed (); + else // I can remove centre { Frm_StartForm (ActRemCtr); Ctr_PutParamOtherCtrCod (Ctr->CtrCod); @@ -1059,7 +1057,8 @@ static void Ctr_ListCentresForEdition (void) /* Number of users in courses of this centre */ HTM_TD_Begin ("class=\"DAT RM\""); - HTM_Unsigned (Ctr->NumUsrs); + HTM_Unsigned (Usr_GetNumUsrsInCrssOfCtr (Rol_UNK, // Here Rol_UNK means "all users" + Ctr->CtrCod)); HTM_TD_End (); /* Centre requester */ @@ -1210,11 +1209,14 @@ void Ctr_RemoveCentre (void) Ctr_GetDataOfCentreByCod (Ctr_EditingCtr,Ctr_GET_EXTRA_DATA); /***** Check if this centre has teachers *****/ - if (Ctr_EditingCtr->Degs.Num || - Ctr_EditingCtr->NumUsrsWhoClaimToBelongToCtr || - Ctr_EditingCtr->NumUsrs) // Centre has degrees or users ==> don't remove + if (Ctr_EditingCtr->Degs.Num) // Centre has degrees Ale_ShowAlert (Ale_WARNING,Txt_To_remove_a_centre_you_must_first_remove_all_degrees_and_teachers_in_the_centre); - else // Centre has no teachers ==> remove it + else if (Ctr_EditingCtr->NumUsrsWhoClaimToBelongToCtr) // Centre has users who claim to belong to it + Ale_ShowAlert (Ale_WARNING,Txt_To_remove_a_centre_you_must_first_remove_all_degrees_and_teachers_in_the_centre); + else if (Usr_GetNumUsrsInCrssOfCtr (Rol_UNK, // Here Rol_UNK means "all users" + Ctr_EditingCtr->CtrCod)) // Centre has users + Ale_ShowAlert (Ale_WARNING,Txt_To_remove_a_centre_you_must_first_remove_all_degrees_and_teachers_in_the_centre); + else // Centre has no degrees or users ==> remove it { /***** Remove all the threads and posts in forums of the centre *****/ For_RemoveForums (Hie_CTR,Ctr_EditingCtr->CtrCod); @@ -1241,6 +1243,9 @@ void Ctr_RemoveCentre (void) "DELETE FROM centres WHERE CtrCod=%ld", Ctr_EditingCtr->CtrCod); + /***** Flush caches *****/ + Ctr_FlushCacheNumUsrsInCrssOfCtr (); + /***** Write message to show the change made *****/ Ale_CreateAlert (Ale_SUCCESS,NULL, Txt_Centre_X_removed, @@ -2052,7 +2057,6 @@ static void Ctr_EditingCentreConstructor (void) Ctr_EditingCtr->Degs.Num = 0; Ctr_EditingCtr->Degs.Lst = NULL; Ctr_EditingCtr->NumCrss = 0; - Ctr_EditingCtr->NumUsrs = 0; Ctr_EditingCtr->NumUsrsWhoClaimToBelongToCtr = 0; } diff --git a/swad_centre.h b/swad_centre.h index 8003a64f8..557284646 100644 --- a/swad_centre.h +++ b/swad_centre.h @@ -73,7 +73,6 @@ struct Centre char WWW[Cns_MAX_BYTES_WWW + 1]; struct ListDegrees Degs; // List of degrees in this centre unsigned NumCrss; // Number of courses in this centre - unsigned NumUsrs; // Number of users in courses of this centre unsigned NumUsrsWhoClaimToBelongToCtr; // Number of users who claim to belong in this centre }; diff --git a/swad_changelog.h b/swad_changelog.h index 62e4a29bf..a117a932e 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.3 (2020-01-04)" +#define Log_PLATFORM_VERSION "SWAD 19.112.4 (2020-01-05)" #define CSS_FILE "swad19.112.css" #define JS_FILE "swad19.91.1.js" /* @@ -501,6 +501,7 @@ 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 + Version 19.112.4: Jan 05, 2020 Optimization in number of users in courses of a centre. (278385 lines) Version 19.112.3: Jan 04, 2020 Fixed bug in hierarchy. (278357 lines) Version 19.112.2: Jan 04, 2020 Changing action descriptions from database to swad-core. Not finished. (278351 lines) Version 19.112.1: Jan 03, 2020 Code refactoring in maps. (278391 lines) diff --git a/swad_global.c b/swad_global.c index 9599b971a..5b02ee6de 100644 --- a/swad_global.c +++ b/swad_global.c @@ -412,6 +412,7 @@ void Gbl_InitializeGlobals (void) Cty_FlushCacheCountryName (); Ins_FlushCacheShortNameOfInstitution (); Ins_FlushCacheFullNameAndCtyOfInstitution (); + Ctr_FlushCacheNumUsrsInCrssOfCtr (); Usr_FlushCacheUsrIsSuperuser (); Usr_FlushCacheUsrBelongsToIns (); Usr_FlushCacheUsrBelongsToCtr (); diff --git a/swad_global.h b/swad_global.h index baba4ca02..da849e297 100644 --- a/swad_global.h +++ b/swad_global.h @@ -772,6 +772,12 @@ struct Globals char ShrtName[Hie_MAX_BYTES_SHRT_NAME + 1]; char CtyName[Hie_MAX_BYTES_FULL_NAME + 1]; } InstitutionShrtNameAndCty; + struct + { + Rol_Role_t Role; + long CtrCod; + unsigned NumUsrs; + } NumUsrsInCrssOfCtr; struct { long UsrCod; diff --git a/swad_user.c b/swad_user.c index 0e29d62d1..7db6b7005 100644 --- a/swad_user.c +++ b/swad_user.c @@ -4200,13 +4200,30 @@ unsigned Usr_GetNumUsrsInCrssOfDeg (Rol_Role_t Role,long DegCod) /*****************************************************************************/ // Here Rol_UNK means any user (students, non-editing teachers or teachers) +void Ctr_FlushCacheNumUsrsInCrssOfCtr (void) + { + Gbl.Cache.NumUsrsInCrssOfCtr.Role = Rol_UNK; + Gbl.Cache.NumUsrsInCrssOfCtr.CtrCod = -1L; + Gbl.Cache.NumUsrsInCrssOfCtr.NumUsrs = 0; + } + unsigned Usr_GetNumUsrsInCrssOfCtr (Rol_Role_t Role,long CtrCod) { - unsigned NumUsrs; + /***** 1. Fast check: Trivial case *****/ + if (CtrCod <= 0) + return 0; - /***** Get the number of users in courses of a centre from database ******/ + /***** 2. Fast check: If cached... *****/ + if (Role == Gbl.Cache.NumUsrsInCrssOfCtr.Role && + CtrCod == Gbl.Cache.NumUsrsInCrssOfCtr.CtrCod) + return Gbl.Cache.NumUsrsInCrssOfCtr.NumUsrs; + + /***** 3. Slow: get number of users in courses of a centre + from database *****/ + Gbl.Cache.NumUsrsInCrssOfCtr.Role = Role; + Gbl.Cache.NumUsrsInCrssOfCtr.CtrCod = CtrCod; if (Role == Rol_UNK) // Any user - NumUsrs = + Gbl.Cache.NumUsrsInCrssOfCtr.NumUsrs = (unsigned) DB_QueryCOUNT ("can not get the number of users" " in courses of a centre", "SELECT COUNT(DISTINCT crs_usr.UsrCod)" @@ -4218,7 +4235,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 - NumUsrs = + Gbl.Cache.NumUsrsInCrssOfCtr.NumUsrs = (unsigned) DB_QueryCOUNT ("can not get the number of users" " in courses of a centre", "SELECT COUNT(DISTINCT crs_usr.UsrCod)" @@ -4228,7 +4245,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 NumUsrs; + return Gbl.Cache.NumUsrsInCrssOfCtr.NumUsrs; } /*****************************************************************************/ diff --git a/swad_user.h b/swad_user.h index 2fdc274c8..432202890 100644 --- a/swad_user.h +++ b/swad_user.h @@ -409,6 +409,7 @@ void Usr_WriteRowUsrMainData (unsigned NumUsr,struct UsrData *UsrDat, unsigned Usr_GetNumUsrsInCrs (Rol_Role_t Role,long CrsCod); unsigned Usr_GetNumUsrsInCrssOfDeg (Rol_Role_t Role,long DegCod); +void Ctr_FlushCacheNumUsrsInCrssOfCtr (void); unsigned Usr_GetNumUsrsInCrssOfCtr (Rol_Role_t Role,long CtrCod); unsigned Usr_GetNumUsrsInCrssOfIns (Rol_Role_t Role,long InsCod); unsigned Usr_GetNumUsrsInCrssOfCty (Rol_Role_t Role,long CtyCod);