Adding a viewtovec trait.
This commit is contained in:
parent
eef93440d0
commit
afc79ce0e3
6 changed files with 116 additions and 94 deletions
|
@ -2,6 +2,7 @@ use crate::{
|
||||||
community::{Community, CommunitySafe},
|
community::{Community, CommunitySafe},
|
||||||
schema::{community, community_follower, user_},
|
schema::{community, community_follower, user_},
|
||||||
user::{UserSafe, User_},
|
user::{UserSafe, User_},
|
||||||
|
views::ViewToVec,
|
||||||
ToSafe,
|
ToSafe,
|
||||||
};
|
};
|
||||||
use diesel::{result::Error, *};
|
use diesel::{result::Error, *};
|
||||||
|
@ -13,6 +14,8 @@ pub struct CommunityFollowerView {
|
||||||
pub follower: UserSafe,
|
pub follower: UserSafe,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CommunityFollowerViewTuple = (CommunitySafe, UserSafe);
|
||||||
|
|
||||||
impl CommunityFollowerView {
|
impl CommunityFollowerView {
|
||||||
pub fn for_community(conn: &PgConnection, for_community_id: i32) -> Result<Vec<Self>, Error> {
|
pub fn for_community(conn: &PgConnection, for_community_id: i32) -> Result<Vec<Self>, Error> {
|
||||||
let res = community_follower::table
|
let res = community_follower::table
|
||||||
|
@ -21,9 +24,9 @@ impl CommunityFollowerView {
|
||||||
.select((Community::safe_columns_tuple(), User_::safe_columns_tuple()))
|
.select((Community::safe_columns_tuple(), User_::safe_columns_tuple()))
|
||||||
.filter(community_follower::community_id.eq(for_community_id))
|
.filter(community_follower::community_id.eq(for_community_id))
|
||||||
.order_by(community_follower::published)
|
.order_by(community_follower::published)
|
||||||
.load::<(CommunitySafe, UserSafe)>(conn)?;
|
.load::<CommunityFollowerViewTuple>(conn)?;
|
||||||
|
|
||||||
Ok(to_vec(res))
|
Ok(Self::to_vec(res))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn for_user(conn: &PgConnection, for_user_id: i32) -> Result<Vec<Self>, Error> {
|
pub fn for_user(conn: &PgConnection, for_user_id: i32) -> Result<Vec<Self>, Error> {
|
||||||
|
@ -33,18 +36,21 @@ impl CommunityFollowerView {
|
||||||
.select((Community::safe_columns_tuple(), User_::safe_columns_tuple()))
|
.select((Community::safe_columns_tuple(), User_::safe_columns_tuple()))
|
||||||
.filter(community_follower::user_id.eq(for_user_id))
|
.filter(community_follower::user_id.eq(for_user_id))
|
||||||
.order_by(community_follower::published)
|
.order_by(community_follower::published)
|
||||||
.load::<(CommunitySafe, UserSafe)>(conn)?;
|
.load::<CommunityFollowerViewTuple>(conn)?;
|
||||||
|
|
||||||
Ok(to_vec(res))
|
Ok(Self::to_vec(res))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_vec(users: Vec<(CommunitySafe, UserSafe)>) -> Vec<CommunityFollowerView> {
|
impl ViewToVec for CommunityFollowerView {
|
||||||
|
type DbTuple = CommunityFollowerViewTuple;
|
||||||
|
fn to_vec(users: Vec<Self::DbTuple>) -> Vec<Self> {
|
||||||
users
|
users
|
||||||
.iter()
|
.iter()
|
||||||
.map(|a| CommunityFollowerView {
|
.map(|a| Self {
|
||||||
community: a.0.to_owned(),
|
community: a.0.to_owned(),
|
||||||
follower: a.1.to_owned(),
|
follower: a.1.to_owned(),
|
||||||
})
|
})
|
||||||
.collect::<Vec<CommunityFollowerView>>()
|
.collect::<Vec<Self>>()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ use crate::{
|
||||||
community::{Community, CommunitySafe},
|
community::{Community, CommunitySafe},
|
||||||
schema::{community, community_moderator, user_},
|
schema::{community, community_moderator, user_},
|
||||||
user::{UserSafe, User_},
|
user::{UserSafe, User_},
|
||||||
|
views::ViewToVec,
|
||||||
ToSafe,
|
ToSafe,
|
||||||
};
|
};
|
||||||
use diesel::{result::Error, *};
|
use diesel::{result::Error, *};
|
||||||
|
@ -13,6 +14,8 @@ pub struct CommunityModeratorView {
|
||||||
pub moderator: UserSafe,
|
pub moderator: UserSafe,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CommunityModeratorViewTuple = (CommunitySafe, UserSafe);
|
||||||
|
|
||||||
impl CommunityModeratorView {
|
impl CommunityModeratorView {
|
||||||
pub fn for_community(conn: &PgConnection, for_community_id: i32) -> Result<Vec<Self>, Error> {
|
pub fn for_community(conn: &PgConnection, for_community_id: i32) -> Result<Vec<Self>, Error> {
|
||||||
let res = community_moderator::table
|
let res = community_moderator::table
|
||||||
|
@ -21,9 +24,9 @@ impl CommunityModeratorView {
|
||||||
.select((Community::safe_columns_tuple(), User_::safe_columns_tuple()))
|
.select((Community::safe_columns_tuple(), User_::safe_columns_tuple()))
|
||||||
.filter(community_moderator::community_id.eq(for_community_id))
|
.filter(community_moderator::community_id.eq(for_community_id))
|
||||||
.order_by(community_moderator::published)
|
.order_by(community_moderator::published)
|
||||||
.load::<(CommunitySafe, UserSafe)>(conn)?;
|
.load::<CommunityModeratorViewTuple>(conn)?;
|
||||||
|
|
||||||
Ok(to_vec(res))
|
Ok(Self::to_vec(res))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn for_user(conn: &PgConnection, for_user_id: i32) -> Result<Vec<Self>, Error> {
|
pub fn for_user(conn: &PgConnection, for_user_id: i32) -> Result<Vec<Self>, Error> {
|
||||||
|
@ -33,18 +36,21 @@ impl CommunityModeratorView {
|
||||||
.select((Community::safe_columns_tuple(), User_::safe_columns_tuple()))
|
.select((Community::safe_columns_tuple(), User_::safe_columns_tuple()))
|
||||||
.filter(community_moderator::user_id.eq(for_user_id))
|
.filter(community_moderator::user_id.eq(for_user_id))
|
||||||
.order_by(community_moderator::published)
|
.order_by(community_moderator::published)
|
||||||
.load::<(CommunitySafe, UserSafe)>(conn)?;
|
.load::<CommunityModeratorViewTuple>(conn)?;
|
||||||
|
|
||||||
Ok(to_vec(res))
|
Ok(Self::to_vec(res))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_vec(users: Vec<(CommunitySafe, UserSafe)>) -> Vec<CommunityModeratorView> {
|
impl ViewToVec for CommunityModeratorView {
|
||||||
users
|
type DbTuple = CommunityModeratorViewTuple;
|
||||||
|
fn to_vec(community_moderators: Vec<Self::DbTuple>) -> Vec<Self> {
|
||||||
|
community_moderators
|
||||||
.iter()
|
.iter()
|
||||||
.map(|a| CommunityModeratorView {
|
.map(|a| Self {
|
||||||
community: a.0.to_owned(),
|
community: a.0.to_owned(),
|
||||||
moderator: a.1.to_owned(),
|
moderator: a.1.to_owned(),
|
||||||
})
|
})
|
||||||
.collect::<Vec<CommunityModeratorView>>()
|
.collect::<Vec<Self>>()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ use crate::{
|
||||||
limit_and_offset,
|
limit_and_offset,
|
||||||
schema::{category, community, community_aggregates, community_follower, user_},
|
schema::{category, community, community_aggregates, community_follower, user_},
|
||||||
user::{UserSafe, User_},
|
user::{UserSafe, User_},
|
||||||
|
views::ViewToVec,
|
||||||
MaybeOptional,
|
MaybeOptional,
|
||||||
SortType,
|
SortType,
|
||||||
ToSafe,
|
ToSafe,
|
||||||
|
@ -23,6 +24,14 @@ pub struct CommunityView {
|
||||||
pub counts: CommunityAggregates,
|
pub counts: CommunityAggregates,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CommunityViewTuple = (
|
||||||
|
CommunitySafe,
|
||||||
|
UserSafe,
|
||||||
|
Category,
|
||||||
|
CommunityAggregates,
|
||||||
|
Option<CommunityFollower>,
|
||||||
|
);
|
||||||
|
|
||||||
impl CommunityView {
|
impl CommunityView {
|
||||||
pub fn read(
|
pub fn read(
|
||||||
conn: &PgConnection,
|
conn: &PgConnection,
|
||||||
|
@ -51,13 +60,7 @@ impl CommunityView {
|
||||||
community_aggregates::all_columns,
|
community_aggregates::all_columns,
|
||||||
community_follower::all_columns.nullable(),
|
community_follower::all_columns.nullable(),
|
||||||
))
|
))
|
||||||
.first::<(
|
.first::<CommunityViewTuple>(conn)?;
|
||||||
CommunitySafe,
|
|
||||||
UserSafe,
|
|
||||||
Category,
|
|
||||||
CommunityAggregates,
|
|
||||||
Option<CommunityFollower>,
|
|
||||||
)>(conn)?;
|
|
||||||
|
|
||||||
Ok(CommunityView {
|
Ok(CommunityView {
|
||||||
community,
|
community,
|
||||||
|
@ -270,35 +273,24 @@ impl<'a> CommunityQueryBuilder<'a> {
|
||||||
.offset(offset)
|
.offset(offset)
|
||||||
.filter(community::removed.eq(false))
|
.filter(community::removed.eq(false))
|
||||||
.filter(community::deleted.eq(false))
|
.filter(community::deleted.eq(false))
|
||||||
.load::<(
|
.load::<CommunityViewTuple>(self.conn)?;
|
||||||
CommunitySafe,
|
|
||||||
UserSafe,
|
|
||||||
Category,
|
|
||||||
CommunityAggregates,
|
|
||||||
Option<CommunityFollower>,
|
|
||||||
)>(self.conn)?;
|
|
||||||
|
|
||||||
Ok(to_vec(res))
|
Ok(CommunityView::to_vec(res))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_vec(
|
impl ViewToVec for CommunityView {
|
||||||
users: Vec<(
|
type DbTuple = CommunityViewTuple;
|
||||||
CommunitySafe,
|
fn to_vec(communities: Vec<Self::DbTuple>) -> Vec<Self> {
|
||||||
UserSafe,
|
communities
|
||||||
Category,
|
|
||||||
CommunityAggregates,
|
|
||||||
Option<CommunityFollower>,
|
|
||||||
)>,
|
|
||||||
) -> Vec<CommunityView> {
|
|
||||||
users
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|a| CommunityView {
|
.map(|a| Self {
|
||||||
community: a.0.to_owned(),
|
community: a.0.to_owned(),
|
||||||
creator: a.1.to_owned(),
|
creator: a.1.to_owned(),
|
||||||
category: a.2.to_owned(),
|
category: a.2.to_owned(),
|
||||||
counts: a.3.to_owned(),
|
counts: a.3.to_owned(),
|
||||||
subscribed: a.4.is_some(),
|
subscribed: a.4.is_some(),
|
||||||
})
|
})
|
||||||
.collect::<Vec<CommunityView>>()
|
.collect::<Vec<Self>>()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,3 +5,10 @@ pub mod community_view;
|
||||||
pub mod post_view;
|
pub mod post_view;
|
||||||
pub mod site_view;
|
pub mod site_view;
|
||||||
pub mod user_view;
|
pub mod user_view;
|
||||||
|
|
||||||
|
pub(crate) trait ViewToVec {
|
||||||
|
type DbTuple;
|
||||||
|
fn to_vec(tuple: Vec<Self::DbTuple>) -> Vec<Self>
|
||||||
|
where
|
||||||
|
Self: Sized;
|
||||||
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ use crate::{
|
||||||
user_,
|
user_,
|
||||||
},
|
},
|
||||||
user::{UserSafe, User_},
|
user::{UserSafe, User_},
|
||||||
|
views::ViewToVec,
|
||||||
ListingType,
|
ListingType,
|
||||||
MaybeOptional,
|
MaybeOptional,
|
||||||
SortType,
|
SortType,
|
||||||
|
@ -38,7 +39,7 @@ pub struct PostView {
|
||||||
pub my_vote: Option<i16>, // Left join to PostLike
|
pub my_vote: Option<i16>, // Left join to PostLike
|
||||||
}
|
}
|
||||||
|
|
||||||
type OutputTuple = (
|
type PostViewTuple = (
|
||||||
Post,
|
Post,
|
||||||
UserSafe,
|
UserSafe,
|
||||||
CommunitySafe,
|
CommunitySafe,
|
||||||
|
@ -107,7 +108,7 @@ impl PostView {
|
||||||
post_read::all_columns.nullable(),
|
post_read::all_columns.nullable(),
|
||||||
post_like::score.nullable(),
|
post_like::score.nullable(),
|
||||||
))
|
))
|
||||||
.first::<OutputTuple>(conn)?;
|
.first::<PostViewTuple>(conn)?;
|
||||||
|
|
||||||
Ok(PostView {
|
Ok(PostView {
|
||||||
post,
|
post,
|
||||||
|
@ -551,17 +552,18 @@ impl<'a> PostQueryBuilder<'a> {
|
||||||
.filter(post::deleted.eq(false))
|
.filter(post::deleted.eq(false))
|
||||||
.filter(community::removed.eq(false))
|
.filter(community::removed.eq(false))
|
||||||
.filter(community::deleted.eq(false))
|
.filter(community::deleted.eq(false))
|
||||||
.load::<OutputTuple>(self.conn)?;
|
.load::<PostViewTuple>(self.conn)?;
|
||||||
|
|
||||||
Ok(to_vec(res))
|
Ok(PostView::to_vec(res))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO turn this into a trait with an associated type
|
impl ViewToVec for PostView {
|
||||||
fn to_vec(posts: Vec<OutputTuple>) -> Vec<PostView> {
|
type DbTuple = PostViewTuple;
|
||||||
|
fn to_vec(posts: Vec<Self::DbTuple>) -> Vec<Self> {
|
||||||
posts
|
posts
|
||||||
.iter()
|
.iter()
|
||||||
.map(|a| PostView {
|
.map(|a| Self {
|
||||||
post: a.0.to_owned(),
|
post: a.0.to_owned(),
|
||||||
creator: a.1.to_owned(),
|
creator: a.1.to_owned(),
|
||||||
community: a.2.to_owned(),
|
community: a.2.to_owned(),
|
||||||
|
@ -572,5 +574,6 @@ fn to_vec(posts: Vec<OutputTuple>) -> Vec<PostView> {
|
||||||
read: a.7.is_some(),
|
read: a.7.is_some(),
|
||||||
my_vote: a.8,
|
my_vote: a.8,
|
||||||
})
|
})
|
||||||
.collect::<Vec<PostView>>()
|
.collect::<Vec<Self>>()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ use crate::{
|
||||||
limit_and_offset,
|
limit_and_offset,
|
||||||
schema::{user_, user_aggregates},
|
schema::{user_, user_aggregates},
|
||||||
user::{UserSafe, User_},
|
user::{UserSafe, User_},
|
||||||
|
views::ViewToVec,
|
||||||
MaybeOptional,
|
MaybeOptional,
|
||||||
SortType,
|
SortType,
|
||||||
ToSafe,
|
ToSafe,
|
||||||
|
@ -17,18 +18,22 @@ pub struct UserViewSafe {
|
||||||
pub counts: UserAggregates,
|
pub counts: UserAggregates,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UserViewSafeTuple = (UserSafe, UserAggregates);
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Clone)]
|
#[derive(Debug, Serialize, Clone)]
|
||||||
pub struct UserViewDangerous {
|
pub struct UserViewDangerous {
|
||||||
pub user: User_,
|
pub user: User_,
|
||||||
pub counts: UserAggregates,
|
pub counts: UserAggregates,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UserViewDangerousTuple = (User_, UserAggregates);
|
||||||
|
|
||||||
impl UserViewDangerous {
|
impl UserViewDangerous {
|
||||||
pub fn read(conn: &PgConnection, id: i32) -> Result<Self, Error> {
|
pub fn read(conn: &PgConnection, id: i32) -> Result<Self, Error> {
|
||||||
let (user, counts) = user_::table
|
let (user, counts) = user_::table
|
||||||
.find(id)
|
.find(id)
|
||||||
.inner_join(user_aggregates::table)
|
.inner_join(user_aggregates::table)
|
||||||
.first::<(User_, UserAggregates)>(conn)?;
|
.first::<UserViewDangerousTuple>(conn)?;
|
||||||
Ok(Self { user, counts })
|
Ok(Self { user, counts })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,7 +44,7 @@ impl UserViewSafe {
|
||||||
.find(id)
|
.find(id)
|
||||||
.inner_join(user_aggregates::table)
|
.inner_join(user_aggregates::table)
|
||||||
.select((User_::safe_columns_tuple(), user_aggregates::all_columns))
|
.select((User_::safe_columns_tuple(), user_aggregates::all_columns))
|
||||||
.first::<(UserSafe, UserAggregates)>(conn)?;
|
.first::<UserViewSafeTuple>(conn)?;
|
||||||
Ok(Self { user, counts })
|
Ok(Self { user, counts })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,9 +54,9 @@ impl UserViewSafe {
|
||||||
.select((User_::safe_columns_tuple(), user_aggregates::all_columns))
|
.select((User_::safe_columns_tuple(), user_aggregates::all_columns))
|
||||||
.filter(user_::admin.eq(true))
|
.filter(user_::admin.eq(true))
|
||||||
.order_by(user_::published)
|
.order_by(user_::published)
|
||||||
.load::<(UserSafe, UserAggregates)>(conn)?;
|
.load::<UserViewSafeTuple>(conn)?;
|
||||||
|
|
||||||
Ok(to_vec(admins))
|
Ok(Self::to_vec(admins))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn banned(conn: &PgConnection) -> Result<Vec<Self>, Error> {
|
pub fn banned(conn: &PgConnection) -> Result<Vec<Self>, Error> {
|
||||||
|
@ -59,9 +64,9 @@ impl UserViewSafe {
|
||||||
.inner_join(user_aggregates::table)
|
.inner_join(user_aggregates::table)
|
||||||
.select((User_::safe_columns_tuple(), user_aggregates::all_columns))
|
.select((User_::safe_columns_tuple(), user_aggregates::all_columns))
|
||||||
.filter(user_::banned.eq(true))
|
.filter(user_::banned.eq(true))
|
||||||
.load::<(UserSafe, UserAggregates)>(conn)?;
|
.load::<UserViewSafeTuple>(conn)?;
|
||||||
|
|
||||||
Ok(to_vec(banned))
|
Ok(Self::to_vec(banned))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,18 +191,21 @@ impl<'a> UserQueryBuilder<'a> {
|
||||||
let (limit, offset) = limit_and_offset(self.page, self.limit);
|
let (limit, offset) = limit_and_offset(self.page, self.limit);
|
||||||
query = query.limit(limit).offset(offset);
|
query = query.limit(limit).offset(offset);
|
||||||
|
|
||||||
let res = query.load::<(UserSafe, UserAggregates)>(self.conn)?;
|
let res = query.load::<UserViewSafeTuple>(self.conn)?;
|
||||||
|
|
||||||
Ok(to_vec(res))
|
Ok(UserViewSafe::to_vec(res))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_vec(users: Vec<(UserSafe, UserAggregates)>) -> Vec<UserViewSafe> {
|
impl ViewToVec for UserViewSafe {
|
||||||
|
type DbTuple = UserViewSafeTuple;
|
||||||
|
fn to_vec(users: Vec<Self::DbTuple>) -> Vec<Self> {
|
||||||
users
|
users
|
||||||
.iter()
|
.iter()
|
||||||
.map(|a| UserViewSafe {
|
.map(|a| Self {
|
||||||
user: a.0.to_owned(),
|
user: a.0.to_owned(),
|
||||||
counts: a.1.to_owned(),
|
counts: a.1.to_owned(),
|
||||||
})
|
})
|
||||||
.collect::<Vec<UserViewSafe>>()
|
.collect::<Vec<Self>>()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue