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}