diff --git a/Makefile b/Makefile index c0312172..0fff1c0c 100644 --- a/Makefile +++ b/Makefile @@ -49,7 +49,7 @@ OBJS = swad_account.o swad_account_database.o swad_action.o swad_admin.o \ swad_figure.o swad_figure_cache.o swad_file.o swad_file_browser.o \ swad_file_extension.o swad_file_MIME.o swad_firewall.o swad_follow.o \ swad_follow_database.o swad_form.o swad_forum.o \ - swad_game.o swad_global.o swad_group.o \ + swad_game.o swad_global.o swad_group.o swad_group_database.o \ swad_help.o swad_hierarchy.o swad_hierarchy_config.o swad_holiday.o \ swad_HTML.o \ swad_icon.o swad_ID.o swad_indicator.o swad_info.o swad_institution.o \ diff --git a/swad_API.c b/swad_API.c index 42a73db8..1ff9b390 100644 --- a/swad_API.c +++ b/swad_API.c @@ -109,6 +109,7 @@ cp -f /home/acanas/swad/swad/swad /var/www/cgi-bin/ #include "swad_file_browser.h" #include "swad_forum.h" #include "swad_global.h" +#include "swad_group_database.h" #include "swad_hierarchy.h" #include "swad_hierarchy_level.h" #include "swad_ID.h" diff --git a/swad_assignment.c b/swad_assignment.c index 922c9959..7dc04c7b 100644 --- a/swad_assignment.c +++ b/swad_assignment.c @@ -41,6 +41,7 @@ #include "swad_form.h" #include "swad_global.h" #include "swad_group.h" +#include "swad_group_database.h" #include "swad_HTML.h" #include "swad_notification.h" #include "swad_pagination.h" diff --git a/swad_attendance.c b/swad_attendance.c index d7c7de05..5c76c6d4 100644 --- a/swad_attendance.c +++ b/swad_attendance.c @@ -41,6 +41,7 @@ #include "swad_form.h" #include "swad_global.h" #include "swad_group.h" +#include "swad_group_database.h" #include "swad_hierarchy_level.h" #include "swad_HTML.h" #include "swad_ID.h" diff --git a/swad_changelog.h b/swad_changelog.h index 87ef1a2a..c351d6dc 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -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 20.93 (2021-06-17)" +#define Log_PLATFORM_VERSION "SWAD 20.94 (2021-06-17)" #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 20.94: Jun 17, 2021 New module swad_group_database for database queries related to groups. (313489 lines) Version 20.93: Jun 17, 2021 Code refactoring. (313382 lines) Version 20.92: Jun 11, 2021 New modules swad_admin and swad_admin_database for administrators. (313381 lines) Version 20.91.3: Jun 11, 2021 Queries moved to module swad_enrolment_database. (313173 lines) diff --git a/swad_exam_session.c b/swad_exam_session.c index afea27cd..ee890814 100644 --- a/swad_exam_session.c +++ b/swad_exam_session.c @@ -43,6 +43,7 @@ #include "swad_exam_type.h" #include "swad_form.h" #include "swad_global.h" +#include "swad_group_database.h" #include "swad_HTML.h" #include "swad_role.h" #include "swad_setting.h" diff --git a/swad_file_browser.c b/swad_file_browser.c index 32635a6f..84ef977a 100644 --- a/swad_file_browser.c +++ b/swad_file_browser.c @@ -48,6 +48,7 @@ #include "swad_file_MIME.h" #include "swad_form.h" #include "swad_global.h" +#include "swad_group_database.h" #include "swad_hierarchy.h" #include "swad_hierarchy_level.h" #include "swad_HTML.h" @@ -11724,7 +11725,7 @@ void Brw_RemoveZonesOfGroupsOfType (long GrpTypCod) long GrpCod; /***** Query database *****/ - NumGrps = Grp_DB_GetGrpsOfType (GrpTypCod,&mysql_res); + NumGrps = Grp_DB_GetGrpsOfType (&mysql_res,GrpTypCod); for (NumGrp = 0; NumGrp < NumGrps; NumGrp++) diff --git a/swad_group.c b/swad_group.c index 50a4d877..71d4e323 100644 --- a/swad_group.c +++ b/swad_group.c @@ -42,6 +42,7 @@ #include "swad_game.h" #include "swad_global.h" #include "swad_group.h" +#include "swad_group_database.h" #include "swad_HTML.h" #include "swad_match.h" #include "swad_notification.h" @@ -107,9 +108,6 @@ static void Grp_PutIconToCreateNewGroup (void); static void Grp_PutCheckboxAllGrps (Grp_WhichGroups_t GroupsSelectableByStdsOrNETs); -static void Grp_DB_LockTables (void); -static void Grp_DB_UnlockTables (void); - static void Grp_ConstructorListGrpAlreadySelec (struct ListGrpsAlreadySelec **AlreadyExistsGroupOfType); static void Grp_DestructorListGrpAlreadySelec (struct ListGrpsAlreadySelec **AlreadyExistsGroupOfType); static void Grp_RemoveUsrFromGroup (long UsrCod,long GrpCod); @@ -123,8 +121,7 @@ static void Grp_WriteHeadingGroupTypes (void); static void Grp_ListGroupsForEdition (const struct Roo_Rooms *Rooms); static void Grp_WriteHeadingGroups (void); -static bool Grp_DB_CheckIfAssociatedToGrp (const char *Table,const char *Field, - long Cod,long GrpCod); + static void Grp_PutIconToEditGroups (__attribute__((unused)) void *Args); static void Grp_ShowWarningToStdsToChangeGrps (void); @@ -137,7 +134,6 @@ static void Grp_WriteGrpHead (struct GroupType *GrpTyp); static void Grp_WriteRowGrp (struct Group *Grp,bool Highlight); static void Grp_PutFormToCreateGroupType (void); static void Grp_PutFormToCreateGroup (const struct Roo_Rooms *Rooms); -static unsigned Grp_DB_CountNumGrpsInThisCrsOfType (long GrpTypCod); static void Grp_GetDataOfGroupTypeByCod (struct GroupType *GrpTyp); static bool Grp_GetMultipleEnrolmentOfAGroupType (long GrpTypCod); static long Grp_DB_GetTypeOfGroupOfAGroup (long GrpCod); @@ -972,35 +968,6 @@ void Grp_ChangeGrpsOtherUsrAtomically (struct ListCodGrps *LstGrpsUsrWants) Grp_FreeListGrpTypesAndGrps (); } -/*****************************************************************************/ -/*********** Lock tables to make the registration in groups atomic ***********/ -/*****************************************************************************/ - -static void Grp_DB_LockTables (void) - { - DB_Query ("can not lock tables to change user's groups", - "LOCK TABLES " - "grp_types WRITE," - "grp_groups WRITE," - "grp_users WRITE," - "crs_users READ," - "crs_user_settings READ," - "roo_rooms READ"); - Gbl.DB.LockedTables = true; - } - -/*****************************************************************************/ -/*********** Unlock tables after changes in registration in groups ***********/ -/*****************************************************************************/ - -static void Grp_DB_UnlockTables (void) - { - Gbl.DB.LockedTables = false; // Set to false before the following unlock... - // ...to not retry the unlock if error in unlocking - DB_Query ("can not unlock tables after changing user's groups", - "UNLOCK TABLES"); - } - /*****************************************************************************/ /******* Check if not selected more than a group of single enrolment *********/ /*****************************************************************************/ @@ -1767,47 +1734,6 @@ void Grp_ListGrpsToEditAsgAttSvyEvtMch (struct GroupType *GrpTyp, Grp_FreeListCodGrp (&LstGrpsIBelong); } -/*****************************************************************************/ -/************ Check if an assignment is associated to a group ****************/ -/*****************************************************************************/ - -static bool Grp_DB_CheckIfAssociatedToGrp (const char *Table,const char *Field, - long Cod,long GrpCod) - { - /***** Get if an assignment, attendance event, survey, exam event or match - is associated to a given group from database *****/ - return (DB_QueryCOUNT ("can not check if associated to a group", - "SELECT COUNT(*)" - " FROM %s" - " WHERE %s=%ld" - " AND GrpCod=%ld", - Table, - Field,Cod, - GrpCod) != 0); - } - - -/*****************************************************************************/ -/*** Check if an assignment, attendance event, survey, exam event or match ***/ -/*** is associated to any group ***/ -/*****************************************************************************/ - -bool Grp_DB_CheckIfAssociatedToGrps (const char *Table,const char *Field,long Cod) - { - /***** Trivial check *****/ - if (Cod <= 0) // Assignment, attendance event, survey, exam event or match code - return false; - - /***** Get if an assignment, attendance event, survey, exam event or match - is associated to any group from database *****/ - return (DB_QueryCOUNT ("can not check if associated to groups", - "SELECT COUNT(*)" - " FROM %s" - " WHERE %s=%ld", - Table, - Field,Cod) != 0); - } - /*****************************************************************************/ /***************** Show list of groups to register/remove me *****************/ /*****************************************************************************/ @@ -2955,7 +2881,7 @@ void Grp_GetListGrpTypesAndGrpsInThisCrs (Grp_WhichGroupTypes_t WhichGroupTypes) if (GrpTyp->NumGrps) // If there are groups of this type... { /***** Query database *****/ - GrpTyp->NumGrps = Grp_DB_GetGrpsOfType (GrpTyp->GrpTypCod,&mysql_res); + GrpTyp->NumGrps = Grp_DB_GetGrpsOfType (&mysql_res,GrpTyp->GrpTypCod); if (GrpTyp->NumGrps > 0) // Groups found... { /***** Create list with groups of this type *****/ @@ -3047,63 +2973,6 @@ void Grp_FreeListGrpTypesAndGrps (void) } } -/*****************************************************************************/ -/*********** Query the number of groups that hay in this course **************/ -/*****************************************************************************/ - -unsigned Grp_DB_CountNumGrpsInCurrentCrs (void) - { - /***** Get number of group in current course from database *****/ - return (unsigned) - DB_QueryCOUNT ("can not get number of groups in this course", - "SELECT COUNT(*)" - " FROM grp_types," - "grp_groups" - " WHERE grp_types.CrsCod=%ld" - " AND grp_types.GrpTypCod=grp_groups.GrpTypCod", - Gbl.Hierarchy.Crs.CrsCod); - } - -/*****************************************************************************/ -/****************** Count number of groups in a group type *******************/ -/*****************************************************************************/ - -static unsigned Grp_DB_CountNumGrpsInThisCrsOfType (long GrpTypCod) - { - /***** Get number of groups of a type from database *****/ - return (unsigned) - DB_QueryCOUNT ("can not get number of groups of a type", - "SELECT COUNT(*)" - " FROM grp_groups" - " WHERE GrpTypCod=%ld", - GrpTypCod); - } - -/*****************************************************************************/ -/******************** Get groups of a type in this course ********************/ -/*****************************************************************************/ - -unsigned Grp_DB_GetGrpsOfType (long GrpTypCod,MYSQL_RES **mysql_res) - { - /***** Get groups of a type from database *****/ - // Don't use INNER JOIN because there are groups without assigned room - return (unsigned) - DB_QuerySELECT (mysql_res,"can not get groups of a type", - "SELECT grp_groups.GrpCod," // row[0] - "grp_groups.GrpName," // row[1] - "grp_groups.RooCod," // row[2] - "roo_rooms.ShortName," // row[3] - "grp_groups.MaxStudents," // row[4] - "grp_groups.Open," // row[5] - "grp_groups.FileZones" // row[6] - " FROM grp_groups" - " LEFT JOIN roo_rooms" - " ON grp_groups.RooCod=roo_rooms.RooCod" - " WHERE grp_groups.GrpTypCod=%ld" - " ORDER BY grp_groups.GrpName", - GrpTypCod); - } - /*****************************************************************************/ /******************* Get data of a group type from its code ******************/ /*****************************************************************************/ diff --git a/swad_group.h b/swad_group.h index 5e502648..f96d5a2f 100644 --- a/swad_group.h +++ b/swad_group.h @@ -1,4 +1,4 @@ -// swad_group.h: groups +// swad_group.h: types of groups and groups #ifndef _SWAD_GRP #define _SWAD_GRP @@ -184,7 +184,6 @@ void Grp_ListGrpsToEditAsgAttSvyEvtMch (struct GroupType *GrpTyp, Grp_WhichIsAssociatedToGrp_t WhichIsAssociatedToGrp, long Cod); -bool Grp_DB_CheckIfAssociatedToGrps (const char *Table,const char *Field,long Cod); void Grp_ReqRegisterInGrps (void); void Grp_ShowLstGrpsToChgMyGrps (void); void Grp_ShowLstGrpsToChgOtherUsrsGrps (long UsrCod); @@ -193,8 +192,6 @@ void Grp_GetListGrpTypesInThisCrs (Grp_WhichGroupTypes_t WhichGroupTypes); void Grp_FreeListGrpTypesAndGrps (void); void Grp_OpenGroupsAutomatically (void); void Grp_GetListGrpTypesAndGrpsInThisCrs (Grp_WhichGroupTypes_t WhichGroupTypes); -unsigned Grp_DB_CountNumGrpsInCurrentCrs (void); -unsigned Grp_DB_GetGrpsOfType (long GrpTypCod,MYSQL_RES **mysql_res); void Grp_GetDataOfGroupByCod (struct GroupData *GrpDat); bool Grp_DB_CheckIfGroupExists (long GrpCod); bool Grp_DB_CheckIfGrpBelongsToCrs (long GrpCod,long CrsCod); diff --git a/swad_group_database.c b/swad_group_database.c new file mode 100644 index 00000000..ae377704 --- /dev/null +++ b/swad_group_database.c @@ -0,0 +1,200 @@ +// swad_group_database.c: types of groups and groups 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 NULL +// #include // For asprintf +// #include // For exit, system, malloc, free, rand, etc. +// #include // For string functions + +// #include "swad_action.h" +// #include "swad_assignment_database.h" +// #include "swad_attendance_database.h" +// #include "swad_box.h" +#include "swad_database.h" +// #include "swad_error.h" +// #include "swad_exam_session.h" +// #include "swad_form.h" +// #include "swad_game.h" +#include "swad_global.h" +#include "swad_group.h" +// #include "swad_HTML.h" +// #include "swad_match.h" +// #include "swad_notification.h" +// #include "swad_parameter.h" +// #include "swad_program.h" +// #include "swad_project.h" +// #include "swad_setting.h" +// #include "swad_survey.h" + +/*****************************************************************************/ +/*************************** Private constants *******************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/****************************** Private types ********************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/************* External global variables from others modules *****************/ +/*****************************************************************************/ + +extern struct Globals Gbl; + +/*****************************************************************************/ +/************************** Private global variables *************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/***************************** Private prototypes ****************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/*********** Lock tables to make the registration in groups atomic ***********/ +/*****************************************************************************/ + +void Grp_DB_LockTables (void) + { + DB_Query ("can not lock tables to change user's groups", + "LOCK TABLES " + "grp_types WRITE," + "grp_groups WRITE," + "grp_users WRITE," + "crs_users READ," + "crs_user_settings READ," + "roo_rooms READ"); + Gbl.DB.LockedTables = true; + } + +/*****************************************************************************/ +/*********** Unlock tables after changes in registration in groups ***********/ +/*****************************************************************************/ + +void Grp_DB_UnlockTables (void) + { + Gbl.DB.LockedTables = false; // Set to false before the following unlock... + // ...to not retry the unlock if error in unlocking + DB_Query ("can not unlock tables after changing user's groups", + "UNLOCK TABLES"); + } + +/*****************************************************************************/ +/************ Check if an assignment is associated to a group ****************/ +/*****************************************************************************/ + +bool Grp_DB_CheckIfAssociatedToGrp (const char *Table,const char *Field, + long Cod,long GrpCod) + { + /***** Get if an assignment, attendance event, survey, exam event or match + is associated to a given group from database *****/ + return (DB_QueryCOUNT ("can not check if associated to a group", + "SELECT COUNT(*)" + " FROM %s" + " WHERE %s=%ld" + " AND GrpCod=%ld", + Table, + Field,Cod, + GrpCod) != 0); + } + +/*****************************************************************************/ +/*** Check if an assignment, attendance event, survey, exam event or match ***/ +/*** is associated to any group ***/ +/*****************************************************************************/ + +bool Grp_DB_CheckIfAssociatedToGrps (const char *Table,const char *Field,long Cod) + { + /***** Trivial check *****/ + if (Cod <= 0) // Assignment, attendance event, survey, exam event or match code + return false; + + /***** Get if an assignment, attendance event, survey, exam event or match + is associated to any group from database *****/ + return (DB_QueryCOUNT ("can not check if associated to groups", + "SELECT COUNT(*)" + " FROM %s" + " WHERE %s=%ld", + Table, + Field,Cod) != 0); + } + +/*****************************************************************************/ +/*********** Query the number of groups that hay in this course **************/ +/*****************************************************************************/ + +unsigned Grp_DB_CountNumGrpsInCurrentCrs (void) + { + /***** Get number of group in current course from database *****/ + return (unsigned) + DB_QueryCOUNT ("can not get number of groups in this course", + "SELECT COUNT(*)" + " FROM grp_types," + "grp_groups" + " WHERE grp_types.CrsCod=%ld" + " AND grp_types.GrpTypCod=grp_groups.GrpTypCod", + Gbl.Hierarchy.Crs.CrsCod); + } + +/*****************************************************************************/ +/****************** Count number of groups in a group type *******************/ +/*****************************************************************************/ + +unsigned Grp_DB_CountNumGrpsInThisCrsOfType (long GrpTypCod) + { + /***** Get number of groups of a type from database *****/ + return (unsigned) + DB_QueryCOUNT ("can not get number of groups of a type", + "SELECT COUNT(*)" + " FROM grp_groups" + " WHERE GrpTypCod=%ld", + GrpTypCod); + } + +/*****************************************************************************/ +/******************** Get groups of a type in this course ********************/ +/*****************************************************************************/ + +unsigned Grp_DB_GetGrpsOfType (MYSQL_RES **mysql_res,long GrpTypCod) + { + /***** Get groups of a type from database *****/ + // Don't use INNER JOIN because there are groups without assigned room + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get groups of a type", + "SELECT grp_groups.GrpCod," // row[0] + "grp_groups.GrpName," // row[1] + "grp_groups.RooCod," // row[2] + "roo_rooms.ShortName," // row[3] + "grp_groups.MaxStudents," // row[4] + "grp_groups.Open," // row[5] + "grp_groups.FileZones" // row[6] + " FROM grp_groups" + " LEFT JOIN roo_rooms" + " ON grp_groups.RooCod=roo_rooms.RooCod" + " WHERE grp_groups.GrpTypCod=%ld" + " ORDER BY grp_groups.GrpName", + GrpTypCod); + } diff --git a/swad_group_database.h b/swad_group_database.h new file mode 100644 index 00000000..f1c9fc81 --- /dev/null +++ b/swad_group_database.h @@ -0,0 +1,57 @@ +// swad_group_database.h: types of groups and groups operations with database + +#ifndef _SWAD_GRP_DB +#define _SWAD_GRP_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 . +*/ +/*****************************************************************************/ +/********************************* Headers ***********************************/ +/*****************************************************************************/ + +// #include "swad_info.h" +// #include "swad_room.h" +// #include "swad_user.h" + +/*****************************************************************************/ +/***************************** Public constants ******************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/******************************* Public types ********************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/****************************** Public prototypes ****************************/ +/*****************************************************************************/ + +void Grp_DB_LockTables (void); +void Grp_DB_UnlockTables (void); + +bool Grp_DB_CheckIfAssociatedToGrp (const char *Table,const char *Field, + long Cod,long GrpCod); +bool Grp_DB_CheckIfAssociatedToGrps (const char *Table,const char *Field,long Cod); + +unsigned Grp_DB_CountNumGrpsInCurrentCrs (void); +unsigned Grp_DB_CountNumGrpsInThisCrsOfType (long GrpTypCod); +unsigned Grp_DB_GetGrpsOfType (MYSQL_RES **mysql_res,long GrpTypCod); + +#endif diff --git a/swad_hierarchy.c b/swad_hierarchy.c index 9d781e79..7db71008 100644 --- a/swad_hierarchy.c +++ b/swad_hierarchy.c @@ -34,6 +34,7 @@ #include "swad_error.h" #include "swad_form.h" #include "swad_global.h" +#include "swad_group_database.h" #include "swad_hierarchy.h" #include "swad_hierarchy_level.h" #include "swad_HTML.h" diff --git a/swad_match.c b/swad_match.c index 0a485e52..bd1abde8 100644 --- a/swad_match.c +++ b/swad_match.c @@ -38,6 +38,7 @@ #include "swad_form.h" #include "swad_game.h" #include "swad_global.h" +#include "swad_group_database.h" #include "swad_HTML.h" #include "swad_match.h" #include "swad_match_result.h" diff --git a/swad_survey.c b/swad_survey.c index 7c0c0f15..2d8398c2 100644 --- a/swad_survey.c +++ b/swad_survey.c @@ -40,6 +40,7 @@ #include "swad_form.h" #include "swad_global.h" #include "swad_group.h" +#include "swad_group_database.h" #include "swad_HTML.h" #include "swad_notification.h" #include "swad_pagination.h"