Version 20.55: Apr 04, 2021 Optimizations in database selects.

This commit is contained in:
acanas 2021-04-04 14:46:41 +02:00
parent fb564b58cf
commit 9dba8e5314
6 changed files with 473 additions and 528 deletions

View File

@ -357,26 +357,12 @@ static void API_FreeSoapContext (struct soap *soap)
static int API_GetPlgCodFromAppKey (struct soap *soap, static int API_GetPlgCodFromAppKey (struct soap *soap,
const char *appKey) const char *appKey)
{ {
MYSQL_RES *mysql_res;
MYSQL_ROW row;
Gbl.WebService.PlgCod = -1L;
/***** Get number of plugins with a IP address *****/ /***** Get number of plugins with a IP address *****/
if (DB_QuerySELECT (&mysql_res,"can not check application key", Gbl.WebService.PlgCod = DB_QuerySELECTCod ("can not check application key",
"SELECT PlgCod" "SELECT PlgCod"
" FROM plg_plugins" " FROM plg_plugins"
" WHERE AppKey='%s'", " WHERE AppKey='%s'",
appKey)) // Session found in table of sessions appKey); // Session found in table of sessions
{
row = mysql_fetch_row (mysql_res);
Gbl.WebService.PlgCod = Str_ConvertStrCodToLongCod (row[0]);
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
if (Gbl.WebService.PlgCod < 0) if (Gbl.WebService.PlgCod < 0)
return soap_sender_fault (soap, return soap_sender_fault (soap,
"Unknown application key", "Unknown application key",
@ -591,26 +577,12 @@ static int API_RemoveOldWSKeys (struct soap *soap)
static int API_GetCurrentDegCodFromCurrentCrsCod (void) static int API_GetCurrentDegCodFromCurrentCrsCod (void)
{ {
MYSQL_RES *mysql_res;
MYSQL_ROW row;
/***** Set default degree code *****/
Gbl.Hierarchy.Deg.DegCod = -1L;
/***** Check that key does not exist in database *****/ /***** Check that key does not exist in database *****/
if (DB_QuerySELECT (&mysql_res,"can not get the degree of a course", Gbl.Hierarchy.Deg.DegCod = DB_QuerySELECTCod ("can not get the degree of a course",
"SELECT DegCod" "SELECT DegCod"
" FROM crs_courses" " FROM crs_courses"
" WHERE CrsCod=%ld", " WHERE CrsCod=%ld",
Gbl.Hierarchy.Crs.CrsCod)) // Course found in table of courses Gbl.Hierarchy.Crs.CrsCod); // Course found in table of courses
{
row = mysql_fetch_row (mysql_res);
Gbl.Hierarchy.Deg.DegCod = Str_ConvertStrCodToLongCod (row[0]);
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
return SOAP_OK; return SOAP_OK;
} }
@ -668,7 +640,7 @@ static bool API_GetSomeUsrDataFromUsrCod (struct UsrData *UsrDat,long CrsCod)
{ {
/* 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", if (DB_QuerySELECT (&mysql_res,"can not get user's role",
"SELECT Role" "SELECT Role" // row[0]
" FROM crs_users" " FROM crs_users"
" WHERE CrsCod=%ld" " WHERE CrsCod=%ld"
" AND UsrCod=%ld", " AND UsrCod=%ld",
@ -702,7 +674,7 @@ static bool API_GetSomeUsrDataFromUsrCod (struct UsrData *UsrDat,long CrsCod)
{ {
/* 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", if (DB_QuerySELECT (&mysql_res,"can not get user's role",
"SELECT MAX(Role)" "SELECT MAX(Role)" // row[0]
" FROM crs_users" " FROM crs_users"
" WHERE UsrCod=%ld", " WHERE UsrCod=%ld",
UsrDat->UsrCod) == 1) UsrDat->UsrCod) == 1)
@ -883,9 +855,6 @@ int swad__loginByUserPasswordKey (struct soap *soap,
{ {
char UsrIDNickOrEmail[Cns_MAX_BYTES_EMAIL_ADDRESS + 1]; char UsrIDNickOrEmail[Cns_MAX_BYTES_EMAIL_ADDRESS + 1];
int ReturnCode; int ReturnCode;
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumRows;
char PhotoURL[Cns_MAX_BYTES_WWW + 1]; char PhotoURL[Cns_MAX_BYTES_WWW + 1];
bool UsrFound; bool UsrFound;
@ -926,8 +895,7 @@ int swad__loginByUserPasswordKey (struct soap *soap,
Str_RemoveLeadingArrobas (UsrIDNickOrEmail); Str_RemoveLeadingArrobas (UsrIDNickOrEmail);
/* User has typed a nickname */ /* User has typed a nickname */
NumRows = Gbl.Usrs.Me.UsrDat.UsrCod = DB_QuerySELECTCod ("can not get user's data",
(unsigned) DB_QuerySELECT (&mysql_res,"can not get user's data",
"SELECT usr_nicknames.UsrCod" "SELECT usr_nicknames.UsrCod"
" FROM usr_nicknames," " FROM usr_nicknames,"
"usr_data" "usr_data"
@ -941,8 +909,7 @@ int swad__loginByUserPasswordKey (struct soap *soap,
{ {
/* User has typed an email */ /* User has typed an email */
// TODO: Get only if email confirmed? // TODO: Get only if email confirmed?
NumRows = Gbl.Usrs.Me.UsrDat.UsrCod = DB_QuerySELECTCod ("can not get user's data",
(unsigned) DB_QuerySELECT (&mysql_res,"can not get user's data",
"SELECT usr_emails.UsrCod" "SELECT usr_emails.UsrCod"
" FROM usr_emails,usr_data" " FROM usr_emails,usr_data"
" WHERE usr_emails.E_mail='%s'" " WHERE usr_emails.E_mail='%s'"
@ -960,8 +927,7 @@ int swad__loginByUserPasswordKey (struct soap *soap,
{ {
/* User has typed a valid user's ID (existing or not) */ /* User has typed a valid user's ID (existing or not) */
// TODO: Get only if ID confirmed? // TODO: Get only if ID confirmed?
NumRows = Gbl.Usrs.Me.UsrDat.UsrCod = DB_QuerySELECTCod ("can not get user's data",
(unsigned) DB_QuerySELECT (&mysql_res,"can not get user's data",
"SELECT usr_ids.UsrCod" "SELECT usr_ids.UsrCod"
" FROM usr_ids," " FROM usr_ids,"
"usr_data" "usr_data"
@ -978,22 +944,12 @@ int swad__loginByUserPasswordKey (struct soap *soap,
} }
/***** Get user's data from database *****/ /***** Get user's data from database *****/
if (NumRows == 1) // User found in table of users' data if (Gbl.Usrs.Me.UsrDat.UsrCod > 0) // User found in table of users' data
{
row = mysql_fetch_row (mysql_res);
/***** Get user code (row[0]) *****/
Gbl.Usrs.Me.UsrDat.UsrCod = Str_ConvertStrCodToLongCod (row[0]);
/***** Get user's data *****/ /***** Get user's data *****/
UsrFound = API_GetSomeUsrDataFromUsrCod (&Gbl.Usrs.Me.UsrDat,-1L); // Get some user's data from database UsrFound = API_GetSomeUsrDataFromUsrCod (&Gbl.Usrs.Me.UsrDat,-1L); // Get some user's data from database
}
else else
UsrFound = false; UsrFound = false;
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
if (UsrFound) if (UsrFound)
{ {
Gbl.Usrs.Me.Logged = true; Gbl.Usrs.Me.Logged = true;
@ -1269,9 +1225,6 @@ int swad__getNewPassword (struct soap *soap,
{ {
int ReturnCode; int ReturnCode;
char UsrIDNickOrEmail[Cns_MAX_BYTES_EMAIL_ADDRESS + 1]; char UsrIDNickOrEmail[Cns_MAX_BYTES_EMAIL_ADDRESS + 1];
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumRows;
char NewRandomPlainPassword[Pwd_MAX_BYTES_PLAIN_PASSWORD + 1]; char NewRandomPlainPassword[Pwd_MAX_BYTES_PLAIN_PASSWORD + 1];
/***** Initializations *****/ /***** Initializations *****/
@ -1292,40 +1245,33 @@ int swad__getNewPassword (struct soap *soap,
Str_RemoveLeadingArrobas (UsrIDNickOrEmail); Str_RemoveLeadingArrobas (UsrIDNickOrEmail);
/* User has typed a nickname */ /* User has typed a nickname */
NumRows = Gbl.Usrs.Me.UsrDat.UsrCod = DB_QuerySELECTCod ("can not get user's data",
(unsigned) DB_QuerySELECT (&mysql_res,"can not get user's data",
"SELECT UsrCod" "SELECT UsrCod"
" FROM usr_nicknames" " FROM usr_nicknames"
" WHERE Nickname='%s'", " WHERE Nickname='%s'",
UsrIDNickOrEmail); UsrIDNickOrEmail);
} }
else if (Mai_CheckIfEmailIsValid (Gbl.Usrs.Me.UsrIdLogin)) // 2: It's an email else if (Mai_CheckIfEmailIsValid (Gbl.Usrs.Me.UsrIdLogin)) // 2: It's an email
{
/* User has typed an email */ /* User has typed an email */
// TODO: Get only if email confirmed? // TODO: Get only if email confirmed?
NumRows = Gbl.Usrs.Me.UsrDat.UsrCod = DB_QuerySELECTCod ("can not get user's data",
(unsigned) DB_QuerySELECT (&mysql_res,"can not get user's data",
"SELECT UsrCod" "SELECT UsrCod"
" FROM usr_emails" " FROM usr_emails"
" WHERE E_mail='%s'", " WHERE E_mail='%s'",
UsrIDNickOrEmail); UsrIDNickOrEmail);
}
else // 3: It's not a nickname nor email else // 3: It's not a nickname nor email
{ {
// Users' IDs are always stored internally in capitals and without leading zeros // Users' IDs are always stored internally in capitals and without leading zeros
Str_RemoveLeadingZeros (UsrIDNickOrEmail); Str_RemoveLeadingZeros (UsrIDNickOrEmail);
Str_ConvertToUpperText (UsrIDNickOrEmail); Str_ConvertToUpperText (UsrIDNickOrEmail);
if (ID_CheckIfUsrIDIsValid (UsrIDNickOrEmail)) if (ID_CheckIfUsrIDIsValid (UsrIDNickOrEmail))
{
/* User has typed a valid user's ID (existing or not) */ /* User has typed a valid user's ID (existing or not) */
// TODO: Get only if ID confirmed? // TODO: Get only if ID confirmed?
NumRows = Gbl.Usrs.Me.UsrDat.UsrCod = DB_QuerySELECTCod ("can not get user's data",
(unsigned) DB_QuerySELECT (&mysql_res,"can not get user's data",
"SELECT UsrCod" "SELECT UsrCod"
" FROM usr_ids" " FROM usr_ids"
" WHERE UsrID='%s'", " WHERE UsrID='%s'",
UsrIDNickOrEmail); UsrIDNickOrEmail);
}
else // String is not a valid user's nickname, email or ID else // String is not a valid user's nickname, email or ID
return soap_receiver_fault (soap, return soap_receiver_fault (soap,
"Bad log in", "Bad log in",
@ -1333,13 +1279,8 @@ int swad__getNewPassword (struct soap *soap,
} }
/***** Get user's data from database *****/ /***** Get user's data from database *****/
if (NumRows == 1) // One unique user found in table of users' data if (Gbl.Usrs.Me.UsrDat.UsrCod > 0) // One unique user found in table of users' data
{ {
row = mysql_fetch_row (mysql_res);
/***** Get user code (row[0]) *****/
Gbl.Usrs.Me.UsrDat.UsrCod = Str_ConvertStrCodToLongCod (row[0]);
Usr_GetUsrDataFromUsrCod (&Gbl.Usrs.Me.UsrDat,Usr_DONT_GET_PREFS); // Get my data Usr_GetUsrDataFromUsrCod (&Gbl.Usrs.Me.UsrDat,Usr_DONT_GET_PREFS); // Get my data
if (Gbl.Usrs.Me.UsrDat.Email[0]) if (Gbl.Usrs.Me.UsrDat.Email[0])
@ -1350,9 +1291,6 @@ int swad__getNewPassword (struct soap *soap,
} }
} }
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
return SOAP_OK; return SOAP_OK;
} }
@ -1392,12 +1330,12 @@ int swad__getCourses (struct soap *soap,
Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role; Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
/***** Query my courses from database *****/ /***** Query my courses from database *****/
NumRows = NumRows = (unsigned)
(unsigned) DB_QuerySELECT (&mysql_res,"can not get user's courses", DB_QuerySELECT (&mysql_res,"can not get user's courses",
"SELECT crs_courses.CrsCod," "SELECT crs_courses.CrsCod," // row[0]
"crs_courses.ShortName," "crs_courses.ShortName," // row[1]
"crs_courses.FullName," "crs_courses.FullName," // row[2]
"crs_users.Role" "crs_users.Role" // row[3]
" FROM crs_users," " FROM crs_users,"
"crs_courses" "crs_courses"
" WHERE crs_users.UsrCod=%ld" " WHERE crs_users.UsrCod=%ld"
@ -2122,8 +2060,8 @@ int swad__getGroupTypes (struct soap *soap,
"Requester must belong to course"); "Requester must belong to course");
/***** Query group types in a course from database *****/ /***** Query group types in a course from database *****/
NumRows = NumRows = (unsigned)
(unsigned) DB_QuerySELECT (&mysql_res,"can not get group types", DB_QuerySELECT (&mysql_res,"can not get group types",
"SELECT GrpTypCod," // row[0] "SELECT GrpTypCod," // row[0]
"GrpTypName," // row[1] "GrpTypName," // row[1]
"Mandatory," // row[2] "Mandatory," // row[2]
@ -2241,8 +2179,8 @@ int swad__getGroups (struct soap *soap,
"Requester must belong to course"); "Requester must belong to course");
/***** Query groups in a course from database *****/ /***** Query groups in a course from database *****/
NumRows = NumRows = (unsigned)
(unsigned) DB_QuerySELECT (&mysql_res,"can not get user's groups", DB_QuerySELECT (&mysql_res,"can not get user's groups",
"SELECT grp_types.GrpTypCod," // row[0] "SELECT grp_types.GrpTypCod," // row[0]
"grp_types.GrpTypName," // row[1] "grp_types.GrpTypName," // row[1]
"grp_groups.GrpCod," // row[2] "grp_groups.GrpCod," // row[2]
@ -2415,8 +2353,8 @@ int swad__sendMyGroups (struct soap *soap,
Grp_FreeListCodGrp (&LstGrpsIWant); Grp_FreeListCodGrp (&LstGrpsIWant);
/***** Query groups in a course from database *****/ /***** Query groups in a course from database *****/
NumRows = NumRows = (unsigned)
(unsigned) DB_QuerySELECT (&mysql_res,"can not get user's groups", DB_QuerySELECT (&mysql_res,"can not get user's groups",
"SELECT grp_types.GrpTypCod," // row[0] "SELECT grp_types.GrpTypCod," // row[0]
"grp_types.GrpTypName," // row[1] "grp_types.GrpTypName," // row[1]
"grp_groups.GrpCod," // row[2] "grp_groups.GrpCod," // row[2]
@ -2601,16 +2539,16 @@ int swad__getAttendanceEvents (struct soap *soap,
"Requester must be a teacher"); "Requester must be a teacher");
/***** Query list of attendance events *****/ /***** Query list of attendance events *****/
NumRows = NumRows = (unsigned)
(unsigned) DB_QuerySELECT (&mysql_res,"can not get attendance events", DB_QuerySELECT (&mysql_res,"can not get attendance events",
"SELECT AttCod," "SELECT AttCod," // row[0]
"Hidden," "Hidden," // row[1]
"UsrCod," "UsrCod," // row[2]
"UNIX_TIMESTAMP(StartTime) AS ST," "UNIX_TIMESTAMP(StartTime) AS ST," // row[3]
"UNIX_TIMESTAMP(EndTime) AS ET," "UNIX_TIMESTAMP(EndTime) AS ET," // row[4]
"CommentTchVisible," "CommentTchVisible," // row[5]
"Title," "Title," // row[6]
"Txt" "Txt" // row[7]
" FROM att_events" " FROM att_events"
" WHERE CrsCod=%d" " WHERE CrsCod=%d"
" ORDER BY ST DESC," " ORDER BY ST DESC,"
@ -2732,7 +2670,6 @@ static void API_GetListGrpsInAttendanceEventFromDB (struct soap *soap,
long AttCod,char **ListGroups) long AttCod,char **ListGroups)
{ {
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row;
long NumGrps; long NumGrps;
long NumGrp; long NumGrp;
long GrpCod; long GrpCod;
@ -2760,10 +2697,7 @@ static void API_GetListGrpsInAttendanceEventFromDB (struct soap *soap,
NumGrp++) NumGrp++)
{ {
/* Get next group */ /* Get next group */
row = mysql_fetch_row (mysql_res); GrpCod = DB_GetNextCod (mysql_res);
/* Get group code (row[0]) */
GrpCod = Str_ConvertStrCodToLongCod (row[0]);
snprintf (GrpCodStr,sizeof (GrpCodStr),NumGrp ? ",%ld" : snprintf (GrpCodStr,sizeof (GrpCodStr),NumGrp ? ",%ld" :
"%ld", "%ld",
GrpCod); GrpCod);
@ -3083,11 +3017,10 @@ int swad__getAttendanceUsers (struct soap *soap,
(unsigned) Rol_STD, (unsigned) Rol_STD,
Event.AttCod); Event.AttCod);
// Query: list of users in attendance list + rest of users (subquery) // Query: list of users in attendance list + rest of users (subquery)
NumRows = NumRows = (unsigned)
(unsigned) DB_QuerySELECT (&mysql_res,"can not get users" DB_QuerySELECT (&mysql_res,"can not get users in an attendance event",
" in an attendance event", "SELECT u.UsrCod," // row[0]
"SELECT u.UsrCod," "u.Present" // row[1]
"u.Present"
" FROM (SELECT UsrCod," " FROM (SELECT UsrCod,"
"Present" "Present"
" FROM att_users" " FROM att_users"
@ -3098,7 +3031,8 @@ int swad__getAttendanceUsers (struct soap *soap,
" ORDER BY usr_data.Surname1," " ORDER BY usr_data.Surname1,"
"usr_data.Surname2," "usr_data.Surname2,"
"usr_data.FirstName", "usr_data.FirstName",
(long) attendanceEventCode,SubQuery); (long) attendanceEventCode,
SubQuery);
getAttendanceUsersOut->numUsers = (int) NumRows; getAttendanceUsersOut->numUsers = (int) NumRows;
getAttendanceUsersOut->usersArray.__size = (int) NumRows; getAttendanceUsersOut->usersArray.__size = (int) NumRows;
@ -3387,8 +3321,8 @@ int swad__getNotifications (struct soap *soap,
return ReturnCode; return ReturnCode;
/***** Get my notifications from database *****/ /***** Get my notifications from database *****/
NumNotifications = NumNotifications = (unsigned)
(unsigned) DB_QuerySELECT (&mysql_res,"can not get user's notifications", DB_QuerySELECT (&mysql_res,"can not get user's notifications",
"SELECT NtfCod," // row[0] "SELECT NtfCod," // row[0]
"NotifyEvent," // row[1] "NotifyEvent," // row[1]
"UNIX_TIMESTAMP(TimeNotif)," // row[2] "UNIX_TIMESTAMP(TimeNotif)," // row[2]
@ -3593,7 +3527,7 @@ static int API_GetMyLanguage (struct soap *soap)
/***** Get user's language *****/ /***** Get user's language *****/
if (DB_QuerySELECT (&mysql_res,"can not get user's language", if (DB_QuerySELECT (&mysql_res,"can not get user's language",
"SELECT Language" "SELECT Language" // row[0]
" FROM usr_data" " FROM usr_data"
" WHERE UsrCod=%ld", " WHERE UsrCod=%ld",
Gbl.Usrs.Me.UsrDat.UsrCod) != 1) Gbl.Usrs.Me.UsrDat.UsrCod) != 1)
@ -3738,7 +3672,7 @@ int swad__sendMessage (struct soap *soap,
{ {
/***** Check if the original message was really received by me *****/ /***** Check if the original message was really received by me *****/
if (!DB_QuerySELECT (&mysql_res,"can not check original message", if (!DB_QuerySELECT (&mysql_res,"can not check original message",
"SELECT SUM(N)" "SELECT SUM(N)" // row[0]
" FROM (SELECT COUNT(*) AS N" " FROM (SELECT COUNT(*) AS N"
" FROM msg_rcv" " FROM msg_rcv"
" WHERE UsrCod=%ld" " WHERE UsrCod=%ld"
@ -3770,8 +3704,7 @@ int swad__sendMessage (struct soap *soap,
"Original message does not exist"); "Original message does not exist");
/***** Get the recipient of the message *****/ /***** Get the recipient of the message *****/
NumRows = ReplyUsrCod = DB_QuerySELECTCod ("can not check original message",
(unsigned) DB_QuerySELECT (&mysql_res,"can not check original message",
"SELECT UsrCod" "SELECT UsrCod"
" FROM msg_snt" " FROM msg_snt"
" WHERE MsgCod=%ld" " WHERE MsgCod=%ld"
@ -3781,16 +3714,7 @@ int swad__sendMessage (struct soap *soap,
" WHERE MsgCod=%ld", " WHERE MsgCod=%ld",
(long) messageCode, (long) messageCode,
(long) messageCode); (long) messageCode);
if (NumRows) // Message found in any of the two tables of sent messages if (ReplyUsrCod <= 0)
{
row = mysql_fetch_row (mysql_res);
ReplyUsrCod = Str_ConvertStrCodToLongCod (row[0]);
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
if (!NumRows)
return soap_sender_fault (soap, return soap_sender_fault (soap,
"Can not send reply message", "Can not send reply message",
"Original message does not exist"); "Original message does not exist");
@ -4387,8 +4311,8 @@ static int API_GetTstQuestions (struct soap *soap,
/***** Get recent test questions from database *****/ /***** Get recent test questions from database *****/
// DISTINCTROW is necessary to not repeat questions // DISTINCTROW is necessary to not repeat questions
NumRows = NumRows = (unsigned)
(unsigned) DB_QuerySELECT (&mysql_res,"can not get test questions", DB_QuerySELECT (&mysql_res,"can not get test questions",
"SELECT DISTINCTROW tst_questions.QstCod," // row[0] "SELECT DISTINCTROW tst_questions.QstCod," // row[0]
"tst_questions.AnsType," // row[1] "tst_questions.AnsType," // row[1]
"tst_questions.Shuffle," // row[2] "tst_questions.Shuffle," // row[2]
@ -4412,7 +4336,9 @@ static int API_GetTstQuestions (struct soap *soap,
" OR " " OR "
"tst_tags.ChangeTime>=FROM_UNIXTIME(%ld))" "tst_tags.ChangeTime>=FROM_UNIXTIME(%ld))"
" ORDER BY QstCod", " ORDER BY QstCod",
CrsCod,CrsCod,CrsCod, CrsCod,
CrsCod,
CrsCod,
BeginTime, BeginTime,
BeginTime); BeginTime);
@ -4483,13 +4409,13 @@ static int API_GetTstAnswers (struct soap *soap,
unsigned Index; unsigned Index;
/***** Get recent test questions from database *****/ /***** Get recent test questions from database *****/
NumRows = NumRows = (unsigned)
(unsigned) DB_QuerySELECT (&mysql_res,"can not get test answers", DB_QuerySELECT (&mysql_res,"can not get test answers",
"SELECT QstCod," "SELECT QstCod," // row[0]
"AnsInd," "AnsInd," // row[1]
"Correct," "Correct," // row[2]
"Answer," "Answer," // row[3]
"Feedback" "Feedback" // row[4]
" FROM tst_answers" " FROM tst_answers"
" WHERE QstCod IN " " WHERE QstCod IN "
"(SELECT tst_questions.QstCod" "(SELECT tst_questions.QstCod"
@ -4512,7 +4438,9 @@ static int API_GetTstAnswers (struct soap *soap,
"tst_tags.ChangeTime>=FROM_UNIXTIME(%ld)))" "tst_tags.ChangeTime>=FROM_UNIXTIME(%ld)))"
" ORDER BY QstCod," " ORDER BY QstCod,"
"AnsInd", "AnsInd",
CrsCod,CrsCod,CrsCod, CrsCod,
CrsCod,
CrsCod,
BeginTime, BeginTime,
BeginTime); BeginTime);
@ -4581,11 +4509,11 @@ static int API_GetTstQuestionTags (struct soap *soap,
unsigned Index; unsigned Index;
/***** Get recent test questions from database *****/ /***** Get recent test questions from database *****/
NumRows = NumRows = (unsigned)
(unsigned) DB_QuerySELECT (&mysql_res,"can not get test question tags", DB_QuerySELECT (&mysql_res,"can not get test question tags",
"SELECT QstCod," "SELECT QstCod," // row[0]
"TagCod," "TagCod," // row[1]
"TagInd" "TagInd" // row[2]
" FROM tst_question_tags" " FROM tst_question_tags"
" WHERE QstCod IN " " WHERE QstCod IN "
"(SELECT tst_questions.QstCod" "(SELECT tst_questions.QstCod"
@ -4608,7 +4536,9 @@ static int API_GetTstQuestionTags (struct soap *soap,
"tst_tags.ChangeTime>=FROM_UNIXTIME(%ld)))" "tst_tags.ChangeTime>=FROM_UNIXTIME(%ld)))"
" ORDER BY QstCod," " ORDER BY QstCod,"
"TagInd", "TagInd",
CrsCod,CrsCod,CrsCod, CrsCod,
CrsCod,
CrsCod,
BeginTime, BeginTime,
BeginTime); BeginTime);
@ -4737,16 +4667,15 @@ int swad__getTrivialQuestion (struct soap *soap,
/***** Start query *****/ /***** Start query *****/
Str_SetDecimalPointToUS (); // To print the floating point as a dot Str_SetDecimalPointToUS (); // To print the floating point as a dot
NumRows = NumRows = (unsigned)
(unsigned) DB_QuerySELECT (&mysql_res,"can not get test questions", DB_QuerySELECT (&mysql_res,"can not get test questions",
"SELECT DISTINCTROW " "SELECT DISTINCTROW "
"tst_questions.QstCod," // row[0] "tst_questions.QstCod," // row[0]
"tst_questions.AnsType," // row[1] "tst_questions.AnsType," // row[1]
"tst_questions.Shuffle," // row[2] "tst_questions.Shuffle," // row[2]
"tst_questions.Stem," // row[3] "tst_questions.Stem," // row[3]
"tst_questions.Feedback," // row[4] "tst_questions.Feedback," // row[4]
"tst_questions.Score/" "tst_questions.Score/tst_questions.NumHits AS S" // row[5]
"tst_questions.NumHits AS S" // row[5]
" FROM crs_courses," " FROM crs_courses,"
"tst_questions" "tst_questions"
" WHERE crs_courses.DegCod IN (%s)" " WHERE crs_courses.DegCod IN (%s)"
@ -4766,8 +4695,10 @@ int swad__getTrivialQuestion (struct soap *soap,
" AND S<='%f'" " AND S<='%f'"
" ORDER BY RAND()" " ORDER BY RAND()"
" LIMIT 1", " LIMIT 1",
DegreesStr,DegreesStr, DegreesStr,
lowerScore,upperScore); DegreesStr,
lowerScore,
upperScore);
Str_SetDecimalPointToLocal (); // Return to local system Str_SetDecimalPointToLocal (); // Return to local system
if (NumRows == 1) // Question found if (NumRows == 1) // Question found
@ -5461,7 +5392,6 @@ static void API_GetListGrpsInGameFromDB (struct soap *soap,
long MchCod,char **ListGroups) long MchCod,char **ListGroups)
{ {
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row;
long NumGrps; long NumGrps;
long NumGrp; long NumGrp;
long GrpCod; long GrpCod;
@ -5488,10 +5418,7 @@ static void API_GetListGrpsInGameFromDB (struct soap *soap,
NumGrp++) NumGrp++)
{ {
/* Get next group */ /* Get next group */
row = mysql_fetch_row (mysql_res); GrpCod = DB_GetNextCod (mysql_res);
/* Get group code (row[0]) */
GrpCod = Str_ConvertStrCodToLongCod (row[0]);
snprintf (GrpCodStr,sizeof (GrpCodStr),NumGrp ? ",%ld" : snprintf (GrpCodStr,sizeof (GrpCodStr),NumGrp ? ",%ld" :
"%ld", "%ld",
GrpCod); GrpCod);
@ -6276,7 +6203,8 @@ int swad__getLastLocation (struct soap *soap,
" AND roo_rooms.BldCod=bld_buildings.BldCod" " AND roo_rooms.BldCod=bld_buildings.BldCod"
" AND bld_buildings.CtrCod=ctr_centers.CtrCod" " AND bld_buildings.CtrCod=ctr_centers.CtrCod"
" AND ctr_centers.InsCod=ins_instits.InsCod", " AND ctr_centers.InsCod=ins_instits.InsCod",
userCode,userCode); userCode,
userCode);
API_GetDataOfLocation (soap, API_GetDataOfLocation (soap,
&(getLastLocationOut->location), &(getLastLocationOut->location),
&(getLastLocationOut->checkinTime), // Get check in time &(getLastLocationOut->checkinTime), // Get check in time

View File

@ -684,7 +684,6 @@ static void Asg_GetListAssignments (struct Asg_Assignments *Assignments)
[Dat_END_TIME ] = "EndTime DESC,StartTime DESC,Title DESC", [Dat_END_TIME ] = "EndTime DESC,StartTime DESC,Title DESC",
}; };
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned long NumRows; unsigned long NumRows;
unsigned NumAsg; unsigned NumAsg;
@ -741,8 +740,7 @@ static void Asg_GetListAssignments (struct Asg_Assignments *Assignments)
NumAsg++) NumAsg++)
{ {
/* Get next assignment code */ /* Get next assignment code */
row = mysql_fetch_row (mysql_res); if ((Assignments->LstAsgCods[NumAsg] = DB_GetNextCod (mysql_res)) < 0)
if ((Assignments->LstAsgCods[NumAsg] = Str_ConvertStrCodToLongCod (row[0])) < 0)
Lay_ShowErrorAndExit ("Error: wrong assignment code."); Lay_ShowErrorAndExit ("Error: wrong assignment code.");
} }
} }

View File

@ -668,7 +668,6 @@ static void Att_GetListAttEvents (struct Att_Events *Events,
[Dat_END_TIME ][Att_OLDEST_FIRST] = "EndTime,StartTime,Title", [Dat_END_TIME ][Att_OLDEST_FIRST] = "EndTime,StartTime,Title",
}; };
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned long NumRows; unsigned long NumRows;
unsigned NumAttEvent; unsigned NumAttEvent;
@ -721,8 +720,7 @@ static void Att_GetListAttEvents (struct Att_Events *Events,
NumAttEvent++) NumAttEvent++)
{ {
/* Get next attendance event code */ /* Get next attendance event code */
row = mysql_fetch_row (mysql_res); if ((Events->Lst[NumAttEvent].AttCod = DB_GetNextCod (mysql_res)) < 0)
if ((Events->Lst[NumAttEvent].AttCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
Lay_ShowErrorAndExit ("Error: wrong attendance event code."); Lay_ShowErrorAndExit ("Error: wrong attendance event code.");
} }
} }
@ -873,7 +871,7 @@ static void Att_GetAttEventDescriptionFromDB (long AttCod,char Description[Cns_M
/***** Get text of attendance event from database *****/ /***** Get text of attendance event from database *****/
NumRows = DB_QuerySELECT (&mysql_res,"can not get attendance event text", NumRows = DB_QuerySELECT (&mysql_res,"can not get attendance event text",
"SELECT Txt" "SELECT Txt" // row[0]
" FROM att_events" " FROM att_events"
" WHERE AttCod=%ld" " WHERE AttCod=%ld"
" AND CrsCod=%ld", " AND CrsCod=%ld",
@ -1549,7 +1547,8 @@ static void Att_GetAndWriteNamesOfGrpsAssociatedToAttEvent (struct Att_Event *Ev
unsigned NumGrps; unsigned NumGrps;
/***** Get groups associated to an attendance event from database *****/ /***** Get groups associated to an attendance event from database *****/
NumGrps = (unsigned) DB_QuerySELECT (&mysql_res,"can not get groups of an attendance event", NumGrps = (unsigned)
DB_QuerySELECT (&mysql_res,"can not get groups of an attendance event",
"SELECT grp_types.GrpTypName," // row[0] "SELECT grp_types.GrpTypName," // row[0]
"grp_groups.GrpName," // row[1] "grp_groups.GrpName," // row[1]
"roo_rooms.ShortName" // row[2] "roo_rooms.ShortName" // row[2]
@ -1720,21 +1719,16 @@ unsigned Att_GetNumAttEventsInCrs (long CrsCod)
unsigned Att_GetNumCoursesWithAttEvents (Hie_Lvl_Level_t Scope) unsigned Att_GetNumCoursesWithAttEvents (Hie_Lvl_Level_t Scope)
{ {
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumCourses;
/***** Get number of courses with attendance events from database *****/ /***** Get number of courses with attendance events from database *****/
switch (Scope) switch (Scope)
{ {
case Hie_Lvl_SYS: case Hie_Lvl_SYS:
DB_QuerySELECT (&mysql_res,"can not get number of courses with attendance events", return DB_QueryCOUNT ("can not get number of courses with attendance events",
"SELECT COUNT(DISTINCT CrsCod)" "SELECT COUNT(DISTINCT CrsCod)"
" FROM att_events" " FROM att_events"
" WHERE CrsCod>0"); " WHERE CrsCod>0");
break;
case Hie_Lvl_INS: case Hie_Lvl_INS:
DB_QuerySELECT (&mysql_res,"can not get number of courses with attendance events", return DB_QueryCOUNT ("can not get number of courses with attendance events",
"SELECT COUNT(DISTINCT att_events.CrsCod)" "SELECT COUNT(DISTINCT att_events.CrsCod)"
" FROM ctr_centers," " FROM ctr_centers,"
"deg_degrees," "deg_degrees,"
@ -1745,9 +1739,8 @@ unsigned Att_GetNumCoursesWithAttEvents (Hie_Lvl_Level_t Scope)
" AND deg_degrees.DegCod=crs_courses.DegCod" " AND deg_degrees.DegCod=crs_courses.DegCod"
" AND crs_courses.CrsCod=att_events.CrsCod", " AND crs_courses.CrsCod=att_events.CrsCod",
Gbl.Hierarchy.Ins.InsCod); Gbl.Hierarchy.Ins.InsCod);
break;
case Hie_Lvl_CTR: case Hie_Lvl_CTR:
DB_QuerySELECT (&mysql_res,"can not get number of courses with attendance events", return DB_QueryCOUNT ("can not get number of courses with attendance events",
"SELECT COUNT(DISTINCT att_events.CrsCod)" "SELECT COUNT(DISTINCT att_events.CrsCod)"
" FROM deg_degrees," " FROM deg_degrees,"
"crs_courses," "crs_courses,"
@ -1756,37 +1749,24 @@ unsigned Att_GetNumCoursesWithAttEvents (Hie_Lvl_Level_t Scope)
" AND deg_degrees.DegCod=crs_courses.DegCod" " AND deg_degrees.DegCod=crs_courses.DegCod"
" AND crs_courses.CrsCod=att_events.CrsCod", " AND crs_courses.CrsCod=att_events.CrsCod",
Gbl.Hierarchy.Ctr.CtrCod); Gbl.Hierarchy.Ctr.CtrCod);
break;
case Hie_Lvl_DEG: case Hie_Lvl_DEG:
DB_QuerySELECT (&mysql_res,"can not get number of courses with attendance events", return DB_QueryCOUNT ("can not get number of courses with attendance events",
"SELECT COUNT(DISTINCT att_events.CrsCod)" "SELECT COUNT(DISTINCT att_events.CrsCod)"
" FROM crs_courses," " FROM crs_courses,"
"att_events" "att_events"
" WHERE crs_courses.DegCod=%ld" " WHERE crs_courses.DegCod=%ld"
" AND crs_courses.CrsCod=att_events.CrsCod", " AND crs_courses.CrsCod=att_events.CrsCod",
Gbl.Hierarchy.Deg.DegCod); Gbl.Hierarchy.Deg.DegCod);
break;
case Hie_Lvl_CRS: case Hie_Lvl_CRS:
DB_QuerySELECT (&mysql_res,"can not get number of courses with attendance events", return DB_QueryCOUNT ("can not get number of courses with attendance events",
"SELECT COUNT(DISTINCT CrsCod)" "SELECT COUNT(DISTINCT CrsCod)"
" FROM att_events" " FROM att_events"
" WHERE CrsCod=%ld", " WHERE CrsCod=%ld",
Gbl.Hierarchy.Crs.CrsCod); Gbl.Hierarchy.Crs.CrsCod);
break;
default: default:
Lay_WrongScopeExit (); Lay_WrongScopeExit ();
break; return 0; // Not reached
} }
/***** Get number of courses *****/
row = mysql_fetch_row (mysql_res);
if (sscanf (row[0],"%u",&NumCourses) != 1)
Lay_ShowErrorAndExit ("Error when getting number of courses with attendance events.");
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
return NumCourses;
} }
/*****************************************************************************/ /*****************************************************************************/
@ -1806,15 +1786,15 @@ unsigned Att_GetNumAttEvents (Hie_Lvl_Level_t Scope,unsigned *NumNotif)
{ {
case Hie_Lvl_SYS: case Hie_Lvl_SYS:
DB_QuerySELECT (&mysql_res,"can not get number of attendance events", DB_QuerySELECT (&mysql_res,"can not get number of attendance events",
"SELECT COUNT(*)," "SELECT COUNT(*)," // row[0]
"SUM(NumNotif)" "SUM(NumNotif)" // row[1]
" FROM att_events" " FROM att_events"
" WHERE CrsCod>0"); " WHERE CrsCod>0");
break; break;
case Hie_Lvl_INS: case Hie_Lvl_INS:
DB_QuerySELECT (&mysql_res,"can not get number of attendance events", DB_QuerySELECT (&mysql_res,"can not get number of attendance events",
"SELECT COUNT(*)," "SELECT COUNT(*)," // row[0]
"SUM(att_events.NumNotif)" "SUM(att_events.NumNotif)" // row[1]
" FROM ctr_centers," " FROM ctr_centers,"
"deg_degrees," "deg_degrees,"
"crs_courses," "crs_courses,"
@ -1827,8 +1807,8 @@ unsigned Att_GetNumAttEvents (Hie_Lvl_Level_t Scope,unsigned *NumNotif)
break; break;
case Hie_Lvl_CTR: case Hie_Lvl_CTR:
DB_QuerySELECT (&mysql_res,"can not get number of attendance events", DB_QuerySELECT (&mysql_res,"can not get number of attendance events",
"SELECT COUNT(*)," "SELECT COUNT(*)," // row[0]
"SUM(att_events.NumNotif)" "SUM(att_events.NumNotif)" // row[1]
" FROM deg_degrees," " FROM deg_degrees,"
"crs_courses," "crs_courses,"
"att_events" "att_events"
@ -1839,8 +1819,8 @@ unsigned Att_GetNumAttEvents (Hie_Lvl_Level_t Scope,unsigned *NumNotif)
break; break;
case Hie_Lvl_DEG: case Hie_Lvl_DEG:
DB_QuerySELECT (&mysql_res,"can not get number of attendance events", DB_QuerySELECT (&mysql_res,"can not get number of attendance events",
"SELECT COUNT(*)," "SELECT COUNT(*)," // row[0]
"SUM(att_events.NumNotif)" "SUM(att_events.NumNotif)" // row[1]
" FROM crs_courses," " FROM crs_courses,"
"att_events" "att_events"
" WHERE crs_courses.DegCod=%ld" " WHERE crs_courses.DegCod=%ld"
@ -1849,8 +1829,8 @@ unsigned Att_GetNumAttEvents (Hie_Lvl_Level_t Scope,unsigned *NumNotif)
break; break;
case Hie_Lvl_CRS: case Hie_Lvl_CRS:
DB_QuerySELECT (&mysql_res,"can not get number of attendance events", DB_QuerySELECT (&mysql_res,"can not get number of attendance events",
"SELECT COUNT(*)," "SELECT COUNT(*)," // row[0]
"SUM(NumNotif)" "SUM(NumNotif)" // row[1]
" FROM att_events" " FROM att_events"
" WHERE CrsCod=%ld", " WHERE CrsCod=%ld",
Gbl.Hierarchy.Crs.CrsCod); Gbl.Hierarchy.Crs.CrsCod);
@ -2572,7 +2552,7 @@ static bool Att_CheckIfUsrIsInTableAttUsr (long AttCod,long UsrCod,bool *Present
/***** Check if a student is registered in an event in database *****/ /***** Check if a student is registered in an event in database *****/
InDBTable = (DB_QuerySELECT (&mysql_res,"can not check if a student" InDBTable = (DB_QuerySELECT (&mysql_res,"can not check if a student"
" is already registered in an event", " is already registered in an event",
"SELECT Present" "SELECT Present" // row[0]
" FROM att_users" " FROM att_users"
" WHERE AttCod=%ld" " WHERE AttCod=%ld"
" AND UsrCod=%ld", " AND UsrCod=%ld",
@ -3009,7 +2989,6 @@ static void Att_GetListSelectedAttCods (struct Att_Events *Events)
long AttCod; long AttCod;
char LongStr[Cns_MAX_DECIMAL_DIGITS_LONG + 1]; char LongStr[Cns_MAX_DECIMAL_DIGITS_LONG + 1];
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumGrpsInThisEvent; unsigned NumGrpsInThisEvent;
unsigned NumGrpInThisEvent; unsigned NumGrpInThisEvent;
long GrpCodInThisEvent; long GrpCodInThisEvent;
@ -3090,8 +3069,7 @@ static void Att_GetListSelectedAttCods (struct Att_Events *Events)
NumGrpInThisEvent++) NumGrpInThisEvent++)
{ {
/* Get next group associated to this event */ /* Get next group associated to this event */
row = mysql_fetch_row (mysql_res); if ((GrpCodInThisEvent = DB_GetNextCod (mysql_res)) > 0)
if ((GrpCodInThisEvent = Str_ConvertStrCodToLongCod (row[0])) > 0)
/* Check if this group is selected */ /* Check if this group is selected */
for (NumGrpSel = 0; for (NumGrpSel = 0;
NumGrpSel < Gbl.Crs.Grps.LstGrpsSel.NumGrps && NumGrpSel < Gbl.Crs.Grps.LstGrpsSel.NumGrps &&

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.54 (2021-03-30)" #define Log_PLATFORM_VERSION "SWAD 20.55 (2021-04-04)"
#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.55: Apr 04, 2021 Optimizations in database selects. (309500 lines)
Version 20.54: Mar 30, 2021 Statistics about agendas. (309539 lines) Version 20.54: Mar 30, 2021 Statistics about agendas. (309539 lines)
Version 20.53.1: Mar 30, 2021 Optimizations in database selects. (309459 lines) Version 20.53.1: Mar 30, 2021 Optimizations in database selects. (309459 lines)
Version 20.53: Mar 29, 2021 Code refactoring in database selects. (309473 lines) Version 20.53: Mar 29, 2021 Code refactoring in database selects. (309473 lines)

View File

@ -3793,15 +3793,53 @@ unsigned long DB_QuerySELECT (MYSQL_RES **mysql_res,const char *MsgError,
int NumBytesPrinted; int NumBytesPrinted;
char *Query; char *Query;
/***** Create query string *****/
va_start (ap,fmt); va_start (ap,fmt);
NumBytesPrinted = vasprintf (&Query,fmt,ap); NumBytesPrinted = vasprintf (&Query,fmt,ap);
va_end (ap); va_end (ap);
if (NumBytesPrinted < 0) // -1 if no memory or any other error if (NumBytesPrinted < 0) // -1 if no memory or any other error
Lay_NotEnoughMemoryExit (); Lay_NotEnoughMemoryExit ();
/***** Do SELECT query *****/
return DB_QuerySELECTusingQueryStr (Query,mysql_res,MsgError); return DB_QuerySELECTusingQueryStr (Query,mysql_res,MsgError);
} }
/*****************************************************************************/
/*** Make a SELECT query for a unique row with one long code from database ***/
/*****************************************************************************/
long DB_QuerySELECTCod (const char *MsgError,
const char *fmt,...)
{
MYSQL_RES *mysql_res;
va_list ap;
int NumBytesPrinted;
char *Query;
long Cod;
/***** 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
Cod = DB_GetNextCod (mysql_res);
else
Cod = -1L;
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
return Cod;
}
/*****************************************************************************/
/*********** Make a SELECT query from database using query string ************/
/*****************************************************************************/
static unsigned long DB_QuerySELECTusingQueryStr (char *Query, static unsigned long DB_QuerySELECTusingQueryStr (char *Query,
MYSQL_RES **mysql_res, MYSQL_RES **mysql_res,
const char *MsgError) const char *MsgError)

View File

@ -41,6 +41,8 @@ void DB_BuildQuery (char **Query,const char *fmt,...);
unsigned long DB_QuerySELECT (MYSQL_RES **mysql_res,const char *MsgError, unsigned long DB_QuerySELECT (MYSQL_RES **mysql_res,const char *MsgError,
const char *fmt,...); const char *fmt,...);
long DB_QuerySELECTCod (const char *MsgError,
const char *fmt,...);
long DB_GetNextCod (MYSQL_RES *mysql_res); long DB_GetNextCod (MYSQL_RES *mysql_res);
unsigned long DB_GetNumRowsTable (const char *Table); unsigned long DB_GetNumRowsTable (const char *Table);
unsigned long DB_QueryCOUNT (const char *MsgError,const char *fmt,...); unsigned long DB_QueryCOUNT (const char *MsgError,const char *fmt,...);