diff --git a/anki/deck.py b/anki/deck.py index 50f7cc9f4..aaaf88282 100644 --- a/anki/deck.py +++ b/anki/deck.py @@ -3122,7 +3122,6 @@ where id = :id""", fid=f.id, cmid=m.cardModels[0].id, id=id) "Please restore from automatic backup (see FAQ).") # ensure correct views and indexes are available self.updateProgress() - DeckStorage._addViews(self) DeckStorage._addIndices(self) # does the user have a model? self.updateProgress(_("Checking schema...")) @@ -3571,7 +3570,6 @@ class DeckStorage(object): deck.s.execute("vacuum") # add views/indices initTagTables(deck.s) - DeckStorage._addViews(deck) DeckStorage._addIndices(deck) deck.s.statement("analyze") deck._initVars() @@ -3734,59 +3732,6 @@ create index if not exists ix_cardTags_tagCard on cardTags (tagId, cardId)""") create index if not exists ix_cardTags_cardId on cardTags (cardId)""") _addIndices = staticmethod(_addIndices) - def _addViews(deck): - "Add latest version of SQL views to DB." - s = deck.s - # old views - s.statement("drop view if exists failedCards") - s.statement("drop view if exists revCardsOld") - s.statement("drop view if exists revCardsNew") - s.statement("drop view if exists revCardsDue") - s.statement("drop view if exists revCardsRandom") - s.statement("drop view if exists acqCardsRandom") - s.statement("drop view if exists acqCardsOld") - s.statement("drop view if exists acqCardsNew") - # failed cards - s.statement(""" -create view failedCards as -select * from cards -where type = 0 and isDue = 1 -order by type, isDue, combinedDue -""") - # rev cards - s.statement(""" -create view revCardsOld as -select * from cards -where type = 1 and isDue = 1 -order by priority desc, interval desc""") - s.statement(""" -create view revCardsNew as -select * from cards -where type = 1 and isDue = 1 -order by priority desc, interval""") - s.statement(""" -create view revCardsDue as -select * from cards -where type = 1 and isDue = 1 -order by priority desc, due""") - s.statement(""" -create view revCardsRandom as -select * from cards -where type = 1 and isDue = 1 -order by priority desc, factId, ordinal""") - # new cards - s.statement(""" -create view acqCardsOld as -select * from cards -where type = 2 and isDue = 1 -order by priority desc, due""") - s.statement(""" -create view acqCardsNew as -select * from cards -where type = 2 and isDue = 1 -order by priority desc, due desc""") - _addViews = staticmethod(_addViews) - def _upgradeDeck(deck, path): "Upgrade deck to the latest version." if deck.version < DECK_VERSION: @@ -3801,353 +3746,8 @@ order by priority desc, due desc""") else: prog = False deck.path = path - if deck.version == 0: - # new columns - try: - 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""") - deck.s.statement(""" - alter table cards add column combinedDue float not null default 0""") - # update cards.spaceUntil based on old facts - deck.s.statement(""" - update cards - set spaceUntil = (select (case - when cards.id = facts.lastCardId - then 0 - else facts.spaceUntil - end) from cards as c, facts - where c.factId = facts.id - and cards.id = c.id)""") - deck.s.statement(""" - update cards - set combinedDue = max(due, spaceUntil) - """) - except: - print "failed to upgrade" - # rebuild with new file format - deck.s.commit() - deck.s.execute("pragma legacy_file_format = off") - deck.s.execute("vacuum") - # add views/indices - DeckStorage._addViews(deck) - DeckStorage._addIndices(deck) - # rebuild type and delay cache - deck.rebuildTypes() - deck.reset() - # bump version - deck.version = 1 - # optimize indices - deck.s.statement("analyze") - if deck.version == 1: - # fix indexes and views - deck.s.statement("drop index if exists ix_cards_newRandomOrder") - deck.s.statement("drop index if exists ix_cards_newOrderedOrder") - DeckStorage._addViews(deck) - DeckStorage._addIndices(deck) - deck.rebuildTypes() - # optimize indices - deck.s.statement("analyze") - deck.version = 2 - if deck.version == 2: - # compensate for bug in 0.9.7 by rebuilding isDue and priorities - deck.s.statement("update cards set isDue = 0") - # compensate for bug in early 0.9.x where fieldId was not unique - deck.s.statement("update fields set id = random()") - deck.version = 3 - if deck.version == 3: - # remove conflicting and unused indexes - deck.s.statement("drop index if exists ix_cards_isDueCombined") - deck.s.statement("drop index if exists ix_facts_lastCardId") - deck.s.statement("drop index if exists ix_cards_successive") - deck.s.statement("drop index if exists ix_cards_priority") - deck.s.statement("drop index if exists ix_cards_reps") - deck.s.statement("drop index if exists ix_cards_due") - deck.s.statement("drop index if exists ix_stats_type") - deck.s.statement("drop index if exists ix_stats_day") - deck.s.statement("drop index if exists ix_factsDeleted_cardId") - deck.s.statement("drop index if exists ix_modelsDeleted_cardId") - DeckStorage._addIndices(deck) - deck.s.statement("analyze") - deck.version = 4 - if deck.version == 4: - # decks field upgraded earlier - deck.version = 5 - if deck.version == 5: - # new spacing - deck.newCardSpacing = NEW_CARDS_DISTRIBUTE - deck.version = 6 - # low priority cards now stay in same queue - deck.rebuildTypes() - if deck.version == 6: - # removed 'new cards first' option, so order has changed - deck.newCardSpacing = NEW_CARDS_DISTRIBUTE - deck.version = 7 - # 8 upgrade code removed as obsolete> - if deck.version < 9: - # back up the media dir again, just in case - shutil.copytree(deck.mediaDir(create=True), - deck.mediaDir() + "-old-%s" % - hash(time.time())) - # backup media - media = deck.s.all(""" -select filename, size, created, originalPath, description from media""") - # fix mediaDeleted definition - deck.s.execute("drop table mediaDeleted") - deck.s.execute("drop table media") - metadata.create_all(deck.engine) - # restore - h = [] - for row in media: - h.append({ - 'id': genID(), - 'filename': row[0], - 'size': row[1], - 'created': row[2], - 'originalPath': row[3], - 'description': row[4]}) - if h: - deck.s.statements(""" -insert into media values ( -:id, :filename, :size, :created, :originalPath, :description)""", h) - deck.version = 9 - if deck.version < 10: - deck.s.statement(""" -alter table models add column source integer not null default 0""") - deck.version = 10 - if deck.version < 11: - DeckStorage._setUTCOffset(deck) - deck.version = 11 - deck.s.commit() - 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") - deck.s.statement("drop index if exists ix_cards_markExpired") - deck.s.statement("drop index if exists ix_cards_failedIsDue") - deck.s.statement("drop index if exists ix_cards_failedOrder") - deck.s.statement("drop index if exists ix_cards_type") - 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.reset() - deck.rebuildCounts() - # regenerate question/answer cache - for m in deck.models: - deck.updateCardsFromModel(m, dirty=False) - deck.version = 13 - if deck.version < 14: - deck.s.statement(""" -update cards set interval = 0 -where interval < 1""") - deck.version = 14 - if deck.version < 15: - deck.delay1 = deck.delay0 - deck.delay2 = 0.0 - deck.version = 15 - if deck.version < 16: - deck.version = 16 - if deck.version < 17: - deck.s.statement("drop view if exists acqCards") - deck.s.statement("drop view if exists futureCards") - deck.s.statement("drop view if exists revCards") - deck.s.statement("drop view if exists typedCards") - deck.s.statement("drop view if exists failedCardsNow") - deck.s.statement("drop view if exists failedCardsSoon") - 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") - deck.s.statement("drop index if exists ix_cards_combinedDue") - # add new views - DeckStorage._addViews(deck) - DeckStorage._addIndices(deck) - deck.version = 17 - if deck.version < 18: - deck.s.statement( - "create table undoLog (seq integer primary key, sql text)") - deck.version = 18 - deck.s.commit() - DeckStorage._addIndices(deck) - deck.s.statement("analyze") - if deck.version < 19: - # permanent undo log causes various problems, revert to temp - deck.s.statement("drop table undoLog") - deck.sessionTimeLimit = 600 - deck.sessionRepLimit = 0 - deck.version = 19 - deck.s.commit() - if deck.version < 20: - DeckStorage._addViews(deck) - DeckStorage._addIndices(deck) - deck.version = 20 - deck.s.commit() - if deck.version < 21: - deck.s.statement("vacuum") - deck.s.statement("analyze") - deck.version = 21 - deck.s.commit() - if deck.version < 22: - deck.s.statement( - 'update cardModels set typeAnswer = ""') - deck.version = 22 - deck.s.commit() - if deck.version < 23: - try: - deck.s.execute("drop table undoLog") - except: - pass - deck.version = 23 - deck.s.commit() - if deck.version < 24: - deck.s.statement( - "update cardModels set lastFontColour = '#ffffff'") - deck.version = 24 - deck.s.commit() - if deck.version < 25: - deck.s.statement("drop index if exists ix_cards_priorityDue") - deck.s.statement("drop index if exists ix_cards_priorityDueReal") - DeckStorage._addViews(deck) - DeckStorage._addIndices(deck) - deck.updateDynamicIndices() - deck.version = 25 - deck.s.commit() - if deck.version < 26: - # no spaces in tags anymore, as separated by space - def munge(tags): - tags = re.sub(", ?", "--tmp--", tags) - tags = re.sub(" - ", "-", tags) - tags = re.sub(" ", "-", tags) - tags = re.sub("--tmp--", " ", tags) - tags = canonifyTags(tags) - return tags - rows = deck.s.all('select id, tags from facts') - d = [] - for (id, tags) in rows: - d.append({ - 'i': id, - 't': munge(tags), - }) - deck.s.statements( - "update facts set tags = :t where id = :i", d) - for k in ('highPriority', 'medPriority', - 'lowPriority', 'suspended'): - x = getattr(deck, k) - setattr(deck, k, munge(x)) - for m in deck.models: - for cm in m.cardModels: - cm.name = munge(cm.name) - m.tags = munge(m.tags) - deck.updateCardsFromModel(m, dirty=False) - deck.version = 26 - deck.s.commit() - deck.s.statement("vacuum") - if deck.version < 27: - DeckStorage._addIndices(deck) - deck.updateCardTags() - deck.version = 27 - deck.s.commit() - if deck.version < 28: - deck.s.statement("pragma default_cache_size= 20000") - deck.version = 28 - deck.s.commit() - if deck.version < 30: - # remove duplicates from review history - deck.s.statement(""" -delete from reviewHistory where id not in ( -select min(id) from reviewHistory group by cardId, time);""") - deck.version = 30 - deck.s.commit() - if deck.version < 31: - # recreate review history table - deck.s.statement("drop index if exists ix_reviewHistory_unique") - schema = """ -CREATE TABLE %s ( -cardId INTEGER NOT NULL, -time NUMERIC(10, 2) NOT NULL, -lastInterval NUMERIC(10, 2) NOT NULL, -nextInterval NUMERIC(10, 2) NOT NULL, -ease INTEGER NOT NULL, -delay NUMERIC(10, 2) NOT NULL, -lastFactor NUMERIC(10, 2) NOT NULL, -nextFactor NUMERIC(10, 2) NOT NULL, -reps NUMERIC(10, 2) NOT NULL, -thinkingTime NUMERIC(10, 2) NOT NULL, -yesCount NUMERIC(10, 2) NOT NULL, -noCount NUMERIC(10, 2) NOT NULL, -PRIMARY KEY (cardId, time))""" - deck.s.statement(schema % "revtmp") - deck.s.statement(""" -insert into revtmp -select cardId, time, lastInterval, nextInterval, ease, delay, lastFactor, -nextFactor, reps, thinkingTime, yesCount, noCount from reviewHistory""") - deck.s.statement("drop table reviewHistory") - metadata.create_all(deck.engine) - deck.s.statement( - "insert into reviewHistory select * from revtmp") - deck.s.statement("drop table revtmp") - deck.version = 31 - deck.s.commit() - deck.s.statement("vacuum") - if deck.version < 32: - deck.s.execute("drop index if exists ix_cardTags_tagId") - deck.s.execute("drop index if exists ix_cardTags_cardId") - DeckStorage._addIndices(deck) - deck.s.execute("analyze") - deck.version = 32 - deck.s.commit() - if deck.version < 33: - deck.s.execute("drop index if exists ix_tags_tag") - DeckStorage._addIndices(deck) - deck.version = 33 - deck.s.commit() - if deck.version < 34: - deck.s.execute("drop view if exists acqCardsRandom") - deck.s.execute("drop index if exists ix_cards_factId") - DeckStorage._addIndices(deck) - deck.updateDynamicIndices() - deck.version = 34 - deck.s.commit() - if deck.version < 36: - deck.s.statement("drop index if exists ix_cards_priorityDue") - DeckStorage._addIndices(deck) - deck.s.execute("analyze") - deck.version = 36 - deck.s.commit() - if deck.version < 37: - if deck.getFailedCardPolicy() == 1: - deck.failedCardMax = 0 - deck.version = 37 - deck.s.commit() - if deck.version < 39: - deck.reset() - # manually suspend all suspended cards - ids = deck.findCards("tag:suspended") - if ids: - # unrolled from suspendCards() to avoid marking dirty - deck.s.statement( - "update cards set isDue=0, priority=-3 " - "where id in %s" % ids2str(ids)) - deck.rebuildCounts() - # suspended tag obsolete - don't do this yet - deck.suspended = re.sub(u" ?Suspended ?", u"", deck.suspended) - deck.version = 39 - deck.s.commit() - if deck.version < 40: - # now stores media url - deck.s.statement("update models set features = ''") - deck.version = 40 - deck.s.commit() if deck.version < 43: - deck.s.statement("update fieldModels set features = ''") - deck.version = 43 - deck.s.commit() + raise Exception("oldDeckVersion") if deck.version < 44: # leaner indices deck.s.statement("drop index if exists ix_cards_factId") @@ -4275,6 +3875,11 @@ this message. (ERR-0101)""") % { "dueAsc", "dueDesc"): deck.s.statement("drop index if exists ix_cards_%s2" % d) deck.s.statement("drop index if exists ix_cards_%s" % d) + # remove old views + for v in ("failedCards", "revCardsOld", "revCardsNew", + "revCardsDue", "revCardsRandom", "acqCardsRandom", + "acqCardsOld", "acqCardsNew"): + deck.s.statement("drop view if exists %s" % v) deck.s.execute("analyze") deck.version = 70 deck.s.commit() diff --git a/tests/importing/test03.anki b/tests/importing/test03.anki deleted file mode 100644 index 5f285ee00..000000000 Binary files a/tests/importing/test03.anki and /dev/null differ diff --git a/tests/importing/test10-2.anki b/tests/importing/test10-2.anki index 7a540d6b6..9ba69ece0 100644 Binary files a/tests/importing/test10-2.anki and b/tests/importing/test10-2.anki differ diff --git a/tests/importing/test10-3.anki b/tests/importing/test10-3.anki index 2b5baf83b..c7e770b36 100644 Binary files a/tests/importing/test10-3.anki and b/tests/importing/test10-3.anki differ diff --git a/tests/importing/test10.anki b/tests/importing/test10.anki index dc881408e..828063188 100644 Binary files a/tests/importing/test10.anki and b/tests/importing/test10.anki differ diff --git a/tests/syncing/media-tests/1.anki b/tests/syncing/media-tests/1.anki index 713815a2c..05940936a 100644 Binary files a/tests/syncing/media-tests/1.anki and b/tests/syncing/media-tests/1.anki differ diff --git a/tests/syncing/media-tests/2.anki b/tests/syncing/media-tests/2.anki index ac9801c8a..13a981b88 100644 Binary files a/tests/syncing/media-tests/2.anki and b/tests/syncing/media-tests/2.anki differ