From 2ffce4f516b1d47de13a3483470ec16c96b5daae Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 21 Mar 2025 12:04:59 +0200 Subject: [PATCH] Add non-blob columns to SQLite (#27236) --- crates/editor/src/persistence.rs | 30 ++++++++++++++----- crates/terminal_view/src/persistence.rs | 40 ++++++++++++++++++------- crates/workspace/src/persistence.rs | 18 ++++++++--- 3 files changed, 66 insertions(+), 22 deletions(-) diff --git a/crates/editor/src/persistence.rs b/crates/editor/src/persistence.rs index ed3ea3354f..7b742cefde 100644 --- a/crates/editor/src/persistence.rs +++ b/crates/editor/src/persistence.rs @@ -20,13 +20,20 @@ pub(crate) struct SerializedEditor { impl StaticColumnCount for SerializedEditor { fn column_count() -> usize { - 5 + 6 } } impl Bind for SerializedEditor { fn bind(&self, statement: &Statement, start_index: i32) -> Result { let start_index = statement.bind(&self.abs_path, start_index)?; + let start_index = statement.bind( + &self + .abs_path + .as_ref() + .map(|p| p.to_string_lossy().to_string()), + start_index, + )?; let start_index = statement.bind(&self.contents, start_index)?; let start_index = statement.bind(&self.language, start_index)?; @@ -51,6 +58,8 @@ impl Column for SerializedEditor { fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> { let (abs_path, start_index): (Option, i32) = Column::column(statement, start_index)?; + let (_abs_path, start_index): (Option, i32) = + Column::column(statement, start_index)?; let (contents, start_index): (Option, i32) = Column::column(statement, start_index)?; let (language, start_index): (Option, i32) = @@ -147,6 +156,10 @@ define_connection!( ON DELETE CASCADE ) STRICT; ), + sql! ( + ALTER TABLE editors ADD COLUMN buffer_path TEXT; + UPDATE editors SET buffer_path = CAST(path AS TEXT); + ), ]; ); @@ -158,7 +171,7 @@ const MAX_QUERY_PLACEHOLDERS: usize = 32000; impl EditorDb { query! { pub fn get_serialized_editor(item_id: ItemId, workspace_id: WorkspaceId) -> Result> { - SELECT path, contents, language, mtime_seconds, mtime_nanos FROM editors + SELECT path, buffer_path, contents, language, mtime_seconds, mtime_nanos FROM editors WHERE item_id = ? AND workspace_id = ? } } @@ -166,17 +179,18 @@ impl EditorDb { query! { pub async fn save_serialized_editor(item_id: ItemId, workspace_id: WorkspaceId, serialized_editor: SerializedEditor) -> Result<()> { INSERT INTO editors - (item_id, workspace_id, path, contents, language, mtime_seconds, mtime_nanos) + (item_id, workspace_id, path, buffer_path, contents, language, mtime_seconds, mtime_nanos) VALUES - (?1, ?2, ?3, ?4, ?5, ?6, ?7) + (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8) ON CONFLICT DO UPDATE SET item_id = ?1, workspace_id = ?2, path = ?3, - contents = ?4, - language = ?5, - mtime_seconds = ?6, - mtime_nanos = ?7 + buffer_path = ?4, + contents = ?5, + language = ?6, + mtime_seconds = ?7, + mtime_nanos = ?8 } } diff --git a/crates/terminal_view/src/persistence.rs b/crates/terminal_view/src/persistence.rs index 5668083973..ff8a80a726 100644 --- a/crates/terminal_view/src/persistence.rs +++ b/crates/terminal_view/src/persistence.rs @@ -403,7 +403,12 @@ define_connection! { DROP TABLE terminals; ALTER TABLE terminals2 RENAME TO terminals; - )]; + ), + sql! ( + ALTER TABLE terminals ADD COLUMN working_directory_path TEXT; + UPDATE terminals SET working_directory_path = CAST(working_directory AS TEXT); + ), + ]; } impl TerminalDb { @@ -419,15 +424,30 @@ impl TerminalDb { } } - query! { - pub async fn save_working_directory( - item_id: ItemId, - workspace_id: WorkspaceId, - working_directory: PathBuf - ) -> Result<()> { - INSERT OR REPLACE INTO terminals(item_id, workspace_id, working_directory) - VALUES (?, ?, ?) - } + pub async fn save_working_directory( + &self, + item_id: ItemId, + workspace_id: WorkspaceId, + working_directory: PathBuf, + ) -> Result<()> { + let query = + "INSERT INTO terminals(item_id, workspace_id, working_directory, working_directory_path) + VALUES (?1, ?2, ?3, ?4) + ON CONFLICT DO UPDATE SET + item_id = ?1, + workspace_id = ?2, + working_directory = ?3, + working_directory_path = ?4" + ; + self.write(move |conn| { + let mut statement = Statement::prepare(conn, query)?; + let mut next_index = statement.bind(&item_id, 1)?; + next_index = statement.bind(&workspace_id, next_index)?; + next_index = statement.bind(&working_directory, next_index)?; + statement.bind(&working_directory.to_string_lossy().to_string(), next_index)?; + statement.exec() + }) + .await } query! { diff --git a/crates/workspace/src/persistence.rs b/crates/workspace/src/persistence.rs index d864c5bd8a..78178ce216 100644 --- a/crates/workspace/src/persistence.rs +++ b/crates/workspace/src/persistence.rs @@ -12,6 +12,7 @@ use anyhow::{anyhow, bail, Context, Result}; use client::DevServerProjectId; use db::{define_connection, query, sqlez::connection::Connection, sqlez_macros::sql}; use gpui::{point, size, Axis, Bounds, WindowBounds, WindowId}; +use itertools::Itertools; use project::debugger::breakpoint_store::{BreakpointKind, SerializedBreakpoint}; use language::{LanguageName, Toolchain}; @@ -529,6 +530,11 @@ define_connection! { ON UPDATE CASCADE ); ), + sql!( + ALTER TABLE workspaces ADD COLUMN local_paths_array TEXT; + CREATE UNIQUE INDEX local_paths_array_uq ON workspaces(local_paths_array); + ALTER TABLE workspaces ADD COLUMN local_paths_order_array TEXT; + ), ]; } @@ -779,9 +785,11 @@ impl WorkspaceDb { bottom_dock_zoom, session_id, window_id, - timestamp + timestamp, + local_paths_array, + local_paths_order_array ) - VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, CURRENT_TIMESTAMP) + VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, CURRENT_TIMESTAMP, ?15, ?16) ON CONFLICT DO UPDATE SET local_paths = ?2, @@ -797,10 +805,12 @@ impl WorkspaceDb { bottom_dock_zoom = ?12, session_id = ?13, window_id = ?14, - timestamp = CURRENT_TIMESTAMP + timestamp = CURRENT_TIMESTAMP, + local_paths_array = ?15, + local_paths_order_array = ?16 ); let mut prepared_query = conn.exec_bound(query)?; - let args = (workspace.id, &local_paths, &local_paths_order, workspace.docks, workspace.session_id, workspace.window_id); + let args = (workspace.id, &local_paths, &local_paths_order, workspace.docks, workspace.session_id, workspace.window_id, local_paths.paths().iter().map(|path| path.to_string_lossy().to_string()).join(","), local_paths_order.order().iter().map(|order| order.to_string()).join(",")); prepared_query(args).context("Updating workspace")?; }