use std::sync::Arc;
#[derive(Clone, Debug, PartialEq)]
pub struct ResultSetMetadata {
pub(crate) column_names: Arc<Vec<String>>,
pub(crate) column_types: Arc<Vec<crate::types::Type>>,
pub(crate) undeclared_parameters: Arc<std::collections::BTreeMap<String, crate::types::Type>>,
}
impl ResultSetMetadata {
pub(crate) fn new(metadata: Option<crate::google::spanner::v1::ResultSetMetadata>) -> Self {
let mut column_names = Vec::new();
let mut column_types = Vec::new();
let mut undeclared_parameters = std::collections::BTreeMap::new();
if let Some(m) = &metadata
&& let Some(undeclared) = &m.undeclared_parameters
{
for field in &undeclared.fields {
let param_type = field.r#type.clone().map(Into::into).unwrap_or_default();
undeclared_parameters.insert(field.name.clone(), param_type);
}
}
let fields = metadata
.and_then(|m| m.row_type)
.into_iter()
.flat_map(|r| r.fields.into_iter());
for field in fields {
column_names.push(field.name);
let column_type = field.r#type.map(Into::into).unwrap_or_default();
column_types.push(column_type);
}
Self {
column_names: Arc::new(column_names),
column_types: Arc::new(column_types),
undeclared_parameters: Arc::new(undeclared_parameters),
}
}
pub fn column_names(&self) -> &[String] {
&self.column_names
}
pub fn column_types(&self) -> &[crate::types::Type] {
&self.column_types
}
pub fn undeclared_parameters(&self) -> &std::collections::BTreeMap<String, crate::types::Type> {
&self.undeclared_parameters
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn auto_traits() {
static_assertions::assert_impl_all!(
ResultSetMetadata: Clone,
std::fmt::Debug,
PartialEq,
Send,
Sync
);
}
#[test]
fn new_and_accessors() {
use crate::google::spanner::v1 as spanner_v1;
let proto = spanner_v1::ResultSetMetadata {
row_type: Some(spanner_v1::StructType {
fields: vec![
spanner_v1::struct_type::Field {
name: "col1".to_string(),
r#type: Some(spanner_v1::Type {
code: spanner_v1::TypeCode::String.into(),
..Default::default()
}),
},
spanner_v1::struct_type::Field {
name: "col2".to_string(),
r#type: Some(spanner_v1::Type {
code: spanner_v1::TypeCode::Int64.into(),
..Default::default()
}),
},
],
}),
..Default::default()
};
let metadata = ResultSetMetadata::new(Some(proto));
assert_eq!(
metadata.column_names(),
&["col1".to_string(), "col2".to_string()]
);
assert_eq!(metadata.column_types().len(), 2);
assert_eq!(
metadata.column_types()[0].code(),
crate::types::TypeCode::String
);
assert_eq!(
metadata.column_types()[1].code(),
crate::types::TypeCode::Int64
);
}
}