snowflake-api 0.2.0

Snowflake API bindings
Documentation
# snowflake-rs

Snowflake library for undocumented public API. If you want to query documented public [SQL REST API](https://docs.snowflake.com/developer-guide/sql-api/intro) use [snowflake-jwt](https://crates.io/crates/snowflake-jwt) together with your favourite request library, see [./jwt/examples](../jwt/examples) for how it's done.

## Features

Since it does a lot of I/O the library is async-only, and currently has hard dependency on [tokio](https://tokio.rs/) as a runtime due to use of [reqwest](https://github.com/seanmonstar/reqwest).

- [x] Single statements
- [ ] Multiple statements
- [ ] Async requests (is it needed if whole library is async?)
- [x] Query results in [Arrow]https://arrow.apache.org/
- [ ] Chunked query results
- [x] Password auth
- [x] Certificate auth
- [ ] Browser-auth
- [x] Closing session
- [x] Token renewal
- [x] PUT support
- [ ] GET support
- [x] AWS integration
- [ ] GCloud integration
- [ ] Azure integration
- [ ] Parallel uploading of small files

## Why

Snowflake has 2 public APIs, one is [SQL REST API](https://docs.snowflake.com/developer-guide/sql-api/intro), which is limited in its support of [PUT](https://docs.snowflake.com/en/sql-reference/sql/put) and [GET](https://docs.snowflake.com/en/sql-reference/sql/get) statements and another undocumented API, which is used by official [Drivers](https://docs.snowflake.com/en/developer-guide/drivers) with the support for both.

This implementation emulates [gosnowflake](https://github.com/snowflakedb/gosnowflake) library, as each official driver comes with a different set of internal flags and defaults (which are selected by `CLIENT_APP_ID`) the Go implementation is the only one currently outputting Arrow by-default.

We've chosen not to generate bindings for C/C++ [libsnowflakeclient](https://github.com/snowflakedb/libsnowflakeclient) library (which backs ODBC driver) as it is in active development and building it under macOS M1 is bigger effort than writing our own API wrapper.

## Usage

In your Cargo.toml:

```toml
[dependencies]
snowflake-api = "0.1.0"
```

Check [examples](./examples) for working programs using the library.


```rust
use anyhow::Result;
use snowflake_api::{QueryResult, SnowflakeApi};

async fn run_query(sql: &str) -> Result<QueryResult> {
    let mut api = SnowflakeApi::with_password_auth(
        "ACCOUNT_IDENTIFIER",
        "WAREHOUSE",
        Some("DATABASE"),
        Some("SCHEMA"),
        "USERNAME",
        Some("ROLE"),
        "PASSWORD",
    )?;
    let res = api.exec(sql).await?;
    
    Ok(res)
}
```

## PUT / GET

[PUT](https://docs.snowflake.com/en/sql-reference/sql/put)/[GET](https://docs.snowflake.com/en/sql-reference/sql/get) statements allow you to access Snowflake-owned storage instead of provisioning your own when doing [COPY INTO](https://docs.snowflake.com/en/sql-reference/sql/copy-into-table). Storage provider depends on which cloud your Snowflake account was provisioned in, hence the need to support multiple cloud backends.