chore: cleanups and refactorings for cleaner code

This commit is contained in:
2026-07-18 21:39:16 +02:00
parent b438a99999
commit e5080b7282
63 changed files with 3454 additions and 4093 deletions

View File

@@ -1,7 +1,6 @@
use diesel::prelude::*;
use crate::db::DbConnection;
use crate::db::from_row::GeneratedFileHashRecord;
use crate::db::schema::generated_file_hashes;
use crate::model::GeneratedFileHash;
@@ -14,9 +13,8 @@ pub fn get_generated_file_hash(
generated_file_hashes::table
.filter(generated_file_hashes::project_id.eq(project_id))
.filter(generated_file_hashes::relative_path.eq(relative_path))
.select(GeneratedFileHashRecord::as_select())
.select(GeneratedFileHash::as_select())
.first(c)
.map(Into::into)
})
}
@@ -26,7 +24,7 @@ pub fn upsert_generated_file_hash(
) -> QueryResult<()> {
conn.with(|c| {
diesel::insert_into(generated_file_hashes::table)
.values(GeneratedFileHashRecord::from(hash))
.values(hash.clone())
.on_conflict((
generated_file_hashes::project_id,
generated_file_hashes::relative_path,
@@ -41,36 +39,6 @@ pub fn upsert_generated_file_hash(
})
}
pub fn delete_generated_file_hash(
conn: &DbConnection,
project_id: &str,
relative_path: &str,
) -> QueryResult<()> {
conn.with(|c| {
diesel::delete(
generated_file_hashes::table
.filter(generated_file_hashes::project_id.eq(project_id))
.filter(generated_file_hashes::relative_path.eq(relative_path)),
)
.execute(c)
.map(|_| ())
})
}
pub fn list_generated_file_hashes_by_project(
conn: &DbConnection,
project_id: &str,
) -> QueryResult<Vec<GeneratedFileHash>> {
conn.with(|c| {
generated_file_hashes::table
.filter(generated_file_hashes::project_id.eq(project_id))
.order(generated_file_hashes::relative_path)
.select(GeneratedFileHashRecord::as_select())
.load(c)
.map(|rows: Vec<GeneratedFileHashRecord>| rows.into_iter().map(Into::into).collect())
})
}
#[cfg(test)]
mod tests {
use super::*;

View File

@@ -3,7 +3,6 @@ use diesel::prelude::*;
use diesel::sql_types::Text;
use crate::db::DbConnection;
use crate::db::from_row::{MediaRecord, convert, convert_all};
use crate::db::schema::media;
use crate::model::Media;
use crate::util::calendar_range_unix_ms;
@@ -13,7 +12,7 @@ diesel::define_sql_function!(fn instr(haystack: Text, needle: Text) -> Integer);
pub fn insert_media(conn: &DbConnection, m: &Media) -> QueryResult<()> {
conn.with(|c| {
diesel::insert_into(media::table)
.values(MediaRecord::from(m))
.values(m.clone())
.execute(c)
.map(|_| ())
})
@@ -23,9 +22,8 @@ pub fn get_media_by_id(conn: &DbConnection, id: &str) -> QueryResult<Media> {
conn.with(|c| {
media::table
.filter(media::id.eq(id))
.select(MediaRecord::as_select())
.select(Media::as_select())
.first(c)
.and_then(convert)
})
}
@@ -34,27 +32,8 @@ pub fn list_media_by_project(conn: &DbConnection, project_id: &str) -> QueryResu
media::table
.filter(media::project_id.eq(project_id))
.order(media::created_at.desc())
.select(MediaRecord::as_select())
.select(Media::as_select())
.load(c)
.and_then(convert_all)
})
}
pub fn list_media_by_project_limited(
conn: &DbConnection,
project_id: &str,
limit: i64,
offset: i64,
) -> QueryResult<Vec<Media>> {
conn.with(|c| {
media::table
.filter(media::project_id.eq(project_id))
.order(media::created_at.desc())
.limit(limit)
.offset(offset)
.select(MediaRecord::as_select())
.load(c)
.and_then(convert_all)
})
}
@@ -70,7 +49,7 @@ pub fn count_media_by_project(conn: &DbConnection, project_id: &str) -> QueryRes
pub fn update_media(conn: &DbConnection, m: &Media) -> QueryResult<()> {
conn.with(|c| {
diesel::update(media::table.filter(media::id.eq(&m.id)))
.set(MediaRecord::from(m))
.set(m.clone())
.execute(c)
.map(|_| ())
})
@@ -140,9 +119,8 @@ pub fn list_media_filtered(
.order(media::created_at.desc())
.limit(limit)
.offset(offset)
.select(MediaRecord::as_select())
.select(Media::as_select())
.load(c)
.and_then(convert_all)
})
}

View File

@@ -1,14 +1,13 @@
use diesel::prelude::*;
use crate::db::DbConnection;
use crate::db::from_row::MediaTranslationRecord;
use crate::db::schema::media_translations;
use crate::model::MediaTranslation;
pub fn insert_media_translation(conn: &DbConnection, t: &MediaTranslation) -> QueryResult<()> {
conn.with(|c| {
diesel::insert_into(media_translations::table)
.values(MediaTranslationRecord::from(t))
.values(t.clone())
.execute(c)
.map(|_| ())
})
@@ -23,9 +22,8 @@ pub fn get_media_translation_by_media_and_language(
media_translations::table
.filter(media_translations::translation_for.eq(translation_for))
.filter(media_translations::language.eq(language))
.select(MediaTranslationRecord::as_select())
.select(MediaTranslation::as_select())
.first(c)
.map(Into::into)
})
}
@@ -37,16 +35,15 @@ pub fn list_media_translations_by_media(
media_translations::table
.filter(media_translations::translation_for.eq(translation_for))
.order(media_translations::language)
.select(MediaTranslationRecord::as_select())
.select(MediaTranslation::as_select())
.load(c)
.map(|rows: Vec<MediaTranslationRecord>| rows.into_iter().map(Into::into).collect())
})
}
pub fn upsert_media_translation(conn: &DbConnection, t: &MediaTranslation) -> QueryResult<()> {
conn.with(|c| {
diesel::insert_into(media_translations::table)
.values(MediaTranslationRecord::from(t))
.values(t.clone())
.on_conflict((
media_translations::translation_for,
media_translations::language,

View File

@@ -4,7 +4,6 @@ use diesel::sql_types::Text;
use diesel::sqlite::Sqlite;
use crate::db::DbConnection;
use crate::db::from_row::{PostRecord, convert, convert_all, post_status_to_str};
use crate::db::schema::posts;
use crate::model::{Post, PostStatus};
use crate::util::calendar_range_unix_ms;
@@ -15,7 +14,7 @@ diesel::define_sql_function!(fn lower(value: Text) -> Text);
pub fn insert_post(conn: &DbConnection, post: &Post) -> QueryResult<()> {
conn.with(|c| {
diesel::insert_into(posts::table)
.values(PostRecord::from(post))
.values(post.clone())
.execute(c)
.map(|_| ())
})
@@ -25,9 +24,8 @@ pub fn get_post_by_id(conn: &DbConnection, id: &str) -> QueryResult<Post> {
conn.with(|c| {
posts::table
.filter(posts::id.eq(id))
.select(PostRecord::as_select())
.select(Post::as_select())
.first(c)
.and_then(convert)
})
}
@@ -40,9 +38,8 @@ pub fn get_post_by_project_and_slug(
posts::table
.filter(posts::project_id.eq(project_id))
.filter(posts::slug.eq(slug))
.select(PostRecord::as_select())
.select(Post::as_select())
.first(c)
.and_then(convert)
})
}
@@ -51,34 +48,15 @@ pub fn list_posts_by_project(conn: &DbConnection, project_id: &str) -> QueryResu
posts::table
.filter(posts::project_id.eq(project_id))
.order(posts::created_at.desc())
.select(PostRecord::as_select())
.select(Post::as_select())
.load(c)
.and_then(convert_all)
})
}
pub fn list_posts_by_project_limited(
conn: &DbConnection,
project_id: &str,
limit: i64,
offset: i64,
) -> QueryResult<Vec<Post>> {
conn.with(|c| {
posts::table
.filter(posts::project_id.eq(project_id))
.order(posts::created_at.desc())
.limit(limit)
.offset(offset)
.select(PostRecord::as_select())
.load(c)
.and_then(convert_all)
})
}
pub fn update_post(conn: &DbConnection, post: &Post) -> QueryResult<()> {
conn.with(|c| {
diesel::update(posts::table.filter(posts::id.eq(&post.id)))
.set(PostRecord::from(post))
.set(post.clone())
.execute(c)
.map(|_| ())
})
@@ -93,7 +71,7 @@ pub fn update_post_status(
conn.with(|c| {
diesel::update(posts::table.filter(posts::id.eq(id)))
.set((
posts::status.eq(post_status_to_str(status)),
posts::status.eq(status.as_str()),
posts::updated_at.eq(updated_at),
))
.execute(c)
@@ -307,17 +285,17 @@ pub fn list_posts_filtered(
.order(posts::created_at.desc())
.limit(limit)
.offset(offset)
.select(PostRecord::as_select())
.select(Post::as_select())
.load(c)?
} else if content_filters {
let mut records: Vec<PostRecord> = post_query(project_id, filters, false, false)
let mut records: Vec<Post> = post_query(project_id, filters, false, false)
.filter(posts::status.eq("draft"))
.select(PostRecord::as_select())
.select(Post::as_select())
.load(c)?;
records.extend(
post_query(project_id, filters, true, true)
.select(PostRecord::as_select())
.load::<PostRecord>(c)?,
.select(Post::as_select())
.load::<Post>(c)?,
);
records.sort_unstable_by_key(|record| std::cmp::Reverse(record.created_at));
records
@@ -330,10 +308,10 @@ pub fn list_posts_filtered(
.order(posts::created_at.desc())
.limit(limit)
.offset(offset)
.select(PostRecord::as_select())
.select(Post::as_select())
.load(c)?
};
convert_all(records)
Ok(records)
})
}
@@ -544,6 +522,29 @@ mod tests {
assert_eq!(fetched.updated_at, 5000);
}
#[test]
fn malformed_persisted_types_fail_deserialization() {
let db = setup();
insert_post(db.conn(), &make_post("x1", "hello")).unwrap();
db.conn()
.with(|connection| {
diesel::update(posts::table.filter(posts::id.eq("x1")))
.set(posts::status.eq("unknown"))
.execute(connection)
})
.unwrap();
assert!(get_post_by_id(db.conn(), "x1").is_err());
db.conn()
.with(|connection| {
diesel::update(posts::table.filter(posts::id.eq("x1")))
.set((posts::status.eq("draft"), posts::tags.eq("not-json")))
.execute(connection)
})
.unwrap();
assert!(get_post_by_id(db.conn(), "x1").is_err());
}
#[test]
fn clear_content_sets_null() {
let db = setup();

View File

@@ -1,14 +1,13 @@
use diesel::prelude::*;
use crate::db::DbConnection;
use crate::db::from_row::PostLinkRecord;
use crate::db::schema::post_links;
use crate::model::PostLink;
pub fn insert_post_link(conn: &DbConnection, link: &PostLink) -> QueryResult<()> {
conn.with(|c| {
diesel::insert_into(post_links::table)
.values(PostLinkRecord::from(link))
.values(link.clone())
.execute(c)
.map(|_| ())
})
@@ -38,9 +37,8 @@ pub fn list_links_by_source(
post_links::table
.filter(post_links::source_post_id.eq(source_post_id))
.order(post_links::created_at)
.select(PostLinkRecord::as_select())
.select(PostLink::as_select())
.load(c)
.map(|rows: Vec<PostLinkRecord>| rows.into_iter().map(Into::into).collect())
})
}
@@ -52,9 +50,8 @@ pub fn list_links_by_target(
post_links::table
.filter(post_links::target_post_id.eq(target_post_id))
.order(post_links::created_at)
.select(PostLinkRecord::as_select())
.select(PostLink::as_select())
.load(c)
.map(|rows: Vec<PostLinkRecord>| rows.into_iter().map(Into::into).collect())
})
}

View File

@@ -1,14 +1,13 @@
use diesel::prelude::*;
use crate::db::DbConnection;
use crate::db::from_row::PostMediaRecord;
use crate::db::schema::post_media;
use crate::model::PostMedia;
pub fn link_media(conn: &DbConnection, pm: &PostMedia) -> QueryResult<()> {
conn.with(|c| {
diesel::insert_into(post_media::table)
.values(PostMediaRecord::from(pm))
.values(pm.clone())
.execute(c)
.map(|_| ())
})
@@ -39,9 +38,8 @@ pub fn list_post_media_by_post(conn: &DbConnection, post_id: &str) -> QueryResul
post_media::table
.filter(post_media::post_id.eq(post_id))
.order(post_media::sort_order)
.select(PostMediaRecord::as_select())
.select(PostMedia::as_select())
.load(c)
.map(|rows: Vec<PostMediaRecord>| rows.into_iter().map(Into::into).collect())
})
}
@@ -53,9 +51,8 @@ pub fn list_post_media_by_media(
post_media::table
.filter(post_media::media_id.eq(media_id))
.order(post_media::created_at)
.select(PostMediaRecord::as_select())
.select(PostMedia::as_select())
.load(c)
.map(|rows: Vec<PostMediaRecord>| rows.into_iter().map(Into::into).collect())
})
}

