roll back the vec cache changes

prepare_cached() is sufficiently fast, and allowing the vec cache
to persist across calls is complicated due to lifetime restrictions
This commit is contained in:
Damien Elmes 2020-03-29 09:26:09 +10:00
parent 1a1a00d50f
commit 2810d3883b
3 changed files with 68 additions and 116 deletions

View File

@ -39,7 +39,6 @@ slog-envlogger = "2.2.0"
serde_repr = "0.1.5"
num_enum = "0.4.2"
unicase = "2.6.0"
variant_count = "=1.0.0"
# pinned until rusqlite 0.22 comes out
[target.'cfg(target_vendor="apple")'.dependencies.rusqlite]

View File

@ -1,7 +1,6 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
use super::sqlite::CachedStatementKind;
use crate::card::{Card, CardID, CardQueue, CardType};
use crate::err::Result;
use crate::timestamp::TimestampMillis;
@ -34,97 +33,81 @@ impl FromSql for CardQueue {
impl super::StorageContext<'_> {
pub fn get_card(&mut self, cid: CardID) -> Result<Option<Card>> {
self.with_cached_stmt(
CachedStatementKind::GetCard,
include_str!("get_card.sql"),
|stmt| {
stmt.query_row(params![cid], |row| {
Ok(Card {
id: cid,
nid: row.get(0)?,
did: row.get(1)?,
ord: row.get(2)?,
mtime: row.get(3)?,
usn: row.get(4)?,
ctype: row.get(5)?,
queue: row.get(6)?,
due: row.get(7)?,
ivl: row.get(8)?,
factor: row.get(9)?,
reps: row.get(10)?,
lapses: row.get(11)?,
left: row.get(12)?,
odue: row.get(13)?,
odid: row.get(14)?,
flags: row.get(15)?,
data: row.get(16)?,
})
})
.optional()
.map_err(Into::into)
},
)
let mut stmt = self.db.prepare_cached(include_str!("get_card.sql"))?;
stmt.query_row(params![cid], |row| {
Ok(Card {
id: cid,
nid: row.get(0)?,
did: row.get(1)?,
ord: row.get(2)?,
mtime: row.get(3)?,
usn: row.get(4)?,
ctype: row.get(5)?,
queue: row.get(6)?,
due: row.get(7)?,
ivl: row.get(8)?,
factor: row.get(9)?,
reps: row.get(10)?,
lapses: row.get(11)?,
left: row.get(12)?,
odue: row.get(13)?,
odid: row.get(14)?,
flags: row.get(15)?,
data: row.get(16)?,
})
})
.optional()
.map_err(Into::into)
}
pub(crate) fn update_card(&mut self, card: &Card) -> Result<()> {
self.with_cached_stmt(
CachedStatementKind::UpdateCard,
include_str!("update_card.sql"),
|stmt| {
stmt.execute(params![
card.nid,
card.did,
card.ord,
card.mtime,
card.usn,
card.ctype as u8,
card.queue as i8,
card.due,
card.ivl,
card.factor,
card.reps,
card.lapses,
card.left,
card.odue,
card.odid,
card.flags,
card.data,
card.id,
])?;
Ok(())
},
)
let mut stmt = self.db.prepare_cached(include_str!("update_card.sql"))?;
stmt.execute(params![
card.nid,
card.did,
card.ord,
card.mtime,
card.usn,
card.ctype as u8,
card.queue as i8,
card.due,
card.ivl,
card.factor,
card.reps,
card.lapses,
card.left,
card.odue,
card.odid,
card.flags,
card.data,
card.id,
])?;
Ok(())
}
pub(crate) fn add_card(&mut self, card: &mut Card) -> Result<()> {
let now = TimestampMillis::now().0;
self.with_cached_stmt(
CachedStatementKind::AddCard,
include_str!("add_card.sql"),
|stmt| {
stmt.execute(params![
now,
card.nid,
card.did,
card.ord,
card.mtime,
card.usn,
card.ctype as u8,
card.queue as i8,
card.due,
card.ivl,
card.factor,
card.reps,
card.lapses,
card.left,
card.odue,
card.odid,
card.flags,
card.data,
])?;
Ok(())
},
)?;
let mut stmt = self.db.prepare_cached(include_str!("add_card.sql"))?;
stmt.execute(params![
now,
card.nid,
card.did,
card.ord,
card.mtime,
card.usn,
card.ctype as u8,
card.queue as i8,
card.due,
card.ivl,
card.factor,
card.reps,
card.lapses,
card.left,
card.odue,
card.odid,
card.flags,
card.data,
])?;
card.id = CardID(self.db.last_insert_rowid());
Ok(())
}

View File

@ -24,7 +24,6 @@ use std::{
path::{Path, PathBuf},
};
use unicase::UniCase;
use variant_count::VariantCount;
const SCHEMA_MIN_VERSION: u8 = 11;
const SCHEMA_MAX_VERSION: u8 = 11;
@ -204,53 +203,24 @@ impl SqliteStorage {
}
}
#[derive(Clone, Copy, VariantCount)]
#[allow(clippy::enum_variant_names)]
pub(super) enum CachedStatementKind {
GetCard,
UpdateCard,
AddCard,
}
pub(crate) struct StorageContext<'a> {
pub(crate) db: &'a Connection,
server: bool,
usn: Option<Usn>,
timing_today: Option<SchedTimingToday>,
cached_statements: Vec<Option<rusqlite::CachedStatement<'a>>>,
}
impl StorageContext<'_> {
fn new(db: &Connection, server: bool) -> StorageContext {
let stmt_len = CachedStatementKind::VARIANT_COUNT;
let mut statements = Vec::with_capacity(stmt_len);
statements.resize_with(stmt_len, Default::default);
StorageContext {
db,
server,
usn: None,
timing_today: None,
cached_statements: statements,
}
}
pub(super) fn with_cached_stmt<F, T>(
&mut self,
kind: CachedStatementKind,
sql: &str,
func: F,
) -> Result<T>
where
F: FnOnce(&mut rusqlite::CachedStatement) -> Result<T>,
{
if self.cached_statements[kind as usize].is_none() {
self.cached_statements[kind as usize] = Some(self.db.prepare_cached(sql)?);
}
func(self.cached_statements[kind as usize].as_mut().unwrap())
}
// Standard transaction start/stop
//////////////////////////////////////