mirror of
https://github.com/ankitects/anki.git
synced 2025-09-23 16:26:40 -04:00
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:
parent
4a22f5b6e7
commit
c973c1eb4f
2 changed files with 46 additions and 71 deletions
103
anki/deck.py
103
anki/deck.py
|
@ -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())
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue