# Snowpack

[![ version](](
[![ license](](
[![Last Updated](](

<!-- MDOC !-->

Snowflake driver for Elixir.

## Features

- Automatic decoding and encoding of Elixir values to and from Snowflake's ODBC driver formats
- Supports transactions, prepared queries, pooling and more via [DBConnection](
- Supports Snowflake ODBC Drivers 2.24.7+


- Support streaming via [DBConnection](

## Usage

Add `:snowpack` to your dependencies:

def deps() do
    {:snowpack, "~> 0.6.0"}

Make sure you are using the latest version!

opts = [
  connection: [
    role: "DEV",
    warehouse: System.get_env("SNOWFLAKE_WH"),
    uid: System.get_env("SNOWFLAKE_UID"),
    pwd: System.get_env("SNOWFLAKE_PWD")

{:ok, pid} = Snowpack.start_link(opts)
Snowpack.query!(pid, "select current_user()")

Snowpack.query(pid, "SELECT * FROM data")
   columns: ["id", "title"],
   num_rows: 3,
   rows: [[1, "Data 1"], [2, "Data 2"], [3, "Data 3"]]

It's recommended to start Snowpack under a supervision tree:

defmodule MyApp.Application do
  use Application

  def start(_type, _args) do
    children = [
      {Snowpack, uid: "snowflake-uid", name: :snowpack}

    opts = [strategy: :one_for_one, name: MyApp.Supervisor]
    Supervisor.start_link(children, opts)

and then we can refer to it by its `:name`:

Snowpack.query!(:snowpack, "SELECT NOW()").rows
[[~N[2018-12-28 13:42:31]]]

## Data representation

Snowflake ODBC       Elixir
-----                ------
NULL                 nil
bool                 true | false
int                  42
float                42.0
decimal              42.0 # (1)
date                 ~D[2013-10-12]
time                 ~T[00:37:14]
datetime             ~N[2013-10-12 00:37:14]  # (2)
timestamp            ~U[2013-10-12 00:37:14Z] # (2)
char                 "é"
text                 "snowpack"
binary               <<1, 2, 3>>
bit                  <<1::size(1), 0::size(1)>>
array                [1, 2, 3]
object               %{key: "value"}


1. See [Decimal](

2. Datetime fields are represented as `NaiveDateTime`, however a UTC `DateTime` can be used for encoding as well.

<!-- MDOC !-->

## Documentation

Documentation is automatically published to
[]( on release. You may build the
documentation locally with

MIX_ENV=docs mix docs

## Erlang ODBC on Apple M1

Install Dependencies via Homebrew

brew install asdf openssl@1.1 libiodbc wxwidgets

NOTE: you may need to unlink `unixodbc` to install and use `libiodbc`, or replace `libiodbc` with `unixodbc` below.

Configure your shell for [asdf](

Install asdf plugins.

asdf plugin add erlang
asdf plugin add elixir

Configure the KERL compiler used by asdf.

export CFLAGS="-O2 -g -fno-stack-check"
export KERL_CONFIGURE_OPTIONS="--with-ssl=$(brew --prefix openssl@1.1)/ --with-wx-config=$(brew --prefix wxwidgets)/bin/wx-config --with-odbc=$(brew --prefix libiodbc)"
export CPPFLAGS="-I$(brew --prefix libiodbc)/include"
export LDFLAGS="-L$(brew --prefix libiodbc)/lib"

Install Erlang and Elixir

asdf install erlang 25.0.3
asdf install elixir 1.13.4-otp-25

## Running tests locally

Copy over the contents from `.env.test` to `.env.test.local`:
cp .env.test .env.test.local

Generate an `rsa_key` for your Snowflake instance and replace the following env
vars in `.env.test.local` (they have `replace_me` default values). It will look
something like this:

- `/opt/snowflake/snowflakeodbc/lib/libSnowflake.dylib` is the default on Macs.
- You can learn more about them
- There is no need to load this to your `env` since we are using `Vapor` to
  handle config.

## Contributing

Issues and PRs are welcome! See our organization []( for more information about best-practices and passing CI.