mirror of
https://github.com/acanas/swad-core.git
synced 2024-06-05 08:15:25 +02:00
Version 21.16: Sep 24, 2021 New module swad_match_database for database queries related to game matches.
This commit is contained in:
parent
b1bc902f24
commit
f0681a98aa
5
Makefile
5
Makefile
|
@ -63,8 +63,9 @@ OBJS = swad_account.o swad_account_database.o swad_action.o swad_admin.o \
|
|||
swad_log.o swad_log_database.o swad_logo.o \
|
||||
swad_MAC.o swad_mail.o swad_mail_database.o swad_main.o \
|
||||
swad_maintenance.o swad_map.o swad_mark.o swad_mark_database.o \
|
||||
swad_match.o swad_match_print.o swad_match_result.o swad_media.o \
|
||||
swad_media_database.o swad_menu.o swad_message.o swad_MFU.o \
|
||||
swad_match.o swad_match_database.o swad_match_print.o \
|
||||
swad_match_result.o swad_media.o swad_media_database.o swad_menu.o \
|
||||
swad_message.o swad_MFU.o \
|
||||
swad_network.o swad_nickname.o swad_notice.o swad_notification.o \
|
||||
swad_notification_database.o swad_pagination.o swad_parameter.o \
|
||||
swad_password.o swad_photo.o swad_place.o swad_plugin.o swad_privacy.o \
|
||||
|
|
|
@ -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.15 (2021-09-24)"
|
||||
#define Log_PLATFORM_VERSION "SWAD 21.16 (2021-09-24)"
|
||||
#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.16: Sep 24, 2021 New module swad_match_database for database queries related to game matches. (316995 lines)
|
||||
Version 21.15: Sep 24, 2021 New module swad_mark_database for database queries related to files of marks. (316792 lines)
|
||||
Version 21.14.1: Sep 23, 2021 Queries moved to module swad_mail_database. (316687 lines)
|
||||
Version 21.14: Sep 22, 2021 New module swad_mail_database for database queries related to mail domains. (316594 lines)
|
||||
|
|
|
@ -1750,7 +1750,7 @@ void Exa_DB_RemoveAllGrpsOfType (long GrpTypCod)
|
|||
/******************** Remove one group from all sessions *********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Exa_DB_RemoveGrpAssociatedToExamSess (long GrpCod)
|
||||
void Exa_DB_RemoveGroup (long GrpCod)
|
||||
{
|
||||
/***** Remove group from all the sessions *****/
|
||||
DB_QueryDELETE ("can not remove group"
|
||||
|
|
|
@ -135,7 +135,7 @@ void Exa_DB_RemoveAllGrpsFromExa (long ExaCod);
|
|||
void Exa_DB_RemoveAllGrpsFromCrs (long CrsCod);
|
||||
void Exa_DB_RemoveAllGrpsFromSes (long SesCod);
|
||||
void Exa_DB_RemoveAllGrpsOfType (long GrpTypCod);
|
||||
void Exa_DB_RemoveGrpAssociatedToExamSess (long GrpCod);
|
||||
void Exa_DB_RemoveGroup (long GrpCod);
|
||||
|
||||
//---------------------------------- Prints -----------------------------------
|
||||
long Exa_DB_CreatePrint (const struct ExaPrn_Print *Print);
|
||||
|
|
16
swad_game.c
16
swad_game.c
|
@ -43,6 +43,7 @@
|
|||
#include "swad_hierarchy_level.h"
|
||||
#include "swad_HTML.h"
|
||||
#include "swad_match.h"
|
||||
#include "swad_match_database.h"
|
||||
#include "swad_match_result.h"
|
||||
#include "swad_pagination.h"
|
||||
#include "swad_role.h"
|
||||
|
@ -1654,7 +1655,7 @@ static void Gam_ListGameQuestions (struct Gam_Games *Games,struct Gam_Game *Game
|
|||
bool ICanEditQuestions = Gam_CheckIfEditable (Game);
|
||||
|
||||
/***** Get data of questions from database *****/
|
||||
NumQsts = Gam_DB_GetGameQuestions (&mysql_res,Game->GamCod);
|
||||
NumQsts = Gam_DB_GetGameQuestionsBasic (&mysql_res,Game->GamCod);
|
||||
|
||||
/***** Begin box *****/
|
||||
Games->GamCod = Game->GamCod;
|
||||
|
@ -1743,17 +1744,16 @@ static void Gam_ListOneOrMoreQuestionsForEdition (struct Gam_Games *Games,
|
|||
/***** Get question data *****/
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
/*
|
||||
row[0] QstInd
|
||||
row[1] QstCod
|
||||
row[0] QstCod
|
||||
row[1] QstInd
|
||||
*/
|
||||
/* Get question code (row[0]) */
|
||||
Question.QstCod = Str_ConvertStrCodToLongCod (row[0]);
|
||||
|
||||
/* Get question index (row[0]) */
|
||||
QstInd = Str_ConvertStrToUnsigned (row[0]);
|
||||
/* Get question index (row[1]) */
|
||||
QstInd = Str_ConvertStrToUnsigned (row[1]);
|
||||
snprintf (StrQstInd,sizeof (StrQstInd),"%u",QstInd);
|
||||
|
||||
/* Get question code (row[1]) */
|
||||
Question.QstCod = Str_ConvertStrCodToLongCod (row[1]);
|
||||
|
||||
/* Initialize context */
|
||||
Games->GamCod = GamCod;
|
||||
Games->QstInd = QstInd;
|
||||
|
|
|
@ -511,22 +511,43 @@ unsigned Gam_DB_GetNumQstsGame (long GamCod)
|
|||
" WHERE GamCod=%ld",
|
||||
GamCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************ Get the questions of a game ************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
unsigned Gam_DB_GetGameQuestions (MYSQL_RES **mysql_res,long GamCod)
|
||||
unsigned Gam_DB_GetGameQuestionsBasic (MYSQL_RES **mysql_res,long GamCod)
|
||||
{
|
||||
return (unsigned)
|
||||
DB_QuerySELECT (mysql_res,"can not get game questions",
|
||||
"SELECT QstInd," // row[0]
|
||||
"QstCod" // row[1]
|
||||
"SELECT QstCod," // row[0]
|
||||
"QstInd" // row[1]
|
||||
" FROM gam_questions"
|
||||
" WHERE GamCod=%ld"
|
||||
" ORDER BY QstInd",
|
||||
GamCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************ Get the questions of a game ************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
unsigned Gam_DB_GetGameQuestionsFull (MYSQL_RES **mysql_res,long GamCod)
|
||||
{
|
||||
return (unsigned)
|
||||
DB_QuerySELECT (mysql_res,"can not get questions of a game",
|
||||
"SELECT gam_questions.QstCod," // row[0]
|
||||
"gam_questions.QstInd," // row[1]
|
||||
"tst_questions.AnsType," // row[2]
|
||||
"tst_questions.Shuffle" // row[3]
|
||||
" FROM gam_questions,"
|
||||
"tst_questions"
|
||||
" WHERE gam_questions.GamCod=%ld"
|
||||
" AND gam_questions.QstCod=tst_questions.QstCod"
|
||||
" ORDER BY gam_questions.QstInd",
|
||||
GamCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************ Get question code given game and index of question *************/
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -61,7 +61,8 @@ void Gam_DB_LockTable (void);
|
|||
void Gam_DB_UnlockTable (void);
|
||||
|
||||
unsigned Gam_DB_GetNumQstsGame (long GamCod);
|
||||
unsigned Gam_DB_GetGameQuestions (MYSQL_RES **mysql_res,long GamCod);
|
||||
unsigned Gam_DB_GetGameQuestionsBasic (MYSQL_RES **mysql_res,long GamCod);
|
||||
unsigned Gam_DB_GetGameQuestionsFull (MYSQL_RES **mysql_res,long GamCod);
|
||||
long Gam_DB_GetQstCodFromQstInd (long GamCod,unsigned QstInd);
|
||||
unsigned Gam_DB_GetQstIndFromQstCod (long GamCod,long QstCod);
|
||||
unsigned Gam_DB_GetMaxQuestionIndexInGame (long GamCod);
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#include "swad_group.h"
|
||||
#include "swad_group_database.h"
|
||||
#include "swad_HTML.h"
|
||||
#include "swad_match.h"
|
||||
#include "swad_match_database.h"
|
||||
#include "swad_notification.h"
|
||||
#include "swad_parameter.h"
|
||||
#include "swad_program.h"
|
||||
|
@ -3563,7 +3563,7 @@ static void Grp_RemoveGroupCompletely (void)
|
|||
Mch_DB_RemoveGroup (GrpDat.GrpCod);
|
||||
|
||||
/***** Remove this group from all exam sessions *****/
|
||||
Exa_DB_RemoveGrpAssociatedToExamSess (GrpDat.GrpCod);
|
||||
Exa_DB_RemoveGroup (GrpDat.GrpCod);
|
||||
|
||||
/***** Remove this group from all surveys *****/
|
||||
Svy_DB_RemoveGroup (GrpDat.GrpCod);
|
||||
|
|
388
swad_match.c
388
swad_match.c
|
@ -42,6 +42,7 @@
|
|||
#include "swad_group_database.h"
|
||||
#include "swad_HTML.h"
|
||||
#include "swad_match.h"
|
||||
#include "swad_match_database.h"
|
||||
#include "swad_match_result.h"
|
||||
#include "swad_role.h"
|
||||
#include "swad_setting.h"
|
||||
|
@ -82,18 +83,6 @@ typedef enum
|
|||
/***************************** Private constants *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
const char *Mch_ShowingStringsDB[Mch_NUM_SHOWING] =
|
||||
{
|
||||
[Mch_START ] = "start",
|
||||
[Mch_STEM ] = "stem",
|
||||
[Mch_ANSWERS] = "answers",
|
||||
[Mch_RESULTS] = "results",
|
||||
[Mch_END ] = "end",
|
||||
};
|
||||
|
||||
#define Mch_MAX_COLS 4
|
||||
#define Mch_NUM_COLS_DEFAULT 1
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************************** Private variables *****************************/
|
||||
/*****************************************************************************/
|
||||
|
@ -136,14 +125,8 @@ static void Mch_ListOneOrMoreMatchesResultTch (struct Gam_Games *Games,
|
|||
|
||||
static void Mch_GetMatchDataFromRow (MYSQL_RES *mysql_res,
|
||||
struct Mch_Match *Match);
|
||||
static Mch_Showing_t Mch_GetShowingFromStr (const char *Str);
|
||||
|
||||
static void Mch_RemoveMatchFromAllTables (long MchCod);
|
||||
static void Mch_DB_RemoveMatchFromTable (long MchCod,const char *TableName);
|
||||
static void Mch_DB_RemoveMatchesInGameFromTable (long GamCod,const char *TableName);
|
||||
static void Mch_DB_RemoveMatchesInCourseFromTable (long CrsCod,const char *TableName);
|
||||
static void Mch_DB_RemoveMatchesMadeByUsrFromTable (long UsrCod,const char *TableName);
|
||||
static void Mch_DB_RemoveMatchesMadeByUsrInCrsFromTable (long UsrCod,long CrsCod,const char *TableName);
|
||||
|
||||
static void Mch_PutParamsPlay (void *MchCod);
|
||||
static void Mch_PutParamMchCod (long MchCod);
|
||||
|
@ -1060,7 +1043,7 @@ static void Mch_GetMatchDataFromRow (MYSQL_RES *mysql_res,
|
|||
Match->Status.QstCod = Str_ConvertStrCodToLongCod (row[7]);
|
||||
|
||||
/* Get what to show (stem, answers, results) (row(8)) */
|
||||
Match->Status.Showing = Mch_GetShowingFromStr (row[8]);
|
||||
Match->Status.Showing = Mch_DB_GetShowingFromStr (row[8]);
|
||||
|
||||
/* Get countdown (row[9]) */
|
||||
Match->Status.Countdown = Str_ConvertStrCodToLongCod (row[9]);
|
||||
|
@ -1084,23 +1067,6 @@ static void Mch_GetMatchDataFromRow (MYSQL_RES *mysql_res,
|
|||
Match->Status.Playing = Mch_DB_GetIfMatchIsBeingPlayed (Match->MchCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/****************** Get parameter with what is being shown *******************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static Mch_Showing_t Mch_GetShowingFromStr (const char *Str)
|
||||
{
|
||||
Mch_Showing_t Showing;
|
||||
|
||||
for (Showing = (Mch_Showing_t) 0;
|
||||
Showing <= (Mch_Showing_t) (Mch_NUM_SHOWING - 1);
|
||||
Showing++)
|
||||
if (!strcmp (Str,Mch_ShowingStringsDB[Showing]))
|
||||
return Showing;
|
||||
|
||||
return (Mch_Showing_t) Mch_SHOWING_DEFAULT;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************** Request the removal of a match (game instance) ***************/
|
||||
/*****************************************************************************/
|
||||
|
@ -1192,20 +1158,7 @@ static void Mch_RemoveMatchFromAllTables (long MchCod)
|
|||
Mch_DB_RemoveMatchFromTable (MchCod,"mch_indexes");
|
||||
|
||||
/***** Remove match from main table *****/
|
||||
DB_QueryDELETE ("can not remove match",
|
||||
"DELETE FROM mch_matches"
|
||||
" WHERE MchCod=%ld",
|
||||
MchCod);
|
||||
}
|
||||
|
||||
static void Mch_DB_RemoveMatchFromTable (long MchCod,const char *TableName)
|
||||
{
|
||||
/***** Remove match from secondary table *****/
|
||||
DB_QueryDELETE ("can not remove match from table",
|
||||
"DELETE FROM %s"
|
||||
" WHERE MchCod=%ld",
|
||||
TableName,
|
||||
MchCod);
|
||||
Mch_DB_RemoveMatchFromTable (MchCod,"mch_matches");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -1215,34 +1168,16 @@ static void Mch_DB_RemoveMatchFromTable (long MchCod,const char *TableName)
|
|||
void Mch_RemoveMatchesInGameFromAllTables (long GamCod)
|
||||
{
|
||||
/***** Remove matches from secondary tables *****/
|
||||
Mch_DB_RemoveMatchesInGameFromTable (GamCod,"mch_players");
|
||||
Mch_DB_RemoveMatchesInGameFromTable (GamCod,"mch_playing");
|
||||
Mch_DB_RemoveMatchesInGameFromTable (GamCod,"mch_results");
|
||||
Mch_DB_RemoveMatchesInGameFromTable (GamCod,"mch_answers");
|
||||
Mch_DB_RemoveMatchesInGameFromTable (GamCod,"mch_times");
|
||||
Mch_DB_RemoveMatchesInGameFromTable (GamCod,"mch_groups");
|
||||
Mch_DB_RemoveMatchesInGameFromTable (GamCod,"mch_indexes");
|
||||
Mch_DB_RemoveMatchesInGameFromOtherTable (GamCod,"mch_players");
|
||||
Mch_DB_RemoveMatchesInGameFromOtherTable (GamCod,"mch_playing");
|
||||
Mch_DB_RemoveMatchesInGameFromOtherTable (GamCod,"mch_results");
|
||||
Mch_DB_RemoveMatchesInGameFromOtherTable (GamCod,"mch_answers");
|
||||
Mch_DB_RemoveMatchesInGameFromOtherTable (GamCod,"mch_times");
|
||||
Mch_DB_RemoveMatchesInGameFromOtherTable (GamCod,"mch_groups");
|
||||
Mch_DB_RemoveMatchesInGameFromOtherTable (GamCod,"mch_indexes");
|
||||
|
||||
/***** Remove matches from main table *****/
|
||||
DB_QueryDELETE ("can not remove matches of a game",
|
||||
"DELETE FROM mch_matches"
|
||||
" WHERE GamCod=%ld",
|
||||
GamCod);
|
||||
}
|
||||
|
||||
static void Mch_DB_RemoveMatchesInGameFromTable (long GamCod,const char *TableName)
|
||||
{
|
||||
/***** Remove matches in game from secondary table *****/
|
||||
DB_QueryDELETE ("can not remove matches of a game from table",
|
||||
"DELETE FROM %s"
|
||||
" USING mch_matches,"
|
||||
"%s"
|
||||
" WHERE mch_matches.GamCod=%ld"
|
||||
" AND mch_matches.MchCod=%s.MchCod",
|
||||
TableName,
|
||||
TableName,
|
||||
GamCod,
|
||||
TableName);
|
||||
/***** Remove matches in game from main table *****/
|
||||
Mch_DB_RemoveMatchesInGameFromMainTable (GamCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -1252,39 +1187,16 @@ static void Mch_DB_RemoveMatchesInGameFromTable (long GamCod,const char *TableNa
|
|||
void Mch_RemoveMatchesInCourseFromAllTables (long CrsCod)
|
||||
{
|
||||
/***** Remove matches from secondary tables *****/
|
||||
Mch_DB_RemoveMatchesInCourseFromTable (CrsCod,"mch_players");
|
||||
Mch_DB_RemoveMatchesInCourseFromTable (CrsCod,"mch_playing");
|
||||
Mch_DB_RemoveMatchesInCourseFromTable (CrsCod,"mch_results");
|
||||
Mch_DB_RemoveMatchesInCourseFromTable (CrsCod,"mch_answers");
|
||||
Mch_DB_RemoveMatchesInCourseFromTable (CrsCod,"mch_times");
|
||||
Mch_DB_RemoveMatchesInCourseFromTable (CrsCod,"mch_groups");
|
||||
Mch_DB_RemoveMatchesInCourseFromTable (CrsCod,"mch_indexes");
|
||||
Mch_DB_RemoveMatchesInCrsFromOtherTable (CrsCod,"mch_players");
|
||||
Mch_DB_RemoveMatchesInCrsFromOtherTable (CrsCod,"mch_playing");
|
||||
Mch_DB_RemoveMatchesInCrsFromOtherTable (CrsCod,"mch_results");
|
||||
Mch_DB_RemoveMatchesInCrsFromOtherTable (CrsCod,"mch_answers");
|
||||
Mch_DB_RemoveMatchesInCrsFromOtherTable (CrsCod,"mch_times");
|
||||
Mch_DB_RemoveMatchesInCrsFromOtherTable (CrsCod,"mch_groups");
|
||||
Mch_DB_RemoveMatchesInCrsFromOtherTable (CrsCod,"mch_indexes");
|
||||
|
||||
/***** Remove matches from main table *****/
|
||||
DB_QueryDELETE ("can not remove matches of a course",
|
||||
"DELETE FROM mch_matches"
|
||||
" USING gam_games,"
|
||||
"mch_matches"
|
||||
" WHERE gam_games.CrsCod=%ld"
|
||||
" AND gam_games.GamCod=mch_matches.GamCod",
|
||||
CrsCod);
|
||||
}
|
||||
|
||||
static void Mch_DB_RemoveMatchesInCourseFromTable (long CrsCod,const char *TableName)
|
||||
{
|
||||
/***** Remove matches in course from secondary table *****/
|
||||
DB_QueryDELETE ("can not remove matches of a course from table",
|
||||
"DELETE FROM %s"
|
||||
" USING gam_games,"
|
||||
"mch_matches,"
|
||||
"%s"
|
||||
" WHERE gam_games.CrsCod=%ld"
|
||||
" AND gam_games.GamCod=mch_matches.GamCod"
|
||||
" AND mch_matches.MchCod=%s.MchCod",
|
||||
TableName,
|
||||
TableName,
|
||||
CrsCod,
|
||||
TableName);
|
||||
/***** Remove matches in course from main table *****/
|
||||
Mch_DB_RemoveMatchesInCrsFromMainTable (CrsCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -1299,16 +1211,6 @@ void Mch_RemoveMatchesMadeByUsrInAllCrss (long UsrCod)
|
|||
Mch_DB_RemoveMatchesMadeByUsrFromTable (UsrCod,"mch_answers");
|
||||
}
|
||||
|
||||
static void Mch_DB_RemoveMatchesMadeByUsrFromTable (long UsrCod,const char *TableName)
|
||||
{
|
||||
/***** Remove matches in course from secondary table *****/
|
||||
DB_QueryDELETE ("can not remove matches of a user from table",
|
||||
"DELETE FROM %s"
|
||||
" WHERE UsrCod=%ld",
|
||||
TableName,
|
||||
UsrCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************** Remove matches made by user in a course *******************/
|
||||
/*****************************************************************************/
|
||||
|
@ -1321,26 +1223,6 @@ void Mch_RemoveMatchesMadeByUsrInCrs (long UsrCod,long CrsCod)
|
|||
Mch_DB_RemoveMatchesMadeByUsrInCrsFromTable (UsrCod,CrsCod,"mch_answers");
|
||||
}
|
||||
|
||||
static void Mch_DB_RemoveMatchesMadeByUsrInCrsFromTable (long UsrCod,long CrsCod,const char *TableName)
|
||||
{
|
||||
/***** Remove matches in course from secondary table *****/
|
||||
DB_QueryDELETE ("can not remove matches of a user from table",
|
||||
"DELETE FROM %s"
|
||||
" USING gam_games,"
|
||||
"mch_matches,"
|
||||
"%s"
|
||||
" WHERE gam_games.CrsCod=%ld"
|
||||
" AND gam_games.GamCod=mch_matches.GamCod"
|
||||
" AND mch_matches.MchCod=%s.MchCod"
|
||||
" AND %s.UsrCod=%ld",
|
||||
TableName,
|
||||
TableName,
|
||||
CrsCod,
|
||||
TableName,
|
||||
TableName,
|
||||
UsrCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************ Edit a match (game instance) ***********************/
|
||||
/*****************************************************************************/
|
||||
|
@ -1701,12 +1583,7 @@ void Mch_ChangeMatch (void)
|
|||
static void Mch_UpdateMatchTitleAndGrps (const struct Mch_Match *Match)
|
||||
{
|
||||
/***** Update match title into database *****/
|
||||
DB_QueryUPDATE ("can not update match",
|
||||
"UPDATE mch_matches"
|
||||
" SET Title='%s'"
|
||||
" WHERE MchCod=%ld",
|
||||
Match->Title,
|
||||
Match->MchCod);
|
||||
Mch_DB_UpdateMatchTitle (Match);
|
||||
|
||||
/***** Update groups associated to the match *****/
|
||||
Mch_DB_RemoveMatchFromTable (Match->MchCod,"mch_groups"); // Remove all groups associated to this match
|
||||
|
@ -1756,30 +1633,7 @@ static long Mch_CreateMatch (long GamCod,char Title[Mch_MAX_BYTES_TITLE + 1])
|
|||
long MchCod;
|
||||
|
||||
/***** Insert this new match into database *****/
|
||||
MchCod =
|
||||
DB_QueryINSERTandReturnCode ("can not create match",
|
||||
"INSERT mch_matches"
|
||||
" (GamCod,UsrCod,StartTime,EndTime,Title,"
|
||||
"QstInd,QstCod,Showing,Countdown,"
|
||||
"NumCols,ShowQstResults,ShowUsrResults)"
|
||||
" VALUES"
|
||||
" (%ld," // GamCod
|
||||
"%ld," // UsrCod
|
||||
"NOW()," // StartTime
|
||||
"NOW()," // EndTime
|
||||
"'%s'," // Title
|
||||
"0," // QstInd: Match has not started, so not the first question yet
|
||||
"-1," // QstCod: Non-existent question
|
||||
"'%s'," // Showing: What is being shown
|
||||
"-1," // Countdown: No countdown
|
||||
"%u," // NumCols: Number of columns in answers
|
||||
"'N'," // ShowQstResults: Don't show question results initially
|
||||
"'N')", // ShowUsrResults: Don't show user results initially
|
||||
GamCod,
|
||||
Gbl.Usrs.Me.UsrDat.UsrCod, // Game creator
|
||||
Title,
|
||||
Mch_ShowingStringsDB[Mch_SHOWING_DEFAULT],
|
||||
Mch_NUM_COLS_DEFAULT);
|
||||
MchCod = Mch_DB_CreateMatch (GamCod,Title);
|
||||
|
||||
/***** Create indexes for answers *****/
|
||||
Mch_CreateIndexes (GamCod,MchCod);
|
||||
|
@ -1809,18 +1663,7 @@ static void Mch_CreateIndexes (long GamCod,long MchCod)
|
|||
unsigned QstInd;
|
||||
|
||||
/***** Get questions of the game *****/
|
||||
NumQsts = (unsigned)
|
||||
DB_QuerySELECT (&mysql_res,"can not get questions of a game",
|
||||
"SELECT gam_questions.QstCod," // row[0]
|
||||
"gam_questions.QstInd," // row[1]
|
||||
"tst_questions.AnsType," // row[2]
|
||||
"tst_questions.Shuffle" // row[3]
|
||||
" FROM gam_questions,"
|
||||
"tst_questions"
|
||||
" WHERE gam_questions.GamCod=%ld"
|
||||
" AND gam_questions.QstCod=tst_questions.QstCod"
|
||||
" ORDER BY gam_questions.QstInd",
|
||||
GamCod);
|
||||
NumQsts = Gam_DB_GetGameQuestionsFull (&mysql_res,GamCod);
|
||||
|
||||
/***** For each question in game... *****/
|
||||
for (NumQst = 0;
|
||||
|
@ -1883,16 +1726,8 @@ static void Mch_ReorderAnswer (long MchCod,unsigned QstInd,
|
|||
/***** Initialize list of answers to empty string *****/
|
||||
StrAnswersOneQst[0] = '\0';
|
||||
|
||||
/***** Get questions of the game *****/
|
||||
NumAnss = (unsigned)
|
||||
DB_QuerySELECT (&mysql_res,"can not get questions of a game",
|
||||
"SELECT AnsInd" // row[0]
|
||||
" FROM tst_answers"
|
||||
" WHERE QstCod=%ld"
|
||||
" ORDER BY %s",
|
||||
Question->QstCod,
|
||||
Question->Answer.Shuffle ? "RAND()" : // Use RAND() because is really random; RAND(NOW()) repeats order
|
||||
"AnsInd");
|
||||
/***** Get suffled/not-shuffled answers indexes of question *****/
|
||||
NumAnss = Tst_DB_GetShuffledAnswersIndexes (&mysql_res,Question);
|
||||
|
||||
/***** For each answer in question... *****/
|
||||
for (NumAns = 0;
|
||||
|
@ -1915,14 +1750,7 @@ static void Mch_ReorderAnswer (long MchCod,unsigned QstInd,
|
|||
DB_FreeMySQLResult (&mysql_res);
|
||||
|
||||
/***** Create entry for this question in table of match indexes *****/
|
||||
DB_QueryINSERT ("can not create match indexes",
|
||||
"INSERT INTO mch_indexes"
|
||||
" (MchCod,QstInd,Indexes)"
|
||||
" VALUES"
|
||||
" (%ld,%u,'%s')",
|
||||
MchCod,
|
||||
QstInd,
|
||||
StrAnswersOneQst);
|
||||
Mch_DB_CreateQstIndexes (MchCod,QstInd,StrAnswersOneQst);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -1935,14 +1763,7 @@ void Mch_GetIndexes (long MchCod,unsigned QstInd,
|
|||
char StrIndexesOneQst[Tst_MAX_BYTES_INDEXES_ONE_QST + 1];
|
||||
|
||||
/***** Get indexes for a question from database *****/
|
||||
DB_QuerySELECTString (StrIndexesOneQst,sizeof (StrIndexesOneQst) - 1,
|
||||
"can not get data of a question",
|
||||
"SELECT Indexes" // row[0]
|
||||
" FROM mch_indexes"
|
||||
" WHERE MchCod=%ld"
|
||||
" AND QstInd=%u",
|
||||
MchCod,
|
||||
QstInd);
|
||||
Mch_DB_GetIndexes (MchCod,QstInd,StrIndexesOneQst);
|
||||
if (!StrIndexesOneQst[0])
|
||||
Err_ShowErrorAndExit ("No indexes found for a question.");
|
||||
|
||||
|
@ -1958,100 +1779,23 @@ static void Mch_CreateGrps (long MchCod)
|
|||
{
|
||||
unsigned NumGrpSel;
|
||||
|
||||
/***** Create groups associated to the match *****/
|
||||
for (NumGrpSel = 0;
|
||||
NumGrpSel < Gbl.Crs.Grps.LstGrpsSel.NumGrps;
|
||||
NumGrpSel++)
|
||||
/* Create group */
|
||||
DB_QueryINSERT ("can not associate a group to a match",
|
||||
"INSERT INTO mch_groups"
|
||||
" (MchCod,GrpCod)"
|
||||
" VALUES"
|
||||
" (%ld,%ld)",
|
||||
MchCod,
|
||||
Mch_DB_AssociateGroupToMatch (MchCod,
|
||||
Gbl.Crs.Grps.LstGrpsSel.GrpCods[NumGrpSel]);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********************* Remove one group from all matches *********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Mch_DB_RemoveGroup (long GrpCod)
|
||||
{
|
||||
/***** Remove group from all the matches *****/
|
||||
DB_QueryDELETE ("can not remove group"
|
||||
" from the associations between matches and groups",
|
||||
"DELETE FROM mch_groups"
|
||||
" WHERE GrpCod=%ld",
|
||||
GrpCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************** Remove groups of one type from all matches ****************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Mch_DB_RemoveGroupsOfType (long GrpTypCod)
|
||||
{
|
||||
/***** Remove group from all the matches *****/
|
||||
DB_QueryDELETE ("can not remove groups of a type"
|
||||
" from the associations between matches and groups",
|
||||
"DELETE FROM mch_groups"
|
||||
" USING grp_groups,"
|
||||
"mch_groups"
|
||||
" WHERE grp_groups.GrpTypCod=%ld"
|
||||
" AND grp_groups.GrpCod=mch_groups.GrpCod",
|
||||
GrpTypCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************** Insert/update a game match being played *******************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void Mch_UpdateMatchStatusInDB (const struct Mch_Match *Match)
|
||||
{
|
||||
char *MchSubQuery;
|
||||
|
||||
/***** Update end time only if match is currently being played *****/
|
||||
if (Match->Status.Playing) // Match is being played
|
||||
{
|
||||
if (asprintf (&MchSubQuery,"mch_matches.EndTime=NOW(),") < 0)
|
||||
Err_NotEnoughMemoryExit ();
|
||||
}
|
||||
else // Match is paused, not being played
|
||||
{
|
||||
if (asprintf (&MchSubQuery,"%s","") < 0)
|
||||
Err_NotEnoughMemoryExit ();
|
||||
}
|
||||
|
||||
/***** Update match status in database *****/
|
||||
DB_QueryUPDATE ("can not update match being played",
|
||||
"UPDATE mch_matches,"
|
||||
"gam_games"
|
||||
" SET %s"
|
||||
"mch_matches.QstInd=%u,"
|
||||
"mch_matches.QstCod=%ld,"
|
||||
"mch_matches.Showing='%s',"
|
||||
"mch_matches.Countdown=%ld,"
|
||||
"mch_matches.NumCols=%u,"
|
||||
"mch_matches.ShowQstResults='%c',"
|
||||
"mch_matches.ShowUsrResults='%c'"
|
||||
" WHERE mch_matches.MchCod=%ld"
|
||||
" AND mch_matches.GamCod=gam_games.GamCod"
|
||||
" AND gam_games.CrsCod=%ld", // Extra check
|
||||
MchSubQuery,
|
||||
Match->Status.QstInd,
|
||||
Match->Status.QstCod,
|
||||
Mch_ShowingStringsDB[Match->Status.Showing],
|
||||
Match->Status.Countdown,
|
||||
Match->Status.NumCols,
|
||||
Match->Status.ShowQstResults ? 'Y' :
|
||||
'N',
|
||||
Match->Status.ShowUsrResults ? 'Y' :
|
||||
'N',
|
||||
Match->MchCod,
|
||||
Gbl.Hierarchy.Crs.CrsCod);
|
||||
free (MchSubQuery);
|
||||
Mch_DB_UpdateMatchStatus (Match);
|
||||
|
||||
/***** Update match as being/not-being played */
|
||||
if (Match->Status.Playing) // Match is being played
|
||||
/* Update match as being played */
|
||||
Mch_DB_UpdateMatchAsBeingPlayed (Match->MchCod);
|
||||
|
@ -2070,17 +1814,7 @@ static void Mch_UpdateElapsedTimeInQuestion (const struct Mch_Match *Match)
|
|||
if (Match->Status.Playing && // Match is being played
|
||||
Match->Status.Showing != Mch_START &&
|
||||
Match->Status.Showing != Mch_END)
|
||||
DB_QueryINSERT ("can not update elapsed time in question",
|
||||
"INSERT INTO mch_times"
|
||||
" (MchCod,QstInd,ElapsedTime)"
|
||||
" VALUES"
|
||||
" (%ld,%u,SEC_TO_TIME(%u))"
|
||||
" ON DUPLICATE KEY"
|
||||
" UPDATE ElapsedTime=ADDTIME(ElapsedTime,SEC_TO_TIME(%u))",
|
||||
Match->MchCod,
|
||||
Match->Status.QstInd,
|
||||
Cfg_SECONDS_TO_REFRESH_MATCH_TCH,
|
||||
Cfg_SECONDS_TO_REFRESH_MATCH_TCH);
|
||||
Mch_DB_UpdateElapsedTimeInQuestion (Match->MchCod,Match->Status.QstInd);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -2504,46 +2238,6 @@ static void Mch_ShowMatchStatusForStd (struct Mch_Match *Match,Mch_Update_t Upda
|
|||
Mch_ShowRightColumnStd (Match,&UsrAnswer,Update);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********************** Get number of matches in a game **********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
unsigned Mch_DB_GetNumMchsInGame (long GamCod)
|
||||
{
|
||||
/***** Trivial check *****/
|
||||
if (GamCod < 0) // A non-existing game...
|
||||
return 0; // ...has no matches
|
||||
|
||||
/***** Get number of matches in a game from database *****/
|
||||
return (unsigned)
|
||||
DB_QueryCOUNT ("can not get number of matches of a game",
|
||||
"SELECT COUNT(*)"
|
||||
" FROM mch_matches"
|
||||
" WHERE GamCod=%ld",
|
||||
GamCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*************** Get number of unfinished matches in a game ******************/
|
||||
/*****************************************************************************/
|
||||
|
||||
unsigned Mch_DB_GetNumUnfinishedMchsInGame (long GamCod)
|
||||
{
|
||||
/***** Trivial check *****/
|
||||
if (GamCod < 0) // A non-existing game...
|
||||
return 0; // ...has no matches
|
||||
|
||||
/***** Get number of matches in a game from database *****/
|
||||
return (unsigned)
|
||||
DB_QueryCOUNT ("can not get number of unfinished matches of a game",
|
||||
"SELECT COUNT(*)"
|
||||
" FROM mch_matches"
|
||||
" WHERE GamCod=%ld"
|
||||
" AND Showing<>'%s'",
|
||||
GamCod,
|
||||
Mch_ShowingStringsDB[Mch_END]);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************ Check if I belong to any of the groups of a match **************/
|
||||
/*****************************************************************************/
|
||||
|
@ -4516,21 +4210,3 @@ unsigned Mch_DB_GetStartEndMatchesInGame (MYSQL_RES **mysql_res,long GamCod)
|
|||
" WHERE GamCod=%ld",
|
||||
GamCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********************** Remove answers of a game question ********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Mch_DB_RemAnswersOfAQuestion (long GamCod,unsigned QstInd)
|
||||
{
|
||||
/***** Remove answers from all matches of this game *****/
|
||||
DB_QueryDELETE ("can not remove the answers of a question",
|
||||
"DELETE FROM mch_answers"
|
||||
" USING mch_matches,"
|
||||
"mch_answers"
|
||||
" WHERE mch_matches.GamCod=%ld" // From all matches of this game...
|
||||
" AND mch_matches.MchCod=mch_answers.MchCod"
|
||||
" AND mch_answers.QstInd=%u", // ...remove only answers to this question
|
||||
GamCod,
|
||||
QstInd);
|
||||
}
|
||||
|
|
11
swad_match.h
11
swad_match.h
|
@ -52,6 +52,10 @@ typedef enum
|
|||
} Mch_Showing_t;
|
||||
#define Mch_SHOWING_DEFAULT Mch_START
|
||||
|
||||
/* Columns */
|
||||
#define Mch_MAX_COLS 4
|
||||
#define Mch_NUM_COLS_DEFAULT 1
|
||||
|
||||
struct Mch_Match
|
||||
{
|
||||
long MchCod;
|
||||
|
@ -119,18 +123,12 @@ void Mch_ResumeMatch (void);
|
|||
void Mch_GetIndexes (long MchCod,unsigned QstInd,
|
||||
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]);
|
||||
|
||||
void Mch_DB_RemoveGroup (long GrpCod);
|
||||
void Mch_DB_RemoveGroupsOfType (long GrpTypCod);
|
||||
|
||||
void Mch_PlayPauseMatch (void);
|
||||
void Mch_ChangeNumColsMch (void);
|
||||
void Mch_ToggleVisResultsMchQst (void);
|
||||
void Mch_BackMatch (void);
|
||||
void Mch_ForwardMatch (void);
|
||||
|
||||
unsigned Mch_DB_GetNumMchsInGame (long GamCod);
|
||||
unsigned Mch_DB_GetNumUnfinishedMchsInGame (long GamCod);
|
||||
|
||||
bool Mch_CheckIfICanPlayThisMatchBasedOnGrps (const struct Mch_Match *Match);
|
||||
|
||||
bool Mch_RegisterMeAsPlayerInMatch (struct Mch_Match *Match);
|
||||
|
@ -161,6 +159,5 @@ void Mch_DrawBarNumUsrs (unsigned NumRespondersAns,unsigned NumRespondersQst,boo
|
|||
void Mch_DB_UpdateIndexesOfQstsGreaterThan (long GamCod,unsigned QstInd);
|
||||
|
||||
unsigned Mch_DB_GetStartEndMatchesInGame (MYSQL_RES **mysql_res,long GamCod);
|
||||
void Mch_DB_RemAnswersOfAQuestion (long GamCod,unsigned QstInd);
|
||||
|
||||
#endif
|
||||
|
|
463
swad_match_database.c
Normal file
463
swad_match_database.c
Normal file
|
@ -0,0 +1,463 @@
|
|||
// swad_match_database.c: matches in games using remote control, operations woth database
|
||||
|
||||
/*
|
||||
SWAD (Shared Workspace At a Distance),
|
||||
is a web platform developed at the University of Granada (Spain),
|
||||
and used to support university teaching.
|
||||
|
||||
This file is part of SWAD core.
|
||||
Copyright (C) 1999-2021 Antonio Cañas Vargas
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*****************************************************************************/
|
||||
/********************************* Headers ***********************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#define _GNU_SOURCE // For asprintf
|
||||
// #include <linux/limits.h> // For PATH_MAX
|
||||
// #include <stddef.h> // For NULL
|
||||
#include <stdio.h> // For asprintf
|
||||
// #include <stdlib.h> // For free
|
||||
#include <string.h> // For string functions
|
||||
|
||||
#include "swad_database.h"
|
||||
// #include "swad_date.h"
|
||||
#include "swad_error.h"
|
||||
// #include "swad_form.h"
|
||||
// #include "swad_game.h"
|
||||
// #include "swad_game_database.h"
|
||||
#include "swad_global.h"
|
||||
// #include "swad_group_database.h"
|
||||
// #include "swad_HTML.h"
|
||||
// #include "swad_match.h"
|
||||
#include "swad_match_database.h"
|
||||
// #include "swad_match_result.h"
|
||||
// #include "swad_role.h"
|
||||
// #include "swad_setting.h"
|
||||
// #include "swad_test.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/************** External global variables from others modules ****************/
|
||||
/*****************************************************************************/
|
||||
|
||||
extern struct Globals Gbl;
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************************** Private constants *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************************* Private types *******************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************************** Private constants *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
const char *Mch_ShowingStringsDB[Mch_NUM_SHOWING] =
|
||||
{
|
||||
[Mch_START ] = "start",
|
||||
[Mch_STEM ] = "stem",
|
||||
[Mch_ANSWERS] = "answers",
|
||||
[Mch_RESULTS] = "results",
|
||||
[Mch_END ] = "end",
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************************** Private variables *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/********************** Create a new match in a game *************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
long Mch_DB_CreateMatch (long GamCod,char Title[Mch_MAX_BYTES_TITLE + 1])
|
||||
{
|
||||
return
|
||||
DB_QueryINSERTandReturnCode ("can not create match",
|
||||
"INSERT mch_matches"
|
||||
" (GamCod,UsrCod,StartTime,EndTime,Title,"
|
||||
"QstInd,QstCod,Showing,Countdown,"
|
||||
"NumCols,ShowQstResults,ShowUsrResults)"
|
||||
" VALUES"
|
||||
" (%ld," // GamCod
|
||||
"%ld," // UsrCod
|
||||
"NOW()," // StartTime
|
||||
"NOW()," // EndTime
|
||||
"'%s'," // Title
|
||||
"0," // QstInd: Match has not started, so not the first question yet
|
||||
"-1," // QstCod: Non-existent question
|
||||
"'%s'," // Showing: What is being shown
|
||||
"-1," // Countdown: No countdown
|
||||
"%u," // NumCols: Number of columns in answers
|
||||
"'N'," // ShowQstResults: Don't show question results initially
|
||||
"'N')", // ShowUsrResults: Don't show user results initially
|
||||
GamCod,
|
||||
Gbl.Usrs.Me.UsrDat.UsrCod, // Game creator
|
||||
Title,
|
||||
Mch_ShowingStringsDB[Mch_SHOWING_DEFAULT],
|
||||
Mch_NUM_COLS_DEFAULT);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************** Update a game match being played ***********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Mch_DB_UpdateMatchStatus (const struct Mch_Match *Match)
|
||||
{
|
||||
char *MchSubQuery;
|
||||
|
||||
/***** Update end time only if match is currently being played *****/
|
||||
if (Match->Status.Playing) // Match is being played
|
||||
{
|
||||
if (asprintf (&MchSubQuery,"mch_matches.EndTime=NOW(),") < 0)
|
||||
Err_NotEnoughMemoryExit ();
|
||||
}
|
||||
else // Match is paused, not being played
|
||||
{
|
||||
if (asprintf (&MchSubQuery,"%s","") < 0)
|
||||
Err_NotEnoughMemoryExit ();
|
||||
}
|
||||
|
||||
/***** Update match status in database *****/
|
||||
DB_QueryUPDATE ("can not update match being played",
|
||||
"UPDATE mch_matches,"
|
||||
"gam_games"
|
||||
" SET %s"
|
||||
"mch_matches.QstInd=%u,"
|
||||
"mch_matches.QstCod=%ld,"
|
||||
"mch_matches.Showing='%s',"
|
||||
"mch_matches.Countdown=%ld,"
|
||||
"mch_matches.NumCols=%u,"
|
||||
"mch_matches.ShowQstResults='%c',"
|
||||
"mch_matches.ShowUsrResults='%c'"
|
||||
" WHERE mch_matches.MchCod=%ld"
|
||||
" AND mch_matches.GamCod=gam_games.GamCod"
|
||||
" AND gam_games.CrsCod=%ld", // Extra check
|
||||
MchSubQuery,
|
||||
Match->Status.QstInd,
|
||||
Match->Status.QstCod,
|
||||
Mch_ShowingStringsDB[Match->Status.Showing],
|
||||
Match->Status.Countdown,
|
||||
Match->Status.NumCols,
|
||||
Match->Status.ShowQstResults ? 'Y' :
|
||||
'N',
|
||||
Match->Status.ShowUsrResults ? 'Y' :
|
||||
'N',
|
||||
Match->MchCod,
|
||||
Gbl.Hierarchy.Crs.CrsCod);
|
||||
free (MchSubQuery);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********************* Update title of an existing match *********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Mch_DB_UpdateMatchTitle (const struct Mch_Match *Match)
|
||||
{
|
||||
DB_QueryUPDATE ("can not update match",
|
||||
"UPDATE mch_matches"
|
||||
" SET Title='%s'"
|
||||
" WHERE MchCod=%ld",
|
||||
Match->Title,
|
||||
Match->MchCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/****************** Get parameter with what is being shown *******************/
|
||||
/*****************************************************************************/
|
||||
|
||||
Mch_Showing_t Mch_DB_GetShowingFromStr (const char *Str)
|
||||
{
|
||||
Mch_Showing_t Showing;
|
||||
|
||||
for (Showing = (Mch_Showing_t) 0;
|
||||
Showing <= (Mch_Showing_t) (Mch_NUM_SHOWING - 1);
|
||||
Showing++)
|
||||
if (!strcmp (Str,Mch_ShowingStringsDB[Showing]))
|
||||
return Showing;
|
||||
|
||||
return (Mch_Showing_t) Mch_SHOWING_DEFAULT;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********************** Get number of matches in a game **********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
unsigned Mch_DB_GetNumMchsInGame (long GamCod)
|
||||
{
|
||||
/***** Trivial check *****/
|
||||
if (GamCod < 0) // A non-existing game...
|
||||
return 0; // ...has no matches
|
||||
|
||||
/***** Get number of matches in a game from database *****/
|
||||
return (unsigned)
|
||||
DB_QueryCOUNT ("can not get number of matches of a game",
|
||||
"SELECT COUNT(*)"
|
||||
" FROM mch_matches"
|
||||
" WHERE GamCod=%ld",
|
||||
GamCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*************** Get number of unfinished matches in a game ******************/
|
||||
/*****************************************************************************/
|
||||
|
||||
unsigned Mch_DB_GetNumUnfinishedMchsInGame (long GamCod)
|
||||
{
|
||||
/***** Trivial check *****/
|
||||
if (GamCod < 0) // A non-existing game...
|
||||
return 0; // ...has no matches
|
||||
|
||||
/***** Get number of matches in a game from database *****/
|
||||
return (unsigned)
|
||||
DB_QueryCOUNT ("can not get number of unfinished matches of a game",
|
||||
"SELECT COUNT(*)"
|
||||
" FROM mch_matches"
|
||||
" WHERE GamCod=%ld"
|
||||
" AND Showing<>'%s'",
|
||||
GamCod,
|
||||
Mch_ShowingStringsDB[Mch_END]);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************* Remove match from table ***************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Mch_DB_RemoveMatchFromTable (long MchCod,const char *TableName)
|
||||
{
|
||||
DB_QueryDELETE ("can not remove match from table",
|
||||
"DELETE FROM %s"
|
||||
" WHERE MchCod=%ld",
|
||||
TableName,
|
||||
MchCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/****************** Remove matches in game from main table *******************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Mch_DB_RemoveMatchesInGameFromMainTable (long GamCod)
|
||||
{
|
||||
DB_QueryDELETE ("can not remove matches of a game",
|
||||
"DELETE FROM mch_matches"
|
||||
" WHERE GamCod=%ld",
|
||||
GamCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************** Remove matches in game from secondary table ***************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Mch_DB_RemoveMatchesInGameFromOtherTable (long GamCod,const char *TableName)
|
||||
{
|
||||
DB_QueryDELETE ("can not remove matches of a game from table",
|
||||
"DELETE FROM %s"
|
||||
" USING mch_matches,"
|
||||
"%s"
|
||||
" WHERE mch_matches.GamCod=%ld"
|
||||
" AND mch_matches.MchCod=%s.MchCod",
|
||||
TableName,
|
||||
TableName,
|
||||
GamCod,
|
||||
TableName);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************** Remove matches in course from main table ******************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Mch_DB_RemoveMatchesInCrsFromMainTable (long CrsCod)
|
||||
{
|
||||
DB_QueryDELETE ("can not remove matches of a course",
|
||||
"DELETE FROM mch_matches"
|
||||
" USING gam_games,"
|
||||
"mch_matches"
|
||||
" WHERE gam_games.CrsCod=%ld"
|
||||
" AND gam_games.GamCod=mch_matches.GamCod",
|
||||
CrsCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*************** Remove matches in course from secondary table ***************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Mch_DB_RemoveMatchesInCrsFromOtherTable (long CrsCod,const char *TableName)
|
||||
{
|
||||
DB_QueryDELETE ("can not remove matches of a course from table",
|
||||
"DELETE FROM %s"
|
||||
" USING gam_games,"
|
||||
"mch_matches,"
|
||||
"%s"
|
||||
" WHERE gam_games.CrsCod=%ld"
|
||||
" AND gam_games.GamCod=mch_matches.GamCod"
|
||||
" AND mch_matches.MchCod=%s.MchCod",
|
||||
TableName,
|
||||
TableName,
|
||||
CrsCod,
|
||||
TableName);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/****************** Remove matches made by a user from table *****************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Mch_DB_RemoveMatchesMadeByUsrFromTable (long UsrCod,const char *TableName)
|
||||
{
|
||||
DB_QueryDELETE ("can not remove matches of a user from table",
|
||||
"DELETE FROM %s"
|
||||
" WHERE UsrCod=%ld",
|
||||
TableName,
|
||||
UsrCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******* Remove matches made by a user in a course from secondary table ******/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Mch_DB_RemoveMatchesMadeByUsrInCrsFromTable (long UsrCod,long CrsCod,
|
||||
const char *TableName)
|
||||
{
|
||||
DB_QueryDELETE ("can not remove matches of a user from table",
|
||||
"DELETE FROM %s"
|
||||
" USING gam_games,"
|
||||
"mch_matches,"
|
||||
"%s"
|
||||
" WHERE gam_games.CrsCod=%ld"
|
||||
" AND gam_games.GamCod=mch_matches.GamCod"
|
||||
" AND mch_matches.MchCod=%s.MchCod"
|
||||
" AND %s.UsrCod=%ld",
|
||||
TableName,
|
||||
TableName,
|
||||
CrsCod,
|
||||
TableName,
|
||||
TableName,
|
||||
UsrCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************** Create group associated to a match *********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Mch_DB_AssociateGroupToMatch (long MchCod,long GrpCod)
|
||||
{
|
||||
DB_QueryINSERT ("can not associate a group to a match",
|
||||
"INSERT INTO mch_groups"
|
||||
" (MchCod,GrpCod)"
|
||||
" VALUES"
|
||||
" (%ld,%ld)",
|
||||
MchCod,
|
||||
GrpCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********************* Remove one group from all matches *********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Mch_DB_RemoveGroup (long GrpCod)
|
||||
{
|
||||
DB_QueryDELETE ("can not remove group"
|
||||
" from the associations between matches and groups",
|
||||
"DELETE FROM mch_groups"
|
||||
" WHERE GrpCod=%ld",
|
||||
GrpCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************** Remove groups of one type from all matches ****************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Mch_DB_RemoveGroupsOfType (long GrpTypCod)
|
||||
{
|
||||
DB_QueryDELETE ("can not remove groups of a type"
|
||||
" from the associations between matches and groups",
|
||||
"DELETE FROM mch_groups"
|
||||
" USING grp_groups,"
|
||||
"mch_groups"
|
||||
" WHERE grp_groups.GrpTypCod=%ld"
|
||||
" AND grp_groups.GrpCod=mch_groups.GrpCod",
|
||||
GrpTypCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******** Remove answers of a question from all matches of this game *********/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Mch_DB_RemAnswersOfAQuestion (long GamCod,unsigned QstInd)
|
||||
{
|
||||
DB_QueryDELETE ("can not remove the answers of a question",
|
||||
"DELETE FROM mch_answers"
|
||||
" USING mch_matches,"
|
||||
"mch_answers"
|
||||
" WHERE mch_matches.GamCod=%ld" // From all matches of this game...
|
||||
" AND mch_matches.MchCod=mch_answers.MchCod"
|
||||
" AND mch_answers.QstInd=%u", // ...remove only answers to this question
|
||||
GamCod,
|
||||
QstInd);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********* Create entry for this question in table of match indexes **********/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Mch_DB_CreateQstIndexes (long MchCod,unsigned QstInd,
|
||||
const char StrAnswersOneQst[Tst_MAX_BYTES_ANSWERS_ONE_QST + 1])
|
||||
{
|
||||
DB_QueryINSERT ("can not create indexes of a question",
|
||||
"INSERT INTO mch_indexes"
|
||||
" (MchCod,QstInd,Indexes)"
|
||||
" VALUES"
|
||||
" (%ld,%u,'%s')",
|
||||
MchCod,
|
||||
QstInd,
|
||||
StrAnswersOneQst);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************** Get indexes for a question from database ******************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Mch_DB_GetIndexes (long MchCod,unsigned QstInd,
|
||||
char StrIndexesOneQst[Tst_MAX_BYTES_INDEXES_ONE_QST + 1])
|
||||
{
|
||||
DB_QuerySELECTString (StrIndexesOneQst,Tst_MAX_BYTES_INDEXES_ONE_QST,
|
||||
"can not get indexes of a question",
|
||||
"SELECT Indexes" // row[0]
|
||||
" FROM mch_indexes"
|
||||
" WHERE MchCod=%ld"
|
||||
" AND QstInd=%u",
|
||||
MchCod,
|
||||
QstInd);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********** Update elapsed time in current question (by a teacher) ***********/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Mch_DB_UpdateElapsedTimeInQuestion (long MchCod,long QstInd)
|
||||
{
|
||||
DB_QueryINSERT ("can not update elapsed time in question",
|
||||
"INSERT INTO mch_times"
|
||||
" (MchCod,QstInd,ElapsedTime)"
|
||||
" VALUES"
|
||||
" (%ld,%u,SEC_TO_TIME(%u))"
|
||||
" ON DUPLICATE KEY"
|
||||
" UPDATE ElapsedTime=ADDTIME(ElapsedTime,SEC_TO_TIME(%u))",
|
||||
MchCod,
|
||||
QstInd,
|
||||
Cfg_SECONDS_TO_REFRESH_MATCH_TCH,
|
||||
Cfg_SECONDS_TO_REFRESH_MATCH_TCH);
|
||||
}
|
||||
|
80
swad_match_database.h
Normal file
80
swad_match_database.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
// swad_match_database.h: matches in games using remote control, operations woth database
|
||||
|
||||
#ifndef _SWAD_MCH_DB
|
||||
#define _SWAD_MCH_DB
|
||||
/*
|
||||
SWAD (Shared Workspace At a Distance in Spanish),
|
||||
is a web platform developed at the University of Granada (Spain),
|
||||
and used to support university teaching.
|
||||
|
||||
This file is part of SWAD core.
|
||||
Copyright (C) 1999-2021 Antonio Cañas Vargas
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*****************************************************************************/
|
||||
/********************************* Headers ***********************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
// #include "swad_game.h"
|
||||
#include "swad_match.h"
|
||||
// #include "swad_match_print.h"
|
||||
// #include "swad_scope.h"
|
||||
// #include "swad_test.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************** Public types and constants ***********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************************** Public prototypes *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
//------------------------------- Matches -------------------------------------
|
||||
long Mch_DB_CreateMatch (long GamCod,char Title[Mch_MAX_BYTES_TITLE + 1]);
|
||||
void Mch_DB_UpdateMatchStatus (const struct Mch_Match *Match);
|
||||
void Mch_DB_UpdateMatchTitle (const struct Mch_Match *Match);
|
||||
|
||||
Mch_Showing_t Mch_DB_GetShowingFromStr (const char *Str);
|
||||
unsigned Mch_DB_GetNumMchsInGame (long GamCod);
|
||||
unsigned Mch_DB_GetNumUnfinishedMchsInGame (long GamCod);
|
||||
|
||||
void Mch_DB_RemoveMatchFromTable (long MchCod,const char *TableName);
|
||||
void Mch_DB_RemoveMatchesInGameFromMainTable (long GamCod);
|
||||
void Mch_DB_RemoveMatchesInGameFromOtherTable (long GamCod,const char *TableName);
|
||||
void Mch_DB_RemoveMatchesInCrsFromMainTable (long CrsCod);
|
||||
void Mch_DB_RemoveMatchesInCrsFromOtherTable (long CrsCod,const char *TableName);
|
||||
void Mch_DB_RemoveMatchesMadeByUsrFromTable (long UsrCod,const char *TableName);
|
||||
void Mch_DB_RemoveMatchesMadeByUsrInCrsFromTable (long UsrCod,long CrsCod,
|
||||
const char *TableName);
|
||||
|
||||
//---------------------------------Groups -------------------------------------
|
||||
void Mch_DB_AssociateGroupToMatch (long MchCod,long GrpCod);
|
||||
|
||||
void Mch_DB_RemoveGroup (long GrpCod);
|
||||
void Mch_DB_RemoveGroupsOfType (long GrpTypCod);
|
||||
|
||||
//-------------------------------- Answers ------------------------------------
|
||||
void Mch_DB_RemAnswersOfAQuestion (long GamCod,unsigned QstInd);
|
||||
|
||||
//----------------------------- Answers indexes -------------------------------
|
||||
void Mch_DB_CreateQstIndexes (long MchCod,unsigned QstInd,
|
||||
const char StrAnswersOneQst[Tst_MAX_BYTES_ANSWERS_ONE_QST + 1]);
|
||||
void Mch_DB_GetIndexes (long MchCod,unsigned QstInd,
|
||||
char StrIndexesOneQst[Tst_MAX_BYTES_INDEXES_ONE_QST + 1]);
|
||||
|
||||
//----------------------------- Elapsed times ---------------------------------
|
||||
void Mch_DB_UpdateElapsedTimeInQuestion (long MchCod,long QstInd);
|
||||
|
||||
#endif
|
18
swad_test.c
18
swad_test.c
|
@ -5891,3 +5891,21 @@ static unsigned Tst_GetNumCoursesWithPluggableTstQuestions (HieLvl_Level_t Scope
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*********** Get suffled/not-shuffled answers indexes of question ************/
|
||||
/*****************************************************************************/
|
||||
|
||||
unsigned Tst_DB_GetShuffledAnswersIndexes (MYSQL_RES **mysql_res,
|
||||
const struct Tst_Question *Question)
|
||||
{
|
||||
return (unsigned)
|
||||
DB_QuerySELECT (mysql_res,"can not get questions of a game",
|
||||
"SELECT AnsInd" // row[0]
|
||||
" FROM tst_answers"
|
||||
" WHERE QstCod=%ld"
|
||||
" ORDER BY %s",
|
||||
Question->QstCod,
|
||||
Question->Answer.Shuffle ? "RAND()" : // Use RAND() because is really random; RAND(NOW()) repeats order
|
||||
"AnsInd");
|
||||
}
|
||||
|
|
|
@ -187,4 +187,7 @@ void Tst_RemoveCrsTests (long CrsCod);
|
|||
|
||||
void Tst_GetTestStats (Tst_AnswerType_t AnsType,struct Tst_Stats *Stats);
|
||||
|
||||
unsigned Tst_DB_GetShuffledAnswersIndexes (MYSQL_RES **mysql_res,
|
||||
const struct Tst_Question *Question);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue
Block a user