1use crate::{AsValue, QueryResult, Value, ValueOwned};
2use std::{
3 borrow::Cow,
4 fmt::{self, Debug, Formatter},
5 iter,
6 sync::Arc,
7 vec,
8};
9
10#[derive(Default, Clone, Copy, Debug)]
12pub struct RowsAffected {
13 pub rows_affected: Option<u64>,
15 pub last_affected_id: Option<i64>,
17}
18
19impl Extend<RowsAffected> for RowsAffected {
20 fn extend<T: IntoIterator<Item = RowsAffected>>(&mut self, iter: T) {
21 for elem in iter {
22 if self.rows_affected.is_some() || elem.rows_affected.is_some() {
23 self.rows_affected = Some(
24 self.rows_affected.unwrap_or_default() + elem.rows_affected.unwrap_or_default(),
25 );
26 }
27 if elem.last_affected_id.is_some() {
28 self.last_affected_id = elem.last_affected_id;
29 }
30 }
31 }
32}
33
34pub type RowLabels = Arc<[String]>;
36pub type RowValues = Vec<ValueOwned>;
38
39pub trait Row: Debug + Send + Sync {
41 fn labels(&self) -> &[String];
43
44 fn len(&self) -> usize;
46
47 fn value(&self, index: usize) -> Option<Cow<'_, Value<'_>>>;
50
51 fn is_empty(&self) -> bool {
52 self.len() == 0
53 }
54
55 fn get_column(&self, name: &str) -> Option<Cow<'_, Value<'_>>> {
56 self.labels()
57 .iter()
58 .position(|label| label == name)
59 .and_then(|index| self.value(index))
60 }
61
62 fn values(&self) -> impl Iterator<Item = Cow<'_, Value<'_>>> {
64 (0..self.len()).map_while(|index| self.value(index))
65 }
66
67 fn iter(&self) -> impl Iterator<Item = (&str, Cow<'_, Value<'_>>)> {
68 iter::zip(self.labels().iter().map(String::as_str), self.values())
69 }
70
71 fn into_values(self) -> impl Iterator<Item = ValueOwned>
73 where
74 Self: Sized,
75 {
76 let row = self;
77 let mut index = 0;
78 iter::from_fn(move || {
79 let value = row.value(index)?.as_value().into_owned();
80 index += 1;
81 Some(value)
82 })
83 }
84}
85
86impl<R: Row + ?Sized> Row for &R {
87 #[inline(always)]
88 fn labels(&self) -> &[String] {
89 (**self).labels()
90 }
91
92 #[inline(always)]
93 fn len(&self) -> usize {
94 (**self).len()
95 }
96
97 #[inline(always)]
98 fn value(&self, index: usize) -> Option<Cow<'_, Value<'_>>> {
99 (**self).value(index)
100 }
101
102 #[inline(always)]
103 fn is_empty(&self) -> bool {
104 (**self).is_empty()
105 }
106
107 #[inline(always)]
108 fn get_column(&self, name: &str) -> Option<Cow<'_, Value<'_>>> {
109 (**self).get_column(name)
110 }
111
112 #[inline(always)]
113 fn values(&self) -> impl Iterator<Item = Cow<'_, Value<'_>>> {
114 (**self).values()
115 }
116
117 #[inline(always)]
118 fn iter(&self) -> impl Iterator<Item = (&str, Cow<'_, Value<'_>>)> {
119 (**self).iter()
120 }
121}
122
123#[derive(Clone, Default)]
125pub struct RowOwned {
126 pub labels: RowLabels,
127 pub values: RowValues,
128}
129
130impl RowOwned {
131 pub fn new(labels: RowLabels, values: RowValues) -> Self {
132 Self {
133 labels,
134 values: values.into(),
135 }
136 }
137}
138
139impl Debug for RowOwned {
140 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
141 f.debug_struct("RowOwned")
142 .field("labels", &self.labels)
143 .field("len", &self.values.len())
144 .finish()
145 }
146}
147
148impl IntoIterator for RowOwned {
149 type Item = ValueOwned;
150 type IntoIter = vec::IntoIter<ValueOwned>;
151
152 #[inline(always)]
153 fn into_iter(self) -> Self::IntoIter {
154 self.values.into_iter()
155 }
156}
157
158impl Row for RowOwned {
159 #[inline(always)]
160 fn labels(&self) -> &[String] {
161 &self.labels
162 }
163
164 #[inline(always)]
165 fn len(&self) -> usize {
166 self.values.len()
167 }
168
169 #[inline(always)]
170 fn value(&self, index: usize) -> Option<Cow<'_, Value<'_>>> {
171 self.values.get(index).map(Cow::Borrowed)
172 }
173
174 fn into_values(self) -> impl Iterator<Item = ValueOwned> {
175 self.values.into_iter()
176 }
177}
178
179impl<R: Row> From<R> for QueryResult<R> {
180 fn from(value: R) -> Self {
181 QueryResult::Row(value)
182 }
183}
184
185impl<R> From<RowsAffected> for QueryResult<R> {
186 fn from(value: RowsAffected) -> Self {
187 QueryResult::Affected(value)
188 }
189}