1use std::{
2 cell::Cell,
3 marker::PhantomData,
4 ops::{Deref, DerefMut},
5};
6
7use sea_query::SqliteQueryBuilder;
8use sea_query_rusqlite::RusqliteBinder;
9
10use crate::{
11 dummy_impl::{Cacher, IntoSelect, Prepared, Row, SelectImpl},
12 rows::Rows,
13};
14
15pub struct Query<'outer, 'inner, S> {
17 pub(crate) phantom: PhantomData<&'inner &'outer ()>,
18 pub(crate) q: Rows<'inner, S>,
19 pub(crate) conn: &'inner rusqlite::Connection,
20}
21
22impl<'outer, 'inner, S> Deref for Query<'outer, 'inner, S> {
23 type Target = Rows<'inner, S>;
24
25 fn deref(&self) -> &Self::Target {
26 &self.q
27 }
28}
29
30impl<'outer, 'inner, S> DerefMut for Query<'outer, 'inner, S> {
31 fn deref_mut(&mut self) -> &mut Self::Target {
32 &mut self.q
33 }
34}
35
36impl<'outer, 'inner, S> Query<'outer, 'inner, S> {
37 pub fn into_vec<O>(&self, select: impl IntoSelect<'inner, 'outer, S, Out = O>) -> Vec<O> {
47 self.into_vec_private(select)
48 }
49
50 pub(crate) fn into_vec_private<'x, D>(&self, dummy: D) -> Vec<D::Out>
51 where
52 D: IntoSelect<'x, 'outer, S>,
53 {
54 let mut cacher = Cacher::new();
55 let mut prepared = dummy.into_select().inner.prepare(&mut cacher);
56
57 let cached = self.ast.cache(cacher.columns);
58
59 let select = self.ast.simple();
60 let (sql, values) = select.build_rusqlite(SqliteQueryBuilder);
61 if SHOW_SQL.get() {
62 println!("{sql}");
63 println!("{values:?}");
64 }
65
66 let mut statement = self.conn.prepare_cached(&sql).unwrap();
67 let mut rows = statement.query(&*values.as_params()).unwrap();
68
69 let mut out = vec![];
70 while let Some(row) = rows.next().unwrap() {
71 out.push(prepared.call(Row::new(row, &cached)));
72 }
73 out
74 }
75}
76
77thread_local! {
78 static SHOW_SQL: Cell<bool> = const { Cell::new(false) };
79}
80
81pub fn show_sql<R>(f: impl FnOnce() -> R) -> R {
82 let old = SHOW_SQL.get();
83 SHOW_SQL.set(true);
84 let res = f();
85 SHOW_SQL.set(old);
86 res
87}