@@ -9,13 +9,13 @@ use std::{
99} ;
1010
1111use anyhow:: { Context as _, Result , bail} ;
12+ use collections:: HashMap ;
1213use db:: { define_connection, query, sqlez:: connection:: Connection , sqlez_macros:: sql} ;
1314use gpui:: { Axis , Bounds , Task , WindowBounds , WindowId , point, size} ;
1415use project:: debugger:: breakpoint_store:: { BreakpointState , SourceBreakpoint } ;
1516
1617use language:: { LanguageName , Toolchain } ;
1718use project:: WorktreeId ;
18- use remote:: ssh_session:: SshProjectId ;
1919use sqlez:: {
2020 bindable:: { Bind , Column , StaticColumnCount } ,
2121 statement:: { SqlType , Statement } ,
@@ -33,7 +33,7 @@ use crate::{
3333
3434use model:: {
3535 GroupId , ItemId , PaneId , SerializedItem , SerializedPane , SerializedPaneGroup ,
36- SerializedSshConnection , SerializedWorkspace ,
36+ SerializedSshConnection , SerializedWorkspace , SshConnectionId ,
3737} ;
3838
3939use self :: model:: { DockStructure , SerializedWorkspaceLocation } ;
@@ -615,15 +615,15 @@ impl WorkspaceDb {
615615 pub ( crate ) fn ssh_workspace_for_roots < P : AsRef < Path > > (
616616 & self ,
617617 worktree_roots : & [ P ] ,
618- ssh_project_id : SshProjectId ,
618+ ssh_project_id : SshConnectionId ,
619619 ) -> Option < SerializedWorkspace > {
620620 self . workspace_for_roots_internal ( worktree_roots, Some ( ssh_project_id) )
621621 }
622622
623623 pub ( crate ) fn workspace_for_roots_internal < P : AsRef < Path > > (
624624 & self ,
625625 worktree_roots : & [ P ] ,
626- ssh_connection_id : Option < SshProjectId > ,
626+ ssh_connection_id : Option < SshConnectionId > ,
627627 ) -> Option < SerializedWorkspace > {
628628 // paths are sorted before db interactions to ensure that the order of the paths
629629 // doesn't affect the workspace selection for existing workspaces
@@ -762,15 +762,21 @@ impl WorkspaceDb {
762762 /// that used this workspace previously
763763 pub ( crate ) async fn save_workspace ( & self , workspace : SerializedWorkspace ) {
764764 let paths = workspace. paths . serialize ( ) ;
765- let ssh_connection_id = match & workspace. location {
766- SerializedWorkspaceLocation :: Local => None ,
767- SerializedWorkspaceLocation :: Ssh ( serialized_ssh_connection) => {
768- Some ( serialized_ssh_connection. id . 0 )
769- }
770- } ;
771765 log:: debug!( "Saving workspace at location: {:?}" , workspace. location) ;
772766 self . write ( move |conn| {
773767 conn. with_savepoint ( "update_worktrees" , || {
768+ let ssh_connection_id = match & workspace. location {
769+ SerializedWorkspaceLocation :: Local => None ,
770+ SerializedWorkspaceLocation :: Ssh ( connection) => {
771+ Some ( Self :: get_or_create_ssh_connection_query (
772+ conn,
773+ connection. host . clone ( ) ,
774+ connection. port ,
775+ connection. user . clone ( ) ,
776+ ) ?. 0 )
777+ }
778+ } ;
779+
774780 // Clear out panes and pane_groups
775781 conn. exec_bound ( sql ! (
776782 DELETE FROM pane_groups WHERE workspace_id = ?1 ;
@@ -893,39 +899,34 @@ impl WorkspaceDb {
893899 host : String ,
894900 port : Option < u16 > ,
895901 user : Option < String > ,
896- ) -> Result < SshProjectId > {
897- if let Some ( id) = self
898- . get_ssh_connection ( host. clone ( ) , port, user. clone ( ) )
899- . await ?
902+ ) -> Result < SshConnectionId > {
903+ self . write ( move |conn| Self :: get_or_create_ssh_connection_query ( conn, host, port, user) )
904+ . await
905+ }
906+
907+ fn get_or_create_ssh_connection_query (
908+ this : & Connection ,
909+ host : String ,
910+ port : Option < u16 > ,
911+ user : Option < String > ,
912+ ) -> Result < SshConnectionId > {
913+ if let Some ( id) = this. select_row_bound ( sql ! (
914+ SELECT id FROM ssh_connections WHERE host IS ? AND port IS ? AND user IS ? LIMIT 1
915+ ) ) ?( ( host. clone ( ) , port, user. clone ( ) ) ) ?
900916 {
901- Ok ( SshProjectId ( id) )
917+ Ok ( SshConnectionId ( id) )
902918 } else {
903919 log:: debug!( "Inserting SSH project at host {host}" ) ;
904- let id = self
905- . insert_ssh_connection ( host, port, user)
906- . await ?
907- . context ( "failed to insert ssh project" ) ?;
908- Ok ( SshProjectId ( id) )
909- }
910- }
911-
912- query ! {
913- async fn get_ssh_connection( host: String , port: Option <u16 >, user: Option <String >) -> Result <Option <u64 >> {
914- SELECT id
915- FROM ssh_connections
916- WHERE host IS ? AND port IS ? AND user IS ?
917- LIMIT 1
918- }
919- }
920-
921- query ! {
922- async fn insert_ssh_connection( host: String , port: Option <u16 >, user: Option <String >) -> Result <Option <u64 >> {
923- INSERT INTO ssh_connections (
924- host,
925- port,
926- user
927- ) VALUES ( ?1 , ?2 , ?3 )
928- RETURNING id
920+ let id = this. select_row_bound ( sql ! (
921+ INSERT INTO ssh_connections (
922+ host,
923+ port,
924+ user
925+ ) VALUES ( ?1 , ?2 , ?3 )
926+ RETURNING id
927+ ) ) ?( ( host, port, user) ) ?
928+ . context ( "failed to insert ssh project" ) ?;
929+ Ok ( SshConnectionId ( id) )
929930 }
930931 }
931932
@@ -963,15 +964,15 @@ impl WorkspaceDb {
963964 fn session_workspaces (
964965 & self ,
965966 session_id : String ,
966- ) -> Result < Vec < ( PathList , Option < u64 > , Option < SshProjectId > ) > > {
967+ ) -> Result < Vec < ( PathList , Option < u64 > , Option < SshConnectionId > ) > > {
967968 Ok ( self
968969 . session_workspaces_query ( session_id) ?
969970 . into_iter ( )
970971 . map ( |( paths, order, window_id, ssh_connection_id) | {
971972 (
972973 PathList :: deserialize ( & SerializedPathList { paths, order } ) ,
973974 window_id,
974- ssh_connection_id. map ( SshProjectId ) ,
975+ ssh_connection_id. map ( SshConnectionId ) ,
975976 )
976977 } )
977978 . collect ( ) )
@@ -1001,15 +1002,15 @@ impl WorkspaceDb {
10011002 }
10021003 }
10031004
1004- fn ssh_connections ( & self ) -> Result < Vec < SerializedSshConnection > > {
1005+ fn ssh_connections ( & self ) -> Result < HashMap < SshConnectionId , SerializedSshConnection > > {
10051006 Ok ( self
10061007 . ssh_connections_query ( ) ?
10071008 . into_iter ( )
1008- . map ( |( id, host, port, user) | SerializedSshConnection {
1009- id : SshProjectId ( id ) ,
1010- host ,
1011- port,
1012- user ,
1009+ . map ( |( id, host, port, user) | {
1010+ (
1011+ SshConnectionId ( id ) ,
1012+ SerializedSshConnection { host , port, user } ,
1013+ )
10131014 } )
10141015 . collect ( ) )
10151016 }
@@ -1021,19 +1022,18 @@ impl WorkspaceDb {
10211022 }
10221023 }
10231024
1024- pub fn ssh_connection ( & self , id : SshProjectId ) -> Result < SerializedSshConnection > {
1025+ pub ( crate ) fn ssh_connection ( & self , id : SshConnectionId ) -> Result < SerializedSshConnection > {
10251026 let row = self . ssh_connection_query ( id. 0 ) ?;
10261027 Ok ( SerializedSshConnection {
1027- id : SshProjectId ( row. 0 ) ,
1028- host : row. 1 ,
1029- port : row. 2 ,
1030- user : row. 3 ,
1028+ host : row. 0 ,
1029+ port : row. 1 ,
1030+ user : row. 2 ,
10311031 } )
10321032 }
10331033
10341034 query ! {
1035- fn ssh_connection_query( id: u64 ) -> Result <( u64 , String , Option <u16 >, Option <String >) > {
1036- SELECT id , host, port, user
1035+ fn ssh_connection_query( id: u64 ) -> Result <( String , Option <u16 >, Option <String >) > {
1036+ SELECT host, port, user
10371037 FROM ssh_connections
10381038 WHERE id = ?
10391039 }
@@ -1075,10 +1075,8 @@ impl WorkspaceDb {
10751075 let ssh_connections = self . ssh_connections ( ) ?;
10761076
10771077 for ( id, paths, ssh_connection_id) in self . recent_workspaces ( ) ? {
1078- if let Some ( ssh_connection_id) = ssh_connection_id. map ( SshProjectId ) {
1079- if let Some ( ssh_connection) =
1080- ssh_connections. iter ( ) . find ( |rp| rp. id == ssh_connection_id)
1081- {
1078+ if let Some ( ssh_connection_id) = ssh_connection_id. map ( SshConnectionId ) {
1079+ if let Some ( ssh_connection) = ssh_connections. get ( & ssh_connection_id) {
10821080 result. push ( (
10831081 id,
10841082 SerializedWorkspaceLocation :: Ssh ( ssh_connection. clone ( ) ) ,
@@ -2340,12 +2338,10 @@ mod tests {
23402338 ]
23412339 . into_iter ( )
23422340 . map ( |( host, user) | async {
2343- let id = db
2344- . get_or_create_ssh_connection ( host. to_string ( ) , None , Some ( user. to_string ( ) ) )
2341+ db. get_or_create_ssh_connection ( host. to_string ( ) , None , Some ( user. to_string ( ) ) )
23452342 . await
23462343 . unwrap ( ) ;
23472344 SerializedSshConnection {
2348- id,
23492345 host : host. into ( ) ,
23502346 port : None ,
23512347 user : Some ( user. into ( ) ) ,
@@ -2501,26 +2497,34 @@ mod tests {
25012497 let stored_projects = db. ssh_connections ( ) . unwrap ( ) ;
25022498 assert_eq ! (
25032499 stored_projects,
2504- & [
2505- SerializedSshConnection {
2506- id: ids[ 0 ] ,
2507- host: "example.com" . into( ) ,
2508- port: None ,
2509- user: None ,
2510- } ,
2511- SerializedSshConnection {
2512- id: ids[ 1 ] ,
2513- host: "anotherexample.com" . into( ) ,
2514- port: Some ( 123 ) ,
2515- user: Some ( "user2" . into( ) ) ,
2516- } ,
2517- SerializedSshConnection {
2518- id: ids[ 2 ] ,
2519- host: "yetanother.com" . into( ) ,
2520- port: Some ( 345 ) ,
2521- user: None ,
2522- } ,
2500+ [
2501+ (
2502+ ids[ 0 ] ,
2503+ SerializedSshConnection {
2504+ host: "example.com" . into( ) ,
2505+ port: None ,
2506+ user: None ,
2507+ }
2508+ ) ,
2509+ (
2510+ ids[ 1 ] ,
2511+ SerializedSshConnection {
2512+ host: "anotherexample.com" . into( ) ,
2513+ port: Some ( 123 ) ,
2514+ user: Some ( "user2" . into( ) ) ,
2515+ }
2516+ ) ,
2517+ (
2518+ ids[ 2 ] ,
2519+ SerializedSshConnection {
2520+ host: "yetanother.com" . into( ) ,
2521+ port: Some ( 345 ) ,
2522+ user: None ,
2523+ }
2524+ ) ,
25232525 ]
2526+ . into_iter( )
2527+ . collect:: <HashMap <_, _>>( ) ,
25242528 ) ;
25252529 }
25262530
0 commit comments