mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 08:46:37 -04:00
drop named sql arguments
This commit is contained in:
parent
c8b9afac0c
commit
f4d4078537
7 changed files with 53 additions and 68 deletions
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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],
|
||||
)
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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."
|
||||
|
|
Loading…
Reference in a new issue