From ceb7f1bf53185dfb8b3bb0680f0de781c35f6528 Mon Sep 17 00:00:00 2001 From: Guillaume Hivert Date: Fri, 2 Aug 2024 01:21:48 +0200 Subject: [PATCH] feat: add fuzzy search --- .../src/backend/gleam/type_search/state.gleam | 29 ++++++++++++++++++- .../src/backend/postgres/queries.gleam | 1 - apps/backend/src/backend/router.gleam | 1 - 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/apps/backend/src/backend/gleam/type_search/state.gleam b/apps/backend/src/backend/gleam/type_search/state.gleam index 3782597..9930818 100644 --- a/apps/backend/src/backend/gleam/type_search/state.gleam +++ b/apps/backend/src/backend/gleam/type_search/state.gleam @@ -42,7 +42,7 @@ fn loop(msg: msg.Msg, state: State) -> actor.Next(msg.Msg, State) { signature |> parse.parse_function |> result.nil_error - |> result.then(type_search.find(state.search, _, state.db)) + |> result.then(permutation_search(state, _)) |> option.from_result |> function.tap(fn(res) { process.send(subject, res) }) actor.continue(state) @@ -59,6 +59,33 @@ fn loop(msg: msg.Msg, state: State) -> actor.Next(msg.Msg, State) { actor.continue(state) } +fn is_permutable(list: List(a), len: Int) { + case list { + _ if len > 4 -> False + [_, ..rest] -> is_permutable(rest, len + 1) + [] -> True + } +} + +fn permutation_search(state: State, kind: parse.Kind) { + case kind { + parse.Function(params, return) -> { + let permutable = is_permutable(params, 0) + use <- bool.lazy_guard(when: !permutable, return: fn() { + type_search.find(state.search, kind, state.db) + }) + Ok({ + let permutations = list.permutations(params) + use permutation <- list.flat_map(permutations) + parse.Function(permutation, return) + |> type_search.find(state.search, _, state.db) + |> result.unwrap([]) + }) + } + _ -> Error(Nil) + } +} + fn compute_rows( offset: Int, db: pgo.Connection, diff --git a/apps/backend/src/backend/postgres/queries.gleam b/apps/backend/src/backend/postgres/queries.gleam index ce56914..a5825f4 100644 --- a/apps/backend/src/backend/postgres/queries.gleam +++ b/apps/backend/src/backend/postgres/queries.gleam @@ -458,7 +458,6 @@ pub fn find_similar_type_names(db: pgo.Connection, name: String) { |> pgo.execute(db, [pgo.text(name)], dynamic.element(0, dynamic.string)) |> result.map_error(error.DatabaseError) |> result.map(fn(r) { r.rows }) - |> io.debug } pub fn name_search(db: pgo.Connection, query: String) { diff --git a/apps/backend/src/backend/router.gleam b/apps/backend/src/backend/router.gleam index 8b5b608..36dfaeb 100644 --- a/apps/backend/src/backend/router.gleam +++ b/apps/backend/src/backend/router.gleam @@ -8,7 +8,6 @@ import cors_builder as cors import gleam/erlang/process import gleam/http import gleam/int -import gleam/io import gleam/json import gleam/list import gleam/option