diff --git a/anki/graphs.py b/anki/graphs.py
index 4857b1eed..1b689b458 100644
--- a/anki/graphs.py
+++ b/anki/graphs.py
@@ -114,10 +114,10 @@ from cards c where queue = 1 and interval > 21"""
return self.deck.db.all("""
select
count() as combinedNewReps,
-date(time-:off, "unixepoch") as day,
+date(time/1000-:off, "unixepoch") as day,
sum(case when lastInterval > 21 then 1 else 0 end) as matureReps,
count() - sum(case when rep = 1 then 1 else 0 end) as combinedYoungReps,
-sum(userTime) as reviewTime from revlog
+sum(userTime/1000) as reviewTime from revlog
group by day order by day
""", off=self.deck.utcOffset)
@@ -244,7 +244,7 @@ group by day order by day
else:
# firstAnswered
res = self.deck.db.column0(
- "select time from revlog where rep = 1")
+ "select time/1000 from revlog where rep = 1")
for r in res:
d = int((r - self.endOfDay) / 86400.0)
days[d] = days.get(d, 0) + 1
diff --git a/anki/revlog.py b/anki/revlog.py
index 33f6dd646..e4b0220b6 100644
--- a/anki/revlog.py
+++ b/anki/revlog.py
@@ -8,17 +8,20 @@ from anki.db import *
# Flags: 0=standard review, 1=reschedule due to cram, drill, etc
# Rep: Repetition number. The same number may appear twice if a card has been
# manually rescheduled or answered on multiple sites before a sync.
+#
+# We store the times in integer milliseconds to avoid an extra index on the
+# primary key.
revlogTable = Table(
'revlog', metadata,
- Column('time', Float, nullable=False, primary_key=True, default=time.time),
+ Column('time', Integer, nullable=False, primary_key=True),
Column('cardId', Integer, nullable=False),
Column('ease', Integer, nullable=False),
Column('rep', Integer, nullable=False),
Column('lastInterval', Float, nullable=False),
Column('interval', Float, nullable=False),
Column('factor', Float, nullable=False),
- Column('userTime', Float, nullable=False),
+ Column('userTime', Integer, nullable=False),
Column('flags', Integer, nullable=False, default=0))
def logReview(db, card, ease, flags=0):
@@ -26,7 +29,7 @@ def logReview(db, card, ease, flags=0):
insert into revlog values (
:created, :cardId, :ease, :rep, :lastInterval, :interval, :factor,
:userTime, :flags)""",
- created=time.time(), cardId=card.id, ease=ease, rep=card.reps,
+ created=int(time.time()*1000), cardId=card.id, ease=ease, rep=card.reps,
lastInterval=card.lastInterval, interval=card.interval,
- factor=card.factor, userTime=card.userTime(),
+ factor=card.factor, userTime=int(card.userTime()*1000),
flags=flags)
diff --git a/anki/stats.py b/anki/stats.py
index 15b128ea1..0c9e51618 100644
--- a/anki/stats.py
+++ b/anki/stats.py
@@ -25,7 +25,7 @@ class CardStats(object):
self.txt = "
"
self.addLine(_("Added"), self.strTime(c.created))
first = self.deck.db.scalar(
- "select time from revlog where rep = 1 and cardId = :id", id=c.id)
+ "select time/1000 from revlog where rep = 1 and cardId = :id", id=c.id)
if first:
self.addLine(_("First Review"), self.strTime(first))
self.addLine(_("Changed"), self.strTime(c.modified))
@@ -42,7 +42,7 @@ class CardStats(object):
self.addLine(_("Reviews"), "%d/%d (s=%d)" % (
c.reps-c.lapses, c.reps, c.successive))
(cnt, total) = self.deck.db.first(
- "select count(), sum(userTime) from revlog where cardId = :id", id=c.id)
+ "select count(), sum(userTime)/1000 from revlog where cardId = :id", id=c.id)
if cnt:
self.addLine(_("Average Time"), fmt(total / float(cnt), point=2))
self.addLine(_("Total Time"), fmt(total, point=2))
@@ -250,15 +250,15 @@ class DeckStats(object):
x = today + 86400*start
y = today + 86400*finish
return self.deck.db.scalar("""
-select count(distinct(cast((time-:off)/86400 as integer))) from revlog
-where time >= :x and time <= :y""",x=x,y=y, off=self.deck.utcOffset)
+select count(distinct(cast((time/1000-:off)/86400 as integer))) from revlog
+where time >= :x*1000 and time <= :y*1000""",x=x,y=y, off=self.deck.utcOffset)
def getRepsDone(self, start, finish):
now = datetime.datetime.today()
x = time.mktime((now + datetime.timedelta(start)).timetuple())
y = time.mktime((now + datetime.timedelta(finish)).timetuple())
return self.deck.db.scalar(
- "select count() from revlog where time >= :x and time <= :y",
+ "select count() from revlog where time >= :x*1000 and time <= :y*1000",
x=x, y=y)
def getAverageInterval(self):
@@ -317,7 +317,7 @@ and queue != -1 and type between 0 and 1""", cutoff=cutoff) or 0) / float(period
cutoff = time.time() - 86400 * period
return (self.deck.db.scalar("""
select count(*) from revlog
-where time > :cutoff""", cutoff=cutoff) or 0) / float(period)
+where time > :cutoff*1000""", cutoff=cutoff) or 0) / float(period)
def getNewPeriod(self, period):
cutoff = time.time() - 86400 * period
@@ -329,4 +329,4 @@ where created > :cutoff""", cutoff=cutoff) or 0)
cutoff = time.time() - 86400 * period
return (self.deck.db.scalar("""
select count(*) from revlog
-where rep = 1 and time > :cutoff""", cutoff=cutoff) or 0)
+where rep = 1 and time > :cutoff*1000""", cutoff=cutoff) or 0)
diff --git a/anki/upgrade.py b/anki/upgrade.py
index a58f91c7f..8ef464f0e 100644
--- a/anki/upgrade.py
+++ b/anki/upgrade.py
@@ -146,9 +146,9 @@ def upgradeDeck(deck):
if deck.version < 74:
# migrate revlog data to new table
deck.db.statement("""
-insert into revlog select
-time, cardId, ease, reps, lastInterval, nextInterval, nextFactor,
-min(thinkingTime, 60), 0 from reviewHistory""")
+insert or ignore into revlog select
+cast(time*1000 as int), cardId, ease, reps, lastInterval, nextInterval, nextFactor,
+cast(min(thinkingTime, 60)*1000 as int), 0 from reviewHistory""")
deck.db.statement("drop table reviewHistory")
# convert old ease0 into ease1
deck.db.statement("update revlog set ease = 1 where ease = 0")