Native DB is a high performance, distributed, and embedded key-value store for multi-platform applications (server, desktop, mobile). It provides a simple API to sync Rust types effortlessly and supports real-time subscriptions.
Key Features
Simple API
Native DB offers a straightforward API for ease of use, minimizing boilerplate code.
Multiple Indexes
Supports multiple indexes including primary, secondary, unique, non-unique, and optional indexes.
Serialization and Deserialization
Transparent serialization and deserialization using native_model .
Automatic Model Migration
Automatically handles model migrations, reducing manual effort.
Thread-Safe and ACID-Compliant
Provides thread-safe operations and fully ACID-compliant transactions powered by redb .
Real-Time Subscription
Supports real-time subscriptions with filters for insert
, update
, and delete
operations.
Rust Type Compatibility
Compatible with all Rust types including enum
, struct
, and tuple
.
Hot Snapshots
Allows creating hot snapshots of the database for backup or cloning purposes.
Installation
Add the following dependencies to your Cargo.toml
file:
[ dependencies ]
native_db = "0.6.1"
native_model = "0.4.14"
Note: native_db
requires native_model
to work.
Status
Native DB is under active development. The API is not stable yet and may change in the future.
Getting Started
With Tauri
Check out the example repository: native_db_tauri_vanilla .
Usual API
Models
Builder
Database
snapshot the database.
rw_transaction open a read-write transaction.
r_transaction open a read-only transaction.
get
scan
primary
all items.
start_with items with a primary key starting with a given value.
range items with a primary key in a given range.
secondary
all items with a given secondary key.
start_with items with a secondary key starting with a given value.
range items with a secondary key in a given range.
len
primary the number of items.
secondary the number of items with a given secondary key.
watch real-time subscriptions via std channel based or tokio channel based depending on the feature tokio
.
get
scan
primary
all items.
start_with items with a primary key starting with a given value.
range items with a primary key in a given range.
secondary
all items with a given secondary key.
start_with items with a secondary key starting with a given value.
range items with a secondary key in a given range.
Example
Here's a basic example of using Native DB:
use serde ::{ Deserialize , Serialize };
use native_db ::*;
use native_model ::{native_model, Model };
#[derive( Serialize , Deserialize , PartialEq , Debug )]
#[native_model(id = 1, version = 1)]
#[native_db]
struct Item {
#[primary_key]
id : u32 ,
#[secondary_key]
name : String ,
}
fn main () -> Result <(), db_type :: Error > {
let mut models = Models :: new ();
// Initialize the model
models . define ::< Item >()?;
// Create a database in memory
let mut db = Builder :: new (). create_in_memory (& models )?;
// Insert data (open a read-write transaction)
let rw = db . rw_transaction (). unwrap ();
rw . insert ( Item { id : 1 , name : "red" . to_string () })?;
rw . insert ( Item { id : 2 , name : "green" . to_string () })?;
rw . insert ( Item { id : 3 , name : "blue" . to_string () })?;
rw . commit ()?;
// Open a read-only transaction
let r = db . r_transaction ()?;
// Retrieve data with id=3
let retrieve_data : Item = r . get (). primary ( 3_ u32 )?. unwrap ();
println! ( "data id='3': {:?}" , retrieve_data );
// Iterate items with name starting with "red"
for item in r . scan (). secondary ::< Item >( ItemKey :: name )?. start_with ( "red" ) {
println! ( "data name= \" red \" : {:?}" , item );
}
// Remove data (open a read-write transaction)
let rw = db . rw_transaction ()?;
rw . remove ( retrieve_data )?;
rw . commit ()?;
Ok (())
}