feat: first take at M4

This commit is contained in:
2026-04-10 15:32:05 +02:00
parent ee961f1b02
commit 3ca80b00d0
27 changed files with 3923 additions and 21 deletions

View File

@@ -0,0 +1,94 @@
use rusqlite::{params, Connection};
use crate::db::from_row::{generated_file_hash_from_row, GENERATED_FILE_HASH_COLUMNS};
use crate::model::GeneratedFileHash;
pub fn get_generated_file_hash(
conn: &Connection,
project_id: &str,
relative_path: &str,
) -> rusqlite::Result<GeneratedFileHash> {
conn.query_row(
&format!(
"SELECT {GENERATED_FILE_HASH_COLUMNS} FROM generated_file_hashes WHERE project_id = ?1 AND relative_path = ?2"
),
params![project_id, relative_path],
generated_file_hash_from_row,
)
}
pub fn upsert_generated_file_hash(conn: &Connection, hash: &GeneratedFileHash) -> rusqlite::Result<()> {
conn.execute(
"INSERT INTO generated_file_hashes (project_id, relative_path, content_hash, updated_at)
VALUES (?1, ?2, ?3, ?4)
ON CONFLICT(project_id, relative_path)
DO UPDATE SET content_hash = excluded.content_hash, updated_at = excluded.updated_at",
params![hash.project_id, hash.relative_path, hash.content_hash, hash.updated_at],
)?;
Ok(())
}
pub fn delete_generated_file_hash(
conn: &Connection,
project_id: &str,
relative_path: &str,
) -> rusqlite::Result<()> {
conn.execute(
"DELETE FROM generated_file_hashes WHERE project_id = ?1 AND relative_path = ?2",
params![project_id, relative_path],
)?;
Ok(())
}
pub fn list_generated_file_hashes_by_project(
conn: &Connection,
project_id: &str,
) -> rusqlite::Result<Vec<GeneratedFileHash>> {
let mut stmt = conn.prepare(&format!(
"SELECT {GENERATED_FILE_HASH_COLUMNS} FROM generated_file_hashes WHERE project_id = ?1 ORDER BY relative_path"
))?;
let rows = stmt.query_map(params![project_id], generated_file_hash_from_row)?;
rows.collect()
}
#[cfg(test)]
mod tests {
use super::*;
use crate::db::queries::project::{insert_project, make_test_project};
use crate::db::Database;
fn setup() -> Database {
let mut db = Database::open_in_memory().unwrap();
db.migrate().unwrap();
insert_project(db.conn(), &make_test_project("p1", "blog")).unwrap();
db
}
#[test]
fn upsert_and_get_generated_hash() {
let db = setup();
let hash = GeneratedFileHash {
project_id: "p1".into(),
relative_path: "index.html".into(),
content_hash: "abc".into(),
updated_at: 42,
};
upsert_generated_file_hash(db.conn(), &hash).unwrap();
let stored = get_generated_file_hash(db.conn(), "p1", "index.html").unwrap();
assert_eq!(stored.content_hash, "abc");
upsert_generated_file_hash(
db.conn(),
&GeneratedFileHash {
content_hash: "def".into(),
updated_at: 99,
..hash
},
)
.unwrap();
let stored = get_generated_file_hash(db.conn(), "p1", "index.html").unwrap();
assert_eq!(stored.content_hash, "def");
assert_eq!(stored.updated_at, 99);
}
}

View File

@@ -9,3 +9,4 @@ pub mod post_media;
pub mod template;
pub mod script;
pub mod setting;
pub mod generated_file_hash;