Version 20.96: Jul 27, 2021 Queries moved to module swad_exam_database.

This commit is contained in:
acanas 2021-07-27 21:33:09 +02:00
parent ea02337e65
commit ef2e43cdcc
8 changed files with 440 additions and 404 deletions

View File

@ -602,13 +602,14 @@ TODO: FIX BUG, URGENT! En las fechas como par
TODO: En las encuestas, que los estudiantes no puedan ver los resultados hasta que no finalice el plazo.
*/
#define Log_PLATFORM_VERSION "SWAD 20.95.3 (2021-07-20)"
#define Log_PLATFORM_VERSION "SWAD 20.96 (2021-07-27)"
#define CSS_FILE "swad20.45.css"
#define JS_FILE "swad20.69.1.js"
/*
TODO: Rename CENTRE to CENTER in help wiki.
TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams
Version 20.96: Jul 27, 2021 Queries moved to module swad_exam_database. (314247 lines)
Version 20.95.3: Jul 20, 2021 Queries moved to module swad_exam_database. (314210 lines)
Version 20.95.2: Jul 16, 2021 Queries moved to module swad_exam_database. (314137 lines)
Version 20.95.1: Jul 15, 2021 Queries moved to module swad_exam_database. (314082 lines)

View File

@ -795,63 +795,16 @@ static Exa_Order_t Exa_GetParamOrder (void)
void Exa_GetListExams (struct Exa_Exams *Exams,Exa_Order_t SelectedOrder)
{
static const char *OrderBySubQuery[Exa_NUM_ORDERS] =
{
[Exa_ORDER_BY_START_DATE] = "StartTime DESC,EndTime DESC,exa_exams.Title DESC",
[Exa_ORDER_BY_END_DATE ] = "EndTime DESC,StartTime DESC,exa_exams.Title DESC",
[Exa_ORDER_BY_TITLE ] = "exa_exams.Title",
};
MYSQL_RES *mysql_res;
MYSQL_ROW row;
char *HiddenSubQuery;
unsigned NumExam;
/***** Free list of exams *****/
if (Exams->LstIsRead)
Exa_FreeListExams (Exams);
/***** Subquery: get hidden exams depending on user's role *****/
switch (Gbl.Usrs.Me.Role.Logged)
{
case Rol_STD:
if (asprintf (&HiddenSubQuery," AND exa_exams.Hidden='N'") < 0)
Err_NotEnoughMemoryExit ();
break;
case Rol_NET:
case Rol_TCH:
case Rol_DEG_ADM:
case Rol_CTR_ADM:
case Rol_INS_ADM:
case Rol_SYS_ADM:
if (asprintf (&HiddenSubQuery,"%s","") < 0)
Err_NotEnoughMemoryExit ();
break;
default:
Err_WrongRoleExit ();
break;
}
/***** Get list of exams from database *****/
Exams->Num = (unsigned)
DB_QuerySELECT (&mysql_res,"can not get exams",
"SELECT exa_exams.ExaCod," // row[0]
"MIN(exa_sessions.StartTime) AS StartTime," // row[1]
"MAX(exa_sessions.EndTime) AS EndTime" // row[2]
" FROM exa_exams"
" LEFT JOIN exa_sessions"
" ON exa_exams.ExaCod=exa_sessions.ExaCod"
" WHERE exa_exams.CrsCod=%ld"
"%s"
" GROUP BY exa_exams.ExaCod"
" ORDER BY %s",
Gbl.Hierarchy.Crs.CrsCod,
HiddenSubQuery,
OrderBySubQuery[SelectedOrder]);
/***** Free allocated memory for subquery *****/
free (HiddenSubQuery);
if (Exams->Num) // Exams found...
if ((Exams->Num = Exa_DB_GetListExams (&mysql_res,SelectedOrder))) // Exams found...
{
/***** Create list of exams *****/
if ((Exams->Lst = malloc ((size_t) Exams->Num *
@ -956,25 +909,14 @@ void Exa_GetDataOfExamByCod (struct Exa_Exam *Exam)
}
/***** Get exam data from database *****/
if (DB_QuerySELECT (&mysql_res,"can not get exam data",
"SELECT ExaCod," // row[0]
"CrsCod," // row[1]
"Hidden," // row[2]
"UsrCod," // row[3]
"MaxGrade," // row[4]
"Visibility," // row[5]
"Title" // row[6]
" FROM exa_exams"
" WHERE ExaCod=%ld",
Exam->ExaCod)) // Exam found...
if (Exa_DB_GetDataOfExamByCod (&mysql_res,Exam->ExaCod)) // Exam found...
{
/* Get row */
row = mysql_fetch_row (mysql_res);
/* Get code of the exam (row[0]) */
/* Get code of the exam (row[0])
and code of the course (row[1]) */
Exam->ExaCod = Str_ConvertStrCodToLongCod (row[0]);
/* Get code of the course (row[1]) */
Exam->CrsCod = Str_ConvertStrCodToLongCod (row[1]);
/* Get whether the exam is hidden (row[2]) */
@ -994,16 +936,13 @@ void Exa_GetDataOfExamByCod (struct Exa_Exam *Exam)
/* Get the title of the exam (row[6]) */
Str_Copy (Exam->Title,row[6],sizeof (Exam->Title) - 1);
/* Get number of sets */
Exam->NumSets = Exa_DB_GetNumSetsExam (Exam->ExaCod);
/* Get number of questions */
Exam->NumQsts = Exa_DB_GetNumQstsExam (Exam->ExaCod);
/* Get number of sessions */
Exam->NumSess = Exa_DB_GetNumSessionsInExam (Exam->ExaCod);
/* Get number of open sessions */
/* Get number of sets,
number of questions,
number of sessions
and number of open sessions */
Exam->NumSets = Exa_DB_GetNumSetsExam (Exam->ExaCod);
Exam->NumQsts = Exa_DB_GetNumQstsExam (Exam->ExaCod);
Exam->NumSess = Exa_DB_GetNumSessionsInExam (Exam->ExaCod);
Exam->NumOpenSess = Exa_DB_GetNumOpenSessionsInExam (Exam->ExaCod);
}
else
@ -1016,20 +955,14 @@ void Exa_GetDataOfExamByCod (struct Exa_Exam *Exam)
if (Exam->ExaCod > 0)
{
/***** Get start and end times from database *****/
if (DB_QuerySELECT (&mysql_res,"can not get exam data",
"SELECT UNIX_TIMESTAMP(MIN(StartTime))," // row[0]
"UNIX_TIMESTAMP(MAX(EndTime))" // row[1]
" FROM exa_sessions"
" WHERE ExaCod=%ld",
Exam->ExaCod))
if (Exa_DB_GetExamStartEnd (&mysql_res,Exam->ExaCod))
{
/* Get row */
row = mysql_fetch_row (mysql_res);
/* Get start date (row[0] holds the start UTC time) */
/* Get start date (row[0] holds the start UTC time)
and end date (row[1] holds the end UTC time) */
Exam->TimeUTC[Dat_START_TIME] = Dat_GetUNIXTimeFromStr (row[0]);
/* Get end date (row[1] holds the end UTC time) */
Exam->TimeUTC[Dat_END_TIME ] = Dat_GetUNIXTimeFromStr (row[1]);
}
@ -1059,20 +992,6 @@ void Exa_FreeListExams (struct Exa_Exams *Exams)
}
}
/*****************************************************************************/
/********************** Get exam text from database **************************/
/*****************************************************************************/
void Exa_DB_GetExamTxt (long ExaCod,char Txt[Cns_MAX_BYTES_TEXT + 1])
{
/***** Get text of exam from database *****/
DB_QuerySELECTString (Txt,Cns_MAX_BYTES_TEXT,"can not get exam text",
"SELECT Txt"
" FROM exa_exams"
" WHERE ExaCod=%ld",
ExaCod);
}
/*****************************************************************************/
/*************** Ask for confirmation of removing of an exam *****************/
/*****************************************************************************/

View File

@ -68,8 +68,6 @@ void Exa_GetDataOfExamByCod (struct Exa_Exam *Exam);
void Exa_GetDataOfExamByFolder (struct Exa_Exam *Exam);
void Exa_FreeListExams (struct Exa_Exams *Exams);
void Exa_DB_GetExamTxt (long ExaCod,char Txt[Cns_MAX_BYTES_TEXT + 1]);
void Exa_AskRemExam (void);
void Exa_RemoveExam (void);
void Exa_RemoveCrsExams (long CrsCod);

View File

@ -33,6 +33,7 @@
#include "swad_exam_database.h"
#include "swad_exam_log.h"
#include "swad_exam_print.h"
#include "swad_exam_set.h"
#include "swad_global.h"
/*****************************************************************************/
@ -59,6 +60,215 @@ extern struct Globals Gbl;
static void Exa_DB_RemoveUsrSesResultsInCrs (long UsrCod,long CrsCod,const char *TableName);
/*****************************************************************************/
/*********************** Get list of all the exams *************************/
/*****************************************************************************/
unsigned Exa_DB_GetListExams (MYSQL_RES **mysql_res,Exa_Order_t SelectedOrder)
{
static const char *OrderBySubQuery[Exa_NUM_ORDERS] =
{
[Exa_ORDER_BY_START_DATE] = "StartTime DESC,EndTime DESC,exa_exams.Title DESC",
[Exa_ORDER_BY_END_DATE ] = "EndTime DESC,StartTime DESC,exa_exams.Title DESC",
[Exa_ORDER_BY_TITLE ] = "exa_exams.Title",
};
char *HiddenSubQuery;
unsigned NumExams;
/***** Subquery: get hidden exams depending on user's role *****/
switch (Gbl.Usrs.Me.Role.Logged)
{
case Rol_STD:
if (asprintf (&HiddenSubQuery," AND exa_exams.Hidden='N'") < 0)
Err_NotEnoughMemoryExit ();
break;
case Rol_NET:
case Rol_TCH:
case Rol_DEG_ADM:
case Rol_CTR_ADM:
case Rol_INS_ADM:
case Rol_SYS_ADM:
if (asprintf (&HiddenSubQuery,"%s","") < 0)
Err_NotEnoughMemoryExit ();
break;
default:
Err_WrongRoleExit ();
break;
}
/***** Get list of exams from database *****/
NumExams = (unsigned)
DB_QuerySELECT (mysql_res,"can not get exams",
"SELECT exa_exams.ExaCod," // row[0]
"MIN(exa_sessions.StartTime) AS StartTime," // row[1]
"MAX(exa_sessions.EndTime) AS EndTime" // row[2]
" FROM exa_exams"
" LEFT JOIN exa_sessions"
" ON exa_exams.ExaCod=exa_sessions.ExaCod"
" WHERE exa_exams.CrsCod=%ld"
"%s"
" GROUP BY exa_exams.ExaCod"
" ORDER BY %s",
Gbl.Hierarchy.Crs.CrsCod,
HiddenSubQuery,
OrderBySubQuery[SelectedOrder]);
/***** Free allocated memory for subquery *****/
free (HiddenSubQuery);
return NumExams;
}
/*****************************************************************************/
/********************** Get exam data using its code *************************/
/*****************************************************************************/
unsigned Exa_DB_GetDataOfExamByCod (MYSQL_RES **mysql_res,long ExaCod)
{
return (unsigned)
DB_QuerySELECT (mysql_res,"can not get exam data",
"SELECT ExaCod," // row[0]
"CrsCod," // row[1]
"Hidden," // row[2]
"UsrCod," // row[3]
"MaxGrade," // row[4]
"Visibility," // row[5]
"Title" // row[6]
" FROM exa_exams"
" WHERE ExaCod=%ld",
ExaCod);
}
/*****************************************************************************/
/*********************** Get exam start and end times ************************/
/*****************************************************************************/
unsigned Exa_DB_GetExamStartEnd (MYSQL_RES **mysql_res,long ExaCod)
{
return (unsigned)
DB_QuerySELECT (mysql_res,"can not get exam data",
"SELECT UNIX_TIMESTAMP(MIN(StartTime))," // row[0]
"UNIX_TIMESTAMP(MAX(EndTime))" // row[1]
" FROM exa_sessions"
" WHERE ExaCod=%ld",
ExaCod);
}
/*****************************************************************************/
/********************** Get exam text from database **************************/
/*****************************************************************************/
void Exa_DB_GetExamTxt (long ExaCod,char Txt[Cns_MAX_BYTES_TEXT + 1])
{
/***** Get text of exam from database *****/
DB_QuerySELECTString (Txt,Cns_MAX_BYTES_TEXT,"can not get exam text",
"SELECT Txt"
" FROM exa_exams"
" WHERE ExaCod=%ld",
ExaCod);
}
/*****************************************************************************/
/********************** Create a new set of questions ************************/
/*****************************************************************************/
long Exa_DB_CreateSet (const struct ExaSet_Set *Set,unsigned SetInd)
{
return
DB_QueryINSERTandReturnCode ("can not create new set of questions",
"INSERT INTO exa_sets"
" (ExaCod,SetInd,NumQstsToPrint,Title)"
" VALUES"
" (%ld,%u,%u,'%s')",
Set->ExaCod,
SetInd,
Set->NumQstsToPrint,
Set->Title);
}
/*****************************************************************************/
/******************** Update an existing set of questions ********************/
/*****************************************************************************/
void Exa_DB_UpdateSet (const struct ExaSet_Set *Set)
{
DB_QueryUPDATE ("can not update set of questions",
"UPDATE exa_sets"
" SET ExaCod=%ld,"
"SetInd=%u,"
"NumQstsToPrint=%u,"
"Title='%s'"
" WHERE SetCod=%ld",
Set->ExaCod,
Set->SetInd,
Set->NumQstsToPrint,
Set->Title,
Set->SetCod);
}
/*****************************************************************************/
/************************ Update set title in database ***********************/
/*****************************************************************************/
void Exa_DB_UpdateSetTitle (const struct ExaSet_Set *Set,
const char NewTitle[ExaSet_MAX_BYTES_TITLE + 1])
{
/***** Update set of questions changing old title by new title *****/
DB_QueryUPDATE ("can not update the title of a set of questions",
"UPDATE exa_sets"
" SET Title='%s'"
" WHERE SetCod=%ld"
" AND ExaCod=%ld", // Extra check
NewTitle,
Set->SetCod,
Set->ExaCod);
}
/*****************************************************************************/
/****** Update number of questions to appear in exam print in database *******/
/*****************************************************************************/
void Exa_DB_UpdateNumQstsToExam (const struct ExaSet_Set *Set,
unsigned NumQstsToPrint)
{
/***** Update set of questions changing old number by new number *****/
DB_QueryUPDATE ("can not update the number of questions to appear in exam print",
"UPDATE exa_sets"
" SET NumQstsToPrint=%u"
" WHERE SetCod=%ld"
" AND ExaCod=%ld", // Extra check
NumQstsToPrint,
Set->SetCod,
Set->ExaCod);
}
/*****************************************************************************/
/*********************** Get number of sets in an exam ***********************/
/*****************************************************************************/
unsigned Exa_DB_GetNumSetsExam (long ExaCod)
{
return (unsigned)
DB_QueryCOUNT ("can not get number of sets in an exam",
"SELECT COUNT(*)"
" FROM exa_sets"
" WHERE ExaCod=%ld",
ExaCod);
}
/*****************************************************************************/
/************* Get total number of questions to print in an exam *************/
/*****************************************************************************/
unsigned Exa_DB_GetNumQstsExam (long ExaCod)
{
return DB_QuerySELECTUnsigned ("can not get number of questions to print in an exam",
"SELECT SUM(NumQstsToPrint)"
" FROM exa_sets"
" WHERE ExaCod=%ld",
ExaCod);
}
/*****************************************************************************/
/***************** Get sets of questions in a given exam *********************/
/*****************************************************************************/
@ -68,14 +278,162 @@ unsigned Exa_DB_GetExamSets (MYSQL_RES **mysql_res,long ExaCod)
return (unsigned)
DB_QuerySELECT (mysql_res,"can not get sets of questions",
"SELECT SetCod," // row[0]
"NumQstsToPrint," // row[1]
"Title" // row[2]
"SetInd," // row[1]
"NumQstsToPrint," // row[2]
"Title" // row[3]
" FROM exa_sets"
" WHERE ExaCod=%ld"
" ORDER BY SetInd",
ExaCod);
}
/*****************************************************************************/
/*********************** Get set data using its code *************************/
/*****************************************************************************/
unsigned Exa_DB_GetDataOfSetByCod (MYSQL_RES **mysql_res,long SetCod)
{
return (unsigned)
DB_QuerySELECT (mysql_res,"can not get set data",
"SELECT SetCod," // row[0]
"ExaCod," // row[1]
"SetInd," // row[2]
"NumQstsToPrint," // row[3]
"Title" // row[4]
" FROM exa_sets"
" WHERE SetCod=%ld",
SetCod);
}
/*****************************************************************************/
/************** Check if the title of a set of questions exists **************/
/*****************************************************************************/
bool Exa_DB_CheckIfSimilarSetExists (const struct ExaSet_Set *Set,
const char Title[ExaSet_MAX_BYTES_TITLE + 1])
{
/***** Get number of set of questions with a field value from database *****/
return (DB_QueryCOUNT ("can not get similar sets of questions",
"SELECT COUNT(*)"
" FROM exa_sets,"
"exa_exams"
" WHERE exa_sets.ExaCod=%ld"
" AND exa_sets.Title='%s'"
" AND exa_sets.SetCod<>%ld"
" AND exa_sets.ExaCod=exa_exams.ExaCod"
" AND exa_exams.CrsCod=%ld", // Extra check
Set->ExaCod,Title,
Set->SetCod,
Gbl.Hierarchy.Crs.CrsCod) != 0);
}
/*****************************************************************************/
/****************** Get set index given exam and set code ********************/
/*****************************************************************************/
unsigned Exa_DB_GetSetIndFromSetCod (long ExaCod,long SetCod)
{
return DB_QuerySELECTUnsigned ("can not get set index",
"SELECT SetInd" // row[0]
" FROM exa_sets"
" WHERE SetCod=%u"
" AND ExaCod=%ld", // Extra check
SetCod,ExaCod);
}
/*****************************************************************************/
/****************** Get set code given exam and set index ********************/
/*****************************************************************************/
long Exa_DB_GetSetCodFromSetInd (long ExaCod,unsigned SetInd)
{
long SetCod;
/***** Get set code from set index *****/
SetCod = DB_QuerySELECTCode ("can not get set code",
"SELECT SetCod"
" FROM exa_sets"
" WHERE ExaCod=%ld"
" AND SetInd=%u",
ExaCod,
SetInd);
if (SetCod <= 0)
Err_WrongSetExit ();
return SetCod;
}
/*****************************************************************************/
/********************* Get maximum set index in an exam **********************/
/*****************************************************************************/
// Question index can be 1, 2, 3...
// Return 0 if no questions
unsigned Exa_DB_GetMaxSetIndexInExam (long ExaCod)
{
/***** Get maximum set index in an exam from database *****/
return DB_QuerySELECTUnsigned ("can not get max set index",
"SELECT MAX(SetInd)"
" FROM exa_sets"
" WHERE ExaCod=%ld",
ExaCod);
}
/*****************************************************************************/
/*********** Get previous set index to a given set index in an exam **********/
/*****************************************************************************/
// Input set index can be 1, 2, 3... n-1
// Return set index will be 1, 2, 3... n if previous set exists, or 0 if no previous set
unsigned Exa_DB_GetPrevSetIndexInExam (long ExaCod,unsigned SetInd)
{
/***** Get previous set index in an exam from database *****/
// Although indexes are always continuous...
// ...this implementation works even with non continuous indexes
return DB_QuerySELECTUnsigned ("can not get previous set index",
"SELECT COALESCE(MAX(SetInd),0)"
" FROM exa_sets"
" WHERE ExaCod=%ld"
" AND SetInd<%u",
ExaCod,
SetInd);
}
/*****************************************************************************/
/*************** Get next set index to a given index in an exam **************/
/*****************************************************************************/
// Input set index can be 0, 1, 2, 3... n-1
// Return set index will be 1, 2, 3... n if next set exists, or 0 if no next set
unsigned Exa_DB_GetNextSetIndexInExam (long ExaCod,unsigned SetInd)
{
/***** Get next set index in an exam from database *****/
// Although indexes are always continuous...
// ...this implementation works even with non continuous indexes
return DB_QuerySELECTUnsigned ("can not get next set index",
"SELECT COALESCE(MIN(SetInd),0)"
" FROM exa_sets"
" WHERE ExaCod=%ld"
" AND SetInd>%u",
ExaCod,
SetInd);
}
/*****************************************************************************/
/********************* Get number of questions in a set **********************/
/*****************************************************************************/
unsigned Exa_DB_GetNumQstsInSet (long SetCod)
{
/***** Get number of questions in set from database *****/
return (unsigned)
DB_QueryCOUNT ("can not get number of questions in a set",
"SELECT COUNT(*)"
" FROM exa_set_questions"
" WHERE SetCod=%ld",
SetCod);
}
/*****************************************************************************/
/******************* Get some random questions from a set ********************/
/*****************************************************************************/

View File

@ -30,6 +30,7 @@
#include "swad_exam_log.h"
#include "swad_exam_print.h"
#include "swad_exam_session.h"
#include "swad_exam_set.h"
#include "swad_test_type.h"
/*****************************************************************************/
@ -40,7 +41,30 @@
/***************************** Public prototypes *****************************/
/*****************************************************************************/
unsigned Exa_DB_GetListExams (MYSQL_RES **mysql_res,Exa_Order_t SelectedOrder);
unsigned Exa_DB_GetDataOfExamByCod (MYSQL_RES **mysql_res,long ExaCod);
unsigned Exa_DB_GetExamStartEnd (MYSQL_RES **mysql_res,long ExaCod);
void Exa_DB_GetExamTxt (long ExaCod,char Txt[Cns_MAX_BYTES_TEXT + 1]);
long Exa_DB_CreateSet (const struct ExaSet_Set *Set,unsigned SetInd);
void Exa_DB_UpdateSet (const struct ExaSet_Set *Set);
void Exa_DB_UpdateSetTitle (const struct ExaSet_Set *Set,
const char NewTitle[ExaSet_MAX_BYTES_TITLE + 1]);
void Exa_DB_UpdateNumQstsToExam (const struct ExaSet_Set *Set,
unsigned NumQstsToPrint);
unsigned Exa_DB_GetNumSetsExam (long ExaCod);
unsigned Exa_DB_GetNumQstsExam (long ExaCod);
unsigned Exa_DB_GetExamSets (MYSQL_RES **mysql_res,long ExaCod);
unsigned Exa_DB_GetDataOfSetByCod (MYSQL_RES **mysql_res,long SetCod);
bool Exa_DB_CheckIfSimilarSetExists (const struct ExaSet_Set *Set,
const char Title[ExaSet_MAX_BYTES_TITLE + 1]);
unsigned Exa_DB_GetSetIndFromSetCod (long ExaCod,long SetCod);
long Exa_DB_GetSetCodFromSetInd (long ExaCod,unsigned SetInd);
unsigned Exa_DB_GetMaxSetIndexInExam (long ExaCod);
unsigned Exa_DB_GetPrevSetIndexInExam (long ExaCod,unsigned SetInd);
unsigned Exa_DB_GetNextSetIndexInExam (long ExaCod,unsigned SetInd);
unsigned Exa_DB_GetNumQstsInSet (long SetCod);
unsigned Exa_DB_GetSomeQstsFromSetToPrint (MYSQL_RES **mysql_res,
long SetCod,unsigned NumQstsToPrint);
unsigned Exa_DB_GetValidityAndTypeOfQuestion (MYSQL_RES **mysql_res,long QstCod);

View File

@ -339,34 +339,38 @@ static void ExaPrn_GetQuestionsForNewPrintFromDB (struct ExaPrn_Print *Print,lon
/***** Get questions from all sets *****/
Print->NumQsts.All = 0;
if ((NumSets = Exa_DB_GetExamSets (&mysql_res,ExaCod)))
/***** For each set in exam... *****/
for (NumSet = 0;
NumSet < NumSets;
NumSet++)
{
/***** Create set of questions *****/
ExaSet_ResetSet (&Set);
NumSets = Exa_DB_GetExamSets (&mysql_res,ExaCod);
/***** Get set data *****/
row = mysql_fetch_row (mysql_res);
/*
row[0] SetCod
row[1] NumQstsToPrint
row[2] Title
*/
/* Get set code (row[0])
and set index (row[1]) */
Set.SetCod = Str_ConvertStrCodToLongCod (row[0]);
Set.NumQstsToPrint = Str_ConvertStrToUnsigned (row[1]);
/***** For each set in exam... *****/
for (NumSet = 0;
NumSet < NumSets;
NumSet++)
{
/***** Create set of questions *****/
ExaSet_ResetSet (&Set);
/* Get the title of the set (row[2]) */
Str_Copy (Set.Title,row[2],sizeof (Set.Title) - 1);
/***** Get set data *****/
row = mysql_fetch_row (mysql_res);
/*
row[0] SetCod
row[1] SetInd
row[2] NumQstsToPrint
row[3] Title
*/
/* Get set code (row[0]),
set index (row[1]),
and number of questions to print (row[2]) */
Set.SetCod = Str_ConvertStrCodToLongCod (row[0]);
Set.SetInd = Str_ConvertStrToUnsigned (row[1]);
Set.NumQstsToPrint = Str_ConvertStrToUnsigned (row[2]);
/***** Questions in this set *****/
NumQstsFromSet = ExaPrn_GetSomeQstsFromSetToPrint (Print,&Set,&NumQstsInPrint);
Print->NumQsts.All += NumQstsFromSet;
}
/* Get the title of the set (row[3]) */
Str_Copy (Set.Title,row[3],sizeof (Set.Title) - 1);
/***** Questions in this set *****/
NumQstsFromSet = ExaPrn_GetSomeQstsFromSetToPrint (Print,&Set,&NumQstsInPrint);
Print->NumQsts.All += NumQstsFromSet;
}
/***** Check *****/
if (Print->NumQsts.All != NumQstsInPrint)

View File

@ -37,6 +37,7 @@
#include "swad_database.h"
#include "swad_error.h"
#include "swad_exam.h"
#include "swad_exam_database.h"
#include "swad_exam_result.h"
#include "swad_exam_session.h"
#include "swad_exam_set.h"
@ -65,8 +66,6 @@ extern struct Globals Gbl;
#define ExaSet_MAX_SELECTED_QUESTIONS 10000
#define ExaSet_MAX_BYTES_LIST_SELECTED_QUESTIONS (ExaSet_MAX_SELECTED_QUESTIONS * (Cns_MAX_DECIMAL_DIGITS_LONG + 1))
#define ExaSet_AFTER_LAST_SET ((unsigned)((1UL << 31) - 1)) // 2^31 - 1, don't change this number because it is used in database to indicate that a session is finished
/*****************************************************************************/
/******************************* Private types *******************************/
/*****************************************************************************/
@ -81,11 +80,6 @@ extern struct Globals Gbl;
static void ExaSet_PutParamsOneQst (void *Exams);
static unsigned Exa_DB_GetNumQstsInSet (long SetCod);
static bool Exa_DB_CheckIfSimilarSetExists (const struct ExaSet_Set *Set,
const char Title[ExaSet_MAX_BYTES_TITLE + 1]);
static void ExaSet_PutFormNewSet (struct Exa_Exams *Exams,
struct Exa_Exam *Exam,
struct ExaSet_Set *Set,
@ -96,21 +90,9 @@ static bool ExaSet_CheckSetTitleReceivedFromForm (const struct ExaSet_Set *Set,
static void ExaSet_CreateSet (struct ExaSet_Set *Set);
static void ExaSet_UpdateSet (const struct ExaSet_Set *Set);
static void Exa_DB_UpdateSetTitle (const struct ExaSet_Set *Set,
const char NewTitle[ExaSet_MAX_BYTES_TITLE + 1]);
static void Exa_DB_UpdateNumQstsToExam (const struct ExaSet_Set *Set,
unsigned NumQstsToPrint);
static void ExaSet_PutParamSetCod (long SetCod);
static unsigned ExaSet_GetSetIndFromSetCod (long ExaCod,long SetCod);
static long ExaSet_GetSetCodFromSetInd (long ExaCod,unsigned SetInd);
static unsigned Exa_DB_GetMaxSetIndexInExam (long ExaCod);
static unsigned Exa_DB_GetPrevSetIndexInExam (long ExaCod,unsigned SetInd);
static unsigned Exa_DB_GetNextSetIndexInExam (long ExaCod,unsigned SetInd);
static void ExaSet_ListSetQuestions (struct Exa_Exams *Exams,
const struct Exa_Exam *Exam,
const struct ExaSet_Set *Set);
@ -185,21 +167,6 @@ long ExaSet_GetParamSetCod (void)
return Par_GetParToLong ("SetCod");
}
/*****************************************************************************/
/********************* Get number of questions in a set **********************/
/*****************************************************************************/
static unsigned Exa_DB_GetNumQstsInSet (long SetCod)
{
/***** Get number of questions in set from database *****/
return (unsigned)
DB_QueryCOUNT ("can not get number of questions in a set",
"SELECT COUNT(*)"
" FROM exa_set_questions"
" WHERE SetCod=%ld",
SetCod);
}
/*****************************************************************************/
/*********************** Get set data using its code *************************/
/*****************************************************************************/
@ -219,15 +186,7 @@ void ExaSet_GetDataOfSetByCod (struct ExaSet_Set *Set)
}
/***** Get data of set of questions from database *****/
if (DB_QuerySELECT (&mysql_res,"can not get set data",
"SELECT SetCod," // row[0]
"ExaCod," // row[1]
"SetInd," // row[2]
"NumQstsToPrint," // row[3]
"Title" // row[4]
" FROM exa_sets"
" WHERE SetCod=%ld",
Set->SetCod)) // Set found...
if (Exa_DB_GetDataOfSetByCod (&mysql_res,Set->SetCod)) // Set found...
{
/* Get row */
row = mysql_fetch_row (mysql_res);
@ -262,28 +221,6 @@ void ExaSet_GetDataOfSetByCod (struct ExaSet_Set *Set)
DB_FreeMySQLResult (&mysql_res);
}
/*****************************************************************************/
/************** Check if the title of a set of questions exists **************/
/*****************************************************************************/
static bool Exa_DB_CheckIfSimilarSetExists (const struct ExaSet_Set *Set,
const char Title[ExaSet_MAX_BYTES_TITLE + 1])
{
/***** Get number of set of questions with a field value from database *****/
return (DB_QueryCOUNT ("can not get similar sets of questions",
"SELECT COUNT(*)"
" FROM exa_sets,"
"exa_exams"
" WHERE exa_sets.ExaCod=%ld"
" AND exa_sets.Title='%s'"
" AND exa_sets.SetCod<>%ld"
" AND exa_sets.ExaCod=exa_exams.ExaCod"
" AND exa_exams.CrsCod=%ld", // Extra check
Set->ExaCod,Title,
Set->SetCod,
Gbl.Hierarchy.Crs.CrsCod) != 0);
}
/*****************************************************************************/
/********************* Put a form to create/edit an exam **********************/
/*****************************************************************************/
@ -549,16 +486,7 @@ static void ExaSet_CreateSet (struct ExaSet_Set *Set)
MaxSetInd = Exa_DB_GetMaxSetIndexInExam (Set->ExaCod);
/***** Create a new exam *****/
Set->SetCod =
DB_QueryINSERTandReturnCode ("can not create new set of questions",
"INSERT INTO exa_sets"
" (ExaCod,SetInd,NumQstsToPrint,Title)"
" VALUES"
" (%ld,%u,%u,'%s')",
Set->ExaCod,
MaxSetInd + 1,
Set->NumQstsToPrint,
Set->Title);
Set->SetCod = Exa_DB_CreateSet (Set,MaxSetInd + 1);
/***** Write success message *****/
Ale_ShowAlert (Ale_SUCCESS,Txt_Created_new_set_of_questions_X,
@ -574,88 +502,12 @@ static void ExaSet_UpdateSet (const struct ExaSet_Set *Set)
extern const char *Txt_The_set_of_questions_has_been_modified;
/***** Update the data of the set of questions *****/
DB_QueryUPDATE ("can not update set of questions",
"UPDATE exa_sets"
" SET ExaCod=%ld,"
"SetInd=%u,"
"NumQstsToPrint=%u,"
"Title='%s'"
" WHERE SetCod=%ld",
Set->ExaCod,
Set->SetInd,
Set->NumQstsToPrint,
Set->Title,
Set->SetCod);
Exa_DB_UpdateSet (Set);
/***** Write success message *****/
Ale_ShowAlert (Ale_SUCCESS,Txt_The_set_of_questions_has_been_modified);
}
/*****************************************************************************/
/************************ Update set title in database ***********************/
/*****************************************************************************/
static void Exa_DB_UpdateSetTitle (const struct ExaSet_Set *Set,
const char NewTitle[ExaSet_MAX_BYTES_TITLE + 1])
{
/***** Update set of questions changing old title by new title *****/
DB_QueryUPDATE ("can not update the title of a set of questions",
"UPDATE exa_sets"
" SET Title='%s'"
" WHERE SetCod=%ld"
" AND ExaCod=%ld", // Extra check
NewTitle,
Set->SetCod,
Set->ExaCod);
}
/*****************************************************************************/
/****** Update number of questions to appear in exam print in database *******/
/*****************************************************************************/
static void Exa_DB_UpdateNumQstsToExam (const struct ExaSet_Set *Set,
unsigned NumQstsToPrint)
{
/***** Update set of questions changing old number by new number *****/
DB_QueryUPDATE ("can not update the number of questions to appear in exam print",
"UPDATE exa_sets"
" SET NumQstsToPrint=%u"
" WHERE SetCod=%ld"
" AND ExaCod=%ld", // Extra check
NumQstsToPrint,
Set->SetCod,
Set->ExaCod);
}
/*****************************************************************************/
/******************* Get number of questions of an exam *********************/
/*****************************************************************************/
unsigned Exa_DB_GetNumSetsExam (long ExaCod)
{
/***** Get number of sets in an exam from database *****/
return (unsigned)
DB_QueryCOUNT ("can not get number of sets in an exam",
"SELECT COUNT(*)"
" FROM exa_sets"
" WHERE ExaCod=%ld",
ExaCod);
}
/*****************************************************************************/
/******************* Get number of questions of an exam *********************/
/*****************************************************************************/
unsigned Exa_DB_GetNumQstsExam (long ExaCod)
{
/***** Get total number of questions to appear in exam print *****/
return DB_QuerySELECTUnsigned ("can not get number of questions in an exam print",
"SELECT SUM(NumQstsToPrint)"
" FROM exa_sets"
" WHERE ExaCod=%ld",
ExaCod);
}
/*****************************************************************************/
/********** Request the creation or edition of an set of questions ***********/
/*****************************************************************************/
@ -771,114 +623,6 @@ static void ExaSet_PutParamSetCod (long SetCod)
Par_PutHiddenParamUnsigned (NULL,"SetCod",SetCod);
}
/*****************************************************************************/
/****************** Get set index given exam and set code ********************/
/*****************************************************************************/
static unsigned ExaSet_GetSetIndFromSetCod (long ExaCod,long SetCod)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
long SetInd;
/***** Get set index from set code *****/
if (!DB_QuerySELECT (&mysql_res,"can not get set index",
"SELECT SetInd" // row[0]
" FROM exa_sets"
" WHERE SetCod=%u"
" AND ExaCod=%ld", // Extra check
SetCod,ExaCod))
Err_WrongSetExit ();
/***** Get set code (row[0]) *****/
row = mysql_fetch_row (mysql_res);
SetInd = Str_ConvertStrToUnsigned (row[0]);
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
return SetInd;
}
/*****************************************************************************/
/****************** Get set code given exam and set index ********************/
/*****************************************************************************/
static long ExaSet_GetSetCodFromSetInd (long ExaCod,unsigned SetInd)
{
long SetCod;
/***** Get set code from set index *****/
SetCod = DB_QuerySELECTCode ("can not get set code",
"SELECT SetCod"
" FROM exa_sets"
" WHERE ExaCod=%ld"
" AND SetInd=%u",
ExaCod,
SetInd);
if (SetCod <= 0)
Err_WrongSetExit ();
return SetCod;
}
/*****************************************************************************/
/********************* Get maximum set index in an exam **********************/
/*****************************************************************************/
// Question index can be 1, 2, 3...
// Return 0 if no questions
static unsigned Exa_DB_GetMaxSetIndexInExam (long ExaCod)
{
/***** Get maximum set index in an exam from database *****/
return DB_QuerySELECTUnsigned ("can not get max set index",
"SELECT MAX(SetInd)"
" FROM exa_sets"
" WHERE ExaCod=%ld",
ExaCod);
}
/*****************************************************************************/
/*********** Get previous set index to a given set index in an exam **********/
/*****************************************************************************/
// Input set index can be 1, 2, 3... n-1
// Return set index will be 1, 2, 3... n if previous set exists, or 0 if no previous set
static unsigned Exa_DB_GetPrevSetIndexInExam (long ExaCod,unsigned SetInd)
{
/***** Get previous set index in an exam from database *****/
// Although indexes are always continuous...
// ...this implementation works even with non continuous indexes
return DB_QuerySELECTUnsigned ("can not get previous set index",
"SELECT COALESCE(MAX(SetInd),0)"
" FROM exa_sets"
" WHERE ExaCod=%ld"
" AND SetInd<%u",
ExaCod,
SetInd);
}
/*****************************************************************************/
/*************** Get next set index to a given index in an exam **************/
/*****************************************************************************/
// Input set index can be 0, 1, 2, 3... n-1
// Return set index will be 1, 2, 3... n if next set exists, or big number if no next set
static unsigned Exa_DB_GetNextSetIndexInExam (long ExaCod,unsigned SetInd)
{
/***** Get next set index in an exam from database *****/
// Although indexes are always continuous...
// ...this implementation works even with non continuous indexes
return DB_QuerySELECTUnsigned ("can not get next set index",
"SELECT COALESCE(MIN(SetInd),%u)"
" FROM exa_sets"
" WHERE ExaCod=%ld"
" AND SetInd>%u",
ExaSet_AFTER_LAST_SET, // End of sets has been reached
ExaCod,
SetInd);
}
/*****************************************************************************/
/************************* List the sets of an exam **************************/
/*****************************************************************************/
@ -898,24 +642,15 @@ void ExaSet_ListExamSets (struct Exa_Exams *Exams,
MaxSetInd = Exa_DB_GetMaxSetIndexInExam (Exam->ExaCod);
/***** Get data of set of questions from database *****/
NumSets = (unsigned)
DB_QuerySELECT (&mysql_res,"can not get sets of questions",
"SELECT SetCod," // row[0]
"SetInd," // row[1]
"NumQstsToPrint," // row[2]
"Title" // row[3]
" FROM exa_sets"
" WHERE ExaCod=%ld"
" ORDER BY SetInd",
Exam->ExaCod);
NumSets = Exa_DB_GetExamSets (&mysql_res,Exam->ExaCod);
/***** Begin box *****/
Exams->ExaCod = Exam->ExaCod;
Box_BoxBegin (NULL,Txt_Sets_of_questions,
NULL,NULL,
Hlp_ASSESSMENT_Exams_question_sets,Box_NOT_CLOSABLE);
/***** Show table with sets *****/
Exams->ExaCod = Exam->ExaCod;
if (NumSets)
ExaSet_ListOneOrMoreSetsForEdition (Exams,Exam,
MaxSetInd,
@ -1861,7 +1596,7 @@ void ExaSet_MoveUpSet (void)
Err_NoPermissionExit ();
/***** Get set index *****/
SetIndBottom = ExaSet_GetSetIndFromSetCod (Exam.ExaCod,Set.SetCod);
SetIndBottom = Exa_DB_GetSetIndFromSetCod (Exam.ExaCod,Set.SetCod);
/***** Move up set *****/
if (SetIndBottom > 1)
@ -1909,7 +1644,7 @@ void ExaSet_MoveDownSet (void)
Err_NoPermissionExit ();
/***** Get set index *****/
SetIndTop = ExaSet_GetSetIndFromSetCod (Exam.ExaCod,Set.SetCod);
SetIndTop = Exa_DB_GetSetIndFromSetCod (Exam.ExaCod,Set.SetCod);
/***** Get maximum set index *****/
MaxSetInd = Exa_DB_GetMaxSetIndexInExam (Exam.ExaCod);
@ -1919,7 +1654,7 @@ void ExaSet_MoveDownSet (void)
{
/* Indexes of sets to be exchanged */
SetIndBottom = Exa_DB_GetNextSetIndexInExam (Exam.ExaCod,SetIndTop);
if (SetIndBottom == ExaSet_AFTER_LAST_SET)
if (SetIndBottom == 0)
Err_ShowErrorAndExit ("Wrong set index.");
/* Exchange sets */
@ -2200,8 +1935,8 @@ static void ExaSet_ExchangeSets (long ExaCod,
Gbl.DB.LockedTables = true;
/***** Get set codes of the sets to be moved *****/
SetCodTop = ExaSet_GetSetCodFromSetInd (ExaCod,SetIndTop);
SetCodBottom = ExaSet_GetSetCodFromSetInd (ExaCod,SetIndBottom);
SetCodTop = Exa_DB_GetSetCodFromSetInd (ExaCod,SetIndTop);
SetCodBottom = Exa_DB_GetSetCodFromSetInd (ExaCod,SetIndBottom);
/***** Exchange indexes of sets *****/
/*

View File

@ -48,9 +48,6 @@ void ExaSet_ReceiveFormSet (void);
void ExaSet_ChangeSetTitle (void);
void ExaSet_ChangeNumQstsToExam (void);
unsigned Exa_DB_GetNumSetsExam (long ExaCod);
unsigned Exa_DB_GetNumQstsExam (long ExaCod);
void ExaSet_RequestCreatOrEditSet (void);
void ExaSet_ReqSelectQstsToAddToSet (void);
void ExaSet_ListQstsToAddToSet (void);