• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

getdozer / dozer / 4377467257

pending completion
4377467257

push

github

GitHub
implement `HAVING` (#1198)

395 of 395 new or added lines in 6 files covered. (100.0%)

27638 of 38584 relevant lines covered (71.63%)

27777.41 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

31.65
/dozer-storage/src/lmdb_database/lmdb_val.rs
1
use dozer_types::{
2
    borrow::{Borrow, Cow},
3
    types::{IndexDefinition, Record, Schema},
4
};
5

6
use crate::errors::StorageError;
7

8
pub enum Encoded<'a> {
9
    U8([u8; 1]),
10
    U8x4([u8; 4]),
11
    U8x8([u8; 8]),
12
    U8x16([u8; 16]),
13
    U8x21([u8; 21]),
14
    Vec(Vec<u8>),
15
    Borrowed(&'a [u8]),
16
}
17

18
impl<'a> AsRef<[u8]> for Encoded<'a> {
19
    fn as_ref(&self) -> &[u8] {
3,849,329✔
20
        match self {
3,849,329✔
21
            Self::U8(v) => v.as_slice(),
32,891✔
22
            Self::U8x4(v) => v.as_slice(),
8✔
23
            Self::U8x8(v) => v.as_slice(),
3,577,927✔
24
            Self::U8x16(v) => v.as_slice(),
×
25
            Self::U8x21(v) => v.as_slice(),
17,613✔
26
            Self::Vec(v) => v.as_slice(),
18,036✔
27
            Self::Borrowed(v) => v,
202,854✔
28
        }
29
    }
3,849,329✔
30
}
31

32
pub trait Encode<'a> {
33
    fn encode(self) -> Result<Encoded<'a>, StorageError>;
34
}
35

36
pub trait BorrowEncode: 'static + for<'a> Borrow<Borrowed<'a> = Self::Encode<'a>> {
37
    type Encode<'a>: Encode<'a>;
38
}
39

40
pub trait Decode: Borrow {
×
41
    fn decode(bytes: &[u8]) -> Result<Cow<Self>, StorageError>;
42
}
43

44
/// A trait for types that can be used in LMDB.
×
45
///
46
/// # Safety
47
///
48
/// - `decode` must match the implementation of `encode`.
49
pub unsafe trait LmdbVal: BorrowEncode + Decode {}
50

51
#[derive(Debug, Clone, Copy, PartialEq)]
4✔
52
pub enum LmdbKeyType {
53
    U32,
54
    #[cfg(target_pointer_width = "64")]
55
    U64,
56
    FixedSizeOtherThanU32OrUsize,
57
    VariableSize,
58
}
59

60
/// A trait for types that can be used as keys in LMDB.
61
///
62
/// # Safety
63
///
64
/// - `TYPE` must match the implementation of `encode`.
65
///
66
/// # Note
67
///
68
/// The implementation for `u32` and `u64` has a caveat: The values are encoded in big-endian but compared in native-endian.
69
pub unsafe trait LmdbKey: LmdbVal {
70
    const TYPE: LmdbKeyType;
71
}
×
72

×
73
impl<'a> Encode<'a> for &'a u8 {
×
74
    fn encode(self) -> Result<Encoded<'a>, StorageError> {
36,323✔
75
        Ok(Encoded::U8([*self]))
36,323✔
76
    }
36,323✔
77
}
×
78

×
79
impl BorrowEncode for u8 {
×
80
    type Encode<'a> = &'a u8;
×
81
}
×
82

83
impl Decode for u8 {
84
    fn decode(bytes: &[u8]) -> Result<Cow<Self>, StorageError> {
×
85
        Ok(Cow::Owned(bytes[0]))
×
86
    }
×
87
}
×
88

×
89
unsafe impl LmdbKey for u8 {
×
90
    const TYPE: LmdbKeyType = LmdbKeyType::FixedSizeOtherThanU32OrUsize;
×
91
}
×
92

93
unsafe impl LmdbVal for u8 {}
×
94

×
95
impl<'a> Encode<'a> for &'a u32 {
×
96
    fn encode(self) -> Result<Encoded<'a>, StorageError> {
8✔
97
        Ok(Encoded::U8x4(self.to_be_bytes()))
8✔
98
    }
8✔
99
}
100

101
impl BorrowEncode for u32 {
×
102
    type Encode<'a> = &'a u32;
×
103
}
×
104

×
105
impl Decode for u32 {
×
106
    fn decode(bytes: &[u8]) -> Result<Cow<Self>, StorageError> {
3✔
107
        Ok(Cow::Owned(u32::from_be_bytes(bytes.try_into().unwrap())))
3✔
108
    }
3✔
109
}
×
110

×
111
unsafe impl LmdbKey for u32 {
×
112
    const TYPE: LmdbKeyType = LmdbKeyType::U32;
×
113
}
×
114

115
unsafe impl LmdbVal for u32 {}
116

117
impl<'a> Encode<'a> for &'a u64 {
118
    fn encode(self) -> Result<Encoded<'a>, StorageError> {
3,579,277✔
119
        Ok(Encoded::U8x8(self.to_be_bytes()))
3,579,277✔
120
    }
3,579,277✔
121
}
122

×
123
impl BorrowEncode for u64 {
×
124
    type Encode<'a> = &'a u64;
×
125
}
×
126

127
impl Decode for u64 {
128
    fn decode(bytes: &[u8]) -> Result<Cow<Self>, StorageError> {
3,585,109✔
129
        Ok(Cow::Owned(u64::from_be_bytes(bytes.try_into().unwrap())))
3,585,109✔
130
    }
3,585,109✔
131
}
132

