(
&self,
auth: AuthCtx,
_database: Database,
confirmed_read: bool,
body: String,
)
| 135 | } |
| 136 | |
| 137 | pub async fn exec_sql( |
| 138 | &self, |
| 139 | auth: AuthCtx, |
| 140 | _database: Database, |
| 141 | confirmed_read: bool, |
| 142 | body: String, |
| 143 | ) -> axum::response::Result<Vec<SqlStmtResult<ProductValue>>> { |
| 144 | let module_host = self |
| 145 | .module() |
| 146 | .await |
| 147 | .map_err(|_| (StatusCode::NOT_FOUND, "module not found".to_string()))?; |
| 148 | |
| 149 | tracing::info!(sql = body); |
| 150 | let mut header = vec![]; |
| 151 | let sql_start = std::time::Instant::now(); |
| 152 | let sql_span = tracing::trace_span!("execute_sql", total_duration = tracing::field::Empty,); |
| 153 | let _guard = sql_span.enter(); |
| 154 | let db = module_host.relational_db().clone(); |
| 155 | let durable_offset = db.durable_tx_offset(); |
| 156 | |
| 157 | let result = sql::execute::run( |
| 158 | db, |
| 159 | body, |
| 160 | auth, |
| 161 | Some(module_host.info.subscriptions.clone()), |
| 162 | Some(module_host), |
| 163 | &mut header, |
| 164 | ) |
| 165 | .await |
| 166 | .map_err(|e| { |
| 167 | log::warn!("{e}"); |
| 168 | (StatusCode::BAD_REQUEST, e.to_string()) |
| 169 | })?; |
| 170 | |
| 171 | let total_duration = sql_start.elapsed(); |
| 172 | drop(_guard); |
| 173 | sql_span.record("total_duration", tracing::field::debug(total_duration)); |
| 174 | |
| 175 | let schema = header |
| 176 | .into_iter() |
| 177 | .map(|(col_name, col_type)| ProductTypeElement::new(col_type, Some(col_name))) |
| 178 | .collect(); |
| 179 | |
| 180 | let tx_offset = result.tx_offset; |
| 181 | let json = vec![SqlStmtResult { |
| 182 | schema, |
| 183 | rows: result.rows, |
| 184 | total_duration_micros: total_duration.as_micros() as u64, |
| 185 | stats: SqlStmtStats::from_metrics(&result.metrics), |
| 186 | }]; |
| 187 | |
| 188 | if confirmed_read && let Some(mut durable_offset) = durable_offset { |
| 189 | let tx_offset = tx_offset.await.map_err(|_| log_and_500("transaction aborted"))?; |
| 190 | durable_offset.wait_for(tx_offset).await.map_err(log_and_500)?; |
| 191 | } |
| 192 | |
| 193 | Ok(json) |
| 194 | } |
no test coverage detected