Incrementally update euph_trees

This commit is contained in:
Joscha 2022-06-24 21:13:02 +02:00
parent ad3a67cdc3
commit cda1e8f7d8

View file

@ -3,7 +3,7 @@ use std::mem;
use async_trait::async_trait; use async_trait::async_trait;
use chrono::{DateTime, TimeZone, Utc}; use chrono::{DateTime, TimeZone, Utc};
use rusqlite::types::{FromSql, FromSqlError, ToSqlOutput, Value, ValueRef}; use rusqlite::types::{FromSql, FromSqlError, ToSqlOutput, Value, ValueRef};
use rusqlite::{params, Connection, OptionalExtension, ToSql, Transaction}; use rusqlite::{named_params, params, Connection, OptionalExtension, ToSql, Transaction};
use tokio::sync::{mpsc, oneshot}; use tokio::sync::{mpsc, oneshot};
use crate::euph::api::{Message, Snowflake, Time}; use crate::euph::api::{Message, Snowflake, Time};
@ -266,7 +266,8 @@ impl EuphRequest {
} }
fn insert_msgs(tx: &Transaction, room: &str, msgs: Vec<Message>) -> rusqlite::Result<()> { fn insert_msgs(tx: &Transaction, room: &str, msgs: Vec<Message>) -> rusqlite::Result<()> {
let mut stmt = tx.prepare(" let mut insert_msg = tx.prepare(
"
INSERT OR REPLACE INTO euph_msgs ( INSERT OR REPLACE INTO euph_msgs (
room, id, parent, previous_edit_id, time, content, encryption_key_id, edited, deleted, truncated, room, id, parent, previous_edit_id, time, content, encryption_key_id, edited, deleted, truncated,
user_id, name, server_id, server_era, session_id, is_staff, is_manager, client_address, real_client_address user_id, name, server_id, server_era, session_id, is_staff, is_manager, client_address, real_client_address
@ -275,10 +276,31 @@ impl EuphRequest {
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?, ? ?, ?, ?, ?, ?, ?, ?, ?, ?
) )
")?; "
)?;
let mut delete_trees = tx.prepare(
"
DELETE FROM euph_trees
WHERE room = ? AND id = ?
",
)?;
let mut insert_trees = tx.prepare(
"
INSERT OR IGNORE INTO euph_trees (room, id)
SELECT *
FROM (VALUES (:room, :id))
WHERE NOT EXISTS(
SELECT *
FROM euph_msgs
WHERE room = :room
AND id = :id
AND parent IS NOT NULL
)
",
)?;
for msg in msgs { for msg in msgs {
stmt.execute(params![ insert_msg.execute(params![
room, room,
msg.id, msg.id,
msg.parent, msg.parent,
@ -299,29 +321,14 @@ impl EuphRequest {
msg.sender.client_address, msg.sender.client_address,
msg.sender.real_client_address, msg.sender.real_client_address,
])?; ])?;
if let Some(parent) = msg.parent {
delete_trees.execute(params![room, msg.id])?;
insert_trees.execute(named_params! {":room": room,":id": parent})?;
} else {
insert_trees.execute(named_params! {":room": room,":id": msg.id})?;
}
} }
// Update euph_trees
tx.execute_batch(
"
DELETE FROM euph_trees;
INSERT INTO euph_trees (room, id)
SELECT room, id
FROM euph_msgs
WHERE parent IS NULL
UNION
SELECT room, parent
FROM euph_msgs
WHERE parent IS NOT NULL
AND NOT EXISTS(
SELECT *
FROM euph_msgs AS parents
WHERE parents.room = euph_msgs.room
AND parents.id = euph_msgs.parent
);
",
)?;
Ok(()) Ok(())
} }