mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 16:56:36 -04:00
drop lock() and setAutocommit()
We no longer need to worry about pysqlite implicitly beginning transactions, and can be more explicit about beginning/ending transactions save() now also has a trx argument controlling whether a transaction should be started / left open
This commit is contained in:
parent
63e3357068
commit
90de4a267d
5 changed files with 31 additions and 32 deletions
|
@ -219,8 +219,10 @@ crt=?, mod=?, scm=?, dty=?, usn=?, ls=?, conf=?""",
|
|||
json.dumps(self.conf),
|
||||
)
|
||||
|
||||
def save(self, name: Optional[str] = None, mod: Optional[int] = None) -> None:
|
||||
"Flush, commit DB, and take out another write lock."
|
||||
def save(
|
||||
self, name: Optional[str] = None, mod: Optional[int] = None, trx: bool = True
|
||||
) -> None:
|
||||
"Flush, commit DB, and take out another write lock if trx=True."
|
||||
# let the managers conditionally flush
|
||||
self.models.flush()
|
||||
self.decks.flush()
|
||||
|
@ -229,8 +231,14 @@ crt=?, mod=?, scm=?, dty=?, usn=?, ls=?, conf=?""",
|
|||
if self.db.mod:
|
||||
self.flush(mod=mod)
|
||||
self.db.commit()
|
||||
self.lock()
|
||||
self.db.mod = False
|
||||
if trx:
|
||||
self.db.begin()
|
||||
elif not trx:
|
||||
# if no changes were pending but calling code expects to be
|
||||
# outside of a transaction, we need to roll back
|
||||
self.db.rollback()
|
||||
|
||||
self._markOp(name)
|
||||
self._lastSave = time.time()
|
||||
|
||||
|
@ -241,20 +249,13 @@ crt=?, mod=?, scm=?, dty=?, usn=?, ls=?, conf=?""",
|
|||
return True
|
||||
return None
|
||||
|
||||
def lock(self) -> None:
|
||||
self.db.begin()
|
||||
|
||||
def close(self, save: bool = True) -> None:
|
||||
"Disconnect from DB."
|
||||
if self.db:
|
||||
if save:
|
||||
self.save()
|
||||
else:
|
||||
self.db.rollback()
|
||||
self.save(trx=False)
|
||||
if not self.server:
|
||||
self.db.setAutocommit(True)
|
||||
self.db.execute("pragma journal_mode = delete")
|
||||
self.db.setAutocommit(False)
|
||||
self.db.close()
|
||||
self.db = None
|
||||
self.backend = None
|
||||
|
@ -271,8 +272,8 @@ crt=?, mod=?, scm=?, dty=?, usn=?, ls=?, conf=?""",
|
|||
|
||||
def rollback(self) -> None:
|
||||
self.db.rollback()
|
||||
self.db.begin()
|
||||
self.load()
|
||||
self.lock()
|
||||
|
||||
def modSchema(self, check: bool) -> None:
|
||||
"Mark schema modified. Call this first so user can abort if necessary."
|
||||
|
@ -303,10 +304,10 @@ crt=?, mod=?, scm=?, dty=?, usn=?, ls=?, conf=?""",
|
|||
self.modSchema(check=False)
|
||||
self.ls = self.scm
|
||||
# ensure db is compacted before upload
|
||||
self.db.setAutocommit(True)
|
||||
self.save(trx=False)
|
||||
self.db.execute("vacuum")
|
||||
self.db.execute("analyze")
|
||||
self.close()
|
||||
self.close(save=False)
|
||||
|
||||
# Object creation helpers
|
||||
##########################################################################
|
||||
|
@ -1012,11 +1013,10 @@ and type=0""",
|
|||
return len(to_fix)
|
||||
|
||||
def optimize(self) -> None:
|
||||
self.db.setAutocommit(True)
|
||||
self.save(trx=False)
|
||||
self.db.execute("vacuum")
|
||||
self.db.execute("analyze")
|
||||
self.db.setAutocommit(False)
|
||||
self.lock()
|
||||
self.db.begin()
|
||||
|
||||
# Logging
|
||||
##########################################################################
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
# Copyright: Ankitects Pty Ltd and contributors
|
||||
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
"""
|
||||
A convenience wrapper over pysqlite.
|
||||
|
||||
Anki's Collection class now uses dbproxy.py instead of this class,
|
||||
but this class is still used by aqt's profile manager, and a number
|
||||
of add-ons rely on it.
|
||||
"""
|
||||
|
||||
import os
|
||||
import time
|
||||
from sqlite3 import Cursor
|
||||
|
|
|
@ -7,8 +7,8 @@ from typing import Any, Iterable, List, Optional, Sequence, Union
|
|||
|
||||
import anki
|
||||
|
||||
# fixme: threads
|
||||
# fixme: col.reopen()
|
||||
# fixme: col.close()/col.reopen() & journal_mode=delete
|
||||
|
||||
# fixme: setAutocommit()
|
||||
# fixme: transaction/lock handling
|
||||
# fixme: progress
|
||||
|
@ -47,12 +47,6 @@ class DBProxy:
|
|||
def rollback(self) -> None:
|
||||
self._backend.db_rollback()
|
||||
|
||||
def setAutocommit(self, autocommit: bool) -> None:
|
||||
if autocommit:
|
||||
self.commit()
|
||||
else:
|
||||
self.begin()
|
||||
|
||||
# Querying
|
||||
################
|
||||
|
||||
|
|
|
@ -65,10 +65,7 @@ class Anki2Importer(Importer):
|
|||
self._importCards()
|
||||
self._importStaticMedia()
|
||||
self._postImport()
|
||||
self.dst.db.setAutocommit(True)
|
||||
self.dst.db.execute("vacuum")
|
||||
self.dst.db.execute("analyze")
|
||||
self.dst.db.setAutocommit(False)
|
||||
self.dst.optimize()
|
||||
|
||||
# Notes
|
||||
######################################################################
|
||||
|
|
|
@ -40,15 +40,12 @@ def Collection(path: str, server: Optional[ServerData] = None) -> _Collection:
|
|||
path, media_dir, media_db, log_path, server=server is not None
|
||||
)
|
||||
db = DBProxy(weakref.proxy(backend), path)
|
||||
db.begin()
|
||||
db.setAutocommit(True)
|
||||
|
||||
# initial setup required?
|
||||
create = db.scalar("select models = '{}' from col")
|
||||
if create:
|
||||
initial_db_setup(db)
|
||||
|
||||
db.setAutocommit(False)
|
||||
# add db to col and do any remaining upgrades
|
||||
col = _Collection(db, backend=backend, server=server)
|
||||
if create:
|
||||
|
@ -59,6 +56,8 @@ def Collection(path: str, server: Optional[ServerData] = None) -> _Collection:
|
|||
addForwardReverse(col)
|
||||
addBasicModel(col)
|
||||
col.save()
|
||||
else:
|
||||
db.begin()
|
||||
return col
|
||||
|
||||
|
||||
|
@ -67,6 +66,7 @@ def Collection(path: str, server: Optional[ServerData] = None) -> _Collection:
|
|||
|
||||
|
||||
def initial_db_setup(db: DBProxy) -> None:
|
||||
db.begin()
|
||||
_addColVars(db, *_getColVars(db))
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue