Skip to main content

exarrow_rs/adbc/
driver.rs

1//! ADBC Driver implementation.
2//!
3//! This module provides the `Driver` type which contains metadata about the
4//! exarrow-rs driver and serves as a factory for creating `Database` instances.
5
6use crate::adbc::Database;
7use crate::error::ConnectionError;
8use std::str::FromStr;
9
10/// ADBC Driver for Exasol.
11///
12/// The `Driver` type represents the exarrow-rs driver and provides metadata
13/// about the driver implementation. It serves as the entry point for creating
14/// database connections.
15///
16/// # Example
17///
18#[derive(Debug, Clone)]
19pub struct Driver {
20    /// Driver name
21    name: String,
22    /// Driver version
23    version: String,
24    /// Vendor name
25    vendor: String,
26    /// Driver description
27    description: String,
28}
29
30impl Driver {
31    /// Create a new Driver instance.
32    ///
33    /// This initializes the driver with metadata from the library.
34    ///
35    /// # Example
36    ///
37    pub fn new() -> Self {
38        Self {
39            name: "exarrow-rs".to_string(),
40            version: env!("CARGO_PKG_VERSION").to_string(),
41            vendor: "exarrow-rs contributors".to_string(),
42            description: "ADBC-compatible driver for Exasol with Arrow data format support"
43                .to_string(),
44        }
45    }
46
47    /// Get the driver name.
48    ///
49    /// # Returns
50    ///
51    /// The name of the driver ("exarrow-rs").
52    pub fn name(&self) -> &str {
53        &self.name
54    }
55
56    /// Get the driver version.
57    ///
58    /// # Returns
59    ///
60    /// The version string from the Cargo.toml.
61    pub fn version(&self) -> &str {
62        &self.version
63    }
64
65    /// Get the vendor name.
66    ///
67    /// # Returns
68    ///
69    /// The vendor name ("exarrow-rs contributors").
70    pub fn vendor(&self) -> &str {
71        &self.vendor
72    }
73
74    /// Get the driver description.
75    ///
76    /// # Returns
77    ///
78    /// A description of the driver's capabilities.
79    pub fn description(&self) -> &str {
80        &self.description
81    }
82
83    /// Open a database connection factory.
84    ///
85    /// This parses the connection string and creates a `Database` instance
86    /// that can be used to establish connections.
87    ///
88    /// # Arguments
89    ///
90    /// * `connection_string` - Connection string in the format:
91    ///   `exasol://[username[:password]@]host[:port][/schema][?param=value&...]`
92    ///
93    /// # Returns
94    ///
95    /// A `Database` instance configured with the connection parameters.
96    ///
97    /// # Errors
98    ///
99    /// Returns `ConnectionError` if the connection string is invalid.
100    ///
101    /// # Example
102    ///
103    pub fn open(&self, connection_string: &str) -> Result<Database, ConnectionError> {
104        Database::from_str(connection_string)
105    }
106
107    /// Check if a connection string is valid.
108    ///
109    /// This validates the connection string format without establishing a connection.
110    ///
111    /// # Arguments
112    ///
113    /// * `connection_string` - The connection string to validate.
114    ///
115    /// # Returns
116    ///
117    /// `true` if the connection string is valid, `false` otherwise.
118    ///
119    /// # Example
120    ///
121    pub fn validate_connection_string(&self, connection_string: &str) -> bool {
122        Database::from_str(connection_string).is_ok()
123    }
124}
125
126impl Default for Driver {
127    fn default() -> Self {
128        Self::new()
129    }
130}
131
132impl std::fmt::Display for Driver {
133    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
134        write!(f, "{} v{} ({})", self.name, self.version, self.vendor)
135    }
136}
137
138#[cfg(test)]
139mod tests {
140    use super::*;
141
142    #[test]
143    fn test_driver_creation() {
144        let driver = Driver::new();
145        assert_eq!(driver.name(), "exarrow-rs");
146        assert_eq!(driver.vendor(), "exarrow-rs contributors");
147        assert!(!driver.version().is_empty());
148        assert!(!driver.description().is_empty());
149    }
150
151    #[test]
152    fn test_driver_default() {
153        let driver = Driver::default();
154        assert_eq!(driver.name(), "exarrow-rs");
155    }
156
157    #[test]
158    fn test_driver_display() {
159        let driver = Driver::new();
160        let display = format!("{}", driver);
161        assert!(display.contains("exarrow-rs"));
162        assert!(display.contains("contributors"));
163    }
164
165    #[test]
166    fn test_driver_open_valid() {
167        let driver = Driver::new();
168        let result = driver.open("exasol://user@localhost");
169        assert!(result.is_ok());
170    }
171
172    #[test]
173    fn test_driver_open_invalid() {
174        let driver = Driver::new();
175        let result = driver.open("invalid://connection");
176        assert!(result.is_err());
177    }
178
179    #[test]
180    fn test_validate_connection_string() {
181        let driver = Driver::new();
182
183        assert!(driver.validate_connection_string("exasol://user@localhost"));
184        assert!(driver.validate_connection_string("exasol://user:pass@host:8563"));
185        assert!(driver.validate_connection_string("exasol://user@host/schema"));
186
187        assert!(!driver.validate_connection_string(""));
188        assert!(!driver.validate_connection_string("invalid"));
189        assert!(!driver.validate_connection_string("postgres://user@host"));
190    }
191}