{"id":21576116,"url":"https://github.com/pmagaz/reddb","last_synced_at":"2025-08-21T10:31:37.900Z","repository":{"id":54267860,"uuid":"207346181","full_name":"pmagaz/reddb","owner":"pmagaz","description":"Minimalistic Rust in-memory embedded database with persistance.","archived":false,"fork":false,"pushed_at":"2024-08-12T07:15:12.000Z","size":291,"stargazers_count":18,"open_issues_count":2,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-12-08T03:23:29.498Z","etag":null,"topics":["database","inserting-data","json","persistance","ron","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pmagaz.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE-MIT","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-09-09T15:48:20.000Z","updated_at":"2024-11-25T11:10:27.000Z","dependencies_parsed_at":"2022-08-13T10:31:01.752Z","dependency_job_id":null,"html_url":"https://github.com/pmagaz/reddb","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmagaz%2Freddb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmagaz%2Freddb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmagaz%2Freddb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmagaz%2Freddb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pmagaz","download_url":"https://codeload.github.com/pmagaz/reddb/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230507051,"owners_count":18236944,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database","inserting-data","json","persistance","ron","rust"],"created_at":"2024-11-24T12:15:30.729Z","updated_at":"2024-12-19T22:08:31.094Z","avatar_url":"https://github.com/pmagaz.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# RedDb\n\n[![Actions Status](https://github.com/pmagaz/reddb/workflows/build/badge.svg)](https://github.com/pmagaz/reddb/actions) [![Crates.io](https://img.shields.io/crates/v/reddb)](https://crates.io/crates/reddb)\n\n`RedDb` is an async, fast, lightweight and embedded in-memory document database with [persistance](#persistance) in different serde-compatible formats (ron and json at the moment and bindcode and cbor soon). RedDb uses [Tokio](https://github.com/tokio-rs/tokio) fort its easy to use async API for [inserting](#inserting-data), [finding](#finding-data), [updating](#updating-data) and [deleting](#deleting-data) data.\n\n## Quickstart\n\nAdd RedDb to your `Cargo.toml` specifing what serializer you want to use:\n\n```toml\n[dependencies.RedDb]\nversion = \"0.2.3\"\nfeatures = [\"ron_ser\"] # Ron serialization / deserialization\nfeatures = [\"json_ser\"] # Json serialization / deserialization\n\n```\n\n```rust\nuse reddb::{Document, RonDb};\n\n#[derive(Clone, Serialize, PartialEq, Deserialize)]\nstruct MyStruct {\n  foo: String,\n}\n\n#[tokio::main]\nasync fn main() -\u003e Result\u003c()\u003e {\n  // RedDb with RON persistance for MyStruct structs\n  let db = RonDb::new::\u003cMyStruct\u003e(\"my.db\").unwrap();\n  let my_struct = MyStruct {\n    foo: String::from(\"hello\")\n  };\n\n  // Insert data\n  let doc = db.insert_one(my_struct).await?;\n  // Find by id\n  let my_doc: Document\u003cMyStruct\u003e = db.find_one(\u0026doc._id).await?;\n  // Find all records equal to my_struct\n  let my_docs : Vec\u003cDocument\u003cMyStruct\u003e\u003e = db.find(\u0026my_struct).await?;\n  Ok(())\n}\n```\n\n## Why\n\nRedDb is the migration of a side project originally written in NodeJs that was designed to store objects in memory (with hd persistance) and do searchs on them.\n\n## When\n\nIf you are looking for a classic Key/Value storage you will find better options since RedDb is not a Key/Value (RedDb uses autogeneratd Uuids). You can store any kind of [data](#Data) since data will be handled as a [generic](#Data) but RedDb was designed to store Objects/Structs and peform basic search operations in those Structs. Said that, if you are looking for a lightweight and easy to use in-memory data store with [persistance](#persistance), RedDb could be a good choice!\n\n## API\n\n- [Data](#data)\n- [Peristantce](#persistance)\n- [Inserting data](#inserting-data)\n- [Finding data](#finding-data)\n- [Updating data](#updating-data)\n- [Deleting data](#deleting-data)\n\n### Data\n\nData is serialized and deserialized in different serde-compatible formats (json, ron, yaml) and wrapped into the Document struct as follows:\n\n```rust\npub struct Document\u003cT\u003e {\n  pub _id: Uuid,\n  pub data: T,\n  pub _st: Status,\n}\n```\n\nSince data field is a generic you can store any kind of data you want. As you will see on the API, Document\u0026lt;T\u003e is the default return type for most operations.\n\n### Persistance\n\nRedDb's persistence uses an append-only format (AOF) so all write operations (Insert, Update, Delete) are added to to the end of the database file. The database is automatically compacted in just one line per object/record everytime you start the database in your application.\n\nThe API provides bulk-like write operations (insert, update and delete) for vectors of data that are faster to persist due to hd sync operations. Use them instead iterate over the `*_one()` methods you'll see on the API.\n\n### Inserting Data\n\nInsert data is pretty straightforward. If you want to insert just one document use insert_one method:\n\n#### Insert one\n\n```rust\n#[derive(Clone, Serialize, PartialEq, Deserialize)]\nstruct MyStruct {\n  foo: String,\n}\n\nlet my_struct = MyStruct {\n  foo: String::from(\"hello\")\n};\n\nlet doc: Document\u003cTestStruct\u003e = store.insert_one(my_struct).await?;\nprintln!(\"{:?}\", doc._id);\n// 94d69737-4b2e-4985-aaa1-e28bbff2e6d0\n```\n\n#### Insert\n\nIf you want to insert a vector of data `insert()` is more suitable and faster to persists than iterate over `insert_one()` method due to the nature of the AOF persistance.\n\n```rust\nlet my_docs = vec![MyStruct {\n  foo: String::from(\"one\"),\n},\nMyStruct {\n  foo: String::from(\"two\"),\n}];\n\nlet docs: Vec\u003cDocument\u003cMyStruct\u003e\u003e = db.insert(my_docs).await?;\n```\n\n### Finding Data\n\nThere are two ways to find your data. By it's id or looking into the database what data matches your query.\n\n#### Find one\n\nPerforms a search by id.\n\n```rust\nlet my_struct = MyStruct {\n  foo: String::from(\"hello\")\n};\n\nlet inserted_doc = db.insert_one(my_struct).await?;\nlet doc: Document\u003cMyStruct\u003e = db.find_one(\u0026inserted_doc._id).await?;\n```\n\n#### Find\n\nLook into the database for data matching your query.\n\n```rust\nlet one = MyStruct {\n  foo: String::from(\"Hello\"),\n};\n\nlet two = MyStruct {\n  foo: String::from(\"Hello\"),\n};\n\nlet three = MyStruct {\n  foo: String::from(\"Bye\"),\n};\n\n\nlet many = vec![one.clone(), two.clone(), three.clone()];\nlet inserted_doc : Document\u003cMyStruct\u003e = db.insert(many).await?;\nlet docs: Vec\u003cDocument\u003cMyStruct\u003e\u003e = db.find(\u0026one).await?;\n```\n\n### Updating Data\n\nUpdate data is pretty straightforward. You can update data\n\n#### Update one\n\nUpdate one record, using it's id as search param.\n\n```rust\nlet my_struct = MyStruct {\n  foo: String::from(\"hello\")\n};\n\nlet new_value = MyStruct {\n  foo: String::from(\"bye\"),\n};\n\nlet inserted_doc = db.insert_one(my_struct).await?;\nlet updated: bool = db.update_one(\u0026inserted_doc._id, new_value)).await?;\n```\n\n#### Update\n\nYou can update all data in the databas that matches your query param. Update will return the number of updated documents.\n\n```rust\nlet search = MyStruct {\n  foo: String::from(\"hello\")\n};\n\nlet new_value = MyStruct {\n  foo: String::from(\"bye\"),\n};\n\nlet updated: usize = store.update(\u0026search, \u0026new_value).await?;\n```\n\n### Deleting Data\n\n#### Delete one\n\nDelete a record by it's id.\n\n```rust\nlet my_struct = MyStruct {\n  foo: String::from(\"hello\")\n};\n\nlet doc = db.insert_one(my_struct).await?;\nlet deleted : bool = db.delete_one(\u0026doc._id)).await?;\n```\n\n#### Delete\n\nLike in `update` method, this method will lookup into the database which data matches your query and then delete it.\n\n```rust\nlet search = MyStruct {\n  foo: String::from(\"hello\")\n};\n\nlet deleted = store.delete(\u0026search).await?;\nprintln!(\"{:?}\", updated);\n// 1\n```\n\n## License\n\nThis library is licensed under\n\n- MIT license\n  ([LICENSE-MIT](https://github.com/pmagaz/reddb/blob/master/LICENSE-MIT)\n  or\n  [opensource.org/licenses/MIT](https://opensource.org/licenses/MIT))\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpmagaz%2Freddb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpmagaz%2Freddb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpmagaz%2Freddb/lists"}