Version 16.247

This commit is contained in:
Antonio Cañas Vargas 2017-06-20 14:43:26 +02:00
parent 500bd55ca7
commit f639ebb425
19 changed files with 627 additions and 499 deletions

View File

@ -1002,7 +1002,7 @@ void Acc_CompletelyEliminateAccount (struct UsrData *UsrDat,
Att_RemoveUsrFromAllAttEvents (UsrDat->UsrCod);
/***** Remove user from all the groups of all courses *****/
Grp_RemUsrFromAllGrps (UsrDat);
Grp_RemUsrFromAllGrps (UsrDat->UsrCod);
/***** Remove user's requests for inscription *****/
sprintf (Query,"DELETE FROM crs_usr_requests WHERE UsrCod=%ld",

View File

@ -236,13 +236,15 @@
/****************************** Public constants *****************************/
/*****************************************************************************/
#define Log_PLATFORM_VERSION "SWAD 16.246 (2017-06-20)"
#define Log_PLATFORM_VERSION "SWAD 16.247 (2017-06-20)"
#define CSS_FILE "swad16.235.1.css"
#define JS_FILE "swad16.206.3.js"
// Number of lines (includes comments but not blank lines) has been got with the following command:
// nl swad*.c swad*.h css/swad*.css py/swad*.py js/swad*.js soap/swad*?.h sql/swad*.sql | tail -1
/*
Version 16.247: Jun 20, 2017 Fixed bug when removing a user from a course.
Code refactoring related with caches. (222063 lines)
Version 16.246: Jun 20, 2017 Fixed bugs and code refactoring in groups. (221975 lines)
Version 16.245: Jun 12, 2017 Place editable in centre configuration. (221876 lines)
Version 16.244.1: Jun 12, 2017 Fix bug in edition of centres. (221817 lines)

View File

@ -287,7 +287,7 @@ void Con_GetAndShowLastClicks (void)
/* Get institution code (row[5]) */
Ins.InsCod = Str_ConvertStrCodToLongCod (row[5]);
Ins_GetShortNameOfInstitutionByCod (&Ins);
Ins_GetShortNameOfInstitution (&Ins);
/* Get centre code (row[6]) */
Ctr.CtrCod = Str_ConvertStrCodToLongCod (row[6]);

View File

@ -1403,53 +1403,56 @@ bool Cty_GetDataOfCountryByCod (struct Country *Cty,Cty_GetExtraData_t GetExtraD
/***************************** Get country name ******************************/
/*****************************************************************************/
void Cty_FlushCacheCountryName (void)
{
Gbl.Cache.CountryName.CtyCod = -1L;
Gbl.Cache.CountryName.CtyName[0] = '\0';
}
void Cty_GetCountryName (long CtyCod,char CtyName[Cty_MAX_BYTES_NAME + 1])
{
extern const char *Txt_STR_LANG_ID[1 + Txt_NUM_LANGUAGES];
char Query[128];
MYSQL_RES *mysql_res;
MYSQL_ROW row;
static struct
{
long CtyCod;
char CtyName[Cty_MAX_BYTES_NAME + 1];
} Cached =
{
-1L,
{'\0'}
};
/***** Check if country code is correct *****/
/***** 1. Fast check: Trivial case *****/
if (CtyCod <= 0)
CtyName[0] = '\0'; // Empty name
else
{
if (CtyCod != Cached.CtyCod) // If not cached...
{
Cached.CtyCod = CtyCod;
CtyName[0] = '\0'; // Empty name
return;
}
/***** Get name of the country from database *****/
sprintf (Query,"SELECT Name_%s FROM countries WHERE CtyCod='%03ld'",
Txt_STR_LANG_ID[Gbl.Prefs.Language],CtyCod);
if (DB_QuerySELECT (Query,&mysql_res,"can not get the name of a country")) // Country found...
{
/* Get row */
row = mysql_fetch_row (mysql_res);
/***** 2. Fast check: If cached... *****/
if (CtyCod == Gbl.Cache.CountryName.CtyCod)
{
Str_Copy (CtyName,Gbl.Cache.CountryName.CtyName,
Cty_MAX_BYTES_NAME);
return;
}
/* Get the name of the country */
Str_Copy (Cached.CtyName,row[0],
Cty_MAX_BYTES_NAME);
}
else
Cached.CtyName[0] = '\0';
/***** 3. Slow: get country name from database *****/
Gbl.Cache.CountryName.CtyCod = CtyCod;
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
sprintf (Query,"SELECT Name_%s FROM countries WHERE CtyCod='%03ld'",
Txt_STR_LANG_ID[Gbl.Prefs.Language],CtyCod);
if (DB_QuerySELECT (Query,&mysql_res,"can not get the name of a country")) // Country found...
{
/* Get row */
row = mysql_fetch_row (mysql_res);
Str_Copy (CtyName,Cached.CtyName,
/* Get the name of the country */
Str_Copy (Gbl.Cache.CountryName.CtyName,row[0],
Cty_MAX_BYTES_NAME);
}
else
Gbl.Cache.CountryName.CtyName[0] = '\0';
/* Free structure that stores the query result */
DB_FreeMySQLResult (&mysql_res);
Str_Copy (CtyName,Gbl.Cache.CountryName.CtyName,
Cty_MAX_BYTES_NAME);
}
/*****************************************************************************/
@ -1703,6 +1706,9 @@ void Cty_RemoveCountry (void)
Cty.CtyCod);
DB_QueryDELETE (Query,"can not remove a country");
/***** Flush cache *****/
Cty_FlushCacheCountryName ();
/***** Write message to show the change made *****/
sprintf (Gbl.Alert.Txt,Txt_Country_X_removed,
Cty.Name[Gbl.Prefs.Language]);
@ -1846,6 +1852,9 @@ static void Cty_UpdateCtyNameDB (long CtyCod,const char *FieldName,const char *N
sprintf (Query,"UPDATE countries SET %s='%s' WHERE CtyCod='%03ld'",
FieldName,NewCtyName,CtyCod);
DB_QueryUPDATE (Query,"can not update the name of a country");
/***** Flush cache *****/
Cty_FlushCacheCountryName ();
}
/*****************************************************************************/

View File

@ -99,6 +99,7 @@ void Cty_FreeListCountries (void);
void Cty_WriteSelectorOfCountry (void);
void Cty_WriteCountryName (long CtyCod,const char *ClassLink);
bool Cty_GetDataOfCountryByCod (struct Country *Cty,Cty_GetExtraData_t GetExtraData);
void Cty_FlushCacheCountryName (void);
void Cty_GetCountryName (long CtyCod,char CtyName[Cty_MAX_BYTES_NAME + 1]);
void Cty_PutParamCtyCod (long CtyCod);
long Cty_GetAndCheckParamOtherCtyCod (long MinCodAllowed);

View File

@ -175,8 +175,8 @@ void Enr_PutButtonInlineToRegisterStds (long CrsCod)
{
extern const char *Txt_Register_students;
if (Rol_GetRoleInCrs (CrsCod,Gbl.Usrs.Me.UsrDat.UsrCod) == Rol_TCH) // I am a teacher in course
if (!Usr_GetNumUsrsInCrs (Rol_STD,CrsCod)) // No students in course
if (Rol_GetRoleUsrInCrs (Gbl.Usrs.Me.UsrDat.UsrCod,CrsCod) == Rol_TCH) // I am a teacher in course
if (!Usr_GetNumUsrsInCrs (Rol_STD,CrsCod)) // No students in course
{
Act_FormStart (ActReqEnrSevStd);
Crs_PutParamCrsCod (CrsCod);
@ -231,7 +231,7 @@ void Enr_ModifyRoleInCurrentCrs (struct UsrData *UsrDat,Rol_Role_t NewRole)
Enr_NotifyAfterEnrolment (UsrDat,NewRole);
UsrDat->Roles.InCurrentCrs.Role = NewRole;
UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = UsrDat->UsrCod;
UsrDat->Roles.InCrss = -1; // Force roles to be got from database
Rol_GetRolesInAllCrssIfNotYetGot (UsrDat); // Get roles
}
@ -280,7 +280,7 @@ void Enr_RegisterUsrInCurrentCrs (struct UsrData *UsrDat,Rol_Role_t NewRole,
'N');
DB_QueryINSERT (Query,"can not register user in course");
UsrDat->Roles.InCurrentCrs.Role = NewRole;
UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = UsrDat->UsrCod;
UsrDat->Roles.InCrss = -1; // Force roles to be got from database
Rol_GetRolesInAllCrssIfNotYetGot (UsrDat); // Get roles
@ -3024,7 +3024,7 @@ void Enr_PutLinkToAdminOneUsr (Act_Action_t NextAction)
extern const char *Txt_Administer_me;
extern const char *Txt_Administer_one_user;
const char *TitleText = Enr_ICanAdminOtherUsrs[Gbl.Usrs.Me.Role.Logged] ? Txt_Administer_one_user :
Txt_Administer_me;
Txt_Administer_me;
Lay_PutContextualLink (NextAction,NULL,NULL,
"config64x64.gif",
@ -3922,7 +3922,7 @@ void Enr_ModifyUsr1 (void)
if (ItsMe)
{
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role = Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs.Role;
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.UsrCod = Gbl.Usrs.Other.UsrDat.UsrCod;
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.GotFromDBForUsrCod = Gbl.Usrs.Other.UsrDat.UsrCod;
Gbl.Usrs.Me.UsrDat.Roles.InCrss = Gbl.Usrs.Other.UsrDat.Roles.InCrss;
Rol_SetMyRoles ();
}
@ -4134,7 +4134,7 @@ static void Enr_EffectivelyRemUsrFromCrs (struct UsrData *UsrDat,struct Course *
extern const char *Txt_THE_USER_X_has_been_removed_from_the_course_Y;
extern const char *Txt_User_not_found_or_you_do_not_have_permission_;
char Query[1024];
bool ItsMe;
bool ItsMe = (UsrDat->UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod);
if (Usr_CheckIfUsrBelongsToCurrentCrs (UsrDat))
{
@ -4142,7 +4142,7 @@ static void Enr_EffectivelyRemUsrFromCrs (struct UsrData *UsrDat,struct Course *
Att_RemoveUsrFromCrsAttEvents (UsrDat->UsrCod,Crs->CrsCod);
/***** Remove user from all the groups in course *****/
Grp_RemUsrFromAllGrpsInCrs (UsrDat,Crs);
Grp_RemUsrFromAllGrpsInCrs (UsrDat->UsrCod,Crs->CrsCod);
/***** Remove user's status about reading of course information *****/
Inf_RemoveUsrFromCrsInfoRead (UsrDat->UsrCod,Crs->CrsCod);
@ -4170,13 +4170,44 @@ static void Enr_EffectivelyRemUsrFromCrs (struct UsrData *UsrDat,struct Course *
Crs->CrsCod,UsrDat->UsrCod);
DB_QueryDELETE (Query,"can not remove a user from a course");
/***** Flush caches *****/
Usr_FlushCacheUsrBelongsToIns ();
Usr_FlushCacheUsrBelongsToCtr ();
Usr_FlushCacheUsrBelongsToDeg ();
Usr_FlushCacheUsrBelongsToCrs ();
Usr_FlushCacheUsrBelongsToCurrentCrs ();
Usr_FlushCacheUsrHasAcceptedInCurrentCrs ();
Usr_FlushCacheUsrSharesAnyOfMyCrs ();
Rol_FlushCacheRoleUsrInCrs ();
Grp_FlushCacheUsrSharesAnyOfMyGrpsInCurrentCrs ();
/***** If it's me, change my roles *****/
ItsMe = (UsrDat->UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod);
if (ItsMe)
{
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role = UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.UsrCod = UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
Gbl.Usrs.Me.UsrDat.Roles.InCrss = UsrDat->Roles.InCrss = -1; // not yet filled/calculated
/* Flush caches */
Grp_FlushCacheIBelongToGrp ();
/* Now I don't belong to current course */
Gbl.Usrs.Me.IBelongToCurrentCrs =
Gbl.Usrs.Me.UsrDat.Accepted = false;
/* Fill the list with the courses I belong to */
Gbl.Usrs.Me.MyCrss.Filled = false;
Usr_GetMyCourses ();
/* Set my roles */
Gbl.Usrs.Me.Role.FromSession =
Gbl.Usrs.Me.Role.Logged =
Gbl.Usrs.Me.Role.LoggedBeforeCloseSession =
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role =
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.GotFromDBForUsrCod =
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = UsrDat->UsrCod;
Gbl.Usrs.Me.UsrDat.Roles.InCrss =
UsrDat->Roles.InCrss = -1; // not yet filled/calculated
Rol_SetMyRoles ();
}

View File

@ -42,6 +42,7 @@
#include "swad_icon.h"
#include "swad_parameter.h"
#include "swad_preference.h"
#include "swad_role.h"
#include "swad_theme.h"
#include "swad_web_service.h"
@ -440,6 +441,22 @@ void Gbl_InitializeGlobals (void)
Gbl.WebService.Function = Svc_unknown;
Gbl.Layout.NestedBox = 0;
/* Flush caches */
Cty_FlushCacheCountryName ();
Ins_FlushCacheShortNameOfInstitution ();
Ins_FlushCacheFullNameAndCtyOfInstitution ();
Usr_FlushCacheUsrIsSuperuser ();
Usr_FlushCacheUsrBelongsToIns ();
Usr_FlushCacheUsrBelongsToCtr ();
Usr_FlushCacheUsrBelongsToDeg ();
Usr_FlushCacheUsrBelongsToCrs ();
Usr_FlushCacheUsrBelongsToCurrentCrs ();
Usr_FlushCacheUsrHasAcceptedInCurrentCrs ();
Usr_FlushCacheUsrSharesAnyOfMyCrs ();
Rol_FlushCacheRoleUsrInCrs ();
Grp_FlushCacheIBelongToGrp ();
Grp_FlushCacheUsrSharesAnyOfMyGrpsInCurrentCrs ();
}
/*****************************************************************************/

View File

@ -747,6 +747,88 @@ struct Globals
{
char *Str;
} QR;
/* Cache */
struct
{
struct
{
long CtyCod;
char CtyName[Cty_MAX_BYTES_NAME + 1];
} CountryName;
struct
{
long InsCod;
char ShrtName[Hie_MAX_BYTES_SHRT_NAME + 1];
} InstitutionShrtName;
struct
{
long InsCod;
char FullName[Hie_MAX_BYTES_FULL_NAME + 1];
char CtyName[Hie_MAX_BYTES_FULL_NAME + 1];
} InstitutionFullNameAndCty;
struct
{
long UsrCod;
bool IsSuperuser;
} UsrIsSuperuser;
struct
{
long UsrCod;
long InsCod;
bool Belongs;
} UsrBelongsToIns;
struct
{
long UsrCod;
long CtrCod;
bool Belongs;
} UsrBelongsToCtr;
struct
{
long UsrCod;
long DegCod;
bool Belongs;
} UsrBelongsToDeg;
struct
{
long UsrCod;
long CrsCod;
bool CountOnlyAcceptedCourses;
bool Belongs;
} UsrBelongsToCrs;
struct
{
long UsrCod;
bool Belongs;
} UsrBelongsToCurrentCrs;
struct
{
long UsrCod;
bool Accepted;
} UsrHasAcceptedInCurrentCrs;
struct
{
long UsrCod;
bool SharesAnyOfMyCrs;
} UsrSharesAnyOfMyCrs;
struct
{
long GrpCod;
bool IBelong;
} IBelongToGrp;
struct
{
long UsrCod;
bool Shares;
} UsrSharesAnyOfMyGrpsInCurrentCrs;
struct
{
long UsrCod;
long CrsCod;
Rol_Role_t Role;
} RoleUsrInCrs;
} Cache;
};
/*****************************************************************************/

View File

@ -1130,7 +1130,9 @@ unsigned Grp_RemoveUsrFromGroups (struct UsrData *UsrDat,struct ListCodGrps *Lst
extern const char *Txt_THE_USER_X_has_been_removed_from_one_group;
extern const char *Txt_THE_USER_X_has_been_removed_from_Y_groups;
struct ListCodGrps LstGrpsHeBelongs;
unsigned NumGrpSel,NumGrpHeBelongs,NumGrpsHeIsRemoved = 0;
unsigned NumGrpSel;
unsigned NumGrpHeBelongs;
unsigned NumGrpsHeIsRemoved = 0;
/***** Query in the database the group codes of any group the user belongs to *****/
Grp_GetLstCodGrpsUsrBelongs (Gbl.CurrentCrs.Crs.CrsCod,-1L,
@ -1173,9 +1175,10 @@ unsigned Grp_RemoveUsrFromGroups (struct UsrData *UsrDat,struct ListCodGrps *Lst
/*************** Remove a user of all the groups of a course *****************/
/*****************************************************************************/
void Grp_RemUsrFromAllGrpsInCrs (struct UsrData *UsrDat,struct Course *Crs)
void Grp_RemUsrFromAllGrpsInCrs (long UsrCod,long CrsCod)
{
char Query[512];
bool ItsMe = (UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod);
/***** Remove user from all the groups of the course *****/
sprintf (Query,"DELETE FROM crs_grp_usr"
@ -1183,22 +1186,33 @@ void Grp_RemUsrFromAllGrpsInCrs (struct UsrData *UsrDat,struct Course *Crs)
" (SELECT crs_grp.GrpCod FROM crs_grp_types,crs_grp"
" WHERE crs_grp_types.CrsCod=%ld"
" AND crs_grp_types.GrpTypCod=crs_grp.GrpTypCod)",
UsrDat->UsrCod,Crs->CrsCod);
UsrCod,CrsCod);
DB_QueryDELETE (Query,"can not remove a user from all groups of a course");
/***** Flush caches *****/
Grp_FlushCacheUsrSharesAnyOfMyGrpsInCurrentCrs ();
if (ItsMe)
Grp_FlushCacheIBelongToGrp ();
}
/*****************************************************************************/
/******* Remove a user from all the groups of all the user's courses *********/
/*****************************************************************************/
void Grp_RemUsrFromAllGrps (struct UsrData *UsrDat)
void Grp_RemUsrFromAllGrps (long UsrCod)
{
char Query[128];
bool ItsMe = (UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod);
/***** Remove user from all groups *****/
sprintf (Query,"DELETE FROM crs_grp_usr WHERE UsrCod=%ld",
UsrDat->UsrCod);
UsrCod);
DB_QueryDELETE (Query,"can not remove a user from the groups he/she belongs to");
/***** Flush caches *****/
Grp_FlushCacheUsrSharesAnyOfMyGrpsInCurrentCrs ();
if (ItsMe)
Grp_FlushCacheIBelongToGrp ();
}
/*****************************************************************************/
@ -1208,12 +1222,18 @@ void Grp_RemUsrFromAllGrps (struct UsrData *UsrDat)
static void Grp_RemoveUsrFromGroup (long UsrCod,long GrpCod)
{
char Query[256];
bool ItsMe = (UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod);
/***** Remove user from group *****/
sprintf (Query,"DELETE FROM crs_grp_usr"
" WHERE GrpCod=%ld AND UsrCod=%ld",
GrpCod,UsrCod);
DB_QueryDELETE (Query,"can not remove a user from a group");
/***** Flush caches *****/
Grp_FlushCacheUsrSharesAnyOfMyGrpsInCurrentCrs ();
if (ItsMe)
Grp_FlushCacheIBelongToGrp ();
}
/*****************************************************************************/
@ -3230,35 +3250,104 @@ static long Grp_GetFirstCodGrpIBelongTo (long GrpTypCod)
}
/*****************************************************************************/
/********************* Check if a user belongs to a group ********************/
/************************ Check if I belong to a group ***********************/
/*****************************************************************************/
// Return true if the user identificado belongs al group with código GrpCod
// Return true if I belong to group with code GrpCod
void Grp_FlushCacheIBelongToGrp (void)
{
Gbl.Cache.IBelongToGrp.GrpCod = -1L;
Gbl.Cache.IBelongToGrp.IBelong = false;
}
bool Grp_GetIfIBelongToGrp (long GrpCod)
{
char Query[256];
static struct
{
long GrpCod;
bool IBelongToGrp;
} Cached =
{
-1L,
false
}; // A cache. If this function is called consecutive times
// with the same group, only the first time is slow
/***** 1. Fast check: Is already calculated if I belong to group? *****/
if (GrpCod == Cached.GrpCod)
return Cached.IBelongToGrp;
/***** 1. Fast check: Trivial case *****/
if (GrpCod <= 0)
return false;
/***** 2. Slow check: Get if I belong to a group from database *****/
/***** 2. Fast check: Is already calculated if I belong to group? *****/
if (GrpCod == Gbl.Cache.IBelongToGrp.GrpCod)
return Gbl.Cache.IBelongToGrp.IBelong;
/***** 3. Slow check: Get if I belong to a group from database *****/
sprintf (Query,"SELECT COUNT(*) FROM crs_grp_usr"
" WHERE GrpCod=%ld AND UsrCod=%ld",
GrpCod,Gbl.Usrs.Me.UsrDat.UsrCod);
Cached.IBelongToGrp = DB_QueryCOUNT (Query,"can not check if you belong to a group") != 0;
Cached.GrpCod = GrpCod;
return Cached.IBelongToGrp;
Gbl.Cache.IBelongToGrp.IBelong = DB_QueryCOUNT (Query,"can not check if you belong to a group") != 0;
Gbl.Cache.IBelongToGrp.GrpCod = GrpCod;
return Gbl.Cache.IBelongToGrp.IBelong;
}
/*****************************************************************************/
/*************** Check if a user belongs to any of my courses ****************/
/*****************************************************************************/
void Grp_FlushCacheUsrSharesAnyOfMyGrpsInCurrentCrs (void)
{
Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.UsrCod = -1L;
Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.Shares = false;
}
bool Grp_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (const struct UsrData *UsrDat)
{
char Query[512];
/***** 1. Fast check: Am I logged? *****/
if (!Gbl.Usrs.Me.Logged)
return false;
/***** 2. Fast check: Is it a valid user code? *****/
if (UsrDat->UsrCod <= 0)
return false;
/***** 3. Fast check: Is it a course selected? *****/
if (Gbl.CurrentCrs.Crs.CrsCod <= 0)
return false;
/***** 4. Fast check: Do I belong to the current course? *****/
if (!Gbl.Usrs.Me.IBelongToCurrentCrs)
return false;
/***** 5. Fast check: It's me? *****/
if (Gbl.Usrs.Me.UsrDat.UsrCod == UsrDat->UsrCod)
return true;
/***** 6. Fast check: Is already calculated if user shares
any group in the current course with me? *****/
if (UsrDat->UsrCod == Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.UsrCod)
return Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.Shares;
/***** 7. Fast / slow check: Does he/she belong to the current course? *****/
if (!Usr_CheckIfUsrBelongsToCurrentCrs (UsrDat))
{
Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.UsrCod = UsrDat->UsrCod;
Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.Shares = false;
return false;
}
/***** 8. Slow check: Get if user shares any group in this course with me from database *****/
/* Check if user shares any group with me */
Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.UsrCod = UsrDat->UsrCod;
sprintf (Query,"SELECT COUNT(*) FROM crs_grp_usr"
" WHERE UsrCod=%ld"
" AND GrpCod IN"
" (SELECT crs_grp_usr.GrpCod"
" FROM crs_grp_usr,crs_grp,crs_grp_types"
" WHERE crs_grp_usr.UsrCod=%ld"
" AND crs_grp_usr.GrpCod=crs_grp.GrpCod"
" AND crs_grp.GrpTypCod=crs_grp_types.GrpTypCod"
" AND crs_grp_types.CrsCod=%ld)",
UsrDat->UsrCod,
Gbl.Usrs.Me.UsrDat.UsrCod,
Gbl.CurrentCrs.Crs.CrsCod);
Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.Shares = DB_QueryCOUNT (Query,"can not check"
" if a user shares any group"
" in the current course with you") != 0;
return Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.Shares;
}
/*****************************************************************************/
@ -4791,71 +4880,3 @@ void Grp_GetParamWhichGrps (void)
AlreadyGot = true;
}
}
/*****************************************************************************/
/*************** Check if a user belongs to any of my courses ****************/
/*****************************************************************************/
bool Grp_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (const struct UsrData *UsrDat)
{
char Query[512];
static struct
{
long UsrCod;
bool UsrSharesAnyOfMyGrpsInCurrentCrs;
} Cached =
{
-1L,
false
}; // A cache. If this function is called consecutive times
// with the same user, only the first time is slow
/***** 1. Fast check: Am I logged? *****/
if (!Gbl.Usrs.Me.Logged)
return false;
/***** 2. Fast check: Is it a valid user code? *****/
if (UsrDat->UsrCod <= 0)
return false;
/***** 3. Fast check: Is it a course selected? *****/
if (Gbl.CurrentCrs.Crs.CrsCod <= 0)
return false;
/***** 4. Fast check: Do I belong to the current course? *****/
if (!Gbl.Usrs.Me.IBelongToCurrentCrs)
return false;
/***** 5. Fast check: It's me? *****/
if (Gbl.Usrs.Me.UsrDat.UsrCod == UsrDat->UsrCod)
return true;
/***** 6. Fast check: Does he/she belong to the current course? *****/
if (!Usr_CheckIfUsrBelongsToCurrentCrs (UsrDat))
return false;
/***** 7. Fast check: Is already calculated if user shares
any group in the current course with me? *****/
if (UsrDat->UsrCod == Cached.UsrCod)
return Cached.UsrSharesAnyOfMyGrpsInCurrentCrs;
/***** 8. Slow check: Get if user shares any group in this course with me from database *****/
/* Check if user shares any group with me */
Cached.UsrCod = UsrDat->UsrCod;
sprintf (Query,"SELECT COUNT(*) FROM crs_grp_usr"
" WHERE UsrCod=%ld"
" AND GrpCod IN"
" (SELECT crs_grp_usr.GrpCod"
" FROM crs_grp_usr,crs_grp,crs_grp_types"
" WHERE crs_grp_usr.UsrCod=%ld"
" AND crs_grp_usr.GrpCod=crs_grp.GrpCod"
" AND crs_grp.GrpTypCod=crs_grp_types.GrpTypCod"
" AND crs_grp_types.CrsCod=%ld)",
UsrDat->UsrCod,
Gbl.Usrs.Me.UsrDat.UsrCod,
Gbl.CurrentCrs.Crs.CrsCod);
Cached.UsrSharesAnyOfMyGrpsInCurrentCrs = DB_QueryCOUNT (Query,"can not check"
" if a user shares any group"
" in the current course with you") != 0;
return Cached.UsrSharesAnyOfMyGrpsInCurrentCrs;
}

View File

@ -148,8 +148,8 @@ void Grp_ChangeGrpsOtherUsrAtomically (struct ListCodGrps *LstGrpsUsrWants);
bool Grp_CheckIfSelectionGrpsSingleEnrolmentIsValid (Rol_Role_t Role,struct ListCodGrps *LstGrps);
void Grp_RegisterUsrIntoGroups (struct UsrData *UsrDat,struct ListCodGrps *LstGrps);
unsigned Grp_RemoveUsrFromGroups (struct UsrData *UsrDat,struct ListCodGrps *LstGrps);
void Grp_RemUsrFromAllGrpsInCrs (struct UsrData *UsrDat,struct Course *Crs);
void Grp_RemUsrFromAllGrps (struct UsrData *UsrDat);
void Grp_RemUsrFromAllGrpsInCrs (long UsrCod,long CrsCod);
void Grp_RemUsrFromAllGrps (long UsrCod);
void Grp_ListGrpsToEditAsgAttOrSvy (struct GroupType *GrpTyp,long Cod,Grp_AsgOrSvy_t Grp_AsgOrSvy);
void Grp_ReqRegisterInGrps (void);
@ -166,7 +166,12 @@ void Grp_GetDataOfGroupByCod (struct GroupData *GrpDat);
bool Grp_CheckIfGroupExists (long GrpCod);
bool Grp_CheckIfGroupBelongsToCourse (long GrpCod,long CrsCod);
unsigned Grp_CountNumUsrsInGrp (Rol_Role_t Role,long GrpCod);
void Grp_FlushCacheIBelongToGrp (void);
bool Grp_GetIfIBelongToGrp (long GrpCod);
void Grp_FlushCacheUsrSharesAnyOfMyGrpsInCurrentCrs (void);
bool Grp_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (const struct UsrData *UsrDat);
unsigned Grp_NumGrpTypesMandatIDontBelongAsStd (void);
void Grp_GetLstCodGrpsWithFileZonesIBelong (struct ListCodGrps *LstGrps);
void Grp_GetNamesGrpsStdBelongsTo (long GrpTypCod,long UsrCod,char *GrpNames);
@ -199,6 +204,4 @@ void Grp_PutParamWhichGrpsAllGrps (void);
void Grp_ShowFormToSelWhichGrps (Act_Action_t Action,void (*FuncParams) ());
void Grp_GetParamWhichGrps (void);
bool Grp_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (const struct UsrData *UsrDat);
#endif

View File

@ -80,8 +80,8 @@ static void Ins_GetParamInsOrder (void);
static void Ins_PutIconToViewInstitutions (void);
static void Ins_GetFullNameAndCtyOfInstitutionByCod (struct Instit *Ins,
char CtyName[Hie_MAX_BYTES_FULL_NAME + 1]);
static void Ins_GetFullNameAndCtyOfInstitution (struct Instit *Ins,
char CtyName[Hie_MAX_BYTES_FULL_NAME + 1]);
static void Ins_ListInstitutionsForEdition (void);
static bool Ins_CheckIfICanEdit (struct Instit *Ins);
@ -1098,7 +1098,7 @@ void Ins_WriteInstitutionNameAndCty (long InsCod)
/***** Get institution full name *****/
Ins.InsCod = InsCod;
Ins_GetFullNameAndCtyOfInstitutionByCod (&Ins,CtyName);
Ins_GetFullNameAndCtyOfInstitution (&Ins,CtyName);
/***** Write institution full name *****/
fprintf (Gbl.F.Out,"%s<br />%s",Ins.FullName,CtyName);
@ -1194,116 +1194,127 @@ bool Ins_GetDataOfInstitutionByCod (struct Instit *Ins,
/*********** Get the short name of an institution from its code **************/
/*****************************************************************************/
void Ins_GetShortNameOfInstitutionByCod (struct Instit *Ins)
void Ins_FlushCacheShortNameOfInstitution (void)
{
Gbl.Cache.InstitutionShrtName.InsCod = -1L;
Gbl.Cache.InstitutionShrtName.ShrtName[0] = '\0';
}
void Ins_GetShortNameOfInstitution (struct Instit *Ins)
{
char Query[128];
MYSQL_RES *mysql_res;
MYSQL_ROW row;
static struct
{
long InsCod;
char ShrtName[Hie_MAX_BYTES_SHRT_NAME + 1];
} Cached =
{
-1L,
{'\0'}
};
/***** 1. Fast check: Trivial case *****/
if (Ins->InsCod <= 0)
Ins->ShrtName[0] = '\0'; // Empty name
else
{
if (Ins->InsCod != Cached.InsCod) // If not cached...
{
/***** Get the short name of an institution from database *****/
sprintf (Query,"SELECT ShortName FROM institutions WHERE InsCod=%ld",
Ins->InsCod);
if (DB_QuerySELECT (Query,&mysql_res,"can not get the short name of an institution") == 1)
{
/***** Get the short name of this institution *****/
row = mysql_fetch_row (mysql_res);
Ins->ShrtName[0] = '\0'; // Empty name
return;
}
Str_Copy (Cached.ShrtName,row[0],
Hie_MAX_BYTES_SHRT_NAME);
}
else
Cached.ShrtName[0] = '\0';
/***** 2. Fast check: If cached... *****/
if (Ins->InsCod == Gbl.Cache.InstitutionShrtName.InsCod)
{
Str_Copy (Ins->ShrtName,Gbl.Cache.InstitutionShrtName.ShrtName,
Hie_MAX_BYTES_SHRT_NAME);
return;
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
/***** 3. Slow: get short name of institution from database *****/
Gbl.Cache.InstitutionShrtName.InsCod = Ins->InsCod;
Str_Copy (Ins->ShrtName,Cached.ShrtName,
sprintf (Query,"SELECT ShortName FROM institutions WHERE InsCod=%ld",
Ins->InsCod);
if (DB_QuerySELECT (Query,&mysql_res,"can not get the short name of an institution") == 1)
{
/* Get the short name of this institution */
row = mysql_fetch_row (mysql_res);
Str_Copy (Gbl.Cache.InstitutionShrtName.ShrtName,row[0],
Hie_MAX_BYTES_SHRT_NAME);
}
else
Gbl.Cache.InstitutionShrtName.ShrtName[0] = '\0';
/* Free structure that stores the query result */
DB_FreeMySQLResult (&mysql_res);
Str_Copy (Ins->ShrtName,Gbl.Cache.InstitutionShrtName.ShrtName,
Hie_MAX_BYTES_SHRT_NAME);
}
/*****************************************************************************/
/************ Get the full name of an institution from its code **************/
/*****************************************************************************/
static void Ins_GetFullNameAndCtyOfInstitutionByCod (struct Instit *Ins,
char CtyName[Hie_MAX_BYTES_FULL_NAME + 1])
void Ins_FlushCacheFullNameAndCtyOfInstitution (void)
{
Gbl.Cache.InstitutionFullNameAndCty.InsCod = -1L;
Gbl.Cache.InstitutionFullNameAndCty.FullName[0] = '\0';
Gbl.Cache.InstitutionFullNameAndCty.CtyName[0] = '\0';
}
static void Ins_GetFullNameAndCtyOfInstitution (struct Instit *Ins,
char CtyName[Hie_MAX_BYTES_FULL_NAME + 1])
{
extern const char *Txt_STR_LANG_ID[1 + Txt_NUM_LANGUAGES];
char Query[512];
MYSQL_RES *mysql_res;
MYSQL_ROW row;
static struct
{
long InsCod;
char FullName[Hie_MAX_BYTES_FULL_NAME + 1];
char CtyName[Hie_MAX_BYTES_FULL_NAME + 1];
} Cached =
{
-1L,
{'\0'},
{'\0'},
};
/***** 1. Fast check: Trivial case *****/
if (Ins->InsCod <= 0)
{
Ins->FullName[0] = '\0'; // Empty name
CtyName[0] = '\0'; // Empty name
return;
}
/***** 2. Fast check: If cached... *****/
if (Ins->InsCod == Gbl.Cache.InstitutionFullNameAndCty.InsCod)
{
Str_Copy (Ins->FullName,Gbl.Cache.InstitutionFullNameAndCty.FullName,
Hie_MAX_BYTES_FULL_NAME);
Str_Copy (CtyName,Gbl.Cache.InstitutionFullNameAndCty.CtyName,
Hie_MAX_BYTES_FULL_NAME);
return;
}
/***** 3. Slow: get full name and country of institution from database *****/
Gbl.Cache.InstitutionFullNameAndCty.InsCod = Ins->InsCod;
sprintf (Query,"SELECT institutions.FullName,countries.Name_%s"
" FROM institutions,countries"
" WHERE institutions.InsCod=%ld"
" AND institutions.CtyCod=countries.CtyCod",
Txt_STR_LANG_ID[Gbl.Prefs.Language],Ins->InsCod);
if (DB_QuerySELECT (Query,&mysql_res,"can not get the full name of an institution") == 1)
{
/* Get row */
row = mysql_fetch_row (mysql_res);
/* Get the full name of this institution (row[0]) */
Str_Copy (Gbl.Cache.InstitutionFullNameAndCty.FullName,row[0],
Hie_MAX_BYTES_FULL_NAME);
/* Get the name of the country (row[1]) */
Str_Copy (Gbl.Cache.InstitutionFullNameAndCty.CtyName,row[1],
Hie_MAX_BYTES_FULL_NAME);
}
else
{
if (Ins->InsCod != Cached.InsCod) // If not cached...
{
/***** Get the short name of an institution from database *****/
sprintf (Query,"SELECT institutions.FullName,countries.Name_%s"
" FROM institutions,countries"
" WHERE institutions.InsCod=%ld"
" AND institutions.CtyCod=countries.CtyCod",
Txt_STR_LANG_ID[Gbl.Prefs.Language],Ins->InsCod);
if (DB_QuerySELECT (Query,&mysql_res,"can not get the full name of an institution") == 1)
{
/* Get row */
row = mysql_fetch_row (mysql_res);
/* Get the full name of this institution (row[0]) */
Str_Copy (Cached.FullName,row[0],
Hie_MAX_BYTES_FULL_NAME);
/* Get the name of the country (row[1]) */
Str_Copy (Cached.CtyName,row[1],
Hie_MAX_BYTES_FULL_NAME);
}
else
{
Cached.FullName[0] = '\0';
Cached.CtyName[0] = '\0';
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
Str_Copy (Ins->FullName,Cached.FullName,
Hie_MAX_BYTES_FULL_NAME);
Str_Copy (CtyName,Cached.CtyName,
Hie_MAX_BYTES_FULL_NAME);
Gbl.Cache.InstitutionFullNameAndCty.FullName[0] = '\0';
Gbl.Cache.InstitutionFullNameAndCty.CtyName[0] = '\0';
}
/* Free structure that stores the query result */
DB_FreeMySQLResult (&mysql_res);
Str_Copy (Ins->FullName,Gbl.Cache.InstitutionFullNameAndCty.FullName,
Hie_MAX_BYTES_FULL_NAME);
Str_Copy (CtyName,Gbl.Cache.InstitutionFullNameAndCty.CtyName,
Hie_MAX_BYTES_FULL_NAME);
}
/*****************************************************************************/
@ -1711,6 +1722,10 @@ void Ins_RemoveInstitution (void)
Ins.InsCod);
DB_QueryDELETE (Query,"can not remove an institution");
/***** Flush caches *****/
Ins_FlushCacheShortNameOfInstitution ();
Ins_FlushCacheFullNameAndCtyOfInstitution ();
/***** Write message to show the change made *****/
sprintf (Gbl.Alert.Txt,Txt_Institution_X_removed,
Ins.FullName);
@ -1859,6 +1874,10 @@ static void Ins_UpdateInsNameDB (long InsCod,const char *FieldName,const char *N
sprintf (Query,"UPDATE institutions SET %s='%s' WHERE InsCod=%ld",
FieldName,NewInsName,InsCod);
DB_QueryUPDATE (Query,"can not update the name of an institution");
/***** Flush caches *****/
Ins_FlushCacheShortNameOfInstitution ();
Ins_FlushCacheFullNameAndCtyOfInstitution ();
}
/*****************************************************************************/

View File

@ -106,7 +106,9 @@ void Ins_GetListInstitutions (long CtyCod,Ins_GetExtraData_t GetExtraData);
void Ins_WriteInstitutionNameAndCty (long InsCod);
bool Ins_GetDataOfInstitutionByCod (struct Instit *Ins,
Ins_GetExtraData_t GetExtraData);
void Ins_GetShortNameOfInstitutionByCod (struct Instit *Ins);
void Ins_FlushCacheShortNameOfInstitution (void);
void Ins_GetShortNameOfInstitution (struct Instit *Ins);
void Ins_FlushCacheFullNameAndCtyOfInstitution (void);
void Ins_FreeListInstitutions (void);
void Ins_WriteSelectorOfInstitution (void);

View File

@ -285,8 +285,9 @@ bool Prf_ShowUserProfile (struct UsrData *UsrDat)
Gbl.CurrentCrs.Crs.CrsCod > 0) // ...and a course is selected
{
/* Get user's role in current course */
UsrDat->Roles.InCurrentCrs.Role = Rol_GetRoleInCrs (Gbl.CurrentCrs.Crs.CrsCod,UsrDat->UsrCod);
UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
UsrDat->Roles.InCurrentCrs.Role = Rol_GetRoleUsrInCrs (UsrDat->UsrCod,
Gbl.CurrentCrs.Crs.CrsCod);
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = UsrDat->UsrCod;
/* Get if user has accepted enrolment in current course */
UsrDat->Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (UsrDat);

View File

@ -2139,7 +2139,7 @@ void Rec_ShowFormOtherNewSharedRecord (struct UsrData *UsrDat,Rol_Role_t Default
Instead it is initialized with the preferred role. */
UsrDat->Roles.InCurrentCrs.Role = (Gbl.CurrentCrs.Crs.CrsCod > 0) ? DefaultRole : // Course selected
Rol_UNK; // No course selected
UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = UsrDat->UsrCod;
Rec_ShowSharedUsrRecord (Rec_SHA_OTHER_NEW_USR_FORM,UsrDat,NULL);
}

View File

@ -68,10 +68,10 @@ void Rol_SetMyRoles (void)
bool ICanBeDegAdm = false;
/***** Get my role in current course if not yet filled *****/
if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.UsrCod != Gbl.Usrs.Me.UsrDat.UsrCod)
if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.GotFromDBForUsrCod != Gbl.Usrs.Me.UsrDat.UsrCod)
{
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role = Rol_GetMyRoleInCrs (Gbl.CurrentCrs.Crs.CrsCod);
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod;
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role = Rol_GetMyRoleInCrs (Gbl.CurrentCrs.Crs.CrsCod);
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.GotFromDBForUsrCod = Gbl.Usrs.Me.UsrDat.UsrCod;
}
/***** Set the user's role I am logged *****/
@ -179,7 +179,7 @@ void Rol_SetMyRoles (void)
if (!(Gbl.Usrs.Me.Role.Available & (1 << Gbl.Usrs.Me.Role.Logged))) // Current type I am logged is not available for me
/* Set the lowest role available for me */
for (Gbl.Usrs.Me.Role.Logged = Rol_UNK;
Gbl.Usrs.Me.Role.Logged < Rol_NUM_ROLES;
Gbl.Usrs.Me.Role.Logged <= (Rol_Role_t) (Rol_NUM_ROLES - 1);
Gbl.Usrs.Me.Role.Logged++)
if (Gbl.Usrs.Me.Role.Available & (1 << Gbl.Usrs.Me.Role.Logged))
break;
@ -326,50 +326,45 @@ Rol_Role_t Rol_GetMyRoleInCrs (long CrsCod)
/********************** Get role of a user in a course ***********************/
/*****************************************************************************/
Rol_Role_t Rol_GetRoleInCrs (long CrsCod,long UsrCod)
void Rol_FlushCacheRoleUsrInCrs (void)
{
Gbl.Cache.RoleUsrInCrs.UsrCod = -1L;
Gbl.Cache.RoleUsrInCrs.CrsCod = -1L;
Gbl.Cache.RoleUsrInCrs.Role = Rol_UNK;
}
Rol_Role_t Rol_GetRoleUsrInCrs (long UsrCod,long CrsCod)
{
char Query[256];
MYSQL_RES *mysql_res;
MYSQL_ROW row;
static struct
{
long CrsCod;
long UsrCod;
Rol_Role_t RoleInCrs;
} Cached =
{
-1L,
-1L,
Rol_UNK,
}; // A cache. If this function is called consecutive times
// with the same user, only the first time is slow
/***** 1. Fast check: trivial cases *****/
if (CrsCod <= 0 ||
UsrCod <= 0)
if (UsrCod <= 0 ||
CrsCod <= 0)
return Rol_UNK;
/***** 2. Fast check: Is role in course already calculated *****/
if (CrsCod == Cached.CrsCod &&
UsrCod == Cached.UsrCod)
return Cached.RoleInCrs;
if (UsrCod == Gbl.Cache.RoleUsrInCrs.UsrCod &&
CrsCod == Gbl.Cache.RoleUsrInCrs.CrsCod )
return Gbl.Cache.RoleUsrInCrs.Role;
/***** 3. Slow check: Get rol of a user in a course from database.
The result of the query will have one row or none *****/
Cached.UsrCod = UsrCod;
Cached.CrsCod = CrsCod;
Cached.RoleInCrs = Rol_UNK;
Gbl.Cache.RoleUsrInCrs.UsrCod = UsrCod;
Gbl.Cache.RoleUsrInCrs.CrsCod = CrsCod;
Gbl.Cache.RoleUsrInCrs.Role = Rol_UNK;
sprintf (Query,"SELECT Role FROM crs_usr"
" WHERE CrsCod=%ld AND UsrCod=%ld",
CrsCod,UsrCod);
if (DB_QuerySELECT (Query,&mysql_res,"can not get the role of a user in a course") == 1) // User belongs to the course
{
row = mysql_fetch_row (mysql_res);
Cached.RoleInCrs = Rol_ConvertUnsignedStrToRole (row[0]);
Gbl.Cache.RoleUsrInCrs.Role = Rol_ConvertUnsignedStrToRole (row[0]);
}
DB_FreeMySQLResult (&mysql_res);
return Cached.RoleInCrs;
return Gbl.Cache.RoleUsrInCrs.Role;
}
/*****************************************************************************/

View File

@ -45,7 +45,8 @@ Rol_Role_t Rol_GetMyMaxRoleInIns (long InsCod);
Rol_Role_t Rol_GetMyMaxRoleInCtr (long CtrCod);
Rol_Role_t Rol_GetMyMaxRoleInDeg (long DegCod);
Rol_Role_t Rol_GetMyRoleInCrs (long CrsCod);
Rol_Role_t Rol_GetRoleInCrs (long CrsCod,long UsrCod);
void Rol_FlushCacheRoleUsrInCrs (void);
Rol_Role_t Rol_GetRoleUsrInCrs (long UsrCod,long CrsCod);
void Rol_GetRolesInAllCrssIfNotYetGot (struct UsrData *UsrDat);
Rol_Role_t Rol_ConvertUnsignedStrToRole (const char *UnsignedStr);

View File

@ -296,7 +296,7 @@ void Usr_ResetUsrDataExceptUsrCodAndIDs (struct UsrData *UsrDat)
UsrDat->Nickname[0] = '\0';
UsrDat->Password[0] = '\0';
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
UsrDat->Roles.InCurrentCrs.UsrCod = -1L;
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = -1L;
UsrDat->Roles.InCrss = -1; // < 0 ==> not yet got from database
UsrDat->Accepted = true;
@ -520,9 +520,9 @@ void Usr_GetUsrDataFromUsrCod (struct UsrData *UsrDat)
Pwd_BYTES_ENCRYPTED_PASSWORD);
/* Get roles */
UsrDat->Roles.InCurrentCrs.Role = Rol_GetRoleInCrs (Gbl.CurrentCrs.Crs.CrsCod,
UsrDat->UsrCod);
UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
UsrDat->Roles.InCurrentCrs.Role = Rol_GetRoleUsrInCrs (UsrDat->UsrCod,
Gbl.CurrentCrs.Crs.CrsCod);
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = UsrDat->UsrCod;
UsrDat->Roles.InCrss = -1; // Force roles to be got from database
Rol_GetRolesInAllCrssIfNotYetGot (UsrDat);
@ -801,37 +801,32 @@ bool Usr_CheckIfUsrIsAdm (long UsrCod,Sco_Scope_t Scope,long Cod)
/********************* Check if a user is a superuser ************************/
/*****************************************************************************/
void Usr_FlushCacheUsrIsSuperuser (void)
{
Gbl.Cache.UsrIsSuperuser.UsrCod = -1L;
Gbl.Cache.UsrIsSuperuser.IsSuperuser = false;
}
bool Usr_CheckIfUsrIsSuperuser (long UsrCod)
{
extern const char *Sco_ScopeDB[Sco_NUM_SCOPES];
char Query[256];
static struct
{
long UsrCod;
bool IsSuperuser;
} Cached =
{
-1L,
false
};
/***** 1. Fast check: Trivial case *****/
if (UsrCod <= 0)
{
/***** Trivial case *****/
Cached.UsrCod = -1L;
Cached.IsSuperuser = false;
}
else if (UsrCod != Cached.UsrCod) // If not cached...
{
/***** Get if a user is superuser from database *****/
sprintf (Query,"SELECT COUNT(*) FROM admin"
" WHERE UsrCod=%ld AND Scope='%s'",
UsrCod,Sco_ScopeDB[Sco_SCOPE_SYS]);
Cached.UsrCod = UsrCod;
Cached.IsSuperuser = (DB_QueryCOUNT (Query,"can not check if a user is superuser") != 0);
}
return false;
return Cached.IsSuperuser;
/***** 2. Fast check: If cached... *****/
if (UsrCod == Gbl.Cache.UsrIsSuperuser.UsrCod)
return Gbl.Cache.UsrIsSuperuser.IsSuperuser;
/***** 3. Slow check: If not cached, get if a user is superuser from database *****/
sprintf (Query,"SELECT COUNT(*) FROM admin"
" WHERE UsrCod=%ld AND Scope='%s'",
UsrCod,Sco_ScopeDB[Sco_SCOPE_SYS]);
Gbl.Cache.UsrIsSuperuser.UsrCod = UsrCod;
Gbl.Cache.UsrIsSuperuser.IsSuperuser = (DB_QueryCOUNT (Query,"can not check if a user is superuser") != 0);
return Gbl.Cache.UsrIsSuperuser.IsSuperuser;
}
/*****************************************************************************/
@ -1168,19 +1163,15 @@ bool Usr_CheckIfICanViewUsrAgenda (struct UsrData *UsrDat)
/*************** Check if a user belongs to any of my courses ****************/
/*****************************************************************************/
void Usr_FlushCacheUsrSharesAnyOfMyCrs (void)
{
Gbl.Cache.UsrSharesAnyOfMyCrs.UsrCod = -1L;
Gbl.Cache.UsrSharesAnyOfMyCrs.SharesAnyOfMyCrs = false;
}
bool Usr_CheckIfUsrSharesAnyOfMyCrs (struct UsrData *UsrDat)
{
char Query[256];
static struct
{
long UsrCod;
bool UsrSharesAnyOfMyCrs;
} Cached =
{
-1L,
false
}; // A cache. If this function is called consecutive times
// with the same user, only the first time is slow
/***** 1. Fast check: Am I logged? *****/
if (!Gbl.Usrs.Me.Logged)
@ -1195,8 +1186,8 @@ bool Usr_CheckIfUsrSharesAnyOfMyCrs (struct UsrData *UsrDat)
return true;
/***** 4. Fast check: Is already calculated if user shares any course with me? *****/
if (UsrDat->UsrCod == Cached.UsrCod)
return Cached.UsrSharesAnyOfMyCrs;
if (UsrDat->UsrCod == Gbl.Cache.UsrSharesAnyOfMyCrs.UsrCod)
return Gbl.Cache.UsrSharesAnyOfMyCrs.SharesAnyOfMyCrs;
/***** 5. Fast check: Is course selected and we both belong to it? *****/
if (Gbl.Usrs.Me.IBelongToCurrentCrs)
@ -1219,9 +1210,9 @@ bool Usr_CheckIfUsrSharesAnyOfMyCrs (struct UsrData *UsrDat)
" WHERE UsrCod=%ld"
" AND CrsCod IN (SELECT CrsCod FROM my_courses_tmp)",
UsrDat->UsrCod);
Cached.UsrSharesAnyOfMyCrs = DB_QueryCOUNT (Query,"can not check if a user shares any course with you") != 0;
Cached.UsrCod = UsrDat->UsrCod;
return Cached.UsrSharesAnyOfMyCrs;
Gbl.Cache.UsrSharesAnyOfMyCrs.SharesAnyOfMyCrs = DB_QueryCOUNT (Query,"can not check if a user shares any course with you") != 0;
Gbl.Cache.UsrSharesAnyOfMyCrs.UsrCod = UsrDat->UsrCod;
return Gbl.Cache.UsrSharesAnyOfMyCrs.SharesAnyOfMyCrs;
}
/*****************************************************************************/
@ -1622,36 +1613,26 @@ static void Usr_RemoveTemporaryTableMyCourses (void)
/**************** Check if a user belongs to an institution ******************/
/*****************************************************************************/
void Usr_FlushCacheUsrBelongsToIns (void)
{
Gbl.Cache.UsrBelongsToIns.UsrCod = -1L;
Gbl.Cache.UsrBelongsToIns.InsCod = -1L;
Gbl.Cache.UsrBelongsToIns.Belongs = false;
}
bool Usr_CheckIfUsrBelongsToIns (long UsrCod,long InsCod)
{
char Query[512];
static struct
{
long UsrCod;
long InsCod;
bool Belongs;
} Cached =
{
-1L,
-1L,
false
};
/***** 1. Fast check: Trivial case *****/
if (UsrCod <= 0 ||
InsCod <= 0)
{
/***** Trivial case *****/
Cached.UsrCod = -1L;
Cached.InsCod = -1L;
Cached.Belongs = false;
return Cached.Belongs;
}
return false;
/***** 2. Fast check: If cached... *****/
if (UsrCod == Cached.UsrCod &&
InsCod != Cached.InsCod)
return Cached.Belongs;
if (UsrCod == Gbl.Cache.UsrBelongsToIns.UsrCod &&
InsCod != Gbl.Cache.UsrBelongsToIns.InsCod)
return Gbl.Cache.UsrBelongsToIns.Belongs;
/***** 3. Slow check: Get is user belongs to institution from database *****/
sprintf (Query,"SELECT COUNT(DISTINCT centres.InsCod)"
@ -1663,45 +1644,36 @@ bool Usr_CheckIfUsrBelongsToIns (long UsrCod,long InsCod)
" AND degrees.CtrCod=centres.CtrCod"
" AND centres.InsCod=%ld",
UsrCod,InsCod);
Cached.UsrCod = UsrCod;
Cached.InsCod = InsCod;
Cached.Belongs = (DB_QueryCOUNT (Query,"can not check if a user belongs to an institution") != 0);
return Cached.Belongs;
Gbl.Cache.UsrBelongsToIns.UsrCod = UsrCod;
Gbl.Cache.UsrBelongsToIns.InsCod = InsCod;
Gbl.Cache.UsrBelongsToIns.Belongs = (DB_QueryCOUNT (Query,"can not check if a user belongs to an institution") != 0);
return Gbl.Cache.UsrBelongsToIns.Belongs;
}
/*****************************************************************************/
/******************* Check if a user belongs to a centre *********************/
/*****************************************************************************/
void Usr_FlushCacheUsrBelongsToCtr (void)
{
Gbl.Cache.UsrBelongsToCtr.UsrCod = -1L;
Gbl.Cache.UsrBelongsToCtr.CtrCod = -1L;
Gbl.Cache.UsrBelongsToCtr.Belongs = false;
}
bool Usr_CheckIfUsrBelongsToCtr (long UsrCod,long CtrCod)
{
char Query[512];
static struct
{
long UsrCod;
long CtrCod;
bool Belongs;
} Cached =
{
-1L,
-1L,
false
};
/***** 1. Fast check: Trivial case *****/
if (UsrCod <= 0 ||
CtrCod <= 0)
{
Cached.UsrCod = -1L;
Cached.CtrCod = -1L;
Cached.Belongs = false;
return Cached.Belongs;
}
return false;
/***** 2. Fast check: If cached... *****/
if (UsrCod == Cached.UsrCod &&
CtrCod == Cached.CtrCod)
return Cached.Belongs;
if (UsrCod == Gbl.Cache.UsrBelongsToCtr.UsrCod &&
CtrCod == Gbl.Cache.UsrBelongsToCtr.CtrCod)
return Gbl.Cache.UsrBelongsToCtr.Belongs;
/***** 3. Slow check: Get is user belongs to centre from database *****/
sprintf (Query,"SELECT COUNT(DISTINCT degrees.CtrCod)"
@ -1712,45 +1684,36 @@ bool Usr_CheckIfUsrBelongsToCtr (long UsrCod,long CtrCod)
" AND courses.DegCod=degrees.DegCod"
" AND degrees.CtrCod=%ld",
UsrCod,CtrCod);
Cached.UsrCod = UsrCod;
Cached.CtrCod = CtrCod;
Cached.Belongs = (DB_QueryCOUNT (Query,"can not check if a user belongs to a centre") != 0);
return Cached.Belongs;
Gbl.Cache.UsrBelongsToCtr.UsrCod = UsrCod;
Gbl.Cache.UsrBelongsToCtr.CtrCod = CtrCod;
Gbl.Cache.UsrBelongsToCtr.Belongs = (DB_QueryCOUNT (Query,"can not check if a user belongs to a centre") != 0);
return Gbl.Cache.UsrBelongsToCtr.Belongs;
}
/*****************************************************************************/
/******************* Check if a user belongs to a degree *********************/
/*****************************************************************************/
void Usr_FlushCacheUsrBelongsToDeg (void)
{
Gbl.Cache.UsrBelongsToDeg.UsrCod = -1L;
Gbl.Cache.UsrBelongsToDeg.DegCod = -1L;
Gbl.Cache.UsrBelongsToDeg.Belongs = false;
}
bool Usr_CheckIfUsrBelongsToDeg (long UsrCod,long DegCod)
{
char Query[512];
static struct
{
long UsrCod;
long DegCod;
bool Belongs;
} Cached =
{
-1L,
-1L,
false
};
/***** 1. Fast check: Trivial case *****/
if (UsrCod <= 0 ||
DegCod <= 0)
{
Cached.UsrCod = -1L;
Cached.DegCod = -1L;
Cached.Belongs = false;
return Cached.Belongs;
}
return false;
/***** 2. Fast check: If cached... *****/
if (UsrCod == Cached.UsrCod &&
DegCod == Cached.DegCod)
return Cached.Belongs;
if (UsrCod == Gbl.Cache.UsrBelongsToDeg.UsrCod &&
DegCod == Gbl.Cache.UsrBelongsToDeg.DegCod)
return Gbl.Cache.UsrBelongsToDeg.Belongs;
/***** 3. Slow check: Get if user belongs to degree from database *****/
sprintf (Query,"SELECT COUNT(DISTINCT courses.DegCod)"
@ -1760,138 +1723,40 @@ bool Usr_CheckIfUsrBelongsToDeg (long UsrCod,long DegCod)
" AND crs_usr.CrsCod=courses.CrsCod"
" AND courses.DegCod=%ld",
UsrCod,DegCod);
Cached.UsrCod = UsrCod;
Cached.DegCod = DegCod;
Cached.Belongs = (DB_QueryCOUNT (Query,"can not check if a user belongs to a degree") != 0);
return Cached.Belongs;
}
/*****************************************************************************/
/***** Check if user belongs (no matter if he/she has accepted or not) *******/
/***** to the current course *******/
/*****************************************************************************/
bool Usr_CheckIfUsrBelongsToCurrentCrs (const struct UsrData *UsrDat)
{
static struct
{
long UsrCod;
bool Belongs;
} Cached =
{
-1L,
false
};
/***** 1. Fast check: trivial cases *****/
if (UsrDat->UsrCod <= 0 ||
Gbl.CurrentCrs.Crs.CrsCod <= 0)
{
Cached.UsrCod = -1L;
Cached.Belongs = false;
return Cached.Belongs;
}
/***** 2. Fast check: If cached... *****/
if (UsrDat->UsrCod == Cached.UsrCod)
return Cached.Belongs;
/***** 3. Fast check: If we know role of user in the current course *****/
if (UsrDat->Roles.InCurrentCrs.UsrCod == UsrDat->UsrCod)
{
Cached.UsrCod = UsrDat->UsrCod;
Cached.Belongs = UsrDat->Roles.InCurrentCrs.Role == Rol_STD ||
UsrDat->Roles.InCurrentCrs.Role == Rol_NET ||
UsrDat->Roles.InCurrentCrs.Role == Rol_TCH;
return Cached.Belongs;
}
/***** 4. Fast / slow check: Get if user belongs to current course *****/
Cached.UsrCod = UsrDat->UsrCod;
Cached.Belongs = Usr_CheckIfUsrBelongsToCrs (UsrDat->UsrCod,
Gbl.CurrentCrs.Crs.CrsCod,
false);
return Cached.Belongs;
}
/*****************************************************************************/
/***** Check if user belongs (no matter if he/she has accepted or not) *******/
/***** to the current course *******/
/*****************************************************************************/
bool Usr_CheckIfUsrHasAcceptedInCurrentCrs (const struct UsrData *UsrDat)
{
static struct
{
long UsrCod;
bool Accepted;
} Cached =
{
-1L,
false
};
/***** 1. Fast check: trivial cases *****/
if (UsrDat->UsrCod <= 0 ||
Gbl.CurrentCrs.Crs.CrsCod <= 0)
{
Cached.UsrCod = -1L;
Cached.Accepted = false;
return Cached.Accepted;
}
/***** 2. Fast check: If cached... *****/
if (UsrDat->UsrCod == Cached.UsrCod)
return Cached.Accepted;
/***** 3. Fast / slow check: Get if user belongs to current course
and has accepted *****/
Cached.UsrCod = UsrDat->UsrCod;
Cached.Accepted = Usr_CheckIfUsrBelongsToCrs (UsrDat->UsrCod,
Gbl.CurrentCrs.Crs.CrsCod,
true);
return Cached.Accepted;
Gbl.Cache.UsrBelongsToDeg.UsrCod = UsrCod;
Gbl.Cache.UsrBelongsToDeg.DegCod = DegCod;
Gbl.Cache.UsrBelongsToDeg.Belongs = (DB_QueryCOUNT (Query,"can not check if a user belongs to a degree") != 0);
return Gbl.Cache.UsrBelongsToDeg.Belongs;
}
/*****************************************************************************/
/******************** Check if a user belongs to a course ********************/
/*****************************************************************************/
void Usr_FlushCacheUsrBelongsToCrs (void)
{
Gbl.Cache.UsrBelongsToCrs.UsrCod = -1L;
Gbl.Cache.UsrBelongsToCrs.CrsCod = -1L;
Gbl.Cache.UsrBelongsToCrs.CountOnlyAcceptedCourses = false;
Gbl.Cache.UsrBelongsToCrs.Belongs = false;
}
bool Usr_CheckIfUsrBelongsToCrs (long UsrCod,long CrsCod,
bool CountOnlyAcceptedCourses)
{
char Query[512];
const char *SubQuery;
static struct
{
long UsrCod;
long CrsCod;
bool CountOnlyAcceptedCourses;
bool Belongs;
} Cached =
{
-1L,
-1L,
false,
false
};
/***** 1. Fast check: trivial cases *****/
/***** 1. Fast check: Trivial cases *****/
if (UsrCod <= 0 ||
CrsCod <= 0)
{
Cached.UsrCod = -1L;
Cached.CrsCod = -1L;
Cached.CountOnlyAcceptedCourses = CountOnlyAcceptedCourses;
Cached.Belongs = false;
return Cached.Belongs;
}
return false;
/***** 2. Fast check: If cached... *****/
if (UsrCod == Cached.UsrCod &&
CrsCod == Cached.CrsCod &&
CountOnlyAcceptedCourses == Cached.CountOnlyAcceptedCourses)
return Cached.Belongs;
if (UsrCod == Gbl.Cache.UsrBelongsToCrs.UsrCod &&
CrsCod == Gbl.Cache.UsrBelongsToCrs.CrsCod &&
CountOnlyAcceptedCourses == Gbl.Cache.UsrBelongsToCrs.CountOnlyAcceptedCourses)
return Gbl.Cache.UsrBelongsToCrs.Belongs;
/***** 3. Slow check: Get if user belongs to course from database *****/
SubQuery = (CountOnlyAcceptedCourses ? " AND crs_usr.Accepted='Y'" :
@ -1899,11 +1764,82 @@ bool Usr_CheckIfUsrBelongsToCrs (long UsrCod,long CrsCod,
sprintf (Query,"SELECT COUNT(*) FROM crs_usr"
" WHERE CrsCod=%ld AND UsrCod=%ld%s",
CrsCod,UsrCod,SubQuery);
Cached.UsrCod = UsrCod;
Cached.CrsCod = CrsCod;
Cached.CountOnlyAcceptedCourses = CountOnlyAcceptedCourses;
Cached.Belongs = (DB_QueryCOUNT (Query,"can not check if a user belongs to a course") != 0);
return Cached.Belongs;
Gbl.Cache.UsrBelongsToCrs.UsrCod = UsrCod;
Gbl.Cache.UsrBelongsToCrs.CrsCod = CrsCod;
Gbl.Cache.UsrBelongsToCrs.CountOnlyAcceptedCourses = CountOnlyAcceptedCourses;
Gbl.Cache.UsrBelongsToCrs.Belongs = (DB_QueryCOUNT (Query,"can not check if a user belongs to a course") != 0);
return Gbl.Cache.UsrBelongsToCrs.Belongs;
}
/*****************************************************************************/
/***** Check if user belongs (no matter if he/she has accepted or not) *******/
/***** to the current course *******/
/*****************************************************************************/
void Usr_FlushCacheUsrBelongsToCurrentCrs (void)
{
Gbl.Cache.UsrBelongsToCurrentCrs.UsrCod = -1L;
Gbl.Cache.UsrBelongsToCurrentCrs.Belongs = false;
}
bool Usr_CheckIfUsrBelongsToCurrentCrs (const struct UsrData *UsrDat)
{
/***** 1. Fast check: Trivial cases *****/
if (UsrDat->UsrCod <= 0 ||
Gbl.CurrentCrs.Crs.CrsCod <= 0)
return false;
/***** 2. Fast check: If cached... *****/
if (UsrDat->UsrCod == Gbl.Cache.UsrBelongsToCurrentCrs.UsrCod)
return Gbl.Cache.UsrBelongsToCurrentCrs.Belongs;
/***** 3. Fast check: If we know role of user in the current course *****/
if (UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod == UsrDat->UsrCod)
{
Gbl.Cache.UsrBelongsToCurrentCrs.UsrCod = UsrDat->UsrCod;
Gbl.Cache.UsrBelongsToCurrentCrs.Belongs = UsrDat->Roles.InCurrentCrs.Role == Rol_STD ||
UsrDat->Roles.InCurrentCrs.Role == Rol_NET ||
UsrDat->Roles.InCurrentCrs.Role == Rol_TCH;
return Gbl.Cache.UsrBelongsToCurrentCrs.Belongs;
}
/***** 4. Fast / slow check: Get if user belongs to current course *****/
Gbl.Cache.UsrBelongsToCurrentCrs.UsrCod = UsrDat->UsrCod;
Gbl.Cache.UsrBelongsToCurrentCrs.Belongs = Usr_CheckIfUsrBelongsToCrs (UsrDat->UsrCod,
Gbl.CurrentCrs.Crs.CrsCod,
false);
return Gbl.Cache.UsrBelongsToCurrentCrs.Belongs;
}
/*****************************************************************************/
/***** Check if user belongs (no matter if he/she has accepted or not) *******/
/***** to the current course *******/
/*****************************************************************************/
void Usr_FlushCacheUsrHasAcceptedInCurrentCrs (void)
{
Gbl.Cache.UsrHasAcceptedInCurrentCrs.UsrCod = -1L;
Gbl.Cache.UsrHasAcceptedInCurrentCrs.Accepted = false;
}
bool Usr_CheckIfUsrHasAcceptedInCurrentCrs (const struct UsrData *UsrDat)
{
/***** 1. Fast check: Trivial cases *****/
if (UsrDat->UsrCod <= 0 ||
Gbl.CurrentCrs.Crs.CrsCod <= 0)
return false;
/***** 2. Fast check: If cached... *****/
if (UsrDat->UsrCod == Gbl.Cache.UsrHasAcceptedInCurrentCrs.UsrCod)
return Gbl.Cache.UsrHasAcceptedInCurrentCrs.Accepted;
/***** 3. Fast / slow check: Get if user belongs to current course
and has accepted *****/
Gbl.Cache.UsrHasAcceptedInCurrentCrs.UsrCod = UsrDat->UsrCod;
Gbl.Cache.UsrHasAcceptedInCurrentCrs.Accepted = Usr_CheckIfUsrBelongsToCrs (UsrDat->UsrCod,
Gbl.CurrentCrs.Crs.CrsCod,
true);
return Gbl.Cache.UsrHasAcceptedInCurrentCrs.Accepted;
}
/*****************************************************************************/
@ -3111,9 +3047,9 @@ static void Usr_SetMyPrefsAndRoles (void)
Hie_InitHierarchy ();
/* Get again my role in this course */
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role = Rol_GetRoleInCrs (Gbl.CurrentCrs.Crs.CrsCod,
Gbl.Usrs.Me.UsrDat.UsrCod);
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod;
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role = Rol_GetRoleUsrInCrs (Gbl.Usrs.Me.UsrDat.UsrCod,
Gbl.CurrentCrs.Crs.CrsCod);
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.GotFromDBForUsrCod = Gbl.Usrs.Me.UsrDat.UsrCod;
}
}

View File

@ -133,7 +133,7 @@ struct UsrData
{
struct
{
long UsrCod; // Role was got from database for this user (used to not retrieve role if already retrieved)
long GotFromDBForUsrCod; // Role was got from database for this user (used to not retrieve role if already retrieved)
Rol_Role_t Role;
} InCurrentCrs; // Role in current course (Rol_UNK is no course selected)
int InCrss; // Roles in all his/her courses
@ -244,6 +244,7 @@ void Usr_BuildFullName (struct UsrData *UsrDat);
void Usr_WriteFirstNameBRSurnames (const struct UsrData *UsrDat);
bool Usr_CheckIfUsrIsAdm (long UsrCod,Sco_Scope_t Scope,long Cod);
void Usr_FlushCacheUsrIsSuperuser (void);
bool Usr_CheckIfUsrIsSuperuser (long UsrCod);
bool Usr_ICanChangeOtherUsrData (const struct UsrData *UsrDat);
@ -257,12 +258,15 @@ unsigned Usr_GetNumCrssOfUsrWithARoleNotAccepted (long UsrCod,Rol_Role_t Role);
unsigned Usr_GetNumUsrsInCrssOfAUsr (long UsrCod,Rol_Role_t UsrRole,
Rol_Role_t OthersRole);
void Usr_FlushCacheUsrBelongsToCurrentCrs (void);
bool Usr_CheckIfUsrBelongsToCurrentCrs (const struct UsrData *UsrDat);
void Usr_FlushCacheUsrHasAcceptedInCurrentCrs (void);
bool Usr_CheckIfUsrHasAcceptedInCurrentCrs (const struct UsrData *UsrDat);
bool Usr_CheckIfICanViewRecordStd (const struct UsrData *UsrDat);
bool Usr_CheckIfICanViewRecordTch (struct UsrData *UsrDat);
bool Usr_CheckIfICanViewWrkTstAtt (const struct UsrData *UsrDat);
bool Usr_CheckIfICanViewUsrAgenda (struct UsrData *UsrDat);
void Usr_FlushCacheUsrSharesAnyOfMyCrs (void);
bool Usr_CheckIfUsrSharesAnyOfMyCrs (struct UsrData *UsrDat);
bool Usr_CheckIfUsrSharesAnyOfMyCrsWithDifferentRole (long UsrCod);
@ -278,9 +282,13 @@ void Usr_FreeMyCentres (void);
void Usr_FreeMyDegrees (void);
void Usr_FreeMyCourses (void);
void Usr_FlushCacheUsrBelongsToIns (void);
bool Usr_CheckIfUsrBelongsToIns (long UsrCod,long InsCod);
void Usr_FlushCacheUsrBelongsToCtr (void);
bool Usr_CheckIfUsrBelongsToCtr (long UsrCod,long CtrCod);
void Usr_FlushCacheUsrBelongsToDeg (void);
bool Usr_CheckIfUsrBelongsToDeg (long UsrCod,long DegCod);
void Usr_FlushCacheUsrBelongsToCrs (void);
bool Usr_CheckIfUsrBelongsToCrs (long UsrCod,long CrsCod,
bool CountOnlyAcceptedCourses);

View File

@ -594,18 +594,18 @@ static bool Svc_GetSomeUsrDataFromUsrCod (struct UsrData *UsrDat,long CrsCod)
{
if (sscanf (row[0],"%u",&UsrDat->Roles.InCurrentCrs.Role) != 1)
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = UsrDat->UsrCod;
}
else // Impossible
{
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = UsrDat->UsrCod;
}
}
else // User does not belong to course
{
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = UsrDat->UsrCod;
}
}
else
@ -621,19 +621,19 @@ static bool Svc_GetSomeUsrDataFromUsrCod (struct UsrData *UsrDat,long CrsCod)
{
if (sscanf (row[0],"%u",&UsrDat->Roles.InCurrentCrs.Role) != 1)
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = UsrDat->UsrCod;
}
else
// MAX(Role) == NULL if user does not belong to any course
{
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = UsrDat->UsrCod;
}
}
else // Impossible
{
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = UsrDat->UsrCod;
}
}