From 49ade0cfbd74010ae11caa7c86850a63b25e9184 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20K=C3=B6sters?= <timo@koesters.xyz>
Date: Tue, 3 Aug 2021 11:24:21 +0200
Subject: [PATCH] improvement: allow batch inserts

---
 src/database.rs                    | 10 ++++++++++
 src/database/abstraction.rs        |  1 +
 src/database/abstraction/sqlite.rs | 17 ++++++++++++++++-
 3 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/src/database.rs b/src/database.rs
index 5b4730289..54abc53d0 100644
--- a/src/database.rs
+++ b/src/database.rs
@@ -484,6 +484,16 @@ pub async fn watch(&self, user_id: &UserId, device_id: &DeviceId) {
                 .watch_prefix(&userid_prefix),
         );
         futures.push(self.rooms.userroomid_leftstate.watch_prefix(&userid_prefix));
+        futures.push(
+            self.rooms
+                .userroomid_notificationcount
+                .watch_prefix(&userid_prefix),
+        );
+        futures.push(
+            self.rooms
+                .userroomid_highlightcount
+                .watch_prefix(&userid_prefix),
+        );
 
         // Events for rooms we are in
         for room_id in self.rooms.rooms_joined(user_id).filter_map(|r| r.ok()) {
diff --git a/src/database/abstraction.rs b/src/database/abstraction.rs
index d0fa780b4..465bb10a6 100644
--- a/src/database/abstraction.rs
+++ b/src/database/abstraction.rs
@@ -25,6 +25,7 @@ pub trait Tree: Send + Sync {
     fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>>;
 
     fn insert(&self, key: &[u8], value: &[u8]) -> Result<()>;
+    fn insert_batch<'a>(&self, iter: &mut dyn Iterator<Item = (Vec<u8>, Vec<u8>)>) -> Result<()>;
 
     fn remove(&self, key: &[u8]) -> Result<()>;
 
diff --git a/src/database/abstraction/sqlite.rs b/src/database/abstraction/sqlite.rs
index d2ecb3a78..ce30a5691 100644
--- a/src/database/abstraction/sqlite.rs
+++ b/src/database/abstraction/sqlite.rs
@@ -201,6 +201,21 @@ fn insert(&self, key: &[u8], value: &[u8]) -> Result<()> {
         Ok(())
     }
 
+    #[tracing::instrument(skip(self, iter))]
+    fn insert_batch<'a>(&self, iter: &mut dyn Iterator<Item = (Vec<u8>, Vec<u8>)>) -> Result<()> {
+        let guard = self.engine.write_lock();
+
+        guard.execute("BEGIN", [])?;
+        for (key, value) in iter {
+            self.insert_with_guard(&guard, &key, &value)?;
+        }
+        guard.execute("COMMIT", [])?;
+
+        drop(guard);
+
+        Ok(())
+    }
+
     #[tracing::instrument(skip(self, key))]
     fn remove(&self, key: &[u8]) -> Result<()> {
         let guard = self.engine.write_lock();
@@ -228,7 +243,7 @@ fn iter<'a>(&'a self) -> Box<dyn Iterator<Item = TupleOfBytes> + 'a> {
 
         let statement = Box::leak(Box::new(
             guard
-                .prepare(&format!("SELECT key, value FROM {}", &self.name))
+                .prepare(&format!("SELECT key, value FROM {} ORDER BY key ASC", &self.name))
                 .unwrap(),
         ));
 
-- 
GitLab