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); Nck_GetNicknameFromUsrCod (UsrDat->UsrCod,UsrDat->Nickname);
/***** Get user's role *****/ /***** Get user's role *****/
/* Query database */
if (CrsCod > 0) if (CrsCod > 0)
{
/* Get the role in the given course */ /* Get the role in the given course */
if (DB_QuerySELECT (&mysql_res,"can not get user's role", UsrDat->Roles.InCurrentCrs.Role =
"SELECT Role" // row[0] DB_QuerySELECTRole ("can not get user's role",
"SELECT Role"
" FROM crs_users" " FROM crs_users"
" WHERE CrsCod=%ld" " WHERE CrsCod=%ld"
" AND UsrCod=%ld", " AND UsrCod=%ld",
CrsCod, CrsCod,
UsrDat->UsrCod)) // User belongs to course UsrDat->UsrCod);
{
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;
}
}
else else
{
/* Get the maximum role in any course */ /* Get the maximum role in any course */
if (DB_QuerySELECT (&mysql_res,"can not get user's role", UsrDat->Roles.InCurrentCrs.Role =
"SELECT MAX(Role)" // row[0] DB_QuerySELECTRole ("can not get user's role",
"SELECT MAX(Role)"
" FROM crs_users" " FROM crs_users"
" WHERE UsrCod=%ld", " WHERE UsrCod=%ld",
UsrDat->UsrCod) == 1) UsrDat->UsrCod);
{ UsrDat->Roles.InCurrentCrs.Filled = true;
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);
return true; return true;
} }

View File

