1use {
2 crate::{sql::Sql, table::Table, ConnTrans, Connection, Error, Row, Transaction},
3 std::convert::TryInto,
4};
5
6pub trait Query<'__query>: Sql<'__query> {
7 fn query_row<C: TryInto<ConnTrans<'__query>>, T: Table>(
8 &'__query self,
9 into_conn_trans: C,
10 ) -> Result<T, Error>
11 where
12 Error: From<C::Error>,
13 {
14 let conn_trans = into_conn_trans.try_into()?;
15
16 match conn_trans {
17 ConnTrans::Conn(conn) => match conn {
18 #[cfg(feature = "postgresql")]
19 Connection::PostgreSQL(mut conn) => {
20 let rows = conn.query(
21 self.sql_postgres().as_ref(),
22 self.params_postgres().as_ref(),
23 )?;
24
25 if rows.is_empty() {
26 return Err(Error::QueryReturnedNoRows);
27 }
28
29 let row = rows.into_iter().next().unwrap();
30
31 if row.columns().len() != T::columns() {
32 return Err(Error::MismatchedColumnCount);
33 }
34
35 let typ = T::from_row(Row::PostgreSQL(row))?;
36
37 Ok(typ)
38 }
39 #[cfg(feature = "sqlite")]
40 Connection::SQLite(conn) => {
41 let mut stmt = conn.prepare(self.sql_sqlite().as_ref())?;
42
43 let mut rows = stmt.query(self.params_sqlite().as_ref())?;
44
45 let next = rows.next()?;
46
47 if next.is_none() {
48 return Err(Error::QueryReturnedNoRows);
49 }
50
51 let row = next.unwrap();
52
53 if row.column_count() != T::columns() {
54 return Err(Error::MismatchedColumnCount);
55 }
56
57 let typ = T::from_row(Row::SQLite(row))?;
58
59 Ok(typ)
60 }
61 },
62 ConnTrans::Trans(trans) => match trans {
63 #[cfg(feature = "postgresql")]
64 Transaction::PostgreSQL(mut trans) => {
65 let rows = trans.query(
66 self.sql_postgres().as_ref(),
67 self.params_postgres().as_ref(),
68 )?;
69
70 if rows.is_empty() {
71 return Err(Error::QueryReturnedNoRows);
72 }
73
74 let row = rows.into_iter().next().unwrap();
75
76 if row.columns().len() != T::columns() {
77 return Err(Error::MismatchedColumnCount);
78 }
79
80 let typ = T::from_row(Row::PostgreSQL(row))?;
81
82 Ok(typ)
83 }
84 #[cfg(feature = "sqlite")]
85 Transaction::SQLite(trans) => {
86 let mut stmt = trans.prepare(self.sql_sqlite().as_ref())?;
87
88 let mut rows = stmt.query(self.params_sqlite().as_ref())?;
89
90 let next = rows.next()?;
91
92 if next.is_none() {
93 return Err(Error::QueryReturnedNoRows);
94 }
95
96 let row = next.unwrap();
97
98 if row.column_count() != T::columns() {
99 return Err(Error::MismatchedColumnCount);
100 }
101
102 let typ = T::from_row(Row::SQLite(row))?;
103
104 Ok(typ)
105 }
106 },
107 }
108 }
109
110 fn query_rows<C: TryInto<ConnTrans<'__query>>, T: Table>(
111 &'__query self,
112 into_conn_trans: C,
113 ) -> Result<Vec<T>, Error>
114 where
115 Error: From<C::Error>,
116 {
117 let conn_trans = into_conn_trans.try_into()?;
118
119 match conn_trans {
120 ConnTrans::Conn(conn) => match conn {
121 #[cfg(feature = "postgresql")]
122 Connection::PostgreSQL(mut conn) => {
123 let rows = conn.query(
124 self.sql_postgres().as_ref(),
125 self.params_postgres().as_ref(),
126 )?;
127
128 let types = rows
129 .into_iter()
130 .map(|row| {
131 if row.columns().len() != T::columns() {
132 Err(Error::MismatchedColumnCount)
133 } else {
134 T::from_row(Row::PostgreSQL(row))
135 }
136 })
137 .collect::<Result<Vec<_>, Error>>()?;
138
139 Ok(types)
140 }
141 #[cfg(feature = "sqlite")]
142 Connection::SQLite(conn) => {
143 let mut stmt = conn.prepare(self.sql_sqlite().as_ref())?;
144
145 let mut rows = stmt.query(self.params_sqlite().as_ref())?;
146
147 let mut vec = Vec::new();
148
149 while let Some(row) = rows.next()? {
150 if row.column_count() != T::columns() {
151 return Err(Error::MismatchedColumnCount);
152 }
153
154 let typ = T::from_row(Row::SQLite(row))?;
155
156 vec.push(typ);
157 }
158
159 Ok(vec)
160 }
161 },
162 ConnTrans::Trans(trans) => match trans {
163 #[cfg(feature = "postgresql")]
164 Transaction::PostgreSQL(mut trans) => {
165 let rows = trans.query(
166 self.sql_postgres().as_ref(),
167 self.params_postgres().as_ref(),
168 )?;
169
170 let types = rows
171 .into_iter()
172 .map(|row| {
173 if row.columns().len() != T::columns() {
174 Err(Error::MismatchedColumnCount)
175 } else {
176 T::from_row(Row::PostgreSQL(row))
177 }
178 })
179 .collect::<Result<Vec<_>, Error>>()?;
180
181 Ok(types)
182 }
183 #[cfg(feature = "sqlite")]
184 Transaction::SQLite(trans) => {
185 let mut stmt = trans.prepare(self.sql_sqlite().as_ref())?;
186
187 let mut rows = stmt.query(self.params_sqlite().as_ref())?;
188
189 let mut vec = Vec::new();
190
191 while let Some(row) = rows.next()? {
192 if row.column_count() != T::columns() {
193 return Err(Error::MismatchedColumnCount);
194 }
195
196 let typ = T::from_row(Row::SQLite(row))?;
197
198 vec.push(typ);
199 }
200
201 Ok(vec)
202 }
203 },
204 }
205 }
206}