19 unstable releases (3 breaking)

0.4.6 Dec 18, 2023
0.4.4 Nov 22, 2023
0.3.13 Jul 17, 2023

#70 in Database implementations

Download history 1/week @ 2024-09-20 29/week @ 2024-09-27 3/week @ 2024-10-04 3/week @ 2024-10-11

120 downloads per month

MIT license

81KB
1K SLoC

Important Update: This crate struct_db has been renamed to native_db to better reflect its functionality and purpose. Please update your dependencies to use native_db for the latest features and updates.

Struct DB 🔧🔩

Crates.io Linux/Windows/macOS/Android/iOS (Build/Test/Release) Documentation License

All Contributors

Provides a drop-in, fast, and embedded database solution based on redb, focusing on maintaining coherence between Rust types and stored data with minimal boilerplate. It supports multiple indexes, real-time watch with filters, schema migration, enjoy 😌🍃.

Features

  • Almost as fast as the storage engine redb.
  • Embedded database (Linux, macOS, Windows, Android, iOS).
  • Support multiple indexes (unique secondary keys).
  • Compatible with all Rust types (enum, struct, tuple etc.).
  • Query data (get, watch, iter etc.) using explicit type or type inference.
  • Real-time subscription with filters for insert, update and delete operations.
  • Schema migration using native Rust coercion.
  • Fully ACID-compliant transactions.
  • Add your own serialization/deserialization logic planned* (e.g: zero-copy).
  • Thread-safe.

Status

Early development. Not ready for production. Follow the roadmap for the 1.0 release.

How to use?

See docs.rs.

Example

use serde::{Deserialize, Serialize};
use struct_db::*;

#[derive(Serialize, Deserialize, PartialEq, Debug)]
#[struct_db(
    fn_primary_key(p_key),  // required
    fn_secondary_key(s_key),  // optional
    // ... other fn_secondary_key ...
)]
struct Data(u32, String);

impl Data {
  // Returns primary key as big-endian bytes for consistent lexicographical ordering.
  pub fn p_key(&self) -> Vec<u8> {
    self.0.to_be_bytes().to_vec()
  }

  // Generates a secondary key combining the String field and the big-endian bytes of
  // the primary key for versatile queries.
  pub fn s_key(&self) -> Vec<u8> {
    let mut s_key = self.1.as_bytes().to_vec();
    s_key.extend_from_slice(&self.p_key().as_slice());
    s_key
  }
 }

 fn main() {
  let mut db = Db::init_tmp("my_db_example").unwrap();
  // Initialize the schema
  db.define::<Data>();

  // Insert data
  let txn = db.transaction().unwrap();
  {
    let mut tables = txn.tables();
    tables.insert(&txn, Data(1,"red".to_string())).unwrap();
    tables.insert(&txn, Data(2,"red".to_string())).unwrap();
    tables.insert(&txn, Data(3,"blue".to_string())).unwrap();
  }
  txn.commit().unwrap();
   
  let txn_read = db.read_transaction().unwrap();
  let mut tables = txn_read.tables();
   
  // Retrieve data with p_key=3 
  let retrieve_data: Data = tables.primary_get(&txn_read, &3_u32.to_be_bytes()).unwrap().unwrap();
  println!("data p_key='3' : {:?}", retrieve_data);
   
  // Iterate data with s_key="red" String
  for item in tables.secondary_iter_start_with::<Data>(&txn_read, DataKey::s_key, "red".as_bytes()).unwrap() {
    println!("data s_key='1': {:?}", item);
  }
   
  // Remove data
  let txn = db.transaction().unwrap();
  {
    let mut tables = txn.tables();
    tables.remove(&txn, retrieve_data).unwrap();
  }
  txn.commit().unwrap();
 }

Roadmap

The following features are planned before the 1.0 release

  • Add benchmarks tests.
  • Add documentation.
  • Stable release of redb or implement another stable storage engine(s) for Linux, macOS, Windows, Android, iOS.
  • Add support for custom serialization/deserialization logic.
  • Add CI for Linux, macOS, Windows, Android, iOS.
  • Use in a real-world project.

Contributors

Akshith Madhur
Akshith Madhur

💻

Dependencies

~1.4–8.5MB
~82K SLoC