1use either::Either;
2use crate::arguments::IntoArguments;
3use crate::database::{Database, HasArguments, HasStatement, HasStatementCache};
4use crate::encode::Encode;
5use crate::error::Error;
6use crate::executor::{Execute, Executor};
7use crate::from_row::FromRow;
8use crate::io::chan_stream::ChanStream;
9use crate::query_as::{
10 query_as, query_as_with, query_statement_as, query_statement_as_with, QueryAs,
11};
12use crate::types::Type;
13
14#[must_use = "query must be executed to affect database"]
17pub struct QueryScalar<DB: Database, O, A> {
18 inner: QueryAs< DB, (O,), A>,
19}
20
21impl<'q, DB: Database, O: Send, A: Send> Execute<'q, DB> for QueryScalar< DB, O, A>
22where
23 A: 'q + IntoArguments<'q, DB>,
24{
25 #[inline]
26 fn sql(&self) -> &str {
27 self.inner.sql()
28 }
29
30 fn statement(&self) -> Option<&<DB as HasStatement>::Statement> {
31 self.inner.statement()
32 }
33
34 #[inline]
35 fn take_arguments(&mut self) -> Option<<DB as HasArguments<'q>>::Arguments> {
36 self.inner.take_arguments()
37 }
38
39 #[inline]
40 fn persistent(&self) -> bool {
41 self.inner.persistent()
42 }
43}
44
45impl<'q, DB: Database, O> QueryScalar< DB, O, <DB as HasArguments<'q>>::Arguments> {
46 pub fn bind<T: 'q + Send + Encode<'q, DB> + Type<DB>>(mut self, value: T) -> Self {
50 self.inner = self.inner.bind(value);
51 self
52 }
53}
54
55impl<'q, DB, O, A> QueryScalar< DB, O, A>
56where
57 DB: Database + HasStatementCache,
58{
59 pub fn persistent(mut self, value: bool) -> Self {
68 self.inner = self.inner.persistent(value);
69 self
70 }
71}
72
73impl<'q, DB, O, A> QueryScalar< DB, O, A>
76where
77 DB: Database,
78 O: Send,
79 A: 'q + IntoArguments<'q, DB>,
80 (O,): Send + for<'r> FromRow<'r, DB::Row>,
81{
82 #[inline]
84 pub fn fetch<'e, 'c: 'e, E>(self, executor: E) -> ChanStream<O>
85 where
86 'q: 'e,
87 E: 'e + Executor< Database = DB>,
88 DB: 'e,
89 A: 'e,
90 O: 'e,
91 {
92 self.inner.fetch(executor).map(|v|{
94 Some(v.0)
95 })
96 }
97
98 #[inline]
101 pub fn fetch_many<'e, 'c: 'e, E>(
102 self,
103 executor: E,
104 ) -> ChanStream<Either<DB::QueryResult, O>>
105 where
106 'q: 'e,
107 E: 'e + Executor< Database = DB>,
108 DB: 'e,
109 A: 'e,
110 O: 'e,
111 {
112 self.inner
113 .fetch_many(executor)
114 .map(|v| {
115 Some(v.map_right(|it| it.0))
116 })
117 }
118
119 #[inline]
121 pub fn fetch_all<'e, 'c: 'e, E>(self, executor: E) -> Result<Vec<O>, Error>
122 where
123 'q: 'e,
124 E: 'e + Executor< Database = DB>,
125 DB: 'e,
126 (O,): 'e,
127 A: 'e,
128 {
129 self.inner
130 .fetch(executor)
131 .map(|it| Some(it.0))
132 .collect(|v|{
133 Some(Ok(v))
134 })
135
136 }
137
138 #[inline]
140 pub fn fetch_one<'e, 'c: 'e, E>(self, executor: E) -> Result<O, Error>
141 where
142 'q: 'e,
143 E: 'e + Executor< Database = DB>,
144 DB: 'e,
145 O: 'e,
146 A: 'e,
147 {
148 self.inner.fetch_one(executor).map(|it| it.0)
149 }
150
151 #[inline]
153 pub fn fetch_optional<'e, 'c: 'e, E>(self, executor: E) -> Result<Option<O>, Error>
154 where
155 'q: 'e,
156 E: 'e + Executor< Database = DB>,
157 DB: 'e,
158 O: 'e,
159 A: 'e,
160 {
161 Ok(self.inner.fetch_optional(executor)?.map(|it| it.0))
162 }
163}
164
165#[inline]
168pub fn query_scalar<'q, DB, O>(
169 sql: &'q str,
170) -> QueryScalar< DB, O, <DB as HasArguments<'q>>::Arguments>
171where
172 DB: Database,
173 (O,): for<'r> FromRow<'r, DB::Row>,
174{
175 QueryScalar {
176 inner: query_as(sql),
177 }
178}
179
180#[inline]
183pub fn query_scalar_with<'q, DB, O, A>(sql: &'q str, arguments: A) -> QueryScalar< DB, O, A>
184where
185 DB: Database,
186 A: IntoArguments<'q, DB>,
187 (O,): for<'r> FromRow<'r, DB::Row>,
188{
189 QueryScalar {
190 inner: query_as_with(sql, arguments),
191 }
192}
193
194pub fn query_statement_scalar<'q, DB, O>(
196 statement: <DB as HasStatement>::Statement,
197) -> QueryScalar< DB, O, <DB as HasArguments<'q>>::Arguments>
198where
199 DB: Database,
200 (O,): for<'r> FromRow<'r, DB::Row>,
201{
202 QueryScalar {
203 inner: query_statement_as(statement),
204 }
205}
206
207pub fn query_statement_scalar_with<'q, DB, O, A>(
209 statement: <DB as HasStatement>::Statement,
210 arguments: A,
211) -> QueryScalar< DB, O, A>
212where
213 DB: Database,
214 A: IntoArguments<'q, DB>,
215 (O,): for<'r> FromRow<'r, DB::Row>,
216{
217 QueryScalar {
218 inner: query_statement_as_with(statement, arguments),
219 }
220}