diff --git a/swad_centre.c b/swad_centre.c index 75506c20..fbe8108d 100644 --- a/swad_centre.c +++ b/swad_centre.c @@ -850,6 +850,7 @@ static void Ctr_ListCentresForEdition (void) char WWW[Cns_MAX_BYTES_WWW + 1]; struct UsrData UsrDat; bool ICanEdit; + unsigned NumUsrsInCrssOfCtr; Ctr_StatusTxt_t StatusTxt; unsigned StatusUnsigned; @@ -868,19 +869,18 @@ static void Ctr_ListCentresForEdition (void) Ctr = &Gbl.Hierarchy.Ins.Ctrs.Lst[NumCtr]; ICanEdit = Ctr_CheckIfICanEditACentre (Ctr); + NumUsrsInCrssOfCtr = Usr_GetNumUsrsInCrssOfCtr (Rol_UNK,Ctr->CtrCod); // Here Rol_UNK means "all users" /* Put icon to remove centre */ HTM_TR_Begin (NULL); HTM_TD_Begin ("class=\"BM\""); - if (!ICanEdit) + if (!ICanEdit || // I cannot edit + NumUsrsInCrssOfCtr) // Centre has users Ico_PutIconRemovalNotAllowed (); else if (Deg_GetNumDegsInCtr (Ctr->CtrCod)) // Centre has degrees Ico_PutIconRemovalNotAllowed (); else if (Usr_GetNumUsrsWhoClaimToBelongToCtr (Ctr->CtrCod)) // 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); @@ -991,8 +991,7 @@ static void Ctr_ListCentresForEdition (void) /* Number of users in courses of this centre */ HTM_TD_Begin ("class=\"DAT RM\""); - HTM_Unsigned (Usr_GetNumUsrsInCrssOfCtr (Rol_UNK, // Here Rol_UNK means "all users" - Ctr->CtrCod)); + HTM_Unsigned (NumUsrsInCrssOfCtr); HTM_TD_End (); /* Centre requester */ diff --git a/swad_changelog.h b/swad_changelog.h index 801d686e..91864f75 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.10 (2020-01-06)" +#define Log_PLATFORM_VERSION "SWAD 19.112.11 (2020-01-06)" #define CSS_FILE "swad19.112.css" #define JS_FILE "swad19.91.1.js" /* @@ -502,6 +502,7 @@ ps2pdf source.ps destination.pdf // TODO: Mapas más estrechos en móvil // TODO: Quitar todos los EXTRA_DATA. + Version 19.112.11:Jan 06, 2020 Optimization in number of users in courses of an institution. (278486 lines) Version 19.112.10:Jan 06, 2020 Optimization in number of users in courses of a degree. (278468 lines) 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) diff --git a/swad_global.c b/swad_global.c index b2100872..07aac42f 100644 --- a/swad_global.c +++ b/swad_global.c @@ -221,7 +221,6 @@ void Gbl_InitializeGlobals (void) Gbl.Hierarchy.Ins.FullName[0] = '\0'; Gbl.Hierarchy.Ins.WWW[0] = '\0'; Gbl.Hierarchy.Ins.Ctrs.Num = Gbl.Hierarchy.Ins.NumDpts = Gbl.Hierarchy.Ins.NumDegs = 0; - Gbl.Hierarchy.Ins.NumUsrs = 0; Gbl.Hierarchy.Ctr.ShrtName[0] = '\0'; Gbl.Hierarchy.Ctr.FullName[0] = '\0'; @@ -416,6 +415,7 @@ void Gbl_InitializeGlobals (void) Crs_FlushCacheNumCrssInCtr (); Crs_FlushCacheNumCrssInDeg (); Usr_FlushCacheNumUsrsWhoClaimToBelongToCtr (); + Usr_FlushCacheNumUsrsInCrssOfIns (); Usr_FlushCacheNumUsrsInCrssOfCtr (); Usr_FlushCacheNumUsrsInCrssOfDeg (); Usr_FlushCacheNumUsrsInCrs (); diff --git a/swad_global.h b/swad_global.h index e56a044d..7d0854e4 100644 --- a/swad_global.h +++ b/swad_global.h @@ -792,6 +792,11 @@ struct Globals long CtrCod; unsigned NumUsrs; } NumUsrsWhoClaimToBelongToCtr; + struct + { + long InsCod; + unsigned NumUsrs; + } NumUsrsInCrssOfIns[Rol_NUM_ROLES]; struct { long CtrCod; diff --git a/swad_institution.c b/swad_institution.c index 55f286c5..571462a9 100644 --- a/swad_institution.c +++ b/swad_institution.c @@ -427,7 +427,7 @@ static void Ins_ListOneInstitutionForSeeing (struct Instit *Ins,unsigned NumIns) /* Number of users in courses of this institution */ HTM_TD_Begin ("class=\"%s RM %s\"",TxtClassNormal,BgColor); - HTM_Unsigned (Ins->NumUsrs); + HTM_Unsigned (Usr_GetNumUsrsInCrssOfIns (Rol_UNK,Ins->InsCod)); // Here Rol_UNK means "all users" HTM_TD_End (); /***** Institution status *****/ @@ -688,7 +688,6 @@ void Ins_GetListInstitutions (long CtyCod,Ins_GetExtraData_t GetExtraData) case Ins_GET_BASIC_DATA: Ins->NumUsrsWhoClaimToBelongToIns = 0; Ins->Ctrs.Num = Ins->NumDegs = Ins->NumCrss = Ins->NumDpts = 0; - Ins->NumUsrs = 0; break; case Ins_GET_EXTRA_DATA: /* Get number of users who claim to belong to this institution (row[7]) */ @@ -706,9 +705,6 @@ void Ins_GetListInstitutions (long CtyCod,Ins_GetExtraData_t GetExtraData) /* Get number of departments in this institution */ Ins->NumDpts = Dpt_GetNumDptsInIns (Ins->InsCod); - - /* Get number of users in courses */ - Ins->NumUsrs = Usr_GetNumUsrsInCrssOfIns (Rol_UNK,Ins->InsCod); // Here Rol_UNK means "all users" break; } } @@ -758,7 +754,6 @@ bool Ins_GetDataOfInstitutionByCod (struct Instit *Ins, Ins->WWW[0] = '\0'; Ins->NumUsrsWhoClaimToBelongToIns = 0; Ins->Ctrs.Num = Ins->NumDegs = Ins->NumCrss = Ins->NumDpts = 0; - Ins->NumUsrs = 0; /***** Check if institution code is correct *****/ if (Ins->InsCod > 0) @@ -805,9 +800,6 @@ bool Ins_GetDataOfInstitutionByCod (struct Instit *Ins, /* Get number of degrees in this institution */ Ins->NumDegs = Deg_GetNumDegsInIns (Ins->InsCod); - - /* Get number of users in courses of this institution */ - Ins->NumUsrs = Usr_GetNumUsrsInCrssOfIns (Rol_UNK,Ins->InsCod); // Here Rol_UNK means "all users" } /* Set return value */ @@ -1041,6 +1033,7 @@ static void Ins_ListInstitutionsForEdition (void) char WWW[Cns_MAX_BYTES_WWW + 1]; struct UsrData UsrDat; bool ICanEdit; + unsigned NumUsrsInCrssOfIns; Ins_StatusTxt_t StatusTxt; unsigned StatusUnsigned; @@ -1059,15 +1052,17 @@ static void Ins_ListInstitutionsForEdition (void) Ins = &Gbl.Hierarchy.Cty.Inss.Lst[NumIns]; ICanEdit = Ins_CheckIfICanEdit (Ins); + NumUsrsInCrssOfIns = Usr_GetNumUsrsInCrssOfIns (Rol_UNK,Ins->InsCod); // Here Rol_UNK means "all users" HTM_TR_Begin (NULL); /* Put icon to remove institution */ HTM_TD_Begin ("class=\"BM\""); - if (Ins->Ctrs.Num || - Ins->NumUsrsWhoClaimToBelongToIns || - Ins->NumUsrs || // Institution has centres or users ==> deletion forbidden - !ICanEdit) + if (!ICanEdit || + Ins->Ctrs.Num || // Institution has centres + NumUsrsInCrssOfIns || // Institution has users + Ins->NumUsrsWhoClaimToBelongToIns) + // Institution has centres or users ==> deletion forbidden Ico_PutIconRemovalNotAllowed (); else { @@ -1152,7 +1147,7 @@ static void Ins_ListInstitutionsForEdition (void) /* Number of users in courses of this institution */ HTM_TD_Begin ("class=\"DAT RM\""); - HTM_Unsigned (Ins->NumUsrs); + HTM_Unsigned (NumUsrsInCrssOfIns); HTM_TD_End (); /* Institution requester */ @@ -1318,8 +1313,12 @@ void Ins_RemoveInstitution (void) if (!Ins_CheckIfICanEdit (Ins_EditingIns)) Lay_NoPermissionExit (); else if (Ins_EditingIns->Ctrs.Num || - Ins_EditingIns->NumUsrsWhoClaimToBelongToIns || - Ins_EditingIns->NumUsrs) // Institution has centres or users ==> don't remove + Ins_EditingIns->NumUsrsWhoClaimToBelongToIns) + // Institution has centres or users ==> don't remove + Ale_CreateAlert (Ale_WARNING,NULL, + Txt_To_remove_an_institution_you_must_first_remove_all_centres_and_users_in_the_institution); + else if (Usr_GetNumUsrsInCrssOfIns (Rol_UNK,Ins_EditingIns->InsCod)) // Here Rol_UNK means "all users" + // Institution has users ==> don't remove Ale_CreateAlert (Ale_WARNING,NULL, Txt_To_remove_an_institution_you_must_first_remove_all_centres_and_users_in_the_institution); else // Institution has no users ==> remove it @@ -1349,6 +1348,7 @@ void Ins_RemoveInstitution (void) /***** Flush caches *****/ Ins_FlushCacheShortNameOfInstitution (); Ins_FlushCacheFullNameAndCtyOfInstitution (); + Usr_FlushCacheNumUsrsInCrssOfIns (); /***** Write message to show the change made *****/ Ale_CreateAlert (Ale_SUCCESS,NULL, @@ -2029,7 +2029,6 @@ static void Ins_EditingInstitutionConstructor (void) Ins_EditingIns->Ctrs.SelectedOrder = Ctr_ORDER_DEFAULT; Ins_EditingIns->NumDpts = 0; Ins_EditingIns->NumDegs = 0; - Ins_EditingIns->NumUsrs = 0; Ins_EditingIns->NumUsrsWhoClaimToBelongToIns = 0; } diff --git a/swad_institution.h b/swad_institution.h index 2a7a225c..0dbedb2f 100644 --- a/swad_institution.h +++ b/swad_institution.h @@ -74,7 +74,6 @@ struct Instit unsigned NumDegs; unsigned NumCrss; unsigned NumDpts; - unsigned NumUsrs; // Number of users in courses of this institution unsigned NumUsrsWhoClaimToBelongToIns; }; diff --git a/swad_institution_config.c b/swad_institution_config.c index 450e5eb0..f2a07774 100644 --- a/swad_institution_config.c +++ b/swad_institution_config.c @@ -428,7 +428,7 @@ static void InsCfg_FullName (bool PutForm) extern const char *Txt_Institution; HieCfg_FullName (PutForm,Txt_Institution,ActRenInsFulCfg, - Gbl.Hierarchy.Ins.FullName); + Gbl.Hierarchy.Ins.FullName); } /*****************************************************************************/ diff --git a/swad_user.c b/swad_user.c index f4e379f8..388aba97 100644 --- a/swad_user.c +++ b/swad_user.c @@ -4222,6 +4222,7 @@ unsigned Usr_GetNumUsrsInCrs (Rol_Role_t Role,long CrsCod) /*****************************************************************************/ /*********** Count how many users with a role belong to a degree *************/ /*****************************************************************************/ +// Here Rol_UNK means any user (students, non-editing teachers or teachers) void Usr_FlushCacheNumUsrsInCrssOfDeg (void) { @@ -4260,7 +4261,7 @@ unsigned Usr_GetNumUsrsInCrssOfDeg (Rol_Role_t Role,long DegCod) /***** 4. Slow: number of users in courses of a degree from database *****/ Gbl.Cache.NumUsrsInCrssOfDeg[Role].DegCod = DegCod; - if (Role == Rol_UNK) + if (Role == Rol_UNK) // Any user Gbl.Cache.NumUsrsInCrssOfDeg[Rol_UNK].NumUsrs = (unsigned) DB_QueryCOUNT ("can not get the number of users" " in courses of a degree", @@ -4354,15 +4355,48 @@ unsigned Usr_GetNumUsrsInCrssOfCtr (Rol_Role_t Role,long CtrCod) /*****************************************************************************/ /********* Count how many users with a role belong to an institution *********/ /*****************************************************************************/ -// Here Rol_UNK means students or teachers +// Here Rol_UNK means any user (students, non-editing teachers or teachers) + +void Usr_FlushCacheNumUsrsInCrssOfIns (void) + { + Gbl.Cache.NumUsrsInCrssOfIns[Rol_UNK].InsCod = + Gbl.Cache.NumUsrsInCrssOfIns[Rol_STD].InsCod = + Gbl.Cache.NumUsrsInCrssOfIns[Rol_NET].InsCod = + Gbl.Cache.NumUsrsInCrssOfIns[Rol_TCH].InsCod = -1L; + + Gbl.Cache.NumUsrsInCrssOfIns[Rol_UNK].NumUsrs = + Gbl.Cache.NumUsrsInCrssOfIns[Rol_STD].NumUsrs = + Gbl.Cache.NumUsrsInCrssOfIns[Rol_NET].NumUsrs = + Gbl.Cache.NumUsrsInCrssOfIns[Rol_TCH].NumUsrs = 0; + } unsigned Usr_GetNumUsrsInCrssOfIns (Rol_Role_t Role,long InsCod) { - unsigned NumUsrs; + /***** 1. Fast check: Trivial case *****/ + if (InsCod <= 0) + return 0; - /***** Get the number of users in courses of an institution from database ******/ + /***** 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 (InsCod == Gbl.Cache.NumUsrsInCrssOfIns[Role].InsCod) + return Gbl.Cache.NumUsrsInCrssOfIns[Role].NumUsrs; + + /***** 4. Slow: get number of users in courses of an institution + from database *****/ + Gbl.Cache.NumUsrsInCrssOfIns[Role].InsCod = InsCod; if (Role == Rol_UNK) // Any user - NumUsrs = + Gbl.Cache.NumUsrsInCrssOfIns[Rol_UNK].NumUsrs = (unsigned) DB_QueryCOUNT ("can not get the number of users" " in courses of an institution", "SELECT COUNT(DISTINCT crs_usr.UsrCod)" @@ -4375,7 +4409,7 @@ unsigned Usr_GetNumUsrsInCrssOfIns (Rol_Role_t Role,long InsCod) else // This query is very slow. // It's a bad idea to get number of teachers or students for a big list of institutions - NumUsrs = + Gbl.Cache.NumUsrsInCrssOfIns[Role].NumUsrs = (unsigned) DB_QueryCOUNT ("can not get the number of users" " in courses of an institution", "SELECT COUNT(DISTINCT crs_usr.UsrCod)" @@ -4386,7 +4420,7 @@ unsigned Usr_GetNumUsrsInCrssOfIns (Rol_Role_t Role,long InsCod) " AND courses.CrsCod=crs_usr.CrsCod" " AND crs_usr.Role=%u", InsCod,(unsigned) Role); - return NumUsrs; + return Gbl.Cache.NumUsrsInCrssOfIns[Role].NumUsrs; } /*****************************************************************************/ @@ -5492,50 +5526,31 @@ static void Usr_GetGstsLst (Hie_Level_t Scope) void Usr_GetUnorderedStdsCodesInDeg (long DegCod) { - const char *QueryFields = - "DISTINCT usr_data.UsrCod," - "usr_data.EncryptedUsrCod," - "usr_data.Password," - "usr_data.Surname1," - "usr_data.Surname2," - "usr_data.FirstName," - "usr_data.Sex," - "usr_data.Photo," - "usr_data.PhotoVisibility," - "usr_data.CtyCod," - "usr_data.InsCod"; - /* - row[ 0]: usr_data.UsrCod - row[ 1]: usr_data.EncryptedUsrCod - row[ 2]: usr_data.Password - row[ 3]: usr_data.Surname1 - row[ 4]: usr_data.Surname2 - row[ 5]: usr_data.FirstName - row[ 6]: usr_data.Sex - row[ 7]: usr_data.Photo - row[ 8]: usr_data.PhotoVisibility - row[ 9]: usr_data.CtyCod - row[10]: usr_data.InsCod - */ char *Query = NULL; - Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs = 0; - if (Usr_GetNumUsrsInCrssOfDeg (Rol_STD,DegCod)) - { /***** Get the students in a degree from database *****/ DB_BuildQuery (&Query, - "SELECT %s FROM courses,crs_usr,usr_data" + "SELECT DISTINCT usr_data.UsrCod," // row[ 0] + "usr_data.EncryptedUsrCod," // row[ 1] + "usr_data.Password," // row[ 2] + "usr_data.Surname1," // row[ 3] + "usr_data.Surname2," // row[ 4] + "usr_data.FirstName," // row[ 5] + "usr_data.Sex," // row[ 6] + "usr_data.Photo," // row[ 7] + "usr_data.PhotoVisibility," // row[ 8] + "usr_data.CtyCod," // row[ 9] + "usr_data.InsCod" // row[10] + " FROM courses,crs_usr,usr_data" " WHERE courses.DegCod=%ld" " AND courses.CrsCod=crs_usr.CrsCod" " AND crs_usr.Role=%u" " AND crs_usr.UsrCod=usr_data.UsrCod", - QueryFields, DegCod,(unsigned) Rol_STD); - /***** Get list of students from database *****/ - Usr_GetListUsrsFromQuery (Query,Rol_STD,Hie_DEG); - } + /***** Get list of students from database *****/ + Usr_GetListUsrsFromQuery (Query,Rol_STD,Hie_DEG); } /*****************************************************************************/ diff --git a/swad_user.h b/swad_user.h index f188dab9..c40780ae 100644 --- a/swad_user.h +++ b/swad_user.h @@ -413,6 +413,7 @@ void Usr_FlushCacheNumUsrsInCrssOfDeg (void); unsigned Usr_GetNumUsrsInCrssOfDeg (Rol_Role_t Role,long DegCod); void Usr_FlushCacheNumUsrsInCrssOfCtr (void); unsigned Usr_GetNumUsrsInCrssOfCtr (Rol_Role_t Role,long CtrCod); +void Usr_FlushCacheNumUsrsInCrssOfIns (void); unsigned Usr_GetNumUsrsInCrssOfIns (Rol_Role_t Role,long InsCod); unsigned Usr_GetNumUsrsInCrssOfCty (Rol_Role_t Role,long CtyCod);