summaryrefslogtreecommitdiff
path: root/cli/cache/check.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/cache/check.rs')
-rw-r--r--cli/cache/check.rs176
1 files changed, 47 insertions, 129 deletions
diff --git a/cli/cache/check.rs b/cli/cache/check.rs
index 1bd410013..bf71380cb 100644
--- a/cli/cache/check.rs
+++ b/cli/cache/check.rs
@@ -1,68 +1,40 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
-use std::path::Path;
-
+use super::cache_db::CacheDB;
+use super::cache_db::CacheDBConfiguration;
+use super::cache_db::CacheFailure;
use deno_ast::ModuleSpecifier;
use deno_core::error::AnyError;
use deno_runtime::deno_webstorage::rusqlite::params;
-use deno_runtime::deno_webstorage::rusqlite::Connection;
-use super::common::INITIAL_PRAGMAS;
+pub static TYPE_CHECK_CACHE_DB: CacheDBConfiguration = CacheDBConfiguration {
+ table_initializer: concat!(
+ "CREATE TABLE IF NOT EXISTS checkcache (
+ check_hash TEXT PRIMARY KEY
+ );",
+ "CREATE TABLE IF NOT EXISTS tsbuildinfo (
+ specifier TEXT PRIMARY KEY,
+ text TEXT NOT NULL
+ );",
+ ),
+ on_version_change: concat!(
+ "DELETE FROM checkcache;",
+ "DELETE FROM tsbuildinfo;"
+ ),
+ preheat_queries: &[],
+ // If the cache fails, just ignore all caching attempts
+ on_failure: CacheFailure::Blackhole,
+};
/// The cache used to tell whether type checking should occur again.
///
/// This simply stores a hash of the inputs of each successful type check
/// and only clears them out when changing CLI versions.
-pub struct TypeCheckCache(Option<Connection>);
+pub struct TypeCheckCache(CacheDB);
impl TypeCheckCache {
- pub fn new(db_file_path: &Path) -> Self {
- log::debug!("Loading type check cache.");
- match Self::try_new(db_file_path) {
- Ok(cache) => cache,
- Err(err) => {
- log::debug!(
- concat!(
- "Failed loading internal type checking cache. ",
- "Recreating...\n\nError details:\n{:#}",
- ),
- err
- );
- // Maybe the cache file is corrupt. Attempt to remove the cache file
- // then attempt to recreate again. Otherwise, use null object pattern.
- match std::fs::remove_file(db_file_path) {
- Ok(_) => match Self::try_new(db_file_path) {
- Ok(cache) => cache,
- Err(err) => {
- log::debug!(
- concat!(
- "Unable to load internal cache for type checking. ",
- "This will reduce the performance of type checking.\n\n",
- "Error details:\n{:#}",
- ),
- err
- );
- Self(None)
- }
- },
- Err(_) => Self(None),
- }
- }
- }
- }
-
- fn try_new(db_file_path: &Path) -> Result<Self, AnyError> {
- let conn = Connection::open(db_file_path)?;
- Self::from_connection(conn, crate::version::deno())
- }
-
- fn from_connection(
- conn: Connection,
- cli_version: &'static str,
- ) -> Result<Self, AnyError> {
- initialize(&conn, cli_version)?;
-
- Ok(Self(Some(conn)))
+ pub fn new(db: CacheDB) -> Self {
+ Self(db)
}
pub fn has_check_hash(&self, hash: u64) -> bool {
@@ -81,13 +53,10 @@ impl TypeCheckCache {
}
fn hash_check_hash_result(&self, hash: u64) -> Result<bool, AnyError> {
- let conn = match &self.0 {
- Some(conn) => conn,
- None => return Ok(false),
- };
- let query = "SELECT * FROM checkcache WHERE check_hash=?1 LIMIT 1";
- let mut stmt = conn.prepare_cached(query)?;
- Ok(stmt.exists(params![hash.to_string()])?)
+ self.0.exists(
+ "SELECT * FROM checkcache WHERE check_hash=?1 LIMIT 1",
+ params![hash.to_string()],
+ )
}
pub fn add_check_hash(&self, check_hash: u64) {
@@ -101,32 +70,24 @@ impl TypeCheckCache {
}
fn add_check_hash_result(&self, check_hash: u64) -> Result<(), AnyError> {
- let conn = match &self.0 {
- Some(conn) => conn,
- None => return Ok(()),
- };
let sql = "
INSERT OR REPLACE INTO
checkcache (check_hash)
VALUES
(?1)";
- let mut stmt = conn.prepare_cached(sql)?;
- stmt.execute(params![&check_hash.to_string(),])?;
+ self.0.execute(sql, params![&check_hash.to_string(),])?;
Ok(())
}
pub fn get_tsbuildinfo(&self, specifier: &ModuleSpecifier) -> Option<String> {
- let conn = match &self.0 {
- Some(conn) => conn,
- None => return None,
- };
- let mut stmt = conn
- .prepare_cached("SELECT text FROM tsbuildinfo WHERE specifier=?1 LIMIT 1")
- .ok()?;
- let mut rows = stmt.query(params![specifier.to_string()]).ok()?;
- let row = rows.next().ok().flatten()?;
-
- row.get(0).ok()
+ self
+ .0
+ .query_row(
+ "SELECT text FROM tsbuildinfo WHERE specifier=?1 LIMIT 1",
+ params![specifier.to_string()],
+ |row| Ok(row.get::<_, String>(0)?),
+ )
+ .ok()?
}
pub fn set_tsbuildinfo(&self, specifier: &ModuleSpecifier, text: &str) {
@@ -145,67 +106,22 @@ impl TypeCheckCache {
specifier: &ModuleSpecifier,
text: &str,
) -> Result<(), AnyError> {
- let conn = match &self.0 {
- Some(conn) => conn,
- None => return Ok(()),
- };
- let mut stmt = conn.prepare_cached(
+ self.0.execute(
"INSERT OR REPLACE INTO tsbuildinfo (specifier, text) VALUES (?1, ?2)",
+ params![specifier.to_string(), text],
)?;
- stmt.execute(params![specifier.to_string(), text])?;
Ok(())
}
}
-fn initialize(
- conn: &Connection,
- cli_version: &'static str,
-) -> Result<(), AnyError> {
- // INT doesn't store up to u64, so use TEXT for check_hash
- let query = format!(
- "{INITIAL_PRAGMAS}
- CREATE TABLE IF NOT EXISTS checkcache (
- check_hash TEXT PRIMARY KEY
- );
- CREATE TABLE IF NOT EXISTS tsbuildinfo (
- specifier TEXT PRIMARY KEY,
- text TEXT NOT NULL
- );
- CREATE TABLE IF NOT EXISTS info (
- key TEXT PRIMARY KEY,
- value TEXT NOT NULL
- );
- ",
- );
- conn.execute_batch(&query)?;
-
- // delete the cache when the CLI version changes
- let data_cli_version: Option<String> = conn
- .query_row(
- "SELECT value FROM info WHERE key='CLI_VERSION' LIMIT 1",
- [],
- |row| row.get(0),
- )
- .ok();
- if data_cli_version.as_deref() != Some(cli_version) {
- conn.execute("DELETE FROM checkcache", params![])?;
- conn.execute("DELETE FROM tsbuildinfo", params![])?;
- let mut stmt = conn
- .prepare("INSERT OR REPLACE INTO info (key, value) VALUES (?1, ?2)")?;
- stmt.execute(params!["CLI_VERSION", cli_version])?;
- }
-
- Ok(())
-}
-
#[cfg(test)]
mod test {
use super::*;
#[test]
pub fn check_cache_general_use() {
- let conn = Connection::open_in_memory().unwrap();
- let cache = TypeCheckCache::from_connection(conn, "1.0.0").unwrap();
+ let conn = CacheDB::in_memory(&TYPE_CHECK_CACHE_DB, "1.0.0");
+ let cache = TypeCheckCache::new(conn);
assert!(!cache.has_check_hash(1));
cache.add_check_hash(1);
@@ -218,8 +134,9 @@ mod test {
assert_eq!(cache.get_tsbuildinfo(&specifier1), Some("test".to_string()));
// try changing the cli version (should clear)
- let conn = cache.0.unwrap();
- let cache = TypeCheckCache::from_connection(conn, "2.0.0").unwrap();
+ let conn = cache.0.recreate_with_version("2.0.0");
+ let cache = TypeCheckCache::new(conn);
+
assert!(!cache.has_check_hash(1));
cache.add_check_hash(1);
assert!(cache.has_check_hash(1));
@@ -228,8 +145,9 @@ mod test {
assert_eq!(cache.get_tsbuildinfo(&specifier1), Some("test".to_string()));
// recreating the cache should not remove the data because the CLI version is the same
- let conn = cache.0.unwrap();
- let cache = TypeCheckCache::from_connection(conn, "2.0.0").unwrap();
+ let conn = cache.0.recreate_with_version("2.0.0");
+ let cache = TypeCheckCache::new(conn);
+
assert!(cache.has_check_hash(1));
assert!(!cache.has_check_hash(2));
assert_eq!(cache.get_tsbuildinfo(&specifier1), Some("test".to_string()));