drop named sql arguments

This commit is contained in:
Damien Elmes 2020-03-02 20:50:17 +10:00
parent c8b9afac0c
commit f4d4078537
7 changed files with 53 additions and 68 deletions

View file

@ -2,8 +2,8 @@
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
# fixme: lossy utf8 handling
# fixme: progress
import os
import time
from sqlite3 import Cursor
from sqlite3 import dbapi2 as sqlite
@ -16,19 +16,13 @@ class DBProxy:
self._path = path
self.mod = False
def execute(self, sql: str, *a, **ka) -> Cursor:
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
t = time.time()
if ka:
# execute("...where id = :id", id=5)
res = self._db.execute(sql, ka)
else:
# execute("...where id = ?", 5)
res = self._db.execute(sql, a)
res = self._db.execute(sql, args)
return res
def executemany(self, sql: str, l: Any) -> None:
@ -47,26 +41,25 @@ class DBProxy:
def rollback(self) -> None:
self._db.rollback()
def scalar(self, *a, **kw) -> Any:
res = self.execute(*a, **kw).fetchone()
def scalar(self, sql: str, *args) -> Any:
res = self.execute(sql, *args).fetchone()
if res:
return res[0]
return None
def all(self, *a, **kw) -> List:
return self.execute(*a, **kw).fetchall()
def all(self, sql: str, *args) -> List:
return self.execute(sql, *args).fetchall()
def first(self, *a, **kw) -> Any:
c = self.execute(*a, **kw)
def first(self, sql: str, *args) -> Any:
c = self.execute(sql, *args)
res = c.fetchone()
c.close()
return res
def list(self, *a, **kw) -> List:
return [x[0] for x in self.execute(*a, **kw)]
def list(self, sql: str, *args) -> List:
return [x[0] for x in self.execute(sql, *args)]
def close(self) -> None:
self._db.text_factory = None
self._db.close()
def __enter__(self) -> "DBProxy":
@ -79,9 +72,6 @@ class DBProxy:
def totalChanges(self) -> Any:
return self._db.total_changes
def interrupt(self) -> None:
self._db.interrupt()
def setAutocommit(self, autocommit: bool) -> None:
if autocommit:
self._db.isolation_level = None

View file

