Implement `db2::Database::fuzzy_search_users`

Antonio Scandurra created

Change summary

crates/collab/src/db2.rs       | 36 ++++++++++++--
crates/collab/src/db2/tests.rs | 90 ++++++++++++++++++------------------
2 files changed, 75 insertions(+), 51 deletions(-)

Detailed changes

crates/collab/src/db2.rs 🔗

@@ -20,8 +20,8 @@ use sea_orm::{
     TransactionTrait,
 };
 use sea_orm::{
-    ActiveValue, ConnectionTrait, FromQueryResult, IntoActiveModel, JoinType, QueryOrder,
-    QuerySelect,
+    ActiveValue, ConnectionTrait, DatabaseBackend, FromQueryResult, IntoActiveModel, JoinType,
+    QueryOrder, QuerySelect, Statement,
 };
 use sea_query::{Alias, Expr, OnConflict, Query};
 use serde::{Deserialize, Serialize};
@@ -499,6 +499,30 @@ impl Database {
         result
     }
 
+    pub async fn fuzzy_search_users(&self, name_query: &str, limit: u32) -> Result<Vec<User>> {
+        self.transact(|tx| async {
+            let tx = tx;
+            let like_string = Self::fuzzy_like_string(name_query);
+            let query = "
+                SELECT users.*
+                FROM users
+                WHERE github_login ILIKE $1
+                ORDER BY github_login <-> $2
+                LIMIT $3
+            ";
+
+            Ok(user::Entity::find()
+                .from_raw_sql(Statement::from_sql_and_values(
+                    self.pool.get_database_backend(),
+                    query.into(),
+                    vec![like_string.into(), name_query.into(), limit.into()],
+                ))
+                .all(&tx)
+                .await?)
+        })
+        .await
+    }
+
     // projects
 
     pub async fn share_project(
@@ -727,9 +751,9 @@ impl Database {
                 let tx = self.pool.begin().await?;
 
                 // In Postgres, serializable transactions are opt-in
-                if let sea_orm::DatabaseBackend::Postgres = self.pool.get_database_backend() {
-                    tx.execute(sea_orm::Statement::from_string(
-                        sea_orm::DatabaseBackend::Postgres,
+                if let DatabaseBackend::Postgres = self.pool.get_database_backend() {
+                    tx.execute(Statement::from_string(
+                        DatabaseBackend::Postgres,
                         "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;".into(),
                     ))
                     .await?;
@@ -1047,7 +1071,7 @@ mod test {
     impl Drop for TestDb {
         fn drop(&mut self) {
             let db = self.db.take().unwrap();
-            if let sea_orm::DatabaseBackend::Postgres = db.pool.get_database_backend() {
+            if let DatabaseBackend::Postgres = db.pool.get_database_backend() {
                 db.runtime.as_ref().unwrap().block_on(async {
                     use util::ResultExt;
                     let query = "

crates/collab/src/db2/tests.rs 🔗

@@ -409,53 +409,53 @@ fn test_fuzzy_like_string() {
     assert_eq!(Database::fuzzy_like_string(" z  "), "%z%");
 }
 
-// #[gpui::test]
-// async fn test_fuzzy_search_users() {
-//     let test_db = PostgresTestDb::new(build_background_executor());
-//     let db = test_db.db();
-//     for (i, github_login) in [
-//         "California",
-//         "colorado",
-//         "oregon",
-//         "washington",
-//         "florida",
-//         "delaware",
-//         "rhode-island",
-//     ]
-//     .into_iter()
-//     .enumerate()
-//     {
-//         db.create_user(
-//             &format!("{github_login}@example.com"),
-//             false,
-//             NewUserParams {
-//                 github_login: github_login.into(),
-//                 github_user_id: i as i32,
-//                 invite_count: 0,
-//             },
-//         )
-//         .await
-//         .unwrap();
-//     }
+#[gpui::test]
+async fn test_fuzzy_search_users() {
+    let test_db = TestDb::postgres(build_background_executor());
+    let db = test_db.db();
+    for (i, github_login) in [
+        "California",
+        "colorado",
+        "oregon",
+        "washington",
+        "florida",
+        "delaware",
+        "rhode-island",
+    ]
+    .into_iter()
+    .enumerate()
+    {
+        db.create_user(
+            &format!("{github_login}@example.com"),
+            false,
+            NewUserParams {
+                github_login: github_login.into(),
+                github_user_id: i as i32,
+                invite_count: 0,
+            },
+        )
+        .await
+        .unwrap();
+    }
 
-//     assert_eq!(
-//         fuzzy_search_user_names(db, "clr").await,
-//         &["colorado", "California"]
-//     );
-//     assert_eq!(
-//         fuzzy_search_user_names(db, "ro").await,
-//         &["rhode-island", "colorado", "oregon"],
-//     );
+    assert_eq!(
+        fuzzy_search_user_names(db, "clr").await,
+        &["colorado", "California"]
+    );
+    assert_eq!(
+        fuzzy_search_user_names(db, "ro").await,
+        &["rhode-island", "colorado", "oregon"],
+    );
 
-//     async fn fuzzy_search_user_names(db: &Db<sqlx::Postgres>, query: &str) -> Vec<String> {
-//         db.fuzzy_search_users(query, 10)
-//             .await
-//             .unwrap()
-//             .into_iter()
-//             .map(|user| user.github_login)
-//             .collect::<Vec<_>>()
-//     }
-// }
+    async fn fuzzy_search_user_names(db: &Database, query: &str) -> Vec<String> {
+        db.fuzzy_search_users(query, 10)
+            .await
+            .unwrap()
+            .into_iter()
+            .map(|user| user.github_login)
+            .collect::<Vec<_>>()
+    }
+}
 
 // #[gpui::test]
 // async fn test_invite_codes() {