#[cfg(test)]
mod testinner {
use crate::*;
use std::hash::Hasher;
#[test]
fn test_main() {
use page_store::*;
let limits = Limits::default();
let file = atom_file::MultiFileStorage::new("test.db");
let upd = atom_file::FastFileStorage::new("test.upd");
let af = atom_file::AtomicFile::new_with_limits(file, upd, &limits.af_lim);
let ps = BlockPageStg::new(af, &limits);
let is_new = ps.is_new();
let spd = SharedPagedData::new_from_ps(ps);
if false {
let psi = &spd.psi;
println!("max page size={}", psi.max_size_page());
for i in 0..psi.sizes() {
println!("page size={}", psi.size(1 + i));
}
}
let mut ps = PageSet::new(spd.new_writer());
if false {
let (root, len) = if is_new { (ps.new_page(), 0) } else { (3, 410) };
test_tv(root, len, &mut ps);
}
if false {
test_varval(&mut ps);
}
if true {
test_cust(&mut ps);
}
spd.shutdown();
}
struct CustEmailKey<'a> {
email: &'a str,
dt: &'a DataType,
map: &'a TabInfo,
}
impl<'a> Hash for CustEmailKey<'a> {
fn hash<H: Hasher>(&self, h: &mut H) {
self.email.hash(h);
}
}
impl<'a> Key<VarValAddr> for CustEmailKey<'a> {
fn ok(&self, addr: VarValAddr, ps: &mut PageSet) -> Option<(VarValAddr, Value)> {
let dt = DataType::IList;
let list = addr.get(&dt, ps);
let rid = list.ilist()[0];
let key = IdKey { rid, dt: self.dt };
let mut hm = HashMap::restore(self.map.main, ps);
let (_, cr) = hm.get(&key).unwrap();
let email = cr.list()[2].string();
if *self.email == **email {
return Some((addr, list));
}
None
}
}
fn init(ps: &mut PageSet) {
let hm = HashMap::<VarValAddr>::new(ps, 1);
ps.obj_map = hm.save();
let hm = HashMap::<VarValAddr>::new(ps, 1);
ps.obj_by_name = hm.save();
let hm = HashMap::<VarValAddr>::new(ps, 1);
ps.table_datatype_map = hm.save();
}
fn cust_dt() -> DataType {
use pstd::veca;
let optint = DataType::Enum(veca![
(LString::from("None"), DataType::Empty),
(LString::from("Some"), DataType::Int),
]);
DataType::Struct(veca![
(LString::from("Id"), DataType::Int),
(LString::from("Name"), DataType::String),
(LString::from("Email"), DataType::String),
(LString::from("Postal"), DataType::String),
(LString::from("HPass"), DataType::Binary),
(LString::from("Age"), optint),
])
}
fn make_cust(
ps: &mut PageSet,
dt: &DataType,
map: &mut TabInfo,
name: &str,
email: &str,
postal: &str,
) {
use pstd::veca;
let rid = map.alloc;
map.alloc += 1;
let cr = Value::List(veca![
Value::Int(rid),
Value::String(LString::from(name)),
Value::String(LString::from(email)),
Value::String(LString::from(postal)),
Value::Binary(LVec::from([1, 2, 3, 4])),
Value::Enum(1, LBox::new(Value::Int(68))),
]);
let key = IdKey{ rid, dt };
key.insert( &cr, &mut map.main, ps );
let av = {
let emkey = CustEmailKey { email, dt, map };
{
let mut hm = HashMap::restore(map.index, ps);
let av = hm.remove(&emkey);
if hm.root_changed() {
map.index = hm.save();
}
av
}
};
let dtil = DataType::IList;
let addr = if let Some((addr, mut list)) = av {
list.ilist_mut().push(rid);
addr.update(&dtil, &list, ps)
} else {
let list = Value::IList(veca![rid]);
VarValAddr::new(&dtil, &list, ps)
};
{
let emkey = CustEmailKey { email, dt, map };
let mut hm = HashMap::restore(map.index, ps);
hm.insert(&emkey, addr);
if hm.root_changed() {
map.index = hm.save();
}
}
}
fn list_cust_ids_with_email(ps: &mut PageSet, map: &TabInfo, dt: &DataType, email: &str) {
let key = CustEmailKey { email, dt, map };
let mut hm = HashMap::restore(map.index, ps);
if let Some((_, list)) = hm.get(&key) {
println!("List of cust ids for {} = {:?}", email, list.ilist());
} else {
println!("No cust ids found for email {}", email);
}
}
fn list_cust_all(ps: &mut PageSet, map: &TabInfo, cdt: &DataType) {
let mut hm = HashMap::<VarValAddr>::restore(map.main, ps);
let mut x = hm.all_addr();
x.sort();
for addr in x {
let cr = addr.get(cdt, ps);
println!("list_cust_all addr={:?} cr={:?}", addr, cr);
}
}
fn test_cust(ps: &mut PageSet) {
init(ps);
create_table("cust", cust_dt(), ps);
let (tid, obj) = get_obj_from_name("cust", ps).unwrap();
let mut cust_map = decode_table(obj);
let cdt = get_table_datatype(tid, ps);
make_cust(
ps,
&cdt,
&mut cust_map,
"George Barwood",
"george@gmail.com",
"33 Sandpipe Close, GL2 4LZ",
);
make_cust(
ps,
&cdt,
&mut cust_map,
"George Barwood",
"george@gmail.com",
"33 Sandpipe Close, GL2 4LZ",
);
make_cust(
ps,
&cdt,
&mut cust_map,
"George Barwood",
"george@gmail.com",
"33 Sandpipe Close, GL2 4LZ",
);
for _ in 102..120 {
make_cust(
ps,
&cdt,
&mut cust_map,
"Marilyn Barwood",
"maz.barwood@gmail.com",
"33 Sandpipe Close, GL2 4LZ",
);
}
list_cust_all(ps, &cust_map, &cdt);
list_cust_ids_with_email(ps, &cust_map, &cdt, "george@gmail.com");
list_cust_ids_with_email(ps, &cust_map, &cdt, "maz.barwood@gmail.com");
list_cust_ids_with_email(ps, &cust_map, &cdt, "mary@gmail.com");
}
}