1use std::{
2 cell::Cell,
3 fmt::Debug,
4 marker::PhantomData,
5 ops::{Deref, DerefMut},
6};
7
8use rusqlite::Connection;
9use sea_query::SqliteQueryBuilder;
10use sea_query_rusqlite::{RusqliteBinder, RusqliteValues};
11
12use crate::{
13 dummy_impl::{Cacher, IntoSelect, Prepared, Row, SelectImpl},
14 rows::Rows,
15};
16
17pub struct Query<'outer, 'inner, S> {
19 pub(crate) phantom: PhantomData<&'inner &'outer ()>,
20 pub(crate) q: Rows<'inner, S>,
21 pub(crate) conn: &'inner rusqlite::Connection,
22}
23
24impl<'inner, S> Deref for Query<'_, 'inner, S> {
25 type Target = Rows<'inner, S>;
26
27 fn deref(&self) -> &Self::Target {
28 &self.q
29 }
30}
31
32impl<S> DerefMut for Query<'_, '_, S> {
33 fn deref_mut(&mut self) -> &mut Self::Target {
34 &mut self.q
35 }
36}
37
38impl<'outer, 'inner, S> Query<'outer, 'inner, S> {
39 pub fn into_vec<O>(&self, select: impl IntoSelect<'inner, 'outer, S, Out = O>) -> Vec<O> {
45 self.into_vec_private(select)
46 }
47
48 pub(crate) fn into_vec_private<'x, D>(&self, dummy: D) -> Vec<D::Out>
49 where
50 D: IntoSelect<'x, 'outer, S>,
51 {
52 let mut cacher = Cacher::new();
53 let mut prepared = dummy.into_select().inner.prepare(&mut cacher);
54
55 let (select, cached) = self.ast.clone().full().simple(cacher.columns);
56 let (sql, values) = select.build_rusqlite(SqliteQueryBuilder);
57 if SHOW_SQL.get() {
58 println!("{sql}");
59 println!("{values:?}");
60 }
61 if GET_PLAN.get() {
62 let node = get_node(&self.conn, &values, &sql);
63 PLAN.set(Some(node));
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 static GET_PLAN: Cell<bool> = const { Cell::new(false) };
80 static PLAN: Cell<Option<Node>> = const { Cell::new(None) };
81}
82
83pub fn show_sql<R>(f: impl FnOnce() -> R) -> R {
84 let old = SHOW_SQL.get();
85 SHOW_SQL.set(true);
86 let res = f();
87 SHOW_SQL.set(old);
88 res
89}
90
91pub fn get_plan<R>(f: impl FnOnce() -> R) -> (R, Node) {
92 let old = GET_PLAN.get();
93 GET_PLAN.set(true);
94 let res = f();
95 GET_PLAN.set(old);
96 (res, PLAN.take().unwrap())
97}
98
99fn get_node(conn: &Connection, values: &RusqliteValues, sql: &str) -> Node {
100 let mut prepared = conn.prepare(&format!("EXPLAIN QUERY PLAN {sql}")).unwrap();
101 let rows = prepared
102 .query_map(&*values.as_params(), |row| {
103 Ok((
104 row.get_unwrap("parent"),
105 Node {
106 id: row.get_unwrap("id"),
107 detail: row.get_unwrap("detail"),
108 children: vec![],
109 },
110 ))
111 })
112 .unwrap();
113 let mut out = Node {
114 id: 0,
115 detail: "QUERY PLAN".to_owned(),
116 children: vec![],
117 };
118 rows.for_each(|res| {
119 let (id, node) = res.unwrap();
120 out.get_mut(id).children.push(node);
121 });
122
123 out
124}
125
126pub struct Node {
127 id: i64,
128 detail: String,
129 children: Vec<Node>,
130}
131
132impl Node {
133 fn get_mut(&mut self, id: i64) -> &mut Node {
134 if self.id == id {
135 return self;
136 }
137 self.children.last_mut().unwrap().get_mut(id)
138 }
139}
140
141impl Debug for Node {
142 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
143 f.write_str(&self.detail)?;
144 if !self.children.is_empty() {
145 f.write_str(" ")?;
146 f.debug_list().entries(&self.children).finish()?;
147 }
148 Ok(())
149 }
150}