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}