drop usage of pysqlite Cursor

This commit is contained in:
Damien Elmes 2020-03-03 10:39:58 +10:00
parent 0b1d96fce0
commit b5c6134d80
2 changed files with 50 additions and 36 deletions

View File

@ -4,9 +4,8 @@
# fixme: lossy utf8 handling # fixme: lossy utf8 handling
# fixme: progress # fixme: progress
from sqlite3 import Cursor
from sqlite3 import dbapi2 as sqlite from sqlite3 import dbapi2 as sqlite
from typing import Any, Iterable, List from typing import Any, Iterable, List, Optional
class DBProxy: class DBProxy:
@ -39,24 +38,51 @@ class DBProxy:
# Querying # Querying
################ ################
def all(self, sql: str, *args) -> List: def _query(self, sql: str, *args, first_row_only: bool = False) -> List[List]:
return self.execute(sql, *args).fetchall() # mark modified?
s = sql.strip().lower()
for stmt in "insert", "update", "delete":
if s.startswith(stmt):
self.mod = True
# fetch rows
curs = self._db.execute(sql, args)
if first_row_only:
row = curs.fetchone()
curs.close()
if row is not None:
return [row]
else:
return []
else:
return curs.fetchall()
def first(self, sql: str, *args) -> Any: # Query shortcuts
c = self.execute(sql, *args) ###################
res = c.fetchone()
c.close() def all(self, sql: str, *args) -> List:
return res return self._query(sql, *args)
def list(self, sql: str, *args) -> List: def list(self, sql: str, *args) -> List:
return [x[0] for x in self.execute(sql, *args)] return [x[0] for x in self._query(sql, *args)]
def scalar(self, sql: str, *args) -> Any: def first(self, sql: str, *args) -> Optional[List]:
res = self.execute(sql, *args).fetchone() rows = self._query(sql, *args, first_row_only=True)
if res: if rows:
return res[0] return rows[0]
else:
return None return None
def scalar(self, sql: str, *args) -> Optional[Any]:
rows = self._query(sql, *args, first_row_only=True)
if rows:
return rows[0][0]
else:
return None
# execute used to return a pysqlite cursor, but now is synonymous
# with .all()
execute = all
# Updates # Updates
################ ################
@ -67,15 +93,3 @@ class DBProxy:
def executescript(self, sql: str) -> None: def executescript(self, sql: str) -> None:
self.mod = True self.mod = True
self._db.executescript(sql) self._db.executescript(sql)
# Cursor API
###############
def execute(self, sql: str, *args) -> Cursor:
s = sql.strip().lower()
# mark modified?
for stmt in "insert", "update", "delete":
if s.startswith(stmt):
self.mod = True
res = self._db.execute(sql, args)
return res

View File

@ -8,7 +8,6 @@ import io
import json import json
import os import os
import random import random
import sqlite3
from typing import Any, Dict, List, Optional, Tuple, Union from typing import Any, Dict, List, Optional, Tuple, Union
import anki import anki
@ -32,7 +31,7 @@ class UnexpectedSchemaChange(Exception):
class Syncer: class Syncer:
cursor: Optional[sqlite3.Cursor] chunkRows: Optional[List[List]]
def __init__(self, col: anki.storage._Collection, server=None) -> None: def __init__(self, col: anki.storage._Collection, server=None) -> None:
self.col = col.weakref() self.col = col.weakref()
@ -247,11 +246,11 @@ class Syncer:
def prepareToChunk(self) -> None: def prepareToChunk(self) -> None:
self.tablesLeft = ["revlog", "cards", "notes"] self.tablesLeft = ["revlog", "cards", "notes"]
self.cursor = None self.chunkRows = None
def cursorForTable(self, table) -> sqlite3.Cursor: def getChunkRows(self, table) -> List[List]:
lim = self.usnLim() lim = self.usnLim()
x = self.col.db.execute x = self.col.db.all
d = (self.maxUsn, lim) d = (self.maxUsn, lim)
if table == "revlog": if table == "revlog":
return x( return x(
@ -280,14 +279,15 @@ from notes where %s"""
lim = 250 lim = 250
while self.tablesLeft and lim: while self.tablesLeft and lim:
curTable = self.tablesLeft[0] curTable = self.tablesLeft[0]
if not self.cursor: if not self.chunkRows:
self.cursor = self.cursorForTable(curTable) self.chunkRows = self.getChunkRows(curTable)
rows = self.cursor.fetchmany(lim) rows = self.chunkRows[:lim]
self.chunkRows = self.chunkRows[lim:]
fetched = len(rows) fetched = len(rows)
if fetched != lim: if fetched != lim:
# table is empty # table is empty
self.tablesLeft.pop(0) self.tablesLeft.pop(0)
self.cursor = None self.chunkRows = None
# mark the objects as having been sent # mark the objects as having been sent
self.col.db.execute( self.col.db.execute(
"update %s set usn=? where usn=-1" % curTable, self.maxUsn "update %s set usn=? where usn=-1" % curTable, self.maxUsn