# Supabase PostgREST
[PostgREST](https://supabase.com/docs/guides/database/overview) implementation for the [Supabase Potion](https://hexdocs.pm/supabase_potion) SDK in Elixir.
The `Supabase.PostgREST` module provides a suite of functions to interact with a Supabase PostgREST API using a fluent interface. This allows you to construct and execute complex queries in the context of a Supabase database application, facilitating a more functional approach to managing database operations in Elixir.
Please, refers to the [official Supabase PostgREST](https://supabase.com/docs/guides/api) documentation to have the context on how to apply query and filters on your data, and also configure your project to expose the PostgREST API.
## Installation
Add the following dependencies to your `mix.exs` file:
```elixir
def deps do
[
{:supabase_potion, "~> 0.5"},
{:supabase_postgrest, "~> 0.1"}
]
end
```
Then, run `mix deps.get` to fetch the dependencies.
## Usage
### Initializing the Client
Before using the `Supabase.PostgREST` module, you need to initialize a Supabase client. This client handles the authentication and configuration needed to interact with the Supabase services.
You can initialize the client as can be found on the [Supabase Potion documentation](https://hexdocs.pm/supabase_potion/readme.html#usage)
This client struct is passed to the various `Supabase.PostgREST` functions to perform operations on your Supabase database.
### Basic Operations
Here’s how you can perform common operations using the `Supabase.PostgREST` module.
Note that all operations and filters on `Supabase.PostgREST` are **lazy**, that means that queries, insertions, deletions and updates are only executed when you explicit call `Supabase.PostgREST.execute/1`.
#### Selecting Data
To select records from a table, use the `from/2` and `select/3` functions:
```elixir
iex> alias Supabase.PostgREST, as: Q
iex> Q.from(client, "users") |> Q.select("*", returning: true) |> Q.execute()
iex> {:ok, result} | {:error, %Supabase.PostgREST.Error{}}
```
You can specify the columns to retrieve instead of using `*`:
```elixir
iex> Q.select(query, ["id", "name"], returning: true)
```
#### Inserting Data
To insert new records, use the `insert/3` function:
```elixir
iex> alias Supabase.PostgREST, as: Q
iex> Q.from(client, "users") |> Q.insert(%{name: "John Doe", age: 30}, returning: :representation) |> Q.execute()
iex> {:ok, result} | {:error, %Supabase.PostgREST.Error{}}
```
#### Updating Data
To update existing records, use the `update/3` function:
```elixir
iex> alias Supabase.PostgREST, as: Q
iex> Q.from(client, "users") |> Q.eq("id", 1) |> Q.update(%{name: "John Smith"}, returning: :representation) |> Q.execute()
iex> {:ok, result} | {:error, %Supabase.PostgREST.Error{}}
```
#### Deleting Data
To delete records, use the `delete/2` function:
```elixir
iex> alias Supabase.PostgREST, as: Q
iex> Q.from(client, "users") |> Q.eq("id", 1) |> Q.delete(query, returning: :representation) |> Q.execute()
iex> {:ok, result} | {:error, %Supabase.PostgREST.Error{}}
```
### Filtering Data
You can apply various filters to your queries using functions like `eq/3`, `lt/3`, `gt/3`, etc.
```elixir
iex> alias Supabase.PostgREST, as: Q
iex> Q.from(client, "users") |> Q.eq("status", "active") |> Q.select("*", returning: true) |> Q.execute()
iex> {:ok, result} | {:error, %Supabase.PostgREST.Error{}}
```
### Advanced Query Building
You can also perform more advanced operations like full-text search, ordering, limiting, and combining filters using logical operators:
```elixir
iex> alias Supabase.PostgREST, as: Q
iex> Q.from(client, "users")
|> Q.text_search("name", "John", type: :plain)
|> Q.order("created_at", asc: true)
|> Q.select(["id", "name", "created_at"], returning: true)
|> Q.execute()
iex> {:ok, result} | {:error, %Supabase.PostgREST.Error{}}
```
### Executing Queries
After constructing a query, you can execute it using the `execute/1` or `execute_to/2` functions. The `execute_to/2` function allows you to map the results directly to a specific schema:
```elixir
iex> defmodule User, do: defstruct([:id])
iex> alias Supabase.PostgREST, as: Q
iex> Q.from(client, "users")
|> Q.eq("id", 1)
|> Q.select(["id"], returning: true)
|> Q.execute_to(User)
iex> {:ok, %User{} = user} | {:error, %Supabase.PostgREST.Error{}}
```
## Contributing
If you find any issues or have suggestions for improvements, please feel free to open an issue or a pull request on the GitHub repository.
## License
This project is licensed under the MIT License.
---
This README provides a clear and structured guide for users of your package, with accurate examples and explanations of how to use the various functions provided by the `Supabase.PostgREST` module.