# `TigerBeetlex.Connection`
[🔗](https://github.com/rbino/tigerbeetlex/blob/0.16.78/lib/tigerbeetlex/connection.ex#L1)

Blocking API.

This module exposes a blocking API to the TigerBeetle NIF client. This is obtained by spawning
receiver processes under a `PartitionSupervisor`. The receiver processes handle receiving messages
from the message based `TigerBeetlex.Client` client and translate them in a blocking API.

If you already have a wrapping process, you can use `TigerBeetlex.Client` directly instead.

# `create_accounts`

```elixir
@spec create_accounts(
  name :: PartitionSupervisor.name(),
  accounts :: [TigerBeetlex.Account.t()]
) ::
  {:ok, [TigerBeetlex.CreateAccountsResult.t()]}
  | {:error, TigerBeetlex.Types.request_error()}
```

Creates a batch of accounts.

`name` is the same atom that was passed in the `:name` option in `start_link/1`.

`accounts` is a list of `TigerBeetlex.Account` structs.

If successful, the function returns `{:ok, results}` where `results` is a list of
`TigerBeetlex.CreateAccountsResult` structs which contain the index
of the account list and the reason of the failure. An account has a corresponding
`TigerBeetlex.CreateAccountsResult` only if it fails to be created, otherwise the account
has been created succesfully (so a successful request returns an empty list).

See [`create_accounts`](https://docs.tigerbeetle.com/reference/requests/create_accounts/).

## Examples
    alias TigerBeetlex.Account
    alias TigerBeetlex.ID

    # Successful request
    accounts = [%Account{id: ID.generate(), ledger: 3, code: 4}]

    TigerBeetlex.Connection.create_accounts(:tb, accounts)
    #=> {:ok, []}

    # Creation error
    accounts = [%Account{id: ID.from_int(0), ledger: 3, code: 4}]

    TigerBeetlex.Connection.create_accounts(:tb, accounts)

    #=> {:ok, [%TigerBeetlex.CreateAccountsResult{index: 0, result: :id_must_not_be_zero}]}

# `create_transfers`

```elixir
@spec create_transfers(
  name :: PartitionSupervisor.name(),
  transfers :: [TigerBeetlex.Transfer.t()]
) ::
  {:ok, [TigerBeetlex.CreateTransfersResult.t()]}
  | {:error, TigerBeetlex.Types.request_error()}
```

Creates a batch of transfers.

`name` is the same atom that was passed in the `:name` option in `start_link/1`.

`transfers` is a list of `TigerBeetlex.Transfer` structs.

If successful, the function returns `{:ok, results}` where `results` is a list of
`TigerBeetlex.CreateTransfersResult` structs which contain the index
of the transfer list and the reason of the failure. A transfer has a corresponding
`TigerBeetlex.CreateTransfersResult` only if it fails to be created, otherwise the transfer
has been created succesfully (so a successful request returns an empty list).

See [`create_transfers`](https://docs.tigerbeetle.com/reference/requests/create_transfers/).

## Examples
    alias TigerBeetlex.ID
    alias TigerBeetlex.Transfer

    # Successful request
    transfers = [
      %Transfer{
        id: ID.generate(),
        debit_account_id: ID.from_int(42),
        credit_account_id: ID.from_int(43),
        ledger: 3,
        code: 4
        amount: 100
      }
    ]

    TigerBeetlex.Connection.create_transfers(:tb, transfers)
    #=> {:ok, []}

    # Creation error
    transfers = [
      %Transfer{
        id: ID.from_int(0),
        debit_account_id: ID.from_int(42),
        credit_account_id: ID.from_int(43),
        ledger: 3,
        code: 4
        amount: 100
      }
    ]

    TigerBeetlex.Connection.create_transfers(:tb, transfers)
    #=> {:ok, [%TigerBeetlex.CreateTransferError{index: 0, result: :id_must_not_be_zero}]}

# `get_account_balances`

```elixir
@spec get_account_balances(
  name :: PartitionSupervisor.name(),
  account_filter :: TigerBeetlex.AccountFilter.t()
) ::
  {:ok, [TigerBeetlex.AccountBalance.t()]}
  | {:error, TigerBeetlex.Types.request_error()}
```

Fetch a list of historical `TigerBeetlex.AccountBalance` for a given `TigerBeetlex.Account`.

Only accounts created with the `history` flag set retain historical balances. This is off by default.

`name` is the same atom that was passed in the `:name` option in `start_link/1`.

`account_filter` is a `TigerBeetlex.AccountFilter` struct. The `limit` field must be set.

If successful, the function returns `{:ok, results}` where `results` is a list of
`TigerBeetlex.AccountBalance` structs.

See [`get_account_balances`](https://docs.tigerbeetle.com/reference/requests/get_account_balances/).

## Examples
    alias TigerBeetlex.AccountFilter
    alias TigerBeetlex.ID

    account_filter = %AccountFilter{id: ID.from_int(42), limit: 10}

    TigerBeetlex.Connection.get_account_balances(:tb, account_filter)
    #=> {:ok, [%TigerBeetlex.AccountBalance{}]}

# `get_account_transfers`

```elixir
@spec get_account_transfers(
  name :: PartitionSupervisor.name(),
  account_filter :: TigerBeetlex.AccountFilter.t()
) ::
  {:ok, [TigerBeetlex.Transfer.t()]}
  | {:error, TigerBeetlex.Types.request_error()}
```

Fetch a list of `TigerBeetlex.Transfer` involving a `TigerBeetlex.Account`.

`name` is the same atom that was passed in the `:name` option in `start_link/1`.

`account_filter` is a `TigerBeetlex.AccountFilter` struct. The `limit` field must be set.

If successful, the function returns `{:ok, results}` where `results` is a list of
`TigerBeetlex.Transfer` structs.

See [`get_account_transfers`](https://docs.tigerbeetle.com/reference/requests/get_account_transfers/).

## Examples
    alias TigerBeetlex.AccountFilter
    alias TigerBeetlex.ID

    account_filter = %AccountFilter{id: ID.from_int(42), limit: 10}

    TigerBeetlex.Connection.get_account_transfers(:tb, account_filter)
    #=> {:ok, [%TigerBeetlex.Transfer{}]}

# `lookup_accounts`

```elixir
@spec lookup_accounts(
  name :: PartitionSupervisor.name(),
  ids :: [TigerBeetlex.Types.id_128()]
) ::
  {:ok, [TigerBeetlex.Account.t()]}
  | {:error, TigerBeetlex.Types.request_error()}
```

Lookup a batch of accounts.

`name` is the same atom that was passed in the `:name` option in `start_link/1`.

`ids` is a list of 128-bit binaries.

If successful, the function returns `{:ok, results}` where `results` is a list of
`TigerBeetlex.Account` structs. If an id in the list does not correspond to an existing
account, it will simply be skipped, so the result can have less accounts then the provided
ids.

See [`lookup_accounts`](https://docs.tigerbeetle.com/reference/requests/lookup_accounts/).

## Examples

    alias TigerBeetlex.ID

    ids = [ID.from_int(42)]

    TigerBeetlex.Connection.lookup_accounts(:tb, ids)
    #=> {:ok, [%TigerBeetlex.Account{}]}

# `lookup_transfers`

```elixir
@spec lookup_transfers(
  name :: PartitionSupervisor.name(),
  ids :: [TigerBeetlex.Types.id_128()]
) ::
  {:ok, [TigerBeetlex.Transfer.t()]}
  | {:error, TigerBeetlex.Types.request_error()}
```

Lookup a batch of transfers.

`name` is the same atom that was passed in the `:name` option in `start_link/1`.

`ids` is a list of 128-bit binaries.

If successful, the function returns `{:ok, results}` where `results` is a list of
`TigerBeetlex.Transfer` structs. If an id in the list does not correspond to an existing
transfer, it will simply be skipped, so the result could have less transfers then the provided
ids.

See [`lookup_transfers`](https://docs.tigerbeetle.com/reference/requests/lookup_transfers/).

## Examples

    alias TigerBeetlex.ID

    ids = [ID.from_int(43)]

    TigerBeetlex.Connection.lookup_transfers(:tb, ids)
    #=> {:ok, [%TigerBeetlex.Transfer{}]}

# `query_accounts`

```elixir
@spec query_accounts(
  name :: PartitionSupervisor.name(),
  query_filter :: TigerBeetlex.QueryFilter.t()
) ::
  {:ok, [TigerBeetlex.Account.t()]}
  | {:error, TigerBeetlex.Types.request_error()}
```

Query accounts by the intersection of some fields and by timestamp range.

`name` is the same atom that was passed in the `:name` option in `start_link/1`.

`query_filter` is a `TigerBeetlex.QueryFilter` struct. The `limit` field must be set.

If successful, the function returns `{:ok, results}` where `results` is a list of
`TigerBeetlex.Account` structs.

See [`query_accounts`](https://docs.tigerbeetle.com/reference/requests/query_accounts/).

## Examples
    alias TigerBeetlex.QueryFilter

    query_filter = %QueryFilter{ledger: 42, limit: 10}

    TigerBeetlex.Connection.query_accounts(:tb, query_filter)
    #=> {:ok, [%TigerBeetlex.Account{}]}

# `query_transfers`

```elixir
@spec query_transfers(
  name :: PartitionSupervisor.name(),
  query_filter :: TigerBeetlex.QueryFilter.t()
) ::
  {:ok, [TigerBeetlex.Account.t()]}
  | {:error, TigerBeetlex.Types.request_error()}
```

Query transfers by the intersection of some fields and by timestamp range.

`name` is the same atom that was passed in the `:name` option in `start_link/1`.

`query_filter` is a `TigerBeetlex.QueryFilter` struct. The `limit` field must be set.

If successful, the function returns `{:ok, results}` where `results` is a list of
`TigerBeetlex.Transfer` structs.

See [`query_transfers`](https://docs.tigerbeetle.com/reference/requests/query_transfers/).

## Examples
    alias TigerBeetlex.QueryFilter

    query_filter = %QueryFilter{ledger: 42, limit: 10}

    TigerBeetlex.Connection.query_transfers(:tb, query_filter)
    #=> {:ok, [%TigerBeetlex.Transfer{}]}

# `start_link`

```elixir
@spec start_link(opts :: TigerBeetlex.Types.start_options()) ::
  Supervisor.on_start() | {:error, TigerBeetlex.Types.init_client_error()}
```

Starts a managed TigerBeetlex connection.

This creates N receiver processes (where N can be controlled by
passing options to the underlying `PartitionSupervisor`) under a `PartitionSupervisor`.

On success, the it returns the pid of the `PartitionSupervisor`. Note that this is not
what you have to pass to all the other functions in this module as first argument,
rather the `name` atom passed as option to `start_link/1` has to be passed.

## Options

These are the TigerBeetlex-specific options supported by this function:

* `:name` (`t:atom/0`) - Required. The name of the Connection process. The same atom has to be passed to all the other functions
  as first argument.

* `:cluster_id` (`t:TigerBeetlex.Types.id_128/0`) - Required. The TigerBeetle cluster id.

* `:addresses` (list of `t:String.t/0`) - Required. The list of node addresses. These can either be a single digit (e.g. `"3000"`), which is
  interpreted as a port on `127.0.0.1`, an IP address + port (e.g. `"127.0.0.1:3000"`), or just
  an IP address (e.g. `"127.0.0.1"`), which defaults to port `3001`.

The rest of the options are forwarded to `PartitionSupervisor.start_link/1`. For example, to
start a pool of five receivers, you can use the `:partitions` option:

    TigerBeetlex.Connection.start_link(
      partitions: 5,
      # ...
    )

## Examples
    alias TigerBeetlex.Connection
    alias TigerBeetlex.ID

    # Start the TigerBeetlex connection
    {:ok, pid} =
      Connection.start_link(
        cluster_id: ID.from_int(0),
        addresses: ["3000"],
        name: :tb
      )

---

*Consult [api-reference.md](api-reference.md) for complete listing*
