Native, high-performance Rust client for AxiomDB with type-safe schema-generated models and real-time reactive collections.
- Split Connection Topology: Separates high-throughput runtime queries (PgBouncer port
6432) from long-lived event listeners (direct port5432). - Real-Time Collections: Table-level change notification pipeline using PostgreSQL
LISTEN/NOTIFY(channel:axiomdb_changes). - Coercion-Free Queries: Leverages PostgreSQL's
json_populate_recordfor insert/update operations, ensuring automatic schema-level type casting. - Robust Auto-Reconnection: Built-in automatic recovery on database drop or transient network failure for active streams.
Add this to your Cargo.toml:
[dependencies]
axiomdb = "0.1.0"
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }AxiomDB requires separate pooled connection strings for queries and direct connection strings for the change listener:
use axiomdb::{Client, Config};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = Config {
database_url: "postgresql://user:pass@db.squareexp.com:6432/sq_my_app?sslmode=require".to_string(),
direct_url: "postgresql://user:pass@db.squareexp.com:5432/sq_my_app?sslmode=require".to_string(),
};
let client = Client::connect(config).await?;
println!("Successfully connected to AxiomDB!");
Ok(())
}Create Rust models mapped to your database schema, deriving sqlx::FromRow and serde::Serialize:
use serde::{Serialize, Deserialize};
use sqlx::FromRow;
#[derive(Clone, Debug, FromRow, Serialize, Deserialize)]
pub struct Project {
pub id: uuid::Uuid,
pub name: String,
pub status: String,
pub created_at: chrono::DateTime<chrono::Utc>,
}AxiomDB provides type-safe Collection<T> structures wrapping table specs:
use axiomdb::{Collection, ModelSpec};
let project_spec = ModelSpec {
table: "projects",
id_column: "id",
};
let projects: Collection<Project> = Collection::new(client.clone(), project_spec);
// 1. Find all rows
let all_projects = projects.find_many().await?;
// 2. Find row by primary key
let project = projects.find_by_id(uuid).await?;Insert and updates take any type implementing serde::Serialize (e.g. partial schemas via JSON or custom maps):
use serde_json::json;
// Create (Insert)
let new_project = projects.create(json!({
"name": "Beta Release",
"status": "active"
})).await?;
// Partial Update
let updated_project = projects.update(
new_project.id,
json!({ "status": "archived" })
).await?;
// Delete
projects.delete(new_project.id).await?;AxiomDB collections support live watch() streams that instantly yield fresh datasets whenever the table changes:
use futures::StreamExt;
let mut stream = projects.watch();
while let Some(result) = stream.next().await {
match result {
Ok(current_dataset) => {
println!("Dataset updated: {:#?}", current_dataset);
}
Err(e) => {
eprintln!("Error in watch stream: {}", e);
}
}
}This project is licensed under the MIT License.