View File

@@ -1,7 +1,6 @@
use diesel::prelude::*;
use crate::db::DbConnection;
use crate::db::from_row::{PostTranslationRecord, convert, convert_all};
use crate::db::schema::post_translations;
use crate::model::PostTranslation;
@@ -13,7 +12,7 @@ pub fn insert_post_translation(conn: &DbConnection, t: &PostTranslation) -> Quer
}
conn.with(|c| {
diesel::insert_into(post_translations::table)
.values(PostTranslationRecord::from(t))
.values(t.clone())
.execute(c)
.map(|_| ())
})
@@ -23,9 +22,8 @@ pub fn get_post_translation_by_id(conn: &DbConnection, id: &str) -> QueryResult<
conn.with(|c| {
post_translations::table
.filter(post_translations::id.eq(id))
.select(PostTranslationRecord::as_select())
.select(PostTranslation::as_select())
.first(c)
.and_then(convert)
})
}
@@ -38,9 +36,8 @@ pub fn get_post_translation_by_post_and_language(
post_translations::table
.filter(post_translations::translation_for.eq(translation_for))
.filter(post_translations::language.eq(language))
.select(PostTranslationRecord::as_select())
.select(PostTranslation::as_select())
.first(c)
.and_then(convert)
})
}
@@ -52,9 +49,8 @@ pub fn list_post_translations_by_post(
post_translations::table
.filter(post_translations::translation_for.eq(translation_for))
.order(post_translations::language)
.select(PostTranslationRecord::as_select())
.select(PostTranslation::as_select())
.load(c)
.and_then(convert_all)
})
}
@@ -66,7 +62,7 @@ pub fn update_post_translation(conn: &DbConnection, t: &PostTranslation) -> Quer
}
conn.with(|c| {
diesel::update(post_translations::table.filter(post_translations::id.eq(&t.id)))
.set(PostTranslationRecord::from(t))
.set(t.clone())
.execute(c)
.map(|_| ())
})

