// swad_course_database.c: edition of courses 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-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 . */ /*****************************************************************************/ /********************************* Headers ***********************************/ /*****************************************************************************/ #define _GNU_SOURCE // For asprintf #include // For asprintf #include "swad_course.h" #include "swad_course_config.h" #include "swad_database.h" #include "swad_error.h" #include "swad_global.h" /*****************************************************************************/ /************** External global variables from others modules ****************/ /*****************************************************************************/ extern struct Globals Gbl; /*****************************************************************************/ /*************************** Public constants ********************************/ /*****************************************************************************/ /*****************************************************************************/ /***************************** Private types *********************************/ /*****************************************************************************/ /*****************************************************************************/ /**************************** Private variables ******************************/ /*****************************************************************************/ /*****************************************************************************/ /**************************** Private prototypes *****************************/ /*****************************************************************************/ /*****************************************************************************/ /************* Add a new requested course to pending requests ****************/ /*****************************************************************************/ void Crs_DB_CreateCourse (struct Crs_Course *Crs,unsigned Status) { /***** Insert new course into pending requests *****/ Crs->CrsCod = DB_QueryINSERTandReturnCode ("can not create a new course", "INSERT INTO crs_courses" " (DegCod,Year,InsCrsCod,Status,RequesterUsrCod," "ShortName,FullName)" " VALUES" " (%ld,%u,'%s',%u,%ld," "'%s','%s')", Crs->DegCod, Crs->Year, Crs->InstitutionalCrsCod, Status, Gbl.Usrs.Me.UsrDat.UsrCod, Crs->ShrtName, Crs->FullName); } /*****************************************************************************/ /******************* Get courses of a degree from database *******************/ /*****************************************************************************/ unsigned Crs_DB_GetCrssInDeg (MYSQL_RES **mysql_res,long DegCod) { return (unsigned) DB_QuerySELECT (mysql_res,"can not get courses of a degree", "SELECT CrsCod" " FROM crs_courses" " WHERE DegCod=%ld", DegCod); } /*****************************************************************************/ /******************** Get courses in current degree *********************/ /*****************************************************************************/ unsigned Crs_DB_GetCrssInCurrentDegBasic (MYSQL_RES **mysql_res) { return (unsigned) DB_QuerySELECT (mysql_res,"can not get courses of a degree", "SELECT CrsCod," // row[0] "ShortName" // row[1] " FROM crs_courses" " WHERE DegCod=%ld" " ORDER BY ShortName", Gbl.Hierarchy.Deg.DegCod); } /*****************************************************************************/ /******************** Get courses in current degree *********************/ /*****************************************************************************/ unsigned Crs_DB_GetCrssInCurrentDegFull (MYSQL_RES **mysql_res) { return (unsigned) DB_QuerySELECT (mysql_res,"can not get courses of a degree", "SELECT CrsCod," // row[0] "DegCod," // row[1] "Year," // row[2] "InsCrsCod," // row[3] "Status," // row[4] "RequesterUsrCod," // row[5] "ShortName," // row[6] "FullName" // row[7] " FROM crs_courses" " WHERE DegCod=%ld" " AND (Status & %u)=0" " ORDER BY Year," "ShortName", Gbl.Hierarchy.Deg.DegCod, (unsigned) Crs_STATUS_BIT_REMOVED); // All courses except those removed } /*****************************************************************************/ /********************* Get data of a course from its code ********************/ /*****************************************************************************/ unsigned Crs_DB_GetDataOfCourseByCod (MYSQL_RES **mysql_res,long CrsCod) { return (unsigned) DB_QuerySELECT (mysql_res,"can not get data of a course", "SELECT CrsCod," // row[0] "DegCod," // row[1] "Year," // row[2] "InsCrsCod," // row[3] "Status," // row[4] "RequesterUsrCod," // row[5] "ShortName," // row[6] "FullName" // row[7] " FROM crs_courses" " WHERE CrsCod=%ld", CrsCod); } /*****************************************************************************/ /******* Get the short names of degree and course from a course code *********/ /*****************************************************************************/ void Crs_DB_GetShortNamesByCod (long CrsCod, char CrsShortName[Cns_HIERARCHY_MAX_BYTES_SHRT_NAME + 1], char DegShortName[Cns_HIERARCHY_MAX_BYTES_SHRT_NAME + 1]) { MYSQL_RES *mysql_res; MYSQL_ROW row; DegShortName[0] = CrsShortName[0] = '\0'; /***** Trivial check: course code should be > 0 *****/ if (CrsCod <= 0) return; /***** Get the short name of a degree from database *****/ if (DB_QuerySELECT (&mysql_res,"can not get the short name of a course", "SELECT crs_courses.ShortName," // row[0] "deg_degrees.ShortName" // row[1] " FROM crs_courses," "deg_degrees" " WHERE crs_courses.CrsCod=%ld" " AND crs_courses.DegCod=deg_degrees.DegCod", CrsCod) == 1) { /***** Get the course short name and degree short name *****/ row = mysql_fetch_row (mysql_res); Str_Copy (CrsShortName,row[0],Cns_HIERARCHY_MAX_BYTES_SHRT_NAME); Str_Copy (DegShortName,row[1],Cns_HIERARCHY_MAX_BYTES_SHRT_NAME); } /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); } /*****************************************************************************/ /********** Check if the name of course exists in existing courses ***********/ /*****************************************************************************/ bool Crs_DB_CheckIfCrsNameExistsInYearOfDeg (const char *FieldName,const char *Name,long CrsCod, long DegCod,unsigned Year) { /***** Get number of courses in a year of a degree and with a name from database *****/ return (DB_QueryCOUNT ("can not check if the name" " of a course already existed", "SELECT COUNT(*)" " FROM crs_courses" " WHERE DegCod=%ld" " AND Year=%u" " AND %s='%s'" " AND CrsCod<>%ld", DegCod, Year, FieldName, Name, CrsCod) != 0); } /*****************************************************************************/ /************************** Write courses of a user **************************/ /*****************************************************************************/ unsigned Crs_DB_GetCrssOfAUsr (MYSQL_RES **mysql_res,long UsrCod,Rol_Role_t Role) { char *SubQuery; unsigned NumCrss; /***** Get courses of a user from database *****/ if (Role == Rol_UNK) // Role == Rol_UNK ==> any role { if (asprintf (&SubQuery,"%s","") < 0) Err_NotEnoughMemoryExit (); } else { if (asprintf (&SubQuery," AND crs_users.Role=%u",(unsigned) Role) < 0) Err_NotEnoughMemoryExit (); } NumCrss = (unsigned) DB_QuerySELECT (mysql_res,"can not get courses of a user", "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] " FROM crs_users," "crs_courses," "deg_degrees," "ctr_centers" " WHERE crs_users.UsrCod=%ld%s" " AND crs_users.CrsCod=crs_courses.CrsCod" " AND crs_courses.DegCod=deg_degrees.DegCod" " AND deg_degrees.CtrCod=ctr_centers.CtrCod" " ORDER BY deg_degrees.FullName," "crs_courses.Year," "crs_courses.FullName", UsrCod,SubQuery); /***** Free allocated memory for subquery *****/ free (SubQuery); return NumCrss; } /*****************************************************************************/ /************************** Get old courses from database ********************/ /*****************************************************************************/ unsigned Crs_DB_GetOldCrss (MYSQL_RES **mysql_res,unsigned long SecondsWithoutAccess) { return (unsigned) DB_QuerySELECT (mysql_res,"can not get old courses", "SELECT CrsCod" " FROM crs_last" " WHERE LastTime