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
|
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
# fixme: lossy utf8 handling
|
# fixme: lossy utf8 handling
|
||||||
|
# fixme: progress
|
||||||
|
|
||||||
import os
|
|
||||||
import time
|
import time
|
||||||
from sqlite3 import Cursor
|
from sqlite3 import Cursor
|
||||||
from sqlite3 import dbapi2 as sqlite
|
from sqlite3 import dbapi2 as sqlite
|
||||||
|
@ -16,19 +16,13 @@ class DBProxy:
|
||||||
self._path = path
|
self._path = path
|
||||||
self.mod = False
|
self.mod = False
|
||||||
|
|
||||||
def execute(self, sql: str, *a, **ka) -> Cursor:
|
def execute(self, sql: str, *args) -> Cursor:
|
||||||
s = sql.strip().lower()
|
s = sql.strip().lower()
|
||||||
# mark modified?
|
# mark modified?
|
||||||
for stmt in "insert", "update", "delete":
|
for stmt in "insert", "update", "delete":
|
||||||
if s.startswith(stmt):
|
if s.startswith(stmt):
|
||||||
self.mod = True
|
self.mod = True
|
||||||
t = time.time()
|
res = self._db.execute(sql, args)
|
||||||
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)
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def executemany(self, sql: str, l: Any) -> None:
|
def executemany(self, sql: str, l: Any) -> None:
|
||||||
|
@ -47,26 +41,25 @@ class DBProxy:
|
||||||
def rollback(self) -> None:
|
def rollback(self) -> None:
|
||||||
self._db.rollback()
|
self._db.rollback()
|
||||||
|
|
||||||
def scalar(self, *a, **kw) -> Any:
|
def scalar(self, sql: str, *args) -> Any:
|
||||||
res = self.execute(*a, **kw).fetchone()
|
res = self.execute(sql, *args).fetchone()
|
||||||
if res:
|
if res:
|
||||||
return res[0]
|
return res[0]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def all(self, *a, **kw) -> List:
|
def all(self, sql: str, *args) -> List:
|
||||||
return self.execute(*a, **kw).fetchall()
|
return self.execute(sql, *args).fetchall()
|
||||||
|
|
||||||
def first(self, *a, **kw) -> Any:
|
def first(self, sql: str, *args) -> Any:
|
||||||
c = self.execute(*a, **kw)
|
c = self.execute(sql, *args)
|
||||||
res = c.fetchone()
|
res = c.fetchone()
|
||||||
c.close()
|
c.close()
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def list(self, *a, **kw) -> List:
|
def list(self, sql: str, *args) -> List:
|
||||||
return [x[0] for x in self.execute(*a, **kw)]
|
return [x[0] for x in self.execute(sql, *args)]
|
||||||
|
|
||||||
def close(self) -> None:
|
def close(self) -> None:
|
||||||
self._db.text_factory = None
|
|
||||||
self._db.close()
|
self._db.close()
|
||||||
|
|
||||||
def __enter__(self) -> "DBProxy":
|
def __enter__(self) -> "DBProxy":
|
||||||
|
@ -79,9 +72,6 @@ class DBProxy:
|
||||||
def totalChanges(self) -> Any:
|
def totalChanges(self) -> Any:
|
||||||
return self._db.total_changes
|
return self._db.total_changes
|
||||||
|
|
||||||
def interrupt(self) -> None:
|
|
||||||
self._db.interrupt()
|
|
||||||
|
|
||||||
def setAutocommit(self, autocommit: bool) -> None:
|
def setAutocommit(self, autocommit: bool) -> None:
|
||||||
if autocommit:
|
if autocommit:
|
||||||
self._db.isolation_level = None
|
self._db.isolation_level = None
|
||||||
|
|
|
@ -286,10 +286,10 @@ and due <= ? limit %d"""
|
||||||
self._lrnQueue = self.col.db.all(
|
self._lrnQueue = self.col.db.all(
|
||||||
f"""
|
f"""
|
||||||
select due, id from cards where
|
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"""
|
limit %d"""
|
||||||
% (self._deckLimit(), self.reportLimit),
|
% (self._deckLimit(), self.reportLimit),
|
||||||
lim=self.dayCutoff,
|
self.dayCutoff,
|
||||||
)
|
)
|
||||||
# as it arrives sorted by did first, we need to sort it
|
# as it arrives sorted by did first, we need to sort it
|
||||||
self._lrnQueue.sort()
|
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(
|
self._lrnQueue = self.col.db.all(
|
||||||
f"""
|
f"""
|
||||||
select due, id from cards where
|
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"""
|
limit %d"""
|
||||||
% (self._deckLimit(), self.reportLimit),
|
% (self._deckLimit(), self.reportLimit),
|
||||||
lim=cutoff,
|
cutoff,
|
||||||
)
|
)
|
||||||
# as it arrives sorted by did first, we need to sort it
|
# as it arrives sorted by did first, we need to sort it
|
||||||
self._lrnQueue.sort()
|
self._lrnQueue.sort()
|
||||||
|
|
|
@ -58,7 +58,7 @@ class CardStats:
|
||||||
self.addLine(_("Reviews"), "%d" % c.reps)
|
self.addLine(_("Reviews"), "%d" % c.reps)
|
||||||
self.addLine(_("Lapses"), "%d" % c.lapses)
|
self.addLine(_("Lapses"), "%d" % c.lapses)
|
||||||
(cnt, total) = self.col.db.first(
|
(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:
|
if cnt:
|
||||||
self.addLine(_("Average Time"), self.time(total / float(cnt)))
|
self.addLine(_("Average Time"), self.time(total / float(cnt)))
|
||||||
|
@ -297,12 +297,12 @@ and due = ?"""
|
||||||
) -> Any:
|
) -> Any:
|
||||||
lim = ""
|
lim = ""
|
||||||
if start is not None:
|
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:
|
if end is not None:
|
||||||
lim += " and day < %d" % end
|
lim += " and day < %d" % end
|
||||||
return self.col.db.all(
|
return self.col.db.all(
|
||||||
f"""
|
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), -- yng
|
||||||
sum(case when ivl >= 21 then 1 else 0 end) -- mtr
|
sum(case when ivl >= 21 then 1 else 0 end) -- mtr
|
||||||
from cards
|
from cards
|
||||||
|
@ -310,8 +310,8 @@ where did in %s and queue in ({QUEUE_TYPE_REV},{QUEUE_TYPE_DAY_LEARN_RELEARN})
|
||||||
%s
|
%s
|
||||||
group by day order by day"""
|
group by day order by day"""
|
||||||
% (self._limit(), lim),
|
% (self._limit(), lim),
|
||||||
today=self.col.sched.today,
|
self.col.sched.today,
|
||||||
chunk=chunk,
|
chunk,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Added, reps and time spent
|
# Added, reps and time spent
|
||||||
|
@ -527,14 +527,13 @@ group by day order by day"""
|
||||||
return self.col.db.all(
|
return self.col.db.all(
|
||||||
"""
|
"""
|
||||||
select
|
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)
|
count(id)
|
||||||
from cards %s
|
from cards %s
|
||||||
group by day order by day"""
|
group by day order by day"""
|
||||||
% lim,
|
% lim,
|
||||||
cut=self.col.sched.dayCutoff,
|
self.col.sched.dayCutoff,
|
||||||
tf=tf,
|
chunk,
|
||||||
chunk=chunk,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def _done(self, num: Optional[int] = 7, chunk: int = 1) -> Any:
|
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(
|
return self.col.db.all(
|
||||||
f"""
|
f"""
|
||||||
select
|
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_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), -- yng count
|
||||||
sum(case when type = {REVLOG_REV} and lastIvl >= 21 then 1 else 0 end), -- mtr 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_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_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
|
-- 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)/?,
|
||||||
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)/?,
|
||||||
sum(case when type = {REVLOG_RELRN} then time/1000.0 else 0 end)/:tf, -- lapse time
|
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)/:tf -- cram time
|
sum(case when type = {REVLOG_CRAM} then time/1000.0 else 0 end)/? -- cram time
|
||||||
from revlog %s
|
from revlog %s
|
||||||
group by day order by day"""
|
group by day order by day"""
|
||||||
% lim,
|
% lim,
|
||||||
cut=self.col.sched.dayCutoff,
|
self.col.sched.dayCutoff,
|
||||||
tf=tf,
|
chunk,
|
||||||
chunk=chunk,
|
tf,
|
||||||
|
tf,
|
||||||
|
tf,
|
||||||
|
tf,
|
||||||
|
tf,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _daysStudied(self) -> Any:
|
def _daysStudied(self) -> Any:
|
||||||
|
@ -592,11 +595,11 @@ group by day order by day"""
|
||||||
ret = self.col.db.first(
|
ret = self.col.db.first(
|
||||||
"""
|
"""
|
||||||
select count(), abs(min(day)) from (select
|
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
|
from revlog %s
|
||||||
group by day order by day)"""
|
group by day order by day)"""
|
||||||
% lim,
|
% lim,
|
||||||
cut=self.col.sched.dayCutoff,
|
self.col.sched.dayCutoff,
|
||||||
)
|
)
|
||||||
assert ret
|
assert ret
|
||||||
return ret
|
return ret
|
||||||
|
@ -655,12 +658,12 @@ group by day order by day)"""
|
||||||
data = [
|
data = [
|
||||||
self.col.db.all(
|
self.col.db.all(
|
||||||
f"""
|
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
|
where did in %s and queue = {QUEUE_TYPE_REV} %s
|
||||||
group by grp
|
group by grp
|
||||||
order by grp"""
|
order by grp"""
|
||||||
% (self._limit(), lim),
|
% (self._limit(), lim),
|
||||||
chunk=chunk,
|
chunk,
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
return (
|
return (
|
||||||
|
@ -866,14 +869,14 @@ order by thetype, ease"""
|
||||||
return self.col.db.all(
|
return self.col.db.all(
|
||||||
f"""
|
f"""
|
||||||
select
|
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) /
|
sum(case when ease = 1 then 0 else 1 end) /
|
||||||
cast(count() as float) * 100,
|
cast(count() as float) * 100,
|
||||||
count()
|
count()
|
||||||
from revlog where type in ({REVLOG_LRN},{REVLOG_REV},{REVLOG_RELRN}) %s
|
from revlog where type in ({REVLOG_LRN},{REVLOG_REV},{REVLOG_RELRN}) %s
|
||||||
group by hour having count() > 30 order by hour"""
|
group by hour having count() > 30 order by hour"""
|
||||||
% lim,
|
% lim,
|
||||||
cut=self.col.sched.dayCutoff - (rolloverHour * 3600),
|
self.col.sched.dayCutoff - (rolloverHour * 3600),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Cards
|
# Cards
|
||||||
|
|
|
@ -110,30 +110,25 @@ class TagManager:
|
||||||
else:
|
else:
|
||||||
l = "tags "
|
l = "tags "
|
||||||
fn = self.remFromStr
|
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(
|
res = self.col.db.all(
|
||||||
"select id, tags from notes where id in %s and (%s)" % (ids2str(ids), lim),
|
"select id, tags from notes where id in %s and (%s)" % (ids2str(ids), lim),
|
||||||
**dict(
|
*["%% %s %%" % y.replace("*", "%") for x, y in enumerate(newTags)],
|
||||||
[
|
|
||||||
("_%d" % x, "%% %s %%" % y.replace("*", "%"))
|
|
||||||
for x, y in enumerate(newTags)
|
|
||||||
]
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
# update tags
|
# update tags
|
||||||
nids = []
|
nids = []
|
||||||
|
|
||||||
def fix(row):
|
def fix(row):
|
||||||
nids.append(row[0])
|
nids.append(row[0])
|
||||||
return {
|
return [
|
||||||
"id": row[0],
|
fn(tags, row[1]),
|
||||||
"t": fn(tags, row[1]),
|
intTime(),
|
||||||
"n": intTime(),
|
self.col.usn(),
|
||||||
"u": self.col.usn(),
|
row[0],
|
||||||
}
|
]
|
||||||
|
|
||||||
self.col.db.executemany(
|
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],
|
[fix(row) for row in res],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -754,10 +754,7 @@ title="%s" %s>%s</button>""" % (
|
||||||
signal.signal(signal.SIGINT, self.onSigInt)
|
signal.signal(signal.SIGINT, self.onSigInt)
|
||||||
|
|
||||||
def onSigInt(self, signum, frame):
|
def onSigInt(self, signum, frame):
|
||||||
# interrupt any current transaction and schedule a rollback & quit
|
# schedule a rollback & quit
|
||||||
if self.col:
|
|
||||||
self.col.db.interrupt()
|
|
||||||
|
|
||||||
def quit():
|
def quit():
|
||||||
self.col.db.rollback()
|
self.col.db.rollback()
|
||||||
self.close()
|
self.close()
|
||||||
|
|
|
@ -35,7 +35,7 @@ class ProgressManager:
|
||||||
"Install a handler in the current DB."
|
"Install a handler in the current DB."
|
||||||
self.lastDbProgress = 0
|
self.lastDbProgress = 0
|
||||||
self.inDB = False
|
self.inDB = False
|
||||||
#db.set_progress_handler(self._dbProgress, 10000)
|
# db.set_progress_handler(self._dbProgress, 10000)
|
||||||
|
|
||||||
def _dbProgress(self):
|
def _dbProgress(self):
|
||||||
"Called from SQLite."
|
"Called from SQLite."
|
||||||
|
|
Loading…
Reference in a new issue