db_library/
lib.rs

1//! # Database Change Listener
2//!
3//! This Rust library provides an event-based mechanism to monitor changes in database tables or collections
4//! and notify backend services, eliminating the need for polling. It supports PostgreSQL and MongoDB,
5//! allowing developers to register listeners and receive real-time updates on specified tables, columns, or collections.
6//!
7//! ## Features
8//! - **Database-Agnostic:** Designed to support multiple databases, starting with PostgreSQL and MongoDB.
9//! - **Event-Driven:** Notifies backend services of table or collection changes via event-based channels.
10//! - **Customizable:** Users can specify the database type, connection URL, table or collection name, and columns to monitor.
11//! - **Efficient:** Eliminates the need for polling, reducing unnecessary database load.
12//! - **Automatic Pool Management:** Handles connection pooling internally to ensure efficient resource usage.
13//!
14//! ## Installation
15//! Add the following to your `Cargo.toml`:
16//! ```bash
17//!    cargo add db-library
18//! ```
19//!
20//! ## Quick Start
21//!
22//! Example for PostgreSQL:
23//!
24//! ```rust
25//! use db_library::{config::DBListenerError, DBConfig, DBListener, EventType, PgNotify};\
26//!
27//! #[tokio::main]
28//! async fn main() -> Result<(), DBListenerError> {
29//!     let database_config = DBConfig::Postgres {
30//!         url, // Database connection URL
31//!         table_name, // Name of the table to monitor
32//!         columns, // List of specific columns to monitor for updates
33//!         table_identifier, // Unique identifier for the table
34//!     };
35//!
36//!     let events = vec![EventType::UPDATE, EventType::INSERT, EventType::DELETE]; // Events to monitor
37//!
38//!     let db_listener = DBListener::new(database_config, events).await?; // Create a new database listener
39//!
40//!     db_listener
41//!         .listen(|notification| async move {
42//!             // Print the raw notification
43//!             println!("Received notification: {:?}", notification);
44//!
45//!             // Attempt to deserialize the notification into the `PgNotify` struct
46//!             match serde_json::from_str::<PgNotify>(&notification.to_string()) {
47//!                 Ok(pg_notify) => {
48//!                     println!("--> Payload received in channel");
49//!                     println!("Parsed Payload: {:#?}", pg_notify);
50//!                 }
51//!                 Err(err) => {
52//!                     epritnln!("Error deserializing notification: {:#?}", err);
53//!                 }
54//!             }
55//!         })
56//!         .await?;
57//!
58//!     Ok(())
59//! }
60//! ```
61//!
62//! Example for MongoDB:
63//!
64//! ```rust
65//! use db_library::{config::DBListenerError, DBConfig, DBListener, EventType, MongoNotify};
66//!
67//! #[tokio::main]
68//! async fn main() -> Result<(), DBListenerError> {
69//!     let database_config = DBConfig::MongoDB {
70//!         url, // Database connection URL
71//!         database, // Name of the database to monitor.
72//!         collection, // Name of the collection to monitor.
73//!     };
74//!
75//!     let events = vec![EventType::INSERT, EventType::UPDATE, EventType::DELETE]; // Events to monitor
76//!
77//!     let db_listener = DBListener::new(database_config, events).await?; // Create a new database listener
78//!
79//!     db_listener
80//!         .listen(|notification| async move {
81//!             // Print the raw notification
82//!             println!("Received notification: {:?}", notification);
83//!
84//!             // Attempt to deserialize the notification into the `MongoNotify` struct
85//!             match serde_json::from_str::<MongoNotify>(&notification.to_string()) {
86//!                 Ok(mongo_notify) => {
87//!                     println!("--> Payload received in channel");
88//!                     println!("Parsed Payload: {:#?}", mongo_notify);
89//!                 }
90//!                 Err(err) => {
91//!                     eprintln!("Error deserializing notification: {:#?}", err);
92//!                 }
93//!             }
94//!         })
95//!         .await?; // <-- Ensuring `.await?` is correctly placed
96//!
97//!     Ok(())
98//! }
99//! ```
100//!
101//! ## Supported Databases
102//! - **PostgreSQL**
103//! - **MongoDB**
104//!
105//! ## Configuration
106//! Users can specify the database type, connection URL, table name or collection name, and columns when initializing
107//! a listener instance. The library provides a flexible configuration to accommodate various use cases.
108//!
109//! ## Use Cases
110//! - **Real-time Data Synchronization:** Keep your application data in sync with database changes.
111//! - **Event-Driven Microservices:** Build microservices that react to database events.
112//! - **Change Tracking for Analytics:** Monitor changes for analytics and reporting purposes.
113
114pub mod config;
115pub mod database;
116pub mod utils;
117
118pub use config::DBListenerError;
119pub use database::mongodb::MongoNotify;
120pub use database::postgres::PgNotify;
121pub use database::{DBConfig, DBListener, EventType};