mirror of https://github.com/acanas/swad-core.git
Version 21.47.5: Oct 29, 2021 Queries moved to module swad_questions_database.
This commit is contained in:
parent
8deffc3112
commit
ee52848fca
|
@ -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 21.47.4 (2021-10-30)"
|
||||
#define Log_PLATFORM_VERSION "SWAD 21.47.5 (2021-10-30)"
|
||||
#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 21.47.5: Oct 29, 2021 Queries moved to module swad_questions_database. (321308 lines)
|
||||
Version 21.47.4: Oct 30, 2021 Review of comments. (321253 lines)
|
||||
Version 21.47.3: Oct 29, 2021 Queries moved to module swad_questions_database. (321299 lines)
|
||||
Version 21.47.2: Oct 29, 2021 Queries moved to module swad_questions_database. (321259 lines)
|
||||
|
|
164
swad_question.c
164
swad_question.c
|
@ -3061,19 +3061,9 @@ bool Qst_CheckIfQuestionExistsInDB (struct Qst_Question *Question)
|
|||
unsigned NumOptsExistingQstInDB;
|
||||
unsigned i;
|
||||
|
||||
/***** Check if stem exists *****/
|
||||
NumQstsWithThisStem =
|
||||
(unsigned) DB_QuerySELECT (&mysql_res_qst,"can not check if a question exists",
|
||||
"SELECT QstCod"
|
||||
" FROM tst_questions"
|
||||
" WHERE CrsCod=%ld"
|
||||
" AND AnsType='%s'"
|
||||
" AND Stem='%s'",
|
||||
Gbl.Hierarchy.Crs.CrsCod,
|
||||
Qst_DB_StrAnswerTypes[Question->Answer.Type],
|
||||
Question->Stem);
|
||||
|
||||
if (NumQstsWithThisStem) // There are questions in database with the same stem that the one of this question
|
||||
/***** Check if there are existing questions in database
|
||||
with the same stem that the one of this question *****/
|
||||
if ((NumQstsWithThisStem = Qst_DB_GetQstCodFromTypeAnsStem (&mysql_res_qst,Question)))
|
||||
{
|
||||
/***** Check if the answer exists in any of the questions with the same stem *****/
|
||||
/* For each question with the same stem */
|
||||
|
@ -3429,17 +3419,8 @@ void Qst_ChangeShuffleQst (void)
|
|||
/***** Get a parameter that indicates whether it's possible to shuffle the answers of this question ******/
|
||||
Shuffle = Par_GetParToBool ("Shuffle");
|
||||
|
||||
/***** Remove the question from all tables *****/
|
||||
/* Update the question changing the current shuffle */
|
||||
DB_QueryUPDATE ("can not update the shuffle type of a question",
|
||||
"UPDATE tst_questions"
|
||||
" SET Shuffle='%c'"
|
||||
" WHERE QstCod=%ld"
|
||||
" AND CrsCod=%ld",
|
||||
Shuffle ? 'Y' :
|
||||
'N',
|
||||
Questions.Question.QstCod,
|
||||
Gbl.Hierarchy.Crs.CrsCod);
|
||||
/***** Update the question changing the current shuffle *****/
|
||||
Qst_DB_UpdateQstShuffle (Questions.Question.QstCod,Shuffle);
|
||||
|
||||
/***** Write message *****/
|
||||
Ale_ShowAlert (Ale_SUCCESS,Shuffle ? Txt_The_answers_of_the_question_with_code_X_will_appear_shuffled :
|
||||
|
@ -3508,64 +3489,14 @@ void Qst_InsertOrUpdateQstIntoDB (struct Qst_Question *Question)
|
|||
extern const char *Qst_DB_StrAnswerTypes[Qst_NUM_ANS_TYPES];
|
||||
|
||||
if (Question->QstCod < 0) // It's a new question
|
||||
{
|
||||
/***** Insert question in the table of questions *****/
|
||||
Question->QstCod =
|
||||
DB_QueryINSERTandReturnCode ("can not create question",
|
||||
"INSERT INTO tst_questions"
|
||||
" (CrsCod,"
|
||||
"EditTime,"
|
||||
"AnsType,"
|
||||
"Shuffle,"
|
||||
"Stem,"
|
||||
"Feedback,"
|
||||
"MedCod,"
|
||||
"NumHits,"
|
||||
"Score)"
|
||||
" VALUES"
|
||||
" (%ld," // CrsCod
|
||||
"NOW()," // EditTime
|
||||
"'%s'," // AnsType
|
||||
"'%c'," // Shuffle
|
||||
"'%s'," // Stem
|
||||
"'%s'," // Feedback
|
||||
"%ld," // MedCod
|
||||
"0," // NumHits
|
||||
"0)", // Score
|
||||
Gbl.Hierarchy.Crs.CrsCod,
|
||||
Qst_DB_StrAnswerTypes[Question->Answer.Type],
|
||||
Question->Answer.Shuffle ? 'Y' :
|
||||
'N',
|
||||
Question->Stem,
|
||||
Question->Feedback ? Question->Feedback :
|
||||
"",
|
||||
Question->Media.MedCod);
|
||||
}
|
||||
Question->QstCod = Qst_DB_CreateQst (Question);
|
||||
else // It's an existing question
|
||||
{
|
||||
/***** Update existing question *****/
|
||||
/* Update question in database */
|
||||
DB_QueryUPDATE ("can not update question",
|
||||
"UPDATE tst_questions"
|
||||
" SET EditTime=NOW(),"
|
||||
"AnsType='%s',"
|
||||
"Shuffle='%c',"
|
||||
"Stem='%s',"
|
||||
"Feedback='%s',"
|
||||
"MedCod=%ld"
|
||||
" WHERE QstCod=%ld"
|
||||
" AND CrsCod=%ld",
|
||||
Qst_DB_StrAnswerTypes[Question->Answer.Type],
|
||||
Question->Answer.Shuffle ? 'Y' :
|
||||
'N',
|
||||
Question->Stem,
|
||||
Question->Feedback ? Question->Feedback :
|
||||
"",
|
||||
Question->Media.MedCod,
|
||||
Question->QstCod,
|
||||
Gbl.Hierarchy.Crs.CrsCod);
|
||||
Qst_DB_UpdateQst (Question);
|
||||
|
||||
/* Remove answers and tags from this test question */
|
||||
/***** Remove answers and tags from this test question *****/
|
||||
Qst_DB_RemAnsFromQst (Question->QstCod);
|
||||
Tag_DB_RemTagsFromQst (Question->QstCod);
|
||||
}
|
||||
|
@ -3577,75 +3508,18 @@ void Qst_InsertOrUpdateQstIntoDB (struct Qst_Question *Question)
|
|||
|
||||
void Qst_InsertAnswersIntoDB (struct Qst_Question *Question)
|
||||
{
|
||||
unsigned NumOpt;
|
||||
unsigned i;
|
||||
void (*Qst_DB_CreateAnswer[Qst_NUM_ANS_TYPES]) (struct Qst_Question *Question) =
|
||||
{
|
||||
[Qst_ANS_INT ] = Qst_DB_CreateIntAnswer,
|
||||
[Qst_ANS_FLOAT ] = Qst_DB_CreateFltAnswer,
|
||||
[Qst_ANS_TRUE_FALSE ] = Qst_DB_CreateTF_Answer,
|
||||
[Qst_ANS_UNIQUE_CHOICE ] = Qst_DB_CreateChoAnswer,
|
||||
[Qst_ANS_MULTIPLE_CHOICE] = Qst_DB_CreateChoAnswer,
|
||||
[Qst_ANS_TEXT ] = Qst_DB_CreateChoAnswer,
|
||||
};
|
||||
|
||||
/***** Insert answers in the answers table *****/
|
||||
switch (Question->Answer.Type)
|
||||
{
|
||||
case Qst_ANS_INT:
|
||||
DB_QueryINSERT ("can not create answer",
|
||||
"INSERT INTO tst_answers"
|
||||
" (QstCod,AnsInd,Answer,Feedback,MedCod,Correct)"
|
||||
" VALUES"
|
||||
" (%ld,0,%ld,'',-1,'Y')",
|
||||
Question->QstCod,
|
||||
Question->Answer.Integer);
|
||||
break;
|
||||
case Qst_ANS_FLOAT:
|
||||
Str_SetDecimalPointToUS (); // To print the floating point as a dot
|
||||
for (i = 0;
|
||||
i < 2;
|
||||
i++)
|
||||
DB_QueryINSERT ("can not create answer",
|
||||
"INSERT INTO tst_answers"
|
||||
" (QstCod,AnsInd,Answer,Feedback,MedCod,Correct)"
|
||||
" VALUES"
|
||||
" (%ld,%u,'%.15lg','',-1,'Y')",
|
||||
Question->QstCod,
|
||||
i,
|
||||
Question->Answer.FloatingPoint[i]);
|
||||
Str_SetDecimalPointToLocal (); // Return to local system
|
||||
break;
|
||||
case Qst_ANS_TRUE_FALSE:
|
||||
DB_QueryINSERT ("can not create answer",
|
||||
"INSERT INTO tst_answers"
|
||||
" (QstCod,AnsInd,Answer,Feedback,MedCod,Correct)"
|
||||
" VALUES"
|
||||
" (%ld,0,'%c','',-1,'Y')",
|
||||
Question->QstCod,
|
||||
Question->Answer.TF);
|
||||
break;
|
||||
case Qst_ANS_UNIQUE_CHOICE:
|
||||
case Qst_ANS_MULTIPLE_CHOICE:
|
||||
case Qst_ANS_TEXT:
|
||||
for (NumOpt = 0;
|
||||
NumOpt < Question->Answer.NumOptions;
|
||||
NumOpt++)
|
||||
if (Question->Answer.Options[NumOpt].Text[0] || // Text
|
||||
Question->Answer.Options[NumOpt].Media.Type != Med_TYPE_NONE) // or media
|
||||
{
|
||||
DB_QueryINSERT ("can not create answer",
|
||||
"INSERT INTO tst_answers"
|
||||
" (QstCod,AnsInd,Answer,Feedback,MedCod,Correct)"
|
||||
" VALUES"
|
||||
" (%ld,%u,'%s','%s',%ld,'%c')",
|
||||
Question->QstCod,NumOpt,
|
||||
Question->Answer.Options[NumOpt].Text,
|
||||
Question->Answer.Options[NumOpt].Feedback ? Question->Answer.Options[NumOpt].Feedback :
|
||||
"",
|
||||
Question->Answer.Options[NumOpt].Media.MedCod,
|
||||
Question->Answer.Options[NumOpt].Correct ? 'Y' :
|
||||
'N');
|
||||
|
||||
/* Update image status */
|
||||
if (Question->Answer.Options[NumOpt].Media.Type != Med_TYPE_NONE)
|
||||
Question->Answer.Options[NumOpt].Media.Status = Med_STORED_IN_DB;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/***** Create answer *****/
|
||||
Qst_DB_CreateAnswer[Question->Answer.Type] (Question);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -71,13 +71,77 @@ extern struct Globals Gbl;
|
|||
/***************************** Private prototypes ****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/*********** Insert or update question in the table of questions *************/
|
||||
/*****************************************************************************/
|
||||
|
||||
long Qst_DB_CreateQst (const struct Qst_Question *Question)
|
||||
{
|
||||
return
|
||||
DB_QueryINSERTandReturnCode ("can not create question",
|
||||
"INSERT INTO tst_questions"
|
||||
" (CrsCod,"
|
||||
"EditTime,"
|
||||
"AnsType,"
|
||||
"Shuffle,"
|
||||
"Stem,"
|
||||
"Feedback,"
|
||||
"MedCod,"
|
||||
"NumHits,"
|
||||
"Score)"
|
||||
" VALUES"
|
||||
" (%ld," // CrsCod
|
||||
"NOW()," // EditTime
|
||||
"'%s'," // AnsType
|
||||
"'%c'," // Shuffle
|
||||
"'%s'," // Stem
|
||||
"'%s'," // Feedback
|
||||
"%ld," // MedCod
|
||||
"0," // NumHits
|
||||
"0)", // Score
|
||||
Gbl.Hierarchy.Crs.CrsCod,
|
||||
Qst_DB_StrAnswerTypes[Question->Answer.Type],
|
||||
Question->Answer.Shuffle ? 'Y' :
|
||||
'N',
|
||||
Question->Stem,
|
||||
Question->Feedback ? Question->Feedback :
|
||||
"",
|
||||
Question->Media.MedCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************ Update existing question in the table of questions *************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Qst_DB_UpdateQst (const struct Qst_Question *Question)
|
||||
{
|
||||
DB_QueryUPDATE ("can not update question",
|
||||
"UPDATE tst_questions"
|
||||
" SET EditTime=NOW(),"
|
||||
"AnsType='%s',"
|
||||
"Shuffle='%c',"
|
||||
"Stem='%s',"
|
||||
"Feedback='%s',"
|
||||
"MedCod=%ld"
|
||||
" WHERE QstCod=%ld"
|
||||
" AND CrsCod=%ld", // Extra check
|
||||
Qst_DB_StrAnswerTypes[Question->Answer.Type],
|
||||
Question->Answer.Shuffle ? 'Y' :
|
||||
'N',
|
||||
Question->Stem,
|
||||
Question->Feedback ? Question->Feedback :
|
||||
"",
|
||||
Question->Media.MedCod,
|
||||
Question->QstCod,
|
||||
Gbl.Hierarchy.Crs.CrsCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*********************** Update the score of a question **********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Qst_DB_UpdateQstScore (long QstCod,bool AnswerIsNotBlank,double Score)
|
||||
{
|
||||
/***** Update number of clicks and score of the question *****/
|
||||
Str_SetDecimalPointToUS (); // To print the floating point as a dot
|
||||
if (AnswerIsNotBlank) // User's answer is not blank
|
||||
DB_QueryUPDATE ("can not update the score of a question",
|
||||
|
@ -97,6 +161,109 @@ void Qst_DB_UpdateQstScore (long QstCod,bool AnswerIsNotBlank,double Score)
|
|||
Str_SetDecimalPointToLocal (); // Return to local system
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*********************** Change the shuffle of a question ********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Qst_DB_UpdateQstShuffle (long QstCod,bool Shuffle)
|
||||
{
|
||||
DB_QueryUPDATE ("can not update the shuffle type of a question",
|
||||
"UPDATE tst_questions"
|
||||
" SET Shuffle='%c'"
|
||||
" WHERE QstCod=%ld"
|
||||
" AND CrsCod=%ld", // Extra check
|
||||
Shuffle ? 'Y' :
|
||||
'N',
|
||||
QstCod,
|
||||
Gbl.Hierarchy.Crs.CrsCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*************************** Create integer answer ***************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Qst_DB_CreateIntAnswer (const struct Qst_Question *Question)
|
||||
{
|
||||
DB_QueryINSERT ("can not create answer",
|
||||
"INSERT INTO tst_answers"
|
||||
" (QstCod,AnsInd,Answer,Feedback,MedCod,Correct)"
|
||||
" VALUES"
|
||||
" (%ld,0,%ld,'',-1,'Y')",
|
||||
Question->QstCod,
|
||||
Question->Answer.Integer);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**************************** Create float answer ****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Qst_DB_CreateFltAnswer (const struct Qst_Question *Question)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
Str_SetDecimalPointToUS (); // To print the floating point as a dot
|
||||
for (i = 0;
|
||||
i < 2;
|
||||
i++)
|
||||
DB_QueryINSERT ("can not create answer",
|
||||
"INSERT INTO tst_answers"
|
||||
" (QstCod,AnsInd,Answer,Feedback,MedCod,Correct)"
|
||||
" VALUES"
|
||||
" (%ld,%u,'%.15lg','',-1,'Y')",
|
||||
Question->QstCod,
|
||||
i,
|
||||
Question->Answer.FloatingPoint[i]);
|
||||
Str_SetDecimalPointToLocal (); // Return to local system
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************************** Create T/F answer *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Qst_DB_CreateTF_Answer (const struct Qst_Question *Question)
|
||||
{
|
||||
DB_QueryINSERT ("can not create answer",
|
||||
"INSERT INTO tst_answers"
|
||||
" (QstCod,AnsInd,Answer,Feedback,MedCod,Correct)"
|
||||
" VALUES"
|
||||
" (%ld,0,'%c','',-1,'Y')",
|
||||
Question->QstCod,
|
||||
Question->Answer.TF);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************************** Create T/F answer *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Qst_DB_CreateChoAnswer (struct Qst_Question *Question)
|
||||
{
|
||||
unsigned NumOpt;
|
||||
|
||||
for (NumOpt = 0;
|
||||
NumOpt < Question->Answer.NumOptions;
|
||||
NumOpt++)
|
||||
if (Question->Answer.Options[NumOpt].Text[0] || // Text
|
||||
Question->Answer.Options[NumOpt].Media.Type != Med_TYPE_NONE) // or media
|
||||
{
|
||||
DB_QueryINSERT ("can not create answer",
|
||||
"INSERT INTO tst_answers"
|
||||
" (QstCod,AnsInd,Answer,Feedback,MedCod,Correct)"
|
||||
" VALUES"
|
||||
" (%ld,%u,'%s','%s',%ld,'%c')",
|
||||
Question->QstCod,NumOpt,
|
||||
Question->Answer.Options[NumOpt].Text,
|
||||
Question->Answer.Options[NumOpt].Feedback ? Question->Answer.Options[NumOpt].Feedback :
|
||||
"",
|
||||
Question->Answer.Options[NumOpt].Media.MedCod,
|
||||
Question->Answer.Options[NumOpt].Correct ? 'Y' :
|
||||
'N');
|
||||
|
||||
/* Update image status */
|
||||
if (Question->Answer.Options[NumOpt].Media.Type != Med_TYPE_NONE)
|
||||
Question->Answer.Options[NumOpt].Media.Status = Med_STORED_IN_DB;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************** Get several test questions from database ******************/
|
||||
/*****************************************************************************/
|
||||
|
@ -951,6 +1118,25 @@ long Qst_DB_GetQstMedCod (long CrsCod,long QstCod)
|
|||
CrsCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/****************** Get question code from type and stem *********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
unsigned Qst_DB_GetQstCodFromTypeAnsStem (MYSQL_RES **mysql_res,
|
||||
const struct Qst_Question *Question)
|
||||
{
|
||||
return (unsigned)
|
||||
DB_QuerySELECT (mysql_res,"can not check if a question exists",
|
||||
"SELECT QstCod"
|
||||
" FROM tst_questions"
|
||||
" WHERE CrsCod=%ld"
|
||||
" AND AnsType='%s'"
|
||||
" AND Stem='%s'",
|
||||
Gbl.Hierarchy.Crs.CrsCod,
|
||||
Qst_DB_StrAnswerTypes[Question->Answer.Type],
|
||||
Question->Stem);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************ Get number of answers of a question from database **************/
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -39,7 +39,16 @@
|
|||
/***************************** Public prototypes *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
long Qst_DB_CreateQst (const struct Qst_Question *Question);
|
||||
void Qst_DB_UpdateQst (const struct Qst_Question *Question);
|
||||
void Qst_DB_UpdateQstScore (long QstCod,bool AnswerIsNotBlank,double Score);
|
||||
void Qst_DB_UpdateQstShuffle (long QstCod,bool Shuffle);
|
||||
//-----------------------------------------------------------------------------
|
||||
void Qst_DB_CreateIntAnswer (struct Qst_Question *Question);
|
||||
void Qst_DB_CreateFltAnswer (struct Qst_Question *Question);
|
||||
void Qst_DB_CreateTF_Answer (struct Qst_Question *Question);
|
||||
void Qst_DB_CreateChoAnswer (struct Qst_Question *Question);
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
unsigned Qst_DB_GetQsts (MYSQL_RES **mysql_res,
|
||||
const struct Qst_Questions *Questions);
|
||||
|
@ -55,6 +64,8 @@ unsigned Qst_DB_GetNumCrssWithPluggableQsts (HieLvl_Level_t Scope,
|
|||
unsigned Qst_DB_GetQstData (MYSQL_RES **mysql_res,long QstCod);
|
||||
Qst_AnswerType_t Qst_DB_GetQstAnswerType (long QstCod);
|
||||
long Qst_DB_GetQstMedCod (long CrsCod,long QstCod);
|
||||
unsigned Qst_DB_GetQstCodFromTypeAnsStem (MYSQL_RES **mysql_res,
|
||||
const struct Qst_Question *Question);
|
||||
|
||||
unsigned Qst_DB_GetNumAnswersQst (long QstCod);
|
||||
unsigned Qst_DB_GetDataOfAnswers (MYSQL_RES **mysql_res,long QstCod,bool Shuffle);
|
||||
|
|
Loading…
Reference in New Issue