#avltree #database #index #library

versatile-data

A library for databases that has convenient datasets that group together commonly used fields and gives you the flexibility to create your own fields

7 releases

0.64.3 Mar 17, 2023
0.63.3 Feb 26, 2023
0.58.0 Dec 31, 2022
0.51.0 Nov 23, 2022

#30 in Database implementations

Download history 110/week @ 2022-12-08 160/week @ 2022-12-15 282/week @ 2022-12-22 298/week @ 2022-12-29 96/week @ 2023-01-05 62/week @ 2023-01-12 50/week @ 2023-01-19 67/week @ 2023-01-26 143/week @ 2023-02-02 317/week @ 2023-02-09 389/week @ 2023-02-16 109/week @ 2023-02-23 43/week @ 2023-03-02 40/week @ 2023-03-09 76/week @ 2023-03-16 67/week @ 2023-03-23

299 downloads per month
Used in 4 crates (via semilattice-database)

MIT/Apache

76KB
2K SLoC

versatile-data

This is a small database that is easy to use. It doesn't use SQL. No table.

It has data formatted like key-value, but with rows like data in Table format. Each row can have data in key-value format. In addition, as a field of commonly used concepts, Activity, term_begin, term_end, last_updated is fixed for each row.

No need to design a table scheme like SQL. You can add any column(field) at any time.

All fields are indexed for fast search. You don't have to think about which fields to index. it is done automatically.

Example

use versatile_data::prelude::*;

let dir="./vd-test/";
if std::path::Path::new(dir).exists(){
    std::fs::remove_dir_all(dir).unwrap();
}
if let Ok(mut data)=Data::new(dir){
    let range=1..=10;
    for i in range.clone(){
        data.update(&Operation::New{
            activity:Activity::Active
            ,term_begin:Term::Default
            ,term_end:Term::Default
            ,fields:vec![
                KeyValue::new("num",i.to_string())
                ,KeyValue::new("num_by3",(i*3).to_string())
                ,KeyValue::new("num_mod3",(i%3).to_string())
            ]
        });
    }
    let mut sam=0.0;
    for i in range.clone(){
        sam+=data.field_num(i,"num");
        println!(
            "{},{},{},{}"
            ,data.serial(i)
            ,std::str::from_utf8(data.field_bytes(i,"num")).unwrap()
            ,std::str::from_utf8(data.field_bytes(i,"num_by3")).unwrap()
            ,std::str::from_utf8(data.field_bytes(i,"num_mod3")).unwrap()
        );
    }
    assert_eq!(sam,55.0);

    let r=data
        .search_field("num",search::Field::Range(b"3".to_vec(),b"8".to_vec()))
        .search_default()   //Automatic execution of the following two lines
        //.search_term(Term::In(SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs()))
        //.search_activity(Activity::Active)
        .result()
    ;
    println!("{:?}",r);

    let r=data
        .search_default()
        .search(Condition::Wide(vec![
            Condition::Field("num".to_string(),search::Field::Match(b"4".to_vec()))
            ,Condition::Field("num".to_string(),search::Field::Match(b"6".to_vec()))
        ]))
        .result()
    ;
    println!("Wide test:{:?}",r);

    let r=data
        .search_default() 
        .result_with_sort(vec![Order::Asc(OrderKey::Serial)])
    ;
    println!("sorted-serial:{:?}",r);

    let r=data
        .search_default() 
        .result_with_sort(vec![Order::Desc(OrderKey::Field("num".to_owned()))])   //natural order
    ;
    println!("sorted-num-desc:{:?}",r);

    let r=data
        .search_default() 
        .result_with_sort(vec![
            Order::Desc(OrderKey::Field("num_mod3".to_owned()))
        ])
    ;
    println!("sorted-mod3-desc:{:?}",r);

    let r=data
        .search_default() 
        .result_with_sort(vec![
            Order::Asc(OrderKey::Field("num_mod3".to_owned()))
            ,Order::Asc(OrderKey::Field("num".to_owned()))
        ])
    ;
    println!("sorted mod3-asc num-asc:{:?}",r);

    let r=data
        .search_default() 
        .result_with_sort(vec![
            Order::Asc(OrderKey::Field("num_mod3".to_owned()))
            ,Order::Desc(OrderKey::Field("num".to_owned()))
        ])
    ;
    println!("sorted mod3-asc num-desc:{:?}",r);

    let r=data
        .search_field("num",search::Field::Range(b"3".to_vec(),b"8".to_vec()))
        .search_row(search::Number::Range(4..=7))
        .search_default()
        .result()
    ;
    println!("{:?}",r);
    
    data.update_field(2,"hoge",b"HAHA").unwrap();
    data.update_field(4,"hoge",b"agaba").unwrap();
    data.update_field(5,"hoge",b"agababi").unwrap();
    data.update_field(1,"hoge",b"ageabe").unwrap();
    data.update_field(7,"hoge",b"ageee").unwrap();
    data.update_field(6,"hoge",b"bebebe").unwrap();
    let r=data
        .search_field("hoge",search::Field::Match(b"HAHA".to_vec()))
        .result()
    ;
    println!("match:{:?}",r);

    let r=data
        .search_field("hoge",search::Field::Forward("age".to_string()))
        .result()
    ;
    println!("forward:{:?}",r);

    let r=data
        .search_field("hoge",search::Field::Partial("eb".to_string()))
        .result()
    ;
    println!("partial:{:?}",r);

    let r=data
        .search_field("hoge",search::Field::Backward("be".to_string()))
        .result()
    ;
    println!("backward:{:?}",r);

    let r=data
        .begin_search()
        .result()
    ;
    println!("all:{:?}",r);
}

Dependencies

~1.3–2MB
~42K SLoC