6
6
mod explain;
7
7
pub use explain:: explain;
8
8
9
+ use ndc_postgres_configuration:: version5:: DynamicConnectionSettings ;
10
+ use ndc_postgres_configuration:: ConnectionSettings ;
9
11
use tracing:: { info_span, Instrument } ;
10
12
11
13
use ndc_sdk:: connector;
@@ -38,6 +40,9 @@ pub async fn query(
38
40
query_request = ?query_request
39
41
) ;
40
42
43
+ let connection_details =
44
+ extract_connection_details_from_query ( configuration, & query_request) . await ?;
45
+
41
46
let plan = async {
42
47
plan_query ( configuration, state, query_request) . map_err ( |err| {
43
48
record:: translation_error ( & err, & state. query_metrics ) ;
@@ -48,10 +53,12 @@ pub async fn query(
48
53
. await ?;
49
54
50
55
let result = async {
51
- execute_query ( state, plan) . await . map_err ( |err| {
52
- record:: execution_error ( & err, & state. query_metrics ) ;
53
- convert:: execution_error_to_response ( err)
54
- } )
56
+ execute_query ( state, plan, connection_details)
57
+ . await
58
+ . map_err ( |err| {
59
+ record:: execution_error ( & err, & state. query_metrics ) ;
60
+ convert:: execution_error_to_response ( err)
61
+ } )
55
62
}
56
63
. instrument ( info_span ! ( "Execute query" ) )
57
64
. await ?;
@@ -65,6 +72,44 @@ pub async fn query(
65
72
timer. complete_with ( result)
66
73
}
67
74
75
+ // if this is a dynamic connection situation, which connection string should we be using?
76
+ pub struct RequestConnectionDetails {
77
+ pool : PgPool
78
+ }
79
+
80
+ async fn extract_connection_details_from_query (
81
+ configuration : & configuration:: Configuration ,
82
+ query_request : & models:: QueryRequest ,
83
+ ) -> Result < Option < RequestConnectionDetails > , translation:: error:: Error > {
84
+ // check in config if we need to look in request arguments
85
+ match & configuration. connection {
86
+ ConnectionSettings :: Static { .. } => Ok ( None ) ,
87
+ ConnectionSettings :: Dynamic {
88
+ dynamic_connection_settings : DynamicConnectionSettings :: NamedFromList ,
89
+ } => {
90
+ let connection_identifier = & query_request
91
+ . request_arguments
92
+ . as_ref ( )
93
+ . and_then ( |request_arguments| request_arguments. get ( "connection_identifier" ) )
94
+ . ok_or_else ( || translation:: error:: Error :: MissingConnectionIdentifier ) ?;
95
+
96
+ // lookup uri
97
+ let connection_uri = "" ;
98
+
99
+ let pool = create_pool ( connection_uri, environment, pool_settings)
100
+ . instrument ( info_span ! (
101
+ "Create connection pool" ,
102
+ internal. visibility = "user" ,
103
+ ) )
104
+ . await ?;
105
+
106
+ Ok ( Some ( RequestConnectionDetails {
107
+ pool
108
+ } ) )
109
+ }
110
+ }
111
+ }
112
+
68
113
fn plan_query (
69
114
configuration : & configuration:: Configuration ,
70
115
state : & state:: State ,
@@ -79,15 +124,18 @@ fn plan_query(
79
124
async fn execute_query (
80
125
state : & state:: State ,
81
126
plan : sql:: execution_plan:: ExecutionPlan < sql:: execution_plan:: Query > ,
127
+ connection_details : Option < RequestConnectionDetails > ,
82
128
) -> Result < JsonResponse < models:: QueryResponse > , query_engine_execution:: error:: Error > {
83
- let state:: Pool :: Static {
84
- pool,
85
- database_info,
86
- } = & state. pool
87
- else {
88
- todo ! ( "Dynamic connect for execute_query" ) ;
89
- } ;
90
-
129
+ match ( & state. pool , connection_details) {
130
+ (
131
+ state:: Pool :: Static {
132
+ pool,
133
+ database_info,
134
+ } ,
135
+ _,
136
+ ) => ( & pool, Some ( database_info) )
137
+ ( state:: Pool :: Dynamic ( _) , Some ( RequestConnectionDetails { pool } ) ) => ( & pool, None ) ,
138
+ }
91
139
query_engine_execution:: query:: execute ( pool, database_info, & state. query_metrics , plan)
92
140
. await
93
141
. map ( JsonResponse :: Serialized )
0 commit comments