Skip to main content

cartel_sqlite/engine/api/exec/
query.rs

1use crate::Cursor;
2use crate::{api, catalogs, row};
3use api::{batches, exec};
4use dope_fiber::abi;
5use std::result;
6
7pub struct Query<
8    'query,
9    'connection: 'query,
10    'd: 'connection,
11    I: catalogs::Catalog = catalogs::Empty,
12> {
13    start: exec::Start<'query, 'connection, 'd, I>,
14    arena: &'query mut batches::Arena<'connection>,
15}
16
17impl<'query, 'connection: 'query, 'd: 'connection, I: catalogs::Catalog>
18    Query<'query, 'connection, 'd, I>
19{
20    pub(crate) const fn new(
21        start: exec::Start<'query, 'connection, 'd, I>,
22        arena: &'query mut batches::Arena<'connection>,
23    ) -> Self {
24        Self { start, arena }
25    }
26
27    #[doc(hidden)]
28    pub fn run_no_rows<Q: catalogs::TypedQuery, P: api::Bind>(
29        self,
30        stmt: catalogs::Statement<I, Q>,
31        params: P,
32    ) -> impl abi::Fiber<'d, Output = result::Result<(), crate::Error>>
33    + use<'query, 'connection, 'd, I, Q, P>
34    where
35        I: catalogs::HasQuery<Q>,
36    {
37        exec::Command::new(self.start.run(stmt, params))
38    }
39
40    #[doc(hidden)]
41    pub fn run_one<R: row::raw::Decode + 'query, P: api::Bind, Q: catalogs::TypedQuery>(
42        self,
43        stmt: catalogs::Statement<I, Q>,
44        params: P,
45    ) -> impl abi::Fiber<'d, Output = result::Result<R::Borrowed<'query>, crate::Error>>
46    + use<'query, 'connection, 'd, I, R, P, Q>
47    where
48        I: catalogs::HasQuery<Q>,
49    {
50        let machine = self.start.run(stmt, params);
51        let create = exec::Single::<R, _>::new(self.arena, |value: Option<_>| {
52            value.ok_or(crate::Error::QueryReturnedNoRows)
53        });
54        exec::Rows::new(machine, create)
55    }
56
57    #[doc(hidden)]
58    pub fn run_first<R: row::raw::Decode + 'query, P: api::Bind, Q: catalogs::TypedQuery>(
59        self,
60        stmt: catalogs::Statement<I, Q>,
61        params: P,
62    ) -> impl abi::Fiber<'d, Output = result::Result<Option<R::Borrowed<'query>>, crate::Error>>
63    + use<'query, 'connection, 'd, I, R, P, Q>
64    where
65        I: catalogs::HasQuery<Q>,
66    {
67        let machine = self.start.run(stmt, params);
68        let create = exec::Single::<R, _>::new(self.arena, Ok);
69        exec::Rows::new(machine, create)
70    }
71
72    #[doc(hidden)]
73    pub fn run_all<R: row::raw::Decode + 'query, P: api::Bind, Q: catalogs::TypedQuery>(
74        self,
75        stmt: catalogs::Statement<I, Q>,
76        params: P,
77    ) -> impl abi::Fiber<'d, Output = result::Result<batches::Rows<'query, R>, crate::Error>>
78    + use<'query, 'connection, 'd, I, R, P, Q>
79    where
80        I: catalogs::HasQuery<Q>,
81    {
82        let machine = self.start.run(stmt, params);
83        exec::Rows::new(machine, exec::Collect::<R>::new(self.arena))
84    }
85
86    #[doc(hidden)]
87    pub fn stream<R: row::raw::Decode, P: api::Bind, Q: catalogs::TypedQuery>(
88        self,
89        stmt: catalogs::Statement<I, Q>,
90        params: P,
91    ) -> Cursor<'query, 'connection, 'd, R, Q, P, I>
92    where
93        I: catalogs::HasQuery<Q>,
94    {
95        Cursor::new(self.start.run(stmt, params))
96    }
97}