Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/milen-denev/rs_aio_db
All in one (aka Aio) database with async support. Based on libsql/Sqlite, bevy_reflect and tokio, includes a dead simple API to be used (no SQL needed just pure Rust). Comes with automigration.
https://github.com/milen-denev/rs_aio_db
Last synced: 2 months ago
JSON representation
All in one (aka Aio) database with async support. Based on libsql/Sqlite, bevy_reflect and tokio, includes a dead simple API to be used (no SQL needed just pure Rust). Comes with automigration.
- Host: GitHub
- URL: https://github.com/milen-denev/rs_aio_db
- Owner: milen-denev
- Created: 2024-03-29T23:09:44.000Z (10 months ago)
- Default Branch: master
- Last Pushed: 2024-11-03T13:56:09.000Z (3 months ago)
- Last Synced: 2024-11-03T14:05:28.548Z (3 months ago)
- Language: Rust
- Homepage:
- Size: 398 KB
- Stars: 17
- Watchers: 1
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
Awesome Lists containing this project
README
# Aio Database
## All in one database with dead simple API## Note:
libsql edition: 0.7.x
rusqlite edition: 0.8.x## Features
- Auto migration: If additional or fewer fields are introduced to a structure, it immediately updates the database schema.
- Local or In-Memory Capability: All functionality operates within local storage or in-memory systems.
- Fully implemented CRUD functionality
- Highly Performant: Offers very good performance, by doing some preliminary tests it seems that the overhead from both main libraries that I use (rusqlite and bevy_reflect) plus the overhead from my library is small enough to be unnoticeable, reading 1000 rows one by one took 28ms.
- Async Support with Tokio
- Highly Concurrent due to the internal connection pooling
- ORM-like API that is dead simple to use
- Use anywhere
- Support for `bool`, `u8`, `u16`, `u32`, `u64`, `i8`, `i16`, `i32`, `i64`, `char`, `String` and `Vec` Rust types
- Support for creating and dropping unique indexes## Production Readiness
This is already used in production in affiliated company for specific use-case. Although any known issues are fixed, use this in production at your own risk.
## Planned Features
- Use of Moka cache for bypassing the local storage and increase performance.
- Additional Query options.## Build issue on Windows Machine
### Reason:
The reason this occurs is because in the build.rs script the developers of rusqlite have put the Linux cp command for copying, which is not available on windows.### Fix:
I created my own copycat of cp, [rust_cp](https://github.com/milen-denev/rust_cp). The repository has compiled binary, put this in any location you want on your windows system, and add Path environment variable, restart the system, and it should work.## Examples
### cargo.toml
```TOML
[dependencies]
rs_aio_db = "0.7.11"
env_logger = "0.11"
tokio = "1"
bevy_reflect = "0.14"
serde = "1.0"
```### main.rs
```rust
use rs_aio_db::db::aio_query::{Next, Operator, QueryBuilder};
use rs_aio_db::db::aio_database::AioDatabase;
use rs_aio_db::Reflect;#[derive(Default, Clone, Debug, Reflect)]
pub struct Person {
pub name: String,
pub age: i32,
pub height: i32,
pub married: bool,
pub some_blob: Vec
}#[derive(Serialize, Deserialize)]
struct AnotherStruct {
pub data_1: i32,
pub data_2: f64,
pub data_3: HashMap
}#[tokio::main]
async fn main() {
std::env::set_var("RUST_LOG", "debug");
env_logger::init();//Locally persisted database
let file_db = AioDatabase::create::("G:\\".into(), "Test".into()).await;//In-Memory database
let in_memory_db = AioDatabase::create_in_memory::("Test".into()).await;let mut hash_map = HashMap::new();
hash_map.insert("Key1".into(), "Value1".into());//Use AioDatabase::get_struct to get back your struct data type
file_db.insert_value(&Person {
name: "Mylo".into(),
age: 0,
height: 0,
married: true,
some_blob: AioDatabase::get_bytes(AnotherStruct {
data_1: 5,
data_2: 10.4,
data_3: hash_map.clone()
})
}).await;let get_single_record = file_db
.query()
.field("age")
.where_is(Operator::Gt(5.to_string()), Some(Next::Or))
.field("name")
.where_is(Operator::Eq("Mylo".into()), None)
.get_single_value::()
.await
.unwrap_or_default();println!("Record result: {:?}", get_single_record);
let get_records = file_db
.query()
.field("age")
.where_is(Operator::Gt(5.to_string()), Some(Next::Or))
.field("name")
.where_is(Operator::Eq("Mylo".into()), None)
.get_many_values::().await;println!("Record results: {:?}", get_records);
let update_rows = file_db
.query()
.field("age")
.where_is(Operator::Eq((0).to_string()), Some(Next::Or))
.update_value(Person {
name: "Mylo".into(),
age: 5,
height: 5,
married: false,
some_blob: AioDatabase::get_bytes(AnotherStruct {
data_1: 5,
data_2: 10.4,
data_3: hash_map.clone()
})
}).await;println!("Updated rows: {:?}", update_rows);
let partial_update_rows = file_db
.query()
.field("age")
.where_is(Operator::Eq((0).to_string()), Some(Next::Or))
.partial_update::("height".into(), "50".into()).await;println!("Updated rows: {:?}", partial_update_rows);
let delete_rows = file_db
.query()
.field("name")
.where_is(Operator::Eq("Mylo".into()), None)
.delete_value::().await;let contains = file_db
.query()
.field("name")
.where_is(Operator::Contains("Mylo".into()), None)
.get_single_value::()
.await
.unwrap_or_default();println!("Contains: {:?}", contains);
let starts_with = file_db
.query()
.field("name")
.where_is(Operator::StartsWith("Mylo".into()), None)
.get_single_value::()
.await
.unwrap_or_default();println!("Starts with: {:?}", starts_with);
let starts_with = file_db
.query()
.field("name")
.where_is(Operator::EndsWith("Mylo".into()), None)
.get_single_value::()
.await
.unwrap_or_default();println!("Ends with: {:?}", starts_with);
_ = file_db.create_unique_index::("name_unique", vec!["name".into()]).await;
_ = file_db.drop_index("name_unique").await;
}
```