1use std::{
2 cell::{Cell, RefCell},
3 collections::BTreeMap,
4 fmt::{Debug, Display},
5 marker::PhantomData,
6 ops::{Deref, DerefMut},
7 rc::Rc,
8};
9
10use rusqlite::Connection;
11use self_cell::{MutBorrow, self_cell};
12
13use crate::{
14 IntoExpr,
15 lower::{
16 self,
17 emit::{self, IndexMap},
18 list_writer::ListWriter,
19 ord_rc::OrdRc,
20 },
21 rows::Rows,
22 select::{Cacher, DynPrepared, IntoSelect, Prepared, Row, SelectImpl},
23 transaction::TXN,
24 value::OrdTyp,
25};
26
27pub struct Query<'t, 'inner, S> {
29 pub(crate) phantom: PhantomData<&'t ()>,
30 pub(crate) q: Rows<'inner, S>,
31}
32
33impl<'inner, S> Deref for Query<'_, 'inner, S> {
34 type Target = Rows<'inner, S>;
35
36 fn deref(&self) -> &Self::Target {
37 &self.q
38 }
39}
40
41impl<S> DerefMut for Query<'_, '_, S> {
42 fn deref_mut(&mut self) -> &mut Self::Target {
43 &mut self.q
44 }
45}
46
47type Stmt<'x> = rusqlite::CachedStatement<'x>;
48type RRows<'a> = rusqlite::Rows<'a>;
49
50self_cell!(
51 pub struct OwnedRows<'x> {
52 owner: MutBorrow<Stmt<'x>>,
53
54 #[covariant]
55 dependent: RRows,
56 }
57);
58
59pub struct Iter<'inner, O> {
64 inner_phantom: PhantomData<(OwnedRows<'inner>, *const ())>,
66 inner: usize,
67
68 prepared: DynPrepared<O>,
69 cached: Vec<String>,
70}
71
72impl<O> Iterator for Iter<'_, O> {
73 type Item = O;
74
75 fn next(&mut self) -> Option<Self::Item> {
76 TXN.with_borrow_mut(|combi| {
77 let combi = combi.as_mut().unwrap();
78 combi.with_dependent_mut(|_txn, row_store| {
79 let rows = row_store.get_mut(self.inner)?;
82 rows.with_dependent_mut(|_, rows| {
83 let row = rows.next().unwrap()?;
84 Some(self.prepared.call(Row::new(row, &self.cached)))
85 })
86 })
87 })
88 }
89}
90
91impl<O> Drop for Iter<'_, O> {
92 fn drop(&mut self) {
93 TXN.with_borrow_mut(|combi| {
94 let combi = combi.as_mut().unwrap();
95 combi.with_dependent_mut(|_txn, row_store| {
96 row_store.try_remove(self.inner);
99 })
100 })
101 }
102}
103
104impl<'t, 'inner, S> Query<'t, 'inner, S> {
105 pub fn into_vec<O>(&self, select: impl IntoSelect<'inner, S, Out = O>) -> Vec<O> {
111 self.into_iter(select).collect()
112 }
113
114 pub fn into_iter<O>(&self, select: impl IntoSelect<'inner, S, Out = O>) -> Iter<'t, O> {
120 self.order_by().into_iter(select)
121 }
122
123 pub fn order_by<'q>(&'q self) -> OrderBy<'q, 't, 'inner, S> {
131 OrderBy {
132 query: self,
133 order: Vec::new(),
134 }
135 }
136}
137
138#[derive(Clone)]
139enum Order {
140 Asc,
141 Desc,
142}
143
144impl Display for Order {
145 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
146 match self {
147 Order::Asc => f.write_str("ASC"),
148 Order::Desc => f.write_str("DESC"),
149 }
150 }
151}
152
153#[derive(Clone)]
157pub struct OrderBy<'q, 't, 'inner, S> {
158 query: &'q Query<'t, 'inner, S>,
159 order: Vec<(Rc<lower::Expr>, Order)>,
160}
161
162impl<'t, 'inner, S> OrderBy<'_, 't, 'inner, S> {
163 pub fn asc<'q, T: OrdTyp>(mut self, key: impl IntoExpr<'inner, S, Typ = T>) -> Self {
165 self.order.push((key.into_expr().inner, Order::Asc));
166 self
167 }
168
169 pub fn desc<'q, T: OrdTyp>(mut self, key: impl IntoExpr<'inner, S, Typ = T>) -> Self {
171 self.order.push((key.into_expr().inner, Order::Desc));
172 self
173 }
174
175 pub fn into_iter<O>(&self, select: impl IntoSelect<'inner, S, Out = O>) -> Iter<'t, O> {
182 let mut cacher = Cacher::new();
183 let prepared = select.into_select().inner.prepare(&mut cacher);
184
185 let mut selected = IndexMap::default();
186 let cached_aliases = cacher
187 .columns
188 .into_iter()
189 .map(|expr| {
190 let (idx, ()) = selected.insert_with(expr, |_| ());
191 format!("s{idx}")
192 })
193 .collect();
194
195 let order_by_cols: Vec<_> = self
196 .order
197 .iter()
198 .map(|(col, order)| {
199 let (idx, _) = selected.insert_with(col.clone(), |_| ());
200 (idx, order)
201 })
202 .collect();
203
204 let rows = self.query.ast.as_ref().clone();
205 let mut stmt = emit::Stmt::default();
206 let forwarded = rows.emit(&mut stmt, false, &selected);
207 assert!(forwarded.is_empty());
208
209 if !order_by_cols.is_empty() {
210 stmt.write(" ORDER BY ");
211 let mut list = ListWriter::new(&mut stmt, ", ");
212 for (idx, order) in order_by_cols {
213 list.item().write(idx + 1).write(" ").write(order);
214 }
215 }
216
217 TXN.with_borrow_mut(|txn| {
218 let combi = txn.as_mut().unwrap();
219
220 combi.with_dependent_mut(|conn, rows_store| {
221 track_stmt(conn.get(), &stmt.sql, &stmt.params);
222 let cached = MutBorrow::new(conn.get().prepare_cached(&stmt.sql).unwrap());
223
224 let idx = rows_store.insert(OwnedRows::new(cached, |cached| {
225 cached
226 .borrow_mut()
227 .query(rusqlite::params_from_iter(stmt.params))
228 .unwrap()
229 }));
230
231 Iter {
232 inner: idx,
233 inner_phantom: PhantomData,
234 prepared,
235 cached: cached_aliases,
236 }
237 })
238 })
239 }
240}
241
242pub(crate) fn track_stmt(
243 conn: &Connection,
244 sql: &String,
245 values: &[OrdRc<rusqlite::types::Value>],
246) {
247 if COLLECT.get() {
248 SQL_AND_PLAN.with_borrow_mut(|map| {
249 map.entry(sql.clone())
250 .or_insert_with(|| get_node(conn, values, sql));
251 });
252 }
253}
254
255thread_local! {
256 static COLLECT: Cell<bool> = const { Cell::new(false) };
257 static SQL_AND_PLAN: RefCell<BTreeMap<String, Node>> = const { RefCell::new(BTreeMap::new()) };
258}
259
260pub fn get_plan<R>(f: impl FnOnce() -> R) -> (R, BTreeMap<String, Node>) {
261 let old = COLLECT.get();
262 COLLECT.set(true);
263 let res = f();
264 COLLECT.set(old);
265 (res, SQL_AND_PLAN.take())
266}
267
268fn get_node(conn: &Connection, values: &[OrdRc<rusqlite::types::Value>], sql: &str) -> Node {
269 let mut prepared = conn.prepare(&format!("EXPLAIN QUERY PLAN {sql}")).unwrap();
270 let rows = prepared
271 .query_map(rusqlite::params_from_iter(values), |row| {
272 Ok((
273 row.get_unwrap("parent"),
274 Node {
275 id: row.get_unwrap("id"),
276 detail: row.get_unwrap("detail"),
277 children: vec![],
278 },
279 ))
280 })
281 .unwrap();
282 let mut out = Node {
283 id: 0,
284 detail: "QUERY PLAN".to_owned(),
285 children: vec![],
286 };
287 rows.for_each(|res| {
288 let (id, node) = res.unwrap();
289 out.get_mut(id).children.push(node);
290 });
291
292 out
293}
294
295pub struct Node {
296 id: i64,
297 detail: String,
298 children: Vec<Node>,
299}
300
301impl Node {
302 fn get_mut(&mut self, id: i64) -> &mut Node {
303 if self.id == id {
304 return self;
305 }
306 self.children.last_mut().unwrap().get_mut(id)
307 }
308}
309
310impl Debug for Node {
311 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
312 f.write_str(&self.detail)?;
313 if !self.children.is_empty() {
314 f.write_str(" ")?;
315 f.debug_list().entries(&self.children).finish()?;
316 }
317 Ok(())
318 }
319}