oracle_rs/lib.rs
1#![warn(missing_docs)]
2
3//! # oracle-rs
4//!
5//! A pure Rust driver for Oracle databases. No OCI or ODPI-C dependencies required.
6//!
7//! This crate implements the Oracle TNS (Transparent Network Substrate) protocol
8//! entirely in Rust, enabling Oracle database connectivity without installing any
9//! Oracle client libraries.
10//!
11//! ## Features
12//!
13//! - **Pure Rust** - No Oracle client libraries required
14//! - **Async/await** - Built on Tokio for modern async applications
15//! - **TLS/SSL** - Secure connections with certificate and wallet support
16//! - **Statement Caching** - LRU cache for prepared statements
17//! - **Comprehensive Type Support** - Including LOBs, JSON, VECTORs, and more
18//!
19//! ## Quick Start
20//!
21//! ```rust,no_run
22//! use oracle_rs::{Config, Connection};
23//!
24//! #[tokio::main]
25//! async fn main() -> oracle_rs::Result<()> {
26//! // Connect to Oracle
27//! let config = Config::new("localhost", 1521, "FREEPDB1", "user", "password");
28//! let conn = Connection::connect_with_config(config).await?;
29//!
30//! // Execute a query
31//! let result = conn.query("SELECT id, name FROM users", &[]).await?;
32//!
33//! for row in &result.rows {
34//! let id = row.get_i64(0).unwrap_or(0);
35//! let name = row.get_string(1).unwrap_or("");
36//! println!("User {}: {}", id, name);
37//! }
38//!
39//! Ok(())
40//! }
41//! ```
42//!
43//! ## Connection Options
44//!
45//! ### Basic Connection
46//!
47//! ```rust,no_run
48//! use oracle_rs::{Config, Connection};
49//!
50//! # async fn example() -> oracle_rs::Result<()> {
51//! let config = Config::new("hostname", 1521, "service_name", "username", "password");
52//! let conn = Connection::connect_with_config(config).await?;
53//! # Ok(())
54//! # }
55//! ```
56//!
57//! ### TLS/SSL Connection
58//!
59//! ```rust,no_run
60//! use oracle_rs::{Config, Connection};
61//!
62//! # async fn example() -> oracle_rs::Result<()> {
63//! let config = Config::new("hostname", 2484, "service_name", "username", "password")
64//! .with_tls()?;
65//!
66//! let conn = Connection::connect_with_config(config).await?;
67//! # Ok(())
68//! # }
69//! ```
70//!
71//! ### Oracle Wallet
72//!
73//! ```rust,no_run
74//! use oracle_rs::{Config, Connection};
75//!
76//! # async fn example() -> oracle_rs::Result<()> {
77//! let config = Config::new("hostname", 2484, "service_name", "username", "password")
78//! .with_wallet("/path/to/wallet", Some("wallet_password"))?;
79//!
80//! let conn = Connection::connect_with_config(config).await?;
81//! # Ok(())
82//! # }
83//! ```
84//!
85//! ## Query Execution
86//!
87//! ### SELECT Queries
88//!
89//! ```rust,no_run
90//! use oracle_rs::{Connection, Value};
91//!
92//! # async fn example(conn: Connection) -> oracle_rs::Result<()> {
93//! // Simple query
94//! let result = conn.query("SELECT * FROM employees", &[]).await?;
95//!
96//! // With bind parameters
97//! let result = conn.query(
98//! "SELECT * FROM employees WHERE department_id = :1 AND salary > :2",
99//! &[10.into(), 50000.0.into()]
100//! ).await?;
101//!
102//! // Access rows
103//! for row in &result.rows {
104//! let name = row.get_by_name("employee_name").and_then(|v| v.as_str()).unwrap_or("");
105//! let salary = row.get_by_name("salary").and_then(|v| v.as_f64()).unwrap_or(0.0);
106//! }
107//! # Ok(())
108//! # }
109//! ```
110//!
111//! ### DML Operations
112//!
113//! ```rust,no_run
114//! use oracle_rs::{Connection, Value};
115//!
116//! # async fn example(conn: Connection) -> oracle_rs::Result<()> {
117//! // INSERT
118//! let result = conn.execute(
119//! "INSERT INTO users (id, name) VALUES (:1, :2)",
120//! &[1.into(), "Alice".into()]
121//! ).await?;
122//! println!("Rows inserted: {}", result.rows_affected);
123//!
124//! // Commit the transaction
125//! conn.commit().await?;
126//! # Ok(())
127//! # }
128//! ```
129//!
130//! ### Batch Operations
131//!
132//! ```rust,no_run
133//! use oracle_rs::{Connection, BatchBuilder, Value};
134//!
135//! # async fn example(conn: Connection) -> oracle_rs::Result<()> {
136//! let batch = BatchBuilder::new("INSERT INTO users (id, name) VALUES (:1, :2)")
137//! .add_row(vec![1.into(), "Alice".into()])
138//! .add_row(vec![2.into(), "Bob".into()])
139//! .add_row(vec![3.into(), "Charlie".into()])
140//! .build();
141//!
142//! let result = conn.execute_batch(&batch).await?;
143//! conn.commit().await?;
144//! # Ok(())
145//! # }
146//! ```
147//!
148//! ## Transactions
149//!
150//! ```rust,no_run
151//! use oracle_rs::{Connection, Value};
152//!
153//! # async fn example(conn: Connection) -> oracle_rs::Result<()> {
154//! // Auto-commit is off by default
155//! conn.execute("INSERT INTO accounts (id, balance) VALUES (:1, :2)", &[1.into(), 100.0.into()]).await?;
156//! conn.execute("UPDATE accounts SET balance = balance - :1 WHERE id = :2", &[50.0.into(), 1.into()]).await?;
157//!
158//! // Commit the transaction
159//! conn.commit().await?;
160//!
161//! // Or rollback on error
162//! // conn.rollback().await?;
163//!
164//! // Savepoints
165//! conn.savepoint("before_update").await?;
166//! conn.execute("UPDATE accounts SET balance = 0 WHERE id = :1", &[1.into()]).await?;
167//! conn.rollback_to_savepoint("before_update").await?; // Undo the update
168//! # Ok(())
169//! # }
170//! ```
171//!
172//! ## Data Types
173//!
174//! | Oracle Type | Rust Type |
175//! |-------------|-----------|
176//! | NUMBER | `i8`, `i16`, `i32`, `i64`, `f32`, `f64`, `String` |
177//! | VARCHAR2, CHAR | `String`, `&str` |
178//! | DATE | `chrono::NaiveDateTime` |
179//! | TIMESTAMP | `chrono::NaiveDateTime` |
180//! | TIMESTAMP WITH TIME ZONE | `chrono::DateTime<FixedOffset>` |
181//! | RAW | `Vec<u8>`, `&[u8]` |
182//! | CLOB, NCLOB | `String` |
183//! | BLOB | `Vec<u8>` |
184//! | BOOLEAN | `bool` |
185//! | JSON | `serde_json::Value` |
186//! | VECTOR | `Vec<f32>`, `Vec<f64>`, `Vec<i8>` |
187//!
188//! ## Connection Pooling
189//!
190//! Use the companion [`deadpool-oracle`](https://crates.io/crates/deadpool-oracle) crate
191//! for connection pooling.
192//!
193//! ## Minimum Oracle Version
194//!
195//! Oracle Database 12c Release 1 (12.1) or later. Some features require newer versions:
196//!
197//! - **Native BOOLEAN**: Oracle 23c (emulated on earlier versions)
198//! - **JSON type**: Oracle 21c
199//! - **VECTOR type**: Oracle 23ai
200
201pub mod batch;
202pub mod buffer;
203pub mod capabilities;
204pub mod config;
205pub mod connection;
206pub mod constants;
207pub mod crypto;
208pub mod cursor;
209pub mod dbobject;
210pub mod drcp;
211pub mod error;
212pub mod implicit;
213pub mod messages;
214pub mod packet;
215pub mod row;
216pub mod statement;
217pub mod statement_cache;
218pub mod transport;
219pub mod types;
220
221// Re-export commonly used types
222pub use batch::{BatchBinds, BatchBuilder, BatchError, BatchOptions, BatchResult};
223pub use capabilities::Capabilities;
224pub use config::{Config, TlsMode};
225pub use connection::{Connection, ConnectionState, PlsqlResult, QueryOptions, QueryResult, ServerInfo};
226pub use transport::{Protocol, TlsConfig};
227pub use constants::FetchOrientation;
228pub use cursor::{ScrollableCursor, ScrollableCursorOptions, ScrollMode, ScrollResult};
229pub use dbobject::{CollectionType, DbObject, DbObjectAttr, DbObjectType};
230pub use drcp::{DrcpOptions, DrcpSession, ReleaseMode, SessionPurity};
231pub use error::{Error, Result};
232pub use implicit::{ImplicitResult, ImplicitResults};
233pub use row::{Row, Value, RowDataDecoder};
234pub use statement::{Statement, StatementType, ColumnInfo, BindInfo, BindParam};
235pub use statement_cache::StatementCache;
236pub use constants::{BindDirection, OracleType};
237pub use types::{
238 LobData, LobLocator, LobValue, OracleVector, OsonDecoder, OsonEncoder, RefCursor,
239 SparseVector, VectorData, VectorFormat,
240};
241
242// Re-export serde_json for users working with JSON columns
243pub use serde_json;