1use sofie_core::{ColumnReader, ColumnSpec, Result, SqlType, SqlValue};
2
3use crate::{Driver, RowSink};
4
5pub struct Decoding<T, F> {
6 expects: Vec<Option<SqlType>>,
7 decode: F,
8 decoded: Vec<T>,
9}
10
11impl<T, F> Decoding<T, F>
12where
13 T: Send,
14 F: FnMut(&mut dyn ColumnReader) -> Result<T> + Send,
15{
16 pub fn new(expects: Vec<Option<SqlType>>, decode: F) -> Self {
17 Self {
18 expects,
19 decode,
20 decoded: Vec::new(),
21 }
22 }
23
24 pub(crate) fn reserve(&mut self, rows: usize) {
25 self.decoded.reserve(rows);
26 }
27
28 pub fn into_decoded(self) -> Vec<T> {
29 self.decoded
30 }
31}
32
33impl<T, F> RowSink for Decoding<T, F>
34where
35 T: Send,
36 F: FnMut(&mut dyn ColumnReader) -> Result<T> + Send,
37{
38 fn expects(&self) -> &[Option<SqlType>] {
39 &self.expects
40 }
41
42 fn row(&mut self, row: &mut dyn ColumnReader) -> Result<()> {
43 self.decoded.push((self.decode)(row)?);
44 Ok(())
45 }
46}
47
48pub async fn query_decoded<T: Send>(
49 driver: &dyn Driver,
50 sql: &str,
51 params: &[SqlValue],
52 expects: Vec<Option<SqlType>>,
53 decode: impl FnMut(&mut dyn ColumnReader) -> Result<T> + Send,
54) -> Result<Vec<T>> {
55 let mut rows = Decoding::new(expects, decode);
56 driver.query(sql, params, &mut rows).await?;
57 Ok(rows.into_decoded())
58}
59
60pub async fn query_values(
62 driver: &dyn Driver,
63 sql: &str,
64 params: &[SqlValue],
65) -> Result<Vec<Vec<SqlValue>>> {
66 query_decoded(driver, sql, params, Vec::new(), row_values).await
67}
68
69pub fn row_values(row: &mut dyn ColumnReader) -> Result<Vec<SqlValue>> {
70 (0..row.remaining()).map(|_| row.value()).collect()
71}
72
73#[must_use]
74pub fn column_types(fields: &[&[ColumnSpec]]) -> Vec<Option<SqlType>> {
75 fields
76 .iter()
77 .flat_map(|columns| columns.iter().map(|column| Some(column.ty)))
78 .collect()
79}