From f99d0b0faad69c28a8698ff2dbbd1090fbdda599 Mon Sep 17 00:00:00 2001 From: acanas Date: Wed, 3 Nov 2021 23:37:01 +0100 Subject: [PATCH] Version 21.50.1: Nov 03, 2021 Queries moved to module swad_user_database and other modules. --- swad_QR.c | 30 ++ swad_QR.h | 1 + swad_action.c | 2 +- swad_center.c | 65 +++- swad_center.h | 4 + swad_center_config.c | 2 +- swad_center_database.c | 13 + swad_center_database.h | 1 + swad_changelog.h | 3 +- swad_country.c | 148 +++++++- swad_country.h | 12 + swad_country_config.c | 2 +- swad_country_database.c | 102 ++++-- swad_country_database.h | 7 +- swad_course.c | 20 +- swad_degree.c | 4 +- swad_enrolment.c | 166 ++++++++- swad_enrolment.h | 6 + swad_enrolment_database.c | 231 +++++++++++- swad_enrolment_database.h | 3 + swad_figure.c | 8 +- swad_global.c | 10 +- swad_help.c | 2 +- swad_hierarchy_config.c | 2 +- swad_indicator.c | 4 +- swad_institution.c | 66 +++- swad_institution.h | 4 + swad_institution_config.c | 2 +- swad_institution_database.c | 14 + swad_institution_database.h | 1 + swad_mark.c | 2 +- swad_notification.c | 2 +- swad_report.c | 4 +- swad_user.c | 700 +----------------------------------- swad_user.h | 29 -- swad_user_database.c | 38 ++ swad_user_database.h | 5 + 37 files changed, 896 insertions(+), 819 deletions(-) diff --git a/swad_QR.c b/swad_QR.c index 9c2923bb..ade87638 100644 --- a/swad_QR.c +++ b/swad_QR.c @@ -106,6 +106,36 @@ void QR_PrintQRCode (void) QR_ImageQRCode (QRString); } +/*****************************************************************************/ +/**************************** Show a user QR code ****************************/ +/*****************************************************************************/ + +void QR_PrintUsrQRCode (void) + { + char NewNickWithArr[Nck_MAX_BYTES_NICK_WITH_ARROBA + 1]; + + if (Usr_GetParamOtherUsrCodEncryptedAndGetUsrData ()) + { + /***** Begin box *****/ + Box_BoxBegin (NULL,Gbl.Usrs.Other.UsrDat.FullName, + NULL,NULL, + NULL,Box_NOT_CLOSABLE); + + /***** Show QR code *****/ + if (Gbl.Usrs.Other.UsrDat.Nickname[0]) + { + snprintf (NewNickWithArr,sizeof (NewNickWithArr),"@%s", + Gbl.Usrs.Other.UsrDat.Nickname); + QR_ImageQRCode (NewNickWithArr); + } + + /***** End box *****/ + Box_BoxEnd (); + } + else + Ale_ShowAlertUserNotFoundOrYouDoNotHavePermission (); + } + /*****************************************************************************/ /******************** Write an QR (image) based on a string ******************/ /*****************************************************************************/ diff --git a/swad_QR.h b/swad_QR.h index d0318dd2..8a148394 100644 --- a/swad_QR.h +++ b/swad_QR.h @@ -44,6 +44,7 @@ void QR_PutLinkToPrintQRCode (Act_Action_t Action, void QR_PutParamQRString (void *QRString); void QR_PrintQRCode (void); +void QR_PrintUsrQRCode (void); void QR_ImageQRCode (const char *QRString); void QR_LinkTo (unsigned Size,const char *ParamName,long Cod); diff --git a/swad_action.c b/swad_action.c index 22acf136..c37f3d4b 100644 --- a/swad_action.c +++ b/swad_action.c @@ -1814,7 +1814,7 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = [ActChgCooPrf ] = {1764,-1,TabUnk,ActReqEdiSet ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Coo_ChangeMyPrefsCookies ,NULL}, [ActChgNtfPrf ] = { 775,-1,TabUnk,ActReqEdiSet ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_NORM,Act_BRW_1ST_TAB,Ntf_ChangeNotifyEvents ,Set_EditSettings ,NULL}, - [ActPrnUsrQR ] = {1022,-1,TabUnk,ActFrmMyAcc ,0x3F8,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,Act_CONT_NORM,Act_BRW_NEW_TAB,NULL ,Usr_PrintUsrQRCode ,NULL}, + [ActPrnUsrQR ] = {1022,-1,TabUnk,ActFrmMyAcc ,0x3F8,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,Act_CONT_NORM,Act_BRW_NEW_TAB,NULL ,QR_PrintUsrQRCode ,NULL}, [ActPrnMyTT ] = { 409,-1,TabUnk,ActSeeMyTT ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_NORM,Act_BRW_NEW_TAB,NULL ,Tmt_ShowClassTimeTable ,NULL}, [ActEdiTut ] = { 65,-1,TabUnk,ActSeeMyTT ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Tmt_EditMyTutTimeTable ,NULL}, diff --git a/swad_center.c b/swad_center.c index 0aac4ee0..73f21373 100644 --- a/swad_center.c +++ b/swad_center.c @@ -376,7 +376,7 @@ static void Ctr_ListOneCenterForSeeing (struct Ctr_Center *Ctr,unsigned NumCtr) /***** Number of users who claim to belong to this center *****/ HTM_TD_Begin ("class=\"%s RM %s\"",TxtClassNormal,BgColor); - HTM_Unsigned (Usr_GetCachedNumUsrsWhoClaimToBelongToCtr (Ctr)); + HTM_Unsigned (Ctr_GetCachedNumUsrsWhoClaimToBelongToCtr (Ctr)); HTM_TD_End (); /***** Place *****/ @@ -396,7 +396,7 @@ static void Ctr_ListOneCenterForSeeing (struct Ctr_Center *Ctr,unsigned NumCtr) /***** Number of users in courses of this center *****/ HTM_TD_Begin ("class=\"%s RM %s\"",TxtClassNormal,BgColor); - HTM_Unsigned (Usr_GetCachedNumUsrsInCrss (HieLvl_CTR,Ctr->CtrCod, + HTM_Unsigned (Enr_GetCachedNumUsrsInCrss (HieLvl_CTR,Ctr->CtrCod, 1 << Rol_STD | 1 << Rol_NET | 1 << Rol_TCH)); // Any user @@ -789,8 +789,8 @@ static void Ctr_ListCentersForEdition (const struct Plc_Places *Places) ICanEdit = Ctr_CheckIfICanEditACenter (Ctr); NumDegs = Deg_GetNumDegsInCtr (Ctr->CtrCod); - NumUsrsCtr = Usr_GetNumUsrsWhoClaimToBelongToCtr (Ctr); - NumUsrsInCrssOfCtr = Usr_GetNumUsrsInCrss (HieLvl_CTR,Ctr->CtrCod, + NumUsrsCtr = Ctr_GetNumUsrsWhoClaimToBelongToCtr (Ctr); + NumUsrsInCrssOfCtr = Enr_GetNumUsrsInCrss (HieLvl_CTR,Ctr->CtrCod, 1 << Rol_STD | 1 << Rol_NET | 1 << Rol_TCH); // Any user @@ -1069,10 +1069,10 @@ void Ctr_RemoveCenter (void) if (Deg_GetNumDegsInCtr (Ctr_EditingCtr->CtrCod)) // Center has degrees Ale_ShowAlert (Ale_WARNING, Txt_To_remove_a_center_you_must_first_remove_all_degrees_and_teachers_in_the_center); - else if (Usr_GetNumUsrsWhoClaimToBelongToCtr (Ctr_EditingCtr)) // Center has users who claim to belong to it + else if (Ctr_GetNumUsrsWhoClaimToBelongToCtr (Ctr_EditingCtr)) // Center has users who claim to belong to it Ale_ShowAlert (Ale_WARNING, Txt_To_remove_a_center_you_must_first_remove_all_degrees_and_teachers_in_the_center); - else if (Usr_GetNumUsrsInCrss (HieLvl_CTR,Ctr_EditingCtr->CtrCod, + else if (Enr_GetNumUsrsInCrss (HieLvl_CTR,Ctr_EditingCtr->CtrCod, 1 << Rol_STD | 1 << Rol_NET | 1 << Rol_TCH)) // Center has users @@ -1108,7 +1108,7 @@ void Ctr_RemoveCenter (void) /***** Flush caches *****/ Deg_FlushCacheNumDegsInCtr (); Crs_FlushCacheNumCrssInCtr (); - Usr_FlushCacheNumUsrsWhoClaimToBelongToCtr (); + Ctr_FlushCacheNumUsrsWhoClaimToBelongToCtr (); /***** Write message to show the change made *****/ Ale_CreateAlert (Ale_SUCCESS,NULL, @@ -2127,3 +2127,54 @@ bool Ctr_CheckIfUsrBelongsToCtr (long UsrCod,long CtrCod) Gbl.Cache.UsrBelongsToCtr.Belongs = Ctr_DB_CheckIfUsrBelongsToCtr (UsrCod,CtrCod); return Gbl.Cache.UsrBelongsToCtr.Belongs; } + +/*****************************************************************************/ +/*********** Get number of users who claim to belong to a center *************/ +/*****************************************************************************/ + +void Ctr_FlushCacheNumUsrsWhoClaimToBelongToCtr (void) + { + Gbl.Cache.NumUsrsWhoClaimToBelongToCtr.CtrCod = -1L; + Gbl.Cache.NumUsrsWhoClaimToBelongToCtr.NumUsrs = 0; + } + +unsigned Ctr_GetNumUsrsWhoClaimToBelongToCtr (struct Ctr_Center *Ctr) + { + /***** 1. Fast check: Trivial case *****/ + if (Ctr->CtrCod <= 0) + return 0; + + /***** 2. Fast check: If already got... *****/ + if (Ctr->NumUsrsWhoClaimToBelongToCtr.Valid) + return Ctr->NumUsrsWhoClaimToBelongToCtr.NumUsrs; + + /***** 3. Fast check: If cached... *****/ + if (Ctr->CtrCod == Gbl.Cache.NumUsrsWhoClaimToBelongToCtr.CtrCod) + { + Ctr->NumUsrsWhoClaimToBelongToCtr.NumUsrs = Gbl.Cache.NumUsrsWhoClaimToBelongToCtr.NumUsrs; + Ctr->NumUsrsWhoClaimToBelongToCtr.Valid = true; + return Ctr->NumUsrsWhoClaimToBelongToCtr.NumUsrs; + } + + /***** 4. Slow: number of users who claim to belong to a center + from database *****/ + Gbl.Cache.NumUsrsWhoClaimToBelongToCtr.CtrCod = Ctr->CtrCod; + Gbl.Cache.NumUsrsWhoClaimToBelongToCtr.NumUsrs = + Ctr->NumUsrsWhoClaimToBelongToCtr.NumUsrs = Ctr_DB_GetNumUsrsWhoClaimToBelongToCtr (Ctr->CtrCod); + FigCch_UpdateFigureIntoCache (FigCch_NUM_USRS_BELONG_CTR,HieLvl_CTR,Gbl.Cache.NumUsrsWhoClaimToBelongToCtr.CtrCod, + FigCch_UNSIGNED,&Gbl.Cache.NumUsrsWhoClaimToBelongToCtr.NumUsrs); + return Ctr->NumUsrsWhoClaimToBelongToCtr.NumUsrs; + } + +unsigned Ctr_GetCachedNumUsrsWhoClaimToBelongToCtr (struct Ctr_Center *Ctr) + { + unsigned NumUsrsCtr; + + /***** Get number of users who claim to belong to center from cache *****/ + if (!FigCch_GetFigureFromCache (FigCch_NUM_USRS_BELONG_CTR,HieLvl_CTR,Ctr->CtrCod, + FigCch_UNSIGNED,&NumUsrsCtr)) + /***** Get current number of users who claim to belong to center from database and update cache *****/ + NumUsrsCtr = Ctr_GetNumUsrsWhoClaimToBelongToCtr (Ctr); + + return NumUsrsCtr; + } diff --git a/swad_center.h b/swad_center.h index fd398ae8..f79b0575 100644 --- a/swad_center.h +++ b/swad_center.h @@ -153,4 +153,8 @@ bool Ctr_CheckIfIBelongToCtr (long CtrCod); void Ctr_FlushCacheUsrBelongsToCtr (void); bool Ctr_CheckIfUsrBelongsToCtr (long UsrCod,long CtrCod); +void Ctr_FlushCacheNumUsrsWhoClaimToBelongToCtr (void); +unsigned Ctr_GetNumUsrsWhoClaimToBelongToCtr (struct Ctr_Center *Ctr); +unsigned Ctr_GetCachedNumUsrsWhoClaimToBelongToCtr (struct Ctr_Center *Ctr); + #endif diff --git a/swad_center_config.c b/swad_center_config.c index f70e5069..e13634b9 100644 --- a/swad_center_config.c +++ b/swad_center_config.c @@ -741,7 +741,7 @@ static void CtrCfg_NumUsrs (void) /* Data */ HTM_TD_Begin ("class=\"DAT LB\""); - HTM_Unsigned (Usr_GetCachedNumUsrsWhoClaimToBelongToCtr (&Gbl.Hierarchy.Ctr)); + HTM_Unsigned (Ctr_GetCachedNumUsrsWhoClaimToBelongToCtr (&Gbl.Hierarchy.Ctr)); HTM_TD_End (); HTM_TR_End (); diff --git a/swad_center_database.c b/swad_center_database.c index ca9869fb..42fded1d 100644 --- a/swad_center_database.c +++ b/swad_center_database.c @@ -793,6 +793,19 @@ bool Ctr_DB_CheckIfUsrBelongsToCtr (long UsrCod,long CtrCod) UsrCod, CtrCod) != 0); } +/*****************************************************************************/ +/*********** Get number of users who claim to belong to a center *************/ +/*****************************************************************************/ + +unsigned Ctr_DB_GetNumUsrsWhoClaimToBelongToCtr (long CtrCod) + { + return (unsigned) + DB_QueryCOUNT ("can not get number of users", + "SELECT COUNT(UsrCod)" + " FROM usr_data" + " WHERE CtrCod=%ld", + CtrCod); + } /*****************************************************************************/ /****************************** Remove a center ******************************/ diff --git a/swad_center_database.h b/swad_center_database.h index a866378f..63ef5861 100644 --- a/swad_center_database.h +++ b/swad_center_database.h @@ -89,6 +89,7 @@ unsigned Ctr_DB_GetCtrsWithCoordsInCurrentIns (MYSQL_RES **mysql_res); unsigned Ctr_DB_GetCtrsFromUsr (MYSQL_RES **mysql_res,long UsrCod,long InsCod); bool Ctr_DB_CheckIfUsrBelongsToCtr (long UsrCod,long CtrCod); +unsigned Ctr_DB_GetNumUsrsWhoClaimToBelongToCtr (long CtrCod); void Ctr_DB_RemoveCenter (long CtrCod); diff --git a/swad_changelog.h b/swad_changelog.h index 8d7f67dc..200439d2 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 21.50 (2021-11-03)" +#define Log_PLATFORM_VERSION "SWAD 21.50.1 (2021-11-03)" #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 21.50.1: Nov 03, 2021 Queries moved to module swad_user_database and other modules. (321759 lines) Version 21.50: Nov 03, 2021 Queries moved to module swad_user_database and other modules. (321696 lines) Version 21.49: Nov 03, 2021 New module swad_user_database for database queries related to users. (321615 lines) Version 21.48: Nov 03, 2021 New module swad_timetable_database for database queries related to timetables. (321438 lines) diff --git a/swad_country.c b/swad_country.c index dcb09b2b..b4e420f5 100644 --- a/swad_country.c +++ b/swad_country.c @@ -253,7 +253,7 @@ void Cty_ListCountries2 (void) /* Number of users who claim to belong to another country */ HTM_TD_Begin ("class=\"DAT RM\""); - HTM_Unsigned (Usr_GetCachedNumUsrsWhoClaimToBelongToAnotherCty ()); + HTM_Unsigned (Cty_GetCachedNumUsrsWhoClaimToBelongToAnotherCty ()); HTM_TD_End (); /* Number of institutions in other countries */ @@ -278,7 +278,7 @@ void Cty_ListCountries2 (void) /* Number of users in courses of other countries */ HTM_TD_Begin ("class=\"DAT RM\""); - HTM_Unsigned (Usr_GetCachedNumUsrsInCrss (HieLvl_CTY,0, + HTM_Unsigned (Enr_GetCachedNumUsrsInCrss (HieLvl_CTY,0, 1 << Rol_STD | 1 << Rol_NET | 1 << Rol_TCH)); // Any user @@ -298,7 +298,7 @@ void Cty_ListCountries2 (void) /* Number of users who do not claim to belong to any country */ HTM_TD_Begin ("class=\"DAT RM\""); - HTM_Unsigned (Usr_GetCachedNumUsrsWhoDontClaimToBelongToAnyCty ()); + HTM_Unsigned (Cty_GetCachedNumUsrsWhoDontClaimToBelongToAnyCty ()); HTM_TD_End (); /* Number of institutions with unknown country */ @@ -425,7 +425,7 @@ static void Cty_ListOneCountryForSeeing (struct Cty_Countr *Cty,unsigned NumCty) /***** Number of users who claim to belong to this country *****/ HTM_TD_Begin ("class=\"DAT RM %s\"",BgColor); - HTM_Unsigned (Usr_GetCachedNumUsrsWhoClaimToBelongToCty (Cty)); + HTM_Unsigned (Cty_GetCachedNumUsrsWhoClaimToBelongToCty (Cty)); HTM_TD_End (); /***** Number of institutions *****/ @@ -450,7 +450,7 @@ static void Cty_ListOneCountryForSeeing (struct Cty_Countr *Cty,unsigned NumCty) /***** Number of users in courses *****/ HTM_TD_Begin ("class=\"DAT RM %s\"",BgColor); - HTM_Unsigned (Usr_GetCachedNumUsrsInCrss (HieLvl_CTY,Cty->CtyCod, + HTM_Unsigned (Enr_GetCachedNumUsrsInCrss (HieLvl_CTY,Cty->CtyCod, 1 << Rol_STD | 1 << Rol_NET | 1 << Rol_TCH)); // Any user @@ -615,7 +615,7 @@ void Cty_WriteScriptGoogleGeochart (void) NumCty < Gbl.Hierarchy.Ctys.Num; NumCty++) { - NumUsrsCty = Usr_GetCachedNumUsrsWhoClaimToBelongToCty (&Gbl.Hierarchy.Ctys.Lst[NumCty]); + NumUsrsCty = Cty_GetCachedNumUsrsWhoClaimToBelongToCty (&Gbl.Hierarchy.Ctys.Lst[NumCty]); if (NumUsrsCty) { NumInss = Ins_GetCachedNumInssInCty (Gbl.Hierarchy.Ctys.Lst[NumCty].CtyCod); @@ -1068,7 +1068,7 @@ static void Cty_ListCountriesForEdition (void) { Cty = &Gbl.Hierarchy.Ctys.Lst[NumCty]; NumInss = Ins_GetNumInssInCty (Cty->CtyCod); - NumUsrsCty = Usr_GetNumUsrsWhoClaimToBelongToCty (Cty); + NumUsrsCty = Cty_GetNumUsrsWhoClaimToBelongToCty (Cty); HTM_TR_Begin (NULL); @@ -1078,7 +1078,7 @@ static void Cty_ListCountriesForEdition (void) NumUsrsCty) // Country has users // Deletion forbidden Ico_PutIconRemovalNotAllowed (); - else if (Usr_GetNumUsrsInCrss (HieLvl_CTY,Cty->CtyCod, + else if (Enr_GetNumUsrsInCrss (HieLvl_CTY,Cty->CtyCod, 1 << Rol_STD | 1 << Rol_NET | 1 << Rol_TCH)) // Country has users @@ -1216,10 +1216,10 @@ void Cty_RemoveCountry (void) if (Ins_GetNumInssInCty (Cty_EditingCty->CtyCod)) // Country has institutions ==> don't remove Ale_CreateAlert (Ale_WARNING,NULL, Txt_You_can_not_remove_a_country_with_institutions_or_users); - else if (Usr_GetNumUsrsWhoClaimToBelongToCty (Cty_EditingCty)) // Country has users ==> don't remove + else if (Cty_GetNumUsrsWhoClaimToBelongToCty (Cty_EditingCty)) // Country has users ==> don't remove Ale_CreateAlert (Ale_WARNING,NULL, Txt_You_can_not_remove_a_country_with_institutions_or_users); - else if (Usr_GetNumUsrsInCrss (HieLvl_CTY,Cty_EditingCty->CtyCod, + else if (Enr_GetNumUsrsInCrss (HieLvl_CTY,Cty_EditingCty->CtyCod, 1 << Rol_STD | 1 << Rol_NET | 1 << Rol_TCH)) // Country has users @@ -1239,7 +1239,7 @@ void Cty_RemoveCountry (void) Ctr_FlushCacheNumCtrsInCty (); Deg_FlushCacheNumDegsInCty (); Crs_FlushCacheNumCrssInCty (); - Usr_FlushCacheNumUsrsWhoClaimToBelongToCty (); + Cty_FlushCacheNumUsrsWhoClaimToBelongToCty (); /***** Write message to show the change made *****/ Ale_CreateAlert (Ale_SUCCESS,NULL, @@ -1969,3 +1969,129 @@ bool Cty_CheckIfIBelongToCty (long CtyCod) return true; return false; } + +/*****************************************************************************/ +/******* Get number of users who don't claim to belong to any country ********/ +/*****************************************************************************/ + +void Cty_FlushCacheNumUsrsWhoDontClaimToBelongToAnyCty (void) + { + Gbl.Cache.NumUsrsWhoDontClaimToBelongToAnyCty.Valid = false; + } + +unsigned Cty_GetNumUsrsWhoDontClaimToBelongToAnyCty (void) + { + /***** 1. Fast check: If cached... *****/ + if (Gbl.Cache.NumUsrsWhoDontClaimToBelongToAnyCty.Valid) + return Gbl.Cache.NumUsrsWhoDontClaimToBelongToAnyCty.NumUsrs; + + /***** 2. Slow: number of users who don't claim to belong to any country + from database *****/ + Gbl.Cache.NumUsrsWhoDontClaimToBelongToAnyCty.NumUsrs = Cty_DB_GetNumUsrsWhoDontClaimToBelongToAnyCty (); + Gbl.Cache.NumUsrsWhoDontClaimToBelongToAnyCty.Valid = true; + FigCch_UpdateFigureIntoCache (FigCch_NUM_USRS_BELONG_CTY,HieLvl_CTY,-1L, + FigCch_UNSIGNED,&Gbl.Cache.NumUsrsWhoDontClaimToBelongToAnyCty.NumUsrs); + return Gbl.Cache.NumUsrsWhoDontClaimToBelongToAnyCty.NumUsrs; + } + +unsigned Cty_GetCachedNumUsrsWhoDontClaimToBelongToAnyCty (void) + { + unsigned NumUsrs; + + /***** Get number of user who don't claim to belong to any country from cache *****/ + if (!FigCch_GetFigureFromCache (FigCch_NUM_USRS_BELONG_CTY,HieLvl_CTY,-1L, + FigCch_UNSIGNED,&NumUsrs)) + /***** Get current number of user who don't claim to belong to any country from database and update cache *****/ + NumUsrs = Cty_GetNumUsrsWhoDontClaimToBelongToAnyCty (); + + return NumUsrs; + } + +/*****************************************************************************/ +/******** Get number of users who claim to belong to another country *********/ +/*****************************************************************************/ + +void Cty_FlushCacheNumUsrsWhoClaimToBelongToAnotherCty (void) + { + Gbl.Cache.NumUsrsWhoClaimToBelongToAnotherCty.Valid = false; + } + +unsigned Cty_GetNumUsrsWhoClaimToBelongToAnotherCty (void) + { + /***** 1. Fast check: If cached... *****/ + if (Gbl.Cache.NumUsrsWhoClaimToBelongToAnotherCty.Valid) + return Gbl.Cache.NumUsrsWhoClaimToBelongToAnotherCty.NumUsrs; + + /***** 2. Slow: number of users who claim to belong to another country + from database *****/ + Gbl.Cache.NumUsrsWhoClaimToBelongToAnotherCty.NumUsrs = Cty_DB_GetNumUsrsWhoClaimToBelongToAnotherCty (); + Gbl.Cache.NumUsrsWhoClaimToBelongToAnotherCty.Valid = true; + FigCch_UpdateFigureIntoCache (FigCch_NUM_USRS_BELONG_CTY,HieLvl_CTY,0, + FigCch_UNSIGNED,&Gbl.Cache.NumUsrsWhoClaimToBelongToAnotherCty.NumUsrs); + return Gbl.Cache.NumUsrsWhoClaimToBelongToAnotherCty.NumUsrs; + } + +unsigned Cty_GetCachedNumUsrsWhoClaimToBelongToAnotherCty (void) + { + unsigned NumUsrsCty; + + /***** Get number of users who claim to belong to another country form cache *****/ + if (!FigCch_GetFigureFromCache (FigCch_NUM_USRS_BELONG_CTY,HieLvl_CTY,0, + FigCch_UNSIGNED,&NumUsrsCty)) + /***** Get current number of users who claim to belong to another country from database and update cache *****/ + NumUsrsCty = Cty_GetNumUsrsWhoClaimToBelongToAnotherCty (); + + return NumUsrsCty; + } + +/*****************************************************************************/ +/*********** Get number of users who claim to belong to a country ************/ +/*****************************************************************************/ + +void Cty_FlushCacheNumUsrsWhoClaimToBelongToCty (void) + { + Gbl.Cache.NumUsrsWhoClaimToBelongToCty.CtyCod = -1L; + Gbl.Cache.NumUsrsWhoClaimToBelongToCty.NumUsrs = 0; + } + +unsigned Cty_GetNumUsrsWhoClaimToBelongToCty (struct Cty_Countr *Cty) + { + /***** 1. Fast check: Trivial case *****/ + if (Cty->CtyCod <= 0) + return 0; + + /***** 2. Fast check: If already got... *****/ + if (Cty->NumUsrsWhoClaimToBelongToCty.Valid) + return Cty->NumUsrsWhoClaimToBelongToCty.NumUsrs; + + /***** 3. Fast check: If cached... *****/ + if (Cty->CtyCod == Gbl.Cache.NumUsrsWhoClaimToBelongToCty.CtyCod) + { + Cty->NumUsrsWhoClaimToBelongToCty.NumUsrs = Gbl.Cache.NumUsrsWhoClaimToBelongToCty.NumUsrs; + Cty->NumUsrsWhoClaimToBelongToCty.Valid = true; + return Cty->NumUsrsWhoClaimToBelongToCty.NumUsrs; + } + + /***** 4. Slow: number of users who claim to belong to an institution + from database *****/ + Gbl.Cache.NumUsrsWhoClaimToBelongToCty.CtyCod = Cty->CtyCod; + Gbl.Cache.NumUsrsWhoClaimToBelongToCty.NumUsrs = + Cty->NumUsrsWhoClaimToBelongToCty.NumUsrs = Cty_DB_GetNumUsrsWhoClaimToBelongToCty (Cty->CtyCod); + Cty->NumUsrsWhoClaimToBelongToCty.Valid = true; + FigCch_UpdateFigureIntoCache (FigCch_NUM_USRS_BELONG_CTY,HieLvl_CTY,Gbl.Cache.NumUsrsWhoClaimToBelongToCty.CtyCod, + FigCch_UNSIGNED,&Gbl.Cache.NumUsrsWhoClaimToBelongToCty.NumUsrs); + return Cty->NumUsrsWhoClaimToBelongToCty.NumUsrs; + } + +unsigned Cty_GetCachedNumUsrsWhoClaimToBelongToCty (struct Cty_Countr *Cty) + { + unsigned NumUsrsCty; + + /***** Get number of users who claim to belong to country from cache ******/ + if (!FigCch_GetFigureFromCache (FigCch_NUM_USRS_BELONG_CTY,HieLvl_CTY,Cty->CtyCod, + FigCch_UNSIGNED,&NumUsrsCty)) + /***** Get current number of users who claim to belong to country from database and update cache ******/ + NumUsrsCty = Cty_GetNumUsrsWhoClaimToBelongToCty (Cty); + + return NumUsrsCty; + } diff --git a/swad_country.h b/swad_country.h index cbcfea81..71720a4e 100644 --- a/swad_country.h +++ b/swad_country.h @@ -127,4 +127,16 @@ void Cty_GetMyCountrs (void); void Cty_FreeMyCountrs (void); bool Cty_CheckIfIBelongToCty (long CtyCod); +void Cty_FlushCacheNumUsrsWhoDontClaimToBelongToAnyCty (void); +unsigned Cty_GetNumUsrsWhoDontClaimToBelongToAnyCty (void); +unsigned Cty_GetCachedNumUsrsWhoDontClaimToBelongToAnyCty (void); + +void Cty_FlushCacheNumUsrsWhoClaimToBelongToAnotherCty (void); +unsigned Cty_GetNumUsrsWhoClaimToBelongToAnotherCty (void); +unsigned Cty_GetCachedNumUsrsWhoClaimToBelongToAnotherCty (void); + +void Cty_FlushCacheNumUsrsWhoClaimToBelongToCty (void); +unsigned Cty_GetNumUsrsWhoClaimToBelongToCty (struct Cty_Countr *Cty); +unsigned Cty_GetCachedNumUsrsWhoClaimToBelongToCty (struct Cty_Countr *Cty); + #endif diff --git a/swad_country_config.c b/swad_country_config.c index bd5287a9..e81a1d90 100644 --- a/swad_country_config.c +++ b/swad_country_config.c @@ -460,7 +460,7 @@ static void CtyCfg_NumUsrs (void) /* Data */ HTM_TD_Begin ("class=\"DAT LB\""); - HTM_Unsigned (Usr_GetCachedNumUsrsWhoClaimToBelongToCty (&Gbl.Hierarchy.Cty)); + HTM_Unsigned (Cty_GetCachedNumUsrsWhoClaimToBelongToCty (&Gbl.Hierarchy.Cty)); HTM_TD_End (); HTM_TR_End (); diff --git a/swad_country_database.c b/swad_country_database.c index 091bf734..b2abcee3 100644 --- a/swad_country_database.c +++ b/swad_country_database.c @@ -368,37 +368,6 @@ unsigned Cty_DB_GetNumCtysWithUsrs (Rol_Role_t Role, SubQuery,(unsigned) Role); } -/*****************************************************************************/ -/**************** Get the countries of a user from database ******************/ -/*****************************************************************************/ -// Returns the number of rows of the result - -unsigned Cty_DB_GetCtysFromUsr (MYSQL_RES **mysql_res,long UsrCod) - { - extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES]; - - return (unsigned) - DB_QuerySELECT (mysql_res,"can not get the countries a user belongs to", - "SELECT cty_countrs.CtyCod," // row[0] - "MAX(crs_users.Role)" // row[1] - " FROM crs_users," - "crs_courses," - "deg_degrees," - "ctr_centers," - "ins_instits," - "cty_countrs" - " WHERE crs_users.UsrCod=%ld" - " AND crs_users.CrsCod=crs_courses.CrsCod" - " AND crs_courses.DegCod=deg_degrees.DegCod" - " AND deg_degrees.CtrCod=ctr_centers.CtrCod" - " AND ctr_centers.InsCod=ins_instits.InsCod" - " AND ins_instits.CtyCod=cty_countrs.CtyCod" - " GROUP BY cty_countrs.CtyCod" - " ORDER BY cty_countrs.Name_%s", - UsrCod, - Lan_STR_LANG_ID[Gbl.Prefs.Language]); - } - /*****************************************************************************/ /******************* Check if a numeric country code exists ******************/ /*****************************************************************************/ @@ -593,6 +562,77 @@ void Cty_DB_UpdateCtyMapAttr (const char NewMapAttribution[Med_MAX_BYTES_ATTRIBU Gbl.Hierarchy.Cty.CtyCod); } +/*****************************************************************************/ +/**************** Get the countries of a user from database ******************/ +/*****************************************************************************/ +// Returns the number of rows of the result + +unsigned Cty_DB_GetCtysFromUsr (MYSQL_RES **mysql_res,long UsrCod) + { + extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES]; + + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get the countries a user belongs to", + "SELECT cty_countrs.CtyCod," // row[0] + "MAX(crs_users.Role)" // row[1] + " FROM crs_users," + "crs_courses," + "deg_degrees," + "ctr_centers," + "ins_instits," + "cty_countrs" + " WHERE crs_users.UsrCod=%ld" + " AND crs_users.CrsCod=crs_courses.CrsCod" + " AND crs_courses.DegCod=deg_degrees.DegCod" + " AND deg_degrees.CtrCod=ctr_centers.CtrCod" + " AND ctr_centers.InsCod=ins_instits.InsCod" + " AND ins_instits.CtyCod=cty_countrs.CtyCod" + " GROUP BY cty_countrs.CtyCod" + " ORDER BY cty_countrs.Name_%s", + UsrCod, + Lan_STR_LANG_ID[Gbl.Prefs.Language]); + } + +/*****************************************************************************/ +/******* Get number of users who don't claim to belong to any country ********/ +/*****************************************************************************/ + +unsigned Cty_DB_GetNumUsrsWhoDontClaimToBelongToAnyCty (void) + { + return (unsigned) + DB_QueryCOUNT ("can not get number of users", + "SELECT COUNT(UsrCod)" + " FROM usr_data" + " WHERE CtyCod<0"); + } + +/*****************************************************************************/ +/******** Get number of users who claim to belong to another country *********/ +/*****************************************************************************/ + +unsigned Cty_DB_GetNumUsrsWhoClaimToBelongToAnotherCty (void) + { + return (unsigned) + DB_QueryCOUNT ("can not get number of users", + "SELECT COUNT(UsrCod)" + " FROM usr_data" + " WHERE CtyCod=0"); + } + +/*****************************************************************************/ +/*********** Get number of users who claim to belong to a country ************/ +/*****************************************************************************/ + +unsigned Cty_DB_GetNumUsrsWhoClaimToBelongToCty (long CtyCod) + { + return (unsigned) + DB_QueryCOUNT ("can not get number of users", + "SELECT COUNT(UsrCod)" + " FROM usr_data" + " WHERE CtyCod=%ld", + CtyCod); + } + /*****************************************************************************/ /******************************* Remove a country ****************************/ /*****************************************************************************/ diff --git a/swad_country_database.h b/swad_country_database.h index 9940bacb..0f271211 100644 --- a/swad_country_database.h +++ b/swad_country_database.h @@ -58,8 +58,6 @@ unsigned Cty_DB_GetNumCtysWithCrss (void); unsigned Cty_DB_GetNumCtysWithUsrs (Rol_Role_t Role, HieLvl_Level_t Scope,long Cod); -unsigned Cty_DB_GetCtysFromUsr (MYSQL_RES **mysql_res,long UsrCod); - bool Cty_DB_CheckIfNumericCountryCodeExists (long CtyCod); bool Cty_DB_CheckIfAlpha2CountryCodeExists (const char Alpha2[2 + 1]); bool Cty_DB_CheckIfCountryNameExists (Lan_Language_t Language,const char *Name,long CtyCod); @@ -76,6 +74,11 @@ bool Cty_DB_GetIfMapIsAvailable (long CtyCod); void Cty_DB_UpdateCtyField (long CtyCod,const char *FieldName,const char *FieldValue); void Cty_DB_UpdateCtyMapAttr (const char NewMapAttribution[Med_MAX_BYTES_ATTRIBUTION + 1]); +unsigned Cty_DB_GetCtysFromUsr (MYSQL_RES **mysql_res,long UsrCod); +unsigned Cty_DB_GetNumUsrsWhoDontClaimToBelongToAnyCty (void); +unsigned Cty_DB_GetNumUsrsWhoClaimToBelongToAnotherCty (void); +unsigned Cty_DB_GetNumUsrsWhoClaimToBelongToCty (long CtyCod); + void Cty_DB_RemoveCty (long CtyCod); #endif diff --git a/swad_course.c b/swad_course.c index d31ee611..809aadcf 100644 --- a/swad_course.c +++ b/swad_course.c @@ -983,9 +983,9 @@ static bool Crs_ListCoursesOfAYearForSeeing (unsigned Year) HTM_TR_Begin (NULL); /* Get number of users */ - NumUsrs[Rol_STD] = Usr_GetCachedNumUsrsInCrss (HieLvl_CRS,Crs->CrsCod,1 << Rol_STD); - NumUsrs[Rol_NET] = Usr_GetCachedNumUsrsInCrss (HieLvl_CRS,Crs->CrsCod,1 << Rol_NET); - NumUsrs[Rol_TCH] = Usr_GetCachedNumUsrsInCrss (HieLvl_CRS,Crs->CrsCod,1 << Rol_TCH); + NumUsrs[Rol_STD] = Enr_GetCachedNumUsrsInCrss (HieLvl_CRS,Crs->CrsCod,1 << Rol_STD); + NumUsrs[Rol_NET] = Enr_GetCachedNumUsrsInCrss (HieLvl_CRS,Crs->CrsCod,1 << Rol_NET); + NumUsrs[Rol_TCH] = Enr_GetCachedNumUsrsInCrss (HieLvl_CRS,Crs->CrsCod,1 << Rol_TCH); NumUsrs[Rol_UNK] = NumUsrs[Rol_STD] + NumUsrs[Rol_NET] + NumUsrs[Rol_TCH]; @@ -1183,9 +1183,9 @@ static void Crs_ListCoursesOfAYearForEdition (unsigned Year) ICanEdit = Crs_CheckIfICanEdit (Crs); /* Get number of users */ - NumUsrs[Rol_STD] = Usr_GetNumUsrsInCrss (HieLvl_CRS,Crs->CrsCod,1 << Rol_STD); - NumUsrs[Rol_NET] = Usr_GetNumUsrsInCrss (HieLvl_CRS,Crs->CrsCod,1 << Rol_NET); - NumUsrs[Rol_TCH] = Usr_GetNumUsrsInCrss (HieLvl_CRS,Crs->CrsCod,1 << Rol_TCH); + NumUsrs[Rol_STD] = Enr_GetNumUsrsInCrss (HieLvl_CRS,Crs->CrsCod,1 << Rol_STD); + NumUsrs[Rol_NET] = Enr_GetNumUsrsInCrss (HieLvl_CRS,Crs->CrsCod,1 << Rol_NET); + NumUsrs[Rol_TCH] = Enr_GetNumUsrsInCrss (HieLvl_CRS,Crs->CrsCod,1 << Rol_TCH); NumUsrs[Rol_UNK] = NumUsrs[Rol_STD] + NumUsrs[Rol_NET] + NumUsrs[Rol_TCH]; @@ -1664,7 +1664,7 @@ void Crs_RemoveCourse (void) if (Crs_CheckIfICanEdit (Crs_EditingCrs)) { /***** Check if this course has users *****/ - if (Usr_GetNumUsrsInCrss (HieLvl_CRS,Crs_EditingCrs->CrsCod, + if (Enr_GetNumUsrsInCrss (HieLvl_CRS,Crs_EditingCrs->CrsCod, 1 << Rol_STD | 1 << Rol_NET | 1 << Rol_TCH)) // Course has users ==> don't remove @@ -2543,9 +2543,9 @@ static void Crs_WriteRowCrsData (unsigned NumCrs,MYSQL_ROW row,bool WriteColumnA Err_WrongCourseExit (); /***** Get number of teachers and students in this course *****/ - NumStds = Usr_GetNumUsrsInCrss (HieLvl_CRS,CrsCod,1 << Rol_STD); - NumNETs = Usr_GetNumUsrsInCrss (HieLvl_CRS,CrsCod,1 << Rol_NET); - NumTchs = Usr_GetNumUsrsInCrss (HieLvl_CRS,CrsCod,1 << Rol_TCH); + NumStds = Enr_GetNumUsrsInCrss (HieLvl_CRS,CrsCod,1 << Rol_STD); + NumNETs = Enr_GetNumUsrsInCrss (HieLvl_CRS,CrsCod,1 << Rol_NET); + NumTchs = Enr_GetNumUsrsInCrss (HieLvl_CRS,CrsCod,1 << Rol_TCH); NumUsrs = NumStds + NumNETs + NumTchs; if (NumUsrs) { diff --git a/swad_degree.c b/swad_degree.c index 41e9e40b..d28a325e 100644 --- a/swad_degree.c +++ b/swad_degree.c @@ -338,7 +338,7 @@ static void Deg_ListDegreesForEdition (void) ICanEdit = Deg_CheckIfICanEditADegree (Deg); NumCrss = Crs_GetNumCrssInDeg (Deg->DegCod); - NumUsrsInCrssOfDeg = Usr_GetNumUsrsInCrss (HieLvl_DEG,Deg->DegCod, + NumUsrsInCrssOfDeg = Enr_GetNumUsrsInCrss (HieLvl_DEG,Deg->DegCod, 1 << Rol_STD | 1 << Rol_NET | 1 << Rol_TCH); // Any user @@ -896,7 +896,7 @@ static void Deg_ListOneDegreeForSeeing (struct Deg_Degree *Deg,unsigned NumDeg) /***** Number of users in courses of this degree *****/ HTM_TD_Begin ("class=\"%s RM %s\"",TxtClassNormal,BgColor); - HTM_Unsigned (Usr_GetCachedNumUsrsInCrss (HieLvl_DEG,Deg->DegCod, + HTM_Unsigned (Enr_GetCachedNumUsrsInCrss (HieLvl_DEG,Deg->DegCod, 1 << Rol_STD | 1 << Rol_NET | 1 << Rol_TCH)); // Any user diff --git a/swad_enrolment.c b/swad_enrolment.c index c7dd6215..3ff84a2d 100644 --- a/swad_enrolment.c +++ b/swad_enrolment.c @@ -44,6 +44,7 @@ #include "swad_enrolment_database.h" #include "swad_error.h" #include "swad_exam_database.h" +#include "swad_figure_cache.h" #include "swad_form.h" #include "swad_global.h" #include "swad_hierarchy.h" @@ -160,6 +161,8 @@ static void Enr_EffectivelyRemUsrFromCrs (struct UsrData *UsrDat, Enr_RemoveUsrProduction_t RemoveUsrWorks, Cns_QuietOrVerbose_t QuietOrVerbose); +static FigCch_FigureCached_t Enr_GetFigureNumUsrsInCrss (unsigned Roles); + /*****************************************************************************/ /** Check if current course has students and show warning no students found **/ /*****************************************************************************/ @@ -168,7 +171,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 (!Usr_GetNumUsrsInCrss (HieLvl_CRS,Gbl.Hierarchy.Crs.CrsCod, + if (!Enr_GetNumUsrsInCrss (HieLvl_CRS,Gbl.Hierarchy.Crs.CrsCod, 1 << Rol_STD)) // No students in course Usr_ShowWarningNoUsersFound (Rol_STD); } @@ -182,7 +185,7 @@ void Enr_PutButtonInlineToRegisterStds (long CrsCod) extern const char *Txt_Register_students; if (Gbl.Usrs.Me.Role.Logged == Rol_TCH) // Course selected and I am logged as teacher - if (!Usr_GetNumUsrsInCrss (HieLvl_CRS,CrsCod, + if (!Enr_GetNumUsrsInCrss (HieLvl_CRS,CrsCod, 1 << Rol_STD)) // No students in course { Frm_BeginForm (ActReqEnrSevStd); @@ -589,7 +592,7 @@ static void Enr_ShowFormRegRemSeveralUsrs (Rol_Role_t Role) Enr_PutLinkToAdminOneUsr (ActReqMdfOneStd); /* Put link to remove all students in the current course */ - if (Usr_GetNumUsrsInCrss (HieLvl_CRS,Gbl.Hierarchy.Crs.CrsCod, + if (Enr_GetNumUsrsInCrss (HieLvl_CRS,Gbl.Hierarchy.Crs.CrsCod, 1 << Rol_STD)) // This course has students Enr_PutLinkToRemAllStdsThisCrs (); break; @@ -1738,7 +1741,7 @@ 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_GetNumUsrsInCrss (HieLvl_CRS,Gbl.Hierarchy.Crs.CrsCod, + unsigned NumStds = Enr_GetNumUsrsInCrss (HieLvl_CRS,Gbl.Hierarchy.Crs.CrsCod, 1 << Rol_STD); // This course has students /***** Begin box *****/ @@ -1903,7 +1906,7 @@ void Enr_SignUpInCrs (void) if (RoleFromForm == Rol_TCH) Notify = true; else - Notify = (Usr_GetNumUsrsInCrss (HieLvl_CRS,Gbl.Hierarchy.Crs.CrsCod, + Notify = (Enr_GetNumUsrsInCrss (HieLvl_CRS,Gbl.Hierarchy.Crs.CrsCod, 1 << Rol_TCH) != 0); // This course has teachers if (Notify) Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_ENROLMENT_REQUEST,ReqCod); @@ -2276,7 +2279,7 @@ static void Enr_ShowEnrolmentRequestsGivenRoles (unsigned RolesSelected) /***** Number of teachers in the course *****/ HTM_TD_Begin ("class=\"DAT RT\""); - HTM_Unsigned (Usr_GetNumUsrsInCrss (HieLvl_CRS,Crs.CrsCod, + HTM_Unsigned (Enr_GetNumUsrsInCrss (HieLvl_CRS,Crs.CrsCod, 1 << Rol_TCH)); HTM_TD_End (); @@ -3525,3 +3528,154 @@ bool Enr_CheckIfUsrSharesAnyOfMyCrs (struct UsrData *UsrDat) Gbl.Cache.UsrSharesAnyOfMyCrs.SharesAnyOfMyCrs = Enr_DB_CheckIfUsrSharesAnyOfMyCrs (UsrDat->UsrCod); return Gbl.Cache.UsrSharesAnyOfMyCrs.SharesAnyOfMyCrs; } + +/*****************************************************************************/ +/******* Get total number of users of one or several roles in courses ********/ +/*****************************************************************************/ + +#define Enr_DB_MAX_BYTES_SUBQUERY_ROLES (Rol_NUM_ROLES * (10 + 1) - 1) + +unsigned Enr_GetNumUsrsInCrss (HieLvl_Level_t Scope,long Cod,unsigned Roles) + { + bool AnyUserInCourses; + unsigned NumUsrs; + + /***** Reset roles that can not belong to courses. + Only + - students, + - non-editing teachers, + - teachers + can belong to a course *****/ + Roles &= ((1 << Rol_STD) | + (1 << Rol_NET) | + (1 << Rol_TCH)); + + /***** Check if no roles requested *****/ + if (Roles == 0) + return 0; + + /***** Check if any user in courses is requested *****/ + AnyUserInCourses = (Roles == ((1 << Rol_STD) | + (1 << Rol_NET) | + (1 << Rol_TCH))); + + /***** Get number of users from database *****/ + NumUsrs = Enr_DB_GetNumUsrsInCrss (Scope,Cod,Roles,AnyUserInCourses); + + FigCch_UpdateFigureIntoCache (Enr_GetFigureNumUsrsInCrss (Roles),Scope,Cod, + FigCch_UNSIGNED,&NumUsrs); + return NumUsrs; + } + +unsigned Enr_GetCachedNumUsrsInCrss (HieLvl_Level_t Scope,long Cod,unsigned Roles) + { + unsigned NumUsrsInCrss; + + /***** Get number of users in courses from cache *****/ + if (!FigCch_GetFigureFromCache (Enr_GetFigureNumUsrsInCrss (Roles),Scope,Cod, + FigCch_UNSIGNED,&NumUsrsInCrss)) + /***** Get current number of users in courses from database and update cache *****/ + NumUsrsInCrss = Enr_GetNumUsrsInCrss (Scope,Cod,Roles); + + return NumUsrsInCrss; + } + +static FigCch_FigureCached_t Enr_GetFigureNumUsrsInCrss (unsigned Roles) + { + switch (Roles) + { + case 1 << Rol_STD: // Students + return FigCch_NUM_STDS_IN_CRSS; + case 1 << Rol_NET: // Non-editing teachers + return FigCch_NUM_NETS_IN_CRSS; + case 1 << Rol_TCH: // Teachers + return FigCch_NUM_TCHS_IN_CRSS; + case 1 << Rol_NET | + 1 << Rol_TCH: // Any teacher in courses + return FigCch_NUM_ALLT_IN_CRSS; + case 1 << Rol_STD | + 1 << Rol_NET | + 1 << Rol_TCH: // Any user in courses + return FigCch_NUM_USRS_IN_CRSS; + default: + Err_WrongRoleExit (); + return FigCch_UNKNOWN; // Not reached + } + } + +/*****************************************************************************/ +/******** Get total number of users who do not belong to any course **********/ +/*****************************************************************************/ + +unsigned Enr_GetCachedNumUsrsNotBelongingToAnyCrs (void) + { + unsigned NumGsts; + + /***** Get number of guests from cache *****/ + if (!FigCch_GetFigureFromCache (FigCch_NUM_GSTS,HieLvl_SYS,-1L, + FigCch_UNSIGNED,&NumGsts)) + { + /***** Get current number of guests from database and update cache *****/ + NumGsts = Enr_DB_GetNumUsrsNotBelongingToAnyCrs (); + FigCch_UpdateFigureIntoCache (FigCch_NUM_GSTS,HieLvl_SYS,-1L, + FigCch_UNSIGNED,&NumGsts); + } + + return NumGsts; + } + +/*****************************************************************************/ +/************ Get average number of courses with users of a type *************/ +/*****************************************************************************/ + +double Enr_GetCachedAverageNumUsrsPerCrs (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role) + { + static const FigCch_FigureCached_t FigureNumUsrsPerCrs[Rol_NUM_ROLES] = + { + [Rol_UNK] = FigCch_NUM_USRS_PER_CRS, // Number of users per course + [Rol_STD] = FigCch_NUM_STDS_PER_CRS, // Number of students per course + [Rol_NET] = FigCch_NUM_NETS_PER_CRS, // Number of non-editing teachers per course + [Rol_TCH] = FigCch_NUM_TCHS_PER_CRS, // Number of teachers per course + }; + double AverageNumUsrsPerCrs; + + /***** Get number of users per course from cache *****/ + if (!FigCch_GetFigureFromCache (FigureNumUsrsPerCrs[Role],Scope,Cod, + FigCch_DOUBLE,&AverageNumUsrsPerCrs)) + { + /***** Get current number of users per course from database and update cache *****/ + AverageNumUsrsPerCrs = Enr_DB_GetAverageNumUsrsPerCrs (Scope,Cod,Role); + FigCch_UpdateFigureIntoCache (FigureNumUsrsPerCrs[Role],Scope,Cod, + FigCch_DOUBLE,&AverageNumUsrsPerCrs); + } + + return AverageNumUsrsPerCrs; + } + +/*****************************************************************************/ +/************ Get average number of courses with users of a role *************/ +/*****************************************************************************/ + +double Enr_GetCachedAverageNumCrssPerUsr (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role) + { + static const FigCch_FigureCached_t FigureNumCrssPerUsr[Rol_NUM_ROLES] = + { + [Rol_UNK] = FigCch_NUM_CRSS_PER_USR, // Number of courses per user + [Rol_STD] = FigCch_NUM_CRSS_PER_STD, // Number of courses per student + [Rol_NET] = FigCch_NUM_CRSS_PER_NET, // Number of courses per non-editing teacher + [Rol_TCH] = FigCch_NUM_CRSS_PER_TCH, // Number of courses per teacher + }; + double AverageNumCrssPerUsr; + + /***** Get number of courses per user from cache *****/ + if (!FigCch_GetFigureFromCache (FigureNumCrssPerUsr[Role],Scope,Cod, + FigCch_DOUBLE,&AverageNumCrssPerUsr)) + { + /***** Get current number of courses per user from database and update cache *****/ + AverageNumCrssPerUsr = Enr_DB_GetAverageNumCrssPerUsr (Scope,Cod,Role); + FigCch_UpdateFigureIntoCache (FigureNumCrssPerUsr[Role],Scope,Cod, + FigCch_DOUBLE,&AverageNumCrssPerUsr); + } + + return AverageNumCrssPerUsr; + } diff --git a/swad_enrolment.h b/swad_enrolment.h index b616bc57..d93dc905 100644 --- a/swad_enrolment.h +++ b/swad_enrolment.h @@ -154,4 +154,10 @@ bool Enr_CheckIfUsrHasAcceptedInCurrentCrs (const struct UsrData *UsrDat); void Enr_FlushCacheUsrSharesAnyOfMyCrs (void); bool Enr_CheckIfUsrSharesAnyOfMyCrs (struct UsrData *UsrDat); +unsigned Enr_GetNumUsrsInCrss (HieLvl_Level_t Scope,long Cod,unsigned Roles); +unsigned Enr_GetCachedNumUsrsInCrss (HieLvl_Level_t Scope,long Cod,unsigned Roles); +unsigned Enr_GetCachedNumUsrsNotBelongingToAnyCrs (void); +double Enr_GetCachedAverageNumUsrsPerCrs (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role); +double Enr_GetCachedAverageNumCrssPerUsr (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role); + #endif diff --git a/swad_enrolment_database.c b/swad_enrolment_database.c index ef325805..a1337f12 100644 --- a/swad_enrolment_database.c +++ b/swad_enrolment_database.c @@ -438,6 +438,235 @@ unsigned Enr_DB_GetNumUsrsInCrssOfAUsr (long UsrCod,Rol_Role_t UsrRole, return NumUsrs; } +/*****************************************************************************/ +/******* Get total number of users of one or several roles in courses ********/ +/*****************************************************************************/ + +#define Enr_DB_MAX_BYTES_SUBQUERY_ROLES (Rol_NUM_ROLES * (10 + 1) - 1) + +unsigned Enr_DB_GetNumUsrsInCrss (HieLvl_Level_t Scope,long Cod,unsigned Roles, + bool AnyUserInCourses) + { + char UnsignedStr[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; + char SubQueryRoles[Enr_DB_MAX_BYTES_SUBQUERY_ROLES + 1]; + bool FirstRole; + bool MoreThanOneRole; + Rol_Role_t Role; + Rol_Role_t FirstRoleRequested; + + /***** Get first role requested *****/ + FirstRoleRequested = Rol_UNK; + for (Role = Rol_STD; + Role <= Rol_TCH; + Role++) + if (Roles & (1 << Role)) + { + FirstRoleRequested = Role; + break; + } + + /***** Check if more than one role is requested *****/ + MoreThanOneRole = false; + if (FirstRoleRequested != Rol_UNK) + for (Role = FirstRoleRequested + 1; + Role <= Rol_TCH; + Role++) + if (Roles & (1 << Role)) + { + MoreThanOneRole = true; + break; + } + + /***** Build subquery for roles *****/ + if (MoreThanOneRole) + { + Str_Copy (SubQueryRoles," IN (",sizeof (SubQueryRoles) - 1); + for (Role = Rol_STD, FirstRole = true; + Role <= Rol_TCH; + Role++) + if (Roles & (1 << Role)) + { + snprintf (UnsignedStr,sizeof (UnsignedStr),"%u",(unsigned) Role); + if (FirstRole) // Not the first role + FirstRole = false; + else + Str_Concat (SubQueryRoles,",",sizeof (SubQueryRoles) - 1); + Str_Concat (SubQueryRoles,UnsignedStr,sizeof (SubQueryRoles) - 1); + } + Str_Concat (SubQueryRoles,")",sizeof (SubQueryRoles) - 1); + } + else // Only one role + sprintf (SubQueryRoles,"=%u",FirstRoleRequested); + + /***** Get number of users from database *****/ + switch (Scope) + { + case HieLvl_SYS: + if (AnyUserInCourses) // Any user + return (unsigned) + DB_QueryCOUNT ("can not get number of users", + "SELECT COUNT(DISTINCT UsrCod)" + " FROM crs_users"); + else + return (unsigned) + DB_QueryCOUNT ("can not get number of users", + "SELECT COUNT(DISTINCT UsrCod)" + " FROM crs_users" + " WHERE Role" + "%s", + SubQueryRoles); + case HieLvl_CTY: + if (AnyUserInCourses) // Any user + return (unsigned) + DB_QueryCOUNT ("can not get number of users", + "SELECT COUNT(DISTINCT crs_users.UsrCod)" + " FROM ins_instits," + "ctr_centers," + "deg_degrees," + "crs_courses," + "crs_users" + " WHERE ins_instits.CtyCod=%ld" + " AND ins_instits.InsCod=ctr_centers.InsCod" + " AND ctr_centers.CtrCod=deg_degrees.CtrCod" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=crs_users.CrsCod", + Cod); + else + return (unsigned) + DB_QueryCOUNT ("can not get number of users", + "SELECT COUNT(DISTINCT crs_users.UsrCod)" + " FROM ins_instits," + "ctr_centers," + "deg_degrees," + "crs_courses," + "crs_users" + " WHERE ins_instits.CtyCod=%ld" + " AND ins_instits.InsCod=ctr_centers.InsCod" + " AND ctr_centers.CtrCod=deg_degrees.CtrCod" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " AND crs_users.Role" + "%s", + Cod, + SubQueryRoles); + case HieLvl_INS: + if (AnyUserInCourses) // Any user + return (unsigned) + DB_QueryCOUNT ("can not get number of users", + "SELECT COUNT(DISTINCT crs_users.UsrCod)" + " FROM ctr_centers," + "deg_degrees," + "crs_courses," + "crs_users" + " WHERE ctr_centers.InsCod=%ld" + " AND ctr_centers.CtrCod=deg_degrees.CtrCod" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=crs_users.CrsCod", + Cod); + else + return (unsigned) + DB_QueryCOUNT ("can not get number of users", + "SELECT COUNT(DISTINCT crs_users.UsrCod)" + " FROM ctr_centers," + "deg_degrees," + "crs_courses," + "crs_users" + " WHERE ctr_centers.InsCod=%ld" + " AND ctr_centers.CtrCod=deg_degrees.CtrCod" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " AND crs_users.Role" + "%s", + Cod, + SubQueryRoles); + case HieLvl_CTR: + if (AnyUserInCourses) // Any user + return (unsigned) + DB_QueryCOUNT ("can not get number of users", + "SELECT COUNT(DISTINCT crs_users.UsrCod)" + " FROM deg_degrees," + "crs_courses," + "crs_users" + " WHERE deg_degrees.CtrCod=%ld" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=crs_users.CrsCod", + Cod); + else + return (unsigned) + DB_QueryCOUNT ("can not get number of users", + "SELECT COUNT(DISTINCT crs_users.UsrCod)" + " FROM deg_degrees," + "crs_courses," + "crs_users" + " WHERE deg_degrees.CtrCod=%ld" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " AND crs_users.Role" + "%s", + Cod, + SubQueryRoles); + case HieLvl_DEG: + if (AnyUserInCourses) // Any user + return (unsigned) + DB_QueryCOUNT ("can not get number of users", + "SELECT COUNT(DISTINCT crs_users.UsrCod)" + " FROM crs_courses," + "crs_users" + " WHERE crs_courses.DegCod=%ld" + " AND crs_courses.CrsCod=crs_users.CrsCod", + Cod); + else + return (unsigned) + DB_QueryCOUNT ("can not get number of users", + "SELECT COUNT(DISTINCT crs_users.UsrCod)" + " FROM crs_courses," + "crs_users" + " WHERE crs_courses.DegCod=%ld" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " AND crs_users.Role" + "%s", + Cod, + SubQueryRoles); + case HieLvl_CRS: + if (AnyUserInCourses) // Any user + return (unsigned) + DB_QueryCOUNT ("can not get number of users", + "SELECT COUNT(DISTINCT UsrCod)" + " FROM crs_users" + " WHERE CrsCod=%ld", + Cod); + else + return (unsigned) + DB_QueryCOUNT ("can not get number of users", + "SELECT COUNT(DISTINCT UsrCod)" + " FROM crs_users" + " WHERE CrsCod=%ld" + " AND Role" + "%s", + Cod, + SubQueryRoles); + default: + Err_WrongScopeExit (); + return 0; // Not reached + } + } + +/*****************************************************************************/ +/******** Get total number of users who do not belong to any course **********/ +/*****************************************************************************/ + +unsigned Enr_DB_GetNumUsrsNotBelongingToAnyCrs (void) + { + return (unsigned) + DB_QueryCOUNT ("can not get number of users" + " who do not belong to any course", + "SELECT COUNT(*)" + " FROM usr_data" + " WHERE UsrCod NOT IN" + " (SELECT DISTINCT(UsrCod)" + " FROM crs_users)"); + } + /*****************************************************************************/ /************ Get average number of courses with users of a type *************/ /*****************************************************************************/ @@ -577,7 +806,7 @@ double Enr_DB_GetAverageNumUsrsPerCrs (HieLvl_Level_t Scope,long Cod,Rol_Role_t Cod, (unsigned) Role); case HieLvl_CRS: - return (double) Usr_GetNumUsrsInCrss (HieLvl_CRS,Cod, + return (double) Enr_GetNumUsrsInCrss (HieLvl_CRS,Cod, Role == Rol_UNK ? 1 << Rol_STD | 1 << Rol_NET | 1 << Rol_TCH : // Any user diff --git a/swad_enrolment_database.h b/swad_enrolment_database.h index f36768b7..6def49a2 100644 --- a/swad_enrolment_database.h +++ b/swad_enrolment_database.h @@ -65,6 +65,9 @@ unsigned Enr_DB_GetNumCrssOfUsrWithARole (long UsrCod,Rol_Role_t Role); unsigned Enr_DB_GetNumCrssOfUsrWithARoleNotAccepted (long UsrCod,Rol_Role_t Role); unsigned Enr_DB_GetNumUsrsInCrssOfAUsr (long UsrCod,Rol_Role_t UsrRole, unsigned OthersRoles); +unsigned Enr_DB_GetNumUsrsInCrss (HieLvl_Level_t Scope,long Cod,unsigned Roles, + bool AnyUserInCourses); +unsigned Enr_DB_GetNumUsrsNotBelongingToAnyCrs (void); double Enr_DB_GetAverageNumUsrsPerCrs (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role); double Enr_DB_GetAverageNumCrssPerUsr (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role); diff --git a/swad_figure.c b/swad_figure.c index d013d122..8f4bd565 100644 --- a/swad_figure.c +++ b/swad_figure.c @@ -464,15 +464,15 @@ static void Fig_GetAndShowNumUsrsInCrss (Rol_Role_t Role) /* Number of users in courses */ HTM_TD_Begin ("class=\"%s\"",Class); - HTM_Unsigned (Usr_GetCachedNumUsrsInCrss (Gbl.Scope.Current,Cod,Roles)); + HTM_Unsigned (Enr_GetCachedNumUsrsInCrss (Gbl.Scope.Current,Cod,Roles)); HTM_TD_End (); HTM_TD_Begin ("class=\"%s\"",Class); - HTM_Double2Decimals (Usr_GetCachedNumCrssPerUsr (Gbl.Scope.Current,Cod,Role)); + HTM_Double2Decimals (Enr_GetCachedAverageNumCrssPerUsr (Gbl.Scope.Current,Cod,Role)); HTM_TD_End (); HTM_TD_Begin ("class=\"%s\"",Class); - HTM_Double2Decimals (Usr_GetCachedNumUsrsPerCrs (Gbl.Scope.Current,Cod,Role)); + HTM_Double2Decimals (Enr_GetCachedAverageNumUsrsPerCrs (Gbl.Scope.Current,Cod,Role)); HTM_TD_End (); HTM_TR_End (); @@ -495,7 +495,7 @@ static void Fig_GetAndShowNumUsrsNotBelongingToAnyCrs (void) HTM_TD_End (); HTM_TD_Begin ("class=\"%s\"",Class); - HTM_Unsigned (Usr_GetCachedNumUsrsNotBelongingToAnyCrs ()); + HTM_Unsigned (Enr_GetCachedNumUsrsNotBelongingToAnyCrs ()); HTM_TD_End (); HTM_TD_Begin ("class=\"%s\"",Class); diff --git a/swad_global.c b/swad_global.c index f4529bee..2716357a 100644 --- a/swad_global.c +++ b/swad_global.c @@ -326,11 +326,11 @@ void Gbl_InitializeGlobals (void) Crs_FlushCacheNumCrssInDeg (); - Usr_FlushCacheNumUsrsWhoDontClaimToBelongToAnyCty (); - Usr_FlushCacheNumUsrsWhoClaimToBelongToAnotherCty (); - Usr_FlushCacheNumUsrsWhoClaimToBelongToCty (); - Usr_FlushCacheNumUsrsWhoClaimToBelongToIns (); - Usr_FlushCacheNumUsrsWhoClaimToBelongToCtr (); + Cty_FlushCacheNumUsrsWhoDontClaimToBelongToAnyCty (); + Cty_FlushCacheNumUsrsWhoClaimToBelongToAnotherCty (); + Cty_FlushCacheNumUsrsWhoClaimToBelongToCty (); + Ins_FlushCacheNumUsrsWhoClaimToBelongToIns (); + Ctr_FlushCacheNumUsrsWhoClaimToBelongToCtr (); Usr_FlushCacheUsrIsSuperuser (); Ins_FlushCacheUsrBelongsToIns (); Ctr_FlushCacheUsrBelongsToCtr (); diff --git a/swad_help.c b/swad_help.c index c452640b..aa12607d 100644 --- a/swad_help.c +++ b/swad_help.c @@ -165,7 +165,7 @@ void Hlp_ShowHelpWhatWouldYouLikeToDo (void) { if (Gbl.Hierarchy.Level == HieLvl_CRS && // Course selected Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs == Rol_TCH) // I am a teacher in current course - if (!Usr_GetCachedNumUsrsInCrss (HieLvl_CRS,Gbl.Hierarchy.Crs.CrsCod, + if (!Enr_GetCachedNumUsrsInCrss (HieLvl_CRS,Gbl.Hierarchy.Crs.CrsCod, 1 << Rol_STD)) // Current course probably has no students { /* Request students enrolment */ diff --git a/swad_hierarchy_config.c b/swad_hierarchy_config.c index b7940715..9e880b36 100644 --- a/swad_hierarchy_config.c +++ b/swad_hierarchy_config.c @@ -335,7 +335,7 @@ void HieCfg_NumUsrsInCrss (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role) /* Data */ HTM_TD_Begin ("class=\"DAT LB\""); - HTM_Unsigned (Usr_GetCachedNumUsrsInCrss (Scope,Cod, + HTM_Unsigned (Enr_GetCachedNumUsrsInCrss (Scope,Cod, Role == Rol_UNK ? (1 << Rol_STD) | (1 << Rol_NET) | (1 << Rol_TCH) : // Any user diff --git a/swad_indicator.c b/swad_indicator.c index 771f1113..665bb2c5 100644 --- a/swad_indicator.c +++ b/swad_indicator.c @@ -807,10 +807,10 @@ static void Ind_ShowTableOfCoursesWithIndicators (const struct Ind_Indicators *I break; case Ind_INDICATORS_FULL: /* Get number of users */ - NumTchs = Usr_GetNumUsrsInCrss (HieLvl_CRS,CrsCod, + NumTchs = Enr_GetNumUsrsInCrss (HieLvl_CRS,CrsCod, 1 << Rol_NET | // Non-editing teachers 1 << Rol_TCH); // Teachers - NumStds = Usr_GetNumUsrsInCrss (HieLvl_CRS,CrsCod, + NumStds = Enr_GetNumUsrsInCrss (HieLvl_CRS,CrsCod, 1 << Rol_STD); // Students HTM_TR_Begin (NULL); diff --git a/swad_institution.c b/swad_institution.c index 9ca03030..67d588cc 100644 --- a/swad_institution.c +++ b/swad_institution.c @@ -406,7 +406,7 @@ static void Ins_ListOneInstitutionForSeeing (struct Ins_Instit *Ins,unsigned Num /***** Number of users who claim to belong to this institution *****/ HTM_TD_Begin ("class=\"%s RM %s\"",TxtClassNormal,BgColor); - HTM_Unsigned (Usr_GetCachedNumUsrsWhoClaimToBelongToIns (Ins)); + HTM_Unsigned (Ins_GetCachedNumUsrsWhoClaimToBelongToIns (Ins)); HTM_TD_End (); /***** Other stats *****/ @@ -432,7 +432,7 @@ static void Ins_ListOneInstitutionForSeeing (struct Ins_Instit *Ins,unsigned Num /* Number of users in courses of this institution */ HTM_TD_Begin ("class=\"%s RM %s\"",TxtClassNormal,BgColor); - HTM_Unsigned (Usr_GetCachedNumUsrsInCrss (HieLvl_INS,Ins->InsCod, + HTM_Unsigned (Enr_GetCachedNumUsrsInCrss (HieLvl_INS,Ins->InsCod, 1 << Rol_STD | 1 << Rol_NET | 1 << Rol_TCH)); // Any user); @@ -961,8 +961,8 @@ static void Ins_ListInstitutionsForEdition (void) ICanEdit = Ins_CheckIfICanEdit (Ins); NumCtrs = Ctr_GetNumCtrsInIns (Ins->InsCod); - NumUsrsIns = Usr_GetNumUsrsWhoClaimToBelongToIns (Ins); - NumUsrsInCrssOfIns = Usr_GetNumUsrsInCrss (HieLvl_INS,Ins->InsCod, + NumUsrsIns = Ins_GetNumUsrsWhoClaimToBelongToIns (Ins); + NumUsrsInCrssOfIns = Enr_GetNumUsrsInCrss (HieLvl_INS,Ins->InsCod, 1 << Rol_STD | 1 << Rol_NET | 1 << Rol_TCH); // Any user @@ -1230,11 +1230,11 @@ void Ins_RemoveInstitution (void) // Institution has centers ==> don't remove Ale_CreateAlert (Ale_WARNING,NULL, Txt_To_remove_an_institution_you_must_first_remove_all_centers_and_users_in_the_institution); - else if (Usr_GetNumUsrsWhoClaimToBelongToIns (Ins_EditingIns)) + else if (Ins_GetNumUsrsWhoClaimToBelongToIns (Ins_EditingIns)) // Institution has users ==> don't remove Ale_CreateAlert (Ale_WARNING,NULL, Txt_To_remove_an_institution_you_must_first_remove_all_centers_and_users_in_the_institution); - else if (Usr_GetNumUsrsInCrss (HieLvl_INS,Ins_EditingIns->InsCod, + else if (Enr_GetNumUsrsInCrss (HieLvl_INS,Ins_EditingIns->InsCod, 1 << Rol_STD | 1 << Rol_NET | 1 << Rol_TCH)) // Any user @@ -1271,7 +1271,7 @@ void Ins_RemoveInstitution (void) Ctr_FlushCacheNumCtrsInIns (); Deg_FlushCacheNumDegsInIns (); Crs_FlushCacheNumCrssInIns (); - Usr_FlushCacheNumUsrsWhoClaimToBelongToIns (); + Ins_FlushCacheNumUsrsWhoClaimToBelongToIns (); /***** Write message to show the change made *****/ Ale_CreateAlert (Ale_SUCCESS,NULL, @@ -2094,3 +2094,55 @@ bool Ins_CheckIfUsrBelongsToIns (long UsrCod,long InsCod) Gbl.Cache.UsrBelongsToIns.Belongs = Ins_DB_CheckIfUsrBelongsToIns (UsrCod,InsCod); return Gbl.Cache.UsrBelongsToIns.Belongs; } + +/*****************************************************************************/ +/******** Get number of users who claim to belong to an institution **********/ +/*****************************************************************************/ + +void Ins_FlushCacheNumUsrsWhoClaimToBelongToIns (void) + { + Gbl.Cache.NumUsrsWhoClaimToBelongToIns.InsCod = -1L; + Gbl.Cache.NumUsrsWhoClaimToBelongToIns.NumUsrs = 0; + } + +unsigned Ins_GetNumUsrsWhoClaimToBelongToIns (struct Ins_Instit *Ins) + { + /***** 1. Fast check: Trivial case *****/ + if (Ins->InsCod <= 0) + return 0; + + /***** 2. Fast check: If already got... *****/ + if (Ins->NumUsrsWhoClaimToBelongToIns.Valid) + return Ins->NumUsrsWhoClaimToBelongToIns.NumUsrs; + + /***** 3. Fast check: If cached... *****/ + if (Ins->InsCod == Gbl.Cache.NumUsrsWhoClaimToBelongToIns.InsCod) + { + Ins->NumUsrsWhoClaimToBelongToIns.NumUsrs = Gbl.Cache.NumUsrsWhoClaimToBelongToIns.NumUsrs; + Ins->NumUsrsWhoClaimToBelongToIns.Valid = true; + return Ins->NumUsrsWhoClaimToBelongToIns.NumUsrs; + } + + /***** 4. Slow: number of users who claim to belong to an institution + from database *****/ + Gbl.Cache.NumUsrsWhoClaimToBelongToIns.InsCod = Ins->InsCod; + Gbl.Cache.NumUsrsWhoClaimToBelongToIns.NumUsrs = + Ins->NumUsrsWhoClaimToBelongToIns.NumUsrs = Ins_DB_GetNumUsrsWhoClaimToBelongToIns (Ins->InsCod); + Ins->NumUsrsWhoClaimToBelongToIns.Valid = true; + FigCch_UpdateFigureIntoCache (FigCch_NUM_USRS_BELONG_INS,HieLvl_INS,Gbl.Cache.NumUsrsWhoClaimToBelongToIns.InsCod, + FigCch_UNSIGNED,&Gbl.Cache.NumUsrsWhoClaimToBelongToIns.NumUsrs); + return Ins->NumUsrsWhoClaimToBelongToIns.NumUsrs; + } + +unsigned Ins_GetCachedNumUsrsWhoClaimToBelongToIns (struct Ins_Instit *Ins) + { + unsigned NumUsrsIns; + + /***** Get number of users who claim to belong to institution from cache *****/ + if (!FigCch_GetFigureFromCache (FigCch_NUM_USRS_BELONG_INS,HieLvl_INS,Ins->InsCod, + FigCch_UNSIGNED,&NumUsrsIns)) + /***** Get current number of users who claim to belong to institution from database and update cache *****/ + NumUsrsIns = Ins_GetNumUsrsWhoClaimToBelongToIns (Ins); + + return NumUsrsIns; + } diff --git a/swad_institution.h b/swad_institution.h index 49fc709e..c257cde6 100644 --- a/swad_institution.h +++ b/swad_institution.h @@ -141,4 +141,8 @@ bool Ins_CheckIfIBelongToIns (long InsCod); void Ins_FlushCacheUsrBelongsToIns (void); bool Ins_CheckIfUsrBelongsToIns (long UsrCod,long InsCod); +void Ins_FlushCacheNumUsrsWhoClaimToBelongToIns (void); +unsigned Ins_GetNumUsrsWhoClaimToBelongToIns (struct Ins_Instit *Ins); +unsigned Ins_GetCachedNumUsrsWhoClaimToBelongToIns (struct Ins_Instit *Ins); + #endif diff --git a/swad_institution_config.c b/swad_institution_config.c index 3e3c9322..fd3ef707 100644 --- a/swad_institution_config.c +++ b/swad_institution_config.c @@ -436,7 +436,7 @@ static void InsCfg_NumUsrs (void) /* Data */ HTM_TD_Begin ("class=\"DAT LB\""); - HTM_Unsigned (Usr_GetCachedNumUsrsWhoClaimToBelongToIns (&Gbl.Hierarchy.Ins)); + HTM_Unsigned (Ins_GetCachedNumUsrsWhoClaimToBelongToIns (&Gbl.Hierarchy.Ins)); HTM_TD_End (); HTM_TR_End (); diff --git a/swad_institution_database.c b/swad_institution_database.c index 89fceef5..bc48cbc7 100644 --- a/swad_institution_database.c +++ b/swad_institution_database.c @@ -822,6 +822,20 @@ bool Ins_DB_CheckIfUsrBelongsToIns (long UsrCod,long InsCod) InsCod) != 0); } +/*****************************************************************************/ +/******** Get number of users who claim to belong to an institution **********/ +/*****************************************************************************/ + +unsigned Ins_DB_GetNumUsrsWhoClaimToBelongToIns (long InsCod) + { + return (unsigned) + DB_QueryCOUNT ("can not get number of users", + "SELECT COUNT(UsrCod)" + " FROM usr_data" + " WHERE InsCod=%ld", + InsCod); + } + /*****************************************************************************/ /***************************** Remove institution ****************************/ /*****************************************************************************/ diff --git a/swad_institution_database.h b/swad_institution_database.h index 0ab62cf4..2b8e544c 100644 --- a/swad_institution_database.h +++ b/swad_institution_database.h @@ -82,6 +82,7 @@ unsigned Ins_DB_GetNumInnsWithUsrs (Rol_Role_t Role, unsigned Ins_DB_GetInssFromUsr (MYSQL_RES **mysql_res,long UsrCod,long CtyCod); bool Ins_DB_CheckIfUsrBelongsToIns (long UsrCod,long InsCod); +unsigned Ins_DB_GetNumUsrsWhoClaimToBelongToIns (long InsCod); void Ins_DB_RemoveInstitution (long InsCod); diff --git a/swad_mark.c b/swad_mark.c index a93ed6b5..afdeaa05 100644 --- a/swad_mark.c +++ b/swad_mark.c @@ -570,7 +570,7 @@ void Mrk_ShowMyMarks (void) } else // Course zone { - if (Usr_GetNumUsrsInCrss (HieLvl_CRS,Gbl.Hierarchy.Crs.CrsCod, + if (Enr_GetNumUsrsInCrss (HieLvl_CRS,Gbl.Hierarchy.Crs.CrsCod, 1 << Rol_STD)) // If there are students in this course { Gbl.Usrs.Other.UsrDat.UsrCod = Enr_DB_GetRamdomStdFromCrs (Gbl.Hierarchy.Crs.CrsCod); diff --git a/swad_notification.c b/swad_notification.c index 4df21ea0..5fe20384 100644 --- a/swad_notification.c +++ b/swad_notification.c @@ -1071,7 +1071,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 (Usr_GetNumUsrsInCrss (HieLvl_CRS,Gbl.Hierarchy.Crs.CrsCod, + if (Enr_GetNumUsrsInCrss (HieLvl_CRS,Gbl.Hierarchy.Crs.CrsCod, 1 << Rol_TCH)) // If this course has teachers ==> send notification to teachers NumUsrs = Enr_DB_GetTchsFromCurrentCrsExceptMe (&mysql_res); diff --git a/swad_report.c b/swad_report.c index a5abaaed..b9171976 100644 --- a/swad_report.c +++ b/swad_report.c @@ -1067,11 +1067,11 @@ static void Rep_WriteRowCrsData (long CrsCod,Rol_Role_t Role, /***** Write number of teachers / students in course *****/ if (WriteNumUsrs) fprintf (Gbl.F.Rep," (%u %s / %u %s)", - Usr_GetCachedNumUsrsInCrss (HieLvl_CRS,Crs.CrsCod, + Enr_GetCachedNumUsrsInCrss (HieLvl_CRS,Crs.CrsCod, 1 << Rol_NET | 1 << Rol_TCH), Txt_teachers_ABBREVIATION, - Usr_GetCachedNumUsrsInCrss (HieLvl_CRS,Crs.CrsCod, + Enr_GetCachedNumUsrsInCrss (HieLvl_CRS,Crs.CrsCod, 1 << Rol_STD), Txt_students_ABBREVIATION); } diff --git a/swad_user.c b/swad_user.c index cb8a113e..b06753b0 100644 --- a/swad_user.c +++ b/swad_user.c @@ -165,9 +165,6 @@ static void Usr_GetMyLastData (void); static void Usr_GetUsrCommentsFromString (char *Str,struct UsrData *UsrDat); static Usr_Sex_t Usr_GetSexFromStr (const char *Str); -static bool Usr_DB_CheckIfMyBirthdayHasNotBeenCongratulated (void); -static void Usr_InsertMyBirthday (void); - static void Usr_GetParamOtherUsrIDNickOrEMail (void); static bool Usr_ChkUsrAndGetUsrDataFromDirectLogin (void); @@ -262,8 +259,6 @@ static void Usr_DrawClassPhoto (Usr_ClassPhotoType_t ClassPhotoType, struct SelectedUsrs *SelectedUsrs, bool PutCheckBoxToSelectUsr); -static FigCch_FigureCached_t Usr_GetFigureNumUsrsInCrss (unsigned Roles); - /*****************************************************************************/ /**** Show alert about number of clicks remaining before sending my photo ****/ /*****************************************************************************/ @@ -1412,7 +1407,8 @@ void Usr_WelcomeUsr (void) if (Usr_DB_CheckIfMyBirthdayHasNotBeenCongratulated ()) { /* Mark my birthday as already congratulated */ - Usr_InsertMyBirthday (); + Usr_DB_DeleteOldBirthdays (); + Usr_DB_MarkMyBirthdayAsCongratulated (); /* Begin alert */ Ale_ShowAlertAndButton1 (Ale_INFO,Txt_Happy_birthday_X, @@ -1499,40 +1495,6 @@ void Usr_CreateBirthdayStrDB (const struct UsrData *UsrDat, UsrDat->Birthday.Day); } -/*****************************************************************************/ -/*************** Check if my birthday is already congratulated ***************/ -/*****************************************************************************/ - -static bool Usr_DB_CheckIfMyBirthdayHasNotBeenCongratulated (void) - { - /***** Delete old birthdays *****/ - return (DB_QueryCOUNT ("can not check if my birthday has been congratulated", - "SELECT COUNT(*)" - " FROM usr_birthdays_today" - " WHERE UsrCod=%ld", - Gbl.Usrs.Me.UsrDat.UsrCod) == 0); - } - -/*****************************************************************************/ -/*** Insert my user's code in the table of birthdays already congratulated ***/ -/*****************************************************************************/ - -static void Usr_InsertMyBirthday (void) - { - /***** Delete old birthdays *****/ - DB_QueryDELETE ("can not delete old birthdays", - "DELETE FROM usr_birthdays_today" - " WHERE Today<>CURDATE()"); - - /***** Insert new birthday *****/ - DB_QueryINSERT ("can not insert birthday", - "INSERT INTO usr_birthdays_today" - " (UsrCod,Today)" - " VALUES" - " (%ld,CURDATE())", - Gbl.Usrs.Me.UsrDat.UsrCod); - } - /*****************************************************************************/ /************************* Filter some user's data ***************************/ /*****************************************************************************/ @@ -2874,258 +2836,6 @@ static void Usr_WriteUsrData (const char *BgColor, HTM_TD_End (); } -/*****************************************************************************/ -/******* Get number of users who don't claim to belong to any country ********/ -/*****************************************************************************/ - -void Usr_FlushCacheNumUsrsWhoDontClaimToBelongToAnyCty (void) - { - Gbl.Cache.NumUsrsWhoDontClaimToBelongToAnyCty.Valid = false; - } - -unsigned Usr_GetNumUsrsWhoDontClaimToBelongToAnyCty (void) - { - /***** 1. Fast check: If cached... *****/ - if (Gbl.Cache.NumUsrsWhoDontClaimToBelongToAnyCty.Valid) - return Gbl.Cache.NumUsrsWhoDontClaimToBelongToAnyCty.NumUsrs; - - /***** 2. Slow: number of users who don't claim to belong to any country - from database *****/ - Gbl.Cache.NumUsrsWhoDontClaimToBelongToAnyCty.NumUsrs = (unsigned) - DB_QueryCOUNT ("can not get number of users", - "SELECT COUNT(UsrCod)" - " FROM usr_data" - " WHERE CtyCod<0"); - Gbl.Cache.NumUsrsWhoDontClaimToBelongToAnyCty.Valid = true; - FigCch_UpdateFigureIntoCache (FigCch_NUM_USRS_BELONG_CTY,HieLvl_CTY,-1L, - FigCch_UNSIGNED,&Gbl.Cache.NumUsrsWhoDontClaimToBelongToAnyCty.NumUsrs); - return Gbl.Cache.NumUsrsWhoDontClaimToBelongToAnyCty.NumUsrs; - } - -unsigned Usr_GetCachedNumUsrsWhoDontClaimToBelongToAnyCty (void) - { - unsigned NumUsrs; - - /***** Get number of user who don't claim to belong to any country from cache *****/ - if (!FigCch_GetFigureFromCache (FigCch_NUM_USRS_BELONG_CTY,HieLvl_CTY,-1L, - FigCch_UNSIGNED,&NumUsrs)) - /***** Get current number of user who don't claim to belong to any country from database and update cache *****/ - NumUsrs = Usr_GetNumUsrsWhoDontClaimToBelongToAnyCty (); - - return NumUsrs; - } - -/*****************************************************************************/ -/******** Get number of users who claim to belong to another country *********/ -/*****************************************************************************/ - -void Usr_FlushCacheNumUsrsWhoClaimToBelongToAnotherCty (void) - { - Gbl.Cache.NumUsrsWhoClaimToBelongToAnotherCty.Valid = false; - } - -unsigned Usr_GetNumUsrsWhoClaimToBelongToAnotherCty (void) - { - /***** 1. Fast check: If cached... *****/ - if (Gbl.Cache.NumUsrsWhoClaimToBelongToAnotherCty.Valid) - return Gbl.Cache.NumUsrsWhoClaimToBelongToAnotherCty.NumUsrs; - - /***** 2. Slow: number of users who claim to belong to another country - from database *****/ - Gbl.Cache.NumUsrsWhoClaimToBelongToAnotherCty.NumUsrs = (unsigned) - DB_QueryCOUNT ("can not get number of users", - "SELECT COUNT(UsrCod)" - " FROM usr_data" - " WHERE CtyCod=0"); - Gbl.Cache.NumUsrsWhoClaimToBelongToAnotherCty.Valid = true; - FigCch_UpdateFigureIntoCache (FigCch_NUM_USRS_BELONG_CTY,HieLvl_CTY,0, - FigCch_UNSIGNED,&Gbl.Cache.NumUsrsWhoClaimToBelongToAnotherCty.NumUsrs); - return Gbl.Cache.NumUsrsWhoClaimToBelongToAnotherCty.NumUsrs; - } - -unsigned Usr_GetCachedNumUsrsWhoClaimToBelongToAnotherCty (void) - { - unsigned NumUsrsCty; - - /***** Get number of users who claim to belong to another country form cache *****/ - if (!FigCch_GetFigureFromCache (FigCch_NUM_USRS_BELONG_CTY,HieLvl_CTY,0, - FigCch_UNSIGNED,&NumUsrsCty)) - /***** Get current number of users who claim to belong to another country from database and update cache *****/ - NumUsrsCty = Usr_GetNumUsrsWhoClaimToBelongToAnotherCty (); - - return NumUsrsCty; - } - -/*****************************************************************************/ -/*********** Get number of users who claim to belong to a country ************/ -/*****************************************************************************/ - -void Usr_FlushCacheNumUsrsWhoClaimToBelongToCty (void) - { - Gbl.Cache.NumUsrsWhoClaimToBelongToCty.CtyCod = -1L; - Gbl.Cache.NumUsrsWhoClaimToBelongToCty.NumUsrs = 0; - } - -unsigned Usr_GetNumUsrsWhoClaimToBelongToCty (struct Cty_Countr *Cty) - { - /***** 1. Fast check: Trivial case *****/ - if (Cty->CtyCod <= 0) - return 0; - - /***** 2. Fast check: If already got... *****/ - if (Cty->NumUsrsWhoClaimToBelongToCty.Valid) - return Cty->NumUsrsWhoClaimToBelongToCty.NumUsrs; - - /***** 3. Fast check: If cached... *****/ - if (Cty->CtyCod == Gbl.Cache.NumUsrsWhoClaimToBelongToCty.CtyCod) - { - Cty->NumUsrsWhoClaimToBelongToCty.NumUsrs = Gbl.Cache.NumUsrsWhoClaimToBelongToCty.NumUsrs; - Cty->NumUsrsWhoClaimToBelongToCty.Valid = true; - return Cty->NumUsrsWhoClaimToBelongToCty.NumUsrs; - } - - /***** 4. Slow: number of users who claim to belong to an institution - from database *****/ - Gbl.Cache.NumUsrsWhoClaimToBelongToCty.CtyCod = Cty->CtyCod; - Gbl.Cache.NumUsrsWhoClaimToBelongToCty.NumUsrs = - Cty->NumUsrsWhoClaimToBelongToCty.NumUsrs = (unsigned) - DB_QueryCOUNT ("can not get number of users", - "SELECT COUNT(UsrCod)" - " FROM usr_data" - " WHERE CtyCod=%ld", - Cty->CtyCod); - Cty->NumUsrsWhoClaimToBelongToCty.Valid = true; - FigCch_UpdateFigureIntoCache (FigCch_NUM_USRS_BELONG_CTY,HieLvl_CTY,Gbl.Cache.NumUsrsWhoClaimToBelongToCty.CtyCod, - FigCch_UNSIGNED,&Gbl.Cache.NumUsrsWhoClaimToBelongToCty.NumUsrs); - return Cty->NumUsrsWhoClaimToBelongToCty.NumUsrs; - } - -unsigned Usr_GetCachedNumUsrsWhoClaimToBelongToCty (struct Cty_Countr *Cty) - { - unsigned NumUsrsCty; - - /***** Get number of users who claim to belong to country from cache ******/ - if (!FigCch_GetFigureFromCache (FigCch_NUM_USRS_BELONG_CTY,HieLvl_CTY,Cty->CtyCod, - FigCch_UNSIGNED,&NumUsrsCty)) - /***** Get current number of users who claim to belong to country from database and update cache ******/ - NumUsrsCty = Usr_GetNumUsrsWhoClaimToBelongToCty (Cty); - - return NumUsrsCty; - } - -/*****************************************************************************/ -/******** Get number of users who claim to belong to an institution **********/ -/*****************************************************************************/ - -void Usr_FlushCacheNumUsrsWhoClaimToBelongToIns (void) - { - Gbl.Cache.NumUsrsWhoClaimToBelongToIns.InsCod = -1L; - Gbl.Cache.NumUsrsWhoClaimToBelongToIns.NumUsrs = 0; - } - -unsigned Usr_GetNumUsrsWhoClaimToBelongToIns (struct Ins_Instit *Ins) - { - /***** 1. Fast check: Trivial case *****/ - if (Ins->InsCod <= 0) - return 0; - - /***** 2. Fast check: If already got... *****/ - if (Ins->NumUsrsWhoClaimToBelongToIns.Valid) - return Ins->NumUsrsWhoClaimToBelongToIns.NumUsrs; - - /***** 3. Fast check: If cached... *****/ - if (Ins->InsCod == Gbl.Cache.NumUsrsWhoClaimToBelongToIns.InsCod) - { - Ins->NumUsrsWhoClaimToBelongToIns.NumUsrs = Gbl.Cache.NumUsrsWhoClaimToBelongToIns.NumUsrs; - Ins->NumUsrsWhoClaimToBelongToIns.Valid = true; - return Ins->NumUsrsWhoClaimToBelongToIns.NumUsrs; - } - - /***** 4. Slow: number of users who claim to belong to an institution - from database *****/ - Gbl.Cache.NumUsrsWhoClaimToBelongToIns.InsCod = Ins->InsCod; - Gbl.Cache.NumUsrsWhoClaimToBelongToIns.NumUsrs = - Ins->NumUsrsWhoClaimToBelongToIns.NumUsrs = (unsigned) - DB_QueryCOUNT ("can not get number of users", - "SELECT COUNT(UsrCod)" - " FROM usr_data" - " WHERE InsCod=%ld", - Ins->InsCod); - Ins->NumUsrsWhoClaimToBelongToIns.Valid = true; - FigCch_UpdateFigureIntoCache (FigCch_NUM_USRS_BELONG_INS,HieLvl_INS,Gbl.Cache.NumUsrsWhoClaimToBelongToIns.InsCod, - FigCch_UNSIGNED,&Gbl.Cache.NumUsrsWhoClaimToBelongToIns.NumUsrs); - return Ins->NumUsrsWhoClaimToBelongToIns.NumUsrs; - } - -unsigned Usr_GetCachedNumUsrsWhoClaimToBelongToIns (struct Ins_Instit *Ins) - { - unsigned NumUsrsIns; - - /***** Get number of users who claim to belong to institution from cache *****/ - if (!FigCch_GetFigureFromCache (FigCch_NUM_USRS_BELONG_INS,HieLvl_INS,Ins->InsCod, - FigCch_UNSIGNED,&NumUsrsIns)) - /***** Get current number of users who claim to belong to institution from database and update cache *****/ - NumUsrsIns = Usr_GetNumUsrsWhoClaimToBelongToIns (Ins); - - return NumUsrsIns; - } - -/*****************************************************************************/ -/*********** Get number of users who claim to belong to a center *************/ -/*****************************************************************************/ - -void Usr_FlushCacheNumUsrsWhoClaimToBelongToCtr (void) - { - Gbl.Cache.NumUsrsWhoClaimToBelongToCtr.CtrCod = -1L; - Gbl.Cache.NumUsrsWhoClaimToBelongToCtr.NumUsrs = 0; - } - -unsigned Usr_GetNumUsrsWhoClaimToBelongToCtr (struct Ctr_Center *Ctr) - { - /***** 1. Fast check: Trivial case *****/ - if (Ctr->CtrCod <= 0) - return 0; - - /***** 2. Fast check: If already got... *****/ - if (Ctr->NumUsrsWhoClaimToBelongToCtr.Valid) - return Ctr->NumUsrsWhoClaimToBelongToCtr.NumUsrs; - - /***** 3. Fast check: If cached... *****/ - if (Ctr->CtrCod == Gbl.Cache.NumUsrsWhoClaimToBelongToCtr.CtrCod) - { - Ctr->NumUsrsWhoClaimToBelongToCtr.NumUsrs = Gbl.Cache.NumUsrsWhoClaimToBelongToCtr.NumUsrs; - Ctr->NumUsrsWhoClaimToBelongToCtr.Valid = true; - return Ctr->NumUsrsWhoClaimToBelongToCtr.NumUsrs; - } - - /***** 4. Slow: number of users who claim to belong to a center - from database *****/ - Gbl.Cache.NumUsrsWhoClaimToBelongToCtr.CtrCod = Ctr->CtrCod; - Gbl.Cache.NumUsrsWhoClaimToBelongToCtr.NumUsrs = - Ctr->NumUsrsWhoClaimToBelongToCtr.NumUsrs = (unsigned) - DB_QueryCOUNT ("can not get number of users", - "SELECT COUNT(UsrCod)" - " FROM usr_data" - " WHERE CtrCod=%ld", - Ctr->CtrCod); - FigCch_UpdateFigureIntoCache (FigCch_NUM_USRS_BELONG_CTR,HieLvl_CTR,Gbl.Cache.NumUsrsWhoClaimToBelongToCtr.CtrCod, - FigCch_UNSIGNED,&Gbl.Cache.NumUsrsWhoClaimToBelongToCtr.NumUsrs); - return Ctr->NumUsrsWhoClaimToBelongToCtr.NumUsrs; - } - -unsigned Usr_GetCachedNumUsrsWhoClaimToBelongToCtr (struct Ctr_Center *Ctr) - { - unsigned NumUsrsCtr; - - /***** Get number of users who claim to belong to center from cache *****/ - if (!FigCch_GetFigureFromCache (FigCch_NUM_USRS_BELONG_CTR,HieLvl_CTR,Ctr->CtrCod, - FigCch_UNSIGNED,&NumUsrsCtr)) - /***** Get current number of users who claim to belong to center from database and update cache *****/ - NumUsrsCtr = Usr_GetNumUsrsWhoClaimToBelongToCtr (Ctr); - - return NumUsrsCtr; - } - /*****************************************************************************/ /******* Build query to get list with data of users in current course ********/ /*****************************************************************************/ @@ -6085,7 +5795,7 @@ void Usr_ListAllDataTchs (void) NumUsrs = Gbl.Usrs.LstUsrs[Rol_NET].NumUsrs + Gbl.Usrs.LstUsrs[Rol_TCH].NumUsrs; else - NumUsrs = Usr_GetNumUsrsInCrss (Gbl.Scope.Current, + NumUsrs = Enr_GetNumUsrsInCrss (Gbl.Scope.Current, (Gbl.Scope.Current == HieLvl_CTY ? Gbl.Hierarchy.Cty.CtyCod : (Gbl.Scope.Current == HieLvl_INS ? Gbl.Hierarchy.Ins.InsCod : (Gbl.Scope.Current == HieLvl_CTR ? Gbl.Hierarchy.Ctr.CtrCod : @@ -6810,7 +6520,7 @@ void Usr_SeeTeachers (void) NumUsrs = Gbl.Usrs.LstUsrs[Rol_NET].NumUsrs + Gbl.Usrs.LstUsrs[Rol_TCH].NumUsrs; else - NumUsrs = Usr_GetNumUsrsInCrss (Gbl.Scope.Current, + NumUsrs = Enr_GetNumUsrsInCrss (Gbl.Scope.Current, (Gbl.Scope.Current == HieLvl_CTY ? Gbl.Hierarchy.Cty.CtyCod : (Gbl.Scope.Current == HieLvl_INS ? Gbl.Hierarchy.Ins.InsCod : (Gbl.Scope.Current == HieLvl_CTR ? Gbl.Hierarchy.Ctr.CtrCod : @@ -7506,7 +7216,7 @@ void Usr_SeeTchClassPhotoPrn (void) NumUsrs = Gbl.Usrs.LstUsrs[Rol_NET].NumUsrs + Gbl.Usrs.LstUsrs[Rol_TCH].NumUsrs; else - NumUsrs = Usr_GetNumUsrsInCrss (Gbl.Scope.Current, + NumUsrs = Enr_GetNumUsrsInCrss (Gbl.Scope.Current, (Gbl.Scope.Current == HieLvl_CTY ? Gbl.Hierarchy.Cty.CtyCod : (Gbl.Scope.Current == HieLvl_INS ? Gbl.Hierarchy.Ins.InsCod : (Gbl.Scope.Current == HieLvl_CTR ? Gbl.Hierarchy.Ctr.CtrCod : @@ -7772,409 +7482,17 @@ unsigned Usr_GetTotalNumberOfUsers (void) (Gbl.Scope.Current == HieLvl_INS ? Gbl.Hierarchy.Ins.InsCod : (Gbl.Scope.Current == HieLvl_CTR ? Gbl.Hierarchy.Ctr.CtrCod : (Gbl.Scope.Current == HieLvl_DEG ? Gbl.Hierarchy.Deg.DegCod : - Gbl.Hierarchy.Crs.CrsCod)))); + Gbl.Hierarchy.Crs.CrsCod)))); Roles = (1 << Rol_STD) | (1 << Rol_NET) | (1 << Rol_TCH); - return Usr_GetCachedNumUsrsInCrss (Gbl.Scope.Current,Cod,Roles); // All users in courses + return Enr_GetCachedNumUsrsInCrss (Gbl.Scope.Current,Cod,Roles); // All users in courses default: Err_WrongScopeExit (); return 0; // Not reached } } -/*****************************************************************************/ -/******* Get total number of users of one or several roles in courses ********/ -/*****************************************************************************/ - -#define Usr_MAX_BYTES_SUBQUERY_ROLES (Rol_NUM_ROLES * (10 + 1) - 1) - -unsigned Usr_GetNumUsrsInCrss (HieLvl_Level_t Scope,long Cod,unsigned Roles) - { - char UnsignedStr[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; - char SubQueryRoles[Usr_MAX_BYTES_SUBQUERY_ROLES + 1]; - bool AnyUserInCourses; - Rol_Role_t Role; - Rol_Role_t FirstRoleRequested; - bool MoreThanOneRole; - bool FirstRole; - unsigned NumUsrs; - - /***** Reset roles that can not belong to courses. - Only - - students, - - non-editing teachers, - - teachers - can belong to a course *****/ - Roles &= ((1 << Rol_STD) | - (1 << Rol_NET) | - (1 << Rol_TCH)); - - /***** Check if no roles requested *****/ - if (Roles == 0) - return 0; - - /***** Check if any user in courses is requested *****/ - AnyUserInCourses = (Roles == ((1 << Rol_STD) | - (1 << Rol_NET) | - (1 << Rol_TCH))); - - /***** Get first role requested *****/ - FirstRoleRequested = Rol_UNK; - for (Role = Rol_STD; - Role <= Rol_TCH; - Role++) - if (Roles & (1 << Role)) - { - FirstRoleRequested = Role; - break; - } - - /***** Check if more than one role is requested *****/ - MoreThanOneRole = false; - if (FirstRoleRequested != Rol_UNK) - for (Role = FirstRoleRequested + 1; - Role <= Rol_TCH; - Role++) - if (Roles & (1 << Role)) - { - MoreThanOneRole = true; - break; - } - - /***** Build subquery for roles *****/ - if (MoreThanOneRole) - { - Str_Copy (SubQueryRoles," IN (",sizeof (SubQueryRoles) - 1); - for (Role = Rol_STD, FirstRole = true; - Role <= Rol_TCH; - Role++) - if (Roles & (1 << Role)) - { - snprintf (UnsignedStr,sizeof (UnsignedStr),"%u",(unsigned) Role); - if (FirstRole) // Not the first role - FirstRole = false; - else - Str_Concat (SubQueryRoles,",",sizeof (SubQueryRoles) - 1); - Str_Concat (SubQueryRoles,UnsignedStr,sizeof (SubQueryRoles) - 1); - } - Str_Concat (SubQueryRoles,")",sizeof (SubQueryRoles) - 1); - } - else // Only one role - sprintf (SubQueryRoles,"=%u",FirstRoleRequested); - - /***** Get number of users from database *****/ - switch (Scope) - { - case HieLvl_SYS: - if (AnyUserInCourses) // Any user - NumUsrs = (unsigned) - DB_QueryCOUNT ("can not get number of users", - "SELECT COUNT(DISTINCT UsrCod)" - " FROM crs_users"); - else - NumUsrs = (unsigned) - DB_QueryCOUNT ("can not get number of users", - "SELECT COUNT(DISTINCT UsrCod)" - " FROM crs_users" - " WHERE Role" - "%s", - SubQueryRoles); - break; - case HieLvl_CTY: - if (AnyUserInCourses) // Any user - NumUsrs = (unsigned) - DB_QueryCOUNT ("can not get number of users", - "SELECT COUNT(DISTINCT crs_users.UsrCod)" - " FROM ins_instits," - "ctr_centers," - "deg_degrees," - "crs_courses," - "crs_users" - " WHERE ins_instits.CtyCod=%ld" - " AND ins_instits.InsCod=ctr_centers.InsCod" - " AND ctr_centers.CtrCod=deg_degrees.CtrCod" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=crs_users.CrsCod", - Cod); - else - NumUsrs = (unsigned) - DB_QueryCOUNT ("can not get number of users", - "SELECT COUNT(DISTINCT crs_users.UsrCod)" - " FROM ins_instits," - "ctr_centers," - "deg_degrees," - "crs_courses," - "crs_users" - " WHERE ins_instits.CtyCod=%ld" - " AND ins_instits.InsCod=ctr_centers.InsCod" - " AND ctr_centers.CtrCod=deg_degrees.CtrCod" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " AND crs_users.Role" - "%s", - Cod, - SubQueryRoles); - break; - case HieLvl_INS: - if (AnyUserInCourses) // Any user - NumUsrs = (unsigned) - DB_QueryCOUNT ("can not get number of users", - "SELECT COUNT(DISTINCT crs_users.UsrCod)" - " FROM ctr_centers," - "deg_degrees," - "crs_courses," - "crs_users" - " WHERE ctr_centers.InsCod=%ld" - " AND ctr_centers.CtrCod=deg_degrees.CtrCod" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=crs_users.CrsCod", - Cod); - else - NumUsrs = (unsigned) - DB_QueryCOUNT ("can not get number of users", - "SELECT COUNT(DISTINCT crs_users.UsrCod)" - " FROM ctr_centers," - "deg_degrees," - "crs_courses," - "crs_users" - " WHERE ctr_centers.InsCod=%ld" - " AND ctr_centers.CtrCod=deg_degrees.CtrCod" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " AND crs_users.Role" - "%s", - Cod, - SubQueryRoles); - break; - case HieLvl_CTR: - if (AnyUserInCourses) // Any user - NumUsrs = (unsigned) - DB_QueryCOUNT ("can not get number of users", - "SELECT COUNT(DISTINCT crs_users.UsrCod)" - " FROM deg_degrees," - "crs_courses," - "crs_users" - " WHERE deg_degrees.CtrCod=%ld" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=crs_users.CrsCod", - Cod); - else - NumUsrs = (unsigned) - DB_QueryCOUNT ("can not get number of users", - "SELECT COUNT(DISTINCT crs_users.UsrCod)" - " FROM deg_degrees," - "crs_courses," - "crs_users" - " WHERE deg_degrees.CtrCod=%ld" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " AND crs_users.Role" - "%s", - Cod, - SubQueryRoles); - break; - case HieLvl_DEG: - if (AnyUserInCourses) // Any user - NumUsrs = (unsigned) - DB_QueryCOUNT ("can not get number of users", - "SELECT COUNT(DISTINCT crs_users.UsrCod)" - " FROM crs_courses," - "crs_users" - " WHERE crs_courses.DegCod=%ld" - " AND crs_courses.CrsCod=crs_users.CrsCod", - Cod); - else - NumUsrs = (unsigned) - DB_QueryCOUNT ("can not get number of users", - "SELECT COUNT(DISTINCT crs_users.UsrCod)" - " FROM crs_courses," - "crs_users" - " WHERE crs_courses.DegCod=%ld" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " AND crs_users.Role%s", - Cod,SubQueryRoles); - break; - case HieLvl_CRS: - if (AnyUserInCourses) // Any user - NumUsrs = (unsigned) - DB_QueryCOUNT ("can not get number of users", - "SELECT COUNT(DISTINCT UsrCod)" - " FROM crs_users" - " WHERE CrsCod=%ld", - Cod); - else - NumUsrs = (unsigned) - DB_QueryCOUNT ("can not get number of users", - "SELECT COUNT(DISTINCT UsrCod)" - " FROM crs_users" - " WHERE CrsCod=%ld" - " AND Role" - "%s", - Cod, - SubQueryRoles); - break; - default: - Err_WrongScopeExit (); - NumUsrs = 0; // Not reached. Initialized to avoid warning. - break; - } - - FigCch_UpdateFigureIntoCache (Usr_GetFigureNumUsrsInCrss (Roles),Scope,Cod, - FigCch_UNSIGNED,&NumUsrs); - return NumUsrs; - } - -unsigned Usr_GetCachedNumUsrsInCrss (HieLvl_Level_t Scope,long Cod,unsigned Roles) - { - unsigned NumUsrsInCrss; - - /***** Get number of users in courses from cache *****/ - if (!FigCch_GetFigureFromCache (Usr_GetFigureNumUsrsInCrss (Roles),Scope,Cod, - FigCch_UNSIGNED,&NumUsrsInCrss)) - /***** Get current number of users in courses from database and update cache *****/ - NumUsrsInCrss = Usr_GetNumUsrsInCrss (Scope,Cod,Roles); - - return NumUsrsInCrss; - } - -static FigCch_FigureCached_t Usr_GetFigureNumUsrsInCrss (unsigned Roles) - { - switch (Roles) - { - case 1 << Rol_STD: // Students - return FigCch_NUM_STDS_IN_CRSS; - case 1 << Rol_NET: // Non-editing teachers - return FigCch_NUM_NETS_IN_CRSS; - case 1 << Rol_TCH: // Teachers - return FigCch_NUM_TCHS_IN_CRSS; - case 1 << Rol_NET | - 1 << Rol_TCH: // Any teacher in courses - return FigCch_NUM_ALLT_IN_CRSS; - case 1 << Rol_STD | - 1 << Rol_NET | - 1 << Rol_TCH: // Any user in courses - return FigCch_NUM_USRS_IN_CRSS; - default: - Err_WrongRoleExit (); - return FigCch_UNKNOWN; // Not reached - } - } - -/*****************************************************************************/ -/******** Get total number of users who do not belong to any course **********/ -/*****************************************************************************/ - -unsigned Usr_GetCachedNumUsrsNotBelongingToAnyCrs (void) - { - unsigned NumGsts; - - /***** Get number of guests from cache *****/ - if (!FigCch_GetFigureFromCache (FigCch_NUM_GSTS,HieLvl_SYS,-1L, - FigCch_UNSIGNED,&NumGsts)) - { - /***** Get current number of guests from database and update cache *****/ - NumGsts = (unsigned) - DB_QueryCOUNT ("can not get number of users" - " who do not belong to any course", - "SELECT COUNT(*)" - " FROM usr_data" - " WHERE UsrCod NOT IN" - " (SELECT DISTINCT(UsrCod)" - " FROM crs_users)"); - FigCch_UpdateFigureIntoCache (FigCch_NUM_GSTS,HieLvl_SYS,-1L, - FigCch_UNSIGNED,&NumGsts); - } - - return NumGsts; - } - -/*****************************************************************************/ -/************ Get average number of courses with users of a type *************/ -/*****************************************************************************/ - -double Usr_GetCachedNumUsrsPerCrs (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role) - { - static const FigCch_FigureCached_t FigureNumUsrsPerCrs[Rol_NUM_ROLES] = - { - [Rol_UNK] = FigCch_NUM_USRS_PER_CRS, // Number of users per course - [Rol_STD] = FigCch_NUM_STDS_PER_CRS, // Number of students per course - [Rol_NET] = FigCch_NUM_NETS_PER_CRS, // Number of non-editing teachers per course - [Rol_TCH] = FigCch_NUM_TCHS_PER_CRS, // Number of teachers per course - }; - double NumUsrsPerCrs; - - /***** Get number of users per course from cache *****/ - if (!FigCch_GetFigureFromCache (FigureNumUsrsPerCrs[Role],Scope,Cod, - FigCch_DOUBLE,&NumUsrsPerCrs)) - { - /***** Get current number of users per course from database and update cache *****/ - NumUsrsPerCrs = Enr_DB_GetAverageNumUsrsPerCrs (Scope,Cod,Role); - FigCch_UpdateFigureIntoCache (FigureNumUsrsPerCrs[Role],Scope,Cod, - FigCch_DOUBLE,&NumUsrsPerCrs); - } - - return NumUsrsPerCrs; - } - -/*****************************************************************************/ -/************ Get average number of courses with users of a role *************/ -/*****************************************************************************/ - -double Usr_GetCachedNumCrssPerUsr (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role) - { - static const FigCch_FigureCached_t FigureNumCrssPerUsr[Rol_NUM_ROLES] = - { - [Rol_UNK] = FigCch_NUM_CRSS_PER_USR, // Number of courses per user - [Rol_STD] = FigCch_NUM_CRSS_PER_STD, // Number of courses per student - [Rol_NET] = FigCch_NUM_CRSS_PER_NET, // Number of courses per non-editing teacher - [Rol_TCH] = FigCch_NUM_CRSS_PER_TCH, // Number of courses per teacher - }; - double NumCrssPerUsr; - - /***** Get number of courses per user from cache *****/ - if (!FigCch_GetFigureFromCache (FigureNumCrssPerUsr[Role],Scope,Cod, - FigCch_DOUBLE,&NumCrssPerUsr)) - { - /***** Get current number of courses per user from database and update cache *****/ - NumCrssPerUsr = Enr_DB_GetAverageNumCrssPerUsr (Scope,Cod,Role); - FigCch_UpdateFigureIntoCache (FigureNumCrssPerUsr[Role],Scope,Cod, - FigCch_DOUBLE,&NumCrssPerUsr); - } - - return NumCrssPerUsr; - } - -/*****************************************************************************/ -/**************************** Show a user QR code ****************************/ -/*****************************************************************************/ - -void Usr_PrintUsrQRCode (void) - { - char NewNickWithArr[Nck_MAX_BYTES_NICK_WITH_ARROBA + 1]; - - if (Usr_GetParamOtherUsrCodEncryptedAndGetUsrData ()) - { - /***** Begin box *****/ - Box_BoxBegin (NULL,Gbl.Usrs.Other.UsrDat.FullName, - NULL,NULL, - NULL,Box_NOT_CLOSABLE); - - /***** Show QR code *****/ - if (Gbl.Usrs.Other.UsrDat.Nickname[0]) - { - snprintf (NewNickWithArr,sizeof (NewNickWithArr),"@%s", - Gbl.Usrs.Other.UsrDat.Nickname); - QR_ImageQRCode (NewNickWithArr); - } - - /***** End box *****/ - Box_BoxEnd (); - } - else - Ale_ShowAlertUserNotFoundOrYouDoNotHavePermission (); - } - /*****************************************************************************/ /********************* Write the author of an assignment *********************/ /*****************************************************************************/ @@ -8258,7 +7576,7 @@ void Usr_ShowTableCellWithUsrData (struct UsrData *UsrDat,unsigned NumRows) /* Begin form to go to user's record card */ Frm_BeginForm (NextAction); Usr_PutParamUsrCodEncrypted (UsrDat->EnUsrCod); - HTM_BUTTON_SUBMIT_Begin (UsrDat->FullName,"BT_LINK LT AUTHOR_TXT",NULL); + HTM_BUTTON_SUBMIT_Begin (UsrDat->FullName,"BT_LINK LT AUTHOR_TXT",NULL); } /* User's ID */ @@ -8282,7 +7600,7 @@ void Usr_ShowTableCellWithUsrData (struct UsrData *UsrDat,unsigned NumRows) else { /* End form */ - HTM_BUTTON_End (); + HTM_BUTTON_End (); Frm_EndForm (); } diff --git a/swad_user.h b/swad_user.h index 1f5db56f..18f0ad59 100644 --- a/swad_user.h +++ b/swad_user.h @@ -346,26 +346,6 @@ void Usr_WriteRowUsrMainData (unsigned NumUsr,struct UsrData *UsrDat, bool PutCheckBoxToSelectUsr,Rol_Role_t Role, struct SelectedUsrs *SelectedUsrs); -void Usr_FlushCacheNumUsrsWhoDontClaimToBelongToAnyCty (void); -unsigned Usr_GetNumUsrsWhoDontClaimToBelongToAnyCty (void); -unsigned Usr_GetCachedNumUsrsWhoDontClaimToBelongToAnyCty (void); - -void Usr_FlushCacheNumUsrsWhoClaimToBelongToAnotherCty (void); -unsigned Usr_GetNumUsrsWhoClaimToBelongToAnotherCty (void); -unsigned Usr_GetCachedNumUsrsWhoClaimToBelongToAnotherCty (void); - -void Usr_FlushCacheNumUsrsWhoClaimToBelongToCty (void); -unsigned Usr_GetNumUsrsWhoClaimToBelongToCty (struct Cty_Countr *Cty); -unsigned Usr_GetCachedNumUsrsWhoClaimToBelongToCty (struct Cty_Countr *Cty); - -void Usr_FlushCacheNumUsrsWhoClaimToBelongToIns (void); -unsigned Usr_GetNumUsrsWhoClaimToBelongToIns (struct Ins_Instit *Ins); -unsigned Usr_GetCachedNumUsrsWhoClaimToBelongToIns (struct Ins_Instit *Ins); - -void Usr_FlushCacheNumUsrsWhoClaimToBelongToCtr (void); -unsigned Usr_GetNumUsrsWhoClaimToBelongToCtr (struct Ctr_Center *Ctr); -unsigned Usr_GetCachedNumUsrsWhoClaimToBelongToCtr (struct Ctr_Center *Ctr); - void Usr_GetListUsrs (HieLvl_Level_t Scope,Rol_Role_t Role); void Usr_SearchListUsrs (Rol_Role_t Role); @@ -447,15 +427,6 @@ void Usr_ConstructPathUsr (long UsrCod,char PathUsr[PATH_MAX + 1 + Cns_MAX_DECIM void Usr_ShowWarningNoUsersFound (Rol_Role_t Role); unsigned Usr_GetTotalNumberOfUsers (void); -unsigned Usr_GetNumUsrsInCrss (HieLvl_Level_t Scope,long Cod,unsigned Roles); -unsigned Usr_GetCachedNumUsrsInCrss (HieLvl_Level_t Scope,long Cod,unsigned Roles); - -unsigned Usr_GetCachedNumUsrsNotBelongingToAnyCrs (void); - -double Usr_GetCachedNumUsrsPerCrs (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role); -double Usr_GetCachedNumCrssPerUsr (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role); - -void Usr_PrintUsrQRCode (void); void Usr_WriteAuthor1Line (long UsrCod,bool Hidden); diff --git a/swad_user_database.c b/swad_user_database.c index 97e49416..ec38aeaa 100644 --- a/swad_user_database.c +++ b/swad_user_database.c @@ -342,3 +342,41 @@ void Usr_DB_RemoveUsrData (long UsrCod) " WHERE UsrCod=%ld", UsrCod); } + +/*****************************************************************************/ +/*** Insert my user's code in the table of birthdays already congratulated ***/ +/*****************************************************************************/ + +void Usr_DB_MarkMyBirthdayAsCongratulated (void) + { + DB_QueryINSERT ("can not insert birthday", + "INSERT INTO usr_birthdays_today" + " (UsrCod,Today)" + " VALUES" + " (%ld,CURDATE())", + Gbl.Usrs.Me.UsrDat.UsrCod); + } + +/*****************************************************************************/ +/*************** Check if my birthday is already congratulated ***************/ +/*****************************************************************************/ + +bool Usr_DB_CheckIfMyBirthdayHasNotBeenCongratulated (void) + { + return (DB_QueryCOUNT ("can not check if my birthday has been congratulated", + "SELECT COUNT(*)" + " FROM usr_birthdays_today" + " WHERE UsrCod=%ld", + Gbl.Usrs.Me.UsrDat.UsrCod) == 0); + } + +/*****************************************************************************/ +/****************************** Delete old birthdays *************************/ +/*****************************************************************************/ + +void Usr_DB_DeleteOldBirthdays (void) + { + DB_QueryDELETE ("can not delete old birthdays", + "DELETE FROM usr_birthdays_today" + " WHERE Today<>CURDATE()"); + } diff --git a/swad_user_database.h b/swad_user_database.h index 0897b312..b02d1f95 100644 --- a/swad_user_database.h +++ b/swad_user_database.h @@ -74,4 +74,9 @@ unsigned Usr_DB_GetOldUsrs (MYSQL_RES **mysql_res,time_t SecondsWithoutAccess); void Usr_DB_RemoveUsrLastData (long UsrCod); void Usr_DB_RemoveUsrData (long UsrCod); +//------------------------------ Birthdays today ------------------------------ +void Usr_DB_MarkMyBirthdayAsCongratulated (void); +bool Usr_DB_CheckIfMyBirthdayHasNotBeenCongratulated (void); +void Usr_DB_DeleteOldBirthdays (void); + #endif