mirror of https://github.com/acanas/swad-core.git
Version 21.54.3: Nov 08, 2021 Queries moved from API module to database modules.
This commit is contained in:
parent
d0f9a8bcfd
commit
0385edbf57
188
swad_API.c
188
swad_API.c
|
@ -119,6 +119,7 @@ cp -f /home/acanas/swad/swad/swad /var/www/cgi-bin/
|
|||
#include "swad_ID.h"
|
||||
#include "swad_mail_database.h"
|
||||
#include "swad_match.h"
|
||||
#include "swad_match_database.h"
|
||||
#include "swad_nickname_database.h"
|
||||
#include "swad_notice.h"
|
||||
#include "swad_notification.h"
|
||||
|
@ -130,6 +131,7 @@ cp -f /home/acanas/swad/swad/swad /var/www/cgi-bin/
|
|||
#include "swad_room_database.h"
|
||||
#include "swad_search.h"
|
||||
#include "swad_session_database.h"
|
||||
#include "swad_setting_database.h"
|
||||
#include "swad_test_config.h"
|
||||
#include "swad_test_visibility.h"
|
||||
#include "swad_user.h"
|
||||
|
@ -278,8 +280,8 @@ static int API_GetTstQuestionTags (struct soap *soap,
|
|||
long CrsCod,long BeginTime,
|
||||
struct swad__getTestsOutput *getTestsOut);
|
||||
|
||||
static void API_GetListGrpsInGameFromDB (struct soap *soap,
|
||||
long MchCod,char **ListGroups);
|
||||
static void API_GetListGrpsInMatchFromDB (struct soap *soap,
|
||||
long MchCod,char **ListGroups);
|
||||
|
||||
static void API_ListDir (unsigned Level,const char *Path,const char *PathInTree);
|
||||
static bool API_WriteRowFileBrowser (unsigned Level,Brw_FileType_t FileType,const char *FileName);
|
||||
|
@ -3235,36 +3237,36 @@ static int API_GetMyLanguage (struct soap *soap)
|
|||
MYSQL_RES *mysql_res;
|
||||
MYSQL_ROW row;
|
||||
Lan_Language_t Lan;
|
||||
bool UsrFound;
|
||||
|
||||
/***** Get user's language *****/
|
||||
if (DB_QuerySELECT (&mysql_res,"can not get user's language",
|
||||
"SELECT Language" // row[0]
|
||||
" FROM usr_data"
|
||||
" WHERE UsrCod=%ld",
|
||||
Gbl.Usrs.Me.UsrDat.UsrCod) != 1)
|
||||
return soap_receiver_fault (soap,
|
||||
"Can not get user's language from database",
|
||||
"User doen't exist in database");
|
||||
if ((UsrFound = Set_DB_GetMyLanguage (&mysql_res)))
|
||||
{
|
||||
/***** Get language from database *****/
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
|
||||
/***** Get language from database *****/
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
|
||||
/* Get language (row[0]) */
|
||||
Gbl.Prefs.Language = Lan_LANGUAGE_UNKNOWN;
|
||||
for (Lan = (Lan_Language_t) 1;
|
||||
Lan <= (Lan_Language_t) (Lan_NUM_LANGUAGES - 1);
|
||||
Lan++)
|
||||
if (!strcasecmp (row[0],Lan_STR_LANG_ID[Lan]))
|
||||
{
|
||||
Gbl.Prefs.Language = Lan;
|
||||
break;
|
||||
}
|
||||
if (Gbl.Prefs.Language == Lan_LANGUAGE_UNKNOWN) // Language stored in database is unknown
|
||||
Gbl.Prefs.Language = Cfg_DEFAULT_LANGUAGE;
|
||||
/* Get language (row[0]) */
|
||||
Gbl.Prefs.Language = Lan_LANGUAGE_UNKNOWN;
|
||||
for (Lan = (Lan_Language_t) 1;
|
||||
Lan <= (Lan_Language_t) (Lan_NUM_LANGUAGES - 1);
|
||||
Lan++)
|
||||
if (!strcasecmp (row[0],Lan_STR_LANG_ID[Lan]))
|
||||
{
|
||||
Gbl.Prefs.Language = Lan;
|
||||
break;
|
||||
}
|
||||
if (Gbl.Prefs.Language == Lan_LANGUAGE_UNKNOWN) // Language stored in database is unknown
|
||||
Gbl.Prefs.Language = Cfg_DEFAULT_LANGUAGE;
|
||||
}
|
||||
|
||||
/***** Free structure that stores the query result *****/
|
||||
DB_FreeMySQLResult (&mysql_res);
|
||||
|
||||
if (!UsrFound)
|
||||
return soap_receiver_fault (soap,
|
||||
"Can not get user's language from database",
|
||||
"User doen't exist in database");
|
||||
|
||||
return SOAP_OK;
|
||||
}
|
||||
|
||||
|
@ -4250,8 +4252,6 @@ static int API_GetTstQuestionTags (struct soap *soap,
|
|||
/***************** Return one test question for Trivial game *****************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#define API_MAX_BYTES_DEGREES_STR (1024 - 1)
|
||||
|
||||
int swad__getTrivialQuestion (struct soap *soap,
|
||||
char *wsKey,char *degrees,float lowerScore,float upperScore, // input
|
||||
struct swad__getTrivialQuestionOutput *getTrivialQuestionOut) // output
|
||||
|
@ -4267,8 +4267,8 @@ int swad__getTrivialQuestion (struct soap *soap,
|
|||
bool FirstDegree = true;
|
||||
MYSQL_RES *mysql_res;
|
||||
MYSQL_ROW row;
|
||||
unsigned NumRow;
|
||||
unsigned NumRows;
|
||||
unsigned NumAnss;
|
||||
unsigned NumAns;
|
||||
long QstCod = -1L;
|
||||
Qst_AnswerType_t AnswerType;
|
||||
unsigned Index;
|
||||
|
@ -4333,44 +4333,9 @@ int swad__getTrivialQuestion (struct soap *soap,
|
|||
"lowerScore or upperScore values not valid");
|
||||
|
||||
/***** Get test questions *****/
|
||||
Str_SetDecimalPointToUS (); // To print the floating point as a dot
|
||||
NumRows = (unsigned)
|
||||
DB_QuerySELECT (&mysql_res,"can not get test questions",
|
||||
"SELECT DISTINCT "
|
||||
"tst_questions.QstCod," // row[0]
|
||||
"tst_questions.AnsType," // row[1]
|
||||
"tst_questions.Shuffle," // row[2]
|
||||
"tst_questions.Stem," // row[3]
|
||||
"tst_questions.Feedback," // row[4]
|
||||
"tst_questions.Score/tst_questions.NumHits AS S" // row[5]
|
||||
" FROM crs_courses,"
|
||||
"tst_questions"
|
||||
" WHERE crs_courses.DegCod IN (%s)"
|
||||
" AND crs_courses.CrsCod=tst_questions.CrsCod"
|
||||
" AND tst_questions.AnsType='unique_choice'"
|
||||
" AND tst_questions.NumHits>0"
|
||||
" AND tst_questions.QstCod NOT IN"
|
||||
" (SELECT tst_question_tags.QstCod"
|
||||
" FROM crs_courses,"
|
||||
"tst_tags,"
|
||||
"tst_question_tags"
|
||||
" WHERE crs_courses.DegCod IN (%s)"
|
||||
" AND crs_courses.CrsCod=tst_tags.CrsCod"
|
||||
" AND tst_tags.TagHidden='Y'"
|
||||
" AND tst_tags.TagCod=tst_question_tags.TagCod)"
|
||||
" HAVING S>='%f'"
|
||||
" AND S<='%f'"
|
||||
" ORDER BY RAND()"
|
||||
" LIMIT 1",
|
||||
DegreesStr,
|
||||
DegreesStr,
|
||||
lowerScore,
|
||||
upperScore);
|
||||
Str_SetDecimalPointToLocal (); // Return to local system
|
||||
|
||||
if (NumRows == 1) // Question found
|
||||
if (Qst_DB_GetTrivialQst (&mysql_res,DegreesStr,lowerScore,upperScore)) // Question found
|
||||
{
|
||||
/* Get next question */
|
||||
/* Get question */
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
|
||||
/* Get question code (row[0]) */
|
||||
|
@ -4426,21 +4391,12 @@ int swad__getTrivialQuestion (struct soap *soap,
|
|||
if (QstCod > 0)
|
||||
{
|
||||
/***** Get answer from database *****/
|
||||
NumRows = (unsigned)
|
||||
DB_QuerySELECT (&mysql_res,"can not get test answers",
|
||||
"SELECT QstCod," // row[0]
|
||||
"AnsInd," // row[1]
|
||||
"Correct," // row[2]
|
||||
"Answer," // row[3]
|
||||
"Feedback" // row[4]
|
||||
" FROM tst_answers"
|
||||
" WHERE QstCod=%ld"
|
||||
" ORDER BY AnsInd",
|
||||
QstCod);
|
||||
NumAnss = Qst_DB_GetDataOfAnswers (&mysql_res,QstCod,
|
||||
false); // Don't shuffle
|
||||
|
||||
getTrivialQuestionOut->answersArray.__size = (int) NumRows;
|
||||
getTrivialQuestionOut->answersArray.__size = (int) NumAnss;
|
||||
|
||||
if (NumRows == 0)
|
||||
if (NumAnss == 0)
|
||||
getTrivialQuestionOut->answersArray.__ptr = NULL;
|
||||
else // Answers found
|
||||
{
|
||||
|
@ -4448,37 +4404,39 @@ int swad__getTrivialQuestion (struct soap *soap,
|
|||
(getTrivialQuestionOut->answersArray.__size) *
|
||||
sizeof (*(getTrivialQuestionOut->answersArray.__ptr)));
|
||||
|
||||
for (NumRow = 0;
|
||||
NumRow < NumRows;
|
||||
NumRow++)
|
||||
for (NumAns = 0;
|
||||
NumAns < NumAnss;
|
||||
NumAns++)
|
||||
{
|
||||
/* Get next question */
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
|
||||
/* Get question code (row[0]) */
|
||||
getTrivialQuestionOut->answersArray.__ptr[NumRow].questionCode = (int) Str_ConvertStrCodToLongCod (row[0]);
|
||||
/* Get question code */
|
||||
getTrivialQuestionOut->answersArray.__ptr[NumAns].questionCode = (int) QstCod;
|
||||
|
||||
/* Get answer index (row[1]) */
|
||||
if (sscanf (row[1],"%u",&Index) == 1)
|
||||
getTrivialQuestionOut->answersArray.__ptr[NumRow].answerIndex = (int) Index;
|
||||
/* Get answer index (row[0]) */
|
||||
if (sscanf (row[0],"%u",&Index) == 1)
|
||||
getTrivialQuestionOut->answersArray.__ptr[NumAns].answerIndex = (int) Index;
|
||||
else
|
||||
getTrivialQuestionOut->answersArray.__ptr[NumRow].answerIndex = 0; // error
|
||||
getTrivialQuestionOut->answersArray.__ptr[NumAns].answerIndex = 0; // error
|
||||
|
||||
/* Get correct (row[2]) */
|
||||
getTrivialQuestionOut->answersArray.__ptr[NumRow].correct = (row[2][0] == 'Y') ? 1 :
|
||||
0;
|
||||
|
||||
/* Get answer (row[3]) */
|
||||
getTrivialQuestionOut->answersArray.__ptr[NumRow].answerText =
|
||||
/* Get answer (row[1]) */
|
||||
getTrivialQuestionOut->answersArray.__ptr[NumAns].answerText =
|
||||
soap_malloc (soap,Cns_MAX_BYTES_TEXT + 1);
|
||||
Str_Copy (getTrivialQuestionOut->answersArray.__ptr[NumRow].answerText,
|
||||
Str_Copy (getTrivialQuestionOut->answersArray.__ptr[NumAns].answerText,
|
||||
row[3],Cns_MAX_BYTES_TEXT);
|
||||
|
||||
/* Get feedback (row[4]) */
|
||||
getTrivialQuestionOut->answersArray.__ptr[NumRow].answerFeedback =
|
||||
/* Get feedback (row[2]) */
|
||||
getTrivialQuestionOut->answersArray.__ptr[NumAns].answerFeedback =
|
||||
soap_malloc (soap,Cns_MAX_BYTES_TEXT + 1);
|
||||
Str_Copy (getTrivialQuestionOut->answersArray.__ptr[NumRow].answerFeedback,
|
||||
Str_Copy (getTrivialQuestionOut->answersArray.__ptr[NumAns].answerFeedback,
|
||||
row[4],Cns_MAX_BYTES_TEXT);
|
||||
|
||||
// Media code (row[3]) ignored here
|
||||
|
||||
/* Get correct (row[4]) */
|
||||
getTrivialQuestionOut->answersArray.__ptr[NumAns].correct = (row[4][0] == 'Y') ? 1 :
|
||||
0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4830,8 +4788,8 @@ int swad__getMatches (struct soap *soap,
|
|||
getMatchesOut->matchesArray.__ptr[NumMatch].questionIndex = (int) Str_ConvertStrToUnsigned (row[5]);
|
||||
|
||||
/* Get list of groups for this match */
|
||||
API_GetListGrpsInGameFromDB (soap,
|
||||
MchCod,&(getMatchesOut->matchesArray.__ptr[NumMatch].groups));
|
||||
API_GetListGrpsInMatchFromDB (soap,
|
||||
MchCod,&(getMatchesOut->matchesArray.__ptr[NumMatch].groups));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5057,8 +5015,8 @@ int swad__answerMatchQuestion (struct soap *soap,
|
|||
/*********************** Get lists of groups of a match **********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void API_GetListGrpsInGameFromDB (struct soap *soap,
|
||||
long MchCod,char **ListGroups)
|
||||
static void API_GetListGrpsInMatchFromDB (struct soap *soap,
|
||||
long MchCod,char **ListGroups)
|
||||
{
|
||||
MYSQL_RES *mysql_res;
|
||||
long NumGrps;
|
||||
|
@ -5068,17 +5026,9 @@ static void API_GetListGrpsInGameFromDB (struct soap *soap,
|
|||
size_t Length;
|
||||
|
||||
/***** Get list of groups *****/
|
||||
NumGrps = (unsigned)
|
||||
DB_QuerySELECT (&mysql_res,"can not get groups of a match",
|
||||
"SELECT GrpCod"
|
||||
" FROM mch_groups"
|
||||
" WHERE MchCod=%ld",
|
||||
MchCod);
|
||||
if (NumGrps == 0)
|
||||
*ListGroups = NULL;
|
||||
else // Groups found
|
||||
if ((NumGrps = Mch_DB_GetGrpCodsAssociatedToMatch (&mysql_res,MchCod))) // Groups found
|
||||
{
|
||||
Length = NumGrps * (10 + 1) - 1;
|
||||
Length = NumGrps * (Cns_MAX_DECIMAL_DIGITS_LONG + 1) - 1;
|
||||
*ListGroups = soap_malloc (soap,Length + 1);
|
||||
(*ListGroups)[0] = '\0';
|
||||
|
||||
|
@ -5094,6 +5044,8 @@ static void API_GetListGrpsInGameFromDB (struct soap *soap,
|
|||
Str_Concat (*ListGroups,GrpCodStr,Length);
|
||||
}
|
||||
}
|
||||
else
|
||||
*ListGroups = NULL;
|
||||
|
||||
/***** Free structure that stores the query result *****/
|
||||
DB_FreeMySQLResult (&mysql_res);
|
||||
|
@ -5775,17 +5727,7 @@ int swad__sendMyLocation (struct soap *soap,
|
|||
|
||||
/***** Check in (insert pair user-room) in the database *****/
|
||||
/* Get the code of the inserted item */
|
||||
ChkCod =
|
||||
DB_QueryINSERTandReturnCode ("can not save current location",
|
||||
"INSERT INTO roo_check_in"
|
||||
" (UsrCod,RooCod,CheckInTime)"
|
||||
" SELECT %ld,"
|
||||
"RooCod,"
|
||||
"NOW()"
|
||||
" FROM roo_rooms"
|
||||
" WHERE RooCod=%d", // Check that room exists
|
||||
Gbl.Usrs.Me.UsrDat.UsrCod,
|
||||
roomCode);
|
||||
ChkCod = Roo_DB_CheckIn (roomCode);
|
||||
|
||||
/***** Return notification code *****/
|
||||
sendMyLocationOut->success = (ChkCod > 0) ? 1 : 0;
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
|
||||
#define API_BYTES_KEY Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64
|
||||
|
||||
#define API_MAX_BYTES_DEGREES_STR (1024 - 1)
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************************* Public types ********************************/
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -2522,13 +2522,8 @@ static void Att_GetListSelectedAttCods (struct Att_Events *Events)
|
|||
else // No students attended to this event
|
||||
{
|
||||
/***** Get groups associated to an attendance event from database *****/
|
||||
NumGrpsInThisEvent = (unsigned)
|
||||
DB_QuerySELECT (&mysql_res,"can not get groups of an attendance event",
|
||||
"SELECT GrpCod" // row[0]
|
||||
" FROM att_groups"
|
||||
" WHERE att_groups.AttCod=%ld",
|
||||
Events->Lst[NumAttEvent].AttCod);
|
||||
if (NumGrpsInThisEvent) // This event is associated to groups
|
||||
if ((NumGrpsInThisEvent = Att_DB_GetGrpCodsAssociatedToEvent (&mysql_res,
|
||||
Events->Lst[NumAttEvent].AttCod))) // This event is associated to groups
|
||||
/* Get groups associated to this event */
|
||||
for (NumGrpInThisEvent = 0;
|
||||
NumGrpInThisEvent < NumGrpsInThisEvent &&
|
||||
|
|
|
@ -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.54.2 (2021-11-08)"
|
||||
#define Log_PLATFORM_VERSION "SWAD 21.54.3 (2021-11-08)"
|
||||
#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.54.3: Nov 08, 2021 Queries moved from API module to database modules. (322095 lines)
|
||||
Version 21.54.2: Nov 08, 2021 Queries moved to module swad_user_database and other modules. (322054 lines)
|
||||
Version 21.54.1: Nov 08, 2021 Queries moved to module swad_user_database. (322060 lines)
|
||||
Version 21.54: Nov 07, 2021 New module swad_API_database for database queries related to API. (322001 lines)
|
||||
|
|
|
@ -2522,14 +2522,14 @@ static void Crs_WriteRowCrsData (unsigned NumCrs,MYSQL_ROW row,bool WriteColumnA
|
|||
bool Accepted;
|
||||
static unsigned RowEvenOdd = 1;
|
||||
/*
|
||||
SELECT deg_degrees.DegCod row[0]
|
||||
crs_courses.CrsCod row[1]
|
||||
deg_degrees.ShortName row[2]
|
||||
deg_degrees.FullName row[3]
|
||||
crs_courses.Year row[4]
|
||||
crs_courses.FullName row[5]
|
||||
ctr_centers.ShortName row[6]
|
||||
crs_users.Accepted row[7] (only if WriteColumnAccepted == true)
|
||||
row[0]: deg_degrees.DegCod
|
||||
row[1]: crs_courses.CrsCod
|
||||
row[2]: deg_degrees.ShortName
|
||||
row[3]: deg_degrees.FullName
|
||||
row[4]: crs_courses.Year
|
||||
row[5]: crs_courses.FullName
|
||||
row[6]: ctr_centers.ShortName
|
||||
row[7]: crs_users.Accepted (only if WriteColumnAccepted == true)
|
||||
*/
|
||||
|
||||
/***** Get degree code (row[0]) *****/
|
||||
|
|
27
swad_match.c
27
swad_match.c
|
@ -127,8 +127,6 @@ static void Mch_ListOneOrMoreMatchesResultTch (struct Gam_Games *Games,
|
|||
static void Mch_GetMatchDataFromRow (MYSQL_RES *mysql_res,
|
||||
struct Mch_Match *Match);
|
||||
|
||||
static void Mch_RemoveMatchFromAllTables (long MchCod);
|
||||
|
||||
static void Mch_PutParamsPlay (void *MchCod);
|
||||
static void Mch_PutParamMchCod (long MchCod);
|
||||
|
||||
|
@ -680,7 +678,7 @@ static void Mch_GetAndWriteNamesOfGrpsAssociatedToMatch (const struct Mch_Match
|
|||
unsigned NumGrp;
|
||||
|
||||
/***** Get groups associated to a match from database *****/
|
||||
NumGrps = Mch_DB_GetGrpsAssociatedToMatch (&mysql_res,Match->MchCod);
|
||||
NumGrps = Mch_DB_GetGrpNamesAssociatedToMatch (&mysql_res,Match->MchCod);
|
||||
|
||||
HTM_DIV_Begin ("class=\"ASG_GRP\"");
|
||||
|
||||
|
@ -1030,7 +1028,7 @@ void Mch_RemoveMatch (void)
|
|||
Err_NoPermissionExit ();
|
||||
|
||||
/***** Remove the match from all database tables *****/
|
||||
Mch_RemoveMatchFromAllTables (Match.MchCod);
|
||||
Mch_DB_RemoveMatchFromAllTables (Match.MchCod);
|
||||
|
||||
/***** Write message *****/
|
||||
Ale_ShowAlert (Ale_SUCCESS,Txt_Match_X_removed,
|
||||
|
@ -1042,27 +1040,6 @@ void Mch_RemoveMatch (void)
|
|||
false); // Do not put form to start new match
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********************** Remove match from all tables *************************/
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
mysql> SELECT table_name FROM information_schema.tables WHERE table_name LIKE 'mch%';
|
||||
*/
|
||||
static void Mch_RemoveMatchFromAllTables (long MchCod)
|
||||
{
|
||||
/***** Remove match from secondary tables *****/
|
||||
Mch_DB_RemoveMatchFromTable (MchCod,"mch_players");
|
||||
Mch_DB_RemoveMatchFromTable (MchCod,"mch_playing");
|
||||
Mch_DB_RemoveMatchFromTable (MchCod,"mch_results");
|
||||
Mch_DB_RemoveMatchFromTable (MchCod,"mch_answers");
|
||||
Mch_DB_RemoveMatchFromTable (MchCod,"mch_times");
|
||||
Mch_DB_RemoveMatchFromTable (MchCod,"mch_groups");
|
||||
Mch_DB_RemoveMatchFromTable (MchCod,"mch_indexes");
|
||||
|
||||
/***** Remove match from main table *****/
|
||||
Mch_DB_RemoveMatchFromTable (MchCod,"mch_matches");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************** Remove match in game from all tables *******************/
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -336,6 +336,27 @@ unsigned Mch_DB_GetNumUnfinishedMchsInGame (long GamCod)
|
|||
Mch_ShowingStringsDB[Mch_END]);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********************** Remove match from all tables *************************/
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
mysql> SELECT table_name FROM information_schema.tables WHERE table_name LIKE 'mch%';
|
||||
*/
|
||||
void Mch_DB_RemoveMatchFromAllTables (long MchCod)
|
||||
{
|
||||
/***** Remove match from secondary tables *****/
|
||||
Mch_DB_RemoveMatchFromTable (MchCod,"mch_players");
|
||||
Mch_DB_RemoveMatchFromTable (MchCod,"mch_playing");
|
||||
Mch_DB_RemoveMatchFromTable (MchCod,"mch_results");
|
||||
Mch_DB_RemoveMatchFromTable (MchCod,"mch_answers");
|
||||
Mch_DB_RemoveMatchFromTable (MchCod,"mch_times");
|
||||
Mch_DB_RemoveMatchFromTable (MchCod,"mch_groups");
|
||||
Mch_DB_RemoveMatchFromTable (MchCod,"mch_indexes");
|
||||
|
||||
/***** Remove match from main table *****/
|
||||
Mch_DB_RemoveMatchFromTable (MchCod,"mch_matches");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************* Remove match from table ***************************/
|
||||
/*****************************************************************************/
|
||||
|
@ -470,7 +491,21 @@ void Mch_DB_AssociateGroupToMatch (long MchCod,long GrpCod)
|
|||
/************** Get groups associated to a match from database ***************/
|
||||
/*****************************************************************************/
|
||||
|
||||
unsigned Mch_DB_GetGrpsAssociatedToMatch (MYSQL_RES **mysql_res,long MchCod)
|
||||
unsigned Mch_DB_GetGrpCodsAssociatedToMatch (MYSQL_RES **mysql_res,long MchCod)
|
||||
{
|
||||
return (unsigned)
|
||||
DB_QuerySELECT (mysql_res,"can not get groups of a match",
|
||||
"SELECT GrpCod"
|
||||
" FROM mch_groups"
|
||||
" WHERE MchCod=%ld",
|
||||
MchCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************** Get groups associated to a match from database ***************/
|
||||
/*****************************************************************************/
|
||||
|
||||
unsigned Mch_DB_GetGrpNamesAssociatedToMatch (MYSQL_RES **mysql_res,long MchCod)
|
||||
{
|
||||
return (unsigned)
|
||||
DB_QuerySELECT (mysql_res,"can not get groups of a match",
|
||||
|
|
|
@ -51,6 +51,7 @@ Mch_Showing_t Mch_DB_GetShowingFromStr (const char *Str);
|
|||
unsigned Mch_DB_GetNumMchsInGame (long GamCod);
|
||||
unsigned Mch_DB_GetNumUnfinishedMchsInGame (long GamCod);
|
||||
|
||||
void Mch_DB_RemoveMatchFromAllTables (long MchCod);
|
||||
void Mch_DB_RemoveMatchFromTable (long MchCod,const char *TableName);
|
||||
void Mch_DB_RemoveMatchesInGameFromMainTable (long GamCod);
|
||||
void Mch_DB_RemoveMatchesInGameFromOtherTable (long GamCod,const char *TableName);
|
||||
|
@ -63,7 +64,8 @@ void Mch_DB_RemoveMatchesMadeByUsrInCrsFromTable (long UsrCod,long CrsCod,
|
|||
//---------------------------------Groups -------------------------------------
|
||||
void Mch_DB_AssociateGroupToMatch (long MchCod,long GrpCod);
|
||||
|
||||
unsigned Mch_DB_GetGrpsAssociatedToMatch (MYSQL_RES **mysql_res,long MchCod);
|
||||
unsigned Mch_DB_GetGrpCodsAssociatedToMatch (MYSQL_RES **mysql_res,long MchCod);
|
||||
unsigned Mch_DB_GetGrpNamesAssociatedToMatch (MYSQL_RES **mysql_res,long MchCod);
|
||||
bool Mch_DB_CheckIfICanPlayThisMatchBasedOnGrps (long MchCod);
|
||||
|
||||
void Mch_DB_RemoveGroup (long GrpCod);
|
||||
|
|
|
@ -518,6 +518,56 @@ unsigned Qst_DB_GetQstsForNewTestPrint (MYSQL_RES **mysql_res,
|
|||
Query);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************* Get one question for trivial game **********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
unsigned Qst_DB_GetTrivialQst (MYSQL_RES **mysql_res,
|
||||
char DegreesStr[API_MAX_BYTES_DEGREES_STR + 1],
|
||||
float lowerScore,float upperScore)
|
||||
{
|
||||
unsigned NumQsts;
|
||||
|
||||
Str_SetDecimalPointToUS (); // To print the floating point as a dot
|
||||
|
||||
NumQsts = (unsigned)
|
||||
DB_QuerySELECT (mysql_res,"can not get test questions",
|
||||
"SELECT DISTINCT "
|
||||
"tst_questions.QstCod," // row[0]
|
||||
"tst_questions.AnsType," // row[1]
|
||||
"tst_questions.Shuffle," // row[2]
|
||||
"tst_questions.Stem," // row[3]
|
||||
"tst_questions.Feedback," // row[4]
|
||||
"tst_questions.Score/tst_questions.NumHits AS S" // row[5]
|
||||
" FROM crs_courses,"
|
||||
"tst_questions"
|
||||
" WHERE crs_courses.DegCod IN (%s)"
|
||||
" AND crs_courses.CrsCod=tst_questions.CrsCod"
|
||||
" AND tst_questions.AnsType='unique_choice'"
|
||||
" AND tst_questions.NumHits>0"
|
||||
" AND tst_questions.QstCod NOT IN"
|
||||
" (SELECT tst_question_tags.QstCod"
|
||||
" FROM crs_courses,"
|
||||
"tst_tags,"
|
||||
"tst_question_tags"
|
||||
" WHERE crs_courses.DegCod IN (%s)"
|
||||
" AND crs_courses.CrsCod=tst_tags.CrsCod"
|
||||
" AND tst_tags.TagHidden='Y'"
|
||||
" AND tst_tags.TagCod=tst_question_tags.TagCod)"
|
||||
" HAVING S>='%f'"
|
||||
" AND S<='%f'"
|
||||
" ORDER BY RAND()"
|
||||
" LIMIT 1",
|
||||
DegreesStr,
|
||||
DegreesStr,
|
||||
lowerScore,
|
||||
upperScore);
|
||||
|
||||
Str_SetDecimalPointToLocal (); // Return to local system
|
||||
|
||||
return NumQsts;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*********************** Get number of test questions ************************/
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -54,6 +54,9 @@ unsigned Qst_DB_GetQsts (MYSQL_RES **mysql_res,
|
|||
const struct Qst_Questions *Questions);
|
||||
unsigned Qst_DB_GetQstsForNewTestPrint (MYSQL_RES **mysql_res,
|
||||
const struct Qst_Questions *Questions);
|
||||
unsigned Qst_DB_GetTrivialQst (MYSQL_RES **mysql_res,
|
||||
char DegreesStr[API_MAX_BYTES_DEGREES_STR + 1],
|
||||
float lowerScore,float upperScore);
|
||||
unsigned Qst_DB_GetNumQsts (MYSQL_RES **mysql_res,
|
||||
HieLvl_Level_t Scope,Qst_AnswerType_t AnsType);
|
||||
unsigned Qst_DB_GetNumCrssWithQsts (HieLvl_Level_t Scope,
|
||||
|
|
|
@ -332,43 +332,6 @@ unsigned Roo_DB_GetMACAddresses (MYSQL_RES **mysql_res,long RooCod)
|
|||
RooCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********************** Check if I can see user's location *******************/
|
||||
/*****************************************************************************/
|
||||
|
||||
bool Roo_DB_CheckIfICanSeeUsrLocation (long UsrCod)
|
||||
{
|
||||
/*
|
||||
I can only consult the location of another user
|
||||
if the intersection of the centers of our courses is not empty.
|
||||
The other user does not have to share any course with me,
|
||||
but at least some course of each one has to share center.
|
||||
*/
|
||||
return
|
||||
DB_QueryEXISTS ("can not check if you can see user location",
|
||||
"SELECT EXISTS"
|
||||
"(SELECT *"
|
||||
" FROM (SELECT DISTINCT "
|
||||
"deg_degrees.CtrCod"
|
||||
" FROM crs_users,"
|
||||
"crs_courses,"
|
||||
"deg_degrees"
|
||||
" WHERE crs_users.UsrCod=%ld"
|
||||
" AND crs_users.CrsCod=crs_courses.CrsCod"
|
||||
" AND crs_courses.DegCod=deg_degrees.DegCod) AS C1," // centers of my courses
|
||||
"(SELECT DISTINCT "
|
||||
"deg_degrees.CtrCod"
|
||||
" FROM crs_users,"
|
||||
"crs_courses,"
|
||||
"deg_degrees"
|
||||
" WHERE crs_users.UsrCod=%ld"
|
||||
" AND crs_users.CrsCod=crs_courses.CrsCod"
|
||||
" AND crs_courses.DegCod=deg_degrees.DegCod) AS C2" // centers of user's courses
|
||||
" WHERE C1.CtrCod=C2.CtrCod)",
|
||||
Gbl.Usrs.Me.UsrDat.UsrCod,
|
||||
UsrCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********************************* Remove room *******************************/
|
||||
/*****************************************************************************/
|
||||
|
@ -420,3 +383,62 @@ void Roo_DB_RemoveAllRoomsInCtr (long CtrCod)
|
|||
" WHERE CtrCod=%ld",
|
||||
CtrCod);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**** Check in (send user's current location by inserting pair user-room) ****/
|
||||
/*****************************************************************************/
|
||||
|
||||
long Roo_DB_CheckIn (long RooCod)
|
||||
{
|
||||
/***** Check in (insert pair user-room) in the database *****/
|
||||
/* Get the code of the inserted item */
|
||||
return
|
||||
DB_QueryINSERTandReturnCode ("can not save current location",
|
||||
"INSERT INTO roo_check_in"
|
||||
" (UsrCod,RooCod,CheckInTime)"
|
||||
" SELECT %ld,"
|
||||
"RooCod,"
|
||||
"NOW()"
|
||||
" FROM roo_rooms"
|
||||
" WHERE RooCod=%ld", // Check that room exists
|
||||
Gbl.Usrs.Me.UsrDat.UsrCod,
|
||||
RooCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********************** Check if I can see user's location *******************/
|
||||
/*****************************************************************************/
|
||||
|
||||
bool Roo_DB_CheckIfICanSeeUsrLocation (long UsrCod)
|
||||
{
|
||||
/*
|
||||
I can only consult the location of another user
|
||||
if the intersection of the centers of our courses is not empty.
|
||||
The other user does not have to share any course with me,
|
||||
but at least some course of each one has to share center.
|
||||
*/
|
||||
return
|
||||
DB_QueryEXISTS ("can not check if you can see user location",
|
||||
"SELECT EXISTS"
|
||||
"(SELECT *"
|
||||
" FROM (SELECT DISTINCT "
|
||||
"deg_degrees.CtrCod"
|
||||
" FROM crs_users,"
|
||||
"crs_courses,"
|
||||
"deg_degrees"
|
||||
" WHERE crs_users.UsrCod=%ld"
|
||||
" AND crs_users.CrsCod=crs_courses.CrsCod"
|
||||
" AND crs_courses.DegCod=deg_degrees.DegCod) AS C1," // centers of my courses
|
||||
"(SELECT DISTINCT "
|
||||
"deg_degrees.CtrCod"
|
||||
" FROM crs_users,"
|
||||
"crs_courses,"
|
||||
"deg_degrees"
|
||||
" WHERE crs_users.UsrCod=%ld"
|
||||
" AND crs_users.CrsCod=crs_courses.CrsCod"
|
||||
" AND crs_courses.DegCod=deg_degrees.DegCod) AS C2" // centers of user's courses
|
||||
" WHERE C1.CtrCod=C2.CtrCod)",
|
||||
Gbl.Usrs.Me.UsrDat.UsrCod,
|
||||
UsrCod);
|
||||
}
|
||||
|
|
|
@ -53,11 +53,15 @@ bool Roo_DB_CheckIfRoomNameExists (long CtrCod,long RooCod,
|
|||
const char *FieldName,const char *Name);
|
||||
unsigned Roo_DB_GetDataOfRoomByCod (MYSQL_RES **mysql_res,long RooCod);
|
||||
unsigned Roo_DB_GetMACAddresses (MYSQL_RES **mysql_res,long RooCod);
|
||||
bool Roo_DB_CheckIfICanSeeUsrLocation (long UsrCod);
|
||||
|
||||
void Roo_DB_RemoveRoom (long RooCod);
|
||||
void Roo_DB_RemoveMACAddress (long RooCod,unsigned long long MACnum);
|
||||
void Roo_DB_RemoveBuildingFromRooms (long BldCod);
|
||||
void Roo_DB_RemoveAllRoomsInCtr (long CtrCod);
|
||||
|
||||
//--------------------------------- Check in ----------------------------------
|
||||
long Roo_DB_CheckIn (long RooCod);
|
||||
|
||||
bool Roo_DB_CheckIfICanSeeUsrLocation (long UsrCod);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -356,19 +356,10 @@ static void Set_GetMyUsrListTypeFromDB (void)
|
|||
extern const char *Set_DB_StringsUsrListTypes[Set_NUM_USR_LIST_TYPES];
|
||||
MYSQL_RES *mysql_res;
|
||||
MYSQL_ROW row;
|
||||
unsigned NumRows;
|
||||
Set_ShowUsrsType_t ListType;
|
||||
|
||||
/***** Get type of listing of users from database *****/
|
||||
NumRows = (unsigned)
|
||||
DB_QuerySELECT (&mysql_res,"can not get type of listing of users",
|
||||
"SELECT UsrListType" // row[0]
|
||||
" FROM crs_user_settings"
|
||||
" WHERE UsrCod=%ld"
|
||||
" AND CrsCod=%ld",
|
||||
Gbl.Usrs.Me.UsrDat.UsrCod,
|
||||
Gbl.Hierarchy.Crs.CrsCod);
|
||||
if (NumRows == 1) // Should be one only row
|
||||
if (Set_DB_GetMyUsrListType (&mysql_res)) // Should be one only row
|
||||
{
|
||||
/* Get type of users' listing used to select some of them */
|
||||
Gbl.Usrs.Me.ListType = Set_SHOW_USRS_TYPE_DEFAULT;
|
||||
|
@ -383,13 +374,10 @@ static void Set_GetMyUsrListTypeFromDB (void)
|
|||
break;
|
||||
}
|
||||
}
|
||||
else if (NumRows == 0) // If I am an administrator or superuser
|
||||
// and I don't belong to current course,
|
||||
// then the result will be the default
|
||||
else // If I am an administrator or superuser
|
||||
// and I don't belong to current course,
|
||||
// then the result will be the default
|
||||
Gbl.Usrs.Me.ListType = Set_SHOW_USRS_TYPE_DEFAULT;
|
||||
else // Error in database:
|
||||
// more than one row for a user in course
|
||||
Err_ShowErrorAndExit ("Error when getting type of listing of users.");
|
||||
|
||||
/***** Free structure that stores the query result *****/
|
||||
DB_FreeMySQLResult (&mysql_res);
|
||||
|
@ -421,7 +409,6 @@ void Set_GetMyColsClassPhotoFromDB (void)
|
|||
{
|
||||
MYSQL_RES *mysql_res;
|
||||
MYSQL_ROW row;
|
||||
unsigned NumRows;
|
||||
|
||||
Gbl.Usrs.ClassPhoto.Cols = Usr_CLASS_PHOTO_COLS_DEF;
|
||||
|
||||
|
@ -430,15 +417,7 @@ void Set_GetMyColsClassPhotoFromDB (void)
|
|||
Gbl.Hierarchy.Level == HieLvl_CRS) // Course selected
|
||||
{
|
||||
/***** Get number of columns in class photo from database *****/
|
||||
NumRows = (unsigned)
|
||||
DB_QuerySELECT (&mysql_res,"can not get number of columns in class photo",
|
||||
"SELECT ColsClassPhoto" // row[0]
|
||||
" FROM crs_user_settings"
|
||||
" WHERE UsrCod=%ld"
|
||||
" AND CrsCod=%ld",
|
||||
Gbl.Usrs.Me.UsrDat.UsrCod,
|
||||
Gbl.Hierarchy.Crs.CrsCod);
|
||||
if (NumRows == 1) // Should be one only row
|
||||
if (Set_DB_GetMyColsClassPhoto (&mysql_res))
|
||||
{
|
||||
/* Get number of columns in class photo */
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
|
@ -448,10 +427,6 @@ void Set_GetMyColsClassPhotoFromDB (void)
|
|||
Gbl.Usrs.ClassPhoto.Cols > Usr_CLASS_PHOTO_COLS_MAX)
|
||||
Gbl.Usrs.ClassPhoto.Cols = Usr_CLASS_PHOTO_COLS_DEF;
|
||||
}
|
||||
else if (NumRows > 1) // Error in database:
|
||||
// more than one row for a user in course
|
||||
Err_ShowErrorAndExit ("Error when getting number of columns"
|
||||
" in class photo.");
|
||||
|
||||
/***** Free structure that stores the query result *****/
|
||||
DB_FreeMySQLResult (&mysql_res);
|
||||
|
@ -534,7 +509,6 @@ void Set_GetMyPrefAboutListWithPhotosFromDB (void)
|
|||
{
|
||||
MYSQL_RES *mysql_res;
|
||||
MYSQL_ROW row;
|
||||
unsigned NumRows;
|
||||
|
||||
Gbl.Usrs.Listing.WithPhotos = Usr_LIST_WITH_PHOTOS_DEF;
|
||||
|
||||
|
@ -542,26 +516,13 @@ void Set_GetMyPrefAboutListWithPhotosFromDB (void)
|
|||
if (Gbl.Usrs.Me.Logged && Gbl.Hierarchy.Crs.CrsCod)
|
||||
{
|
||||
/***** Get if listing of users must show photos from database *****/
|
||||
NumRows = (unsigned)
|
||||
DB_QuerySELECT (&mysql_res,"can not check if listing of users"
|
||||
" must show photos",
|
||||
"SELECT ListWithPhotos" // row[0]
|
||||
" FROM crs_user_settings"
|
||||
" WHERE UsrCod=%ld"
|
||||
" AND CrsCod=%ld",
|
||||
Gbl.Usrs.Me.UsrDat.UsrCod,
|
||||
Gbl.Hierarchy.Crs.CrsCod);
|
||||
if (NumRows == 1) // Should be one only row
|
||||
if (Set_DB_GetMyPrefAboutListWithPhotosPhoto (&mysql_res))
|
||||
{
|
||||
/* Get number of columns in class photo */
|
||||
Gbl.Usrs.Listing.WithPhotos = Usr_LIST_WITH_PHOTOS_DEF;
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
Gbl.Usrs.Listing.WithPhotos = (row[0][0] == 'Y');
|
||||
}
|
||||
else if (NumRows > 1) // Error in database:
|
||||
// more than one row for a user in course
|
||||
Err_ShowErrorAndExit ("Error when checking if listing of users"
|
||||
" must show photos.");
|
||||
|
||||
/***** Free structure that stores the query result *****/
|
||||
DB_FreeMySQLResult (&mysql_res);
|
||||
|
|
|
@ -211,6 +211,20 @@ void Set_DB_UpdateMySettingsAboutNotifyEvents (void)
|
|||
Gbl.Usrs.Me.UsrDat.UsrCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********************* Get my language from database *************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
unsigned Set_DB_GetMyLanguage (MYSQL_RES **mysql_res)
|
||||
{
|
||||
return (unsigned)
|
||||
DB_QuerySELECT (mysql_res,"can not get user's language",
|
||||
"SELECT Language" // row[0]
|
||||
" FROM usr_data"
|
||||
" WHERE UsrCod=%ld",
|
||||
Gbl.Usrs.Me.UsrDat.UsrCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************ Register last prefs in current course in database **************/
|
||||
/*****************************************************************************/
|
||||
|
@ -308,6 +322,55 @@ void Set_DB_UpdateMyPrefAboutListWithPhotosPhoto (void)
|
|||
Gbl.Hierarchy.Crs.CrsCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*************** Get my type of listing of users from database ***************/
|
||||
/*****************************************************************************/
|
||||
|
||||
unsigned Set_DB_GetMyUsrListType (MYSQL_RES **mysql_res)
|
||||
{
|
||||
return (unsigned)
|
||||
DB_QuerySELECT (mysql_res,"can not get type of listing of users",
|
||||
"SELECT UsrListType" // row[0]
|
||||
" FROM crs_user_settings"
|
||||
" WHERE UsrCod=%ld"
|
||||
" AND CrsCod=%ld",
|
||||
Gbl.Usrs.Me.UsrDat.UsrCod,
|
||||
Gbl.Hierarchy.Crs.CrsCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*********** Get my number of columns in class photo from database ***********/
|
||||
/*****************************************************************************/
|
||||
|
||||
unsigned Set_DB_GetMyColsClassPhoto (MYSQL_RES **mysql_res)
|
||||
{
|
||||
return (unsigned)
|
||||
DB_QuerySELECT (mysql_res,"can not get number of columns in class photo",
|
||||
"SELECT ColsClassPhoto" // row[0]
|
||||
" FROM crs_user_settings"
|
||||
" WHERE UsrCod=%ld"
|
||||
" AND CrsCod=%ld",
|
||||
Gbl.Usrs.Me.UsrDat.UsrCod,
|
||||
Gbl.Hierarchy.Crs.CrsCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********* Get my preference about listing with photos from database *********/
|
||||
/*****************************************************************************/
|
||||
|
||||
unsigned Set_DB_GetMyPrefAboutListWithPhotosPhoto (MYSQL_RES **mysql_res)
|
||||
{
|
||||
return (unsigned)
|
||||
DB_QuerySELECT (mysql_res,"can not check if listing of users"
|
||||
" should show photos",
|
||||
"SELECT ListWithPhotos" // row[0]
|
||||
" FROM crs_user_settings"
|
||||
" WHERE UsrCod=%ld"
|
||||
" AND CrsCod=%ld",
|
||||
Gbl.Usrs.Me.UsrDat.UsrCod,
|
||||
Gbl.Hierarchy.Crs.CrsCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/****************** Remove a user from a courses setting *********************/
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -52,6 +52,8 @@ void Set_DB_UpdateMySettingsAboutBasicProfile (void);
|
|||
void Set_DB_UpdateMySettingsAboutExtendedProfile (void);
|
||||
void Set_DB_UpdateMySettingsAboutNotifyEvents (void);
|
||||
|
||||
unsigned Set_DB_GetMyLanguage (MYSQL_RES **mysql_res);
|
||||
|
||||
//-------------------- User settings in the current course --------------------
|
||||
void Set_DB_InsertUsrInCrsSettings (long UsrCod,long CrsCod);
|
||||
|
||||
|
@ -60,6 +62,10 @@ void Set_DB_UpdateMyUsrListType (void);
|
|||
void Set_DB_UpdateMyColsClassPhoto (void);
|
||||
void Set_DB_UpdateMyPrefAboutListWithPhotosPhoto (void);
|
||||
|
||||
unsigned Set_DB_GetMyUsrListType (MYSQL_RES **mysql_res);
|
||||
unsigned Set_DB_GetMyColsClassPhoto (MYSQL_RES **mysql_res);
|
||||
unsigned Set_DB_GetMyPrefAboutListWithPhotosPhoto (MYSQL_RES **mysql_res);
|
||||
|
||||
void Set_DB_RemUsrFromCrsSettings (long UsrCod,long CrsCod);
|
||||
void Set_DB_RemUsrFromAllCrssSettings (long UsrCod);
|
||||
void Set_DB_RemAllUsrsFromCrsSettings (long CrsCod);
|
||||
|
|
Loading…
Reference in New Issue