optimize add/deleteTag(), add progress callbacks and check (media) db

This commit is contained in:
Damien Elmes 2009-01-16 18:17:36 +09:00
parent 8bd84d4dfe
commit 240d311ca0
2 changed files with 45 additions and 6 deletions

View file

@ -1413,10 +1413,11 @@ update facts set
tags = :tags, tags = :tags,
modified = :now modified = :now
where id = :id""", pending) where id = :id""", pending)
factIds = [c['id'] for c in pending]
cardIds = self.s.column0( cardIds = self.s.column0(
"select id from cards where factId in %s" % "select id from cards where factId in %s" %
ids2str(ids)) ids2str(factIds))
self.updateCardQACacheFromIds(ids, type="facts") self.updateCardQACacheFromIds(factIds, type="facts")
self.updatePriorities(cardIds) self.updatePriorities(cardIds)
self.flushMod() self.flushMod()
@ -1441,13 +1442,27 @@ update facts set
tags = :tags, tags = :tags,
modified = :now modified = :now
where id = :id""", pending) where id = :id""", pending)
factIds = [c['id'] for c in pending]
cardIds = self.s.column0( cardIds = self.s.column0(
"select id from cards where factId in %s" % "select id from cards where factId in %s" %
ids2str(ids)) ids2str(factIds))
self.updateCardQACacheFromIds(ids, type="facts") self.updateCardQACacheFromIds(factIds, type="facts")
self.updatePriorities(cardIds) self.updatePriorities(cardIds)
self.flushMod() self.flushMod()
# Progress info
##########################################################################
def startProgress(self, title, min, max):
runHook("startProgress", title, min, max)
def updateProgress(self, label=None, value=None):
runHook("updateProgress", label, value)
def finishProgress(self):
runHook("updateProgress")
runHook("finishProgress")
# File-related # File-related
########################################################################## ##########################################################################
@ -1626,13 +1641,17 @@ Return new path, relative to media dir."""
def fixIntegrity(self): def fixIntegrity(self):
"Responsibility of caller to call rebuildQueue()" "Responsibility of caller to call rebuildQueue()"
self.startProgress(_("Check DB"), 0, 11)
self.updateProgress(_("Checking integrity..."))
if self.s.scalar("pragma integrity_check") != "ok": if self.s.scalar("pragma integrity_check") != "ok":
return _("Database file damaged. Restore from backup.") return _("Database file damaged. Restore from backup.")
# ensure correct views and indexes are available # ensure correct views and indexes are available
self.updateProgress()
DeckStorage._addViews(self) DeckStorage._addViews(self)
DeckStorage._addIndices(self) DeckStorage._addIndices(self)
problems = [] problems = []
# does the user have a model? # does the user have a model?
self.updateProgress(_("Checking schema..."))
if not self.s.scalar("select count(id) from models"): if not self.s.scalar("select count(id) from models"):
self.addModel(BasicModel()) self.addModel(BasicModel())
problems.append(_("Deck was missing a model")) problems.append(_("Deck was missing a model"))
@ -1643,11 +1662,13 @@ decks.currentModelId = models.id"""):
self.currentModelId = self.models[0].id self.currentModelId = self.models[0].id
problems.append(_("The current model didn't exist")) problems.append(_("The current model didn't exist"))
# forget all deletions (do this before deleting anything) # forget all deletions (do this before deleting anything)
self.updateProgress()
self.s.statement("delete from cardsDeleted") self.s.statement("delete from cardsDeleted")
self.s.statement("delete from factsDeleted") self.s.statement("delete from factsDeleted")
self.s.statement("delete from modelsDeleted") self.s.statement("delete from modelsDeleted")
self.s.statement("delete from mediaDeleted") self.s.statement("delete from mediaDeleted")
# facts missing a field? # facts missing a field?
self.updateProgress()
ids = self.s.column0(""" ids = self.s.column0("""
select distinct facts.id from facts, fieldModels where select distinct facts.id from facts, fieldModels where
facts.modelId = fieldModels.modelId and fieldModels.id not in facts.modelId = fieldModels.modelId and fieldModels.id not in
@ -1685,6 +1706,7 @@ select id from fields where factId not in (select id from facts)""")
problems.append(_("Deleted %d dangling fields") % len(ids)) problems.append(_("Deleted %d dangling fields") % len(ids))
self.s.flush() self.s.flush()
# fix problems with cards being scheduled when not due # fix problems with cards being scheduled when not due
self.updateProgress()
self.s.statement("update cards set isDue = 0") self.s.statement("update cards set isDue = 0")
# fix problems with conflicts on merge # fix problems with conflicts on merge
self.s.statement("update fields set id = random()") self.s.statement("update fields set id = random()")
@ -1694,8 +1716,10 @@ select id from fields where factId not in (select id from facts)""")
"update cardModels set allowEmptyAnswer = 1, typeAnswer = 0 " "update cardModels set allowEmptyAnswer = 1, typeAnswer = 0 "
"where allowEmptyAnswer is null or typeAnswer is null") "where allowEmptyAnswer is null or typeAnswer is null")
# fix any priorities # fix any priorities
self.updateProgress(_("Updating priorities..."))
self.updateAllPriorities() self.updateAllPriorities()
# fix problems with stripping html # fix problems with stripping html
self.updateProgress(_("Rebuilding QA cache..."))
fields = self.s.all("select id, value from fields") fields = self.s.all("select id, value from fields")
newFields = [] newFields = []
for (id, value) in fields: for (id, value) in fields:
@ -1712,14 +1736,18 @@ select id from fields where factId not in (select id from facts)""")
self.s.statement("update facts set modified = :t", t=time.time()) self.s.statement("update facts set modified = :t", t=time.time())
self.s.statement("update models set modified = :t", t=time.time()) self.s.statement("update models set modified = :t", t=time.time())
self.lastSync = 0 self.lastSync = 0
# update counts # rebuild
self.updateProgress(_("Rebuilding types..."))
self.rebuildTypes()
self.updateProgress(_("Rebuilding counts..."))
self.rebuildCounts() self.rebuildCounts()
# update deck and save # update deck and save
self.flushMod() self.flushMod()
self.save() self.save()
self.refresh() self.refresh()
self.rebuildTypes() self.updateProgress(_("Rebuilding queue..."))
self.rebuildQueue() self.rebuildQueue()
self.finishProgress()
if problems: if problems:
return "\n".join(problems) return "\n".join(problems)
return "ok" return "ok"

View file

@ -119,7 +119,9 @@ def rebuildMediaDir(deck, deleteRefs=False, dirty=True):
unusedFileCount = 0 unusedFileCount = 0
missingFileCount = 0 missingFileCount = 0
deck.mediaDir(create=True) deck.mediaDir(create=True)
deck.startProgress(_("Check Media DB"), 0, 6)
# rename all files to checksum versions, note non-renamed ones # rename all files to checksum versions, note non-renamed ones
deck.updateProgress(_("Checksum files..."))
for oldBase in os.listdir(unicode(deck.mediaDir())): for oldBase in os.listdir(unicode(deck.mediaDir())):
oldPath = os.path.join(deck.mediaDir(), oldBase) oldPath = os.path.join(deck.mediaDir(), oldBase)
if oldBase.startswith("."): if oldBase.startswith("."):
@ -132,6 +134,7 @@ def rebuildMediaDir(deck, deleteRefs=False, dirty=True):
else: else:
renamedFiles[oldBase] = newBase renamedFiles[oldBase] = newBase
# now look through all fields, and update references to files # now look through all fields, and update references to files
deck.updateProgress(_("Scan fields..."))
for (id, fid, val) in deck.s.all( for (id, fid, val) in deck.s.all(
"select id, factId, value from fields"): "select id, factId, value from fields"):
oldval = val oldval = val
@ -158,16 +161,22 @@ def rebuildMediaDir(deck, deleteRefs=False, dirty=True):
if fid not in factsMissingMedia: if fid not in factsMissingMedia:
unmodifiedFacts[fid] = 1 unmodifiedFacts[fid] = 1
# update modified fields # update modified fields
deck.updateProgress(_("Modify fields..."))
if modifiedFacts: if modifiedFacts:
_modifyFields(deck, updateFields, modifiedFacts, dirty) _modifyFields(deck, updateFields, modifiedFacts, dirty)
# fix tags # fix tags
deck.updateProgress(_("Update tags..."))
if dirty: if dirty:
t = time.time()
if deleteRefs: if deleteRefs:
deck.deleteTags(modifiedFacts.keys(), _("Media Missing")) deck.deleteTags(modifiedFacts.keys(), _("Media Missing"))
else: else:
deck.addTags(factsMissingMedia.keys(), _("Media Missing")) deck.addTags(factsMissingMedia.keys(), _("Media Missing"))
print time.time() - t; t = time.time()
deck.deleteTags(unmodifiedFacts.keys(), _("Media Missing")) deck.deleteTags(unmodifiedFacts.keys(), _("Media Missing"))
print time.time() - t; t = time.time()
# build cache of db records # build cache of db records
deck.updateProgress(_("Delete unused files..."))
mediaIds = dict(deck.s.all("select filename, id from media")) mediaIds = dict(deck.s.all("select filename, id from media"))
# assume latex files exist # assume latex files exist
for f in deck.s.column0( for f in deck.s.column0(
@ -186,6 +195,7 @@ def rebuildMediaDir(deck, deleteRefs=False, dirty=True):
else: else:
os.unlink(path) os.unlink(path)
unusedFileCount += 1 unusedFileCount += 1
deck.updateProgress(_("Delete stale references..."))
for (fname, id) in mediaIds.items(): for (fname, id) in mediaIds.items():
# maybe delete from db # maybe delete from db
if id: if id:
@ -196,6 +206,7 @@ values (:id, strftime('%s', 'now'))""", id=id)
# update deck and save # update deck and save
deck.flushMod() deck.flushMod()
deck.save() deck.save()
deck.finishProgress()
return missingFileCount, unusedFileCount return missingFileCount, unusedFileCount
def mediaRefs(string): def mediaRefs(string):