Blog attempt 5
at trunk 81 lines 2.3 kB view raw
1use super::Post; 2use crate::{ 3 W, 4 error::{AppError, Result}, 5}; 6 7pub enum PostSource { 8 Draft, 9 Post(String), 10} 11 12pub fn all(conn: &W) -> Result<Vec<Post>> { 13 let conn = conn.lock()?; 14 15 let mut stmt = conn.prepare("SELECT title, contents, slug, subtitle, category, bsky_uri, creation_datetime FROM post") 16 .map_err(AppError::from)?; 17 18 let posts_result: rusqlite::Result<Vec<Post>> = stmt 19 .query_map([], |row| { 20 Ok(Post { 21 title: row.get(0)?, 22 contents: row.get(1)?, 23 slug: row.get(2)?, 24 subtitle: row.get(3)?, 25 category: row.get(4)?, 26 bsky_uri: row.get(5)?, 27 creation_datetime: row.get(6)?, 28 }) 29 })? 30 .collect(); 31 32 let mut posts = posts_result.map_err(AppError::from)?; 33 posts.sort_by(|a, b| { 34 a.creation_datetime 35 .partial_cmp(&b.creation_datetime) 36 .unwrap_or(std::cmp::Ordering::Equal) 37 .reverse() 38 }); 39 Ok(posts) 40} 41 42pub fn one(slug: String, conn: &W) -> Result<Post> { 43 fetch_post_inner(&PostSource::Post(slug), conn) 44} 45 46pub fn one_draft(conn: &W) -> Result<Post> { 47 fetch_post_inner(&PostSource::Draft, conn) 48} 49 50fn fetch_post_inner(source: &PostSource, conn: &W) -> Result<Post> { 51 let conn = conn.lock()?; 52 53 let (query, params): (&str, Vec<&dyn rusqlite::ToSql>) = match source { 54 PostSource::Post(slug) => ( 55 "SELECT title, contents, slug, subtitle, category, bsky_uri, creation_datetime FROM post WHERE slug = ?1", 56 vec![slug], 57 ), 58 PostSource::Draft => ( 59 "SELECT title, contents, slug, subtitle, category, bsky_uri, creation_datetime FROM draft", 60 vec![], 61 ), 62 }; 63 64 let mut stmt = conn.prepare(query).map_err(AppError::from)?; 65 66 let post = stmt 67 .query_one(params.as_slice(), |row| { 68 Ok(Post { 69 title: row.get(0)?, 70 contents: row.get(1)?, 71 slug: row.get(2)?, 72 subtitle: row.get(3)?, 73 category: row.get(4)?, 74 bsky_uri: row.get(5)?, 75 creation_datetime: row.get(6)?, 76 }) 77 }) 78 .map_err(AppError::from)?; 79 80 Ok(post) 81}