use common::*; use simpledb::codec::{get_score_bytes, get_score_from_bytes, KeyType, VecScoreVal}; pub mod common; #[test] fn test_get_or_save_meta() { let path = get_random_database_path(); { let db = open_database_with_path(&path); let m1 = db.get_or_create_meta("aaa", KeyType::Map).unwrap(); assert_eq!(1, m1.id); let m2 = db.get_or_create_meta("bbb", KeyType::List).unwrap(); assert_eq!(2, m2.id); let m3 = db.get_meta("ccc").unwrap(); assert!(m3.is_none()); let m4 = db.get_meta("aaa").unwrap(); assert!(m4.is_some()); dump_database_meta(&db); } { let db = open_database_with_path(&path); dump_database_meta(&db); let m1 = db.get_or_create_meta("aaa", KeyType::Map).unwrap(); assert_eq!(1, m1.id); assert_eq!(KeyType::Map, m1.key_type); let m2 = db.get_or_create_meta("bbb", KeyType::List).unwrap(); assert_eq!(2, m2.id); assert_eq!(KeyType::List, m2.key_type); let m3 = db.get_meta("ccc").unwrap(); assert!(m3.is_none()); let m4 = db.get_or_create_meta("ccc", KeyType::Set).unwrap(); assert_eq!(3, m4.id); assert_eq!(KeyType::Set, m4.key_type); dump_database_meta(&db); } } #[test] fn test_for_each_key() { let path = get_random_database_path(); let db = open_database_with_path(&path); db.map_put("a111", "a", "123".as_bytes()).unwrap(); db.map_put("b111", "a", "123".as_bytes()).unwrap(); db.list_left_push("a222", "123".as_bytes()).unwrap(); db.list_left_push("b222", "123".as_bytes()).unwrap(); db.set_add("c111", "aaa".as_bytes()).unwrap(); db.set_add("c222", "aaa".as_bytes()).unwrap(); let keys: Vec = db.keys().unwrap().iter().map(|(k, _)| k.clone()).collect(); assert_eq!( keys, vec![ "a111".to_string(), "a222".to_string(), "b111".to_string(), "b222".to_string(), "c111".to_string(), "c222".to_string() ] ); let keys: Vec = db .keys_with_prefix("a") .unwrap() .iter() .map(|(k, _)| k.clone()) .collect(); assert_eq!(keys, vec!["a111".to_string(), "a222".to_string(),]); let keys: Vec = db .keys_with_prefix("b") .unwrap() .iter() .map(|(k, _)| k.clone()) .collect(); assert_eq!(keys, vec!["b111".to_string(), "b222".to_string(),]); let keys = db.keys_with_prefix("abc").unwrap(); assert_eq!(keys.len(), 0); } #[test] fn test_map() { let path = get_random_database_path(); { let db = open_database_with_path(&path); let key = "hello"; assert_eq!(0, db.map_count(key).unwrap()); assert!(db.map_get(key, "aaa").unwrap().is_none()); assert!(db.map_get(key, "bbb").unwrap().is_none()); assert!(db.map_get(key, "ccc").unwrap().is_none()); db.map_put(key, "aaa", "123".as_bytes()).unwrap(); db.map_put(key, "bbb", "456".as_bytes()).unwrap(); db.map_put(key, "ccc", "789".as_bytes()).unwrap(); assert_eq!(3, db.map_count(key).unwrap()); dump_database_meta(&db); dump_database_data(&db, key); assert_eq!("123", vec_to_str(db.map_get(key, "aaa").unwrap().unwrap())); assert_eq!("456", vec_to_str(db.map_get(key, "bbb").unwrap().unwrap())); assert_eq!("789", vec_to_str(db.map_get(key, "ccc").unwrap().unwrap())); let vec = db.map_items(key).unwrap(); assert_eq!(3, vec.len()); let (f, v) = vec.get(0).unwrap(); assert_eq!("aaa", f); assert_eq!("123", vec_to_str(v.to_vec())); assert!(db.map_delete(key, "aaa").unwrap()); assert!(db.map_delete(key, "bbb").unwrap()); assert!(!db.map_delete(key, "ddd").unwrap()); assert_eq!(1, db.map_count(key).unwrap()); dump_database_meta(&db); dump_database_data(&db, key); assert!(db.map_delete(key, "ccc").unwrap()); let mut counter = 0; db.for_each_key(|_, _| { counter += 1; true }) .unwrap(); assert_eq!(0, counter); db.map_put(key, "xx11", "1".as_bytes()).unwrap(); db.map_put(key, "xx12", "2".as_bytes()).unwrap(); db.map_put(key, "xx13", "3".as_bytes()).unwrap(); db.map_put(key, "yy11", "4".as_bytes()).unwrap(); db.map_put(key, "yy12", "5".as_bytes()).unwrap(); db.map_put(key, "yy13", "6".as_bytes()).unwrap(); db.map_put(key, "zz11", "7".as_bytes()).unwrap(); db.map_put(key, "zz12", "8".as_bytes()).unwrap(); db.map_put(key, "zz13", "9".as_bytes()).unwrap(); let vec = db.map_items_with_prefix(key, "xx").unwrap(); println!("{:?}", vec); assert_eq!(3, vec.len()); assert_eq!("xx11", vec[0].0.to_string()); assert_eq!("xx12", vec[1].0.to_string()); assert_eq!("xx13", vec[2].0.to_string()); let vec = db.map_items_with_prefix(key, "yy").unwrap(); println!("{:?}", vec); assert_eq!(3, vec.len()); assert_eq!("yy11", vec[0].0.to_string()); assert_eq!("yy12", vec[1].0.to_string()); assert_eq!("yy13", vec[2].0.to_string()); } } #[test] fn test_set() { let path = get_random_database_path(); { let db = open_database_with_path(&path); let key = "hello"; assert!(!db.set_is_member(key, "aaa".as_bytes()).unwrap()); assert_eq!(0, db.set_count(key).unwrap()); assert!(db.set_add(key, "aaa".as_bytes()).unwrap()); assert!(db.set_add(key, "bbb".as_bytes()).unwrap()); assert!(!db.set_add(key, "bbb".as_bytes()).unwrap()); assert_eq!(2, db.set_count(key).unwrap()); assert!(db.set_is_member(key, "aaa".as_bytes()).unwrap()); assert!(db.set_is_member(key, "bbb".as_bytes()).unwrap()); dump_database_meta(&db); dump_database_data(&db, key); let vec = db.set_items(key).unwrap(); assert_eq!(2, vec.len()); assert_eq!("aaa".as_bytes(), vec.get(0).unwrap().as_ref()); assert_eq!("bbb".as_bytes(), vec.get(1).unwrap().as_ref()); assert!(db.set_delete(key, "aaa".as_bytes()).unwrap()); assert!(!db.set_delete(key, "aaa".as_bytes()).unwrap()); assert_eq!(1, db.set_count(key).unwrap()); assert!(!db.set_is_member(key, "aaa".as_bytes()).unwrap()); assert!(db.set_is_member(key, "bbb".as_bytes()).unwrap()); dump_database_meta(&db); dump_database_data(&db, key); } } #[test] fn test_list() { let path = get_random_database_path(); { let db = open_database_with_path(&path); let key = "hello"; assert_eq!(0, db.list_count(key).unwrap()); assert_eq!(None, db.list_left_pop(key).unwrap()); assert_eq!(None, db.list_right_pop(key).unwrap()); assert_eq!(1, db.list_left_push(key, "a".as_bytes()).unwrap()); assert_eq!(2, db.list_left_push(key, "b".as_bytes()).unwrap()); assert_eq!(3, db.list_left_push(key, "c".as_bytes()).unwrap()); assert_eq!(4, db.list_right_push(key, "d".as_bytes()).unwrap()); assert_eq!(5, db.list_right_push(key, "e".as_bytes()).unwrap()); assert_eq!(6, db.list_right_push(key, "f".as_bytes()).unwrap()); assert_eq!(7, db.list_right_push(key, "g".as_bytes()).unwrap()); assert_eq!(7, db.list_count(key).unwrap()); dump_database_meta(&db); dump_database_data(&db, key); let vec = db.list_items(key).unwrap(); assert_eq!(7, vec.len()); assert_eq!( "cbadefg", String::from_utf8(vec.iter().flat_map(|v| v.to_vec()).collect::>()).unwrap() ); assert_eq!( "c".as_bytes(), db.list_left_pop(key).unwrap().unwrap().as_ref() ); assert_eq!( "g".as_bytes(), db.list_right_pop(key).unwrap().unwrap().as_ref() ); assert_eq!( "f".as_bytes(), db.list_right_pop(key).unwrap().unwrap().as_ref() ); assert_eq!(4, db.list_count(key).unwrap()); dump_database_meta(&db); dump_database_data(&db, key); assert_eq!(5, db.list_right_push(key, "x".as_bytes()).unwrap()); assert_eq!(6, db.list_right_push(key, "y".as_bytes()).unwrap()); assert_eq!(7, db.list_left_push(key, "z".as_bytes()).unwrap()); let vec = db.list_items(key).unwrap(); assert_eq!(7, vec.len()); assert_eq!( "zbadexy", String::from_utf8(vec.iter().flat_map(|v| v.to_vec()).collect::>()).unwrap() ); dump_database_meta(&db); dump_database_data(&db, key); assert_eq!( "z".as_bytes(), db.list_left_pop(key).unwrap().unwrap().as_ref() ); assert_eq!( "b".as_bytes(), db.list_left_pop(key).unwrap().unwrap().as_ref() ); assert_eq!( "a".as_bytes(), db.list_left_pop(key).unwrap().unwrap().as_ref() ); assert_eq!( "d".as_bytes(), db.list_left_pop(key).unwrap().unwrap().as_ref() ); assert_eq!( "e".as_bytes(), db.list_left_pop(key).unwrap().unwrap().as_ref() ); assert_eq!( "x".as_bytes(), db.list_left_pop(key).unwrap().unwrap().as_ref() ); assert_eq!( "y".as_bytes(), db.list_left_pop(key).unwrap().unwrap().as_ref() ); assert_eq!(None, db.list_left_pop(key).unwrap()); assert_eq!(None, db.list_right_pop(key).unwrap()); assert_eq!(0, db.list_count(key).unwrap()); dump_database_meta(&db); dump_database_data(&db, key); } } #[test] fn test_sorted_list() { let path = get_random_database_path(); { let db = open_database_with_path(&path); let key = "hello"; assert_eq!(0, db.sorted_list_count(key).unwrap()); assert_eq!( 1, db.sorted_list_add(key, get_score_bytes(123).as_slice(), "a".as_bytes()) .unwrap() ); assert_eq!( 2, db.sorted_list_add(key, get_score_bytes(120).as_slice(), "b".as_bytes()) .unwrap() ); assert_eq!( 3, db.sorted_list_add(key, get_score_bytes(0).as_slice(), "c".as_bytes()) .unwrap() ); assert_eq!( 4, db.sorted_list_add(key, get_score_bytes(120).as_slice(), "d".as_bytes()) .unwrap() ); assert_eq!( 5, db.sorted_list_add(key, get_score_bytes(-5).as_slice(), "e".as_bytes()) .unwrap() ); assert_eq!( 6, db.sorted_list_add(key, get_score_bytes(-10).as_slice(), "f".as_bytes()) .unwrap() ); assert_eq!(6, db.sorted_list_count(key).unwrap()); dump_database_meta(&db); dump_database_data(&db, key); let vec = db.sorted_list_items(key).unwrap(); assert_eq!(6, vec.len()); let scores: Vec = vec.iter().map(|(s, _)| get_score_from_bytes(s)).collect(); assert_eq!(vec![-10, -5, 0, 120, 120, 123], scores); let values: Vec = vec .iter() .map(|(_, v)| String::from_utf8(v.to_vec()).unwrap()) .collect(); assert_eq!(vec!["f", "e", "c", "b", "d", "a"], values); assert_eq!( None, db.sorted_list_left_pop(key, Some(get_score_bytes(-200).as_slice())) .unwrap() ); assert_eq!( None, db.sorted_list_right_pop(key, Some(get_score_bytes(200).as_slice())) .unwrap() ); { let (score, value) = db .sorted_list_left_pop(key, Some(get_score_bytes(-8).as_slice())) .unwrap() .unwrap(); assert_eq!(-10, get_score_from_bytes(score.as_ref())); assert_eq!("f", String::from_utf8(value.to_vec()).unwrap()); assert_eq!( None, db.sorted_list_left_pop(key, Some(get_score_bytes(-8).as_slice())) .unwrap() ); } { let (score, value) = db .sorted_list_right_pop(key, Some(get_score_bytes(121).as_slice())) .unwrap() .unwrap(); assert_eq!(123, get_score_from_bytes(score.as_ref())); assert_eq!("a", String::from_utf8(value.to_vec()).unwrap()); assert_eq!( None, db.sorted_list_right_pop(key, Some(get_score_bytes(121).as_slice())) .unwrap() ); } { let (score, value) = db.sorted_list_left_pop(key, None).unwrap().unwrap(); assert_eq!(-5, get_score_from_bytes(score.as_ref())); assert_eq!("e", String::from_utf8(value.to_vec()).unwrap()); } { let (score, value) = db.sorted_list_right_pop(key, None).unwrap().unwrap(); assert_eq!(120, get_score_from_bytes(score.as_ref())); assert_eq!("d", String::from_utf8(value.to_vec()).unwrap()); } assert_eq!(2, db.sorted_list_count(key).unwrap()); let vec = db.sorted_list_items(key).unwrap(); assert_eq!(2, vec.len()); let scores: Vec = vec.iter().map(|(s, _)| get_score_from_bytes(s)).collect(); assert_eq!(vec![0, 120], scores); let values: Vec = vec .iter() .map(|(_, v)| String::from_utf8(v.to_vec()).unwrap()) .collect(); assert_eq!(vec!["c", "b"], values); dump_database_meta(&db); dump_database_data(&db, key); } } #[test] fn test_sorted_set() { let path = get_random_database_path(); { let db = open_database_with_path(&path); let key = "hello"; assert!(!db.sorted_set_is_member(key, "aaa".as_bytes()).unwrap()); assert_eq!(0, db.set_count(key).unwrap()); assert_eq!( 1, db.sorted_set_add(key, get_score_bytes(120).as_slice(), "aaa".as_bytes()) .unwrap() ); assert_eq!(1, db.set_count(key).unwrap()); assert!(db.sorted_set_is_member(key, "aaa".as_bytes()).unwrap()); assert_eq!( 2, db.sorted_set_add(key, get_score_bytes(110).as_slice(), "bbb".as_bytes()) .unwrap() ); assert_eq!(2, db.set_count(key).unwrap()); assert_eq!( 3, db.sorted_set_add(key, get_score_bytes(130).as_slice(), "ccc".as_bytes()) .unwrap() ); assert_eq!(3, db.set_count(key).unwrap()); let parse_results = |vec: VecScoreVal| { let values: Vec = vec .iter() .map(|(_, v)| String::from_utf8(v.to_vec()).unwrap()) .collect(); let scores: Vec = vec .iter() .map(|(s, _)| get_score_from_bytes(s.as_ref())) .collect(); (scores, values) }; let (scores, values) = parse_results(db.sorted_set_items(key).unwrap()); assert_eq!( values, vec!["bbb".to_string(), "aaa".to_string(), "ccc".to_string()] ); assert_eq!(scores, vec![110, 120, 130]); let (scores, values) = parse_results(db.sorted_set_left(key, None, 2).unwrap()); assert_eq!(values, vec!["bbb".to_string(), "aaa".to_string()]); assert_eq!(scores, vec![110, 120]); let (scores, values) = parse_results( db.sorted_set_left(key, Some(get_score_bytes(125).as_slice()), 2) .unwrap(), ); assert_eq!(values, vec!["bbb".to_string(), "aaa".to_string()]); assert_eq!(scores, vec![110, 120]); let (scores, values) = parse_results( db.sorted_set_left(key, Some(get_score_bytes(125).as_slice()), 1) .unwrap(), ); assert_eq!(values, vec!["bbb".to_string()]); assert_eq!(scores, vec![110]); dump_database_meta(&db); dump_database_data(&db, key); let (scores, values) = parse_results(db.sorted_set_right(key, None, 10).unwrap()); assert_eq!( values, vec!["ccc".to_string(), "aaa".to_string(), "bbb".to_string()] ); assert_eq!(scores, vec![130, 120, 110]); let (scores, values) = parse_results( db.sorted_set_right(key, Some(get_score_bytes(115).as_slice()), 10) .unwrap(), ); assert_eq!(values, vec!["ccc".to_string(), "aaa".to_string()]); assert_eq!(scores, vec![130, 120]); assert!(!db.sorted_set_delete(key, "ddd".as_bytes()).unwrap()); assert!(db.sorted_set_delete(key, "aaa".as_bytes()).unwrap()); assert!(db.sorted_set_delete(key, "bbb".as_bytes()).unwrap()); assert_eq!(1, db.set_count(key).unwrap()); assert!(db.sorted_set_delete(key, "ccc".as_bytes()).unwrap()); assert_eq!(0, db.set_count(key).unwrap()); dump_database_meta(&db); dump_database_data(&db, key); } } #[test] fn test_delete_all() { let path = get_random_database_path(); let db = open_database_with_path(&path); let count = 10; let key1 = "hello"; let key2 = "world"; for i in 1..=count { db.map_put( key1, format!("key_{}", i).as_str(), get_score_bytes(i).as_slice(), ) .unwrap(); } for i in 1..=count { db.list_right_push(key2, get_score_bytes(i).as_slice()) .unwrap(); } dump_database_meta(&db); dump_database_data(&db, key1); dump_database_data(&db, key2); db.delete_all(key1).unwrap(); dump_database_meta(&db); dump_database_data(&db, key1); dump_database_data(&db, key2); assert_eq!(0, db.get_count(key1).unwrap()); assert_eq!(count, db.get_count(key2).unwrap()); db.delete_all(key2).unwrap(); dump_database_meta(&db); dump_database_data(&db, key1); dump_database_data(&db, key2); assert_eq!(0, db.get_count(key1).unwrap()); assert_eq!(0, db.get_count(key2).unwrap()); }