| Crates.io | ekodb_client |
| lib.rs | ekodb_client |
| version | 0.8.0 |
| created_at | 2025-10-14 04:44:11.690507+00 |
| updated_at | 2026-01-06 20:34:46.353204+00 |
| description | Official Rust client library for ekoDB - A high-performance database |
| homepage | |
| repository | https://github.com/ekoDB/ekodb |
| max_upload_size | |
| id | 1881666 |
| size | 420,286 |
Official Rust client library for ekoDB - A high-performance database with intelligent caching, real-time capabilities, AI integration, and automatic optimization.
Add this to your Cargo.toml:
[dependencies]
ekodb_client = "0.1"
tokio = { version = "1", features = ["full"] }
use ekodb_client::{Client, QueryBuilder, Record};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create a client (automatically handles authentication)
let client = Client::builder()
.base_url("http://localhost:8080")
.api_key("your-api-key")
.build()?;
// Insert a record
let mut record = Record::new();
record.insert("name", "John Doe");
record.insert("age", 30);
record.insert("email", "john@example.com");
let result = client.insert("users", record).await?;
println!("Inserted: {:?}", result);
// Query with the builder
let query = QueryBuilder::new()
.gte("age", 18)
.eq("status", "active")
.limit(10)
.build();
let users = client.find("users", query).await?;
println!("Found {} users", users.len());
Ok(())
}
You can configure the client using environment variables:
export API_BASE_URL="http://localhost:8080"
export API_BASE_KEY="your-api-key"
# Run example
cargo run -p ekodb_client --example simple_crud
use std::env;
let client = Client::builder()
.base_url(env::var("API_BASE_URL")?)
.api_key(env::var("API_BASE_KEY")?)
.timeout(Duration::from_secs(30))
.max_retries(3)
.build()?;
use ekodb_client::{Client, FieldType, Record};
// Insert
let mut user = Record::new();
user.insert("name", "Alice");
user.insert("age", 25);
let inserted = client.insert("users", user).await?;
// Extract ID from response
let user_id = if let Some(FieldType::String(id)) = inserted.get("id") {
id.clone()
} else {
return Err("No ID returned".into());
};
// Find by ID
let user = client.find_by_id("users", &user_id).await?;
// Update
let mut updates = Record::new();
updates.insert("age", 26);
let updated = client.update("users", &user_id, updates).await?;
// Delete
client.delete("users", &user_id).await?;
use ekodb_client::QueryBuilder;
use serde_json::json;
// Simple queries
let query = QueryBuilder::new()
.eq("status", "active")
.gte("age", 18)
.lt("age", 65)
.build();
let results = client.find("users", query).await?;
// Complex queries with sorting and pagination
let query = QueryBuilder::new()
.in_array("status", vec![json!("active"), json!("pending")])
.regex("email", r".*@example\.com$")
.sort_desc("created_at")
.limit(20)
.skip(0)
.build();
let results = client.find("users", query).await?;
use ekodb_client::BatchBuilder;
// Create records for batch insert
let mut user1 = Record::new();
user1.insert("name", "Alice");
user1.insert("email", "alice@example.com");
let mut user2 = Record::new();
user2.insert("name", "Bob");
user2.insert("email", "bob@example.com");
// Build and execute batch
let batch = BatchBuilder::new()
.insert("users", user1)
.insert("users", user2)
.build();
let results = client.batch_insert("users", &batch.operations).await?;
println!("Batch completed: {} successful, {} failed",
results.successful.len(), results.failed.len());
// Connect to WebSocket
let ws_client = client.websocket("ws://localhost:8080/ws").await?;
// Query via WebSocket
let results = ws_client.find_all("users").await?;
println!("Found {} users via WebSocket", results.len());
// Query with filters using ekoDB format
let query = QueryBuilder::new()
.eq("status", "active")
.build();
let active_users = ws_client.find("users", query).await?;
// Insert with 1 hour TTL
let record = Record::new()
.with("name", "Session Data")
.with("token", "abc123");
client.insert_with_ttl("sessions", record, "1h").await?;
// Insert with 5 minutes TTL
client.insert_with_ttl("cache", data, "5m").await?;
// Supported TTL formats: "30s", "5m", "1h", "2d"
// Set a key-value pair
client.kv_set("session:user123", json!({
"userId": 123,
"username": "john_doe"
})).await?;
// Get a value
let session = client.kv_get("session:user123").await?;
// Delete a key
client.kv_delete("session:user123").await?;
// Set with TTL
client.kv_set_with_ttl("cache:product:1", product_data, "1h").await?;
use ekodb_client::SearchQuery;
// Basic text search
let search = SearchQuery::new("programming")
.min_score(0.1)
.limit(10);
let results = client.search("articles", search).await?;
for result in results.results {
println!("Score: {:.4} - {:?}", result.score, result.record.get("title"));
}
// Search with field weights
let search = SearchQuery::new("rust database")
.fields(vec!["title".to_string(), "description".to_string()])
.weights(vec![("title".to_string(), 2.0)].into_iter().collect())
.limit(5);
let results = client.search("articles", search).await?;
use ekodb_client::{ChatMessageRequest, CollectionConfig, CreateChatSessionRequest};
// Create a chat session
let session_request = CreateChatSessionRequest {
collections: vec![CollectionConfig {
collection_name: "documentation".to_string(),
fields: vec![],
search_options: None,
}],
llm_provider: "openai".to_string(),
llm_model: Some("gpt-4".to_string()),
system_prompt: Some("You are a helpful assistant.".to_string()),
parent_id: None,
branch_point_idx: None,
max_context_messages: Some(10),
bypass_ripple: Some(false),
};
let session = client.create_chat_session(session_request).await?;
// Send a message
let message = ChatMessageRequest::new("What is ekoDB?");
let response = client.chat_message(&session.chat_id, message).await?;
println!("AI Response: {}", response.responses[0]);
println!("Context snippets: {}", response.context_snippets.len());
use ekodb_client::{FieldTypeSchema, Schema};
// Create a collection with schema
let schema = Schema::new()
.add_field("title", FieldTypeSchema::new("String").required())
.add_field("email", FieldTypeSchema::new("String").required())
.add_field("age", FieldTypeSchema::new("Integer"))
.add_field("status", FieldTypeSchema::new("String"));
client.create_collection("users", schema).await?;
// Get schema
let schema = client.get_schema("users").await?;
for (name, field) in &schema.fields {
println!("Field: {} - Type: {}", name, field.field_type);
}
// List all collections
let collections = client.list_collections().await?;
println!("Collections: {:?}", collections);
// Count documents in a collection
let count = client.count("users").await?;
println!("Total users: {}", count);
// Check if collection exists
let exists = client.collection_exists("users").await?;
// Delete a collection
client.delete_collection("old_data").await?;
use ekodb_client::Error;
match client.insert("users", record).await {
Ok(result) => println!("Success: {:?}", result),
Err(Error::RateLimit { retry_after_secs }) => {
println!("Rate limited. Retry after {} seconds", retry_after_secs);
}
Err(Error::Auth(msg)) => {
println!("Authentication failed: {}", msg);
}
Err(Error::NotFound) => {
println!("Record not found");
}
Err(e) => {
println!("Error: {}", e);
}
}
ekoDB supports the following data types:
String - Text dataInteger - 64-bit signed integersFloat - 64-bit floating point numbersNumber - Flexible numeric type (Integer, Float, or Decimal)Boolean - True/false valuesDecimal - High-precision decimal numbers for financial calculationsNull - Explicit null valuesDateTime - ISO-8601 formatted timestampsDuration - Time durations (e.g., "30s", "5m", "1h")UUID - Universally unique identifiers (auto-validated)Object - Nested structures (HashMap)Array - Ordered collectionsSet - Unordered collections (automatically deduplicated by server)Vector - Vector embeddings for similarity searchBinary - Binary data (base64 encoded)Bytes - Raw byte arraysThe library includes 13 comprehensive examples demonstrating all features:
# Set environment variables
export API_BASE_URL="http://localhost:8080"
export API_BASE_KEY="your-api-key"
# Run individual examples
cargo run --example client_simple_crud
cargo run --example client_batch_operations
cargo run --example client_kv_operations
cargo run --example client_collection_management
cargo run --example client_document_ttl
cargo run --example client_simple_websocket
cargo run --example client_websocket_ttl
cargo run --example client_query_builder
cargo run --example client_search
cargo run --example client_schema_management
cargo run --example client_chat_basic
cargo run --example client_chat_sessions
cargo run --example client_chat_advanced
All examples are located in examples/rust/examples/ directory.
insert(collection, record) - Insert a documentinsert_with_ttl(collection, record, ttl) - Insert with expirationfind_by_id(collection, id) - Find document by IDfind(collection, query) - Query documents with filtersfind_all(collection) - Get all documents in collectionupdate(collection, id, updates) - Update a documentdelete(collection, id) - Delete a documentbatch_insert(collection, records) - Bulk insert documentsbatch_update(collection, updates) - Bulk update documentsbatch_delete(collection, ids) - Bulk delete documentsQueryBuilder::new() - Create a new query builder.eq(field, value) - Equal to.ne(field, value) - Not equal to.gt(field, value) - Greater than.gte(field, value) - Greater than or equal.lt(field, value) - Less than.lte(field, value) - Less than or equal.in_array(field, values) - In array.nin(field, values) - Not in array.regex(field, pattern) - Regex match.sort_asc(field) / .sort_desc(field) - Sorting.limit(n) / .skip(n) - Pagination.build() - Build the querysearch(collection, search_query) - Full-text searchSearchQuery::new(query) - Create search query.fields(fields) - Specify fields to search.weights(weights) - Field weights for scoring.min_score(score) - Minimum relevance score.limit(n) - Maximum resultscreate_chat_session(request) - Create a new chat sessionchat_message(chat_id, message) - Send a chat messageget_chat_messages(chat_id, query) - Get message historylist_chat_sessions(query) - List all chat sessionsupdate_chat_session(chat_id, request) - Update session configurationdelete_chat_session(chat_id) - Delete a chat sessioncreate_collection(collection, schema) - Create collection with schemaget_schema(collection) - Get collection schemaupdate_schema(collection, schema) - Update collection schemaSchema::new() - Create a new schema.add_field(name, field_type) - Add field to schemaFieldTypeSchema::new(type) - Create field type.required() - Mark field as requiredkv_set(key, value) - Set a key-value pairkv_set_with_ttl(key, value, ttl) - Set with expirationkv_get(key) - Get value by keykv_delete(key) - Delete a keylist_collections() - List all collectionscount(collection) - Count documents in collectioncollection_exists(collection) - Check if collection existsdelete_collection(collection) - Delete entire collectionwebsocket(url) - Connect to WebSocket endpointws_client.find(collection, query) - Query via WebSocketws_client.find_all(collection) - Get all via WebSocket// Create one client instance and reuse it
let client = Client::builder()
.base_url(&base_url)
.api_key(&api_key)
.timeout(Duration::from_secs(30))
.max_retries(3)
.build()?;
// The client is thread-safe and can be cloned cheaply
let client_clone = client.clone();
use ekodb_client::Error;
match client.insert("users", record).await {
Ok(result) => {
// Handle success
}
Err(Error::RateLimit { retry_after_secs }) => {
// Wait and retry
tokio::time::sleep(Duration::from_secs(retry_after_secs)).await;
}
Err(Error::Auth(msg)) => {
// Handle authentication error
}
Err(e) => {
// Handle other errors
}
}
.limit() and .skip() to
paginateAll client examples follow a cleanup convention to prevent test pollution:
// At the end of your example/test
println!("\n=== Cleanup ===");
client.delete_collection(collection).await?;
println!("✓ Deleted collection");
If you see authentication errors:
If requests are timing out:
.timeout(Duration::from_secs(60))The client automatically retries on rate limits (429), but you can also handle them manually:
if let Err(Error::RateLimit { retry_after_secs }) = result {
tokio::time::sleep(Duration::from_secs(retry_after_secs)).await;
// Retry the operation
}
This project is licensed under either of:
at your option.
Contributions are welcome! Please feel free to submit a Pull Request.