mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-29 07:41:20 +00:00
Revert changes to comment.rs
This commit is contained in:
parent
82e37f7b57
commit
f54a350b85
1 changed files with 28 additions and 67 deletions
|
@ -1,16 +1,6 @@
|
|||
use crate::{
|
||||
newtypes::{CommentId, DbUrl, PersonId},
|
||||
schema::comment::dsl::{
|
||||
ap_id,
|
||||
comment,
|
||||
content,
|
||||
creator_id,
|
||||
deleted,
|
||||
id,
|
||||
path,
|
||||
removed,
|
||||
updated,
|
||||
},
|
||||
schema::comment::dsl::{ap_id, comment, content, creator_id, deleted, path, removed, updated},
|
||||
source::comment::{
|
||||
Comment,
|
||||
CommentInsertForm,
|
||||
|
@ -21,24 +11,16 @@ use crate::{
|
|||
CommentUpdateForm,
|
||||
},
|
||||
traits::{Crud, Likeable, Saveable},
|
||||
utils::{functions::AsText, get_conn, naive_now, DbPool, DELETED_REPLACEMENT_TEXT},
|
||||
utils::{get_conn, naive_now, DbPool, DELETED_REPLACEMENT_TEXT},
|
||||
};
|
||||
use diesel::{
|
||||
dsl::{insert_into, sql_query},
|
||||
result::Error,
|
||||
ExpressionMethods,
|
||||
QueryDsl,
|
||||
TextExpressionMethods,
|
||||
};
|
||||
use diesel_async::RunQueryDsl;
|
||||
use diesel_ltree::{
|
||||
functions::{ltree2text, text2ltree},
|
||||
Ltree,
|
||||
};
|
||||
use futures_util::{
|
||||
future::TryFutureExt,
|
||||
stream::{self, StreamExt, TryStreamExt},
|
||||
};
|
||||
use diesel_ltree::Ltree;
|
||||
use url::Url;
|
||||
|
||||
impl Comment {
|
||||
|
@ -75,63 +57,42 @@ impl Comment {
|
|||
comment_form: &CommentInsertForm,
|
||||
parent_path: Option<&Ltree>,
|
||||
) -> Result<Comment, Error> {
|
||||
Comment::create_batch(pool, &[(comment_form.clone(), parent_path.cloned())])
|
||||
.await?
|
||||
.into_iter()
|
||||
.next()
|
||||
.ok_or(Error::NotFound)
|
||||
}
|
||||
|
||||
pub async fn create_batch(
|
||||
pool: &mut DbPool<'_>,
|
||||
items: &[(CommentInsertForm, Option<Ltree>)],
|
||||
) -> Result<Vec<Comment>, Error> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
|
||||
conn
|
||||
.build_transaction()
|
||||
.run(|conn| {
|
||||
Box::pin(async move {
|
||||
let forms = items
|
||||
.iter()
|
||||
.map(|(comment_form, parent_path)| CommentInsertForm {
|
||||
path: Some(parent_path.clone().unwrap_or(Ltree("0".to_owned()))),
|
||||
..comment_form.clone()
|
||||
});
|
||||
|
||||
// Insert, to get the ids
|
||||
let inserted_comments = insert_into(comment)
|
||||
.values(forms.clone().collect::<Vec<_>>())
|
||||
.load::<Self>(conn)
|
||||
.or_else(|_| {
|
||||
// `ap_id` unique constraint violation is handled individually for each row
|
||||
// because batched upsert requires having the same `set` argument for all rows
|
||||
stream::iter(forms)
|
||||
.then(|form| {
|
||||
insert_into(comment)
|
||||
.values(form.clone())
|
||||
// Insert, to get the id
|
||||
let inserted_comment = insert_into(comment)
|
||||
.values(comment_form)
|
||||
.on_conflict(ap_id)
|
||||
.do_update()
|
||||
.set(form)
|
||||
.set(comment_form)
|
||||
.get_result::<Self>(conn)
|
||||
})
|
||||
.try_collect::<Vec<_>>()
|
||||
})
|
||||
.await?;
|
||||
|
||||
// For each comment, append its id to its path
|
||||
let updated_comments = diesel::update(comment)
|
||||
.filter(id.eq_any(inserted_comments.into_iter().map(|c| c.id)))
|
||||
.set(path.eq(text2ltree(
|
||||
ltree2text(path).concat(".").concat(AsText::new(id)),
|
||||
)))
|
||||
.load::<Self>(conn)
|
||||
.await?;
|
||||
let comment_id = inserted_comment.id;
|
||||
|
||||
// You need to update the ltree column
|
||||
let ltree = Ltree(if let Some(parent_path) = parent_path {
|
||||
// The previous parent will already have 0 in it
|
||||
// Append this comment id
|
||||
format!("{}.{}", parent_path.0, comment_id)
|
||||
} else {
|
||||
// '0' is always the first path, append to that
|
||||
format!("{}.{}", 0, comment_id)
|
||||
});
|
||||
|
||||
let updated_comment = diesel::update(comment.find(comment_id))
|
||||
.set(path.eq(ltree))
|
||||
.get_result::<Self>(conn)
|
||||
.await;
|
||||
|
||||
// Update the child count for the parent comment_aggregates
|
||||
// You could do this with a trigger, but since you have to do this manually anyway,
|
||||
// you can just have it here
|
||||
for parent_path in items.iter().filter_map(|(_, p)| p.as_ref()) {
|
||||
if let Some(parent_path) = parent_path {
|
||||
// You have to update counts for all parents, not just the immediate one
|
||||
// TODO if the performance of this is terrible, it might be better to do this as part of a
|
||||
// scheduled query... although the counts would often be wrong.
|
||||
|
@ -160,7 +121,7 @@ where ca.comment_id = c.id"
|
|||
sql_query(update_child_count_stmt).execute(conn).await?;
|
||||
}
|
||||
}
|
||||
Ok(updated_comments)
|
||||
updated_comment
|
||||
}) as _
|
||||
})
|
||||
.await
|
||||
|
|
Loading…
Reference in a new issue