Expand description
§Database Change Listener
This Rust library provides an event-based mechanism to monitor changes in database tables or collections and notify backend services, eliminating the need for polling. It supports PostgreSQL and MongoDB, allowing developers to register listeners and receive real-time updates on specified tables, columns, or collections.
§Features
- Database-Agnostic: Designed to support multiple databases, starting with PostgreSQL and MongoDB.
- Event-Driven: Notifies backend services of table or collection changes via event-based channels.
- Customizable: Users can specify the database type, connection URL, table or collection name, and columns to monitor.
- Efficient: Eliminates the need for polling, reducing unnecessary database load.
- Automatic Pool Management: Handles connection pooling internally to ensure efficient resource usage.
§Installation
Add the following to your Cargo.toml
:
cargo add db-library
§Quick Start
Example for PostgreSQL:
use db_library::{config::DBListenerError, DBConfig, DBListener, EventType, PgNotify};\
#[tokio::main]
async fn main() -> Result<(), DBListenerError> {
let database_config = DBConfig::Postgres {
url, // Database connection URL
table_name, // Name of the table to monitor
columns, // List of specific columns to monitor for updates
table_identifier, // Unique identifier for the table
};
let events = vec![EventType::UPDATE, EventType::INSERT, EventType::DELETE]; // Events to monitor
let db_listener = DBListener::new(database_config, events).await?; // Create a new database listener
db_listener
.listen(|notification| async move {
// Print the raw notification
println!("Received notification: {:?}", notification);
// Attempt to deserialize the notification into the `PgNotify` struct
match serde_json::from_str::<PgNotify>(¬ification.to_string()) {
Ok(pg_notify) => {
println!("--> Payload received in channel");
println!("Parsed Payload: {:#?}", pg_notify);
}
Err(err) => {
epritnln!("Error deserializing notification: {:#?}", err);
}
}
})
.await?;
Ok(())
}
Example for MongoDB:
use db_library::{config::DBListenerError, DBConfig, DBListener, EventType, MongoNotify};
#[tokio::main]
async fn main() -> Result<(), DBListenerError> {
let database_config = DBConfig::MongoDB {
url, // Database connection URL
database, // Name of the database to monitor.
collection, // Name of the collection to monitor.
};
let events = vec![EventType::INSERT, EventType::UPDATE, EventType::DELETE]; // Events to monitor
let db_listener = DBListener::new(database_config, events).await?; // Create a new database listener
db_listener
.listen(|notification| async move {
// Print the raw notification
println!("Received notification: {:?}", notification);
// Attempt to deserialize the notification into the `MongoNotify` struct
match serde_json::from_str::<MongoNotify>(¬ification.to_string()) {
Ok(mongo_notify) => {
println!("--> Payload received in channel");
println!("Parsed Payload: {:#?}", mongo_notify);
}
Err(err) => {
eprintln!("Error deserializing notification: {:#?}", err);
}
}
})
.await?; // <-- Ensuring `.await?` is correctly placed
Ok(())
}
§Supported Databases
- PostgreSQL
- MongoDB
§Configuration
Users can specify the database type, connection URL, table name or collection name, and columns when initializing a listener instance. The library provides a flexible configuration to accommodate various use cases.
§Use Cases
- Real-time Data Synchronization: Keep your application data in sync with database changes.
- Event-Driven Microservices: Build microservices that react to database events.
- Change Tracking for Analytics: Monitor changes for analytics and reporting purposes.
Re-exports§
pub use config::DBListenerError;
pub use database::mongodb::MongoNotify;
pub use database::postgres::PgNotify;
pub use database::DBConfig;
pub use database::DBListener;
pub use database::EventType;