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…
Reference in a new issue