@ -96,48 +96,47 @@ void Ann_ShowAllAnnouncements (void)
/***** Get announcements from database *****/ /***** Get announcements from database *****/
if (ICanEdit) if (ICanEdit)
{
/* Select all announcements */ /* Select all announcements */
NumAnnouncements = (unsigned) DB_QuerySELECT (&mysql_res,"can not get announcements", NumAnnouncements = (unsigned)
"SELECT AnnCod," // row[0] DB_QuerySELECT (&mysql_res,"can not get announcements",
"Status," // row[1] "SELECT AnnCod," // row[0]
"Roles," // row[2] "Status," // row[1]
"Subject," // row[3] "Roles," // row[2]
"Content" // row[4] "Subject," // row[3]
" FROM ann_announcements" "Content" // row[4]
" ORDER BY AnnCod DESC"); " FROM ann_announcements"
} " ORDER BY AnnCod DESC");
else if (Gbl.Usrs.Me.Logged) else if (Gbl.Usrs.Me.Logged)
{ {
/* Select only announcements I can see */ /* Select only announcements I can see */
Rol_GetRolesInAllCrssIfNotYetGot (&Gbl.Usrs.Me.UsrDat); Rol_GetRolesInAllCrssIfNotYetGot (&Gbl.Usrs.Me.UsrDat);
NumAnnouncements = (unsigned) DB_QuerySELECT (&mysql_res,"can not get announcements", NumAnnouncements = (unsigned)
"SELECT AnnCod," // row[0] DB_QuerySELECT (&mysql_res,"can not get announcements",
"Status," // row[1] "SELECT AnnCod," // row[0]
"Roles," // row[2] "Status," // row[1]
"Subject," // row[3] "Roles," // row[2]
"Content" // row[4] "Subject," // row[3]
" FROM ann_announcements" "Content" // row[4]
" WHERE (Roles&%u)<>0 " // All my roles in different courses " FROM ann_announcements"
" ORDER BY AnnCod DESC", " WHERE (Roles&%u)<>0 " // All my roles in different courses
(unsigned) Gbl.Usrs.Me.UsrDat.Roles.InCrss); " ORDER BY AnnCod DESC",
(unsigned) Gbl.Usrs.Me.UsrDat.Roles.InCrss);
} }
else // No user logged else // No user logged
{
/* Select only active announcements for unknown users */ /* Select only active announcements for unknown users */
NumAnnouncements = (unsigned) DB_QuerySELECT (&mysql_res,"can not get announcements", NumAnnouncements = (unsigned)
"SELECT AnnCod," // row[0] DB_QuerySELECT (&mysql_res,"can not get announcements",
"Status," // row[1] "SELECT AnnCod," // row[0]
"Roles," // row[2] "Status," // row[1]
"Subject," // row[3] "Roles," // row[2]
"Content" // row[4] "Subject," // row[3]
" FROM ann_announcements" "Content" // row[4]
" WHERE Status=%u" " FROM ann_announcements"
" AND (Roles&%u)<>0 " " WHERE Status=%u"
" ORDER BY AnnCod DESC", " AND (Roles&%u)<>0 "
(unsigned) Ann_ACTIVE_ANNOUNCEMENT, " ORDER BY AnnCod DESC",
(unsigned) (1 << Rol_UNK)); (unsigned) Ann_ACTIVE_ANNOUNCEMENT,
} (unsigned) (1 << Rol_UNK));
/***** Begin box *****/ /***** Begin box *****/
Box_BoxBegin ("550px",Txt_Announcements, Box_BoxBegin ("550px",Txt_Announcements,
@ -231,21 +230,22 @@ void Ann_ShowMyAnnouncementsNotMarkedAsSeen (void)
/***** Select announcements not seen *****/ /***** Select announcements not seen *****/
Rol_GetRolesInAllCrssIfNotYetGot (&Gbl.Usrs.Me.UsrDat); Rol_GetRolesInAllCrssIfNotYetGot (&Gbl.Usrs.Me.UsrDat);
NumAnnouncements = (unsigned) DB_QuerySELECT (&mysql_res,"can not get announcements", NumAnnouncements = (unsigned)
"SELECT AnnCod," // row[0] DB_QuerySELECT (&mysql_res,"can not get announcements",
"Subject," // row[1] "SELECT AnnCod," // row[0]
"Content" // row[2] "Subject," // row[1]
" FROM ann_announcements" "Content" // row[2]
" WHERE Status=%u" " FROM ann_announcements"
" AND (Roles&%u)<>0 " // All my roles in different courses " WHERE Status=%u"
" AND AnnCod NOT IN" " AND (Roles&%u)<>0 " // All my roles in different courses
" (SELECT AnnCod" " AND AnnCod NOT IN"
" FROM ann_seen" " (SELECT AnnCod"
" WHERE UsrCod=%ld)" " FROM ann_seen"
" ORDER BY AnnCod DESC", // Newest first " WHERE UsrCod=%ld)"
(unsigned) Ann_ACTIVE_ANNOUNCEMENT, " ORDER BY AnnCod DESC", // Newest first
(unsigned) Gbl.Usrs.Me.UsrDat.Roles.InCrss, (unsigned) Ann_ACTIVE_ANNOUNCEMENT,
Gbl.Usrs.Me.UsrDat.UsrCod); (unsigned) Gbl.Usrs.Me.UsrDat.Roles.InCrss,
Gbl.Usrs.Me.UsrDat.UsrCod);
/***** Show the announcements *****/ /***** Show the announcements *****/
if (NumAnnouncements) 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. 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 CSS_FILE "swad20.45.css"
#define JS_FILE "swad20.6.2.js" #define JS_FILE "swad20.6.2.js"
/* /*
TODO: Rename CENTRE to CENTER in help wiki. TODO: Rename CENTRE to CENTER in help wiki.
TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams 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.61: Apr 13, 2021 Optimizations in database selects. (308567 lines)
Version 20.60: Apr 07, 2021 Optimizations in database selects. (308790 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) 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 *****/ /***** Get number of users connected to chat rooms from database *****/
return DB_QuerySELECTUnsigned ("can not get number of users" return DB_QuerySELECTUnsigned ("can not get number of users"
" connected to a chat room", " connected to a chat room",
"SELECT NumUsrs" // row[0] "SELECT NumUsrs"
" FROM cht_rooms" " FROM cht_rooms"
" WHERE RoomCode='%s'", " WHERE RoomCode='%s'",
RoomCode); RoomCode);

View File

@ -3906,6 +3906,40 @@ double DB_QuerySELECTDouble (const char *MsgError,
return DoubleNum; 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 *****/ /**** 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 <mysql/mysql.h> // To access MySQL databases
#include "swad_role.h"
/*****************************************************************************/ /*****************************************************************************/
/***************************** Public prototypes *****************************/ /***************************** Public prototypes *****************************/
/*****************************************************************************/ /*****************************************************************************/
@ -47,6 +49,8 @@ unsigned DB_QuerySELECTUnsigned (const char *MsgError,
const char *fmt,...); const char *fmt,...);
double DB_QuerySELECTDouble (const char *MsgError, double DB_QuerySELECTDouble (const char *MsgError,
const char *fmt,...); 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, void DB_QuerySELECTString (char *Str,size_t StrSize,const char *MsgError,
const char *fmt,...); const char *fmt,...);

View File

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

View File

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

View File

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

View File

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

View File

@ -602,6 +602,11 @@ struct Globals
long CrsCod; long CrsCod;
Rol_Role_t Role; Rol_Role_t Role;
} RoleUsrInCrs; } RoleUsrInCrs;
struct
{
bool Cached;
Rol_Role_t Role;
} MyRoleInCurrentCrs;
struct struct
{ {
long PrjCod; 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 Gbl.Hierarchy.Level == Hie_Lvl_CRS) // ...and a course is selected
{ {
/* Get user's role in current course */ /* Get user's role in current course */
UsrDat->Roles.InCurrentCrs.Role = Rol_GetRoleUsrInCrs (UsrDat->UsrCod, UsrDat->Roles.InCurrentCrs.Role = Rol_GetRoleUsrInCrs (UsrDat->UsrCod,
Gbl.Hierarchy.Crs.CrsCod); Gbl.Hierarchy.Crs.CrsCod);
UsrDat->Roles.InCurrentCrs.Valid = true; UsrDat->Roles.InCurrentCrs.Filled = true;
/* Get if user has accepted enrolment in current course */ /* Get if user has accepted enrolment in current course */
UsrDat->Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (UsrDat); 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 /* In this case UsrDat->Roles.InCurrentCrsDB
is not the current role in current course. is not the current role in current course.
Instead it is initialized with the preferred role. */ Instead it is initialized with the preferred role. */
UsrDat->Roles.InCurrentCrs.Role = (Gbl.Hierarchy.Level == Hie_Lvl_CRS) ? DefaultRole : // Course selected UsrDat->Roles.InCurrentCrs.Role = (Gbl.Hierarchy.Level == Hie_Lvl_CRS) ? DefaultRole : // Course selected
Rol_UNK; // No course selected Rol_UNK; // No course selected
UsrDat->Roles.InCurrentCrs.Valid = true; UsrDat->Roles.InCurrentCrs.Filled = true;
Rec_ShowSharedUsrRecord (Rec_SHA_OTHER_NEW_USR_FORM,UsrDat,NULL); Rec_ShowSharedUsrRecord (Rec_SHA_OTHER_NEW_USR_FORM,UsrDat,NULL);
} }

View File

@ -85,10 +85,10 @@ void Rol_SetMyRoles (void)
bool ICanBeDegAdm = false; bool ICanBeDegAdm = false;
/***** Get my role in current course if not yet filled *****/ /***** 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.Role = Rol_GetMyRoleInCrs (Gbl.Hierarchy.Crs.CrsCod);
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Valid = true; Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Filled = true;
} }
/***** Set the user's role I am logged *****/ /***** Set the user's role I am logged *****/
@ -315,44 +315,68 @@ Rol_Role_t Rol_GetMyMaxRoleInDeg (long DegCod)
{ {
unsigned NumMyDeg; unsigned NumMyDeg;
if (DegCod > 0) /***** 1. Fast check: trivial cases *****/
{ if (DegCod <= 0)
/***** Fill the list with the degrees I belong to (if not already filled) *****/ return Rol_UNK;
Usr_GetMyDegrees ();
/***** Check if the degree passed as parameter is any of my degrees *****/ /***** Fill the list with the degrees I belong to (if not already filled) *****/
for (NumMyDeg = 0; Usr_GetMyDegrees ();
NumMyDeg < Gbl.Usrs.Me.MyDegs.Num;
NumMyDeg++) /***** Check if the degree passed as parameter is any of my degrees *****/
if (Gbl.Usrs.Me.MyDegs.Degs[NumMyDeg].DegCod == DegCod) for (NumMyDeg = 0;
return Gbl.Usrs.Me.MyDegs.Degs[NumMyDeg].MaxRole; NumMyDeg < Gbl.Usrs.Me.MyDegs.Num;
return Rol_GST; NumMyDeg++)
} if (Gbl.Usrs.Me.MyDegs.Degs[NumMyDeg].DegCod == DegCod)
return Rol_UNK; // No degree return Gbl.Usrs.Me.MyDegs.Degs[NumMyDeg].MaxRole;
return Rol_GST;
} }
/*****************************************************************************/ /*****************************************************************************/
/*************************** Get my role in a course *************************/ /*************************** 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) Rol_Role_t Rol_GetMyRoleInCrs (long CrsCod)
{ {
unsigned NumMyCrs; 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) *****/ Gbl.Cache.MyRoleInCurrentCrs.Role = Role;
Usr_GetMyCourses (); Gbl.Cache.MyRoleInCurrentCrs.Cached = true;
/***** 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;
} }
return Rol_UNK; return Role;
} }
/*****************************************************************************/ /*****************************************************************************/
@ -363,14 +387,11 @@ void Rol_FlushCacheRoleUsrInCrs (void)
{ {
Gbl.Cache.RoleUsrInCrs.UsrCod = -1L; Gbl.Cache.RoleUsrInCrs.UsrCod = -1L;
Gbl.Cache.RoleUsrInCrs.CrsCod = -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) Rol_Role_t Rol_GetRoleUsrInCrs (long UsrCod,long CrsCod)
{ {
MYSQL_RES *mysql_res;
MYSQL_ROW row;
/***** 1. Fast check: trivial cases *****/ /***** 1. Fast check: trivial cases *****/
if (UsrCod <= 0 || if (UsrCod <= 0 ||
CrsCod <= 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? *****/ /***** 2. Fast check: Is role in course already calculated? *****/
if (UsrCod == Gbl.Cache.RoleUsrInCrs.UsrCod && if (UsrCod == Gbl.Cache.RoleUsrInCrs.UsrCod &&
CrsCod == Gbl.Cache.RoleUsrInCrs.CrsCod ) CrsCod == Gbl.Cache.RoleUsrInCrs.CrsCod)
return Gbl.Cache.RoleUsrInCrs.Role; 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 *****/ The result of the query will have one row or none *****/
Gbl.Cache.RoleUsrInCrs.UsrCod = UsrCod; Gbl.Cache.RoleUsrInCrs.UsrCod = UsrCod;
Gbl.Cache.RoleUsrInCrs.CrsCod = CrsCod; Gbl.Cache.RoleUsrInCrs.CrsCod = CrsCod;
Gbl.Cache.RoleUsrInCrs.Role = Rol_UNK; if (UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod) // It's me
if (DB_QuerySELECT (&mysql_res,"can not get the role of a user in a course", /* Get my role in course */
"SELECT Role" // row[0] Gbl.Cache.RoleUsrInCrs.Role = Rol_GetMyRoleInCrs (CrsCod);
" FROM crs_users" else
" WHERE CrsCod=%ld" /* Get role of the user in course from database */
" AND UsrCod=%ld", Gbl.Cache.RoleUsrInCrs.Role =
CrsCod,UsrCod) == 1) // User belongs to the course DB_QuerySELECTRole ("can not get the role of a user in a course",
{ "SELECT Role"
row = mysql_fetch_row (mysql_res); " FROM crs_users"
Gbl.Cache.RoleUsrInCrs.Role = Rol_ConvertUnsignedStrToRole (row[0]); " WHERE CrsCod=%ld"
} " AND UsrCod=%ld",
DB_FreeMySQLResult (&mysql_res); CrsCod,
UsrCod);
return Gbl.Cache.RoleUsrInCrs.Role; 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_GetMyMaxRoleInIns (long InsCod);
Rol_Role_t Rol_GetMyMaxRoleInCtr (long CtrCod); Rol_Role_t Rol_GetMyMaxRoleInCtr (long CtrCod);
Rol_Role_t Rol_GetMyMaxRoleInDeg (long DegCod); Rol_Role_t Rol_GetMyMaxRoleInDeg (long DegCod);
void Rol_FlushCacheMyRoleInCurrentCrs (void);
Rol_Role_t Rol_GetMyRoleInCrs (long CrsCod); Rol_Role_t Rol_GetMyRoleInCrs (long CrsCod);
void Rol_FlushCacheRoleUsrInCrs (void); void Rol_FlushCacheRoleUsrInCrs (void);
Rol_Role_t Rol_GetRoleUsrInCrs (long UsrCod,long CrsCod); 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->EnUsrCod[0] = '\0';
UsrDat->Nickname[0] = '\0'; UsrDat->Nickname[0] = '\0';
UsrDat->Password[0] = '\0'; UsrDat->Password[0] = '\0';
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK; UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
UsrDat->Roles.InCurrentCrs.Valid = false; UsrDat->Roles.InCurrentCrs.Filled = false;
UsrDat->Roles.InCrss = -1; // < 0 ==> not yet got from database UsrDat->Roles.InCrss = -1; // < 0 ==> not yet got from database
UsrDat->Accepted = false; 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); Str_Copy (UsrDat->Password,row[1],sizeof (UsrDat->Password) - 1);
/* Get roles */ /* Get roles */
UsrDat->Roles.InCurrentCrs.Role = Rol_GetRoleUsrInCrs (UsrDat->UsrCod, UsrDat->Roles.InCurrentCrs.Role = Rol_GetRoleUsrInCrs (UsrDat->UsrCod,
Gbl.Hierarchy.Crs.CrsCod); Gbl.Hierarchy.Crs.CrsCod);
UsrDat->Roles.InCurrentCrs.Valid = true; UsrDat->Roles.InCurrentCrs.Filled = true;
UsrDat->Roles.InCrss = -1; // Force roles to be got from database UsrDat->Roles.InCrss = -1; // Force roles to be got from database
Rol_GetRolesInAllCrssIfNotYetGot (UsrDat); Rol_GetRolesInAllCrssIfNotYetGot (UsrDat);
@ -894,6 +894,7 @@ void Usr_FlushCachesUsr (void)
Usr_FlushCacheUsrBelongsToCurrentCrs (); Usr_FlushCacheUsrBelongsToCurrentCrs ();
Usr_FlushCacheUsrHasAcceptedInCurrentCrs (); Usr_FlushCacheUsrHasAcceptedInCurrentCrs ();
Usr_FlushCacheUsrSharesAnyOfMyCrs (); Usr_FlushCacheUsrSharesAnyOfMyCrs ();
Rol_FlushCacheMyRoleInCurrentCrs ();
Rol_FlushCacheRoleUsrInCrs (); Rol_FlushCacheRoleUsrInCrs ();
Grp_FlushCacheUsrSharesAnyOfMyGrpsInCurrentCrs (); Grp_FlushCacheUsrSharesAnyOfMyGrpsInCurrentCrs ();
Grp_FlushCacheIBelongToGrp (); Grp_FlushCacheIBelongToGrp ();
@ -2077,9 +2078,9 @@ bool Usr_CheckIfUsrBelongsToCurrentCrs (const struct UsrData *UsrDat)
return Gbl.Cache.UsrBelongsToCurrentCrs.Belongs; return Gbl.Cache.UsrBelongsToCurrentCrs.Belongs;
/***** 3. Fast check: If we know role of user in the current course *****/ /***** 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 || Gbl.Cache.UsrBelongsToCurrentCrs.Belongs = UsrDat->Roles.InCurrentCrs.Role == Rol_STD ||
UsrDat->Roles.InCurrentCrs.Role == Rol_NET || UsrDat->Roles.InCurrentCrs.Role == Rol_NET ||
UsrDat->Roles.InCurrentCrs.Role == Rol_TCH; 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 *****/ /***** 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.Cache.UsrBelongsToCurrentCrs.Belongs = Usr_CheckIfUsrBelongsToCrs (UsrDat->UsrCod,
Gbl.Hierarchy.Crs.CrsCod, Gbl.Hierarchy.Crs.CrsCod,
false); false);
@ -3415,9 +3416,8 @@ static void Usr_SetMyPrefsAndRoles (void)
/* Course may have changed ==> get my role in current course again */ /* Course may have changed ==> get my role in current course again */
if (Gbl.Hierarchy.Level == Hie_Lvl_CRS) // Course selected if (Gbl.Hierarchy.Level == Hie_Lvl_CRS) // Course selected
{ {
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role = Rol_GetRoleUsrInCrs (Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role = Rol_GetMyRoleInCrs (Gbl.Hierarchy.Crs.CrsCod);
Gbl.Hierarchy.Crs.CrsCod); Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Filled = true;
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Valid = true;
} }
// role and action will be got from last data // 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); Cod);
else else
return DB_QuerySELECTDouble ("can not get number of courses per 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 (SELECT COUNT(crs_users.CrsCod) AS NumCrss"
" FROM ins_instits," " FROM ins_instits,"
"ctr_centers," "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: case Hie_Lvl_INS:
if (Role == Rol_UNK) // Any user if (Role == Rol_UNK) // Any user
return DB_QuerySELECTDouble ("can not get number of courses per 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 (SELECT COUNT(crs_users.CrsCod) AS NumCrss"
" FROM ctr_centers," " FROM ctr_centers,"
"deg_degrees," "deg_degrees,"
@ -9778,7 +9778,7 @@ static double Usr_GetNumCrssPerUsr (Hie_Lvl_Level_t Scope,long Cod,Rol_Role_t Ro
Cod); Cod);
else else
return DB_QuerySELECTDouble ("can not get number of courses per 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 (SELECT COUNT(crs_users.CrsCod) AS NumCrss"
" FROM ctr_centers," " FROM ctr_centers,"
"deg_degrees," "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: case Hie_Lvl_CTR:
if (Role == Rol_UNK) // Any user if (Role == Rol_UNK) // Any user
return DB_QuerySELECTDouble ("can not get number of courses per 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 (SELECT COUNT(crs_users.CrsCod) AS NumCrss"
" FROM deg_degrees," " FROM deg_degrees,"
"crs_courses," "crs_courses,"
@ -9807,7 +9807,7 @@ static double Usr_GetNumCrssPerUsr (Hie_Lvl_Level_t Scope,long Cod,Rol_Role_t Ro
Cod); Cod);
else else
return DB_QuerySELECTDouble ("can not get number of courses per 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 (SELECT COUNT(crs_users.CrsCod) AS NumCrss"
" FROM deg_degrees," " FROM deg_degrees,"
"crs_courses," "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: case Hie_Lvl_DEG:
if (Role == Rol_UNK) // Any user if (Role == Rol_UNK) // Any user
return DB_QuerySELECTDouble ("can not get number of courses per 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 (SELECT COUNT(crs_users.CrsCod) AS NumCrss"
" FROM crs_courses," " FROM crs_courses,"
"crs_users" "crs_users"
@ -9832,7 +9832,7 @@ static double Usr_GetNumCrssPerUsr (Hie_Lvl_Level_t Scope,long Cod,Rol_Role_t Ro
Cod); Cod);
else else
return DB_QuerySELECTDouble ("can not get number of courses per 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 (SELECT COUNT(crs_users.CrsCod) AS NumCrss"
" FROM crs_courses," " FROM crs_courses,"
"crs_users" "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: case Hie_Lvl_SYS:
if (Role == Rol_UNK) // Any user if (Role == Rol_UNK) // Any user
return DB_QuerySELECTDouble ("can not get number of users per course", 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 (SELECT COUNT(UsrCod) AS NumUsrs"
" FROM crs_users" " FROM crs_users"
" GROUP BY CrsCod) AS NumUsrsTable"); " GROUP BY CrsCod) AS NumUsrsTable");
else else
return DB_QuerySELECTDouble ("can not get number of users per course", 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 (SELECT COUNT(UsrCod) AS NumUsrs"
" FROM crs_users" " FROM crs_users"
" WHERE Role=%u GROUP BY CrsCod) AS NumUsrsTable", " 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: case Hie_Lvl_CTY:
if (Role == Rol_UNK) // Any user if (Role == Rol_UNK) // Any user
return DB_QuerySELECTDouble ("can not get number of users per course", 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 (SELECT COUNT(crs_users.UsrCod) AS NumUsrs"
" FROM ins_instits," " FROM ins_instits,"
"ctr_centers," "ctr_centers,"
@ -9916,7 +9916,7 @@ static double Usr_GetNumUsrsPerCrs (Hie_Lvl_Level_t Scope,long Cod,Rol_Role_t Ro
Cod); Cod);
else else
return DB_QuerySELECTDouble ("can not get number of users per course", 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 (SELECT COUNT(crs_users.UsrCod) AS NumUsrs"
" FROM ins_instits," " FROM ins_instits,"
"ctr_centers," "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: case Hie_Lvl_INS:
if (Role == Rol_UNK) // Any user if (Role == Rol_UNK) // Any user
return DB_QuerySELECTDouble ("can not get number of users per course", 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 (SELECT COUNT(crs_users.UsrCod) AS NumUsrs"
" FROM ctr_centers," " FROM ctr_centers,"
"deg_degrees," "deg_degrees,"
@ -9949,7 +9949,7 @@ static double Usr_GetNumUsrsPerCrs (Hie_Lvl_Level_t Scope,long Cod,Rol_Role_t Ro
Cod); Cod);
else else
return DB_QuerySELECTDouble ("can not get number of users per course", 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 (SELECT COUNT(crs_users.UsrCod) AS NumUsrs"
" FROM ctr_centers," " FROM ctr_centers,"
"deg_degrees," "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: case Hie_Lvl_CTR:
if (Role == Rol_UNK) // Any user if (Role == Rol_UNK) // Any user
return DB_QuerySELECTDouble ("can not get number of users per course", 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 (SELECT COUNT(crs_users.UsrCod) AS NumUsrs"
" FROM deg_degrees," " FROM deg_degrees,"
"crs_courses," "crs_courses,"
@ -9978,7 +9978,7 @@ static double Usr_GetNumUsrsPerCrs (Hie_Lvl_Level_t Scope,long Cod,Rol_Role_t Ro
Cod); Cod);
else else
return DB_QuerySELECTDouble ("can not get number of users per course", 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 (SELECT COUNT(crs_users.UsrCod) AS NumUsrs"
" FROM deg_degrees," " FROM deg_degrees,"
"crs_courses," "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: case Hie_Lvl_DEG:
if (Role == Rol_UNK) // Any user if (Role == Rol_UNK) // Any user
return DB_QuerySELECTDouble ("can not get number of users per course", 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 (SELECT COUNT(crs_users.UsrCod) AS NumUsrs"
" FROM crs_courses," " FROM crs_courses,"
"crs_users" "crs_users"
@ -10003,7 +10003,7 @@ static double Usr_GetNumUsrsPerCrs (Hie_Lvl_Level_t Scope,long Cod,Rol_Role_t Ro
Cod); Cod);
else else
return DB_QuerySELECTDouble ("can not get number of users per course", 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 (SELECT COUNT(crs_users.UsrCod) AS NumUsrs"
" FROM crs_courses," " FROM crs_courses,"
"crs_users" "crs_users"

View File

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