| Crates.io | grapple_db |
| lib.rs | grapple_db |
| version | 0.3.1 |
| created_at | 2025-06-03 17:31:27.883134+00 |
| updated_at | 2025-06-11 20:59:39.27206+00 |
| description | Library with clients for different databases with lightweight interface |
| homepage | |
| repository | https://github.com/grapple228/rust_grapple_db.git |
| max_upload_size | |
| id | 1699325 |
| size | 248,216 |
grapple_db is a library designed to simplify interactions with various databases. It offers a flexible architecture that allows you to select the database client you need and utilize it according to your requirements. The library can be easily integrated into your project using feature flags.
Defaults: []
To include grapple_db in your project, add it to your dependencies. For example:
# Example for Cargo.toml (Rust)
[dependencies]
grapple_db = { version = "0.2", features = ["scylla", "redis"] }
scylla = "1.2.0" # for scylla feature
Full code example for tuples can be found in /examples/redis_tuple.rs
Full code example for models can be found in /examples/redis_model.rs
// Default
let client = Client::default().await?;
// From url
let client = Client::from_url("redis://127.0.0.1:6379").await?;
// From config
use grapple_db::redis::pool::Config;
let cfg = Config::from_url("redis://127.0.0.1:6379");
let client = Client::connect(&cfg).await?;
Tuple
use grapple_db::redis::Client;
let id = "tuple_id".to_string();
let value = 3;
let tuple = (id, value);
Custom model
// Imports
use grapple_db::redis; // If have original redis-rs, then it not needed
use grapple_db::redis::{macros::FromRedisValue, RedisModel};
// Define struct
#[derive(Debug, Default, serde::Serialize, serde::Deserialize, FromRedisValue)]
pub struct Model {
a: i32,
b: i32,
}
// Implement trait
impl RedisModel for Model {
fn key(&self) -> redis::Result<String> {
// Key for model
Ok(format!("{}.{}", self.a, self.b))
}
}
Tuple
let value: Option<i32> = client.get(&key).await?;
Model
let key = model.key()?;
let value: Option<Model> = client.get(&key).await?;
Tuple
let tuple = (id, value);
client.set(&tuple).await?;
Custom Model
let model = Model::default();
client.set(&model).await?;
client.del(&key).await?;
Delete Batch
client.mdel(&keys).await?;
Set batch
client.mset(&models).await?;
Get batch
client.mget(&keys).await?;
let key = model.key()?;
let val = client.exists(&key).await?;
let val = client.rename(&key).await?;
// For not coveded methods use connection and operate over it
client.connection().await?
.client_setname::<_, String>("my_client_name".to_string()).await?;
Full code example can be found in /examples/scylla.rs
// With default configuring
let client = Client::default()
// With custom configuring
let con_params = ConnectionParams::default();
let client = Client::connect(&con_params).await?;
Any of the models could be used with the same client
use grapple_db::scylla::{
charybdis,
macros::charybdis_model,
types::{Text},
};
#[charybdis_model(
table_name = users,
partition_keys = [id],
clustering_keys = [],
global_secondary_indexes = [name],
local_secondary_indexes = [],
)]
#[derive(Debug, Clone, Default)]
pub struct User {
id: Uuid,
name: Option<Text>,
pwd: Option<Text>,
}
// Any find method that returns one entity
let query = User::find_<any>()
let result = client.get(query).await?;
let model = User::default();
client.insert(&model).await?;
let model = User::default();
client.update(&model).await?;
let model = User::default();
client.delete(&model).await?;
// Any find method that returns stream
let query = User::find_<any>()
let count = client.count(query).await?;
// Any find method that returns stream
let query = User::find_<any>()
let stream = client.stream(query).await?;
// Iterate as you want
// There are also available pagable stream
let per_page = 3;
let mut pagable_stream = PagableCharybdisStream::new(stream, per_page);
let mut entities_count = 0;
while let Some(entities) = pagable_stream.next_page().await {
for entity in entities {
// Do something with entity
println!("{:?}", entity);
}
entities_count += &entities.len();
}
let chunk_size = 300;
let entities: Vec<User> = vec![];
client.insert_many(&entities, chunk_size).await?;
client.update_many(&entities, chunk_size).await?;
client.delete_many(&entities, chunk_size).await?;
let queries = entities.iter().map(|u| User::find_by_id(u.id.clone())).collect::<Vec<_>>();
let got: Vec<User> = client.get_many(queries).await?;
I utilized the original benchmarks from the Carybdis ORM, which compared the Scylla Driver with its own performance, and incorporated code from my library. The time difference is minimal and using my library is easier for my use case.
You can check the performance difference by running:
cargo bench --features scylla --bench scylla_bench
Benchmark code available at /benches/scylla_bench.rs
Benchmark results available at /benches/scylla_bench.md
The scylla feature is built on top of the Charybdis ORM, which provides essential functionality for ScyllaDB interactions. For more details on its features and usage, you can find in repo: Git
Contributions are welcome! If you have suggestions for improvements or new features, feel free to open an issue or submit a pull request. I wrote this library for my own use, so it may not fit everyone's needs, but your input is appreciated!
This project is licensed under the MIT License. See the LICENSE file for details.