mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-26 18:03:02 +03:00
Add fuzzy_search_users to Db trait, PostgresDb
This commit is contained in:
parent
079e514379
commit
6050e0ead7
@ -0,0 +1,2 @@
|
||||
CREATE EXTENSION IF NOT EXISTS pg_trgm;
|
||||
CREATE INDEX trigram_index_users_on_github_login ON users USING GIN(github_login gin_trgm_ops);
|
@ -10,6 +10,7 @@ use time::OffsetDateTime;
|
||||
pub trait Db: Send + Sync {
|
||||
async fn create_user(&self, github_login: &str, admin: bool) -> Result<UserId>;
|
||||
async fn get_all_users(&self) -> Result<Vec<User>>;
|
||||
async fn fuzzy_search_users(&self, query: &str, limit: u32) -> Result<Vec<User>>;
|
||||
async fn get_user_by_id(&self, id: UserId) -> Result<Option<User>>;
|
||||
async fn get_users_by_ids(&self, ids: Vec<UserId>) -> Result<Vec<User>>;
|
||||
async fn get_user_by_github_login(&self, github_login: &str) -> Result<Option<User>>;
|
||||
@ -99,6 +100,21 @@ impl Db for PostgresDb {
|
||||
Ok(sqlx::query_as(query).fetch_all(&self.pool).await?)
|
||||
}
|
||||
|
||||
async fn fuzzy_search_users(&self, name_query: &str, limit: u32) -> Result<Vec<User>> {
|
||||
let query = "
|
||||
SELECT users.*
|
||||
FROM users
|
||||
WHERE github_login % $1
|
||||
ORDER BY github_login <-> $1
|
||||
LIMIT $2
|
||||
";
|
||||
Ok(sqlx::query_as(query)
|
||||
.bind(name_query)
|
||||
.bind(limit)
|
||||
.fetch_all(&self.pool)
|
||||
.await?)
|
||||
}
|
||||
|
||||
async fn get_user_by_id(&self, id: UserId) -> Result<Option<User>> {
|
||||
let users = self.get_users_by_ids(vec![id]).await?;
|
||||
Ok(users.into_iter().next())
|
||||
@ -640,6 +656,31 @@ pub mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_fuzzy_search_users() {
|
||||
let test_db = TestDb::postgres().await;
|
||||
let db = test_db.db();
|
||||
for github_login in [
|
||||
"nathansobo",
|
||||
"nathansobot",
|
||||
"nathanszabo",
|
||||
"maxbrunsfeld",
|
||||
"as-cii",
|
||||
] {
|
||||
db.create_user(github_login, false).await.unwrap();
|
||||
}
|
||||
|
||||
let results = db
|
||||
.fuzzy_search_users("nathasbo", 10)
|
||||
.await
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|user| user.github_login)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
assert_eq!(results, &["nathansobo", "nathanszabo", "nathansobot"]);
|
||||
}
|
||||
|
||||
pub struct TestDb {
|
||||
pub db: Option<Arc<dyn Db>>,
|
||||
pub url: String,
|
||||
@ -749,6 +790,10 @@ pub mod tests {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
async fn fuzzy_search_users(&self, _: &str, _: u32) -> Result<Vec<User>> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
async fn get_user_by_id(&self, id: UserId) -> Result<Option<User>> {
|
||||
Ok(self.get_users_by_ids(vec![id]).await?.into_iter().next())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user