]> Untitled Git - lemmy.git/blob - server/src/db/community.rs
Merge remote-tracking branch 'upstream/master'
[lemmy.git] / server / src / db / community.rs
1 use super::*;
2 use crate::schema::{community, community_follower, community_moderator, community_user_ban};
3
4 #[derive(Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
5 #[table_name = "community"]
6 pub struct Community {
7   pub id: i32,
8   pub name: String,
9   pub title: String,
10   pub description: Option<String>,
11   pub category_id: i32,
12   pub creator_id: i32,
13   pub removed: bool,
14   pub published: chrono::NaiveDateTime,
15   pub updated: Option<chrono::NaiveDateTime>,
16   pub deleted: bool,
17   pub nsfw: bool,
18 }
19
20 #[derive(Insertable, AsChangeset, Clone, Serialize, Deserialize)]
21 #[table_name = "community"]
22 pub struct CommunityForm {
23   pub name: String,
24   pub title: String,
25   pub description: Option<String>,
26   pub category_id: i32,
27   pub creator_id: i32,
28   pub removed: Option<bool>,
29   pub updated: Option<chrono::NaiveDateTime>,
30   pub deleted: Option<bool>,
31   pub nsfw: bool,
32 }
33
34 impl Crud<CommunityForm> for Community {
35   fn read(conn: &PgConnection, community_id: i32) -> Result<Self, Error> {
36     use crate::schema::community::dsl::*;
37     community.find(community_id).first::<Self>(conn)
38   }
39
40   fn delete(conn: &PgConnection, community_id: i32) -> Result<usize, Error> {
41     use crate::schema::community::dsl::*;
42     diesel::delete(community.find(community_id)).execute(conn)
43   }
44
45   fn create(conn: &PgConnection, new_community: &CommunityForm) -> Result<Self, Error> {
46     use crate::schema::community::dsl::*;
47     insert_into(community)
48       .values(new_community)
49       .get_result::<Self>(conn)
50   }
51
52   fn update(
53     conn: &PgConnection,
54     community_id: i32,
55     new_community: &CommunityForm,
56   ) -> Result<Self, Error> {
57     use crate::schema::community::dsl::*;
58     diesel::update(community.find(community_id))
59       .set(new_community)
60       .get_result::<Self>(conn)
61   }
62 }
63
64 impl Community {
65   pub fn read_from_name(conn: &PgConnection, community_name: String) -> Result<Self, Error> {
66     use crate::schema::community::dsl::*;
67     community
68       .filter(name.eq(community_name))
69       .first::<Self>(conn)
70   }
71
72   pub fn get_url(&self) -> String {
73     format!("https://{}/c/{}", Settings::get().hostname, self.name)
74   }
75 }
76
77 #[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
78 #[belongs_to(Community)]
79 #[table_name = "community_moderator"]
80 pub struct CommunityModerator {
81   pub id: i32,
82   pub community_id: i32,
83   pub user_id: i32,
84   pub published: chrono::NaiveDateTime,
85 }
86
87 #[derive(Insertable, AsChangeset, Clone)]
88 #[table_name = "community_moderator"]
89 pub struct CommunityModeratorForm {
90   pub community_id: i32,
91   pub user_id: i32,
92 }
93
94 impl Joinable<CommunityModeratorForm> for CommunityModerator {
95   fn join(
96     conn: &PgConnection,
97     community_user_form: &CommunityModeratorForm,
98   ) -> Result<Self, Error> {
99     use crate::schema::community_moderator::dsl::*;
100     insert_into(community_moderator)
101       .values(community_user_form)
102       .get_result::<Self>(conn)
103   }
104
105   fn leave(
106     conn: &PgConnection,
107     community_user_form: &CommunityModeratorForm,
108   ) -> Result<usize, Error> {
109     use crate::schema::community_moderator::dsl::*;
110     diesel::delete(
111       community_moderator
112         .filter(community_id.eq(community_user_form.community_id))
113         .filter(user_id.eq(community_user_form.user_id)),
114     )
115     .execute(conn)
116   }
117 }
118
119 impl CommunityModerator {
120   pub fn delete_for_community(conn: &PgConnection, for_community_id: i32) -> Result<usize, Error> {
121     use crate::schema::community_moderator::dsl::*;
122     diesel::delete(community_moderator.filter(community_id.eq(for_community_id))).execute(conn)
123   }
124 }
125
126 #[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
127 #[belongs_to(Community)]
128 #[table_name = "community_user_ban"]
129 pub struct CommunityUserBan {
130   pub id: i32,
131   pub community_id: i32,
132   pub user_id: i32,
133   pub published: chrono::NaiveDateTime,
134 }
135
136 #[derive(Insertable, AsChangeset, Clone)]
137 #[table_name = "community_user_ban"]
138 pub struct CommunityUserBanForm {
139   pub community_id: i32,
140   pub user_id: i32,
141 }
142
143 impl Bannable<CommunityUserBanForm> for CommunityUserBan {
144   fn ban(
145     conn: &PgConnection,
146     community_user_ban_form: &CommunityUserBanForm,
147   ) -> Result<Self, Error> {
148     use crate::schema::community_user_ban::dsl::*;
149     insert_into(community_user_ban)
150       .values(community_user_ban_form)
151       .get_result::<Self>(conn)
152   }
153
154   fn unban(
155     conn: &PgConnection,
156     community_user_ban_form: &CommunityUserBanForm,
157   ) -> Result<usize, Error> {
158     use crate::schema::community_user_ban::dsl::*;
159     diesel::delete(
160       community_user_ban
161         .filter(community_id.eq(community_user_ban_form.community_id))
162         .filter(user_id.eq(community_user_ban_form.user_id)),
163     )
164     .execute(conn)
165   }
166 }
167
168 #[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
169 #[belongs_to(Community)]
170 #[table_name = "community_follower"]
171 pub struct CommunityFollower {
172   pub id: i32,
173   pub community_id: i32,
174   pub user_id: i32,
175   pub published: chrono::NaiveDateTime,
176 }
177
178 #[derive(Insertable, AsChangeset, Clone)]
179 #[table_name = "community_follower"]
180 pub struct CommunityFollowerForm {
181   pub community_id: i32,
182   pub user_id: i32,
183 }
184
185 impl Followable<CommunityFollowerForm> for CommunityFollower {
186   fn follow(
187     conn: &PgConnection,
188     community_follower_form: &CommunityFollowerForm,
189   ) -> Result<Self, Error> {
190     use crate::schema::community_follower::dsl::*;
191     insert_into(community_follower)
192       .values(community_follower_form)
193       .get_result::<Self>(conn)
194   }
195   fn ignore(
196     conn: &PgConnection,
197     community_follower_form: &CommunityFollowerForm,
198   ) -> Result<usize, Error> {
199     use crate::schema::community_follower::dsl::*;
200     diesel::delete(
201       community_follower
202         .filter(community_id.eq(&community_follower_form.community_id))
203         .filter(user_id.eq(&community_follower_form.user_id)),
204     )
205     .execute(conn)
206   }
207 }
208
209 #[cfg(test)]
210 mod tests {
211   use super::super::user::*;
212   use super::*;
213   #[test]
214   fn test_crud() {
215     let conn = establish_unpooled_connection();
216
217     let new_user = UserForm {
218       name: "bobbee".into(),
219       fedi_name: "rrf".into(),
220       preferred_username: None,
221       password_encrypted: "nope".into(),
222       email: None,
223       matrix_user_id: None,
224       avatar: None,
225       admin: false,
226       banned: false,
227       updated: None,
228       show_nsfw: false,
229       theme: "darkly".into(),
230       default_sort_type: SortType::Hot as i16,
231       default_listing_type: ListingType::Subscribed as i16,
232       lang: "browser".into(),
233       show_avatars: true,
234       send_notifications_to_email: false,
235     };
236
237     let inserted_user = User_::create(&conn, &new_user).unwrap();
238
239     let new_community = CommunityForm {
240       name: "TIL".into(),
241       creator_id: inserted_user.id,
242       title: "nada".to_owned(),
243       description: None,
244       category_id: 1,
245       nsfw: false,
246       removed: None,
247       deleted: None,
248       updated: None,
249     };
250
251     let inserted_community = Community::create(&conn, &new_community).unwrap();
252
253     let expected_community = Community {
254       id: inserted_community.id,
255       creator_id: inserted_user.id,
256       name: "TIL".into(),
257       title: "nada".to_owned(),
258       description: None,
259       category_id: 1,
260       nsfw: false,
261       removed: false,
262       deleted: false,
263       published: inserted_community.published,
264       updated: None,
265     };
266
267     let community_follower_form = CommunityFollowerForm {
268       community_id: inserted_community.id,
269       user_id: inserted_user.id,
270     };
271
272     let inserted_community_follower =
273       CommunityFollower::follow(&conn, &community_follower_form).unwrap();
274
275     let expected_community_follower = CommunityFollower {
276       id: inserted_community_follower.id,
277       community_id: inserted_community.id,
278       user_id: inserted_user.id,
279       published: inserted_community_follower.published,
280     };
281
282     let community_user_form = CommunityModeratorForm {
283       community_id: inserted_community.id,
284       user_id: inserted_user.id,
285     };
286
287     let inserted_community_user = CommunityModerator::join(&conn, &community_user_form).unwrap();
288
289     let expected_community_user = CommunityModerator {
290       id: inserted_community_user.id,
291       community_id: inserted_community.id,
292       user_id: inserted_user.id,
293       published: inserted_community_user.published,
294     };
295
296     let community_user_ban_form = CommunityUserBanForm {
297       community_id: inserted_community.id,
298       user_id: inserted_user.id,
299     };
300
301     let inserted_community_user_ban =
302       CommunityUserBan::ban(&conn, &community_user_ban_form).unwrap();
303
304     let expected_community_user_ban = CommunityUserBan {
305       id: inserted_community_user_ban.id,
306       community_id: inserted_community.id,
307       user_id: inserted_user.id,
308       published: inserted_community_user_ban.published,
309     };
310
311     let read_community = Community::read(&conn, inserted_community.id).unwrap();
312     let updated_community =
313       Community::update(&conn, inserted_community.id, &new_community).unwrap();
314     let ignored_community = CommunityFollower::ignore(&conn, &community_follower_form).unwrap();
315     let left_community = CommunityModerator::leave(&conn, &community_user_form).unwrap();
316     let unban = CommunityUserBan::unban(&conn, &community_user_ban_form).unwrap();
317     let num_deleted = Community::delete(&conn, inserted_community.id).unwrap();
318     User_::delete(&conn, inserted_user.id).unwrap();
319
320     assert_eq!(expected_community, read_community);
321     assert_eq!(expected_community, inserted_community);
322     assert_eq!(expected_community, updated_community);
323     assert_eq!(expected_community_follower, inserted_community_follower);
324     assert_eq!(expected_community_user, inserted_community_user);
325     assert_eq!(expected_community_user_ban, inserted_community_user_ban);
326     assert_eq!(1, ignored_community);
327     assert_eq!(1, left_community);
328     assert_eq!(1, unban);
329     // assert_eq!(2, loaded_count);
330     assert_eq!(1, num_deleted);
331   }
332 }