Version 20.62: Apr 15, 2021 Optimizations in database selects related to roles.

This commit is contained in:
acanas 2021-04-15 19:42:00 +02:00
parent 91d8c066a5
commit 367b80943e
17 changed files with 226 additions and 211 deletions

View File

@ -635,77 +635,25 @@ static bool API_GetSomeUsrDataFromUsrCod (struct UsrData *UsrDat,long CrsCod)
Nck_GetNicknameFromUsrCod (UsrDat->UsrCod,UsrDat->Nickname);
/***** Get user's role *****/
/* Query database */
if (CrsCod > 0)
{
/* Get the role in the given course */
if (DB_QuerySELECT (&mysql_res,"can not get user's role",
"SELECT Role" // row[0]
UsrDat->Roles.InCurrentCrs.Role =
DB_QuerySELECTRole ("can not get user's role",
"SELECT Role"
" FROM crs_users"
" WHERE CrsCod=%ld"
" AND UsrCod=%ld",
CrsCod,
UsrDat->UsrCod)) // User belongs to course
{
row = mysql_fetch_row (mysql_res);
if (row[0])
{
if (sscanf (row[0],"%u",&UsrDat->Roles.InCurrentCrs.Role) == 1)
UsrDat->Roles.InCurrentCrs.Valid = true;
else
{
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
UsrDat->Roles.InCurrentCrs.Valid = false;
}
}
else // Impossible
{
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
UsrDat->Roles.InCurrentCrs.Valid = false;
}
}
else // User does not belong to course
{
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
UsrDat->Roles.InCurrentCrs.Valid = true;
}
}
UsrDat->UsrCod);
else
{
/* Get the maximum role in any course */
if (DB_QuerySELECT (&mysql_res,"can not get user's role",
"SELECT MAX(Role)" // row[0]
UsrDat->Roles.InCurrentCrs.Role =
DB_QuerySELECTRole ("can not get user's role",
"SELECT MAX(Role)"
" FROM crs_users"
" WHERE UsrCod=%ld",
UsrDat->UsrCod) == 1)
{
row = mysql_fetch_row (mysql_res);
if (row[0])
{
if (sscanf (row[0],"%u",&UsrDat->Roles.InCurrentCrs.Role) == 1)
UsrDat->Roles.InCurrentCrs.Valid = true;
else
{
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
UsrDat->Roles.InCurrentCrs.Valid = false;
}
}
else
// MAX(Role) == NULL if user does not belong to any course
{
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
UsrDat->Roles.InCurrentCrs.Valid = true;
}
}
else // Impossible
{
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
UsrDat->Roles.InCurrentCrs.Valid = false;
}
}
/* Free structure that stores the query result */
DB_FreeMySQLResult (&mysql_res);
UsrDat->UsrCod);
UsrDat->Roles.InCurrentCrs.Filled = true;
return true;
}

View File

