diff --git a/src/rust/lektor_db/src/connexion.rs b/src/rust/lektor_db/src/connexion.rs
index 6021a8a1d341535e2e0f296adb85d9abdbcfd631..03f8ca4e60f73e0390e01f0beaf65da46b2fae5c 100644
--- a/src/rust/lektor_db/src/connexion.rs
+++ b/src/rust/lektor_db/src/connexion.rs
@@ -1,6 +1,7 @@
 use crate::{models::*, types::*, uri::LktUri, *};
 use hashbrown::HashMap;
 use kurisu_api::v1 as api_v1;
+use smallstring::SmallString;
 
 /// Create a connexion to a database and run automatically the migrations.
 fn establish_connection(path: impl AsRef<str>) -> Result<SqliteConnection, String> {
@@ -17,6 +18,24 @@ pub struct LktDatabaseConnection {
     sqlite: SqliteConnection,
 }
 
+/// Builder to realize a search operation in the database.
+#[derive(Debug, Default, Clone, PartialEq, Eq)]
+pub struct LktDatabaseSearch {
+    search_type: LktDatabaseSearchType,
+    uri: LktUri,
+    range: Option<Range<usize>>,
+}
+
+/// A searcg type, to determine which table we are search.
+#[derive(Debug, Default, Clone, PartialEq, Eq)]
+pub enum LktDatabaseSearchType {
+    Playlist(SmallString),
+    History,
+
+    #[default]
+    Database,
+}
+
 /// Load the diesel DSL for a given table. With the loaded dsl execute the
 /// expression...
 macro_rules! with_dsl {
@@ -38,6 +57,30 @@ macro_rules! fuzzy {
     (@inner $x:ident $y:ident $($xs:ident)+) => { fuzzy!(@inner $x $y).concat(fuzzy!(@inner $($xs)+)) };
 }
 
+impl LktDatabaseSearch {
+    pub fn new(search_type: LktDatabaseSearchType) -> Self {
+        Self {
+            search_type,
+            ..Default::default()
+        }
+    }
+
+    pub fn search_type(mut self, ty: LktDatabaseSearchType) -> Self {
+        self.search_type = ty;
+        self
+    }
+
+    pub fn range(mut self, range: Range<usize>) -> Self {
+        self.range = Some(range);
+        self
+    }
+
+    pub fn uri(mut self, uri: LktUri) -> Self {
+        self.uri = uri;
+        self
+    }
+}
+
 impl LktDatabaseConnection {
     /// Create a new database connexion.
     pub fn try_new(path: impl AsRef<Path>) -> LktDatabaseResult<Self> {
@@ -201,17 +244,43 @@ impl LktDatabaseConnection {
         }}
     }
 
-    /// Search the history by URIs. We return the local ids.
-    pub fn search_history(&mut self, _uri: LktUri) -> LktDatabaseResult<Vec<i64>> {
-        todo!()
-    }
+    /// Search the database with the built search. We return the local ids.
+    pub fn search(&mut self, search: LktDatabaseSearch) -> LktDatabaseResult<Vec<i64>> {
+        // We begin by filtering the database, for KaraMaker, Language, Search
+        // and Playlist we get all non virtual karas, because we are joining
+        // other tables we can't use [into_boxed]...
+
+        let karas = match search.uri {
+            LktUri::Id(uri_id) => with_dsl! { kara => kara
+                .filter(id.is(uri_id))
+                .filter(is_virtual.is(false))
+                .into_boxed()
+            },
+
+            LktUri::Origin(ref uri_origin) => with_dsl! { kara => kara
+                .filter(song_origin.is(uri_origin.as_str()))
+                .filter(is_virtual.is(false))
+                .into_boxed()
+            },
+
+            LktUri::Type(ref uri_type) => with_dsl!(kara => kara
+                .filter(song_type.is(uri_type.as_str()))
+                .filter(is_virtual.is(false))
+                .into_boxed()
+            ),
+
+            LktUri::FuzzySearch(_) => with_dsl! { kara => kara.into_boxed() },
+
+            LktUri::KaraMaker(_)
+            | LktUri::Language(_)
+            | LktUri::Search(_)
+            | LktUri::Playlist(_)
+            | LktUri::Any => with_dsl! { kara => kara
+                .filter(is_virtual.is(false))
+                .into_boxed()
+            },
+        };
 
-    /// Search the given playlist by URIs. We return the local ids.
-    pub fn search_playlist<S: AsRef<str>>(
-        &mut self,
-        _playlist: S,
-        _uri: LktUri,
-    ) -> LktDatabaseResult<Vec<i64>> {
         todo!()
     }
 
diff --git a/src/rust/lektor_db/src/uri.rs b/src/rust/lektor_db/src/uri.rs
index dd5e0b17b66f9574925703963ed4a6d6ae3d83ed..dd0fee774d9dff5b553a6ff838980c784e07ab57 100644
--- a/src/rust/lektor_db/src/uri.rs
+++ b/src/rust/lektor_db/src/uri.rs
@@ -1,7 +1,7 @@
 use lektor_c_compat::rs::{LktCUri, LktUriField};
 use smallstring::SmallString;
 
-#[derive(Debug, Clone, Default)]
+#[derive(Debug, Clone, Default, PartialEq, Eq)]
 pub enum LktUri {
     /// The id of the kara must match the URI.
     Id(i64),