diff --git a/sql/cambios.sql b/sql/cambios.sql index 92d76e3a0..6a003f277 100644 --- a/sql/cambios.sql +++ b/sql/cambios.sql @@ -11158,3 +11158,10 @@ OPTIMIZE TABLE ws_keys; ----- SELECT TstCod,AllowTeachers,UNIX_TIMESTAMP(TstTime) AS T,NumQsts,NumQstsNotBlank,Score FROM tst_exams WHERE T>='0' AND T<='2000000000' ORDER BY TstCod; + +----- + +SELECT * FROM expanded_folders WHERE UNIX_TIMESTAMP() > UNIX_TIMESTAMP(ClickTime)+'1000'; +SELECT * FROM expanded_folders WHERE ClickTimeCrsCod,(unsigned) Not_ACTIVE_NOTICE); NumNotices = DB_QuerySELECT (Query,&mysql_res,"can not get notices from database"); diff --git a/swad_changelog.h b/swad_changelog.h index 72a430b4d..8484ede18 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -108,16 +108,23 @@ // TODO: Row with total of users in figures // TODO: Remove total rows in listing of places // TODO: Show message indicating that mail could be in SPAM folder +// TODO: Remove email address for recipients rejected (mailbox unavailable) /*****************************************************************************/ /****************************** Public constants *****************************/ /*****************************************************************************/ -#define Log_PLATFORM_VERSION "SWAD 15.36 (2015/11/10)" +#define Log_PLATFORM_VERSION "SWAD 15.37 (2015/11/11)" // Number of lines (includes comments but not blank lines) has been got with the following command: // nl swad*.c swad*.h css/swad*.css py/swad*.py js/swad*.js soap/swad*.h sql/swad*.sql | tail -1 /* + Version 15.37: Nov 11, 2015 Changes to speed up queries related to time. + Time to next test printed in user's local time. + Table table IP_last removed. (186909 lines) + 1 change necessary in database: +DROP TABLE IF EXISTS IP_last; + Version 15.36: Nov 10, 2015 Fixed bug in assignments, reported by Javier Fernández Baldomero. Changes in automatic creation of assignment folders. (186985 lines) Version 15.35.5: Nov 09, 2015 Fixed bug in swad.sql, reported by Florent H. Carré. diff --git a/swad_course.c b/swad_course.c index ce0552f15..24f32dc77 100644 --- a/swad_course.c +++ b/swad_course.c @@ -3490,7 +3490,7 @@ void Crs_RemoveOldCrss (void) /***** Get old courses from database *****/ sprintf (Query,"SELECT CrsCod FROM crs_last WHERE" - " UNIX_TIMESTAMP(LastTime) < UNIX_TIMESTAMP()-%lu" + " LastTime"); - /***** Table IP_last *****/ -/* -mysql> DESCRIBE IP_last; -+-----------+----------+------+-----+---------+-------+ -| Field | Type | Null | Key | Default | Extra | -+-----------+----------+------+-----+---------+-------+ -| IP | char(15) | NO | PRI | NULL | | -| LastClick | datetime | NO | MUL | NULL | | -+-----------+----------+------+-----+---------+-------+ -2 rows in set (0.00 sec) -*/ - DB_CreateTable ("CREATE TABLE IF NOT EXISTS IP_last (" - "IP CHAR(15) NOT NULL," - "LastClick DATETIME NOT NULL," - "PRIMARY KEY(IP),INDEX(LastClick))"); - /***** Table IP_prefs *****/ /* mysql> DESCRIBE IP_prefs; diff --git a/swad_enrollment.c b/swad_enrollment.c index eccf59882..e4cd993b1 100644 --- a/swad_enrollment.c +++ b/swad_enrollment.c @@ -744,7 +744,7 @@ void Enr_RemoveOldUsrs (void) sprintf (Query,"SELECT UsrCod FROM" "(" "SELECT UsrCod FROM usr_last WHERE" - " UNIX_TIMESTAMP(LastTime) < UNIX_TIMESTAMP()-%lu" + " LastTime UNIX_TIMESTAMP(ClickTime)+%ld", + " WHERE ClickTime UNIX_TIMESTAMP(CopyTime)+%ld", + " WHERE CopyTimeThrCod); NumRows = DB_QuerySELECT (Query,&mysql_res,"can not get data of a thread of a forum"); @@ -4208,7 +4211,7 @@ void For_RemoveExpiredThrsClipboards (void) /***** Remove all expired clipboards *****/ sprintf (Query,"DELETE LOW_PRIORITY FROM forum_thr_clip" - " WHERE UNIX_TIMESTAMP() > UNIX_TIMESTAMP(TimeInsert)+%ld", + " WHERE TimeInsert UNIX_TIMESTAMP(DateAndTime)+'%ld')", + " WHERE DateAndTime sent message is deleted { /***** Get data of message from table msg_snt_deleted *****/ sprintf (Query,"SELECT CrsCod,UsrCod,UNIX_TIMESTAMP(CreatTime)" - " FROM msg_snt_deleted WHERE MsgCod='%ld'",MsgCod); + " FROM msg_snt_deleted WHERE MsgCod='%ld'", + MsgCod); NumRows = DB_QuerySELECT (Query,&mysql_res,"can not get data of a message"); *Deleted = true; diff --git a/swad_notification.c b/swad_notification.c index a784283e7..9286c51ca 100644 --- a/swad_notification.c +++ b/swad_notification.c @@ -1279,7 +1279,7 @@ void Ntf_SendPendingNotifByEMailToAllUsrs (void) /***** Get users who must be notified from database ******/ // (Status & Ntf_STATUS_BIT_EMAIL) && !(Status & Ntf_STATUS_BIT_SENT) && !(Status & (Ntf_STATUS_BIT_READ | Ntf_STATUS_BIT_REMOVED)) sprintf (Query,"SELECT DISTINCT ToUsrCod FROM notif" - " WHERE UNIX_TIMESTAMP(TimeNotif) < UNIX_TIMESTAMP()-%lu" + " WHERE TimeNotif0 AND (Status & %u)=0 AND (Status & %u)=0", Cfg_TIME_TO_SEND_PENDING_NOTIF, (unsigned) Ntf_STATUS_BIT_EMAIL, @@ -1320,7 +1320,7 @@ void Ntf_SendPendingNotifByEMailToAllUsrs (void) /***** Delete old notifications ******/ sprintf (Query,"DELETE LOW_PRIORITY FROM notif" - " WHERE UNIX_TIMESTAMP(TimeNotif) < UNIX_TIMESTAMP()-%lu", + " WHERE TimeNotif'%ld'", + " AND TimeNotif>FROM_UNIXTIME('%ld')", Gbl.Usrs.Me.UsrDat.UsrCod, (unsigned) (Ntf_STATUS_BIT_READ | Ntf_STATUS_BIT_REMOVED), Gbl.Usrs.Me.UsrLast.LastAccNotif); diff --git a/swad_password.c b/swad_password.c index 64aca8546..74bd9caaa 100644 --- a/swad_password.c +++ b/swad_password.c @@ -456,7 +456,7 @@ void Pwd_SetMyPendingPassword (char PlainPassword[Pwd_MAX_LENGTH_PLAIN_PASSWORD+ /***** Remove expired pending passwords from database *****/ sprintf (Query,"DELETE FROM pending_passwd" - " WHERE (UNIX_TIMESTAMP() > UNIX_TIMESTAMP(DateAndTime)+'%ld')", + " WHERE DateAndTime UNIX_TIMESTAMP(LastChange)+%ld", + " WHERE LastChange'%ld'" // Necessary because the following comparison is not exact in floating point - " AND NumClicks>='0' AND UNIX_TIMESTAMP(FirstClickTime)>'0')" + " AND NumClicks>='0' AND FirstClickTime>FROM_UNIXTIME('0'))" " AS TableNumClicksPerDay" " WHERE NumClicksPerDay>" "(SELECT NumClicks/(DATEDIFF(NOW(),FirstClickTime)+1)" " FROM usr_figures" " WHERE UsrCod='%ld'" - " AND NumClicks>='0' AND UNIX_TIMESTAMP(FirstClickTime)>'0')", + " AND NumClicks>='0' AND FirstClickTime>FROM_UNIXTIME('0'))", UsrCod,UsrCod); return DB_QueryCOUNT (Query,"can not get ranking using number of clicks per day"); } @@ -738,7 +738,7 @@ static unsigned long Prf_GetNumUsrsWithNumClicksPerDay (void) /***** Select number of rows with values already calculated *****/ sprintf (Query,"SELECT COUNT(*) FROM usr_figures" - " WHERE NumClicks>='0' AND UNIX_TIMESTAMP(FirstClickTime)>'0'"); + " WHERE NumClicks>='0' AND FirstClickTime>FROM_UNIXTIME('0')"); return DB_QueryCOUNT (Query,"can not get number of users with number of clicks per day"); } diff --git a/swad_session.c b/swad_session.c index 907a8afbe..549043d20 100644 --- a/swad_session.c +++ b/swad_session.c @@ -236,9 +236,11 @@ void Ses_RemoveExpiredSessions (void) /* A session expire when last click (LastTime) is too old, or when there was at least one refresh (navigator supports AJAX) and last refresh is too old (browser probably was closed) */ sprintf (Query,"DELETE LOW_PRIORITY FROM sessions WHERE" - " (UNIX_TIMESTAMP() > UNIX_TIMESTAMP(LastTime)+%ld) OR" - " ((UNIX_TIMESTAMP(LastRefresh) > UNIX_TIMESTAMP(LastTime)+1) AND" - " (UNIX_TIMESTAMP() > UNIX_TIMESTAMP(LastRefresh)+%ld))", + " LastTimeUNIX_TIMESTAMP()-%u", - Gbl.IP,Cfg_MIN_TIME_BETWEEN_2_CLICKS_FROM_THE_SAME_IP); - NumClicks = (unsigned) DB_QueryCOUNT (Query,"can not get the number of very recent clicks"); - - ***** Remove old clicks/refreshes ***** - sprintf (Query,"DELETE FROM IP_last" - " WHERE UNIX_TIMESTAMP(LastClick)<=UNIX_TIMESTAMP()-%u", - Cfg_MIN_TIME_BETWEEN_2_CLICKS_FROM_THE_SAME_IP); - DB_QueryDELETE (Query,"can not remove old last IP"); - - ***** Replace last click/refresh from this IP ***** - sprintf (Query,"REPLACE INTO IP_last" - " (IP,LastClick)" - " VALUES ('%s',NOW())", - Gbl.IP); - DB_QueryREPLACE (Query,"can not update last IP"); - - ***** If too fast, write warning and exit ***** - if (NumClicks) // Too fast - { - ***** Write header to standard output to avoid timeout ***** - // Two \r\n are necessary - fprintf (stdout,"Content-type: text/html; charset=windows-1252\r\n\r\n" - "\n" - "\n" - "" - "%s" - "" - "" - "