@ -96,48 +96,47 @@ void Ann_ShowAllAnnouncements (void)
/***** Get announcements from database *****/
if (ICanEdit)
{
/* Select all announcements */
NumAnnouncements = (unsigned) DB_QuerySELECT (&mysql_res,"can not get announcements",
"SELECT AnnCod," // row[0]
"Status," // row[1]
"Roles," // row[2]
"Subject," // row[3]
"Content" // row[4]
" FROM ann_announcements"
" ORDER BY AnnCod DESC");
}
NumAnnouncements = (unsigned)
DB_QuerySELECT (&mysql_res,"can not get announcements",
"SELECT AnnCod," // row[0]
"Status," // row[1]
"Roles," // row[2]
"Subject," // row[3]
"Content" // row[4]
" FROM ann_announcements"
" ORDER BY AnnCod DESC");
else if (Gbl.Usrs.Me.Logged)
{
/* Select only announcements I can see */
Rol_GetRolesInAllCrssIfNotYetGot (&Gbl.Usrs.Me.UsrDat);
NumAnnouncements = (unsigned) DB_QuerySELECT (&mysql_res,"can not get announcements",
"SELECT AnnCod," // row[0]
"Status," // row[1]
"Roles," // row[2]
"Subject," // row[3]
"Content" // row[4]
" FROM ann_announcements"
" WHERE (Roles&%u)<>0 " // All my roles in different courses
" ORDER BY AnnCod DESC",
(unsigned) Gbl.Usrs.Me.UsrDat.Roles.InCrss);
NumAnnouncements = (unsigned)
DB_QuerySELECT (&mysql_res,"can not get announcements",
"SELECT AnnCod," // row[0]
"Status," // row[1]
"Roles," // row[2]
"Subject," // row[3]
"Content" // row[4]
" FROM ann_announcements"
" WHERE (Roles&%u)<>0 " // All my roles in different courses
" ORDER BY AnnCod DESC",
(unsigned) Gbl.Usrs.Me.UsrDat.Roles.InCrss);
}
else // No user logged
{
/* Select only active announcements for unknown users */
NumAnnouncements = (unsigned) DB_QuerySELECT (&mysql_res,"can not get announcements",
"SELECT AnnCod," // row[0]
"Status," // row[1]
"Roles," // row[2]
"Subject," // row[3]
"Content" // row[4]
" FROM ann_announcements"
" WHERE Status=%u"
" AND (Roles&%u)<>0 "
" ORDER BY AnnCod DESC",
(unsigned) Ann_ACTIVE_ANNOUNCEMENT,
(unsigned) (1 << Rol_UNK));
}
NumAnnouncements = (unsigned)
DB_QuerySELECT (&mysql_res,"can not get announcements",
"SELECT AnnCod," // row[0]
"Status," // row[1]
"Roles," // row[2]
"Subject," // row[3]
"Content" // row[4]
" FROM ann_announcements"
" WHERE Status=%u"
" AND (Roles&%u)<>0 "
" ORDER BY AnnCod DESC",
(unsigned) Ann_ACTIVE_ANNOUNCEMENT,
(unsigned) (1 << Rol_UNK));
/***** Begin box *****/
Box_BoxBegin ("550px",Txt_Announcements,
@ -231,21 +230,22 @@ void Ann_ShowMyAnnouncementsNotMarkedAsSeen (void)
/***** Select announcements not seen *****/
Rol_GetRolesInAllCrssIfNotYetGot (&Gbl.Usrs.Me.UsrDat);
NumAnnouncements = (unsigned) DB_QuerySELECT (&mysql_res,"can not get announcements",
"SELECT AnnCod," // row[0]
"Subject," // row[1]
"Content" // row[2]
" FROM ann_announcements"
" WHERE Status=%u"
" AND (Roles&%u)<>0 " // All my roles in different courses
" AND AnnCod NOT IN"
" (SELECT AnnCod"
" FROM ann_seen"
" WHERE UsrCod=%ld)"
" ORDER BY AnnCod DESC", // Newest first
(unsigned) Ann_ACTIVE_ANNOUNCEMENT,
(unsigned) Gbl.Usrs.Me.UsrDat.Roles.InCrss,
Gbl.Usrs.Me.UsrDat.UsrCod);
NumAnnouncements = (unsigned)
DB_QuerySELECT (&mysql_res,"can not get announcements",
"SELECT AnnCod," // row[0]
"Subject," // row[1]
"Content" // row[2]
" FROM ann_announcements"
" WHERE Status=%u"
" AND (Roles&%u)<>0 " // All my roles in different courses
" AND AnnCod NOT IN"
" (SELECT AnnCod"
" FROM ann_seen"
" WHERE UsrCod=%ld)"
" ORDER BY AnnCod DESC", // Newest first
(unsigned) Ann_ACTIVE_ANNOUNCEMENT,
(unsigned) Gbl.Usrs.Me.UsrDat.Roles.InCrss,
Gbl.Usrs.Me.UsrDat.UsrCod);
/***** Show the announcements *****/
if (NumAnnouncements)

View File

@ -600,13 +600,14 @@ TODO: Salvador Romero Cort
TODO: FIX BUG, URGENT! En las fechas como parámetro Dat_WriteParamsIniEndDates(), por ejemplo al cambiar el color de la gráfica de accesos por día y hora, no se respeta la zona horaria.
*/
#define Log_PLATFORM_VERSION "SWAD 20.61 (2021-04-13)"
#define Log_PLATFORM_VERSION "SWAD 20.62 (2021-04-15)"
#define CSS_FILE "swad20.45.css"
#define JS_FILE "swad20.6.2.js"
/*
TODO: Rename CENTRE to CENTER in help wiki.
TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams
Version 20.62: Apr 15, 2021 Optimizations in database selects related to roles. (308574 lines)
Version 20.61: Apr 13, 2021 Optimizations in database selects. (308567 lines)
Version 20.60: Apr 07, 2021 Optimizations in database selects. (308790 lines)
Version 20.59: Apr 06, 2021 Optimizations in database selects. (308903 lines)

View File

@ -352,7 +352,7 @@ static unsigned Cht_GetNumUsrsInChatRoom (const char *RoomCode)
/***** Get number of users connected to chat rooms from database *****/
return DB_QuerySELECTUnsigned ("can not get number of users"
" connected to a chat room",
"SELECT NumUsrs" // row[0]
"SELECT NumUsrs"
" FROM cht_rooms"
" WHERE RoomCode='%s'",
RoomCode);

View File

@ -3906,6 +3906,40 @@ double DB_QuerySELECTDouble (const char *MsgError,
return DoubleNum;
}
/*****************************************************************************/
/***** Make a SELECT query for a unique row with one role from database ******/
/*****************************************************************************/
Rol_Role_t DB_QuerySELECTRole (const char *MsgError,
const char *fmt,...)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
va_list ap;
int NumBytesPrinted;
char *Query;
Rol_Role_t Role = Rol_UNK;
/***** Create query string *****/
va_start (ap,fmt);
NumBytesPrinted = vasprintf (&Query,fmt,ap);
va_end (ap);
if (NumBytesPrinted < 0) // -1 if no memory or any other error
Lay_NotEnoughMemoryExit ();
/***** Do SELECT query *****/
if (DB_QuerySELECTusingQueryStr (Query,&mysql_res,MsgError)) // Row found
{
row = mysql_fetch_row (mysql_res);
if (row[0])
Role = Rol_ConvertUnsignedStrToRole (row[0]);
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
return Role;
}
/*****************************************************************************/
/**** Make a SELECT query for a unique row with one double from database *****/

View File

@ -29,6 +29,8 @@
#include <mysql/mysql.h> // To access MySQL databases
#include "swad_role.h"
/*****************************************************************************/
/***************************** Public prototypes *****************************/
/*****************************************************************************/
@ -47,6 +49,8 @@ unsigned DB_QuerySELECTUnsigned (const char *MsgError,
const char *fmt,...);
double DB_QuerySELECTDouble (const char *MsgError,
const char *fmt,...);
Rol_Role_t DB_QuerySELECTRole (const char *MsgError,
const char *fmt,...);
void DB_QuerySELECTString (char *Str,size_t StrSize,const char *MsgError,
const char *fmt,...);

View File

@ -260,8 +260,8 @@ void Enr_ModifyRoleInCurrentCrs (struct UsrData *UsrDat,Rol_Role_t NewRole)
Usr_FlushCachesUsr ();
/***** Set user's roles *****/
UsrDat->Roles.InCurrentCrs.Role = NewRole;
UsrDat->Roles.InCurrentCrs.Valid = true;
UsrDat->Roles.InCurrentCrs.Role = NewRole;
UsrDat->Roles.InCurrentCrs.Filled = true;
UsrDat->Roles.InCrss = -1; // Force roles to be got from database
Rol_GetRolesInAllCrssIfNotYetGot (UsrDat); // Get roles
@ -326,8 +326,8 @@ void Enr_RegisterUsrInCurrentCrs (struct UsrData *UsrDat,Rol_Role_t NewRole,
Usr_FlushCachesUsr ();
/***** Set roles *****/
UsrDat->Roles.InCurrentCrs.Role = NewRole;
UsrDat->Roles.InCurrentCrs.Valid = true;
UsrDat->Roles.InCurrentCrs.Role = NewRole;
UsrDat->Roles.InCurrentCrs.Filled = true;
UsrDat->Roles.InCrss = -1; // Force roles to be got from database
Rol_GetRolesInAllCrssIfNotYetGot (UsrDat); // Get roles
@ -3960,8 +3960,8 @@ void Enr_ModifyUsr1 (void)
/***** If it's me, change my roles *****/
if (ItsMe)
{
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role = Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs.Role;
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Valid = true;
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role = Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs.Role;
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Filled = true;
Gbl.Usrs.Me.UsrDat.Roles.InCrss = Gbl.Usrs.Other.UsrDat.Roles.InCrss;
Rol_SetMyRoles ();
}
@ -4243,8 +4243,8 @@ static void Enr_EffectivelyRemUsrFromCrs (struct UsrData *UsrDat,
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role =
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Valid =
UsrDat->Roles.InCurrentCrs.Valid = true;
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Filled =
UsrDat->Roles.InCurrentCrs.Filled = true;
Gbl.Usrs.Me.UsrDat.Roles.InCrss =
UsrDat->Roles.InCrss = -1; // not yet filled/calculated
@ -4254,9 +4254,9 @@ static void Enr_EffectivelyRemUsrFromCrs (struct UsrData *UsrDat,
else // Not me
{
/* Now he/she does not belong to current course */
UsrDat->Accepted = false;
UsrDat->Roles.InCurrentCrs.Role = Rol_USR;
UsrDat->Roles.InCurrentCrs.Valid = false;
UsrDat->Accepted = false;
UsrDat->Roles.InCurrentCrs.Role = Rol_USR;
UsrDat->Roles.InCurrentCrs.Filled = false; // TODO: Set to true?
}
if (QuietOrVerbose == Cns_VERBOSE)

View File

@ -1777,7 +1777,7 @@ unsigned Exa_GetPrevQuestionIndexInExam (long ExaCod,unsigned QstInd)
// Although indexes are always continuous...
// ...this implementation works even with non continuous indexes
return DB_QuerySELECTUnsigned ("can not get previous question index",
"SELECT MAX(QstInd)" // row[0]
"SELECT MAX(QstInd)"
" FROM exa_set_questions"
" WHERE ExaCod=%ld"
" AND QstInd<%u",

View File

@ -4048,7 +4048,7 @@ static void Fig_GetAndShowFollowStats (void)
case Hie_Lvl_SYS:
Average = DB_QuerySELECTDouble ("can not get number of questions"
" per survey",
"SELECT AVG(N)" // row[0]
"SELECT AVG(N)"
" FROM (SELECT COUNT(%s) AS N"
" FROM usr_follow"
" GROUP BY %s) AS F",
@ -4058,7 +4058,7 @@ static void Fig_GetAndShowFollowStats (void)
case Hie_Lvl_CTY:
Average = DB_QuerySELECTDouble ("can not get number of questions"
" per survey",
"SELECT AVG(N)" // row[0]
"SELECT AVG(N)"
" FROM (SELECT COUNT(DISTINCT usr_follow.%s) AS N"
" FROM ins_instits,"
"ctr_centers,"
@ -4081,7 +4081,7 @@ static void Fig_GetAndShowFollowStats (void)
case Hie_Lvl_INS:
Average = DB_QuerySELECTDouble ("can not get number of questions"
" per survey",
"SELECT AVG(N)" // row[0]
"SELECT AVG(N)"
" FROM (SELECT COUNT(DISTINCT usr_follow.%s) AS N"
" FROM ctr_centers,"
"deg_degrees,"
@ -4102,7 +4102,7 @@ static void Fig_GetAndShowFollowStats (void)
case Hie_Lvl_CTR:
Average = DB_QuerySELECTDouble ("can not get number of questions"
" per survey",
"SELECT AVG(N)" // row[0]
"SELECT AVG(N)"
" FROM (SELECT COUNT(DISTINCT usr_follow.%s) AS N"
" FROM deg_degrees,"
"crs_courses,"
@ -4121,7 +4121,7 @@ static void Fig_GetAndShowFollowStats (void)
case Hie_Lvl_DEG:
Average = DB_QuerySELECTDouble ("can not get number of questions"
" per survey",
"SELECT AVG(N)" // row[0]
"SELECT AVG(N)"
" FROM (SELECT COUNT(DISTINCT usr_follow.%s) AS N"
" FROM crs_courses,"
"crs_users,"
@ -4138,7 +4138,7 @@ static void Fig_GetAndShowFollowStats (void)
case Hie_Lvl_CRS:
Average = DB_QuerySELECTDouble ("can not get number of questions"
" per survey",
"SELECT AVG(N)" // row[0]
"SELECT AVG(N)"
" FROM (SELECT COUNT(DISTINCT usr_follow.%s) AS N"
" FROM crs_users,"
"usr_follow"

View File

@ -338,6 +338,7 @@ void Gbl_InitializeGlobals (void)
Usr_FlushCacheUsrBelongsToCurrentCrs ();
Usr_FlushCacheUsrHasAcceptedInCurrentCrs ();
Usr_FlushCacheUsrSharesAnyOfMyCrs ();
Rol_FlushCacheMyRoleInCurrentCrs ();
Rol_FlushCacheRoleUsrInCrs ();
Prj_FlushCacheMyRolesInProject ();
Grp_FlushCacheIBelongToGrp ();

View File

@ -602,6 +602,11 @@ struct Globals
long CrsCod;
Rol_Role_t Role;
} RoleUsrInCrs;
struct
{
bool Cached;
Rol_Role_t Role;
} MyRoleInCurrentCrs;
struct
{
long PrjCod;

View File

@ -314,9 +314,9 @@ bool Prf_ShowUserProfile (struct UsrData *UsrDat)
Gbl.Hierarchy.Level == Hie_Lvl_CRS) // ...and a course is selected
{
/* Get user's role in current course */
UsrDat->Roles.InCurrentCrs.Role = Rol_GetRoleUsrInCrs (UsrDat->UsrCod,
Gbl.Hierarchy.Crs.CrsCod);
UsrDat->Roles.InCurrentCrs.Valid = true;
UsrDat->Roles.InCurrentCrs.Role = Rol_GetRoleUsrInCrs (UsrDat->UsrCod,
Gbl.Hierarchy.Crs.CrsCod);
UsrDat->Roles.InCurrentCrs.Filled = true;
/* Get if user has accepted enrolment in current course */
UsrDat->Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (UsrDat);

View File

@ -2050,9 +2050,9 @@ void Rec_ShowFormOtherNewSharedRecord (struct UsrData *UsrDat,Rol_Role_t Default
/* In this case UsrDat->Roles.InCurrentCrsDB
is not the current role in current course.
Instead it is initialized with the preferred role. */
UsrDat->Roles.InCurrentCrs.Role = (Gbl.Hierarchy.Level == Hie_Lvl_CRS) ? DefaultRole : // Course selected
Rol_UNK; // No course selected
UsrDat->Roles.InCurrentCrs.Valid = true;
UsrDat->Roles.InCurrentCrs.Role = (Gbl.Hierarchy.Level == Hie_Lvl_CRS) ? DefaultRole : // Course selected
Rol_UNK; // No course selected
UsrDat->Roles.InCurrentCrs.Filled = true;
Rec_ShowSharedUsrRecord (Rec_SHA_OTHER_NEW_USR_FORM,UsrDat,NULL);
}

View File

@ -85,10 +85,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.Valid)
if (!Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Filled)
{
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role = Rol_GetMyRoleInCrs (Gbl.Hierarchy.Crs.CrsCod);
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Valid = true;
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role = Rol_GetMyRoleInCrs (Gbl.Hierarchy.Crs.CrsCod);
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Filled = true;
}
/***** Set the user's role I am logged *****/
@ -315,44 +315,68 @@ Rol_Role_t Rol_GetMyMaxRoleInDeg (long DegCod)
{
unsigned NumMyDeg;
if (DegCod > 0)
{
/***** Fill the list with the degrees I belong to (if not already filled) *****/
Usr_GetMyDegrees ();
/***** 1. Fast check: trivial cases *****/
if (DegCod <= 0)
return Rol_UNK;
/***** Check if the degree passed as parameter is any of my degrees *****/
for (NumMyDeg = 0;
NumMyDeg < Gbl.Usrs.Me.MyDegs.Num;
NumMyDeg++)
if (Gbl.Usrs.Me.MyDegs.Degs[NumMyDeg].DegCod == DegCod)
return Gbl.Usrs.Me.MyDegs.Degs[NumMyDeg].MaxRole;
return Rol_GST;
}
return Rol_UNK; // No degree
/***** Fill the list with the degrees I belong to (if not already filled) *****/
Usr_GetMyDegrees ();
/***** Check if the degree passed as parameter is any of my degrees *****/
for (NumMyDeg = 0;
NumMyDeg < Gbl.Usrs.Me.MyDegs.Num;
NumMyDeg++)
if (Gbl.Usrs.Me.MyDegs.Degs[NumMyDeg].DegCod == DegCod)
return Gbl.Usrs.Me.MyDegs.Degs[NumMyDeg].MaxRole;
return Rol_GST;
}
/*****************************************************************************/
/*************************** Get my role in a course *************************/
/*****************************************************************************/
void Rol_FlushCacheMyRoleInCurrentCrs (void)
{
Gbl.Cache.MyRoleInCurrentCrs.Cached = false;
Gbl.Cache.MyRoleInCurrentCrs.Role = Rol_UNK;
}
Rol_Role_t Rol_GetMyRoleInCrs (long CrsCod)
{
unsigned NumMyCrs;
Rol_Role_t Role;
if (CrsCod > 0)
/***** 1. Fast check: trivial cases *****/
if (CrsCod <= 0)
return Rol_UNK;
/***** 2. Fast check: is my role in current course already calculated? *****/
if (CrsCod == Gbl.Hierarchy.Crs.CrsCod &&
Gbl.Cache.MyRoleInCurrentCrs.Cached)
return Gbl.Cache.MyRoleInCurrentCrs.Role;
/***** 3. Slow check: get my role from list of my courses *****/
/* Fill the list with the courses I belong to (if not already filled) */
Usr_GetMyCourses ();
/* Check if the current course is any of my courses */
for (NumMyCrs = 0, Role = Rol_UNK;
NumMyCrs < Gbl.Usrs.Me.MyCrss.Num;
NumMyCrs++)
if (Gbl.Usrs.Me.MyCrss.Crss[NumMyCrs].CrsCod == CrsCod)
{
Role = Gbl.Usrs.Me.MyCrss.Crss[NumMyCrs].Role;
break;
}
/* Update my role in current course */
if (CrsCod == Gbl.Hierarchy.Crs.CrsCod)
{
/***** Fill the list with the courses I belong to (if not already filled) *****/
Usr_GetMyCourses ();
/***** Check if the course is any of my courses *****/
for (NumMyCrs = 0;
NumMyCrs < Gbl.Usrs.Me.MyCrss.Num;
NumMyCrs++)
if (Gbl.Usrs.Me.MyCrss.Crss[NumMyCrs].CrsCod == CrsCod)
return Gbl.Usrs.Me.MyCrss.Crss[NumMyCrs].Role;
Gbl.Cache.MyRoleInCurrentCrs.Role = Role;
Gbl.Cache.MyRoleInCurrentCrs.Cached = true;
}
return Rol_UNK;
return Role;
}
/*****************************************************************************/
@ -363,14 +387,11 @@ void Rol_FlushCacheRoleUsrInCrs (void)
{
Gbl.Cache.RoleUsrInCrs.UsrCod = -1L;
Gbl.Cache.RoleUsrInCrs.CrsCod = -1L;
Gbl.Cache.RoleUsrInCrs.Role = Rol_UNK;
Gbl.Cache.RoleUsrInCrs.Role = Rol_UNK;
}
Rol_Role_t Rol_GetRoleUsrInCrs (long UsrCod,long CrsCod)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
/***** 1. Fast check: trivial cases *****/
if (UsrCod <= 0 ||
CrsCod <= 0)
@ -378,26 +399,26 @@ Rol_Role_t Rol_GetRoleUsrInCrs (long UsrCod,long CrsCod)
/***** 2. Fast check: Is role in course already calculated? *****/
if (UsrCod == Gbl.Cache.RoleUsrInCrs.UsrCod &&
CrsCod == Gbl.Cache.RoleUsrInCrs.CrsCod )
CrsCod == Gbl.Cache.RoleUsrInCrs.CrsCod)
return Gbl.Cache.RoleUsrInCrs.Role;
/***** 3. Slow check: Get rol of a user in a course from database.
/***** 3. Slow check: Get role of a user in a course from database.
The result of the query will have one row or none *****/
Gbl.Cache.RoleUsrInCrs.UsrCod = UsrCod;
Gbl.Cache.RoleUsrInCrs.CrsCod = CrsCod;
Gbl.Cache.RoleUsrInCrs.Role = Rol_UNK;
if (DB_QuerySELECT (&mysql_res,"can not get the role of a user in a course",
"SELECT Role" // row[0]
" FROM crs_users"
" WHERE CrsCod=%ld"
" AND UsrCod=%ld",
CrsCod,UsrCod) == 1) // User belongs to the course
{
row = mysql_fetch_row (mysql_res);
Gbl.Cache.RoleUsrInCrs.Role = Rol_ConvertUnsignedStrToRole (row[0]);
}
DB_FreeMySQLResult (&mysql_res);
if (UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod) // It's me
/* Get my role in course */
Gbl.Cache.RoleUsrInCrs.Role = Rol_GetMyRoleInCrs (CrsCod);
else
/* Get role of the user in course from database */
Gbl.Cache.RoleUsrInCrs.Role =
DB_QuerySELECTRole ("can not get the role of a user in a course",
"SELECT Role"
" FROM crs_users"
" WHERE CrsCod=%ld"
" AND UsrCod=%ld",
CrsCod,
UsrCod);
return Gbl.Cache.RoleUsrInCrs.Role;
}

View File

@ -45,6 +45,7 @@ Rol_Role_t Rol_GetMaxRoleInCrss (unsigned Roles);
Rol_Role_t Rol_GetMyMaxRoleInIns (long InsCod);
Rol_Role_t Rol_GetMyMaxRoleInCtr (long CtrCod);
Rol_Role_t Rol_GetMyMaxRoleInDeg (long DegCod);
void Rol_FlushCacheMyRoleInCurrentCrs (void);
Rol_Role_t Rol_GetMyRoleInCrs (long CrsCod);
void Rol_FlushCacheRoleUsrInCrs (void);
Rol_Role_t Rol_GetRoleUsrInCrs (long UsrCod,long CrsCod);

View File

@ -323,8 +323,8 @@ void Usr_ResetUsrDataExceptUsrCodAndIDs (struct UsrData *UsrDat)
UsrDat->EnUsrCod[0] = '\0';
UsrDat->Nickname[0] = '\0';
UsrDat->Password[0] = '\0';
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
UsrDat->Roles.InCurrentCrs.Valid = false;
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
UsrDat->Roles.InCurrentCrs.Filled = false;
UsrDat->Roles.InCrss = -1; // < 0 ==> not yet got from database
UsrDat->Accepted = false;
@ -589,9 +589,9 @@ void Usr_GetUsrDataFromUsrCod (struct UsrData *UsrDat,Usr_GetPrefs_t GetPrefs)
Str_Copy (UsrDat->Password,row[1],sizeof (UsrDat->Password) - 1);
/* Get roles */
UsrDat->Roles.InCurrentCrs.Role = Rol_GetRoleUsrInCrs (UsrDat->UsrCod,
Gbl.Hierarchy.Crs.CrsCod);
UsrDat->Roles.InCurrentCrs.Valid = true;
UsrDat->Roles.InCurrentCrs.Role = Rol_GetRoleUsrInCrs (UsrDat->UsrCod,
Gbl.Hierarchy.Crs.CrsCod);
UsrDat->Roles.InCurrentCrs.Filled = true;
UsrDat->Roles.InCrss = -1; // Force roles to be got from database
Rol_GetRolesInAllCrssIfNotYetGot (UsrDat);
@ -894,6 +894,7 @@ void Usr_FlushCachesUsr (void)
Usr_FlushCacheUsrBelongsToCurrentCrs ();
Usr_FlushCacheUsrHasAcceptedInCurrentCrs ();
Usr_FlushCacheUsrSharesAnyOfMyCrs ();
Rol_FlushCacheMyRoleInCurrentCrs ();
Rol_FlushCacheRoleUsrInCrs ();
Grp_FlushCacheUsrSharesAnyOfMyGrpsInCurrentCrs ();
Grp_FlushCacheIBelongToGrp ();
@ -2077,9 +2078,9 @@ bool Usr_CheckIfUsrBelongsToCurrentCrs (const struct UsrData *UsrDat)
return Gbl.Cache.UsrBelongsToCurrentCrs.Belongs;
/***** 3. Fast check: If we know role of user in the current course *****/
if (UsrDat->Roles.InCurrentCrs.Valid)
if (UsrDat->Roles.InCurrentCrs.Filled)
{
Gbl.Cache.UsrBelongsToCurrentCrs.UsrCod = 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;
@ -2087,7 +2088,7 @@ bool Usr_CheckIfUsrBelongsToCurrentCrs (const struct UsrData *UsrDat)
}
/***** 4. Fast / slow check: Get if user belongs to current course *****/
Gbl.Cache.UsrBelongsToCurrentCrs.UsrCod = UsrDat->UsrCod;
Gbl.Cache.UsrBelongsToCurrentCrs.UsrCod = UsrDat->UsrCod;
Gbl.Cache.UsrBelongsToCurrentCrs.Belongs = Usr_CheckIfUsrBelongsToCrs (UsrDat->UsrCod,
Gbl.Hierarchy.Crs.CrsCod,
false);
@ -3415,9 +3416,8 @@ static void Usr_SetMyPrefsAndRoles (void)
/* Course may have changed ==> get my role in current course again */
if (Gbl.Hierarchy.Level == Hie_Lvl_CRS) // Course selected
{
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role = Rol_GetRoleUsrInCrs (Gbl.Usrs.Me.UsrDat.UsrCod,
Gbl.Hierarchy.Crs.CrsCod);
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Valid = true;
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role = Rol_GetMyRoleInCrs (Gbl.Hierarchy.Crs.CrsCod);
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Filled = true;
}
// role and action will be got from last data
@ -9745,7 +9745,7 @@ static double Usr_GetNumCrssPerUsr (Hie_Lvl_Level_t Scope,long Cod,Rol_Role_t Ro
Cod);
else
return DB_QuerySELECTDouble ("can not get number of courses per user",
"SELECT AVG(NumCrss)" // row[0]
"SELECT AVG(NumCrss)"
" FROM (SELECT COUNT(crs_users.CrsCod) AS NumCrss"
" FROM ins_instits,"
"ctr_centers,"
@ -9764,7 +9764,7 @@ static double Usr_GetNumCrssPerUsr (Hie_Lvl_Level_t Scope,long Cod,Rol_Role_t Ro
case Hie_Lvl_INS:
if (Role == Rol_UNK) // Any user
return DB_QuerySELECTDouble ("can not get number of courses per user",
"SELECT AVG(NumCrss)" // row[0]
"SELECT AVG(NumCrss)"
" FROM (SELECT COUNT(crs_users.CrsCod) AS NumCrss"
" FROM ctr_centers,"
"deg_degrees,"
@ -9778,7 +9778,7 @@ static double Usr_GetNumCrssPerUsr (Hie_Lvl_Level_t Scope,long Cod,Rol_Role_t Ro
Cod);
else
return DB_QuerySELECTDouble ("can not get number of courses per user",
"SELECT AVG(NumCrss)" // row[0]
"SELECT AVG(NumCrss)"
" FROM (SELECT COUNT(crs_users.CrsCod) AS NumCrss"
" FROM ctr_centers,"
"deg_degrees,"
@ -9795,7 +9795,7 @@ static double Usr_GetNumCrssPerUsr (Hie_Lvl_Level_t Scope,long Cod,Rol_Role_t Ro
case Hie_Lvl_CTR:
if (Role == Rol_UNK) // Any user
return DB_QuerySELECTDouble ("can not get number of courses per user",
"SELECT AVG(NumCrss)" // row[0]
"SELECT AVG(NumCrss)"
" FROM (SELECT COUNT(crs_users.CrsCod) AS NumCrss"
" FROM deg_degrees,"
"crs_courses,"
@ -9807,7 +9807,7 @@ static double Usr_GetNumCrssPerUsr (Hie_Lvl_Level_t Scope,long Cod,Rol_Role_t Ro
Cod);
else
return DB_QuerySELECTDouble ("can not get number of courses per user",
"SELECT AVG(NumCrss)" // row[0]
"SELECT AVG(NumCrss)"
" FROM (SELECT COUNT(crs_users.CrsCod) AS NumCrss"
" FROM deg_degrees,"
"crs_courses,"
@ -9822,7 +9822,7 @@ static double Usr_GetNumCrssPerUsr (Hie_Lvl_Level_t Scope,long Cod,Rol_Role_t Ro
case Hie_Lvl_DEG:
if (Role == Rol_UNK) // Any user
return DB_QuerySELECTDouble ("can not get number of courses per user",
"SELECT AVG(NumCrss)" // row[0]
"SELECT AVG(NumCrss)"
" FROM (SELECT COUNT(crs_users.CrsCod) AS NumCrss"
" FROM crs_courses,"
"crs_users"
@ -9832,7 +9832,7 @@ static double Usr_GetNumCrssPerUsr (Hie_Lvl_Level_t Scope,long Cod,Rol_Role_t Ro
Cod);
else
return DB_QuerySELECTDouble ("can not get number of courses per user",
"SELECT AVG(NumCrss)" // row[0]
"SELECT AVG(NumCrss)"
" FROM (SELECT COUNT(crs_users.CrsCod) AS NumCrss"
" FROM crs_courses,"
"crs_users"
@ -9886,13 +9886,13 @@ static double Usr_GetNumUsrsPerCrs (Hie_Lvl_Level_t Scope,long Cod,Rol_Role_t Ro
case Hie_Lvl_SYS:
if (Role == Rol_UNK) // Any user
return DB_QuerySELECTDouble ("can not get number of users per course",
"SELECT AVG(NumUsrs)" // row[0]
"SELECT AVG(NumUsrs)"
" FROM (SELECT COUNT(UsrCod) AS NumUsrs"
" FROM crs_users"
" GROUP BY CrsCod) AS NumUsrsTable");
else
return DB_QuerySELECTDouble ("can not get number of users per course",
"SELECT AVG(NumUsrs)" // row[0]
"SELECT AVG(NumUsrs)"
" FROM (SELECT COUNT(UsrCod) AS NumUsrs"
" FROM crs_users"
" WHERE Role=%u GROUP BY CrsCod) AS NumUsrsTable",
@ -9900,7 +9900,7 @@ static double Usr_GetNumUsrsPerCrs (Hie_Lvl_Level_t Scope,long Cod,Rol_Role_t Ro
case Hie_Lvl_CTY:
if (Role == Rol_UNK) // Any user
return DB_QuerySELECTDouble ("can not get number of users per course",
"SELECT AVG(NumUsrs)" // row[0]
"SELECT AVG(NumUsrs)"
" FROM (SELECT COUNT(crs_users.UsrCod) AS NumUsrs"
" FROM ins_instits,"
"ctr_centers,"
@ -9916,7 +9916,7 @@ static double Usr_GetNumUsrsPerCrs (Hie_Lvl_Level_t Scope,long Cod,Rol_Role_t Ro
Cod);
else
return DB_QuerySELECTDouble ("can not get number of users per course",
"SELECT AVG(NumUsrs)" // row[0]
"SELECT AVG(NumUsrs)"
" FROM (SELECT COUNT(crs_users.UsrCod) AS NumUsrs"
" FROM ins_instits,"
"ctr_centers,"
@ -9935,7 +9935,7 @@ static double Usr_GetNumUsrsPerCrs (Hie_Lvl_Level_t Scope,long Cod,Rol_Role_t Ro
case Hie_Lvl_INS:
if (Role == Rol_UNK) // Any user
return DB_QuerySELECTDouble ("can not get number of users per course",
"SELECT AVG(NumUsrs)" // row[0]
"SELECT AVG(NumUsrs)"
" FROM (SELECT COUNT(crs_users.UsrCod) AS NumUsrs"
" FROM ctr_centers,"
"deg_degrees,"
@ -9949,7 +9949,7 @@ static double Usr_GetNumUsrsPerCrs (Hie_Lvl_Level_t Scope,long Cod,Rol_Role_t Ro
Cod);
else
return DB_QuerySELECTDouble ("can not get number of users per course",
"SELECT AVG(NumUsrs)" // row[0]
"SELECT AVG(NumUsrs)"
" FROM (SELECT COUNT(crs_users.UsrCod) AS NumUsrs"
" FROM ctr_centers,"
"deg_degrees,"
@ -9966,7 +9966,7 @@ static double Usr_GetNumUsrsPerCrs (Hie_Lvl_Level_t Scope,long Cod,Rol_Role_t Ro
case Hie_Lvl_CTR:
if (Role == Rol_UNK) // Any user
return DB_QuerySELECTDouble ("can not get number of users per course",
"SELECT AVG(NumUsrs)" // row[0]
"SELECT AVG(NumUsrs)"
" FROM (SELECT COUNT(crs_users.UsrCod) AS NumUsrs"
" FROM deg_degrees,"
"crs_courses,"
@ -9978,7 +9978,7 @@ static double Usr_GetNumUsrsPerCrs (Hie_Lvl_Level_t Scope,long Cod,Rol_Role_t Ro
Cod);
else
return DB_QuerySELECTDouble ("can not get number of users per course",
"SELECT AVG(NumUsrs)" // row[0]
"SELECT AVG(NumUsrs)"
" FROM (SELECT COUNT(crs_users.UsrCod) AS NumUsrs"
" FROM deg_degrees,"
"crs_courses,"
@ -9993,7 +9993,7 @@ static double Usr_GetNumUsrsPerCrs (Hie_Lvl_Level_t Scope,long Cod,Rol_Role_t Ro
case Hie_Lvl_DEG:
if (Role == Rol_UNK) // Any user
return DB_QuerySELECTDouble ("can not get number of users per course",
"SELECT AVG(NumUsrs)" // row[0]
"SELECT AVG(NumUsrs)"
" FROM (SELECT COUNT(crs_users.UsrCod) AS NumUsrs"
" FROM crs_courses,"
"crs_users"
@ -10003,7 +10003,7 @@ static double Usr_GetNumUsrsPerCrs (Hie_Lvl_Level_t Scope,long Cod,Rol_Role_t Ro
Cod);
else
return DB_QuerySELECTDouble ("can not get number of users per course",
"SELECT AVG(NumUsrs)" // row[0]
"SELECT AVG(NumUsrs)"
" FROM (SELECT COUNT(crs_users.UsrCod) AS NumUsrs"
" FROM crs_courses,"
"crs_users"

View File

@ -171,7 +171,7 @@ struct UsrData
{
struct
{
bool Valid; // Role is valid (is already filled)?
bool Filled; // Role is valid (is already filled)?
Rol_Role_t Role;
} InCurrentCrs; // Role in current course (Rol_UNK is no course selected)
int InCrss; // Roles in all his/her courses