3 newtypes::{DbUrl, PersonId},
4 schema::person::dsl::*,
5 source::person::{Person, PersonForm},
8 use chrono::NaiveDateTime;
9 use diesel::{dsl::*, result::Error, ExpressionMethods, PgConnection, QueryDsl, RunQueryDsl, *};
10 use lemmy_apub_lib::traits::{ActorType, ApubObject};
11 use lemmy_utils::LemmyError;
15 use crate::{schema::person::columns::*, source::person::Person, traits::ToSafe};
37 impl ToSafe for Person {
38 type SafeColumns = Columns;
39 fn safe_columns_tuple() -> Self::SafeColumns {
63 mod safe_type_alias_1 {
64 use crate::{schema::person_alias_1::columns::*, source::person::PersonAlias1, traits::ToSafe};
86 impl ToSafe for PersonAlias1 {
87 type SafeColumns = Columns;
88 fn safe_columns_tuple() -> Self::SafeColumns {
112 mod safe_type_alias_2 {
113 use crate::{schema::person_alias_2::columns::*, source::person::PersonAlias2, traits::ToSafe};
135 impl ToSafe for PersonAlias2 {
136 type SafeColumns = Columns;
137 fn safe_columns_tuple() -> Self::SafeColumns {
161 impl Crud for Person {
162 type Form = PersonForm;
163 type IdType = PersonId;
164 fn read(conn: &PgConnection, person_id: PersonId) -> Result<Self, Error> {
166 .filter(deleted.eq(false))
170 fn delete(conn: &PgConnection, person_id: PersonId) -> Result<usize, Error> {
171 diesel::delete(person.find(person_id)).execute(conn)
173 fn create(conn: &PgConnection, form: &PersonForm) -> Result<Self, Error> {
174 insert_into(person).values(form).get_result::<Self>(conn)
176 fn update(conn: &PgConnection, person_id: PersonId, form: &PersonForm) -> Result<Self, Error> {
177 diesel::update(person.find(person_id))
179 .get_result::<Self>(conn)
184 pub fn ban_person(conn: &PgConnection, person_id: PersonId, ban: bool) -> Result<Self, Error> {
185 diesel::update(person.find(person_id))
187 .get_result::<Self>(conn)
190 pub fn add_admin(conn: &PgConnection, person_id: PersonId, added: bool) -> Result<Self, Error> {
191 diesel::update(person.find(person_id))
192 .set(admin.eq(added))
193 .get_result::<Self>(conn)
196 pub fn find_by_name(conn: &PgConnection, from_name: &str) -> Result<Person, Error> {
198 .filter(deleted.eq(false))
199 .filter(local.eq(true))
200 .filter(name.ilike(from_name))
201 .first::<Person>(conn)
204 pub fn mark_as_updated(conn: &PgConnection, person_id: PersonId) -> Result<Person, Error> {
205 diesel::update(person.find(person_id))
206 .set((last_refreshed_at.eq(naive_now()),))
207 .get_result::<Self>(conn)
210 pub fn delete_account(conn: &PgConnection, person_id: PersonId) -> Result<Person, Error> {
211 use crate::schema::local_user;
213 // Set the local user info to none
214 diesel::update(local_user::table.filter(local_user::person_id.eq(person_id)))
216 local_user::email.eq::<Option<String>>(None),
217 local_user::validator_time.eq(naive_now()),
221 diesel::update(person.find(person_id))
223 display_name.eq::<Option<String>>(None),
224 bio.eq::<Option<String>>(None),
225 matrix_user_id.eq::<Option<String>>(None),
227 updated.eq(naive_now()),
229 .get_result::<Self>(conn)
232 pub fn upsert(conn: &PgConnection, person_form: &PersonForm) -> Result<Person, Error> {
235 .on_conflict(actor_id)
238 .get_result::<Self>(conn)
242 impl ApubObject for Person {
243 type DataType = PgConnection;
245 fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
246 Some(self.last_refreshed_at)
249 fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result<Option<Self>, LemmyError> {
250 use crate::schema::person::dsl::*;
251 let object_id: DbUrl = object_id.into();
254 .filter(deleted.eq(false))
255 .filter(actor_id.eq(object_id))
261 fn delete(self, conn: &PgConnection) -> Result<(), LemmyError> {
262 use crate::schema::person::dsl::*;
263 diesel::update(person.find(self.id))
264 .set((deleted.eq(true), updated.eq(naive_now())))
265 .get_result::<Self>(conn)?;
270 impl ActorType for Person {
271 fn is_local(&self) -> bool {
274 fn actor_id(&self) -> Url {
275 self.actor_id.to_owned().into_inner()
277 fn name(&self) -> String {
281 fn public_key(&self) -> Option<String> {
282 self.public_key.to_owned()
285 fn private_key(&self) -> Option<String> {
286 self.private_key.to_owned()
289 fn inbox_url(&self) -> Url {
290 self.inbox_url.clone().into()
293 fn shared_inbox_url(&self) -> Option<Url> {
294 self.shared_inbox_url.clone().map(|s| s.into_inner())
300 use crate::{establish_unpooled_connection, source::person::*, traits::Crud};
304 let conn = establish_unpooled_connection();
306 let new_person = PersonForm {
307 name: "holly".into(),
308 ..PersonForm::default()
311 let inserted_person = Person::create(&conn, &new_person).unwrap();
313 let expected_person = Person {
314 id: inserted_person.id,
315 name: "holly".into(),
321 published: inserted_person.published,
323 actor_id: inserted_person.actor_id.to_owned(),
330 last_refreshed_at: inserted_person.published,
331 inbox_url: inserted_person.inbox_url.to_owned(),
332 shared_inbox_url: None,
333 matrix_user_id: None,
336 let read_person = Person::read(&conn, inserted_person.id).unwrap();
337 let updated_person = Person::update(&conn, inserted_person.id, &new_person).unwrap();
338 let num_deleted = Person::delete(&conn, inserted_person.id).unwrap();
340 assert_eq!(expected_person, read_person);
341 assert_eq!(expected_person, inserted_person);
342 assert_eq!(expected_person, updated_person);
343 assert_eq!(1, num_deleted);