1use cdbc::arguments::Arguments;
2use cdbc::encode::Encode;
3use crate::database::Mssql;
4use crate::io::MssqlBufMutExt;
5use crate::protocol::rpc::StatusFlags;
6use cdbc::types::Type;
7
8#[derive(Default)]
9pub struct MssqlArguments {
10 pub ordinal: usize,
12 name: String,
14 pub data: Vec<u8>,
15 pub declarations: String,
16}
17
18impl MssqlArguments {
19 pub fn add_named<'q, T: Encode<'q, Mssql> + Type<Mssql>>(
20 &mut self,
21 name: &str,
22 value: T,
23 ) {
24 let ty = value.produces().unwrap_or_else(T::type_info);
25
26 let mut ty_name = String::new();
27 ty.0.fmt(&mut ty_name);
28
29 self.data.put_b_varchar(name); self.data.push(0); ty.0.put(&mut self.data); ty.0.put_value(&mut self.data, value); }
35
36 pub fn add_unnamed<'q, T: Encode<'q, Mssql> + Type<Mssql>>(&mut self, value: T) {
37 self.add_named("", value);
38 }
39
40 pub fn declare<'q, T: Encode<'q, Mssql> + Type<Mssql>>(
41 &mut self,
42 name: &str,
43 initial_value: T,
44 ) {
45 let ty = initial_value.produces().unwrap_or_else(T::type_info);
46
47 let mut ty_name = String::new();
48 ty.0.fmt(&mut ty_name);
49
50 self.data.put_b_varchar(name); self.data.push(StatusFlags::BY_REF_VALUE.bits()); ty.0.put(&mut self.data); ty.0.put_value(&mut self.data, initial_value); }
56
57 pub fn append(&mut self, arguments: &mut MssqlArguments) {
58 self.ordinal += arguments.ordinal;
59 self.data.append(&mut arguments.data);
60 }
61
62 pub fn add<'q, T>(&mut self, value: T)
63 where
64 T: Encode<'q, Mssql> + Type<Mssql>,
65 {
66 let ty = value.produces().unwrap_or_else(T::type_info);
67
68 self.name.clear();
72 self.name.push_str("@p");
73
74 self.ordinal += 1;
75 self.name.push_str(itoa::Buffer::new().format(self.ordinal));
76
77 let MssqlArguments {
78 ref name,
79 ref mut declarations,
80 ref mut data,
81 ..
82 } = self;
83
84 if !declarations.is_empty() {
88 declarations.push_str(",");
89 }
90
91 declarations.push_str(name);
92 declarations.push(' ');
93 ty.0.fmt(declarations);
94
95 data.put_b_varchar(name); data.push(0); ty.0.put(data); ty.0.put_value(data, value); }
103}
104
105impl<'q> Arguments<'q> for MssqlArguments {
106 type Database = Mssql;
107
108 fn reserve(&mut self, _additional: usize, size: usize) {
109 self.data.reserve(size + 10); }
111
112 fn add<T>(&mut self, value: T)
113 where
114 T: 'q + Encode<'q, Self::Database> + Type<Mssql>,
115 {
116 self.add(value)
117 }
118}