snowflake_connector_rs/
lib.rs

1//! # Snowflake Connector
2//!
3//! A Rust client for Snowflake, which enables you to connect to Snowflake and run queries.
4//!
5//! ```rust
6//! # use snowflake_connector_rs::{Result, SnowflakeAuthMethod, SnowflakeClient, SnowflakeClientConfig};
7//! # async fn run() -> Result<()> {
8//! let client = SnowflakeClient::new(
9//!     "USERNAME",
10//!     SnowflakeAuthMethod::Password("PASSWORD".to_string()),
11//!     SnowflakeClientConfig {
12//!         account: "ACCOUNT".to_string(),
13//!         role: Some("ROLE".to_string()),
14//!         warehouse: Some("WAREHOUSE".to_string()),
15//!         database: Some("DATABASE".to_string()),
16//!         schema: Some("SCHEMA".to_string()),
17//!         timeout: Some(std::time::Duration::from_secs(30)),
18//!     },
19//! )?;
20//! let session = client.create_session().await?;
21//!
22//! let query = "CREATE TEMPORARY TABLE example (id NUMBER, value STRING)";
23//! session.query(query).await?;
24//!
25//! let query = "INSERT INTO example (id, value) VALUES (1, 'hello'), (2, 'world')";
26//! session.query(query).await?;
27//!
28//! let query = "SELECT * FROM example ORDER BY id";
29//! let rows = session.query(query).await?;
30//! assert_eq!(rows.len(), 2);
31//! assert_eq!(rows[0].get::<i64>("ID")?, 1);
32//! assert_eq!(rows[0].get::<String>("VALUE")?, "hello");
33//! # Ok(())
34//! # }
35//! ```
36
37mod auth;
38mod chunk;
39mod error;
40mod query;
41mod row;
42mod session;
43
44use std::time::Duration;
45
46pub use error::{Error, Result};
47pub use query::QueryExecutor;
48pub use row::{SnowflakeColumn, SnowflakeColumnType, SnowflakeDecode, SnowflakeRow};
49pub use session::SnowflakeSession;
50
51use auth::login;
52
53use reqwest::{Client, ClientBuilder, Proxy};
54
55#[derive(Clone)]
56pub struct SnowflakeClient {
57    http: Client,
58
59    username: String,
60    auth: SnowflakeAuthMethod,
61    config: SnowflakeClientConfig,
62}
63
64#[derive(Default, Clone)]
65pub struct SnowflakeClientConfig {
66    pub account: String,
67
68    pub warehouse: Option<String>,
69    pub database: Option<String>,
70    pub schema: Option<String>,
71    pub role: Option<String>,
72    pub timeout: Option<Duration>,
73}
74
75#[derive(Clone)]
76pub enum SnowflakeAuthMethod {
77    Password(String),
78    KeyPair {
79        encrypted_pem: String,
80        password: Vec<u8>,
81    },
82}
83
84impl SnowflakeClient {
85    pub fn new(
86        username: &str,
87        auth: SnowflakeAuthMethod,
88        config: SnowflakeClientConfig,
89    ) -> Result<Self> {
90        let client = ClientBuilder::new().gzip(true).use_rustls_tls().build()?;
91        Ok(Self {
92            http: client,
93            username: username.to_string(),
94            auth,
95            config,
96        })
97    }
98
99    pub fn with_proxy(self, host: &str, port: u16, username: &str, password: &str) -> Result<Self> {
100        let proxy = Proxy::all(format!("http://{}:{}", host, port).as_str())?
101            .basic_auth(username, password);
102
103        let client = ClientBuilder::new()
104            .gzip(true)
105            .use_rustls_tls()
106            .proxy(proxy)
107            .build()?;
108        Ok(Self {
109            http: client,
110            username: self.username,
111            auth: self.auth,
112            config: self.config,
113        })
114    }
115
116    pub async fn create_session(&self) -> Result<SnowflakeSession> {
117        let session_token = login(&self.http, &self.username, &self.auth, &self.config).await?;
118        Ok(SnowflakeSession {
119            http: self.http.clone(),
120            account: self.config.account.clone(),
121            session_token,
122            timeout: self.config.timeout,
123        })
124    }
125}