133
unsafe impl LmdbKey for u64 {
×
134
    #[cfg(target_pointer_width = "64")]
×
135
    const TYPE: LmdbKeyType = LmdbKeyType::U64;
×
136
    #[cfg(not(target_pointer_width = "64"))]
137
    const TYPE: LmdbKeyType = LmdbKeyType::FixedSizeOtherThanU32OrUsize;
138
}
×
139

×
140
unsafe impl LmdbVal for u64 {}
×
141

142
impl<'a> Encode<'a> for &'a [u8] {
143
    fn encode(self) -> Result<Encoded<'a>, StorageError> {
203,331✔
144
        Ok(Encoded::Borrowed(self))
203,331✔
145
    }
203,331✔
146
}
×
147

148
impl BorrowEncode for Vec<u8> {
×
149
    type Encode<'a> = &'a [u8];
×
150
}
×
151

152
impl Decode for Vec<u8> {
153
    fn decode(bytes: &[u8]) -> Result<Cow<Self>, StorageError> {
5,170,736✔
154
        Ok(Cow::Borrowed(bytes))
5,170,736✔
155
    }
5,170,736✔
156
}
×
157

×
158
unsafe impl LmdbKey for Vec<u8> {
×
159
    const TYPE: LmdbKeyType = LmdbKeyType::VariableSize;
×
160
}
×
161

×
162
unsafe impl LmdbVal for Vec<u8> {}
163

164
impl<'a> Encode<'a> for &'a str {
165
    fn encode(self) -> Result<Encoded<'a>, StorageError> {
×
166
        Ok(Encoded::Borrowed(self.as_bytes()))
×
167
    }
×
168
}
×
169

×
170
impl BorrowEncode for String {
×
171
    type Encode<'a> = &'a str;
×
172
}
×
173

174
impl Decode for String {
175
    fn decode(bytes: &[u8]) -> Result<Cow<Self>, StorageError> {
×
176
        Ok(Cow::Borrowed(std::str::from_utf8(bytes).unwrap()))
×
177
    }
×
178
}
179

180
unsafe impl LmdbVal for String {}
×
181

×
182
unsafe impl LmdbKey for String {
×
183
    const TYPE: LmdbKeyType = LmdbKeyType::VariableSize;
×
184
}
×
185

×
186
impl<'a> Encode<'a> for &'a Record {
×
187
    fn encode(self) -> Result<Encoded<'a>, StorageError> {
×
188
        dozer_types::bincode::serialize(self)
×
189
            .map(Encoded::Vec)
×
190
            .map_err(|e| StorageError::SerializationError {
×
191
                typ: "Record",
×
192
                reason: Box::new(e),
×
193
            })
×
194
    }
×
195
}
×
196

×
197
impl BorrowEncode for Record {
×
198
    type Encode<'a> = &'a Record;
×
199
}
200

201
impl Decode for Record {
202
    fn decode(bytes: &[u8]) -> Result<Cow<Self>, StorageError> {
×
203
        dozer_types::bincode::deserialize(bytes)
×
204
            .map(Cow::Owned)
×
205
            .map_err(|e| StorageError::DeserializationError {
×
206
                typ: "Record",
×
207
                reason: Box::new(e),
×
208
            })
×
209
    }
×
210
}
×
211

×
212
unsafe impl LmdbKey for Record {
×
213
    const TYPE: LmdbKeyType = LmdbKeyType::VariableSize;
214
}
215

216
unsafe impl LmdbVal for Record {}
217

218
impl<'a> Encode<'a> for &'a (Schema, Vec<IndexDefinition>) {
×
219
    fn encode(self) -> Result<Encoded<'a>, StorageError> {
342✔
220
        dozer_types::bincode::serialize(self)
342✔
221
            .map(Encoded::Vec)
342✔
222
            .map_err(|e| StorageError::SerializationError {
342✔
223
                typ: "(Schema, Vec<IndexDefinition>)",
×
224
                reason: Box::new(e),
×
225
            })
342✔
226
    }
342✔
227
}
×
228

×
229
impl BorrowEncode for (Schema, Vec<IndexDefinition>) {
×
230
    type Encode<'a> = &'a (Schema, Vec<IndexDefinition>);
231
}
232

233
impl Decode for (Schema, Vec<IndexDefinition>) {
234
    fn decode(bytes: &[u8]) -> Result<Cow<Self>, StorageError> {
297✔
235
        dozer_types::bincode::deserialize(bytes)
297✔
236
            .map(Cow::Owned)
297✔
237
            .map_err(|e| StorageError::DeserializationError {
297✔
238
                typ: "(Schema, Vec<IndexDefinition>)",
×
239
                reason: Box::new(e),
×
240
            })
297✔
241
    }
297✔
242
}
×
243

×
244
unsafe impl LmdbVal for (Schema, Vec<IndexDefinition>) {}
×
245

×
246
#[cfg(test)]
247
mod tests {
248
    use super::*;
249

250
    #[test]
1✔
251
    fn test_lmdb_key_types() {
1✔
252
        assert_eq!(u8::TYPE, LmdbKeyType::FixedSizeOtherThanU32OrUsize);
1✔
253
        assert_eq!(u32::TYPE, LmdbKeyType::U32);
1✔
254
        assert_eq!(u64::TYPE, LmdbKeyType::U64);
1✔
255
        assert_eq!(Vec::<u8>::TYPE, LmdbKeyType::VariableSize);
1✔
256
    }
1✔
257
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc