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