use crate::{export, export_from_snapshot, import, EIRes, Info};
use bincode::{deserialize_from, serialize};
use persy::{Persy, Snapshot};
use std::io::{Read, Write};
pub fn import_binary(persy: &Persy, read: &mut dyn Read) -> EIRes<()> {
import(persy, Reader { read })
}
pub fn export_binary(persy: &Persy, write: &mut dyn Write) -> EIRes<()> {
for info in export(persy)? {
write.write_all(&serialize(&true)?)?;
write.write_all(&serialize(&info)?)?;
}
write.write_all(&serialize(&false)?)?;
Ok(())
}
pub fn export_binary_from_snapshot(snapshot: &Snapshot, write: &mut dyn Write) -> EIRes<()> {
for info in export_from_snapshot(snapshot)? {
write.write_all(&serialize(&true)?)?;
write.write_all(&serialize(&info)?)?;
}
write.write_all(&serialize(&false)?)?;
Ok(())
}
struct Reader<'a> {
read: &'a mut dyn Read,
}
impl<'a> Iterator for Reader<'a> {
type Item = Info;
fn next(&mut self) -> Option<Self::Item> {
if let Ok(more) = deserialize_from(&mut self.read) {
if more {
if let Ok(info) = deserialize_from(&mut self.read) {
Some(info)
} else {
None
}
} else {
None
}
} else {
None
}
}
}
#[cfg(test)]
mod tests {
use super::{export_binary, import_binary};
use persy::{ByteVec, IndexType, OpenOptions, Persy, PersyId, Transaction, ValueMode};
use std::io::Cursor;
fn util<C, V>(create: C, verify: V)
where
C: FnOnce(&mut Transaction),
V: FnOnce(&Persy),
{
let p = OpenOptions::new().memory().expect("open fine");
let mut tx = p.begin().unwrap();
create(&mut tx);
let prep = tx.prepare().unwrap();
prep.commit().unwrap();
let mut data = Vec::new();
export_binary(&p, &mut data).unwrap();
let p1 = OpenOptions::new().memory().expect("open fine");
import_binary(&p1, &mut Cursor::new(data)).unwrap();
verify(&p1);
}
fn check_key_value<K: IndexType + PartialEq, V: IndexType + PartialEq + std::fmt::Debug>(
p: &Persy,
index: &str,
k: K,
v: V,
) {
assert_eq!(v, p.get::<K, V>(index, &k).unwrap().into_iter().next().unwrap());
}
#[test]
fn binary_all_data_export_import() {
util(
|tx| {
tx.create_segment("test").unwrap();
let persy_id = tx.insert("test", &"test".to_string().as_bytes()).unwrap();
tx.create_index::<u8, u8>("test_u8", ValueMode::Replace).unwrap();
tx.put::<u8, u8>("test_u8", 10, 10).unwrap();
tx.create_index::<u16, u16>("test_u16", ValueMode::Replace).unwrap();
tx.put::<u16, u16>("test_u16", 10, 10).unwrap();
tx.create_index::<u32, u32>("test_u32", ValueMode::Replace).unwrap();
tx.put::<u32, u32>("test_u32", 10, 10).unwrap();
tx.create_index::<u64, u64>("test_u64", ValueMode::Replace).unwrap();
tx.put::<u64, u64>("test_u64", 10, 10).unwrap();
tx.create_index::<u128, u128>("test_u128", ValueMode::Replace).unwrap();
tx.put::<u128, u128>("test_u128", 10, 10).unwrap();
tx.create_index::<i8, i8>("test_i8", ValueMode::Replace).unwrap();
tx.put::<i8, i8>("test_i8", 10, 10).unwrap();
tx.create_index::<i16, i16>("test_i16", ValueMode::Replace).unwrap();
tx.put::<i16, i16>("test_i16", 10, 10).unwrap();
tx.create_index::<i32, i32>("test_i32", ValueMode::Replace).unwrap();
tx.put::<i32, i32>("test_i32", 10, 10).unwrap();
tx.create_index::<i64, i64>("test_i64", ValueMode::Replace).unwrap();
tx.put::<i64, i64>("test_i64", 10, 10).unwrap();
tx.create_index::<i128, i128>("test_i128", ValueMode::Replace).unwrap();
tx.put::<i128, i128>("test_i128", 10, 10).unwrap();
tx.create_index::<f32, f32>("test_f32", ValueMode::Replace).unwrap();
tx.put::<f32, f32>("test_f32", 10.0, 10.0).unwrap();
tx.create_index::<f64, f64>("test_f64", ValueMode::Replace).unwrap();
tx.put::<f64, f64>("test_f64", 10.0, 10.0).unwrap();
tx.create_index::<String, String>("test_string", ValueMode::Replace)
.unwrap();
tx.put::<String, String>("test_string", "one".to_string(), "two".to_string())
.unwrap();
tx.create_index::<ByteVec, ByteVec>("test_bytevec", ValueMode::Replace)
.unwrap();
let bv = ByteVec::new(vec![20, 10]);
let bv1 = ByteVec::new(vec![10, 20]);
tx.put::<ByteVec, ByteVec>("test_bytevec", bv, bv1).unwrap();
tx.create_index::<PersyId, PersyId>("test_p", ValueMode::Replace)
.unwrap();
tx.put::<PersyId, PersyId>("test_p", persy_id.clone(), persy_id)
.unwrap();
},
|p| {
for (_, content) in p.scan("test").unwrap() {
assert_eq!("test".to_string().as_bytes().to_vec(), content);
}
check_key_value(p, "test_u8", 10 as u8, 10 as u8);
check_key_value(p, "test_u16", 10 as u16, 10 as u16);
check_key_value(p, "test_u32", 10 as u32, 10 as u32);
check_key_value(p, "test_u64", 10 as u64, 10 as u64);
check_key_value(p, "test_u128", 10 as u128, 10 as u128);
check_key_value(p, "test_i8", 10 as i8, 10 as i8);
check_key_value(p, "test_i16", 10 as i16, 10 as i16);
check_key_value(p, "test_i32", 10 as i32, 10 as i32);
check_key_value(p, "test_i64", 10 as i64, 10 as i64);
check_key_value(p, "test_i128", 10 as i128, 10 as i128);
check_key_value(p, "test_f32", 10 as f32, 10 as f32);
check_key_value(p, "test_f64", 10 as f64, 10 as f64);
check_key_value(p, "test_string", "one".to_string(), "two".to_string());
let bv = ByteVec::new(vec![20, 10]);
let bv1 = ByteVec::new(vec![10, 20]);
check_key_value(p, "test_bytevec", bv, bv1);
assert_eq!(
1,
p.range::<PersyId, PersyId, _>("test_p", ..)
.unwrap()
.into_iter()
.count()
);
},
);
}
}