sqlite_collections/ds/set/
iter.rs1use super::Error;
2use crate::format::Format;
3use crate::{identifier::Identifier, AsConnection};
4use rusqlite::{params, OptionalExtension};
5
6use std::marker::PhantomData;
7
8#[derive(Debug)]
9pub struct Iter<'db, 'tbl, S, C>
10where
11 S: Format,
12 C: AsConnection,
13{
14 connection: C,
15 database: Identifier<'db>,
16 table: Identifier<'tbl>,
17 front: Option<S::Buffer>,
18 back: Option<S::Buffer>,
19 size: usize,
20 serializer: PhantomData<S>,
21}
22
23impl<'db, 'tbl, S, C> Iter<'db, 'tbl, S, C>
24where
25 S: Format,
26 C: AsConnection,
27{
28 pub fn new(
29 connection: C,
30 database: Identifier<'db>,
31 table: Identifier<'tbl>,
32 ) -> rusqlite::Result<Self> {
33 let mut new = Self {
34 connection,
35 database,
36 table,
37 size: 0,
38 front: None,
39 back: None,
40 serializer: PhantomData,
41 };
42 new.update_size()?;
43 Ok(new)
44 }
45
46 fn update_size(&mut self) -> rusqlite::Result<usize> {
47 self.size = self.select("COUNT(*)", "", |row| row.get(0))?;
48 Ok(self.size)
49 }
50
51 fn select<U, F>(&self, selection: &str, order: &str, f: F) -> rusqlite::Result<U>
52 where
53 F: FnOnce(&rusqlite::Row<'_>) -> rusqlite::Result<U>,
54 {
55 let database = &self.database;
56 let table = &self.table;
57
58 match (
59 self.front.as_ref(),
60 self.back.as_ref(),
61 ) {
62 (None, None) => self
63 .connection
64 .as_connection()
65 .prepare_cached(&format!(
66 "SELECT {selection} FROM {database}.{table} {order} LIMIT 1"
67 ))?
68 .query_row([], f),
69 (Some(front), None) => self
70 .connection
71 .as_connection()
72 .prepare_cached(&format!(
73 "SELECT {selection} FROM {database}.{table} WHERE key > ? {order} LIMIT 1"
74 ))?
75 .query_row(params![front], f),
76 (None, Some(back)) => self
77 .connection
78 .as_connection()
79 .prepare_cached(&format!(
80 "SELECT {selection} FROM {database}.{table} WHERE key < ? {order} LIMIT 1"
81 ))?
82 .query_row(params![back], f),
83 (Some(front), Some(back)) => self
84 .connection
85 .as_connection()
86 .prepare_cached(&format!(
87 "SELECT {selection} FROM {database}.{table} WHERE key > ? AND key < ? {order} LIMIT 1"
88 ))?
89 .query_row(params![front, back], f),
90 }
91 }
92}
93
94impl<'db, 'tbl, S, C> Iterator for Iter<'db, 'tbl, S, C>
95where
96 S: Format,
97 C: AsConnection,
98{
99 type Item = Result<S::Out, Error<S>>;
100
101 fn next(&mut self) -> Option<Self::Item> {
102 let next: rusqlite::Result<Option<S::Buffer>> = self
103 .select("key", "ORDER BY key ASC", |row| row.get(0))
104 .optional();
105 match next {
106 Ok(Some(serialized)) => {
107 let ret = S::deserialize(&serialized).map_err(Error::Deserialize);
108 self.front = Some(serialized);
109 Some(self.update_size().map_err(Into::into).and(ret))
110 }
111 Ok(None) => {
112 self.size = 0;
113 None
114 }
115 Err(e) => Some(Err(e.into())),
116 }
117 }
118
119 fn size_hint(&self) -> (usize, Option<usize>) {
124 (self.size, Some(self.size))
125 }
126}
127
128impl<'db, 'tbl, S, C> DoubleEndedIterator for Iter<'db, 'tbl, S, C>
129where
130 S: Format,
131 C: AsConnection,
132{
133 fn next_back(&mut self) -> Option<Self::Item> {
134 let next: rusqlite::Result<Option<S::Buffer>> = self
135 .select("key", "ORDER BY key DESC", |row| row.get(0))
136 .optional();
137 match next {
138 Ok(Some(serialized)) => {
139 let ret = S::deserialize(&serialized).map_err(Error::Deserialize);
140 self.back = Some(serialized);
141 Some(self.update_size().map_err(Into::into).and(ret))
142 }
143 Ok(None) => {
144 self.size = 0;
145 None
146 }
147 Err(e) => Some(Err(e.into())),
148 }
149 }
150}