google_cloud_spanner/
result_set_metadata.rs1use std::sync::Arc;
16
17#[derive(Clone, Debug, PartialEq)]
40pub struct ResultSetMetadata {
41 pub(crate) column_names: Arc<Vec<String>>,
42 pub(crate) column_types: Arc<Vec<crate::types::Type>>,
43 pub(crate) undeclared_parameters: Arc<std::collections::BTreeMap<String, crate::types::Type>>,
44}
45
46impl ResultSetMetadata {
47 pub(crate) fn new(metadata: Option<crate::google::spanner::v1::ResultSetMetadata>) -> Self {
48 let mut column_names = Vec::new();
49 let mut column_types = Vec::new();
50 let mut undeclared_parameters = std::collections::BTreeMap::new();
51
52 if let Some(m) = &metadata
53 && let Some(undeclared) = &m.undeclared_parameters
54 {
55 for field in &undeclared.fields {
56 let param_type = field.r#type.clone().map(Into::into).unwrap_or_default();
57 undeclared_parameters.insert(field.name.clone(), param_type);
58 }
59 }
60
61 let fields = metadata
62 .and_then(|m| m.row_type)
63 .into_iter()
64 .flat_map(|r| r.fields.into_iter());
65 for field in fields {
66 column_names.push(field.name);
67 let column_type = field.r#type.map(Into::into).unwrap_or_default();
68 column_types.push(column_type);
69 }
70
71 Self {
72 column_names: Arc::new(column_names),
73 column_types: Arc::new(column_types),
74 undeclared_parameters: Arc::new(undeclared_parameters),
75 }
76 }
77
78 pub fn column_names(&self) -> &[String] {
80 &self.column_names
81 }
82
83 pub fn column_types(&self) -> &[crate::types::Type] {
85 &self.column_types
86 }
87 pub fn undeclared_parameters(&self) -> &std::collections::BTreeMap<String, crate::types::Type> {
89 &self.undeclared_parameters
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96
97 #[test]
98 fn auto_traits() {
99 static_assertions::assert_impl_all!(
100 ResultSetMetadata: Clone,
101 std::fmt::Debug,
102 PartialEq,
103 Send,
104 Sync
105 );
106 }
107
108 #[test]
109 fn new_and_accessors() {
110 use crate::google::spanner::v1 as spanner_v1;
111
112 let proto = spanner_v1::ResultSetMetadata {
113 row_type: Some(spanner_v1::StructType {
114 fields: vec![
115 spanner_v1::struct_type::Field {
116 name: "col1".to_string(),
117 r#type: Some(spanner_v1::Type {
118 code: spanner_v1::TypeCode::String.into(),
119 ..Default::default()
120 }),
121 },
122 spanner_v1::struct_type::Field {
123 name: "col2".to_string(),
124 r#type: Some(spanner_v1::Type {
125 code: spanner_v1::TypeCode::Int64.into(),
126 ..Default::default()
127 }),
128 },
129 ],
130 }),
131 ..Default::default()
132 };
133
134 let metadata = ResultSetMetadata::new(Some(proto));
135
136 assert_eq!(
137 metadata.column_names(),
138 &["col1".to_string(), "col2".to_string()]
139 );
140 assert_eq!(metadata.column_types().len(), 2);
141 assert_eq!(
142 metadata.column_types()[0].code(),
143 crate::types::TypeCode::String
144 );
145 assert_eq!(
146 metadata.column_types()[1].code(),
147 crate::types::TypeCode::Int64
148 );
149 }
150}