new decks now default to in-memory storage until saveas

- undo needs fixing
- media support needs to be changed to work with in-memory db
This commit is contained in:
Damien Elmes 2009-01-04 07:13:30 +09:00
parent 4a22f5b6e7
commit c973c1eb4f
2 changed files with 46 additions and 71 deletions

View file

@ -1408,7 +1408,7 @@ Return new path, relative to media dir."""
self.s.rollback() self.s.rollback()
self.s.clear() self.s.clear()
self.s.close() self.s.close()
self.engine.execute("delete from undoLog") #self.engine.execute("delete from undoLog")
self.engine.execute("vacuum") self.engine.execute("vacuum")
self.engine.dispose() self.engine.dispose()
@ -1452,40 +1452,38 @@ Return new path, relative to media dir."""
def saveAs(self, newPath): def saveAs(self, newPath):
oldMediaDir = self.mediaDir() oldMediaDir = self.mediaDir()
# flush old deck
self.s.flush() self.s.flush()
# remove new deck if it exists # remove new deck if it exists
try: try:
os.unlink(newPath) os.unlink(newPath)
except OSError: except OSError:
pass pass
# create new deck # setup new db tables, then close
newDeck = DeckStorage.Deck(newPath) newDeck = DeckStorage.Deck(newPath)
# attach current db to new newDeck.close()
s = newDeck.s.statement # attach new db and copy everything in
s("pragma read_uncommitted = 1") s = self.s.statement
s("attach database :path as old", path=self.path) s("attach database :path as new", path=newPath)
# copy all data s("delete from new.decks")
s("delete from decks") s("delete from new.stats")
s("delete from stats") s("insert into new.decks select * from decks")
s("insert into decks select * from old.decks") s("insert into new.fieldModels select * from fieldModels")
s("insert into fieldModels select * from old.fieldModels") s("insert into new.modelsDeleted select * from modelsDeleted")
s("insert into modelsDeleted select * from old.modelsDeleted") s("insert into new.cardModels select * from cardModels")
s("insert into cardModels select * from old.cardModels") s("insert into new.facts select * from facts")
s("insert into facts select * from old.facts") s("insert into new.fields select * from fields")
s("insert into fields select * from old.fields") s("insert into new.cards select * from cards")
s("insert into cards select * from old.cards") s("insert into new.factsDeleted select * from factsDeleted")
s("insert into factsDeleted select * from old.factsDeleted") s("insert into new.reviewHistory select * from reviewHistory")
s("insert into reviewHistory select * from old.reviewHistory") s("insert into new.cardsDeleted select * from cardsDeleted")
s("insert into cardsDeleted select * from old.cardsDeleted") s("insert into new.models select * from models")
s("insert into models select * from old.models") s("insert into new.stats select * from stats")
s("insert into stats select * from old.stats") s("detach database new")
# detach old db and commit # close ourselves
s("detach database old") self.s.commit()
self.close() self.close()
newDeck.s.commit() # open new db
newDeck.refresh() newDeck = DeckStorage.Deck(newPath)
newDeck.rebuildQueue()
# move media # move media
if oldMediaDir: if oldMediaDir:
newDeck.renameMediaDir(oldMediaDir) newDeck.renameMediaDir(oldMediaDir)
@ -1756,52 +1754,27 @@ mapper(Deck, decksTable, properties={
########################################################################## ##########################################################################
numBackups = 30 numBackups = 30
backupDir = os.path.expanduser("~/.anki/backups")
# anki dir
if sys.platform.startswith("darwin"):
ankiDir = os.path.expanduser("~/Library/Application Support/Anki")
else:
ankiDir = os.path.expanduser("~/.anki/")
newDeckDir = ankiDir
if not os.path.exists(ankiDir):
os.makedirs(ankiDir)
# backup
backupDir = os.path.join(ankiDir, "backups")
if not os.path.exists(backupDir):
os.makedirs(backupDir)
class DeckStorage(object): class DeckStorage(object):
def newDeckPath():
n = 2
path = os.path.expanduser(
os.path.join(newDeckDir, "mydeck.anki"))
while os.path.exists(path):
path = os.path.expanduser(
os.path.join(newDeckDir, "mydeck%d.anki") % n)
n += 1
return path
newDeckPath = staticmethod(newDeckPath)
def Deck(path=None, backup=True, lock=True): def Deck(path=None, backup=True, lock=True):
"Create a new deck or attach to an existing one." "Create a new deck or attach to an existing one."
# generate a temp name if necessary
if path is None:
path = DeckStorage.newDeckPath()
create = True create = True
if path != -1: if path is None:
sqlpath = None
else:
# ensure unicode & abspath
if isinstance(path, types.UnicodeType): if isinstance(path, types.UnicodeType):
path = path.encode(sys.getfilesystemencoding()) path = path.encode(sys.getfilesystemencoding())
path = os.path.abspath(path) path = os.path.abspath(path)
#print "using path", path # check if we need to init
if os.path.exists(path): if os.path.exists(path):
create = False create = False
# attach and sync/fetch deck - first, to unicode
if not isinstance(path, types.UnicodeType):
path = unicode(path, sys.getfilesystemencoding())
try:
# sqlite needs utf8 # sqlite needs utf8
(engine, session) = DeckStorage._attach(path.encode("utf-8"), create) sqlpath = path.encode("utf-8")
try:
(engine, session) = DeckStorage._attach(sqlpath, create)
s = session() s = session()
metadata.create_all(engine) metadata.create_all(engine)
if create: if create:
@ -1886,8 +1859,8 @@ alter table cardModels add column allowEmptyAnswer boolean not null default 1"""
def _attach(path, create): def _attach(path, create):
"Attach to a file, initializing DB" "Attach to a file, initializing DB"
if path == -1: if path is None:
path = "sqlite:///:memory:" path = "sqlite://"
else: else:
path = "sqlite:///" + path path = "sqlite:///" + path
engine = create_engine(path, engine = create_engine(path,
@ -2200,6 +2173,10 @@ where interval < 1""")
_setUTCOffset = staticmethod(_setUTCOffset) _setUTCOffset = staticmethod(_setUTCOffset)
def backup(modified, path): def backup(modified, path):
try:
os.makedirs(backupDir)
except OSError:
pass
# need a non-unicode path # need a non-unicode path
path = path.encode(sys.getfilesystemencoding()) path = path.encode(sys.getfilesystemencoding())
bdir = backupDir.encode(sys.getfilesystemencoding()) bdir = backupDir.encode(sys.getfilesystemencoding())

View file

@ -16,26 +16,24 @@ newModified = None
def test_new(): def test_new():
deck = DeckStorage.Deck() deck = DeckStorage.Deck()
assert deck.path assert not deck.path
assert deck.engine assert deck.engine
assert deck.modified assert deck.modified
# for attachOld()
global newPath, newModified
newPath = deck.path
deck.save()
newModified = deck.modified
deck.close()
def test_attachNew(): def test_attachNew():
global newPath, newModified
path = "/tmp/test_attachNew" path = "/tmp/test_attachNew"
try: try:
os.unlink(path) os.unlink(path)
except OSError: except OSError:
pass pass
deck = DeckStorage.Deck(path) deck = DeckStorage.Deck(path)
# for attachOld()
newPath = deck.path
deck.save()
newModified = deck.modified
deck.close() deck.close()
del deck del deck
os.unlink(path)
def test_attachOld(): def test_attachOld():
deck = DeckStorage.Deck(newPath) deck = DeckStorage.Deck(newPath)