summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--synapse/handlers/user_directory.py3
-rw-r--r--synapse/storage/user_directory.py35
2 files changed, 38 insertions, 0 deletions
diff --git a/synapse/handlers/user_directory.py b/synapse/handlers/user_directory.py
index 0cf403f599..4a9565df93 100644
--- a/synapse/handlers/user_directory.py
+++ b/synapse/handlers/user_directory.py
@@ -40,6 +40,9 @@ class UserDirectoyHandler(object):
 
         self.clock.call_later(0, self.notify_new_event)
 
+    def search_users(self, search_term, limit):
+        return self.store.search_user_dir(search_term, limit)
+
     @defer.inlineCallbacks
     def notify_new_event(self):
         if self._is_processing:
diff --git a/synapse/storage/user_directory.py b/synapse/storage/user_directory.py
index d72b93b585..650c49982d 100644
--- a/synapse/storage/user_directory.py
+++ b/synapse/storage/user_directory.py
@@ -153,3 +153,38 @@ class UserDirectoryStore(SQLBaseStore):
         return self._execute(
             "get_current_state_deltas", self.cursor_to_dict, sql, prev_stream_id
         )
+
+    @defer.inlineCallbacks
+    def search_user_dir(self, search_term, limit):
+        if isinstance(self.database_engine, PostgresEngine):
+            sql = """
+                SELECT user_id, display_name, avatar_url
+                FROM user_directory
+                WHERE vector @@ to_tsquery('english', ?)
+                ORDER BY  ts_rank_cd(vector, to_tsquery('english', ?)) DESC
+                LIMIT ?
+            """
+            args = (search_term, search_term, limit + 1,)
+        elif isinstance(self.database_engine, Sqlite3Engine):
+            sql = """
+                SELECT user_id, display_name, avatar_url
+                FROM user_directory
+                WHERE value MATCH ?
+                ORDER BY rank(matchinfo(user_directory)) DESC
+                LIMIT ?
+            """
+            args = (search_term, limit + 1)
+        else:
+            # This should be unreachable.
+            raise Exception("Unrecognized database engine")
+
+        results = yield self._execute(
+            "search_user_dir", self.cursor_to_dict, sql, *args
+        )
+
+        limited = len(results) > limit
+
+        defer.returnValue({
+            "limited": limited,
+            "results": results,
+        })