diff --git a/swad_changelog.h b/swad_changelog.h index 7d409d3e..841ef611 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -553,7 +553,7 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - * En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 20.30 (2021-02-11)" +#define Log_PLATFORM_VERSION "SWAD 20.30.1 (2021-02-14)" #define CSS_FILE "swad20.8.css" #define JS_FILE "swad20.6.2.js" /* @@ -601,6 +601,7 @@ TODO: DNI de un estudiante sale err TODO: BUG: Cuando un tipo de grupo sólo tiene un grupo, inscribirse es voluntario, el estudiante sólo puede pertenecer a un grupo, y se inscribe en él, debería poder desapuntarse. Ahora no puede. TODO: Salvador Romero Cortés: @acanas opción para editar posts + Version 20.30.1: Feb 14, 2021 Code refactoring in timeline related to temporary tables. (305883 lines) Version 20.30: Feb 11, 2021 Code refactoring in hierarchy. (305853 lines) Version 20.29.3: Feb 11, 2021 Code refactoring in timeline. (305826 lines) Version 20.29.2: Feb 11, 2021 Code refactoring in timeline. (305806 lines) diff --git a/swad_follow.c b/swad_follow.c index 28967e9d..38e64d24 100644 --- a/swad_follow.c +++ b/swad_follow.c @@ -1481,3 +1481,31 @@ void Fol_RemoveUsrFromUsrFollow (long UsrCod) /***** Flush cache *****/ Fol_FlushCacheFollow (); } + +/*****************************************************************************/ +/******* Create/drop temporary tables with me and the users I follow *********/ +/*****************************************************************************/ + +void Fol_CreateTmpTableMeAndUsrsIFollow (void) + { + /***** Create temporary table with me and the users I follow *****/ + DB_Query ("can not create temporary table", + "CREATE TEMPORARY TABLE fol_tmp_me_and_followed " + "(UsrCod INT NOT NULL," + "UNIQUE INDEX(UsrCod))" + " ENGINE=MEMORY" + " SELECT %ld AS UsrCod" // Me + " UNION" + " SELECT FollowedCod AS UsrCod" // Users I follow + " FROM usr_follow" + " WHERE FollowerCod=%ld", + Gbl.Usrs.Me.UsrDat.UsrCod, + Gbl.Usrs.Me.UsrDat.UsrCod); + } + +void Fol_DropTmpTableMeAndUsrsIFollow (void) + { + /***** Drop temporary table with me and the users I follow *****/ + DB_Query ("can not remove temporary table", + "DROP TEMPORARY TABLE IF EXISTS fol_tmp_me_and_followed"); + } diff --git a/swad_follow.h b/swad_follow.h index b0dc5579..6d1556d1 100644 --- a/swad_follow.h +++ b/swad_follow.h @@ -78,4 +78,8 @@ void Fol_GetNotifFollower (char SummaryStr[Ntf_MAX_BYTES_SUMMARY + 1], void Fol_RemoveUsrFromUsrFollow (long UsrCod); +void Fol_CreateTmpTableMeAndUsrsIFollow (void); +void Fol_DropTmpTableMeAndUsrsIFollow (void); + + #endif diff --git a/swad_timeline.c b/swad_timeline.c index 10c1984f..4a769c3b 100644 --- a/swad_timeline.c +++ b/swad_timeline.c @@ -61,10 +61,10 @@ mysql> SHOW TABLES LIKE 'tl_%'; | | (3863) | | |Publication i+3|-- | | |(original note)| \ | | - |_______________| \ ___tl_notes____ | | _exam_announcements_ - | | \ | | | | | | - |Publication i+2|-- ---->| Note n |<-+ | | Exam announcement | (5571) - |(original note)| \ |(exam announc.)|-(2639)->|____________________| + |_______________| \ ___tl_notes____ | | exam_announcements + | | \ | | | | | | + |Publication i+2|-- ---->| Note n |<-+ | | Exam announc. | (5571) + |(original note)| \ |(exam announc.)|-(2639)->|_______________| |_______________| \ |_______________| 12% ____files____ | | \ | | | | | |Publication i+1|-- ---->| Note n-1 |-(64)--->| Public file | (1473406) diff --git a/swad_timeline_comment.c b/swad_timeline_comment.c index 3f8eb50a..4ff154dc 100644 --- a/swad_timeline_comment.c +++ b/swad_timeline_comment.c @@ -28,6 +28,7 @@ #define _GNU_SOURCE // For asprintf #include // For PATH_MAX #include // For asprintf +#include // For malloc and free #include "swad_database.h" #include "swad_forum.h" diff --git a/swad_timeline_note.c b/swad_timeline_note.c index 6c61a644..65b2a0e1 100644 --- a/swad_timeline_note.c +++ b/swad_timeline_note.c @@ -1441,3 +1441,39 @@ void TL_Not_ClearTimelineNotesThisSessionFromDB (void) " WHERE SessionId='%s'", Gbl.Session.Id); } + +/*****************************************************************************/ +/******** Create/drop temporary tables with notes already retrieved **********/ +/*****************************************************************************/ + +void TL_Not_CreateTmpTablesWithNotesAlreadyRetrieved (const struct TL_Timeline *Timeline) + { + /***** Create temporary table with notes just retrieved *****/ + DB_Query ("can not create temporary table", + "CREATE TEMPORARY TABLE tl_tmp_just_retrieved_notes " + "(NotCod BIGINT NOT NULL,UNIQUE INDEX(NotCod))" + " ENGINE=MEMORY"); + + if (Timeline->WhatToGet == TL_GET_ONLY_OLD_PUBS) + /***** Create temporary table with all notes visible in timeline *****/ + DB_Query ("can not create temporary table", + "CREATE TEMPORARY TABLE tl_tmp_visible_timeline " + "(NotCod BIGINT NOT NULL,UNIQUE INDEX(NotCod))" + " ENGINE=MEMORY" + " SELECT NotCod FROM tl_timelines WHERE SessionId='%s'", + Gbl.Session.Id); + } + +void TL_Not_DropTmpTableJustRetrievedNotes (void) + { + /***** Drop temporary table with notes just retrieved *****/ + DB_Query ("can not remove temporary table", + "DROP TEMPORARY TABLE IF EXISTS tl_tmp_just_retrieved_notes"); + } + +void TL_Not_DropTmpTableVisibleTimeline (void) + { + /***** Drop temporary table with all notes visible in timeline *****/ + DB_Query ("can not remove temporary table", + "DROP TEMPORARY TABLE IF EXISTS tl_tmp_visible_timeline"); + } diff --git a/swad_timeline_note.h b/swad_timeline_note.h index 20939368..74309dfe 100644 --- a/swad_timeline_note.h +++ b/swad_timeline_note.h @@ -124,4 +124,8 @@ void TL_Not_GetDataOfNoteByCod (struct TL_Not_Note *Not); void TL_Not_ClearOldTimelinesNotesFromDB (void); void TL_Not_ClearTimelineNotesThisSessionFromDB (void); +void TL_Not_CreateTmpTablesWithNotesAlreadyRetrieved (const struct TL_Timeline *Timeline); +void TL_Not_DropTmpTableJustRetrievedNotes (void); +void TL_Not_DropTmpTableVisibleTimeline (void); + #endif diff --git a/swad_timeline_publication.c b/swad_timeline_publication.c index f3810c3e..bb76bfc9 100644 --- a/swad_timeline_publication.c +++ b/swad_timeline_publication.c @@ -29,6 +29,7 @@ #include // For string functions #include "swad_database.h" +#include "swad_follow.h" #include "swad_global.h" #include "swad_profile.h" #include "swad_timeline.h" @@ -75,11 +76,9 @@ extern struct Globals Gbl; /***************************** Private prototypes ****************************/ /*****************************************************************************/ -static unsigned TL_Pub_GetMaxPubsToGet (const struct TL_Timeline *Timeline); +static void TL_Pub_DropTemporaryTables (const struct TL_Timeline *Timeline); -static void TL_Pub_CreateTmpTableCurrentTimeline (const struct TL_Timeline *Timeline); -static void TL_Pub_CreateTmpTablePublishers (void); -static void TL_Pub_DropTmpTablesUsedToQueryTimeline (void); +static unsigned TL_Pub_GetMaxPubsToGet (const struct TL_Timeline *Timeline); static void TL_Pub_CreateSubQueryPublishers (const struct TL_Timeline *Timeline, struct TL_Pub_SubQueries *SubQueries); @@ -114,7 +113,7 @@ void TL_Pub_GetListPubsToShowInTimeline (struct TL_Timeline *Timeline) TL_Not_ClearTimelineNotesThisSessionFromDB (); /***** Create temporary table with notes in current timeline *****/ - TL_Pub_CreateTmpTableCurrentTimeline (Timeline); + TL_Not_CreateTmpTablesWithNotesAlreadyRetrieved (Timeline); /***** Create temporary table and subquery with potential publishers *****/ TL_Pub_CreateSubQueryPublishers (Timeline,&SubQueries); @@ -142,18 +141,20 @@ void TL_Pub_GetListPubsToShowInTimeline (struct TL_Timeline *Timeline) */ switch (Timeline->WhatToGet) { - case TL_GET_ONLY_NEW_PUBS: // Get the publications (without limit) newer than LastPubCod + case TL_GET_ONLY_NEW_PUBS: // Get the publications (without limit) + // newer than LastPubCod /* This query is made via AJAX automatically from time to time */ RangePubsToGet.Top = 0; // +Infinite RangePubsToGet.Bottom = TL_Pub_GetPubCodFromSession ("LastPubCod"); break; - case TL_GET_ONLY_OLD_PUBS: // Get some limited publications older than FirstPubCod + case TL_GET_ONLY_OLD_PUBS: // Get some limited publications + // older than FirstPubCod /* This query is made via AJAX when I click in link to get old publications */ RangePubsToGet.Top = TL_Pub_GetPubCodFromSession ("FirstPubCod"); RangePubsToGet.Bottom = 0; // -Infinite break; - case TL_GET_RECENT_TIMELINE: // Get some limited recent publications + case TL_GET_RECENT_TIMELINE: // Get some limited recent publications default: /* This is the first query to get initial timeline shown ==> no notes yet in current timeline table */ @@ -162,13 +163,12 @@ void TL_Pub_GetListPubsToShowInTimeline (struct TL_Timeline *Timeline) break; } /* Create subquery with bottom range of publications to get from tl_pubs. - Bottom publication code remains unchanged in all iterations of the next loop. */ + Bottom pub. code remains unchanged in all iterations of the next loop. */ TL_Pub_CreateSubQueryRangeBottom (&RangePubsToGet,&SubQueries); - /* - With the current approach, we select one by one + /* With the current approach, we select one by one the publications and notes in a loop. In each iteration, - we get the more recent publication (original, shared or commment) + we get the most recent publication (original, shared or commment) of every set of publications corresponding to the same note, checking that the note is not already retrieved. After getting a publication, its note code is stored @@ -180,9 +180,7 @@ void TL_Pub_GetListPubsToShowInTimeline (struct TL_Timeline *Timeline) "SELECT MAX(PubCod) AS NewestPubCod FROM tl_pubs ... " GROUP BY NotCod ORDER BY NewestPubCod DESC LIMIT ..." but this query is slow (several seconds) with a big table. - */ - /* Chained list of publications: Timeline->Pubs.Top Pub #0 @@ -226,7 +224,7 @@ void TL_Pub_GetListPubsToShowInTimeline (struct TL_Timeline *Timeline) /* Insert note in temporary tables with just retrieved notes. These tables will be used to not get notes already shown */ TL_Not_InsertNoteInJustRetrievedNotes (Pub->NotCod); - if (Timeline->WhatToGet == TL_GET_ONLY_OLD_PUBS) + if (Timeline->WhatToGet == TL_GET_ONLY_OLD_PUBS) // Get only old publications TL_Not_InsertNoteInVisibleTimeline (Pub->NotCod); /* Narrow the range for the next iteration */ @@ -241,7 +239,24 @@ void TL_Pub_GetListPubsToShowInTimeline (struct TL_Timeline *Timeline) TL_Not_AddNotesJustRetrievedToTimelineThisSession (); /***** Drop temporary tables *****/ - TL_Pub_DropTmpTablesUsedToQueryTimeline (); + TL_Pub_DropTemporaryTables (Timeline); + } + +/*****************************************************************************/ +/*************************** Drop temporary tables ***************************/ +/*****************************************************************************/ + +static void TL_Pub_DropTemporaryTables (const struct TL_Timeline *Timeline) + { + /***** Drop temporary tables with notes already retrieved *****/ + TL_Not_DropTmpTableJustRetrievedNotes (); + if (Timeline->WhatToGet == TL_GET_ONLY_OLD_PUBS) // Get only old publications + TL_Not_DropTmpTableVisibleTimeline (); + + /**** Drop temporary table with me and users I follow ****/ + if (Timeline->UsrOrGbl == TL_Usr_TIMELINE_GBL) // Show the global timeline + if (Timeline->Who == Usr_WHO_FOLLOWED) // Show the timeline of the users I follow + Fol_DropTmpTableMeAndUsrsIFollow (); } /*****************************************************************************/ @@ -260,58 +275,6 @@ static unsigned TL_Pub_GetMaxPubsToGet (const struct TL_Timeline *Timeline) return MaxPubsToGet[Timeline->WhatToGet]; } -/*****************************************************************************/ -/************* Create temporary tables used to query timeline ****************/ -/*****************************************************************************/ - -static void TL_Pub_CreateTmpTableCurrentTimeline (const struct TL_Timeline *Timeline) - { - /***** Create temporary table with notes just retrieved *****/ - DB_Query ("can not create temporary table", - "CREATE TEMPORARY TABLE tl_tmp_just_retrieved_notes " - "(NotCod BIGINT NOT NULL,UNIQUE INDEX(NotCod))" - " ENGINE=MEMORY"); - - if (Timeline->WhatToGet == TL_GET_ONLY_OLD_PUBS) - /***** Create temporary table with all notes visible in timeline *****/ - DB_Query ("can not create temporary table", - "CREATE TEMPORARY TABLE tl_tmp_visible_timeline " - "(NotCod BIGINT NOT NULL,UNIQUE INDEX(NotCod))" - " ENGINE=MEMORY" - " SELECT NotCod FROM tl_timelines WHERE SessionId='%s'", - Gbl.Session.Id); - } - -static void TL_Pub_CreateTmpTablePublishers (void) - { - /***** Create temporary table with me and the users I follow *****/ - DB_Query ("can not create temporary table", - "CREATE TEMPORARY TABLE tl_tmp_publishers " - "(UsrCod INT NOT NULL," - "UNIQUE INDEX(UsrCod))" - " ENGINE=MEMORY" - " SELECT %ld AS UsrCod" // Me - " UNION" - " SELECT FollowedCod AS UsrCod" // Users I follow - " FROM usr_follow" - " WHERE FollowerCod=%ld", - Gbl.Usrs.Me.UsrDat.UsrCod, - Gbl.Usrs.Me.UsrDat.UsrCod); - } - -/*****************************************************************************/ -/*************** Drop temporary tables used to query timeline ****************/ -/*****************************************************************************/ - -static void TL_Pub_DropTmpTablesUsedToQueryTimeline (void) - { - DB_Query ("can not remove temporary tables", - "DROP TEMPORARY TABLE IF EXISTS " - "tl_tmp_just_retrieved_notes," - "tl_tmp_visible_timeline," - "tl_tmp_publishers"); - } - /*****************************************************************************/ /******* Create temporary table and subquery with potential publishers *******/ /*****************************************************************************/ @@ -337,10 +300,10 @@ static void TL_Pub_CreateSubQueryPublishers (const struct TL_Timeline *Timeline, Gbl.Usrs.Me.UsrDat.UsrCod); break; case Usr_WHO_FOLLOWED: // Show the timeline of the users I follow - TL_Pub_CreateTmpTablePublishers (); - SubQueries->TablePublishers = ",tl_tmp_publishers"; + Fol_CreateTmpTableMeAndUsrsIFollow (); + SubQueries->TablePublishers = ",fol_tmp_me_and_followed"; Str_Copy (SubQueries->Publishers, - "tl_pubs.PublisherCod=tl_tmp_publishers.UsrCod AND ", + "tl_pubs.PublisherCod=fol_tmp_me_and_followed.UsrCod AND ", TL_Pub_MAX_BYTES_SUBQUERY); break; case Usr_WHO_ALL: // Show the timeline of all users @@ -371,7 +334,7 @@ static void TL_Pub_CreateSubQueryAlreadyExists (const struct TL_Timeline *Timeli " (SELECT NotCod FROM tl_tmp_just_retrieved_notes)", // Avoid notes just retrieved TL_Pub_MAX_BYTES_SUBQUERY); break; - case TL_GET_ONLY_OLD_PUBS: + case TL_GET_ONLY_OLD_PUBS: // Get only old publications Str_Copy (SubQueries->AlreadyExists, " tl_pubs.NotCod NOT IN" " (SELECT NotCod FROM tl_tmp_visible_timeline)", // Avoid notes already shown @@ -456,7 +419,7 @@ static void TL_Pub_UpdateFirstLastPubCodesIntoSession (const struct TL_Timeline " WHERE SessionId='%s'", Gbl.Session.Id); break; - case TL_GET_ONLY_OLD_PUBS: + case TL_GET_ONLY_OLD_PUBS: // Get only old publications // The oldest publication code retrieved and shown FirstPubCod = Timeline->Pubs.Bottom ? Timeline->Pubs.Bottom->PubCod : 0; diff --git a/swad_timeline_user.c b/swad_timeline_user.c index 9e6abc23..c8d09689 100644 --- a/swad_timeline_user.c +++ b/swad_timeline_user.c @@ -29,6 +29,7 @@ #define _GNU_SOURCE // For asprintf #include // For PATH_MAX #include // For asprintf +#include // For malloc and free #include "swad_database.h" #include "swad_global.h"