aboutsummaryrefslogtreecommitdiffstats
path: root/crates/daemon/src/aclient/database/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/daemon/src/aclient/database/mod.rs')
-rw-r--r--crates/daemon/src/aclient/database/mod.rs145
1 files changed, 62 insertions, 83 deletions
diff --git a/crates/daemon/src/aclient/database/mod.rs b/crates/daemon/src/aclient/database/mod.rs
index cdf71065..9da943ca 100644
--- a/crates/daemon/src/aclient/database/mod.rs
+++ b/crates/daemon/src/aclient/database/mod.rs
@@ -12,8 +12,8 @@ use sqlx::{
};
use time::OffsetDateTime;
use tracing::debug;
-use turtle::history::{History, HistoryId, get_host_user};
-use turtle_common::utils;
+use turtle::history::{History, HistoryId};
+use turtle_common::utils::{self, get_host_user};
use uuid::Uuid;
use crate::aclient::{
@@ -25,46 +25,29 @@ use crate::aclient::{settings::Settings, utils::setup_db};
#[derive(Clone)]
pub(crate) struct Context {
- pub(crate) session: String,
- pub(crate) cwd: String,
- pub(crate) hostname: String,
- pub(crate) host_id: String,
- pub(crate) git_root: Option<PathBuf>,
+ session: String,
+ cwd: String,
+ hostname: String,
+ host_id: String,
+ git_root: Option<PathBuf>,
}
#[derive(Default, Clone)]
-pub(crate) struct OptFilters {
- pub(crate) exit: Option<i64>,
- pub(crate) exclude_exit: Option<i64>,
- pub(crate) cwd: Option<String>,
- pub(crate) exclude_cwd: Option<String>,
- pub(crate) before: Option<String>,
- pub(crate) after: Option<String>,
- pub(crate) limit: Option<i64>,
- pub(crate) offset: Option<i64>,
- pub(crate) reverse: bool,
- pub(crate) include_duplicates: bool,
-}
-
-pub(crate) async fn current_context(session: String) -> eyre::Result<Context> {
- // TODO(@bpeetz): More of this needs to be moved to the client <2026-07-20>
-
- let hostname = get_host_user();
- let cwd = utils::get_current_dir();
- let host_id = Settings::host_id().await?;
- let git_root = utils::in_git_repo(cwd.as_str());
-
- Ok(Context {
- session,
- hostname,
- cwd,
- git_root,
- host_id: host_id.0.as_simple().to_string(),
- })
+struct OptFilters {
+ exit: Option<i64>,
+ exclude_exit: Option<i64>,
+ cwd: Option<String>,
+ exclude_cwd: Option<String>,
+ before: Option<String>,
+ after: Option<String>,
+ limit: Option<i64>,
+ offset: Option<i64>,
+ reverse: bool,
+ include_duplicates: bool,
}
impl Context {
- pub(crate) fn from_history(entry: &History) -> Self {
+ fn from_history(entry: &History) -> Self {
Self {
session: entry.session.clone(),
cwd: entry.cwd.clone(),
@@ -88,12 +71,12 @@ fn get_session_start_time(session_id: &str) -> Option<i64> {
// Intended for use on a developer machine and not a sync server.
// TODO: implement IntoIterator
#[derive(Debug, Clone)]
-pub struct ClientSqlite {
- pub(crate) pool: SqlitePool,
+pub(crate) struct ClientSqlite {
+ pool: SqlitePool,
}
impl ClientSqlite {
- pub async fn new(path: impl AsRef<Path>, timeout: f64) -> Result<Self> {
+ pub(crate) async fn new(path: impl AsRef<Path>, timeout: f64) -> Result<Self> {
fn mk_opts(path: &str) -> Result<SqliteConnectOptions> {
let opts = SqliteConnectOptions::from_str(path)?
.journal_mode(SqliteJournalMode::Wal)
@@ -220,7 +203,7 @@ impl ClientSqlite {
Ok(())
}
- pub(crate) async fn load(&self, id: &str) -> Result<Option<History>> {
+ async fn load(&self, id: &str) -> Result<Option<History>> {
debug!("loading history item {}", id);
let res = sqlx::query("select * from history where id = ?1")
@@ -232,11 +215,10 @@ impl ClientSqlite {
Ok(res)
}
- // make a unique list, that only shows the *newest* version of things
+ /// make a unique list, that only shows the *newest* version of things
pub(crate) async fn list(
&self,
- filters: &[FilterMode],
- context: &Context,
+ filters: Option<(&Context, &[FilterMode])>,
max: Option<usize>,
unique: bool,
include_deleted: bool,
@@ -249,28 +231,30 @@ impl ClientSqlite {
query.and_where_is_null("deleted_at");
}
- let git_root = context.git_root.clone().map_or_else(
- || context.cwd.clone(),
- |git_root| git_root.to_str().unwrap_or("/").to_string(),
- );
+ if let Some((context, filters)) = filters {
+ let git_root = context.git_root.clone().map_or_else(
+ || context.cwd.clone(),
+ |git_root| git_root.to_str().unwrap_or("/").to_string(),
+ );
- let session_start = get_session_start_time(&context.session);
+ let session_start = get_session_start_time(&context.session);
- for filter in filters {
- match filter {
- FilterMode::Global => &mut query,
- FilterMode::Host => query.and_where_eq("hostname", quote(&context.hostname)),
- FilterMode::Session => query.and_where_eq("session", quote(&context.session)),
- FilterMode::SessionPreload => {
- query.and_where_eq("session", quote(&context.session));
- if let Some(session_start) = session_start {
- query.or_where_lt("timestamp", session_start);
+ for filter in filters {
+ match filter {
+ FilterMode::Global => &mut query,
+ FilterMode::Host => query.and_where_eq("hostname", quote(&context.hostname)),
+ FilterMode::Session => query.and_where_eq("session", quote(&context.session)),
+ FilterMode::SessionPreload => {
+ query.and_where_eq("session", quote(&context.session));
+ if let Some(session_start) = session_start {
+ query.or_where_lt("timestamp", session_start);
+ }
+ &mut query
}
- &mut query
- }
- FilterMode::Directory => query.and_where_eq("cwd", quote(&context.cwd)),
- FilterMode::Workspace => query.and_where_like_left("cwd", &git_root),
- };
+ FilterMode::Directory => query.and_where_eq("cwd", quote(&context.cwd)),
+ FilterMode::Workspace => query.and_where_like_left("cwd", &git_root),
+ };
+ }
}
if unique {
@@ -310,7 +294,7 @@ impl ClientSqlite {
Ok(res)
}
- pub(crate) async fn last(&self) -> Result<Option<History>> {
+ async fn last(&self) -> Result<Option<History>> {
let res = sqlx::query(
"select * from history where duration >= 0 order by timestamp desc limit 1",
)
@@ -321,7 +305,7 @@ impl ClientSqlite {
Ok(res)
}
- pub(crate) async fn history_count(&self, include_deleted: bool) -> Result<i64> {
+ async fn history_count(&self, include_deleted: bool) -> Result<i64> {
let query = if include_deleted {
"select count(1) from history"
} else {
@@ -336,7 +320,7 @@ impl ClientSqlite {
// Could maybe break it down to a searchparams struct or smth but that feels a little... pointless.
// Been debating maybe a DSL for search? eg "before:time limit:1 the query"
#[expect(clippy::too_many_lines)]
- pub(crate) async fn search(
+ async fn search(
&self,
search_mode: SearchMode,
filter: FilterMode,
@@ -492,7 +476,7 @@ impl ClientSqlite {
Ok(ordering::reorder_fuzzy(search_mode, orig_query, res))
}
- pub(crate) async fn query_history(&self, query: &str) -> Result<Vec<History>> {
+ async fn query_history(&self, query: &str) -> Result<Vec<History>> {
let res = sqlx::query(query)
.map(Self::query_history_inner)
.fetch_all(&self.pool)
@@ -501,7 +485,7 @@ impl ClientSqlite {
Ok(res)
}
- pub(crate) async fn all_with_count(&self) -> Result<Vec<(History, i32)>> {
+ async fn all_with_count(&self) -> Result<Vec<(History, i32)>> {
debug!("listing history");
let mut query = SqlBuilder::select_from(SqlName::new("history").alias("h").baquoted());
@@ -539,7 +523,7 @@ impl ClientSqlite {
Ok(res)
}
- pub(crate) fn all_paged(&self, page_size: usize, include_deleted: bool, unique: bool) -> Paged {
+ fn all_paged(&self, page_size: usize, include_deleted: bool, unique: bool) -> Paged {
Paged::new(self.clone(), page_size, include_deleted, unique)
}
@@ -555,7 +539,7 @@ impl ClientSqlite {
Ok(())
}
- pub(crate) async fn stats(&self, h: &History) -> Result<HistoryStats> {
+ async fn stats(&self, h: &History) -> Result<HistoryStats> {
// We select the previous in the session by time
let mut prev = SqlBuilder::select_from("history");
prev.field("*")
@@ -672,7 +656,7 @@ impl ClientSqlite {
})
}
- pub(crate) async fn get_dups(&self, before: i64, dupkeep: u32) -> Result<Vec<History>> {
+ async fn get_dups(&self, before: i64, dupkeep: u32) -> Result<Vec<History>> {
let res = sqlx::query(
"SELECT * FROM (
SELECT *, ROW_NUMBER()
@@ -693,7 +677,7 @@ impl ClientSqlite {
}
}
-pub(crate) struct Paged {
+struct Paged {
database: ClientSqlite,
page_size: usize,
last_id: Option<String>,
@@ -702,12 +686,7 @@ pub(crate) struct Paged {
}
impl Paged {
- pub(crate) fn new(
- database: ClientSqlite,
- page_size: usize,
- include_deleted: bool,
- unique: bool,
- ) -> Self {
+ fn new(database: ClientSqlite, page_size: usize, include_deleted: bool, unique: bool) -> Self {
Self {
database,
page_size,
@@ -717,7 +696,7 @@ impl Paged {
}
}
- pub(crate) async fn next(&mut self) -> Result<Option<Vec<History>>> {
+ async fn next(&mut self) -> Result<Option<Vec<History>>> {
let mut query = SqlBuilder::select_from(SqlName::new("history").alias("h").baquoted());
query.field("*").order_desc("id");
@@ -1220,12 +1199,12 @@ mod test {
}
}
-pub(crate) struct QueryTokenizer<'a> {
+struct QueryTokenizer<'a> {
query: &'a str,
last_pos: usize,
}
-pub(crate) enum QueryToken<'a> {
+enum QueryToken<'a> {
Match(&'a str, bool),
MatchStart(&'a str, bool),
MatchEnd(&'a str, bool),
@@ -1235,7 +1214,7 @@ pub(crate) enum QueryToken<'a> {
}
impl QueryToken<'_> {
- pub(crate) fn has_uppercase(&self) -> bool {
+ fn has_uppercase(&self) -> bool {
match self {
Self::Match(term, _)
| Self::MatchStart(term, _)
@@ -1245,7 +1224,7 @@ impl QueryToken<'_> {
}
}
- pub(crate) fn is_inverse(&self) -> bool {
+ fn is_inverse(&self) -> bool {
match self {
Self::Match(_, inv)
| Self::MatchStart(_, inv)
@@ -1257,7 +1236,7 @@ impl QueryToken<'_> {
}
impl<'a> QueryTokenizer<'a> {
- pub(crate) fn new(query: &'a str) -> Self {
+ fn new(query: &'a str) -> Self {
Self { query, last_pos: 0 }
}
}