@@ -40,17 +40,14 @@ use crate::{
4040} ;
4141
4242use self :: { debouncer:: EventDebouncer , options:: Options } ;
43- use sqlx:: {
44- postgres:: { PgListener , PgPool } ,
45- Executor ,
46- } ;
43+ use sqlx:: { postgres:: PgPool , Executor } ;
4744
4845#[ derive( Debug ) ]
4946enum InternalMessage {
5047 PublishDiagnostics ( lsp_types:: Url ) ,
5148 SetOptions ( Options ) ,
52- RefreshSchemaCache ,
5349 SetSchemaCache ( SchemaCache ) ,
50+ SetDatabaseConnection ( DbConnection ) ,
5451}
5552
5653/// `lsp-servers` `Connection` type uses a crossbeam channel, which is not compatible with tokio's async runtime.
@@ -210,29 +207,54 @@ impl Server {
210207 } ) ;
211208 }
212209
213- async fn update_options ( & mut self , options : Options ) -> anyhow:: Result < ( ) > {
214- if options. db_connection_string . is_none ( ) {
210+ fn update_db_connection ( & self , options : Options ) -> anyhow:: Result < ( ) > {
211+ if options. db_connection_string . is_none ( )
212+ || self
213+ . db_conn
214+ . as_ref ( )
215+ . is_some_and ( |c| c. connected_to ( options. db_connection_string . as_ref ( ) . unwrap ( ) ) )
216+ {
215217 return Ok ( ( ) ) ;
216218 }
217219
218- let new_conn = if self . db_conn . is_none ( ) {
219- DbConnection :: new ( options. db_connection_string . clone ( ) . unwrap ( ) ) . await ?
220- } else {
221- let current_conn = self . db_conn . take ( ) . unwrap ( ) ;
222- current_conn
223- . refresh_db_connection ( options. db_connection_string . clone ( ) )
224- . await ?
225- } ;
220+ let connection_string = options. db_connection_string . unwrap ( ) ;
226221
227222 let internal_tx = self . internal_tx . clone ( ) ;
223+ let client = self . client . clone ( ) ;
228224 self . spawn_with_cancel ( async move {
229- new_conn. start_listening ( move || {
225+ match DbConnection :: new ( connection_string. into ( ) ) . await {
226+ Ok ( conn) => {
227+ internal_tx
228+ . send ( InternalMessage :: SetDatabaseConnection ( conn) )
229+ . unwrap ( ) ;
230+ }
231+ Err ( why) => {
232+ client. send_info_notification ( & format ! ( "Unable to update database connection: {}" , why) ) ;
233+
234+ }
235+ }
236+ } ) ;
237+
238+ Ok ( ( ) )
239+ }
240+
241+ async fn listen_for_schema_updates ( & mut self ) -> anyhow:: Result < ( ) > {
242+ if self . db_conn . is_none ( ) {
243+ eprintln ! ( "Error trying to listen for schema updates: No database connection" ) ;
244+ return Ok ( ( ) ) ;
245+ }
246+
247+ let internal_tx = self . internal_tx . clone ( ) ;
248+ self . db_conn
249+ . as_mut ( )
250+ . unwrap ( )
251+ . listen_for_schema_updates ( move |schema_cache| {
230252 internal_tx
231- . send ( InternalMessage :: RefreshSchemaCache )
253+ . send ( InternalMessage :: SetSchemaCache ( schema_cache ) )
232254 . unwrap ( ) ;
233- // TODO: handle result
234- } ) . await . unwrap ( )
235- } ) ;
255+ // TODO: handle result
256+ } )
257+ . await ? ;
236258
237259 Ok ( ( ) )
238260 }
@@ -692,26 +714,6 @@ impl Server {
692714 } ) ;
693715 }
694716
695- async fn refresh_schema_cache ( & self ) {
696- if self . db_conn . is_none ( ) {
697- return ;
698- }
699-
700- let tx = self . internal_tx . clone ( ) ;
701- let conn = self . db_conn . as_ref ( ) . unwrap ( ) . pool . clone ( ) ;
702- let client = self . client . clone ( ) ;
703-
704- client
705- . send_notification :: < ShowMessage > ( ShowMessageParams {
706- typ : lsp_types:: MessageType :: INFO ,
707- message : "Refreshing schema cache..." . to_string ( ) ,
708- } )
709- . unwrap ( ) ;
710- let schema_cache = SchemaCache :: load ( & conn) . await ;
711- tx. send ( InternalMessage :: SetSchemaCache ( schema_cache) )
712- . unwrap ( ) ;
713- }
714-
715717 fn did_change_configuration (
716718 & mut self ,
717719 params : DidChangeConfigurationParams ,
@@ -720,7 +722,7 @@ impl Server {
720722 self . pull_options ( ) ;
721723 } else {
722724 let options = self . client . parse_options ( params. settings ) ?;
723- self . update_options ( options) ;
725+ self . update_db_connection ( options) ;
724726 }
725727
726728 Ok ( ( ) )
@@ -744,14 +746,14 @@ impl Server {
744746 msg = self . client_rx. recv( ) => {
745747 match msg {
746748 None => panic!( "The LSP's client closed, but not via an 'exit' method. This should never happen." ) ,
747- Some ( m) => self . handle_message( m)
749+ Some ( m) => self . handle_message( m) . await
748750 }
749751 } ,
750752 } ?;
751753 }
752754 }
753755
754- fn handle_message ( & mut self , msg : Message ) -> anyhow:: Result < ( ) > {
756+ async fn handle_message ( & mut self , msg : Message ) -> anyhow:: Result < ( ) > {
755757 match msg {
756758 Message :: Request ( request) => {
757759 if let Some ( response) = dispatch:: RequestDispatcher :: new ( request)
@@ -768,7 +770,8 @@ impl Server {
768770 Message :: Notification ( notification) => {
769771 dispatch:: NotificationDispatcher :: new ( notification)
770772 . on :: < DidChangeConfiguration , _ > ( |params| {
771- self . did_change_configuration ( params)
773+ self . did_change_configuration ( params) ;
774+ Ok ( ( ) )
772775 } ) ?
773776 . on :: < DidCloseTextDocument , _ > ( |params| self . did_close ( params) ) ?
774777 . on :: < DidOpenTextDocument , _ > ( |params| self . did_open ( params) ) ?
@@ -788,17 +791,24 @@ impl Server {
788791 async fn handle_internal_message ( & mut self , msg : InternalMessage ) -> anyhow:: Result < ( ) > {
789792 match msg {
790793 InternalMessage :: SetSchemaCache ( c) => {
794+ self . client
795+ . send_info_notification ( "Refreshing Schema Cache..." ) ;
791796 self . ide . set_schema_cache ( c) ;
797+ self . client . send_info_notification ( "Updated Schema Cache." ) ;
792798 self . compute_now ( ) ;
793799 }
794- InternalMessage :: RefreshSchemaCache => {
795- self . refresh_schema_cache ( ) . await ;
796- }
797800 InternalMessage :: PublishDiagnostics ( uri) => {
798801 self . publish_diagnostics ( uri) ?;
799802 }
800803 InternalMessage :: SetOptions ( options) => {
801- self . update_options ( options) ;
804+ self . update_db_connection ( options) ;
805+ }
806+ InternalMessage :: SetDatabaseConnection ( conn) => {
807+ let current = self . db_conn . replace ( conn) ;
808+ if current. is_some ( ) {
809+ current. unwrap ( ) . close ( ) . await
810+ }
811+ self . listen_for_schema_updates ( ) ;
802812 }
803813 }
804814
0 commit comments