From 2d22b09cd87cb6ac3e2aba004cf58caa8d5811f3 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Thu, 7 Jan 2021 14:43:34 +0100 Subject: [PATCH 1/7] Display backlog learn cards correctly in FutureDue graph * now they are shown as due in the past * before that they were always displayed as due today --- ts/graphs/future-due.ts | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/ts/graphs/future-due.ts b/ts/graphs/future-due.ts index 09e33133b..339864f46 100644 --- a/ts/graphs/future-due.ts +++ b/ts/graphs/future-due.ts @@ -23,31 +23,38 @@ export interface GraphData { } export function gatherData(data: pb.BackendProto.GraphsOut): GraphData { - const isLearning = (queue: number): boolean => - [CardQueue.Learn, CardQueue.PreviewRepeat].includes(queue); + const isLearning = (card: pb.BackendProto.Card): boolean => + [CardQueue.Learn, CardQueue.PreviewRepeat].includes(card.queue); + let haveBacklog = false; const due = (data.cards as pb.BackendProto.Card[]) - .filter( - (c) => - // reviews + .filter((c: pb.BackendProto.Card) => { + // reviews + return ( [CardQueue.Review, CardQueue.DayLearn].includes(c.queue) || - // or learning cards due today - (isLearning(c.queue) && c.due < data.nextDayAtSecs) - ) - .map((c) => { - if (isLearning(c.queue)) { - return 0; + // or learning cards + isLearning(c) + ); + }) + .map((c: pb.BackendProto.Card) => { + let dueDay: number; + + if (isLearning(c)) { + const offset = c.due - data.nextDayAtSecs + dueDay = Math.floor(offset / 86_400) + 1; + } else { // - testing just odue fails on day 1 // - testing just odid fails on lapsed cards that // have due calculated at regraduation time const due = c.originalDeckId && c.originalDue ? c.originalDue : c.due; - const dueDay = due - data.daysElapsed; - if (dueDay < 0) { - haveBacklog = true; - } - return dueDay; + dueDay = due - data.daysElapsed; + } + + haveBacklog = haveBacklog || dueDay < 0; + + return dueDay }); const dueCounts = rollup( From 7b14449df4db0e1ffd2e12b94f35bae7414c0332 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Thu, 7 Jan 2021 17:14:31 +0100 Subject: [PATCH 2/7] Fix one-off error for Histograms: examples: * x0 = -66 and x1 = -64 should yield 65-66 days ago instead of 64-65 days ago * x0 = -2 and x1 = 0 should yield 1-2 days ago instead of 0-1 days ago --- ts/graphs/future-due.ts | 1 - ts/lib/time.ts | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/ts/graphs/future-due.ts b/ts/graphs/future-due.ts index 339864f46..6515a11c6 100644 --- a/ts/graphs/future-due.ts +++ b/ts/graphs/future-due.ts @@ -42,7 +42,6 @@ export function gatherData(data: pb.BackendProto.GraphsOut): GraphData { if (isLearning(c)) { const offset = c.due - data.nextDayAtSecs dueDay = Math.floor(offset / 86_400) + 1; - } else { // - testing just odue fails on day 1 // - testing just odid fails on lapsed cards that diff --git a/ts/lib/time.ts b/ts/lib/time.ts index 7ad6c61d7..c3eebefb8 100644 --- a/ts/lib/time.ts +++ b/ts/lib/time.ts @@ -151,8 +151,8 @@ export function dayLabel(i18n: I18n, daysStart: number, daysEnd: number): string }); } else { return i18n.tr(i18n.TR.STATISTICS_DAYS_AGO_RANGE, { - daysStart: Math.abs(daysEnd), - daysEnd: -daysStart - 1, + daysStart: Math.abs(daysEnd - 1), + daysEnd: -daysStart, }); } } From 795dcab370b95b6d504399923c80bd4862251190 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Thu, 7 Jan 2021 17:24:10 +0100 Subject: [PATCH 3/7] Include PreviewRepeat cards in is:due --- rslib/src/search/sqlwriter.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rslib/src/search/sqlwriter.rs b/rslib/src/search/sqlwriter.rs index dcc87c24e..8a7fa2329 100644 --- a/rslib/src/search/sqlwriter.rs +++ b/rslib/src/search/sqlwriter.rs @@ -294,12 +294,13 @@ impl SqlWriter<'_> { self.sql, "( (c.queue in ({rev},{daylrn}) and c.due <= {today}) or - (c.queue = {lrn} and c.due <= {learncutoff}) + (c.queue in ({lrn},{previewrepeat}) and c.due <= {learncutoff}) )", rev = CardQueue::Review as i8, daylrn = CardQueue::DayLearn as i8, today = timing.days_elapsed, lrn = CardQueue::Learn as i8, + previewrepeat = CardQueue::PreviewRepeat as i8, learncutoff = TimestampSecs::now().0 + (self.col.learn_ahead_secs() as i64), ), StateKind::UserBuried => write!(self.sql, "c.queue = {}", CardQueue::UserBuried as i8), From 155a59b80b41fd8af6d77e32bc3cb07641f2b865 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Thu, 7 Jan 2021 19:01:10 +0100 Subject: [PATCH 4/7] Search for Learn and PreviewRepeat cards when using prop:due --- rslib/src/search/sqlwriter.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/rslib/src/search/sqlwriter.rs b/rslib/src/search/sqlwriter.rs index 8a7fa2329..cfa749bf3 100644 --- a/rslib/src/search/sqlwriter.rs +++ b/rslib/src/search/sqlwriter.rs @@ -235,16 +235,24 @@ impl SqlWriter<'_> { fn write_prop(&mut self, op: &str, kind: &PropertyKind) -> Result<()> { let timing = self.col.timing_today()?; + match kind { PropertyKind::Due(days) => { let day = days + (timing.days_elapsed as i32); write!( self.sql, - "(c.queue in ({rev},{daylrn}) and due {op} {day})", + "( + (c.queue in ({rev},{daylrn}) and c.due {op} {day}) or + (c.queue in ({lrn},{previewrepeat}) and ((c.due - {cutoff}) / 86400) {op} {days}) + )", rev = CardQueue::Review as u8, daylrn = CardQueue::DayLearn as u8, op = op, - day = day + day = day, + lrn = CardQueue::Learn as i8, + previewrepeat = CardQueue::PreviewRepeat as i8, + cutoff = timing.next_day_at, + days = days ) } PropertyKind::Position(pos) => { From 5f52367403a44eeb8b0fb5406a71d855929c0e3f Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Thu, 7 Jan 2021 19:36:08 +0100 Subject: [PATCH 5/7] Fix formatting graphs ts --- ts/graphs/future-due.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ts/graphs/future-due.ts b/ts/graphs/future-due.ts index 6515a11c6..1ae73c0bf 100644 --- a/ts/graphs/future-due.ts +++ b/ts/graphs/future-due.ts @@ -40,7 +40,7 @@ export function gatherData(data: pb.BackendProto.GraphsOut): GraphData { let dueDay: number; if (isLearning(c)) { - const offset = c.due - data.nextDayAtSecs + const offset = c.due - data.nextDayAtSecs; dueDay = Math.floor(offset / 86_400) + 1; } else { // - testing just odue fails on day 1 @@ -48,12 +48,11 @@ export function gatherData(data: pb.BackendProto.GraphsOut): GraphData { // have due calculated at regraduation time const due = c.originalDeckId && c.originalDue ? c.originalDue : c.due; dueDay = due - data.daysElapsed; - } haveBacklog = haveBacklog || dueDay < 0; - return dueDay + return dueDay; }); const dueCounts = rollup( From 04a56209c6ffcb7e0eb47128346248cd2f4fdab8 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Thu, 7 Jan 2021 19:56:36 +0100 Subject: [PATCH 6/7] Restate rslib unit test --- rslib/src/search/sqlwriter.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/rslib/src/search/sqlwriter.rs b/rslib/src/search/sqlwriter.rs index cfa749bf3..3a46489b4 100644 --- a/rslib/src/search/sqlwriter.rs +++ b/rslib/src/search/sqlwriter.rs @@ -241,9 +241,9 @@ impl SqlWriter<'_> { let day = days + (timing.days_elapsed as i32); write!( self.sql, - "( - (c.queue in ({rev},{daylrn}) and c.due {op} {day}) or - (c.queue in ({lrn},{previewrepeat}) and ((c.due - {cutoff}) / 86400) {op} {days}) + "(\ + (c.queue in ({rev},{daylrn}) and c.due {op} {day}) or \ + (c.queue in ({lrn},{previewrepeat}) and ((c.due - {cutoff}) / 86400) {op} {days})\ )", rev = CardQueue::Review as u8, daylrn = CardQueue::DayLearn as u8, @@ -300,10 +300,10 @@ impl SqlWriter<'_> { StateKind::Suspended => write!(self.sql, "c.queue = {}", CardQueue::Suspended as i8), StateKind::Due => write!( self.sql, - "( - (c.queue in ({rev},{daylrn}) and c.due <= {today}) or - (c.queue in ({lrn},{previewrepeat}) and c.due <= {learncutoff}) - )", + "(\ + (c.queue in ({rev},{daylrn}) and c.due <= {today}) or \ + (c.queue in ({lrn},{previewrepeat}) and c.due <= {learncutoff})\ + )", rev = CardQueue::Review as i8, daylrn = CardQueue::DayLearn as i8, today = timing.days_elapsed, @@ -734,8 +734,9 @@ mod test { assert_eq!( s(ctx, "prop:due!=-1").0, format!( - "((c.queue in (2,3) and due != {}))", - timing.days_elapsed - 1 + "(((c.queue in (2,3) and c.due != {days}) or (c.queue in (1,4) and ((c.due - {cutoff}) / 86400) != -1)))", + days = timing.days_elapsed - 1, + cutoff = timing.next_day_at ) ); From 4c570785bbfaf920e6675f4d702b5d78b42a7349 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Thu, 7 Jan 2021 20:10:25 +0100 Subject: [PATCH 7/7] Add comment about integer division --- rslib/src/search/sqlwriter.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/rslib/src/search/sqlwriter.rs b/rslib/src/search/sqlwriter.rs index 3a46489b4..a29502d63 100644 --- a/rslib/src/search/sqlwriter.rs +++ b/rslib/src/search/sqlwriter.rs @@ -241,6 +241,7 @@ impl SqlWriter<'_> { let day = days + (timing.days_elapsed as i32); write!( self.sql, + // SQL does integer division if both parameters are integers "(\ (c.queue in ({rev},{daylrn}) and c.due {op} {day}) or \ (c.queue in ({lrn},{previewrepeat}) and ((c.due - {cutoff}) / 86400) {op} {days})\