refactor(db): Store thread body in the posts table
This is a simplification over the previous approach. The OP of a thread is just a normal post like any other in this model, which allows some code simplifications (and future query convenience).
This commit is contained in:
		
							parent
							
								
									a90d1cc1a4
								
							
						
					
					
						commit
						8c30ef92f6
					
				
					 5 changed files with 36 additions and 23 deletions
				
			
		
							
								
								
									
										31
									
								
								src/db.rs
									
										
									
									
									
								
							
							
						
						
									
										31
									
								
								src/db.rs
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -5,7 +5,7 @@ use diesel;
 | 
			
		|||
use diesel::prelude::*;
 | 
			
		||||
use diesel::r2d2::{Pool, ConnectionManager};
 | 
			
		||||
use models::*;
 | 
			
		||||
use errors::Result;
 | 
			
		||||
use errors::{ConverseError, Result};
 | 
			
		||||
 | 
			
		||||
/// The DB actor itself. Several of these will be run in parallel by
 | 
			
		||||
/// `SyncArbiter`.
 | 
			
		||||
| 
						 | 
				
			
			@ -62,7 +62,10 @@ impl Handler<GetThread> for DbExecutor {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
/// Message used to create a new thread
 | 
			
		||||
pub struct CreateThread(pub NewThread);
 | 
			
		||||
pub struct CreateThread {
 | 
			
		||||
    pub new_thread: NewThread,
 | 
			
		||||
    pub body: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Message for CreateThread {
 | 
			
		||||
    type Result = Result<Thread>;
 | 
			
		||||
| 
						 | 
				
			
			@ -73,12 +76,30 @@ impl Handler<CreateThread> for DbExecutor {
 | 
			
		|||
 | 
			
		||||
    fn handle(&mut self, msg: CreateThread, _: &mut Self::Context) -> Self::Result {
 | 
			
		||||
        use schema::threads;
 | 
			
		||||
        use schema::posts;
 | 
			
		||||
 | 
			
		||||
        let conn = self.0.get()?;
 | 
			
		||||
 | 
			
		||||
        Ok(diesel::insert_into(threads::table)
 | 
			
		||||
           .values(&msg.0)
 | 
			
		||||
           .get_result(&conn)?)
 | 
			
		||||
        conn.transaction::<Thread, ConverseError, _>(|| {
 | 
			
		||||
            // First insert the thread structure itself
 | 
			
		||||
            let thread: Thread = diesel::insert_into(threads::table)
 | 
			
		||||
                .values(&msg.new_thread)
 | 
			
		||||
                .get_result(&conn)?;
 | 
			
		||||
 | 
			
		||||
            // ... then create the first post in the thread.
 | 
			
		||||
            let new_post = NewPost {
 | 
			
		||||
                thread_id: thread.id,
 | 
			
		||||
                body: msg.body,
 | 
			
		||||
                author_name: msg.new_thread.author_name.clone(),
 | 
			
		||||
                author_email: msg.new_thread.author_email.clone(),
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            diesel::insert_into(posts::table)
 | 
			
		||||
                .values(&new_post)
 | 
			
		||||
                .execute(&conn)?;
 | 
			
		||||
 | 
			
		||||
            Ok(thread)
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -105,12 +105,16 @@ pub fn submit_thread(state: State<AppState>,
 | 
			
		|||
 | 
			
		||||
    let new_thread = NewThread {
 | 
			
		||||
        title: input.0.title,
 | 
			
		||||
        body: input.0.body,
 | 
			
		||||
        author_name: author.name,
 | 
			
		||||
        author_email: author.email,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    state.db.send(CreateThread(new_thread))
 | 
			
		||||
    let msg = CreateThread {
 | 
			
		||||
        new_thread,
 | 
			
		||||
        body: input.0.body,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    state.db.send(msg)
 | 
			
		||||
        .from_err()
 | 
			
		||||
        .and_then(move |res| {
 | 
			
		||||
            let thread = res?;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,7 +5,6 @@ use schema::{threads, posts};
 | 
			
		|||
pub struct Thread {
 | 
			
		||||
    pub id: i32,
 | 
			
		||||
    pub title: String,
 | 
			
		||||
    pub body: String,
 | 
			
		||||
    pub posted: DateTime<Utc>,
 | 
			
		||||
    pub author_name: String,
 | 
			
		||||
    pub author_email: String,
 | 
			
		||||
| 
						 | 
				
			
			@ -26,7 +25,6 @@ pub struct Post {
 | 
			
		|||
#[table_name="threads"]
 | 
			
		||||
pub struct NewThread {
 | 
			
		||||
    pub title: String,
 | 
			
		||||
    pub body: String,
 | 
			
		||||
    pub author_name: String,
 | 
			
		||||
    pub author_email: String,
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -101,24 +101,15 @@ fn md5_hex(input: &[u8]) -> String {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
fn prepare_thread(comrak: &ComrakOptions, page: ThreadPage) -> RenderableThreadPage {
 | 
			
		||||
    let mut posts = vec![RenderablePost {
 | 
			
		||||
        // Always pin the ID of the first post.
 | 
			
		||||
        id: 0,
 | 
			
		||||
        body: markdown_to_html(&page.thread.body, comrak),
 | 
			
		||||
        posted: page.thread.posted.into(),
 | 
			
		||||
        author_name: page.thread.author_name,
 | 
			
		||||
        author_gravatar: md5_hex(page.thread.author_email.as_bytes()),
 | 
			
		||||
    }];
 | 
			
		||||
 | 
			
		||||
    for post in page.posts {
 | 
			
		||||
        posts.push(RenderablePost {
 | 
			
		||||
    let posts = page.posts.into_iter().map(|post| {
 | 
			
		||||
        RenderablePost {
 | 
			
		||||
            id: post.id,
 | 
			
		||||
            body: markdown_to_html(&post.body, comrak),
 | 
			
		||||
            posted: post.posted.into(),
 | 
			
		||||
            author_name: post.author_name,
 | 
			
		||||
            author_gravatar: md5_hex(post.author_email.as_bytes()),
 | 
			
		||||
        });
 | 
			
		||||
        }
 | 
			
		||||
    }).collect();
 | 
			
		||||
 | 
			
		||||
    RenderableThreadPage {
 | 
			
		||||
        posts,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,7 +13,6 @@ table! {
 | 
			
		|||
    threads (id) {
 | 
			
		||||
        id -> Int4,
 | 
			
		||||
        title -> Varchar,
 | 
			
		||||
        body -> Text,
 | 
			
		||||
        posted -> Timestamptz,
 | 
			
		||||
        author_name -> Varchar,
 | 
			
		||||
        author_email -> Varchar,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue