Skip to main content

prax_scylladb/
lib.rs

1//! # prax-scylladb
2//!
3//! ScyllaDB database driver for Prax ORM - high-performance Cassandra-compatible database.
4//!
5//! ScyllaDB is a drop-in replacement for Apache Cassandra that offers significantly
6//! better performance. This driver provides async support for ScyllaDB operations
7//! within the Prax ORM ecosystem.
8//!
9//! ## Features
10//!
11//! - **High Performance**: Built on the official `scylla` async driver
12//! - **Connection Pooling**: Automatic connection management with configurable pool sizes
13//! - **Prepared Statements**: Efficient query execution with automatic caching
14//! - **Async/Await**: Full async support with Tokio runtime
15//! - **Type Safety**: Strong typing with automatic CQL type conversions
16//! - **Lightweight Transactions**: Support for conditional updates (LWT)
17//!
18//! ## Quick Start
19//!
20//! ```rust,no_run
21//! use prax_scylladb::{ScyllaConfig, ScyllaPool};
22//!
23//! #[tokio::main]
24//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
25//!     // Configure the connection
26//!     let config = ScyllaConfig::builder()
27//!         .known_nodes(["127.0.0.1:9042"])
28//!         .default_keyspace("my_keyspace")
29//!         .build();
30//!
31//!     // Create connection pool
32//!     let pool = ScyllaPool::connect(config).await?;
33//!
34//!     // Execute queries
35//!     let result = pool
36//!         .query("SELECT * FROM users WHERE id = ?", (user_id,))
37//!         .await?;
38//!
39//!     Ok(())
40//! }
41//! ```
42//!
43//! ## Configuration
44//!
45//! ```rust
46//! use prax_scylladb::ScyllaConfig;
47//!
48//! let config = ScyllaConfig::builder()
49//!     .known_nodes(["node1:9042", "node2:9042", "node3:9042"])
50//!     .default_keyspace("production")
51//!     .username("admin")
52//!     .password("secret")
53//!     .connection_timeout_secs(10)
54//!     .request_timeout_secs(30)
55//!     .build();
56//! ```
57//!
58//! ## Prepared Statements
59//!
60//! For frequently executed queries, use prepared statements:
61//!
62//! ```rust,no_run
63//! use prax_scylladb::ScyllaEngine;
64//!
65//! async fn get_user(engine: &ScyllaEngine, id: uuid::Uuid) -> Result<Option<User>, Error> {
66//!     engine
67//!         .query_one("SELECT * FROM users WHERE id = ?", (id,))
68//!         .await
69//! }
70//! ```
71//!
72//! ## Batch Operations
73//!
74//! Execute multiple statements atomically:
75//!
76//! ```rust,no_run
77//! use prax_scylladb::ScyllaEngine;
78//!
79//! async fn transfer_funds(
80//!     engine: &ScyllaEngine,
81//!     from: uuid::Uuid,
82//!     to: uuid::Uuid,
83//!     amount: i64,
84//! ) -> Result<(), Error> {
85//!     engine.batch()
86//!         .add("UPDATE accounts SET balance = balance - ? WHERE id = ?", (amount, from))
87//!         .add("UPDATE accounts SET balance = balance + ? WHERE id = ?", (amount, to))
88//!         .execute()
89//!         .await
90//! }
91//! ```
92
93#![cfg_attr(docsrs, feature(doc_cfg))]
94#![warn(missing_docs)]
95#![warn(clippy::all)]
96#![warn(clippy::pedantic)]
97#![allow(clippy::module_name_repetitions)]
98
99mod config;
100mod connection;
101mod engine;
102mod error;
103mod pool;
104mod row;
105mod types;
106
107pub use config::{ScyllaConfig, ScyllaConfigBuilder};
108pub use connection::ScyllaConnection;
109pub use engine::{ScyllaBatch, ScyllaEngine};
110pub use error::{ScyllaError, ScyllaResult};
111pub use pool::ScyllaPool;
112pub use row::FromScyllaRow;
113pub use types::{ScyllaValue, ToCqlValue};
114
115/// Prelude module for convenient imports.
116pub mod prelude {
117    pub use crate::config::{ScyllaConfig, ScyllaConfigBuilder};
118    pub use crate::connection::ScyllaConnection;
119    pub use crate::engine::{ScyllaBatch, ScyllaEngine};
120    pub use crate::error::{ScyllaError, ScyllaResult};
121    pub use crate::pool::ScyllaPool;
122    pub use crate::row::FromScyllaRow;
123    pub use crate::types::{ScyllaValue, ToCqlValue};
124}
125
126#[cfg(test)]
127mod tests {
128    use super::*;
129
130    #[test]
131    fn test_config_builder() {
132        let config = ScyllaConfig::builder()
133            .known_nodes(["127.0.0.1:9042"])
134            .default_keyspace("test")
135            .build();
136
137        assert_eq!(config.default_keyspace(), Some("test"));
138        assert_eq!(config.known_nodes().len(), 1);
139    }
140
141    #[test]
142    fn test_config_from_url() {
143        let config = ScyllaConfig::from_url("scylla://localhost:9042/my_keyspace").unwrap();
144        assert_eq!(config.default_keyspace(), Some("my_keyspace"));
145    }
146}