1use std::{fmt::Debug, sync::Arc};
2
3use serde_json::Value;
4use sqlx_core::{column::ColumnIndex, database::Database, ext::ustr::UStr, row::Row, HashMap};
5
6use crate::{column::ExaColumn, database::Exasol, value::ExaValueRef, SqlxError, SqlxResult};
7
8#[derive(Debug)]
10pub struct ExaRow {
11 pub(crate) column_names: Arc<HashMap<UStr, usize>>,
12 columns: Arc<[ExaColumn]>,
13 data: Vec<Value>,
14}
15
16impl ExaRow {
17 #[must_use]
18 pub fn new(
19 data: Vec<Value>,
20 columns: Arc<[ExaColumn]>,
21 column_names: Arc<HashMap<UStr, usize>>,
22 ) -> Self {
23 Self {
24 column_names,
25 columns,
26 data,
27 }
28 }
29}
30
31impl Row for ExaRow {
32 type Database = Exasol;
33
34 fn columns(&self) -> &[<Self::Database as Database>::Column] {
35 &self.columns
36 }
37
38 fn try_get_raw<I>(&self, index: I) -> SqlxResult<<Self::Database as Database>::ValueRef<'_>>
39 where
40 I: ColumnIndex<Self>,
41 {
42 let col_idx = index.index(self)?;
43 let err_fn = || SqlxError::ColumnIndexOutOfBounds {
44 index: col_idx,
45 len: self.columns.len(),
46 };
47
48 let value = self.data.get(col_idx).ok_or_else(err_fn)?;
49 let type_info = &self.columns.get(col_idx).ok_or_else(err_fn)?.data_type;
50 let val = ExaValueRef { value, type_info };
51
52 Ok(val)
53 }
54}
55
56impl ColumnIndex<ExaRow> for &'_ str {
57 fn index(&self, container: &ExaRow) -> SqlxResult<usize> {
58 container
59 .column_names
60 .get(*self)
61 .copied()
62 .ok_or_else(|| SqlxError::ColumnNotFound((*self).to_string()))
63 }
64}