View File

@@ -1,14 +1,13 @@
use diesel::prelude::*;
use crate::db::DbConnection;
use crate::db::from_row::ProjectRecord;
use crate::db::schema::projects;
use crate::model::Project;
pub fn insert_project(conn: &DbConnection, project: &Project) -> QueryResult<()> {
conn.with(|c| {
diesel::insert_into(projects::table)
.values(ProjectRecord::from(project))
.values(project.clone())
.execute(c)
.map(|_| ())
})
@@ -18,9 +17,8 @@ pub fn get_project_by_id(conn: &DbConnection, id: &str) -> QueryResult<Project>
conn.with(|c| {
projects::table
.filter(projects::id.eq(id))
.select(ProjectRecord::as_select())
.select(Project::as_select())
.first(c)
.map(Into::into)
})
}
@@ -28,9 +26,8 @@ pub fn get_project_by_slug(conn: &DbConnection, slug: &str) -> QueryResult<Proje
conn.with(|c| {
projects::table
.filter(projects::slug.eq(slug))
.select(ProjectRecord::as_select())
.select(Project::as_select())
.first(c)
.map(Into::into)
})
}
@@ -38,9 +35,8 @@ pub fn get_active_project(conn: &DbConnection) -> QueryResult<Project> {
conn.with(|c| {
projects::table
.filter(projects::is_active.eq(1))
.select(ProjectRecord::as_select())
.select(Project::as_select())
.first(c)
.map(Into::into)
})
}
@@ -62,16 +58,15 @@ pub fn list_projects(conn: &DbConnection) -> QueryResult<Vec<Project>> {
conn.with(|c| {
projects::table
.order(projects::name)
.select(ProjectRecord::as_select())
.select(Project::as_select())
.load(c)
.map(|rows: Vec<ProjectRecord>| rows.into_iter().map(Into::into).collect())
})
}
pub fn update_project(conn: &DbConnection, project: &Project) -> QueryResult<()> {
conn.with(|c| {
diesel::update(projects::table.filter(projects::id.eq(&project.id)))
.set(ProjectRecord::from(project))
.set(project.clone())
.execute(c)
.map(|_| ())
})

View File

@@ -1,14 +1,13 @@
use diesel::prelude::*;
use crate::db::DbConnection;
use crate::db::from_row::{ScriptRecord, convert, convert_all};
use crate::db::schema::scripts;
use crate::model::Script;
pub fn insert_script(conn: &DbConnection, s: &Script) -> QueryResult<()> {
conn.with(|c| {
diesel::insert_into(scripts::table)
.values(ScriptRecord::from(s))
.values(s.clone())
.execute(c)
.map(|_| ())
})
@@ -18,9 +17,8 @@ pub fn get_script_by_id(conn: &DbConnection, id: &str) -> QueryResult<Script> {
conn.with(|c| {
scripts::table
.filter(scripts::id.eq(id))
.select(ScriptRecord::as_select())
.select(Script::as_select())
.first(c)
.and_then(convert)
})
}
@@ -33,9 +31,8 @@ pub fn get_script_by_slug(
scripts::table
.filter(scripts::project_id.eq(project_id))
.filter(scripts::slug.eq(slug))
.select(ScriptRecord::as_select())
.select(Script::as_select())
.first(c)
.and_then(convert)
})
}
@@ -44,16 +41,15 @@ pub fn list_scripts_by_project(conn: &DbConnection, project_id: &str) -> QueryRe
scripts::table
.filter(scripts::project_id.eq(project_id))
.order(scripts::title)
.select(ScriptRecord::as_select())
.select(Script::as_select())
.load(c)
.and_then(convert_all)
})
}
pub fn update_script(conn: &DbConnection, s: &Script) -> QueryResult<()> {
conn.with(|c| {
diesel::update(scripts::table.filter(scripts::id.eq(&s.id)))
.set(ScriptRecord::from(s))
.set(s.clone())
.execute(c)
.map(|_| ())
})

View File

@@ -1,7 +1,6 @@
use diesel::prelude::*;
use crate::db::DbConnection;
use crate::db::from_row::SettingRecord;
use crate::db::schema::settings;
use crate::model::Setting;
@@ -9,9 +8,8 @@ pub fn get_setting_by_key(conn: &DbConnection, key: &str) -> QueryResult<Setting
conn.with(|c| {
settings::table
.filter(settings::key.eq(key))
.select(SettingRecord::as_select())
.select(Setting::as_select())
.first(c)
.map(Into::into)
})
}
@@ -43,9 +41,8 @@ pub fn list_all_settings(conn: &DbConnection) -> QueryResult<Vec<Setting>> {
conn.with(|c| {
settings::table
.order(settings::key)
.select(SettingRecord::as_select())
.select(Setting::as_select())
.load(c)
.map(|rows: Vec<SettingRecord>| rows.into_iter().map(Into::into).collect())
})
}

