mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-12-01 22:01:49 +00:00
stuff including batch_upsert function
This commit is contained in:
parent
ea6f3910eb
commit
fdebc85753
3 changed files with 50 additions and 8 deletions
|
@ -57,21 +57,37 @@ impl Comment {
|
||||||
comment_form: &CommentInsertForm,
|
comment_form: &CommentInsertForm,
|
||||||
parent_path: Option<&Ltree>,
|
parent_path: Option<&Ltree>,
|
||||||
) -> Result<Comment, Error> {
|
) -> Result<Comment, Error> {
|
||||||
|
Comment::create_batch(pool, &[(comment_form, parent_path)]).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?;
|
let conn = &mut get_conn(pool).await?;
|
||||||
|
|
||||||
conn
|
conn
|
||||||
.build_transaction()
|
.build_transaction()
|
||||||
.run(|conn| {
|
.run(|conn| {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
// Insert, to get the id
|
let forms = items
|
||||||
let inserted_comment = insert_into(comment)
|
.iter()
|
||||||
.values(comment_form)
|
.map(|&(form, _)| form)
|
||||||
.on_conflict(ap_id)
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
// Insert, to get the ids
|
||||||
|
let inserted_comments = insert_into(comment)
|
||||||
|
.values(&forms)
|
||||||
|
/*.on_conflict(ap_id)
|
||||||
.do_update()
|
.do_update()
|
||||||
.set(comment_form)
|
.set()*/
|
||||||
.get_result::<Self>(conn)
|
.get_result::<Self>(conn)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
// `ap_id` unique constraint violation is handled individually for each row
|
||||||
|
// because batch upsert requires having the same `set` argument for all rows
|
||||||
|
|
||||||
|
|
||||||
let comment_id = inserted_comment.id;
|
let comment_id = inserted_comment.id;
|
||||||
|
|
||||||
// You need to update the ltree column
|
// You need to update the ltree column
|
||||||
|
|
|
@ -19,7 +19,7 @@ use diesel::{
|
||||||
sql_types::{Text, Timestamptz},
|
sql_types::{Text, Timestamptz},
|
||||||
IntoSql,
|
IntoSql,
|
||||||
PgConnection,
|
PgConnection,
|
||||||
RunQueryDsl,
|
RunQueryDsl, Insertable, Table, Column, AsChangeset, Expression, SelectableExpression, expression::NonAggregate, query_builder::QueryFragment,
|
||||||
};
|
};
|
||||||
use diesel_async::{
|
use diesel_async::{
|
||||||
pg::AsyncPgConnection,
|
pg::AsyncPgConnection,
|
||||||
|
@ -153,6 +153,19 @@ macro_rules! try_join_with_pool {
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn batch_upsert<T, U, Target, R>(conn: &mut AsyncPgConnection, target: T, records: U, conflict_target: Target) -> Result<Vec<R>, DieselError>
|
||||||
|
where
|
||||||
|
T: Table,
|
||||||
|
T::AllColumns: Expression + SelectableExpression<T> + NonAggregate + QueryFragment<Pg>,
|
||||||
|
U: IntoIterator + Clone,
|
||||||
|
Vec<U::Item>: Insertable<T>,
|
||||||
|
U::Item: Insertable<T> + AsChangeset<Target = T>,
|
||||||
|
Target: Column<Table = T>,
|
||||||
|
{
|
||||||
|
let result = diesel::insert_into(target).values(records.clone().into_iter().collect::<Vec<_>>()).load::<R>(conn).await;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
pub fn fuzzy_search(q: &str) -> String {
|
pub fn fuzzy_search(q: &str) -> String {
|
||||||
let replaced = q.replace('%', "\\%").replace('_', "\\_").replace(' ', "%");
|
let replaced = q.replace('%', "\\%").replace('_', "\\_").replace(' ', "%");
|
||||||
format!("%{replaced}%")
|
format!("%{replaced}%")
|
||||||
|
|
|
@ -18,10 +18,23 @@ then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Create cluster
|
# Create cluster
|
||||||
initdb --username=postgres --auth=trust --no-instructions
|
initdb --username=postgres --auth=trust --no-instructions \
|
||||||
|
# Only listen to socket in current directory
|
||||||
|
-c listen_addresses= -c unix_socket_directories=$PWD \
|
||||||
|
# Write logs to a file in $PGDATA/log
|
||||||
|
-c logging_collector=on \
|
||||||
|
# Log all query plans by default
|
||||||
|
-c session_preload_libraries=auto_explain -c auto_explain.log_min_duration=0
|
||||||
|
# Include actual row amounts and run times for query plan nodes
|
||||||
|
-c auto_explain.log_analyze=on
|
||||||
|
# Avoid sequential scans so query plans show what index scans can be done
|
||||||
|
# (index scan is normally avoided in some cases, such as the table being small enough)
|
||||||
|
-c enable_seqscan=off
|
||||||
|
# Don't log parameter values
|
||||||
|
-c auto_explain.log_parameter_max_length=0
|
||||||
|
|
||||||
# Start server that only listens to socket in current directory
|
# Start server that only listens to socket in current directory
|
||||||
pg_ctl start --options="-c listen_addresses= -c unix_socket_directories=$PWD -c logging_collector=on -c session_preload_libraries=auto_explain -c auto_explain.log_min_duration=0 -c auto_explain.log_parameter_max_length=0 -c auto_explain.log_analyze=on -c enable_seqscan=off" > /dev/null
|
pg_ctl start
|
||||||
|
|
||||||
# Setup database
|
# Setup database
|
||||||
psql -c "CREATE USER lemmy WITH PASSWORD 'password' SUPERUSER;" -U postgres
|
psql -c "CREATE USER lemmy WITH PASSWORD 'password' SUPERUSER;" -U postgres
|
||||||
|
|
Loading…
Reference in a new issue