1 use crate::{ApubObject, Bannable, Crud, DeleteableOrRemoveable, Followable, Joinable};
2 use diesel::{dsl::*, result::Error, *};
11 CommunityModeratorForm,
13 CommunityPersonBanForm,
22 use crate::{source::community::Community, ToSafe};
23 use lemmy_db_schema::schema::community::*;
41 impl ToSafe for Community {
42 type SafeColumns = Columns;
43 fn safe_columns_tuple() -> Self::SafeColumns {
63 impl Crud for Community {
64 type Form = CommunityForm;
65 type IdType = CommunityId;
66 fn read(conn: &PgConnection, community_id: CommunityId) -> Result<Self, Error> {
67 use lemmy_db_schema::schema::community::dsl::*;
68 community.find(community_id).first::<Self>(conn)
71 fn delete(conn: &PgConnection, community_id: CommunityId) -> Result<usize, Error> {
72 use lemmy_db_schema::schema::community::dsl::*;
73 diesel::delete(community.find(community_id)).execute(conn)
76 fn create(conn: &PgConnection, new_community: &CommunityForm) -> Result<Self, Error> {
77 use lemmy_db_schema::schema::community::dsl::*;
78 insert_into(community)
79 .values(new_community)
80 .get_result::<Self>(conn)
85 community_id: CommunityId,
86 new_community: &CommunityForm,
87 ) -> Result<Self, Error> {
88 use lemmy_db_schema::schema::community::dsl::*;
89 diesel::update(community.find(community_id))
91 .get_result::<Self>(conn)
95 impl ApubObject for Community {
96 type Form = CommunityForm;
97 fn read_from_apub_id(conn: &PgConnection, for_actor_id: &DbUrl) -> Result<Self, Error> {
98 use lemmy_db_schema::schema::community::dsl::*;
100 .filter(actor_id.eq(for_actor_id))
104 fn upsert(conn: &PgConnection, community_form: &CommunityForm) -> Result<Community, Error> {
105 use lemmy_db_schema::schema::community::dsl::*;
106 insert_into(community)
107 .values(community_form)
108 .on_conflict(actor_id)
111 .get_result::<Self>(conn)
115 pub trait Community_ {
116 fn read_from_name(conn: &PgConnection, community_name: &str) -> Result<Community, Error>;
119 community_id: CommunityId,
121 ) -> Result<Community, Error>;
124 community_id: CommunityId,
126 ) -> Result<Community, Error>;
127 fn distinct_federated_communities(conn: &PgConnection) -> Result<Vec<String>, Error>;
128 fn read_from_followers_url(
130 followers_url: &DbUrl,
131 ) -> Result<Community, Error>;
134 impl Community_ for Community {
135 fn read_from_name(conn: &PgConnection, community_name: &str) -> Result<Community, Error> {
136 use lemmy_db_schema::schema::community::dsl::*;
138 .filter(local.eq(true))
139 .filter(name.eq(community_name))
145 community_id: CommunityId,
147 ) -> Result<Community, Error> {
148 use lemmy_db_schema::schema::community::dsl::*;
149 diesel::update(community.find(community_id))
150 .set((deleted.eq(new_deleted), updated.eq(naive_now())))
151 .get_result::<Self>(conn)
156 community_id: CommunityId,
158 ) -> Result<Community, Error> {
159 use lemmy_db_schema::schema::community::dsl::*;
160 diesel::update(community.find(community_id))
161 .set((removed.eq(new_removed), updated.eq(naive_now())))
162 .get_result::<Self>(conn)
165 fn distinct_federated_communities(conn: &PgConnection) -> Result<Vec<String>, Error> {
166 use lemmy_db_schema::schema::community::dsl::*;
167 community.select(actor_id).distinct().load::<String>(conn)
170 fn read_from_followers_url(
172 followers_url_: &DbUrl,
173 ) -> Result<Community, Error> {
174 use lemmy_db_schema::schema::community::dsl::*;
176 .filter(followers_url.eq(followers_url_))
181 impl Joinable for CommunityModerator {
182 type Form = CommunityModeratorForm;
185 community_moderator_form: &CommunityModeratorForm,
186 ) -> Result<Self, Error> {
187 use lemmy_db_schema::schema::community_moderator::dsl::*;
188 insert_into(community_moderator)
189 .values(community_moderator_form)
190 .get_result::<Self>(conn)
195 community_moderator_form: &CommunityModeratorForm,
196 ) -> Result<usize, Error> {
197 use lemmy_db_schema::schema::community_moderator::dsl::*;
200 .filter(community_id.eq(community_moderator_form.community_id))
201 .filter(person_id.eq(community_moderator_form.person_id)),
207 impl DeleteableOrRemoveable for CommunitySafe {
208 fn blank_out_deleted_or_removed_info(mut self) -> Self {
209 self.title = "".into();
210 self.description = None;
217 impl DeleteableOrRemoveable for Community {
218 fn blank_out_deleted_or_removed_info(mut self) -> Self {
219 self.title = "".into();
220 self.description = None;
227 pub trait CommunityModerator_ {
228 fn delete_for_community(
230 for_community_id: CommunityId,
231 ) -> Result<usize, Error>;
232 fn get_person_moderated_communities(
234 for_person_id: PersonId,
235 ) -> Result<Vec<CommunityId>, Error>;
238 impl CommunityModerator_ for CommunityModerator {
239 fn delete_for_community(
241 for_community_id: CommunityId,
242 ) -> Result<usize, Error> {
243 use lemmy_db_schema::schema::community_moderator::dsl::*;
244 diesel::delete(community_moderator.filter(community_id.eq(for_community_id))).execute(conn)
247 fn get_person_moderated_communities(
249 for_person_id: PersonId,
250 ) -> Result<Vec<CommunityId>, Error> {
251 use lemmy_db_schema::schema::community_moderator::dsl::*;
253 .filter(person_id.eq(for_person_id))
254 .select(community_id)
255 .load::<CommunityId>(conn)
259 impl Bannable for CommunityPersonBan {
260 type Form = CommunityPersonBanForm;
263 community_person_ban_form: &CommunityPersonBanForm,
264 ) -> Result<Self, Error> {
265 use lemmy_db_schema::schema::community_person_ban::dsl::*;
266 insert_into(community_person_ban)
267 .values(community_person_ban_form)
268 .get_result::<Self>(conn)
273 community_person_ban_form: &CommunityPersonBanForm,
274 ) -> Result<usize, Error> {
275 use lemmy_db_schema::schema::community_person_ban::dsl::*;
278 .filter(community_id.eq(community_person_ban_form.community_id))
279 .filter(person_id.eq(community_person_ban_form.person_id)),
285 impl Followable for CommunityFollower {
286 type Form = CommunityFollowerForm;
289 community_follower_form: &CommunityFollowerForm,
290 ) -> Result<Self, Error> {
291 use lemmy_db_schema::schema::community_follower::dsl::*;
292 insert_into(community_follower)
293 .values(community_follower_form)
294 .on_conflict((community_id, person_id))
296 .set(community_follower_form)
297 .get_result::<Self>(conn)
301 community_id_: CommunityId,
302 person_id_: PersonId,
303 ) -> Result<Self, Error>
307 use lemmy_db_schema::schema::community_follower::dsl::*;
310 .filter(community_id.eq(community_id_))
311 .filter(person_id.eq(person_id_)),
313 .set(pending.eq(true))
314 .get_result::<Self>(conn)
318 community_follower_form: &CommunityFollowerForm,
319 ) -> Result<usize, Error> {
320 use lemmy_db_schema::schema::community_follower::dsl::*;
323 .filter(community_id.eq(&community_follower_form.community_id))
324 .filter(person_id.eq(&community_follower_form.person_id)),
328 // TODO: this function name only makes sense if you call it with a remote community. for a local
329 // community, it will also return true if only remote followers exist
330 fn has_local_followers(conn: &PgConnection, community_id_: CommunityId) -> Result<bool, Error> {
331 use lemmy_db_schema::schema::community_follower::dsl::*;
332 diesel::select(exists(
333 community_follower.filter(community_id.eq(community_id_)),
341 use crate::{establish_unpooled_connection, Bannable, Crud, Followable, Joinable};
342 use lemmy_db_schema::source::{community::*, person::*};
343 use serial_test::serial;
348 let conn = establish_unpooled_connection();
350 let new_person = PersonForm {
351 name: "bobbee".into(),
352 ..PersonForm::default()
355 let inserted_person = Person::create(&conn, &new_person).unwrap();
357 let new_community = CommunityForm {
359 title: "nada".to_owned(),
360 ..CommunityForm::default()
363 let inserted_community = Community::create(&conn, &new_community).unwrap();
365 let expected_community = Community {
366 id: inserted_community.id,
368 title: "nada".to_owned(),
373 published: inserted_community.published,
375 actor_id: inserted_community.actor_id.to_owned(),
379 last_refreshed_at: inserted_community.published,
382 followers_url: inserted_community.followers_url.to_owned(),
383 inbox_url: inserted_community.inbox_url.to_owned(),
384 shared_inbox_url: None,
387 let community_follower_form = CommunityFollowerForm {
388 community_id: inserted_community.id,
389 person_id: inserted_person.id,
393 let inserted_community_follower =
394 CommunityFollower::follow(&conn, &community_follower_form).unwrap();
396 let expected_community_follower = CommunityFollower {
397 id: inserted_community_follower.id,
398 community_id: inserted_community.id,
399 person_id: inserted_person.id,
400 pending: Some(false),
401 published: inserted_community_follower.published,
404 let community_moderator_form = CommunityModeratorForm {
405 community_id: inserted_community.id,
406 person_id: inserted_person.id,
409 let inserted_community_moderator =
410 CommunityModerator::join(&conn, &community_moderator_form).unwrap();
412 let expected_community_moderator = CommunityModerator {
413 id: inserted_community_moderator.id,
414 community_id: inserted_community.id,
415 person_id: inserted_person.id,
416 published: inserted_community_moderator.published,
419 let community_person_ban_form = CommunityPersonBanForm {
420 community_id: inserted_community.id,
421 person_id: inserted_person.id,
424 let inserted_community_person_ban =
425 CommunityPersonBan::ban(&conn, &community_person_ban_form).unwrap();
427 let expected_community_person_ban = CommunityPersonBan {
428 id: inserted_community_person_ban.id,
429 community_id: inserted_community.id,
430 person_id: inserted_person.id,
431 published: inserted_community_person_ban.published,
434 let read_community = Community::read(&conn, inserted_community.id).unwrap();
435 let updated_community =
436 Community::update(&conn, inserted_community.id, &new_community).unwrap();
437 let ignored_community = CommunityFollower::unfollow(&conn, &community_follower_form).unwrap();
438 let left_community = CommunityModerator::leave(&conn, &community_moderator_form).unwrap();
439 let unban = CommunityPersonBan::unban(&conn, &community_person_ban_form).unwrap();
440 let num_deleted = Community::delete(&conn, inserted_community.id).unwrap();
441 Person::delete(&conn, inserted_person.id).unwrap();
443 assert_eq!(expected_community, read_community);
444 assert_eq!(expected_community, inserted_community);
445 assert_eq!(expected_community, updated_community);
446 assert_eq!(expected_community_follower, inserted_community_follower);
447 assert_eq!(expected_community_moderator, inserted_community_moderator);
448 assert_eq!(expected_community_person_ban, inserted_community_person_ban);
449 assert_eq!(1, ignored_community);
450 assert_eq!(1, left_community);
451 assert_eq!(1, unban);
452 // assert_eq!(2, loaded_count);
453 assert_eq!(1, num_deleted);