View File

@@ -2,7 +2,6 @@ use diesel::prelude::*;
use diesel::sql_types::Text;
use crate::db::DbConnection;
use crate::db::from_row::TagRecord;
use crate::db::schema::tags;
use crate::model::Tag;
@@ -11,7 +10,7 @@ diesel::define_sql_function!(fn lower(value: Text) -> Text);
pub fn insert_tag(conn: &DbConnection, tag: &Tag) -> QueryResult<()> {
conn.with(|c| {
diesel::insert_into(tags::table)
.values(TagRecord::from(tag))
.values(tag.clone())
.execute(c)
.map(|_| ())
})
@@ -21,9 +20,8 @@ pub fn get_tag_by_id(conn: &DbConnection, id: &str) -> QueryResult<Tag> {
conn.with(|c| {
tags::table
.filter(tags::id.eq(id))
.select(TagRecord::as_select())
.select(Tag::as_select())
.first(c)
.map(Into::into)
})
}
@@ -36,9 +34,8 @@ pub fn get_tag_by_project_and_name(
tags::table
.filter(tags::project_id.eq(project_id))
.filter(lower(tags::name).eq(name.to_lowercase()))
.select(TagRecord::as_select())
.select(Tag::as_select())
.first(c)
.map(Into::into)
})
}
@@ -47,16 +44,15 @@ pub fn list_tags_by_project(conn: &DbConnection, project_id: &str) -> QueryResul
tags::table
.filter(tags::project_id.eq(project_id))
.order(tags::name)
.select(TagRecord::as_select())
.select(Tag::as_select())
.load(c)
.map(|rows: Vec<TagRecord>| rows.into_iter().map(Into::into).collect())
})
}
pub fn update_tag(conn: &DbConnection, tag: &Tag) -> QueryResult<()> {
conn.with(|c| {
diesel::update(tags::table.filter(tags::id.eq(&tag.id)))
.set(TagRecord::from(tag))
.set(tag.clone())
.execute(c)
.map(|_| ())
})

View File

@@ -1,14 +1,13 @@
use diesel::prelude::*;
use crate::db::DbConnection;
use crate::db::from_row::{TemplateRecord, convert, convert_all};
use crate::db::schema::templates;
use crate::model::Template;
pub fn insert_template(conn: &DbConnection, t: &Template) -> QueryResult<()> {
conn.with(|c| {
diesel::insert_into(templates::table)
.values(TemplateRecord::from(t))
.values(t.clone())
.execute(c)
.map(|_| ())
})
@@ -18,9 +17,8 @@ pub fn get_template_by_id(conn: &DbConnection, id: &str) -> QueryResult<Template
conn.with(|c| {
templates::table
.filter(templates::id.eq(id))
.select(TemplateRecord::as_select())
.select(Template::as_select())
.first(c)
.and_then(convert)
})
}
@@ -33,9 +31,8 @@ pub fn get_template_by_slug(
templates::table
.filter(templates::project_id.eq(project_id))
.filter(templates::slug.eq(slug))
.select(TemplateRecord::as_select())
.select(Template::as_select())
.first(c)
.and_then(convert)
})
}
@@ -47,16 +44,15 @@ pub fn list_templates_by_project(
templates::table
.filter(templates::project_id.eq(project_id))
.order(templates::title)
.select(TemplateRecord::as_select())
.select(Template::as_select())
.load(c)
.and_then(convert_all)
})
}
pub fn update_template(conn: &DbConnection, t: &Template) -> QueryResult<()> {
conn.with(|c| {
diesel::update(templates::table.filter(templates::id.eq(&t.id)))
.set(TemplateRecord::from(t))
.set(t.clone())
.execute(c)
.map(|_| ())
})