1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use {HdbError, HdbResult};
use protocol::parts::hdb_value::HdbValue;
use protocol::parts::parameter_descriptor::ParameterDescriptor;
use serde;
use serde_db::de::DbValue;
use std::fmt;
use std::mem;
#[derive(Clone, Debug)]
pub struct OutputParameters {
metadata: Vec<ParameterDescriptor>,
values: Vec<HdbValue>,
}
impl OutputParameters {
pub fn parameter_into<'de, T>(&mut self, i: usize) -> HdbResult<T>
where
T: serde::de::Deserialize<'de>,
{
trace!("OutputParameters::parameter_into()");
let mut tmp = HdbValue::NOTHING;
mem::swap(&mut self.values[i], &mut tmp);
Ok(DbValue::into_typed(tmp)?)
}
pub fn parameter_descriptor(&self, i: usize) -> HdbResult<&ParameterDescriptor> {
trace!("OutputParameters::parameter_descriptor()");
self.metadata
.get(i)
.ok_or_else(|| HdbError::usage_("wrong index: no such parameter"))
}
}
impl fmt::Display for OutputParameters {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
writeln!(fmt)?;
for parameter_descriptor in &self.metadata {
write!(
fmt,
"{}, ",
parameter_descriptor.name().unwrap_or(&String::new())
)?;
}
writeln!(fmt)?;
for value in &self.values {
write!(fmt, "{}, ", &value)?;
}
writeln!(fmt)?;
Ok(())
}
}
pub mod factory {
use super::OutputParameters;
use conn_core::AmConnCore;
use protocol::parts::hdb_value::factory as HdbValueFactory;
use protocol::parts::hdb_value::HdbValue;
use protocol::parts::parameter_descriptor::{
ParameterBinding, ParameterDescriptor, ParameterDirection,
};
use {HdbError, HdbResult};
use std::io;
pub fn parse(
o_am_conn_core: Option<&AmConnCore>,
par_md: &[ParameterDescriptor],
rdr: &mut io::BufRead,
) -> HdbResult<OutputParameters> {
trace!("OutputParameters::parse()");
let am_conn_core = o_am_conn_core
.ok_or_else(|| HdbError::impl_("Cannot parse output parameters without am_conn_core"))?;
let mut output_pars = OutputParameters {
metadata: Vec::<ParameterDescriptor>::new(),
values: Vec::<HdbValue>::new(),
};
for descriptor in par_md {
match descriptor.direction() {
ParameterDirection::INOUT | ParameterDirection::OUT => {
let typecode = descriptor.type_id();
let nullable = match descriptor.binding() {
ParameterBinding::Optional => true,
_ => false,
};
trace!(
"Parsing value with typecode {}, nullable {}",
typecode,
nullable
);
let value =
HdbValueFactory::parse_from_reply(typecode, nullable, am_conn_core, rdr)?;
trace!("Found value {:?}", value);
output_pars.metadata.push(descriptor.clone());
output_pars.values.push(value);
}
_ => {}
}
}
Ok(output_pars)
}
}