Expand description
Embedded file-based JSON database engine using memory-mapped files.
§sqjson
sqjson is a lightweight, embedded, file-based key-value database written in Rust.
It stores structured data as JSON values and uses memory-mapped I/O for efficient read/write access.
Inspired by SQLite, but minimal and JSON-native, with an emphasis on simplicity and portability.
§Features
- Embedded, single-file storage (
.dbfile) - Efficient memory-mapped I/O for fast reads/writes
- JSON value storage using
serde_json - String-keyed key-value API:
put,get,delete,flush - Field-level access:
get_field(key, field) - Secondary indexes for fast field-based queries:
query(field, value) - Range queries for numeric or string fields:
range_query(field, min, max) - Update specific field without replacing the full record:
update_field(key, field, value) - Text search on string fields:
search_contains(field, substring) - Filter records using a custom predicate:
filter(|val| ...) - Pagination for queries:
query_page(field, value, limit, offset) - Export query results to a JSON file:
export_query(field, value, path) - Export full database:
export_to_file(path) - Compact database to reclaim space (like SQLite VACUUM):
compact() - Atomic transactions:
begin_transaction(),commit(),rollback(),in_transaction() - Show all stored records
§Examples
§Open or Create a Database
use sqjson::{YourDb, DbError};
use serde_json::json;
fn main() -> Result<(), DbError> {
let mut db = YourDb::open("jsondb.db")?;
// Insert JSON records
db.put("user:1", &json!({ "name": "Alice", "age": 30, "city": "NY" }))?;
db.put("user:2", &json!({ "name": "Bob", "age": 25, "city": "LA" }))?;
// Flush to disk
db.flush()?;
Ok(())
}§Query by Field
let db = YourDb::open("jsondb.db")?;
let users_age_30 = db.query("age", 30)?;
println!("Users with age 30: {:?}", users_age_30);
let users_city_ny = db.query("city", "NY")?;
println!("Users in NY: {:?}", users_city_ny);§Range Query
let db = YourDb::open("jsondb.db")?;
let age_range = db.range_query("age", json!(20), json!(30))?;
println!("Users age 20–30: {:?}", age_range);§Update a Single Field
let mut db = YourDb::open("jsondb.db")?;
db.update_field("user:2", "city", json!("SF"))?;§Search by Substring
let db = YourDb::open("jsondb.db")?;
let results = db.search_contains("name", "li")?;
println!("Users with 'li' in name: {:?}", results);§Export
let mut db = YourDb::open("jsondb.db")?;
db.export_to_file("backup.json")?;§Transactions
Group several writes so they either all land or none do. Reads inside the transaction
see its own uncommitted changes; rollback() discards them entirely.
let mut db = YourDb::open("jsondb.db")?;
db.begin_transaction()?;
db.put("user:1", &json!({ "name": "Ali" }))?;
db.put("user:2", &json!({ "name": "Ahmed" }))?;
// Reads inside the transaction observe the staged writes.
assert_eq!(db.get("user:1")?, Some(json!({ "name": "Ali" })));
if db.in_transaction() {
db.commit()?; // or db.rollback()? to discard everything above
}Nested transactions are not supported: a second begin_transaction() returns an error.
flush() and compact() are refused while a transaction is active, since both would
make uncommitted state durable.
§Compact Database
let mut db = YourDb::open("jsondb.db")?;
db.compact()?; // Reclaim space after deletesStructs§
- YourDb
- Small file-backed key/value JSON DB with optional secondary indexes.