Run `sql` on `client` and return every row's columns as a `HashMap` keyed by column name. Used for `SELECT *` over TVFs that expand into multiple pgwire fields (one per array dimension/attribute).
(
client: &tokio_postgres::Client,
sql: &str,
)
| 41 | /// keyed by column name. Used for `SELECT *` over TVFs that expand into |
| 42 | /// multiple pgwire fields (one per array dimension/attribute). |
| 43 | async fn query_named_rows( |
| 44 | client: &tokio_postgres::Client, |
| 45 | sql: &str, |
| 46 | ) -> Vec<std::collections::HashMap<String, String>> { |
| 47 | let msgs = client.simple_query(sql).await.unwrap_or_else(|e| { |
| 48 | let detail = if let Some(db) = e.as_db_error() { |
| 49 | format!( |
| 50 | "SQLSTATE={} severity={} msg={}", |
| 51 | db.code().code(), |
| 52 | db.severity(), |
| 53 | db.message() |
| 54 | ) |
| 55 | } else { |
| 56 | format!("{e:?}") |
| 57 | }; |
| 58 | panic!("query failed: {detail}\n sql: {sql}") |
| 59 | }); |
| 60 | msgs.into_iter() |
| 61 | .filter_map(|m| { |
| 62 | if let tokio_postgres::SimpleQueryMessage::Row(r) = m { |
| 63 | let names: Vec<String> = r.columns().iter().map(|c| c.name().to_string()).collect(); |
| 64 | let mut map = std::collections::HashMap::with_capacity(names.len()); |
| 65 | for (i, name) in names.into_iter().enumerate() { |
| 66 | map.insert(name, r.get(i).unwrap_or("").to_string()); |
| 67 | } |
| 68 | Some(map) |
| 69 | } else { |
| 70 | None |
| 71 | } |
| 72 | }) |
| 73 | .collect() |
| 74 | } |
| 75 | |
| 76 | /// Spin up a 3-node cluster with a pre-populated genome array. |
| 77 | /// |
no test coverage detected