refactor(db/render/schema): Use SimplePost type for thread views

This uses the simplified view for querying posts instead of the post
table directly to display posts.
This commit is contained in:
Vincent Ambo 2018-05-01 20:49:19 +02:00 committed by Vincent Ambo
parent 9d5830e9a7
commit 9b1f6d3628
4 changed files with 69 additions and 32 deletions

View file

@ -55,22 +55,22 @@ impl Handler<ListThreads> for DbExecutor {
/// Message used to fetch a specific thread. Returns the thread and
/// its posts.
pub struct GetThread(pub i32);
message!(GetThread, Result<(Thread, Vec<Post>)>);
message!(GetThread, Result<(Thread, Vec<SimplePost>)>);
impl Handler<GetThread> for DbExecutor {
type Result = <GetThread as Message>::Result;
fn handle(&mut self, msg: GetThread, _: &mut Self::Context) -> Self::Result {
use schema::threads::dsl::*;
use schema::posts::dsl::id;
use schema::simple_posts::dsl::id;
let conn = self.0.get()?;
let thread_result: Thread = threads
.find(msg.0).first(&conn)?;
let post_list = Post::belonging_to(&thread_result)
let post_list = SimplePost::belonging_to(&thread_result)
.order_by(id.asc())
.load::<Post>(&conn)?;
.load::<SimplePost>(&conn)?;
Ok((thread_result, post_list))
}
@ -80,15 +80,15 @@ impl Handler<GetThread> for DbExecutor {
#[derive(Deserialize, Debug)]
pub struct GetPost { pub id: i32 }
message!(GetPost, Result<Post>);
message!(GetPost, Result<SimplePost>);
impl Handler<GetPost> for DbExecutor {
type Result = <GetPost as Message>::Result;
fn handle(&mut self, msg: GetPost, _: &mut Self::Context) -> Self::Result {
use schema::posts::dsl::*;
use schema::simple_posts::dsl::*;
let conn = self.0.get()?;
Ok(posts.find(msg.id).first(&conn)?)
Ok(simple_posts.find(msg.id).first(&conn)?)
}
}
@ -141,8 +141,7 @@ impl Handler<CreateThread> for DbExecutor {
let new_post = NewPost {
thread_id: thread.id,
body: msg.post,
author_name: msg.new_thread.author_name.clone(),
author_email: msg.new_thread.author_email.clone(),
user_id: msg.new_thread.user_id,
};
diesel::insert_into(posts::table)

View file

@ -17,22 +17,58 @@
// <http://www.gnu.org/licenses/>.
use chrono::prelude::{DateTime, Utc};
use schema::{threads, posts};
use schema::{users, threads, posts, simple_posts};
use diesel::sql_types::{Text, Integer};
/// Represents a single user in the Converse database. Converse does
/// not handle logins itself, but rather looks them up based on the
/// email address received from an OIDC provider.
#[derive(Identifiable, Queryable, Serialize)]
pub struct User {
pub id: i32,
pub name: String,
pub email: String,
pub admin: bool,
}
#[derive(Identifiable, Queryable, Serialize, Associations)]
#[belongs_to(User)]
pub struct Thread {
pub id: i32,
pub title: String,
pub posted: DateTime<Utc>,
pub author_name: String,
pub author_email: String,
pub sticky: bool,
pub user_id: i32,
}
/// This struct is used as the query type for the thread index view,
/// which lists the index of threads ordered by the last post in each
/// thread.
#[derive(Identifiable, Queryable, Serialize, Associations)]
#[belongs_to(Thread)]
#[belongs_to(User)]
pub struct Post {
pub id: i32,
pub thread_id: i32,
pub body: String,
pub posted: DateTime<Utc>,
pub user_id: i32,
}
/// This struct is used as the query result type for the simplified
/// post view, which already joins user information in the database.
#[derive(Identifiable, Queryable, Serialize, Associations)]
#[belongs_to(Thread)]
pub struct SimplePost {
pub id: i32,
pub thread_id: i32,
pub body: String,
pub posted: DateTime<Utc>,
pub user_id: i32,
pub author_name: String,
pub author_email: String,
}
/// This struct is used as the query result type for the thread index
/// view, which lists the index of threads ordered by the last post in
/// each thread.
#[derive(Queryable, Serialize)]
pub struct ThreadIndex {
pub thread_id: i32,
@ -45,23 +81,11 @@ pub struct ThreadIndex {
pub posted: DateTime<Utc>,
}
#[derive(Identifiable, Queryable, Serialize, Associations)]
#[belongs_to(Thread)]
pub struct Post {
pub id: i32,
pub thread_id: i32,
pub body: String,
pub posted: DateTime<Utc>,
pub author_name: String,
pub author_email: String,
}
#[derive(Deserialize, Insertable)]
#[table_name="threads"]
pub struct NewThread {
pub title: String,
pub author_name: String,
pub author_email: String,
pub user_id: i32,
}
#[derive(Deserialize, Insertable)]
@ -69,8 +93,7 @@ pub struct NewThread {
pub struct NewPost {
pub thread_id: i32,
pub body: String,
pub author_name: String,
pub author_email: String,
pub user_id: i32,
}
/// This struct models the response of a full-text search query. It

View file

@ -89,7 +89,7 @@ impl Handler<IndexPage> for Renderer {
pub struct ThreadPage {
pub current_user: Option<String>,
pub thread: Thread,
pub posts: Vec<Post>,
pub posts: Vec<SimplePost>,
}
message!(ThreadPage, Result<String>);

View file

@ -47,7 +47,20 @@ table! {
// Note: Manually inserted as print-schema does not add views.
table! {
thread_index (thread_id){
simple_posts (id) {
id -> Int4,
thread_id -> Int4,
body -> Text,
posted -> Timestamptz,
user_id -> Int4,
author_name -> Text,
author_email -> Text,
}
}
// Note: Manually inserted as print-schema does not add views.
table! {
thread_index (thread_id) {
thread_id -> Int4,
title -> Text,
thread_author -> Text,
@ -62,9 +75,11 @@ table! {
joinable!(posts -> threads (thread_id));
joinable!(posts -> users (user_id));
joinable!(threads -> users (user_id));
joinable!(simple_posts -> threads (thread_id));
allow_tables_to_appear_in_same_query!(
posts,
threads,
users,
simple_posts,
);