native_db_32bit/transaction/query/scan/primary_scan.rs
1use crate::db_type::{unwrap_item, DatabaseInnerKeyValue, DatabaseInnerKeyValueRange, Input};
2use crate::InnerKeyValue;
3use std::marker::PhantomData;
4use std::ops::RangeBounds;
5
6/// Scan values from the database.
7pub struct PrimaryScan<PrimaryTable, T: Input>
8where
9 PrimaryTable: redb::ReadableTable<DatabaseInnerKeyValue, &'static [u8]>,
10{
11 pub(crate) primary_table: PrimaryTable,
12 pub(crate) _marker: PhantomData<T>,
13}
14
15impl<PrimaryTable, T: Input> PrimaryScan<PrimaryTable, T>
16where
17 PrimaryTable: redb::ReadableTable<DatabaseInnerKeyValue, &'static [u8]>,
18{
19 pub(crate) fn new(table: PrimaryTable) -> Self {
20 Self {
21 primary_table: table,
22 _marker: PhantomData::default(),
23 }
24 }
25
26 /// Iterate over all values.
27 ///
28 /// # Example
29 /// ```rust
30 /// use native_db::*;
31 /// use native_model::{native_model, Model};
32 /// use serde::{Deserialize, Serialize};
33 ///
34 /// #[derive(Serialize, Deserialize)]
35 /// #[native_model(id=1, version=1)]
36 /// #[native_db]
37 /// struct Data {
38 /// #[primary_key]
39 /// id: u64,
40 /// }
41 ///
42 /// fn main() -> Result<(), db_type::Error> {
43 /// let mut builder = DatabaseBuilder::new();
44 /// builder.define::<Data>()?;
45 /// let db = builder.create_in_memory()?;
46 ///
47 /// // Open a read transaction
48 /// let r = db.r_transaction()?;
49 ///
50 /// // Get all values
51 /// let _values: Vec<Data> = r.scan().primary()?.all().collect();
52 /// Ok(())
53 /// }
54 /// ```
55 pub fn all(&self) -> PrimaryScanIterator<T> {
56 let range = self
57 .primary_table
58 .range::<DatabaseInnerKeyValue>(..)
59 .unwrap();
60 PrimaryScanIterator {
61 range,
62 _marker: PhantomData::default(),
63 }
64 }
65
66 /// Iterate over all values in a range.
67 ///
68 /// # Example
69 /// ```rust
70 /// use native_db::*;
71 /// use native_model::{native_model, Model};
72 /// use serde::{Deserialize, Serialize};
73 ///
74 /// #[derive(Serialize, Deserialize)]
75 /// #[native_model(id=1, version=1)]
76 /// #[native_db]
77 /// struct Data {
78 /// #[primary_key]
79 /// id: u64,
80 /// }
81 ///
82 /// fn main() -> Result<(), db_type::Error> {
83 /// let mut builder = DatabaseBuilder::new();
84 /// builder.define::<Data>()?;
85 /// let db = builder.create_in_memory()?;
86 ///
87 /// // Open a read transaction
88 /// let r = db.r_transaction()?;
89 ///
90 /// // Get the values from 5 to the end
91 /// let _values: Vec<Data> = r.scan().primary()?.range(5u64..).collect();
92 /// Ok(())
93 /// }
94 /// ```
95 pub fn range<TR: InnerKeyValue, R: RangeBounds<TR>>(&self, range: R) -> PrimaryScanIterator<T> {
96 let database_inner_key_value_range = DatabaseInnerKeyValueRange::new(range);
97 let range = self
98 .primary_table
99 .range::<DatabaseInnerKeyValue>(database_inner_key_value_range)
100 .unwrap();
101 PrimaryScanIterator {
102 range,
103 _marker: PhantomData::default(),
104 }
105 }
106
107 /// Iterate over all values starting with a prefix.
108 ///
109 /// # Example
110 /// ```rust
111 /// use native_db::*;
112 /// use native_model::{native_model, Model};
113 /// use serde::{Deserialize, Serialize};
114 ///
115 /// #[derive(Serialize, Deserialize)]
116 /// #[native_model(id=1, version=1)]
117 /// #[native_db]
118 /// struct Data {
119 /// #[primary_key]
120 /// id: String,
121 /// }
122 ///
123 /// fn main() -> Result<(), db_type::Error> {
124 /// let mut builder = DatabaseBuilder::new();
125 /// builder.define::<Data>()?;
126 /// let db = builder.create_in_memory()?;
127 ///
128 /// // Open a read transaction
129 /// let r = db.r_transaction()?;
130 ///
131 /// // Get the values starting with "victor"
132 /// let _values: Vec<Data> = r.scan().primary()?.start_with("victor").collect();
133 /// Ok(())
134 /// }
135 /// ```
136 pub fn start_with<'a>(
137 &'a self,
138 start_with: impl InnerKeyValue + 'a,
139 ) -> PrimaryScanIteratorStartWith<'a, T> {
140 let start_with = start_with.database_inner_key_value();
141 let range = self
142 .primary_table
143 .range::<DatabaseInnerKeyValue>(start_with.clone()..)
144 .unwrap();
145 PrimaryScanIteratorStartWith {
146 start_with,
147 range,
148 _marker: PhantomData::default(),
149 }
150 }
151}
152
153pub struct PrimaryScanIterator<'a, T: Input> {
154 pub(crate) range: redb::Range<'a, DatabaseInnerKeyValue, &'static [u8]>,
155 pub(crate) _marker: PhantomData<T>,
156}
157
158impl<'a, T: Input> Iterator for PrimaryScanIterator<'a, T> {
159 type Item = T;
160
161 fn next(&mut self) -> Option<Self::Item> {
162 match self.range.next() {
163 Some(Ok((_, v))) => unwrap_item(Some(v)),
164 _ => None,
165 }
166 }
167}
168impl<'a, T: Input> DoubleEndedIterator for PrimaryScanIterator<'a, T> {
169 fn next_back(&mut self) -> Option<Self::Item> {
170 match self.range.next_back() {
171 Some(Ok((_, v))) => unwrap_item(Some(v)),
172 _ => None,
173 }
174 }
175}
176
177pub struct PrimaryScanIteratorStartWith<'a, T: Input> {
178 pub(crate) range: redb::Range<'a, DatabaseInnerKeyValue, &'static [u8]>,
179 pub(crate) start_with: DatabaseInnerKeyValue,
180 pub(crate) _marker: PhantomData<T>,
181}
182
183impl<'a, T: Input> Iterator for PrimaryScanIteratorStartWith<'a, T> {
184 type Item = T;
185
186 fn next(&mut self) -> Option<Self::Item> {
187 match self.range.next() {
188 Some(Ok((k, v))) => {
189 let k = k.value();
190 if k.as_slice().starts_with(self.start_with.as_slice()) {
191 unwrap_item(Some(v))
192 } else {
193 None
194 }
195 }
196 _ => None,
197 }
198 }
199}