@ -286,10 +286,10 @@ and due <= ? limit %d"""
self._lrnQueue = self.col.db.all(
f"""
select due, id from cards where
did in %s and queue = {QUEUE_TYPE_LRN} and due < :lim
did in %s and queue = {QUEUE_TYPE_LRN} and due < ?
limit %d"""
% (self._deckLimit(), self.reportLimit),
lim=self.dayCutoff,
self.dayCutoff,
)
# as it arrives sorted by did first, we need to sort it
self._lrnQueue.sort()

View file

@ -545,10 +545,10 @@ select count() from cards where did in %s and queue = {QUEUE_TYPE_PREVIEW}
self._lrnQueue = self.col.db.all(
f"""
select due, id from cards where
did in %s and queue in ({QUEUE_TYPE_LRN},{QUEUE_TYPE_PREVIEW}) and due < :lim
did in %s and queue in ({QUEUE_TYPE_LRN},{QUEUE_TYPE_PREVIEW}) and due < ?
limit %d"""
% (self._deckLimit(), self.reportLimit),
lim=cutoff,
cutoff,
)
# as it arrives sorted by did first, we need to sort it
self._lrnQueue.sort()

View file

@ -58,7 +58,7 @@ class CardStats:
self.addLine(_("Reviews"), "%d" % c.reps)
self.addLine(_("Lapses"), "%d" % c.lapses)
(cnt, total) = self.col.db.first(
"select count(), sum(time)/1000 from revlog where cid = :id", id=c.id
"select count(), sum(time)/1000 from revlog where cid = ?", c.id
)
if cnt:
self.addLine(_("Average Time"), self.time(total / float(cnt)))
@ -297,12 +297,12 @@ and due = ?"""
) -> Any:
lim = ""
if start is not None:
lim += " and due-:today >= %d" % start
lim += " and due-%d >= %d" % (self.col.sched.today, start)
if end is not None:
lim += " and day < %d" % end
return self.col.db.all(
f"""
select (due-:today)/:chunk as day,
select (due-?)/? as day,
sum(case when ivl < 21 then 1 else 0 end), -- yng
sum(case when ivl >= 21 then 1 else 0 end) -- mtr
from cards
@ -310,8 +310,8 @@ where did in %s and queue in ({QUEUE_TYPE_REV},{QUEUE_TYPE_DAY_LEARN_RELEARN})
%s
group by day order by day"""
% (self._limit(), lim),
today=self.col.sched.today,
chunk=chunk,
self.col.sched.today,
chunk,
)
# Added, reps and time spent
@ -527,14 +527,13 @@ group by day order by day"""
return self.col.db.all(
"""
select
(cast((id/1000.0 - :cut) / 86400.0 as int))/:chunk as day,
(cast((id/1000.0 - ?) / 86400.0 as int))/? as day,
count(id)
from cards %s
group by day order by day"""
% lim,
cut=self.col.sched.dayCutoff,
tf=tf,
chunk=chunk,
self.col.sched.dayCutoff,
chunk,
)
def _done(self, num: Optional[int] = 7, chunk: int = 1) -> Any:
@ -557,24 +556,28 @@ group by day order by day"""
return self.col.db.all(
f"""
select
(cast((id/1000.0 - :cut) / 86400.0 as int))/:chunk as day,
(cast((id/1000.0 - ?) / 86400.0 as int))/? as day,
sum(case when type = {REVLOG_LRN} then 1 else 0 end), -- lrn count
sum(case when type = {REVLOG_REV} and lastIvl < 21 then 1 else 0 end), -- yng count
sum(case when type = {REVLOG_REV} and lastIvl >= 21 then 1 else 0 end), -- mtr count
sum(case when type = {REVLOG_RELRN} then 1 else 0 end), -- lapse count
sum(case when type = {REVLOG_CRAM} then 1 else 0 end), -- cram count
sum(case when type = {REVLOG_LRN} then time/1000.0 else 0 end)/:tf, -- lrn time
sum(case when type = {REVLOG_LRN} then time/1000.0 else 0 end)/?, -- lrn time
-- yng + mtr time
sum(case when type = {REVLOG_REV} and lastIvl < 21 then time/1000.0 else 0 end)/:tf,
sum(case when type = {REVLOG_REV} and lastIvl >= 21 then time/1000.0 else 0 end)/:tf,
sum(case when type = {REVLOG_RELRN} then time/1000.0 else 0 end)/:tf, -- lapse time
sum(case when type = {REVLOG_CRAM} then time/1000.0 else 0 end)/:tf -- cram time
sum(case when type = {REVLOG_REV} and lastIvl < 21 then time/1000.0 else 0 end)/?,
sum(case when type = {REVLOG_REV} and lastIvl >= 21 then time/1000.0 else 0 end)/?,
sum(case when type = {REVLOG_RELRN} then time/1000.0 else 0 end)/?, -- lapse time
sum(case when type = {REVLOG_CRAM} then time/1000.0 else 0 end)/? -- cram time
from revlog %s
group by day order by day"""
% lim,
cut=self.col.sched.dayCutoff,
tf=tf,
chunk=chunk,
self.col.sched.dayCutoff,
chunk,
tf,
tf,
tf,
tf,
tf,
)
def _daysStudied(self) -> Any:
@ -592,11 +595,11 @@ group by day order by day"""
ret = self.col.db.first(
"""
select count(), abs(min(day)) from (select
(cast((id/1000 - :cut) / 86400.0 as int)+1) as day
(cast((id/1000 - ?) / 86400.0 as int)+1) as day
from revlog %s
group by day order by day)"""
% lim,
cut=self.col.sched.dayCutoff,
self.col.sched.dayCutoff,
)
assert ret
return ret
@ -655,12 +658,12 @@ group by day order by day)"""
data = [
self.col.db.all(
f"""
select ivl / :chunk as grp, count() from cards
select ivl / ? as grp, count() from cards
where did in %s and queue = {QUEUE_TYPE_REV} %s
group by grp
order by grp"""
% (self._limit(), lim),
chunk=chunk,
chunk,
)
]
return (
@ -866,14 +869,14 @@ order by thetype, ease"""
return self.col.db.all(
f"""
select
23 - ((cast((:cut - id/1000) / 3600.0 as int)) %% 24) as hour,
23 - ((cast((? - id/1000) / 3600.0 as int)) %% 24) as hour,
sum(case when ease = 1 then 0 else 1 end) /
cast(count() as float) * 100,
count()
from revlog where type in ({REVLOG_LRN},{REVLOG_REV},{REVLOG_RELRN}) %s
group by hour having count() > 30 order by hour"""
% lim,
cut=self.col.sched.dayCutoff - (rolloverHour * 3600),
self.col.sched.dayCutoff - (rolloverHour * 3600),
)
# Cards

View file

@ -110,30 +110,25 @@ class TagManager:
else:
l = "tags "
fn = self.remFromStr
lim = " or ".join([l + "like :_%d" % c for c, t in enumerate(newTags)])
lim = " or ".join(l + "like ?" for x in newTags)
res = self.col.db.all(
"select id, tags from notes where id in %s and (%s)" % (ids2str(ids), lim),
**dict(
[
("_%d" % x, "%% %s %%" % y.replace("*", "%"))
for x, y in enumerate(newTags)
]
),
*["%% %s %%" % y.replace("*", "%") for x, y in enumerate(newTags)],
)
# update tags
nids = []
def fix(row):
nids.append(row[0])
return {
"id": row[0],
"t": fn(tags, row[1]),
"n": intTime(),
"u": self.col.usn(),
}
return [
fn(tags, row[1]),
intTime(),
self.col.usn(),
row[0],
]
self.col.db.executemany(
"update notes set tags=:t,mod=:n,usn=:u where id = :id",
"update notes set tags=?,mod=?,usn=? where id = ?",
[fix(row) for row in res],
)

View file

@ -754,10 +754,7 @@ title="%s" %s>%s</button>""" % (
signal.signal(signal.SIGINT, self.onSigInt)
def onSigInt(self, signum, frame):
# interrupt any current transaction and schedule a rollback & quit
if self.col:
self.col.db.interrupt()
# schedule a rollback & quit
def quit():
self.col.db.rollback()
self.close()

View file

@ -35,7 +35,7 @@ class ProgressManager:
"Install a handler in the current DB."
self.lastDbProgress = 0
self.inDB = False
#db.set_progress_handler(self._dbProgress, 10000)
# db.set_progress_handler(self._dbProgress, 10000)
def _dbProgress(self):
"Called from SQLite."