// swad_info_database.c: info about course, operations with 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-2023 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 . */ /*****************************************************************************/ /********************************* Headers ***********************************/ /*****************************************************************************/ #include // For string functions #include "swad_database.h" #include "swad_global.h" /*****************************************************************************/ /************** External global variables from others modules ****************/ /*****************************************************************************/ extern struct Globals Gbl; /*****************************************************************************/ /***************************** Private constants *****************************/ /*****************************************************************************/ static const char *Inf_DB_NamesForInfoType[Inf_NUM_TYPES] = { [Inf_INTRODUCTION ] = "intro", // TODO: Change this to "introduction"! [Inf_TEACHING_GUIDE] = "description", // TODO: Change this to "guide"! [Inf_LECTURES ] = "theory", // TODO: Change this to "lectures"! [Inf_PRACTICALS ] = "practices", // TODO: Change this to "practicals"! [Inf_BIBLIOGRAPHY ] = "bibliography", [Inf_FAQ ] = "FAQ", [Inf_LINKS ] = "links", [Inf_ASSESSMENT ] = "assessment", }; static const char *Inf_DB_NamesForInfoSrc[Inf_NUM_SOURCES] = { [Inf_NONE ] = "none", [Inf_EDITOR ] = "editor", [Inf_PLAIN_TEXT] = "plain_text", [Inf_RICH_TEXT ] = "rich_text", [Inf_PAGE ] = "page", [Inf_URL ] = "URL", }; /*****************************************************************************/ /**************************** Private prototypes *****************************/ /*****************************************************************************/ /*****************************************************************************/ /*** Convert a string with info type in database to a Inf_InfoType_t value ***/ /*****************************************************************************/ Inf_Type_t Inf_DB_ConvertFromStrDBToInfoType (const char *StrInfoTypeDB) { Inf_Type_t InfoType; for (InfoType = (Inf_Type_t) 0; InfoType <= (Inf_Type_t) (Inf_NUM_TYPES - 1); InfoType++) if (!strcmp (StrInfoTypeDB,Inf_DB_NamesForInfoType[InfoType])) return InfoType; return (Inf_Type_t) 0; } /*****************************************************************************/ /********* Set info source for a type of course info from database ***********/ /*****************************************************************************/ void Inf_DB_SetInfoSrc (Inf_Src_t InfoSrc) { /***** Get if info source is already stored in database *****/ if (DB_QueryCOUNT ("can not get if info source is already stored in database", "SELECT COUNT(*)" " FROM crs_info_src" " WHERE CrsCod=%ld" " AND InfoType='%s'", Gbl.Hierarchy.Crs.CrsCod, Inf_DB_NamesForInfoType[Gbl.Crs.Info.Type])) // Info is already stored in database, so update it { // Update info source if (InfoSrc == Inf_NONE) DB_QueryUPDATE ("can not update info source", "UPDATE crs_info_src" " SET InfoSrc='%s'," "MustBeRead='N'" " WHERE CrsCod=%ld" " AND InfoType='%s'", Inf_DB_NamesForInfoSrc[Inf_NONE], Gbl.Hierarchy.Crs.CrsCod, Inf_DB_NamesForInfoType[Gbl.Crs.Info.Type]); else // MustBeRead remains unchanged DB_QueryUPDATE ("can not update info source", "UPDATE crs_info_src" " SET InfoSrc='%s'" " WHERE CrsCod=%ld" " AND InfoType='%s'", Inf_DB_NamesForInfoSrc[InfoSrc], Gbl.Hierarchy.Crs.CrsCod, Inf_DB_NamesForInfoType[Gbl.Crs.Info.Type]); } else // Info is not stored in database, so insert it DB_QueryINSERT ("can not insert info source", "INSERT INTO crs_info_src" " (CrsCod,InfoType,InfoSrc,MustBeRead)" " VALUES" " (%ld,'%s','%s','N')", Gbl.Hierarchy.Crs.CrsCod, Inf_DB_NamesForInfoType[Gbl.Crs.Info.Type], Inf_DB_NamesForInfoSrc[InfoSrc]); } /*****************************************************************************/ /***************** Get info source for a type of course info *****************/ /*****************************************************************************/ unsigned Inf_DB_GetInfoSrc (MYSQL_RES **mysql_res, long CrsCod,Inf_Type_t InfoType) { /***** Get info source for a specific type of info from database *****/ return (unsigned) DB_QuerySELECT (mysql_res,"can not get info source", "SELECT InfoSrc" // row[0] " FROM crs_info_src" " WHERE CrsCod=%ld" " AND InfoType='%s'", CrsCod, Inf_DB_NamesForInfoType[InfoType]); } /*****************************************************************************/ /*** Get info source and wether info must be read for a type of course info **/ /*****************************************************************************/ unsigned Inf_DB_GetInfoSrcAndMustBeRead (MYSQL_RES **mysql_res, long CrsCod,Inf_Type_t InfoType) { return (unsigned) DB_QuerySELECT (mysql_res,"can not get info source", "SELECT InfoSrc," // row[0] "MustBeRead" // row[1] " FROM crs_info_src" " WHERE CrsCod=%ld" " AND InfoType='%s'", CrsCod, Inf_DB_NamesForInfoType[InfoType]); } /*****************************************************************************/ /** Convert a string with info source in database to a Inf_InfoSrc_t value ***/ /*****************************************************************************/ Inf_Src_t Inf_DB_ConvertFromStrDBToInfoSrc (const char *StrInfoSrcDB) { Inf_Src_t InfoSrc; for (InfoSrc = (Inf_Src_t) 0; InfoSrc <= (Inf_Src_t) (Inf_NUM_SOURCES - 1); InfoSrc++) if (!strcmp (StrInfoSrcDB,Inf_DB_NamesForInfoSrc[InfoSrc])) return InfoSrc; return Inf_NONE; } /*****************************************************************************/ /********** Set info text for a type of course info from database ************/ /*****************************************************************************/ void Inf_DB_SetInfoTxt (const char *InfoTxtHTML,const char *InfoTxtMD) { /***** Insert or replace info source for a specific type of course information *****/ DB_QueryREPLACE ("can not update info text", "REPLACE INTO crs_info_txt" " (CrsCod,InfoType,InfoTxtHTML,InfoTxtMD)" " VALUES" " (%ld,'%s','%s','%s')", Gbl.Hierarchy.Crs.CrsCod, Inf_DB_NamesForInfoType[Gbl.Crs.Info.Type], InfoTxtHTML, InfoTxtMD); } /*****************************************************************************/ /********** Get info text for a type of course info from database ************/ /*****************************************************************************/ unsigned Inf_DB_GetInfoTxt (MYSQL_RES **mysql_res, long CrsCod,Inf_Type_t InfoType) { return (unsigned) DB_QuerySELECT (mysql_res,"can not get info text", "SELECT InfoTxtHTML," // row[0] "InfoTxtMD" // row[1] " FROM crs_info_txt" " WHERE CrsCod=%ld" " AND InfoType='%s'", CrsCod, Inf_DB_NamesForInfoType[InfoType]); } /*****************************************************************************/ /***************** Set if students must read course info *********************/ /*****************************************************************************/ void Inf_DB_SetForceRead (bool MustBeRead) { DB_QueryUPDATE ("can not update if info must be read", "UPDATE crs_info_src" " SET MustBeRead='%c'" " WHERE CrsCod=%ld" " AND InfoType='%s'", MustBeRead ? 'Y' : 'N', Gbl.Hierarchy.Crs.CrsCod, Inf_DB_NamesForInfoType[Gbl.Crs.Info.Type]); } /*****************************************************************************/ /********************* Set if I have read course info ************************/ /*****************************************************************************/ void Inf_DB_SetIHaveRead (bool IHaveRead) { if (IHaveRead) /***** Insert I have read course information *****/ DB_QueryREPLACE ("can not set that I have read course info", "REPLACE INTO crs_info_read" " (UsrCod,CrsCod,InfoType)" " VALUES" " (%ld,%ld,'%s')", Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.Hierarchy.Crs.CrsCod, Inf_DB_NamesForInfoType[Gbl.Crs.Info.Type]); else /***** Remove I have read course information *****/ DB_QueryDELETE ("can not set that I have not read course info", "DELETE FROM crs_info_read" " WHERE UsrCod=%ld" " AND CrsCod=%ld" " AND InfoType='%s'", Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.Hierarchy.Crs.CrsCod, Inf_DB_NamesForInfoType[Gbl.Crs.Info.Type]); } /*****************************************************************************/ /******************** Check I have read a course info ************************/ /*****************************************************************************/ bool Inf_DB_CheckIfIHaveReadInfo (void) { return DB_QueryEXISTS ("can not check if I have read course info", "SELECT EXISTS" "(SELECT *" " FROM crs_info_read" " WHERE UsrCod=%ld" " AND CrsCod=%ld" " AND InfoType='%s')", Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.Hierarchy.Crs.CrsCod, Inf_DB_NamesForInfoType[Gbl.Crs.Info.Type]); } /*****************************************************************************/ /******************* Get info types where I must read info *******************/ /*****************************************************************************/ unsigned Inf_DB_GetInfoTypesfIMustReadInfo (MYSQL_RES **mysql_res) { return (unsigned) DB_QuerySELECT (mysql_res,"can not get if you must read any course info", "SELECT InfoType" // row[0] " FROM crs_info_src" " WHERE CrsCod=%ld" " AND MustBeRead='Y'" " AND InfoType NOT IN" " (SELECT InfoType" " FROM crs_info_read" " WHERE UsrCod=%ld" " AND CrsCod=%ld)", Gbl.Hierarchy.Crs.CrsCod, Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.Hierarchy.Crs.CrsCod); } /*****************************************************************************/ /********* Remove user's status about reading of course information **********/ /*****************************************************************************/ void Inf_DB_RemoveUsrFromCrsInfoRead (long UsrCod,long CrsCod) { DB_QueryDELETE ("can not set that I have not read course info", "DELETE FROM crs_info_read" " WHERE UsrCod=%ld" " AND CrsCod=%ld", UsrCod,CrsCod); }