summaryrefslogtreecommitdiff
path: root/cli/cache/incremental.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/cache/incremental.rs')
-rw-r--r--cli/cache/incremental.rs166
1 files changed, 53 insertions, 113 deletions
diff --git a/cli/cache/incremental.rs b/cli/cache/incremental.rs
index d5298071f..deb30cdd1 100644
--- a/cli/cache/incremental.rs
+++ b/cli/cache/incremental.rs
@@ -8,57 +8,49 @@ use deno_core::error::AnyError;
use deno_core::parking_lot::Mutex;
use deno_core::serde_json;
use deno_runtime::deno_webstorage::rusqlite::params;
-use deno_runtime::deno_webstorage::rusqlite::Connection;
use serde::Serialize;
use tokio::task::JoinHandle;
+use super::cache_db::CacheDB;
+use super::cache_db::CacheDBConfiguration;
+use super::cache_db::CacheFailure;
use super::common::FastInsecureHasher;
-use super::common::INITIAL_PRAGMAS;
+
+pub static INCREMENTAL_CACHE_DB: CacheDBConfiguration = CacheDBConfiguration {
+ table_initializer: "CREATE TABLE IF NOT EXISTS incrementalcache (
+ file_path TEXT PRIMARY KEY,
+ state_hash TEXT NOT NULL,
+ source_hash TEXT NOT NULL
+ );",
+ on_version_change: "DELETE FROM incrementalcache;",
+ preheat_queries: &[],
+ // If the cache fails, just ignore all caching attempts
+ on_failure: CacheFailure::Blackhole,
+};
/// Cache used to skip formatting/linting a file again when we
/// know it is already formatted or has no lint diagnostics.
-pub struct IncrementalCache(Option<IncrementalCacheInner>);
+pub struct IncrementalCache(IncrementalCacheInner);
impl IncrementalCache {
pub fn new<TState: Serialize>(
- db_file_path: &Path,
+ db: CacheDB,
state: &TState,
initial_file_paths: &[PathBuf],
) -> Self {
- // if creating the incremental cache fails, then we
- // treat it as not having a cache
- let result =
- IncrementalCacheInner::new(db_file_path, state, initial_file_paths);
- IncrementalCache(match result {
- Ok(inner) => Some(inner),
- Err(err) => {
- log::debug!("Creating the incremental cache failed.\n{:#}", err);
- // Maybe the cache file is corrupt. Attempt to remove
- // the cache file for next time
- let _ = std::fs::remove_file(db_file_path);
- None
- }
- })
+ IncrementalCache(IncrementalCacheInner::new(db, state, initial_file_paths))
}
pub fn is_file_same(&self, file_path: &Path, file_text: &str) -> bool {
- if let Some(inner) = &self.0 {
- inner.is_file_same(file_path, file_text)
- } else {
- false
- }
+ self.0.is_file_same(file_path, file_text)
}
pub fn update_file(&self, file_path: &Path, file_text: &str) {
- if let Some(inner) = &self.0 {
- inner.update_file(file_path, file_text)
- }
+ self.0.update_file(file_path, file_text)
}
pub async fn wait_completion(&self) {
- if let Some(inner) = &self.0 {
- inner.wait_completion().await;
- }
+ self.0.wait_completion().await;
}
}
@@ -75,18 +67,15 @@ struct IncrementalCacheInner {
impl IncrementalCacheInner {
pub fn new<TState: Serialize>(
- db_file_path: &Path,
+ db: CacheDB,
state: &TState,
initial_file_paths: &[PathBuf],
- ) -> Result<Self, AnyError> {
+ ) -> Self {
let state_hash = FastInsecureHasher::new()
.write_str(&serde_json::to_string(state).unwrap())
.finish();
- let sql_cache = SqlIncrementalCache::new(db_file_path, state_hash)?;
- Ok(Self::from_sql_incremental_cache(
- sql_cache,
- initial_file_paths,
- ))
+ let sql_cache = SqlIncrementalCache::new(db, state_hash);
+ Self::from_sql_incremental_cache(sql_cache, initial_file_paths)
}
fn from_sql_incremental_cache(
@@ -155,7 +144,7 @@ impl IncrementalCacheInner {
}
struct SqlIncrementalCache {
- conn: Connection,
+ conn: CacheDB,
/// A hash of the state used to produce the formatting/linting other than
/// the CLI version. This state is a hash of the configuration and ensures
/// we format/lint a file when the configuration changes.
@@ -163,20 +152,8 @@ struct SqlIncrementalCache {
}
impl SqlIncrementalCache {
- pub fn new(db_file_path: &Path, state_hash: u64) -> Result<Self, AnyError> {
- log::debug!("Loading incremental cache.");
- let conn = Connection::open(db_file_path)?;
- Self::from_connection(conn, state_hash, crate::version::deno())
- }
-
- fn from_connection(
- conn: Connection,
- state_hash: u64,
- cli_version: &'static str,
- ) -> Result<Self, AnyError> {
- initialize(&conn, cli_version)?;
-
- Ok(Self { conn, state_hash })
+ pub fn new(conn: CacheDB, state_hash: u64) -> Self {
+ Self { conn, state_hash }
}
pub fn get_source_hash(&self, path: &Path) -> Option<u64> {
@@ -206,15 +183,15 @@ impl SqlIncrementalCache {
file_path=?1
AND state_hash=?2
LIMIT 1";
- let mut stmt = self.conn.prepare_cached(query)?;
- let mut rows = stmt
- .query(params![path.to_string_lossy(), self.state_hash.to_string()])?;
- if let Some(row) = rows.next()? {
- let hash: String = row.get(0)?;
- Ok(Some(hash.parse::<u64>()?))
- } else {
- Ok(None)
- }
+ let res = self.conn.query_row(
+ query,
+ params![path.to_string_lossy(), self.state_hash.to_string()],
+ |row| {
+ let hash: String = row.get(0)?;
+ Ok(hash.parse::<u64>()?)
+ },
+ )?;
+ Ok(res)
}
pub fn set_source_hash(
@@ -227,53 +204,18 @@ impl SqlIncrementalCache {
incrementalcache (file_path, state_hash, source_hash)
VALUES
(?1, ?2, ?3)";
- let mut stmt = self.conn.prepare_cached(sql)?;
- stmt.execute(params![
- path.to_string_lossy(),
- &self.state_hash.to_string(),
- &source_hash,
- ])?;
+ self.conn.execute(
+ sql,
+ params![
+ path.to_string_lossy(),
+ &self.state_hash.to_string(),
+ &source_hash,
+ ],
+ )?;
Ok(())
}
}
-fn initialize(
- conn: &Connection,
- cli_version: &'static str,
-) -> Result<(), AnyError> {
- // INT doesn't store up to u64, so use TEXT for source_hash
- let query = format!(
- "{INITIAL_PRAGMAS}
- CREATE TABLE IF NOT EXISTS incrementalcache (
- file_path TEXT PRIMARY KEY,
- state_hash TEXT NOT NULL,
- source_hash 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 incrementalcache", 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 std::path::PathBuf;
@@ -282,8 +224,8 @@ mod test {
#[test]
pub fn sql_cache_general_use() {
- let conn = Connection::open_in_memory().unwrap();
- let cache = SqlIncrementalCache::from_connection(conn, 1, "1.0.0").unwrap();
+ let conn = CacheDB::in_memory(&INCREMENTAL_CACHE_DB, "1.0.0");
+ let cache = SqlIncrementalCache::new(conn, 1);
let path = PathBuf::from("/mod.ts");
assert_eq!(cache.get_source_hash(&path), None);
@@ -291,9 +233,8 @@ mod test {
assert_eq!(cache.get_source_hash(&path), Some(2));
// try changing the cli version (should clear)
- let conn = cache.conn;
- let mut cache =
- SqlIncrementalCache::from_connection(conn, 1, "2.0.0").unwrap();
+ let conn = cache.conn.recreate_with_version("2.0.0");
+ let mut cache = SqlIncrementalCache::new(conn, 1);
assert_eq!(cache.get_source_hash(&path), None);
// add back the file to the cache
@@ -309,8 +250,8 @@ mod test {
assert_eq!(cache.get_source_hash(&path), Some(2));
// recreating the cache should not remove the data because the CLI version and state hash is the same
- let conn = cache.conn;
- let cache = SqlIncrementalCache::from_connection(conn, 1, "2.0.0").unwrap();
+ let conn = cache.conn.recreate_with_version("2.0.0");
+ let cache = SqlIncrementalCache::new(conn, 1);
assert_eq!(cache.get_source_hash(&path), Some(2));
// now try replacing and using another path
@@ -324,9 +265,8 @@ mod test {
#[tokio::test]
pub async fn incremental_cache_general_use() {
- let conn = Connection::open_in_memory().unwrap();
- let sql_cache =
- SqlIncrementalCache::from_connection(conn, 1, "1.0.0").unwrap();
+ let conn = CacheDB::in_memory(&INCREMENTAL_CACHE_DB, "1.0.0");
+ let sql_cache = SqlIncrementalCache::new(conn, 1);
let file_path = PathBuf::from("/mod.ts");
let file_text = "test";
let file_hash = FastInsecureHasher::new().write_str(file_text).finish();