Current section
Files
Jump to
Current section
Files
lib/prql.ex
defmodule Prql do
@moduledoc """
PRQL compiler for Elixir, powered by Rust's prqlc.
"""
alias Prql.Options
@type option :: Options.option()
@type options :: Options.options()
@type dialect :: Options.dialect()
@type display_option :: Options.display_option()
@type format_error :: {:error, String.t()}
@doc """
Compiles a PRQL query to SQL.
## Options
- `:format` - Whether to format the SQL output (default: `false`)
- `:target` - The SQL dialect to target (optional, no default)
- `:signature_comment` - Whether to include the PRQL signature comment (default: `false`)
- `:color` - Whether to enable color in the output (default: `false`)
- `:display` - Display options for the output (`:plain` or `:ansi_color`, default: `:plain`)
## Examples
iex> Prql.compile("from employees | select {name, age}")
{:ok, "SELECT name, age FROM employees"}
iex> Prql.compile("from employees | select {name, age}", target: :postgres)
{:ok, "SELECT name, age FROM employees"}
Returns `{:ok, sql_string}` on success, or `{:error, reason}` on failure.
"""
@spec compile(String.t(), options()) :: {:ok, String.t()} | {:error, String.t()}
def compile(prql_query, options \\ []) when is_binary(prql_query) and is_list(options) do
with {:ok, normalized_options} <- Options.normalize(options) do
Prql.Native.compile(prql_query, normalized_options)
end
end
@doc """
Same as `compile/2` but raises an exception if compilation fails.
## Options
See `compile/2` for available options.
## Examples
iex> Prql.compile!("from employees | select {name, age}")
"SELECT name, age FROM employees"
iex> Prql.compile!("from employees | select {name, age}", target: :postgres)
"SELECT name, age FROM employees"
iex> Prql.compile!("invalid prql")
** (RuntimeError) PRQL compilation failed: ...
"""
@spec compile!(String.t(), options()) :: String.t() | no_return()
def compile!(prql_query, options \\ []) do
case compile(prql_query, options) do
{:ok, sql} -> sql
{:error, reason} -> raise "PRQL compilation failed: #{reason}"
end
end
@doc """
Formats a PRQL query according to the standard style.
## Examples
iex> Prql.format("from employees | select {name, age}")
{:ok, "\""
from employees
select {name, age}
"\""}
iex> Prql.format("invalid prql")
{:error, "unexpected keyword prql"}
"""
@spec format(String.t()) :: {:ok, String.t()} | format_error()
def format(prql_query) when is_binary(prql_query) do
Prql.Native.format(prql_query)
end
@doc """
Same as `format/1` but raises an exception if formatting fails.
## Examples
iex> Prql.format!("from employees | select {name, age}")
""\"
from employees
select {name, age}
""\"
iex> Prql.format!("invalid prql")
** (RuntimeError) PRQL formatting failed: ...
"""
@spec format!(String.t()) :: String.t() | no_return()
def format!(prql_query) do
case format(prql_query) do
{:ok, formatted} -> formatted
{:error, reason} -> raise "PRQL formatting failed: #{reason}"
end
end
end