db_derive/
query.rs

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}