11use anyhow:: Result ;
22use spin_core:: wasmtime:: component:: Resource ;
3- use spin_world:: spin:: postgres:: postgres:: { self as v3} ;
3+ use spin_world:: spin:: postgres3_0_0:: postgres:: { self as v3} ;
4+ use spin_world:: spin:: postgres4_0_0:: postgres:: { self as v4} ;
45use spin_world:: v1:: postgres as v1;
56use spin_world:: v1:: rdbms_types as v1_types;
67use spin_world:: v2:: postgres:: { self as v2} ;
@@ -16,24 +17,24 @@ impl<C: Client> InstanceState<C> {
1617 async fn open_connection < Conn : ' static > (
1718 & mut self ,
1819 address : & str ,
19- ) -> Result < Resource < Conn > , v3 :: Error > {
20+ ) -> Result < Resource < Conn > , v4 :: Error > {
2021 self . connections
2122 . push (
2223 C :: build_client ( address)
2324 . await
24- . map_err ( |e| v3 :: Error :: ConnectionFailed ( format ! ( "{e:?}" ) ) ) ?,
25+ . map_err ( |e| v4 :: Error :: ConnectionFailed ( format ! ( "{e:?}" ) ) ) ?,
2526 )
26- . map_err ( |_| v3 :: Error :: ConnectionFailed ( "too many connections" . into ( ) ) )
27+ . map_err ( |_| v4 :: Error :: ConnectionFailed ( "too many connections" . into ( ) ) )
2728 . map ( Resource :: new_own)
2829 }
2930
3031 async fn get_client < Conn : ' static > (
3132 & mut self ,
3233 connection : Resource < Conn > ,
33- ) -> Result < & C , v3 :: Error > {
34+ ) -> Result < & C , v4 :: Error > {
3435 self . connections
3536 . get ( connection. rep ( ) )
36- . ok_or_else ( || v3 :: Error :: ConnectionFailed ( "no connection found" . into ( ) ) )
37+ . ok_or_else ( || v4 :: Error :: ConnectionFailed ( "no connection found" . into ( ) ) )
3738 }
3839
3940 async fn is_address_allowed ( & self , address : & str ) -> Result < bool > {
@@ -67,11 +68,15 @@ impl<C: Client> InstanceState<C> {
6768
6869fn v2_params_to_v3 (
6970 params : Vec < v2_types:: ParameterValue > ,
70- ) -> Result < Vec < v3 :: ParameterValue > , v2:: Error > {
71+ ) -> Result < Vec < v4 :: ParameterValue > , v2:: Error > {
7172 params. into_iter ( ) . map ( |p| p. try_into ( ) ) . collect ( )
7273}
7374
74- impl < C : Send + Sync + Client > spin_world:: spin:: postgres:: postgres:: HostConnection
75+ fn v3_params_to_v4 ( params : Vec < v3:: ParameterValue > ) -> Vec < v4:: ParameterValue > {
76+ params. into_iter ( ) . map ( |p| p. into ( ) ) . collect ( )
77+ }
78+
79+ impl < C : Send + Sync + Client > spin_world:: spin:: postgres3_0_0:: postgres:: HostConnection
7580 for InstanceState < C >
7681{
7782 #[ instrument( name = "spin_outbound_pg.open" , skip( self , address) , err( level = Level :: INFO ) , fields( otel. kind = "client" , db. system = "postgresql" , db. address = Empty , server. port = Empty , db. namespace = Empty ) ) ]
@@ -87,7 +92,7 @@ impl<C: Send + Sync + Client> spin_world::spin::postgres::postgres::HostConnecti
8792 "address {address} is not permitted"
8893 ) ) ) ;
8994 }
90- self . open_connection ( & address) . await
95+ Ok ( self . open_connection ( & address) . await ? )
9196 }
9297
9398 #[ instrument( name = "spin_outbound_pg.execute" , skip( self , connection, params) , err( level = Level :: INFO ) , fields( otel. kind = "client" , db. system = "postgresql" , otel. name = statement) ) ]
@@ -97,10 +102,11 @@ impl<C: Send + Sync + Client> spin_world::spin::postgres::postgres::HostConnecti
97102 statement : String ,
98103 params : Vec < v3:: ParameterValue > ,
99104 ) -> Result < u64 , v3:: Error > {
100- self . get_client ( connection)
105+ Ok ( self
106+ . get_client ( connection)
101107 . await ?
102- . execute ( statement, params)
103- . await
108+ . execute ( statement, v3_params_to_v4 ( params) )
109+ . await ? )
104110 }
105111
106112 #[ instrument( name = "spin_outbound_pg.query" , skip( self , connection, params) , err( level = Level :: INFO ) , fields( otel. kind = "client" , db. system = "postgresql" , otel. name = statement) ) ]
@@ -110,13 +116,64 @@ impl<C: Send + Sync + Client> spin_world::spin::postgres::postgres::HostConnecti
110116 statement : String ,
111117 params : Vec < v3:: ParameterValue > ,
112118 ) -> Result < v3:: RowSet , v3:: Error > {
119+ Ok ( self
120+ . get_client ( connection)
121+ . await ?
122+ . query ( statement, v3_params_to_v4 ( params) )
123+ . await ?
124+ . into ( ) )
125+ }
126+
127+ async fn drop ( & mut self , connection : Resource < v3:: Connection > ) -> anyhow:: Result < ( ) > {
128+ self . connections . remove ( connection. rep ( ) ) ;
129+ Ok ( ( ) )
130+ }
131+ }
132+
133+ impl < C : Send + Sync + Client > v4:: HostConnection for InstanceState < C > {
134+ #[ instrument( name = "spin_outbound_pg.open" , skip( self , address) , err( level = Level :: INFO ) , fields( otel. kind = "client" , db. system = "postgresql" , db. address = Empty , server. port = Empty , db. namespace = Empty ) ) ]
135+ async fn open ( & mut self , address : String ) -> Result < Resource < v4:: Connection > , v4:: Error > {
136+ spin_factor_outbound_networking:: record_address_fields ( & address) ;
137+
138+ if !self
139+ . is_address_allowed ( & address)
140+ . await
141+ . map_err ( |e| v4:: Error :: Other ( e. to_string ( ) ) ) ?
142+ {
143+ return Err ( v4:: Error :: ConnectionFailed ( format ! (
144+ "address {address} is not permitted"
145+ ) ) ) ;
146+ }
147+ self . open_connection ( & address) . await
148+ }
149+
150+ #[ instrument( name = "spin_outbound_pg.execute" , skip( self , connection, params) , err( level = Level :: INFO ) , fields( otel. kind = "client" , db. system = "postgresql" , otel. name = statement) ) ]
151+ async fn execute (
152+ & mut self ,
153+ connection : Resource < v4:: Connection > ,
154+ statement : String ,
155+ params : Vec < v4:: ParameterValue > ,
156+ ) -> Result < u64 , v4:: Error > {
157+ self . get_client ( connection)
158+ . await ?
159+ . execute ( statement, params)
160+ . await
161+ }
162+
163+ #[ instrument( name = "spin_outbound_pg.query" , skip( self , connection, params) , err( level = Level :: INFO ) , fields( otel. kind = "client" , db. system = "postgresql" , otel. name = statement) ) ]
164+ async fn query (
165+ & mut self ,
166+ connection : Resource < v4:: Connection > ,
167+ statement : String ,
168+ params : Vec < v4:: ParameterValue > ,
169+ ) -> Result < v4:: RowSet , v4:: Error > {
113170 self . get_client ( connection)
114171 . await ?
115172 . query ( statement, params)
116173 . await
117174 }
118175
119- async fn drop ( & mut self , connection : Resource < v3 :: Connection > ) -> anyhow:: Result < ( ) > {
176+ async fn drop ( & mut self , connection : Resource < v4 :: Connection > ) -> anyhow:: Result < ( ) > {
120177 self . connections . remove ( connection. rep ( ) ) ;
121178 Ok ( ( ) )
122179 }
@@ -134,10 +191,16 @@ impl<C: Send + Sync + Client> v3::Host for InstanceState<C> {
134191 }
135192}
136193
194+ impl < C : Send + Sync + Client > v4:: Host for InstanceState < C > {
195+ fn convert_error ( & mut self , error : v4:: Error ) -> Result < v4:: Error > {
196+ Ok ( error)
197+ }
198+ }
199+
137200/// Delegate a function call to the v3::HostConnection implementation
138201macro_rules! delegate {
139202 ( $self: ident. $name: ident( $address: expr, $( $arg: expr) ,* ) ) => { {
140- if !$self. is_address_allowed( & $address) . await . map_err( |e| v3 :: Error :: Other ( e. to_string( ) ) ) ? {
203+ if !$self. is_address_allowed( & $address) . await . map_err( |e| v4 :: Error :: Other ( e. to_string( ) ) ) ? {
141204 return Err ( v1:: PgError :: ConnectionFailed ( format!(
142205 "address {} is not permitted" , $address
143206 ) ) ) ;
@@ -146,7 +209,7 @@ macro_rules! delegate {
146209 Ok ( c) => c,
147210 Err ( e) => return Err ( e. into( ) ) ,
148211 } ;
149- <Self as v3 :: HostConnection >:: $name( $self, connection, $( $arg) ,* )
212+ <Self as v4 :: HostConnection >:: $name( $self, connection, $( $arg) ,* )
150213 . await
151214 . map_err( |e| e. into( ) )
152215 } } ;
0 commit comments