diff --git a/anki/cards.py b/anki/cards.py index a1aace277..2eac98669 100644 --- a/anki/cards.py +++ b/anki/cards.py @@ -60,7 +60,6 @@ cardsTable = Table( Column('noCount', Integer, nullable=False, default=0), # caching Column('spaceUntil', Float, nullable=False, default=0), - Column('relativeDelay', Float, nullable=False, default=0), Column('isDue', Boolean, nullable=False, default=0), Column('type', Integer, nullable=False, default=2), Column('combinedDue', Integer, nullable=False, default=0)) @@ -163,8 +162,14 @@ class Card(object): return findTag(tag, parseTags(self.allTags())) def fromDB(self, s, id): - r = s.first("select * from cards where id = :id", - id=id) + r = s.first("""select +id, factId, cardModelId, created, modified, tags, ordinal, question, answer, +priority, interval, lastInterval, due, lastDue, factor, +lastFactor, firstAnswered, reps, successive, averageTime, reviewTime, +youngEase0, youngEase1, youngEase2, youngEase3, youngEase4, +matureEase0, matureEase1, matureEase2, matureEase3, matureEase4, +yesCount, noCount, spaceUntil, isDue, type, combinedDue +from cards where id = :id""", id=id) if not r: return (self.id, @@ -201,7 +206,6 @@ class Card(object): self.yesCount, self.noCount, self.spaceUntil, - self.relativeDelay, self.isDue, self.type, self.combinedDue) = r @@ -242,7 +246,6 @@ matureEase4=:matureEase4, yesCount=:yesCount, noCount=:noCount, spaceUntil = :spaceUntil, -relativeDelay = :interval / (strftime("%s", "now") - :due + 1), isDue = :isDue, type = :type, combinedDue = max(:spaceUntil, :due) diff --git a/anki/deck.py b/anki/deck.py index 3400613cd..da2aea3cc 100644 --- a/anki/deck.py +++ b/anki/deck.py @@ -34,8 +34,7 @@ PRIORITY_NORM = 2 PRIORITY_LOW = 1 PRIORITY_NONE = 0 MATURE_THRESHOLD = 21 -# need interval > 0 to ensure relative delay is ordered properly -NEW_INTERVAL = 0.001 +NEW_INTERVAL = 0 NEW_CARDS_LAST = 1 NEW_CARDS_DISTRIBUTE = 0 @@ -46,7 +45,7 @@ decksTable = Table( Column('created', Float, nullable=False, default=time.time), Column('modified', Float, nullable=False, default=time.time), Column('description', UnicodeText, nullable=False, default=u""), - Column('version', Integer, nullable=False, default=12), + Column('version', Integer, nullable=False, default=13), Column('currentModelId', Integer, ForeignKey("models.id")), # syncing Column('syncName', UnicodeText), @@ -280,7 +279,6 @@ where id != :id and factId = :factId""", entry = CardHistoryEntry(card, ease, lastDelay) entry.writeSQL(self.s) self.modified = now - #print "ans", time.time() - t # Queue/cache management ########################################################################## @@ -462,7 +460,7 @@ factor = 2.5, reps = 0, successive = 0, averageTime = 0, reviewTime = 0, youngEase0 = 0, youngEase1 = 0, youngEase2 = 0, youngEase3 = 0, youngEase4 = 0, matureEase0 = 0, matureEase1 = 0, matureEase2 = 0, matureEase3 = 0,matureEase4 = 0, yesCount = 0, noCount = 0, -spaceUntil = 0, relativeDelay = 0, isDue = 0, type = 2, +spaceUntil = 0, isDue = 0, type = 2, combinedDue = created, modified = :now, due = created where id in %s""" % ids2str(ids), now=time.time(), new=NEW_INTERVAL) self.flushMod() @@ -624,12 +622,12 @@ suspended cards.''') % { def suspendedCardCount(self): return self.s.scalar(""" -select count(id) from cards where type in (0,1,2) and isDue in (0,1) + "select count(id) from cards where type in (0,1,2) and priority = 0") and priority = 0""") def seenCardCount(self): return self.s.scalar( - "select count(id) from cards where type in (0, 1)") + "select count(id) from cards where type = 2") # Counts related to due cards ########################################################################## @@ -645,6 +643,7 @@ and priority = 0""") return self.s.scalar(""" select count(cards.id) from cards where type in (1,2) and isDue = 0 and priority in (1,2,3,4) and due < :now""", +priority in (1,2,3,4) and due < :now and spaceUntil > :now""", now=time.time()) def isEmpty(self): @@ -1655,11 +1654,8 @@ alter table decks add column newCount integer not null default 0""") "Add indices to the DB." # card queues deck.s.statement(""" -create index if not exists ix_cards_checkDueOrder on cards -(type, isDue, priority desc, combinedDue desc)""") - deck.s.statement(""" -create index if not exists ix_cards_failedOrder on cards -(type, isDue, priority desc, due)""") +create index if not exists ix_cards_combinedDue on cards +(type, isDue, combinedDue, priority)""") deck.s.statement(""" create index if not exists ix_cards_revisionOrder on cards (type, isDue, priority desc, interval desc)""") @@ -1668,7 +1664,7 @@ create index if not exists ix_cards_newRandomOrder on cards (type, isDue, priority desc, factId, ordinal)""") deck.s.statement(""" create index if not exists ix_cards_newOrderedOrder on cards -(type, isDue, priority desc, due)""") +(type, isDue, priority desc, combinedDue)""") # card spacing deck.s.statement(""" create index if not exists ix_cards_factId on cards (factId)""") @@ -1699,7 +1695,7 @@ create index if not exists ix_mediaDeleted_factId on mediaDeleted (mediaId)""") def _addViews(deck): "Add latest version of SQL views to DB." s = deck.s - # old tables + # old views s.statement("drop view if exists failedCards") s.statement("drop view if exists acqCards") s.statement("drop view if exists futureCards") @@ -1714,15 +1710,16 @@ create index if not exists ix_mediaDeleted_factId on mediaDeleted (mediaId)""") create view failedCardsNow as select * from cards where type = 0 and isDue = 1 -order by due +and +priority in (1,2,3,4) +order by type, isDue, combinedDue """) s.statement(""" create view failedCardsSoon as select * from cards -where type = 0 and priority in (1,2,3,4) +where type = 0 and +priority in (1,2,3,4) and combinedDue <= (select max(delay0, delay1) + -strftime("%s", "now")+1 from decks) -order by modified +strftime("%s", "now")+1 from decks where id = 1) +order by type, isDue, combinedDue """) s.statement(""" create view revCards as @@ -1738,7 +1735,7 @@ order by priority desc, factId, ordinal""") create view acqCardsOrdered as select * from cards where type = 2 and isDue = 1 -order by priority desc, due""") +order by priority desc, combinedDue""") _addViews = staticmethod(_addViews) def _upgradeDeck(deck, path): @@ -1750,8 +1747,6 @@ order by priority desc, due""") deck.s.statement(""" alter table cards add column spaceUntil float not null default 0""") deck.s.statement(""" - alter table cards add column relativeDelay float not null default 0.0""") - deck.s.statement(""" alter table cards add column isDue boolean not null default 0""") deck.s.statement(""" alter table cards add column type integer not null default 0""") @@ -1881,7 +1876,7 @@ alter table models add column source integer not null default 0""") DeckStorage._setUTCOffset(deck) deck.version = 11 deck.s.commit() - if deck.version < 12: #True: # False: #True: #deck.version < 12: + if deck.version < 12: deck.s.statement("drop index if exists ix_cards_revisionOrder") deck.s.statement("drop index if exists ix_cards_newRandomOrder") deck.s.statement("drop index if exists ix_cards_newOrderedOrder") @@ -1892,12 +1887,14 @@ alter table models add column source integer not null default 0""") deck.s.statement("drop index if exists ix_cards_priority") DeckStorage._addViews(deck) DeckStorage._addIndices(deck) + deck.s.statement("analyze") + if deck.version < 13: deck.rebuildCounts() deck.rebuildQueue() # regenerate question/answer cache for m in deck.models: deck.updateCardsFromModel(m) - deck.version = 12 + deck.version = 13 deck.s.commit() return deck _upgradeDeck = staticmethod(_upgradeDeck) diff --git a/anki/exporting.py b/anki/exporting.py index 7705ee246..0a411eb2c 100644 --- a/anki/exporting.py +++ b/anki/exporting.py @@ -77,7 +77,7 @@ class AnkiExporter(Exporter): delete from reviewHistory""") self.newDeck.s.statement(""" update cards set -interval = 0.001, +interval = 0, lastInterval = 0, due = created, lastDue = 0, @@ -101,7 +101,6 @@ yesCount = 0, noCount = 0, spaceUntil = 0, isDue = 1, -relativeDelay = 0, type = 2, combinedDue = created, modified = :now diff --git a/anki/sync.py b/anki/sync.py index fce1dc334..0c085549d 100644 --- a/anki/sync.py +++ b/anki/sync.py @@ -526,8 +526,7 @@ priority, interval, lastInterval, due, lastDue, factor, firstAnswered, reps, successive, averageTime, reviewTime, youngEase0, youngEase1, youngEase2, youngEase3, youngEase4, matureEase0, matureEase1, matureEase2, matureEase3, matureEase4, yesCount, noCount, -question, answer, lastFactor, spaceUntil, isDue, type, combinedDue, -relativeDelay) +question, answer, lastFactor, spaceUntil, isDue, type, combinedDue) values (:id, :factId, :cardModelId, :created, :modified, :tags, :ordinal, :priority, :interval, :lastInterval, :due, :lastDue, :factor, @@ -535,7 +534,7 @@ values :youngEase1, :youngEase2, :youngEase3, :youngEase4, :matureEase0, :matureEase1, :matureEase2, :matureEase3, :matureEase4, :yesCount, :noCount, :question, :answer, :lastFactor, :spaceUntil, :isDue, -:type, :combinedDue, 0)""", dlist) +:type, :combinedDue)""", dlist) self.deck.s.statement( "delete from cardsDeleted where cardId in %s" % ids2str([c[0] for c in cards])) @@ -803,11 +802,10 @@ priority, interval, lastInterval, due, lastDue, factor, firstAnswered, reps, successive, averageTime, reviewTime, youngEase0, youngEase1, youngEase2, youngEase3, youngEase4, matureEase0, matureEase1, matureEase2, matureEase3, matureEase4, yesCount, noCount, -question, answer, lastFactor, spaceUntil, isDue, type, combinedDue, -relativeDelay) +question, answer, lastFactor, spaceUntil, isDue, type, combinedDue) values (:id, :factId, :cardModelId, :created, :t, "", :ordinal, -1, 0.001, 0, :created, 0, 2.5, +1, 0, 0, :created, 0, 2.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,