%s

" - "

" - "← %s" - "

" - "" - "", - Txt_STR_LANG_ID[Gbl.Prefs.Language], - Cfg_PLATFORM_FULL_NAME, - Txt_Too_fast, - Txt_Go_back); - exit (0); - // sleep (Cfg_MIN_TIME_BETWEEN_2_CLICKS_FROM_THE_SAME_IP); // Sleep those seconds - } - } -*/ /*****************************************************************************/ /**************************** Log access in database *************************/ /*****************************************************************************/ @@ -412,7 +348,7 @@ void Sta_RemoveOldEntriesRecentLog (void) /***** Remove all expired clipboards *****/ sprintf (Query,"DELETE LOW_PRIORITY FROM log_recent" - " WHERE UNIX_TIMESTAMP(ClickTime)='%ld'" - " AND" - " UNIX_TIMESTAMP(%s.ClickTime)<='%ld'", - LogTable,(long) Gbl.DateRange.TimeUTC[0], - LogTable,(long) Gbl.DateRange.TimeUTC[1]); + sprintf (QueryAux," WHERE %s.ClickTime" + " BETWEEN FROM_UNIXTIME('%ld') AND FROM_UNIXTIME('%ld')", + LogTable, + (long) Gbl.DateRange.TimeUTC[0], + (long) Gbl.DateRange.TimeUTC[1]); strcat (Query,QueryAux); switch (GlobalOrCourse) @@ -2168,12 +2103,12 @@ static void Sta_ShowDistrAccessesPerDaysAndHour (unsigned long NumRows,MYSQL_RES if (NumRow == 1) Dat_AssignDate (&PreviousReadDate,&CurrentReadDate); - /* Update number of pages generated per hour */ + /* Update number of hits per hour */ if (PreviousReadDate.Year != CurrentReadDate.Year || PreviousReadDate.Month != CurrentReadDate.Month || PreviousReadDate.Day != CurrentReadDate.Day) // Current read date (CurrentReadDate) is older than previous read date (PreviousReadDate) */ { - /* In the next loop we show (NumDaysFromLastDateToCurrDate-1) days (the menos antiguos) with 0 clicks + /* In the next loop we show (NumDaysFromLastDateToCurrDate-1) days with 0 clicks and a last day (older) with Hits.Num */ Dat_AssignDate (&Date,&LastDate); NumDaysFromLastDateToCurrDate = Dat_GetNumDaysBetweenDates (&PreviousReadDate,&LastDate); diff --git a/swad_statistic.h b/swad_statistic.h index 1ade0f7a3..e4982fcfe 100644 --- a/swad_statistic.h +++ b/swad_statistic.h @@ -138,7 +138,6 @@ typedef enum /*****************************************************************************/ void Sta_GetRemoteAddr (void); -void Sta_ExitIfTooFast (void); void Sta_LogAccess (const char *Comments); void Sta_RemoveOldEntriesRecentLog (void); void Sta_AskShowCrsHits (void); diff --git a/swad_test.c b/swad_test.c index 439e8640b..943db5ece 100644 --- a/swad_test.c +++ b/swad_test.c @@ -561,13 +561,13 @@ static void Tst_ShowTstTotalMark (double TotalScore) static bool Tst_CheckIfNextTstAllowed (void) { - extern const char *Txt_You_can_not_make_a_new_test_in_the_course_X_until_TIME_Y; - extern const char *Txt_You_can_not_make_a_new_test_in_the_course_X_until_TIME_Y_on_DATE_Z; + extern const char *Txt_Test; + extern const char *Txt_You_can_not_make_a_new_test_in_the_course_X_until; char Query[512]; MYSQL_RES *mysql_res; MYSQL_ROW row; long NumSecondsFromNowToNextAccTst = -1L; // Access allowed when this number <= 0 - unsigned Year,Month,Day,Hour,Minute,Second; + time_t TimeNextTestUTC = (time_t) 0; /***** Superusers are allowed to do all test they want *****/ if (Gbl.Usrs.Me.LoggedRole == Rol_SYS_ADM) @@ -575,7 +575,7 @@ static bool Tst_CheckIfNextTstAllowed (void) /***** Get date of next allowed access to test from database *****/ sprintf (Query,"SELECT UNIX_TIMESTAMP(LastAccTst+INTERVAL (NumQstsLastTst*%lu) SECOND)-UNIX_TIMESTAMP()," - "LastAccTst+INTERVAL (NumQstsLastTst*%lu) SECOND" + "UNIX_TIMESTAMP(LastAccTst+INTERVAL (NumQstsLastTst*%lu) SECOND)" " FROM crs_usr" " WHERE CrsCod='%ld' AND UsrCod='%ld'", Gbl.Test.Config.MinTimeNxtTstPerQst, @@ -587,9 +587,8 @@ static bool Tst_CheckIfNextTstAllowed (void) row = mysql_fetch_row (mysql_res); if (row[0]) if (sscanf (row[0],"%ld",&NumSecondsFromNowToNextAccTst) == 1) - /* Datetime of next access allowed (row[1]) */ - if (sscanf (row[1],"%04u-%02u-%02u %02u:%02u:%02u",&Year,&Month,&Day,&Hour,&Minute,&Second) != 6) - Lay_ShowErrorAndExit ("Wrong date of next allowed access to test."); + /* Time UTC of next access allowed (row[1]) */ + TimeNextTestUTC = Dat_GetUNIXTimeFromStr (row[1]); } else Lay_ShowErrorAndExit ("Error when reading date of next allowed access to test."); @@ -600,15 +599,31 @@ static bool Tst_CheckIfNextTstAllowed (void) /***** Check if access is allowed *****/ if (NumSecondsFromNowToNextAccTst > 0) { - if (Year == Gbl.Now.Date.Year && - Month == Gbl.Now.Date.Month && - Day == Gbl.Now.Date.Day) // Next access allowed is today - sprintf (Gbl.Message,Txt_You_can_not_make_a_new_test_in_the_course_X_until_TIME_Y, - Gbl.CurrentCrs.Crs.FullName,Hour,Minute,Second); - else - sprintf (Gbl.Message,Txt_You_can_not_make_a_new_test_in_the_course_X_until_TIME_Y_on_DATE_Z, - Gbl.CurrentCrs.Crs.FullName,Hour,Minute,Second,Year,Month,Day); - Lay_ShowAlert (Lay_WARNING,Gbl.Message); + /***** Start frame *****/ + Lay_StartRoundFrameTable (NULL,2,Txt_Test); + Lay_WriteHeaderClassPhoto (1,false,false, + Gbl.CurrentIns.Ins.InsCod, + Gbl.CurrentDeg.Deg.DegCod, + Gbl.CurrentCrs.Crs.CrsCod); + + /***** Write warning *****/ + fprintf (Gbl.F.Out,"" + ""); + fprintf (Gbl.F.Out,Txt_You_can_not_make_a_new_test_in_the_course_X_until, + Gbl.CurrentCrs.Crs.FullName); + fprintf (Gbl.F.Out,": " + "" + "" + "" + "" + "", + (long) TimeNextTestUTC); + + /***** End frame *****/ + Lay_EndRoundFrameTable (); + return false; } return true; @@ -6209,8 +6224,8 @@ static void Tst_ShowResultsOfTestExams (struct UsrData *UsrDat) "NumQsts,NumQstsNotBlank,Score" " FROM tst_exams" " WHERE CrsCod='%ld' AND UsrCod='%ld'" - " AND UNIX_TIMESTAMP(TstTime)>='%ld'" - " AND UNIX_TIMESTAMP(TstTime)<='%ld'" + " AND TstTime>=FROM_UNIXTIME('%ld')" + " AND TstTime<=FROM_UNIXTIME('%ld')" " ORDER BY TstCod", Gbl.CurrentCrs.Crs.CrsCod, UsrDat->UsrCod, diff --git a/swad_text.c b/swad_text.c index b33dd1a6f..03a6ab537 100644 --- a/swad_text.c +++ b/swad_text.c @@ -49860,64 +49860,25 @@ const char *Txt_You_can_not_leave_the_web_address_empty = "You can not leave the web address empty."; // Necessita de tradução #endif -const char *Txt_You_can_not_make_a_new_test_in_the_course_X_until_TIME_Y = // Warning: it is very important to include %s and three %02u in the following sentences +const char *Txt_You_can_not_make_a_new_test_in_the_course_X_until = // Warning: it is very important to include %s in the following sentences #if L==0 - "No puede hacer un nuevo test en la asignatura %s" - " hasta las %02uh%02u'%02u""; // Necessita traduccio + "No puede hacer un nuevo test en la asignatura %s hasta"; // Necessita traduccio #elif L==1 - "You can not make a new test in the course %s" - " until %02uh%02u'%02u""; // Need Übersetzung + "You can not make a new test in the course %s until"; // Need Übersetzung #elif L==2 - "You can not make a new test in the course %s" - " until %02uh%02u'%02u""; + "You can not make a new test in the course %s until"; #elif L==3 - "No puede hacer un nuevo test en la asignatura %s" - " hasta las %02uh%02u'%02u""; + "No puede hacer un nuevo test en la asignatura %s hasta"; #elif L==4 - "You can not make a new test in the course %s" - " until %02uh%02u'%02u""; // Besoin de traduction + "You can not make a new test in the course %s until"; // Besoin de traduction #elif L==5 - "No puede hacer un nuevo test en la asignatura %s" - " hasta las %02uh%02u'%02u""; // Okoteve traducción + "No puede hacer un nuevo test en la asignatura %s hasta"; // Okoteve traducción #elif L==6 - "Non puoi fare un nuovo test nel corso %s" - " fino al %02uh%02u'%02u""; + "Non puoi fare un nuovo test nel corso %s fino"; #elif L==7 - "You can not make a new test in the course %s" - " until %02uh%02u'%02u""; // Potrzebujesz tlumaczenie + "You can not make a new test in the course %s until"; // Potrzebujesz tlumaczenie #elif L==8 - "You can not make a new test in the course %s" - " until %02uh%02u'%02u""; // Necessita de tradução -#endif - -const char *Txt_You_can_not_make_a_new_test_in_the_course_X_until_TIME_Y_on_DATE_Z = // Warning: it is very important to include %s, five %02u and %04u in the following sentences -#if L==0 - "No puede hacer un nuevo test en la asignatura %s" - " hasta las %02u:%02u:%02u del %04u-%02u-%02u"; // Necessita traduccio -#elif L==1 - "You can not make a new test in the course %s" - " until %02u:%02u:%02u on %04u-%02u-%02u"; // Need Übersetzung -#elif L==2 - "You can not make a new test in the course %s" - " until %02u:%02u:%02u on %04u-%02u-%02u"; -#elif L==3 - "No puede hacer un nuevo test en la asignatura %s" - " hasta las %02u:%02u:%02u del %04u-%02u-%02u"; -#elif L==4 - "You can not make a new test in the course %s" - " until %02u:%02u:%02u on %04u-%02u-%02u"; // Besoin de traduction -#elif L==5 - "No puede hacer un nuevo test en la asignatura %s" - " hasta las %02u:%02u:%02u del %04u-%02u-%02u"; // Okoteve traducción -#elif L==6 - "Non puoi fare un nuovo test nel corso %s" - " fino al %02u:%02u:%02u del %04u-%02u-%02u"; -#elif L==7 - "You can not make a new test in the course %s" - " until %02u:%02u:%02u on %04u-%02u-%02u"; // Potrzebujesz tlumaczenie -#elif L==8 - "You can not make a new test in the course %s" - " until %02u:%02u:%02u on %04u-%02u-%02u"; // Necessita de tradução + "You can not make a new test in the course %s until"; // Necessita de tradução #endif const char *Txt_You_can_not_paste_file_or_folder_here = diff --git a/swad_web_service.c b/swad_web_service.c index b7cd0c5da..fbed2c8f6 100644 --- a/swad_web_service.c +++ b/swad_web_service.c @@ -474,7 +474,7 @@ static int Svc_RemoveOldWSKeys (void) /* A session expire when last click (LastTime) is too old, or when there was at least one refresh (navigator supports AJAX) and last refresh is too old (browser probably was closed) */ sprintf (Query,"DELETE LOW_PRIORITY FROM ws_keys WHERE" - " UNIX_TIMESTAMP() > UNIX_TIMESTAMP(LastTime)+%ld", + " LastTime=%ld" + " FROM notif" + " WHERE ToUsrCod='%ld' AND TimeNotif>=FROM_UNIXTIME('%ld')" " ORDER BY TimeNotif DESC", Gbl.Usrs.Me.UsrDat.UsrCod,beginTime); NumRows = DB_QuerySELECT (Query,&mysql_res,"can not get user's notifications"); @@ -3413,11 +3414,16 @@ static int Svc_GetTstQuestions (long CrsCod,long BeginTime,struct swad__getTests " AND tst_questions.QstCod=tst_question_tags.QstCod" " AND tst_question_tags.TagCod=tst_tags.TagCod" " AND tst_tags.CrsCod='%ld'" - " AND (UNIX_TIMESTAMP(tst_questions.EditTime)>='%ld'" - " OR UNIX_TIMESTAMP(tst_tags.ChangeTime)>='%ld')" + " AND " + "(" + "tst_questions.EditTime>=FROM_UNIXTIME('%ld')" + " OR " + "tst_tags.ChangeTime>=FROM_UNIXTIME('%ld')" + ")" " ORDER BY QstCod", CrsCod,CrsCod,CrsCod, - BeginTime,BeginTime); + BeginTime, + BeginTime); NumRows = (unsigned) DB_QuerySELECT (Query,&mysql_res,"can not get test questions"); getTestsOut->questionsArray.__size = (int) NumRows; @@ -3492,11 +3498,17 @@ static int Svc_GetTstAnswers (long CrsCod,long BeginTime,struct swad__getTestsOu " AND tst_questions.QstCod=tst_question_tags.QstCod" " AND tst_question_tags.TagCod=tst_tags.TagCod" " AND tst_tags.CrsCod='%ld'" - " AND (UNIX_TIMESTAMP(tst_questions.EditTime)>='%ld'" - " OR UNIX_TIMESTAMP(tst_tags.ChangeTime)>='%ld'))" + " AND " + "(" + "tst_questions.EditTime>=FROM_UNIXTIME('%ld')" + " OR " + "tst_tags.ChangeTime>=FROM_UNIXTIME('%ld')" + ")" + ")" " ORDER BY QstCod,AnsInd", CrsCod,CrsCod,CrsCod, - BeginTime,BeginTime); + BeginTime, + BeginTime); NumRows = (unsigned) DB_QuerySELECT (Query,&mysql_res,"can not get test answers"); getTestsOut->answersArray.__size = (int) NumRows; @@ -3571,11 +3583,17 @@ static int Svc_GetTstQuestionTags (long CrsCod,long BeginTime,struct swad__getTe " AND tst_questions.QstCod=tst_question_tags.QstCod" " AND tst_question_tags.TagCod=tst_tags.TagCod" " AND tst_tags.CrsCod='%ld'" - " AND (UNIX_TIMESTAMP(tst_questions.EditTime)>='%ld'" - " OR UNIX_TIMESTAMP(tst_tags.ChangeTime)>='%ld'))" + " AND " + "(" + "tst_questions.EditTime>=FROM_UNIXTIME('%ld')" + " OR " + "tst_tags.ChangeTime>=FROM_UNIXTIME('%ld')" + ")" + ")" " ORDER BY QstCod,TagInd", CrsCod,CrsCod,CrsCod, - BeginTime,BeginTime); + BeginTime, + BeginTime); NumRows = (unsigned) DB_QuerySELECT (Query,&mysql_res,"can not get test question tags"); getTestsOut->questionTagsArray.__size = (int) NumRows;